More completely seed UUID::Random()

Generate enuogh randomness with std::random_device to fully seed the
internal state of an std::mt19937. This ensures that even the first
UUID::Random() call after boot has full entropy, so long as
`std::random_device` is non-deterministic.

Also, initialize the random number generator during AOS initialization.

Change-Id: Ie09d85f09f7969bcd47576a577b4415d39186233
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/uuid_collision_test.cc b/aos/uuid_collision_test.cc
index f06f6de..05bbccd 100644
--- a/aos/uuid_collision_test.cc
+++ b/aos/uuid_collision_test.cc
@@ -24,5 +24,21 @@
     uuids.insert(uuid);
   }
 }
+
+// Tests that our random seed generation for the mt19937 does not trivially
+// collide.
+TEST(UUIDTest, SeedInitializationTest) {
+  std::uniform_int_distribution<uint64_t> distribution(0);
+  std::set<uint64_t> values;
+  // This test takes significantly longer than the above due to needing to query
+  // std::random_device substantially. However, covering a range of 2 ** 18
+  // should readily catch things if we are accidentally using 32-bit seeds.
+  for (size_t ii = 0; ii < (1UL << 18); ++ii) {
+    std::mt19937 twister = internal::FullySeededRandomGenerator();
+    const uint64_t value = distribution(twister);
+    ASSERT_FALSE(values.count(value) > 0) << ii;
+    values.insert(value);
+  }
+}
 }  // namespace testing
 }  // namespace aos