Add ability to specify random seed when creating built it network emulation

Bug: webrtc:12340
Change-Id: Iffd054928249099866ef4527b911b1e358e26f5a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/200805
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32920}
diff --git a/api/test/network_emulation_manager.cc b/api/test/network_emulation_manager.cc
index 602c90a..9c148a0 100644
--- a/api/test/network_emulation_manager.cc
+++ b/api/test/network_emulation_manager.cc
@@ -56,18 +56,20 @@
 }
 
 NetworkEmulationManager::SimulatedNetworkNode
-NetworkEmulationManager::SimulatedNetworkNode::Builder::Build() const {
+NetworkEmulationManager::SimulatedNetworkNode::Builder::Build(
+    uint64_t random_seed) const {
   RTC_CHECK(net_);
-  return Build(net_);
+  return Build(net_, random_seed);
 }
 
 NetworkEmulationManager::SimulatedNetworkNode
 NetworkEmulationManager::SimulatedNetworkNode::Builder::Build(
-    NetworkEmulationManager* net) const {
+    NetworkEmulationManager* net,
+    uint64_t random_seed) const {
   RTC_CHECK(net);
   RTC_CHECK(net_ == nullptr || net_ == net);
   SimulatedNetworkNode res;
-  auto behavior = std::make_unique<SimulatedNetwork>(config_);
+  auto behavior = std::make_unique<SimulatedNetwork>(config_, random_seed);
   res.simulation = behavior.get();
   res.node = net->CreateEmulatedNode(std::move(behavior));
   return res;
diff --git a/api/test/network_emulation_manager.h b/api/test/network_emulation_manager.h
index 8619f36..80efb0e 100644
--- a/api/test/network_emulation_manager.h
+++ b/api/test/network_emulation_manager.h
@@ -152,8 +152,9 @@
       Builder& capacity_Mbps(int link_capacity_Mbps);
       Builder& loss(double loss_rate);
       Builder& packet_queue_length(int max_queue_length_in_packets);
-      SimulatedNetworkNode Build() const;
-      SimulatedNetworkNode Build(NetworkEmulationManager* net) const;
+      SimulatedNetworkNode Build(uint64_t random_seed = 1) const;
+      SimulatedNetworkNode Build(NetworkEmulationManager* net,
+                                 uint64_t random_seed = 1) const;
 
      private:
       NetworkEmulationManager* const net_;
@@ -165,9 +166,15 @@
   virtual TimeController* time_controller() = 0;
 
   // Creates an emulated network node, which represents single network in
-  // the emulated network layer.
+  // the emulated network layer. Uses default implementation on network behavior
+  // which can be configured with |config|. |random_seed| can be provided to
+  // alter randomization behavior.
   virtual EmulatedNetworkNode* CreateEmulatedNode(
-      BuiltInNetworkBehaviorConfig config) = 0;
+      BuiltInNetworkBehaviorConfig config,
+      uint64_t random_seed = 1) = 0;
+  // Creates an emulated network node, which represents single network in
+  // the emulated network layer. |network_behavior| determines how created node
+  // will forward incoming packets to the next receiver.
   virtual EmulatedNetworkNode* CreateEmulatedNode(
       std::unique_ptr<NetworkBehaviorInterface> network_behavior) = 0;
 
diff --git a/rtc_base/random.h b/rtc_base/random.h
index 0e2d103..b3b9fd1 100644
--- a/rtc_base/random.h
+++ b/rtc_base/random.h
@@ -66,7 +66,8 @@
   double Exponential(double lambda);
 
  private:
-  // Outputs a nonzero 64-bit random number.
+  // Outputs a nonzero 64-bit random number using Xorshift algorithm.
+  // https://en.wikipedia.org/wiki/Xorshift
   uint64_t NextOutput() {
     state_ ^= state_ >> 12;
     state_ ^= state_ << 25;
diff --git a/test/network/network_emulation_manager.cc b/test/network/network_emulation_manager.cc
index e9656fa..57706fc 100644
--- a/test/network/network_emulation_manager.cc
+++ b/test/network/network_emulation_manager.cc
@@ -63,8 +63,10 @@
 }
 
 EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
-    BuiltInNetworkBehaviorConfig config) {
-  return CreateEmulatedNode(std::make_unique<SimulatedNetwork>(config));
+    BuiltInNetworkBehaviorConfig config,
+    uint64_t random_seed) {
+  return CreateEmulatedNode(
+      std::make_unique<SimulatedNetwork>(config, random_seed));
 }
 
 EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
diff --git a/test/network/network_emulation_manager.h b/test/network/network_emulation_manager.h
index 7b954e7..b2b41b3 100644
--- a/test/network/network_emulation_manager.h
+++ b/test/network/network_emulation_manager.h
@@ -44,8 +44,8 @@
   explicit NetworkEmulationManagerImpl(TimeMode mode);
   ~NetworkEmulationManagerImpl();
 
-  EmulatedNetworkNode* CreateEmulatedNode(
-      BuiltInNetworkBehaviorConfig config) override;
+  EmulatedNetworkNode* CreateEmulatedNode(BuiltInNetworkBehaviorConfig config,
+                                          uint64_t random_seed = 1) override;
   EmulatedNetworkNode* CreateEmulatedNode(
       std::unique_ptr<NetworkBehaviorInterface> network_behavior) override;