Bug 1180084 - Convert TestPLDHash.cpp to a gtest. r=froydnj.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 07 Jul 2015 17:54:03 -0700
changeset 251833 40740cddc1315f7c527a62042e86b9bcace3193d
parent 251832 b94026e3296fefb08d098b4763bad3ad46f1c49f
child 251834 694521589eb069ddc72fb1cc46c7e1bd1f39bd92
push id61971
push usernnethercote@mozilla.com
push dateWed, 08 Jul 2015 01:29:00 +0000
treeherdermozilla-inbound@40740cddc131 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1180084
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1180084 - Convert TestPLDHash.cpp to a gtest. r=froydnj. The switch to unsigned integer constants (e.g. "0u") are necessary to avoid compiler warnings about signed/unsigned comparisons.
xpcom/tests/TestPLDHash.cpp
xpcom/tests/gtest/TestPLDHash.cpp
xpcom/tests/gtest/moz.build
xpcom/tests/moz.build
rename from xpcom/tests/TestPLDHash.cpp
rename to xpcom/tests/gtest/TestPLDHash.cpp
--- a/xpcom/tests/TestPLDHash.cpp
+++ b/xpcom/tests/gtest/TestPLDHash.cpp
@@ -1,90 +1,69 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include <stdio.h>
 #include "pldhash.h"
+#include "gtest/gtest.h"
 
 // This test mostly focuses on edge cases. But more coverage of normal
 // operations wouldn't be a bad thing.
 
-namespace TestPLDHash {
-
-static bool test_pldhash_Init_capacity_ok()
+TEST(PLDHashTableTest, InitCapacityOk)
 {
   // Try the largest allowed capacity.  With PL_DHASH_MAX_CAPACITY==1<<26, this
   // would allocate (if we added an element) 0.5GB of entry store on 32-bit
   // platforms and 1GB on 64-bit platforms.
   //
   // Ideally we'd also try (a) a too-large capacity, and (b) a large capacity
   // combined with a large entry size that when multipled overflow. But those
   // cases would cause the test to abort immediately.
   //
   // Furthermore, ideally we'd also try a large-but-ok capacity that almost but
   // doesn't quite overflow, but that would result in allocating just under 4GB
   // of entry storage.  That's very likely to fail on 32-bit platforms, so such
   // a test wouldn't be reliable.
   //
   PLDHashTable t(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub),
                  PL_DHASH_MAX_INITIAL_LENGTH);
-
-  return true;
 }
 
-static bool test_pldhash_lazy_storage()
+TEST(PLDHashTableTest, LazyStorage)
 {
   PLDHashTable t(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub));
 
   // PLDHashTable allocates entry storage lazily. Check that all the non-add
   // operations work appropriately when the table is empty and the storage
   // hasn't yet been allocated.
 
-  if (t.Capacity() != 0) {
-    return false;
-  }
-
-  if (t.EntrySize() != sizeof(PLDHashEntryStub)) {
-    return false;
-  }
+  ASSERT_EQ(t.Capacity(), 0u);
+  ASSERT_EQ(t.EntrySize(), sizeof(PLDHashEntryStub));
+  ASSERT_EQ(t.EntryCount(), 0u);
+  ASSERT_EQ(t.Generation(), 0u);
 
-  if (t.EntryCount() != 0) {
-    return false;
-  }
-
-  if (t.Generation() != 0) {
-    return false;
-  }
-
-  if (PL_DHashTableSearch(&t, (const void*)1)) {
-    return false;   // search succeeded?
-  }
+  ASSERT_TRUE(!PL_DHashTableSearch(&t, (const void*)1));
 
   // No result to check here, but call it to make sure it doesn't crash.
   PL_DHashTableRemove(&t, (const void*)2);
 
   for (auto iter = t.Iter(); !iter.Done(); iter.Next()) {
-    return false; // shouldn't hit this on an empty table
+    ASSERT_TRUE(false); // shouldn't hit this on an empty table
   }
 
   for (auto iter = t.RemovingIter(); !iter.Done(); iter.Next()) {
-    return false; // shouldn't hit this on an empty table
+    ASSERT_TRUE(false); // shouldn't hit this on an empty table
   }
 
   // Using a null |mallocSizeOf| should be fine because it shouldn't be called
   // for an empty table.
   mozilla::MallocSizeOf mallocSizeOf = nullptr;
-  if (PL_DHashTableSizeOfExcludingThis(&t, nullptr, mallocSizeOf) != 0) {
-    return false;   // size is non-zero?
-  }
-
-  return true;
+  ASSERT_EQ(PL_DHashTableSizeOfExcludingThis(&t, nullptr, mallocSizeOf), 0u);
 }
 
 // A trivial hash function is good enough here. It's also super-fast for
 // test_pldhash_grow_to_max_capacity() because we insert the integers 0..,
 // which means it's collision-free.
 static PLDHashNumber
 TrivialHash(PLDHashTable *table, const void *key)
 {
@@ -101,17 +80,17 @@ TrivialInitEntry(PLDHashEntryHdr* aEntry
 static const PLDHashTableOps trivialOps = {
   TrivialHash,
   PL_DHashMatchEntryStub,
   PL_DHashMoveEntryStub,
   PL_DHashClearEntryStub,
   TrivialInitEntry
 };
 
-static bool test_pldhash_move_semantics()
+TEST(PLDHashTableTest, MoveSemantics)
 {
   PLDHashTable t1(&trivialOps, sizeof(PLDHashEntryStub));
   PL_DHashTableAdd(&t1, (const void*)88);
   PLDHashTable t2(&trivialOps, sizeof(PLDHashEntryStub));
   PL_DHashTableAdd(&t2, (const void*)99);
 
   t1 = mozilla::Move(t1);   // self-move
 
@@ -130,79 +109,63 @@ static bool test_pldhash_move_semantics(
   t5 = mozilla::Move(t6);   // empty overwritten with non-empty
 
   PLDHashTable t7(&trivialOps, sizeof(PLDHashEntryStub));
   PLDHashTable t8(mozilla::Move(t7));  // new table constructed with uninited
 
   PLDHashTable t9(&trivialOps, sizeof(PLDHashEntryStub));
   PL_DHashTableAdd(&t9, (const void*)88);
   PLDHashTable t10(mozilla::Move(t9));  // new table constructed with inited
-
-  return true;
 }
 
-static bool test_pldhash_Clear()
+TEST(PLDHashTableTest, Clear)
 {
   PLDHashTable t1(&trivialOps, sizeof(PLDHashEntryStub));
 
   t1.Clear();
-  if (t1.EntryCount() != 0) {
-    return false;
-  }
+  ASSERT_EQ(t1.EntryCount(), 0u);
 
   t1.ClearAndPrepareForLength(100);
-  if (t1.EntryCount() != 0) {
-    return false;
-  }
+  ASSERT_EQ(t1.EntryCount(), 0u);
 
   PL_DHashTableAdd(&t1, (const void*)77);
   PL_DHashTableAdd(&t1, (const void*)88);
   PL_DHashTableAdd(&t1, (const void*)99);
-  if (t1.EntryCount() != 3) {
-    return false;
-  }
+  ASSERT_EQ(t1.EntryCount(), 3u);
 
   t1.Clear();
-  if (t1.EntryCount() != 0) {
-    return false;
-  }
+  ASSERT_EQ(t1.EntryCount(), 0u);
 
   PL_DHashTableAdd(&t1, (const void*)55);
   PL_DHashTableAdd(&t1, (const void*)66);
   PL_DHashTableAdd(&t1, (const void*)77);
   PL_DHashTableAdd(&t1, (const void*)88);
   PL_DHashTableAdd(&t1, (const void*)99);
-  if (t1.EntryCount() != 5) {
-    return false;
-  }
+  ASSERT_EQ(t1.EntryCount(), 5u);
 
   t1.ClearAndPrepareForLength(8192);
-  if (t1.EntryCount() != 0) {
-    return false;
-  }
-
-  return true;
+  ASSERT_EQ(t1.EntryCount(), 0u);
 }
 
-static bool test_pldhash_Iterator()
+TEST(PLDHashTableIterator, Iterator)
 {
   PLDHashTable t(&trivialOps, sizeof(PLDHashEntryStub));
 
   // Explicitly test the move constructor. We do this because, due to copy
   // elision, compilers might optimize away move constructor calls for normal
   // iterator use.
   {
     PLDHashTable::Iterator iter1(&t);
     PLDHashTable::Iterator iter2(mozilla::Move(iter1));
   }
 
   // Iterate through the empty table.
   for (PLDHashTable::Iterator iter(&t); !iter.Done(); iter.Next()) {
     (void) iter.Get();
-    return false;   // shouldn't hit this
+    ASSERT_TRUE(false); // shouldn't hit this
   }
 
   // Add three entries.
   PL_DHashTableAdd(&t, (const void*)77);
   PL_DHashTableAdd(&t, (const void*)88);
   PL_DHashTableAdd(&t, (const void*)99);
 
   // Check the iterator goes through each entry once.
@@ -216,92 +179,82 @@ static bool test_pldhash_Iterator()
     if (entry->key == (const void*)88) {
       saw88 = true;
     }
     if (entry->key == (const void*)99) {
       saw99 = true;
     }
     n++;
   }
-  if (!saw77 || !saw88 || !saw99 || n != 3) {
-    return false;
-  }
-
-  return true;
+  ASSERT_TRUE(saw77 && saw88 && saw99 && n == 3);
 }
 
-static bool test_pldhash_RemovingIterator()
+TEST(PLDHashTableTest, RemovingIterator)
 {
   PLDHashTable t(&trivialOps, sizeof(PLDHashEntryStub));
 
   // Explicitly test the move constructor. We do this because, due to copy
   // elision, compilers might optimize away move constructor calls for normal
   // iterator use.
   {
     PLDHashTable::RemovingIterator iter1(&t);
     PLDHashTable::RemovingIterator iter2(mozilla::Move(iter1));
   }
 
   // First, we insert 64 items, which results in a capacity of 128, and a load
   // factor of 50%.
   for (intptr_t i = 0; i < 64; i++) {
     PL_DHashTableAdd(&t, (const void*)i);
   }
-  if (t.EntryCount() != 64 || t.Capacity() != 128) {
-    return false;
-  }
+  ASSERT_EQ(t.EntryCount(), 64u);
+  ASSERT_EQ(t.Capacity(), 128u);
 
   // The first removing iterator does no removing; capacity and entry count are
   // unchanged.
   for (PLDHashTable::RemovingIterator iter(&t); !iter.Done(); iter.Next()) {
     (void) iter.Get();
   }
-  if (t.EntryCount() != 64 || t.Capacity() != 128) {
-    return false;
-  }
+  ASSERT_EQ(t.EntryCount(), 64u);
+  ASSERT_EQ(t.Capacity(), 128u);
 
   // The second removing iterator removes 16 items. This reduces the load
   // factor to 37.5% (48 / 128), which isn't low enough to shrink the table.
   for (auto iter = t.RemovingIter(); !iter.Done(); iter.Next()) {
     auto entry = static_cast<PLDHashEntryStub*>(iter.Get());
     if ((intptr_t)(entry->key) % 4 == 0) {
       iter.Remove();
     }
   }
-  if (t.EntryCount() != 48 || t.Capacity() != 128) {
-    return false;
-  }
+  ASSERT_EQ(t.EntryCount(), 48u);
+  ASSERT_EQ(t.Capacity(), 128u);
 
   // The third removing iterator removes another 16 items. This reduces
   // the load factor to 25% (32 / 128), so the table is shrunk.
   for (auto iter = t.RemovingIter(); !iter.Done(); iter.Next()) {
     auto entry = static_cast<PLDHashEntryStub*>(iter.Get());
     if ((intptr_t)(entry->key) % 2 == 0) {
       iter.Remove();
     }
   }
-  if (t.EntryCount() != 32 || t.Capacity() != 64) {
-    return false;
-  }
+  ASSERT_EQ(t.EntryCount(), 32u);
+  ASSERT_EQ(t.Capacity(), 64u);
 
   // The fourth removing iterator removes all remaining items. This reduces
   // the capacity to the minimum.
   for (auto iter = t.RemovingIter(); !iter.Done(); iter.Next()) {
     iter.Remove();
   }
-  if (t.EntryCount() != 0 || t.Capacity() != PL_DHASH_MIN_CAPACITY) {
-    return false;
-  }
-
-  return true;
+  ASSERT_EQ(t.EntryCount(), 0u);
+  ASSERT_EQ(t.Capacity(), unsigned(PL_DHASH_MIN_CAPACITY));
 }
 
-// See bug 931062, we skip this test on Android due to OOM.
+// See bug 931062, we skip this test on Android due to OOM. Also, it's slow,
+// and so should always be last.
 #ifndef MOZ_WIDGET_ANDROID
-static bool test_pldhash_grow_to_max_capacity()
+TEST(PLDHashTableTest, GrowToMaxCapacity)
 {
   // This is infallible.
   PLDHashTable* t =
     new PLDHashTable(&trivialOps, sizeof(PLDHashEntryStub), 128);
 
   // Keep inserting elements until failure occurs because the table is full.
   size_t numInserted = 0;
   while (true) {
@@ -310,54 +263,15 @@ static bool test_pldhash_grow_to_max_cap
     }
     numInserted++;
   }
 
   // We stop when the element count is 96.875% of PL_DHASH_MAX_SIZE (see
   // MaxLoadOnGrowthFailure()).
   if (numInserted != PL_DHASH_MAX_CAPACITY - (PL_DHASH_MAX_CAPACITY >> 5)) {
     delete t;
-    return false;
+    ASSERT_TRUE(false);
   }
 
   delete t;
-  return true;
 }
 #endif
 
-//----
-
-typedef bool (*TestFunc)();
-#define DECL_TEST(name) { #name, name }
-
-static const struct Test {
-  const char* name;
-  TestFunc    func;
-} tests[] = {
-  DECL_TEST(test_pldhash_Init_capacity_ok),
-  DECL_TEST(test_pldhash_lazy_storage),
-  DECL_TEST(test_pldhash_move_semantics),
-  DECL_TEST(test_pldhash_Clear),
-  DECL_TEST(test_pldhash_Iterator),
-  DECL_TEST(test_pldhash_RemovingIterator),
-// See bug 931062, we skip this test on Android due to OOM. Also, it's slow,
-// and so should always be last.
-#ifndef MOZ_WIDGET_ANDROID
-  DECL_TEST(test_pldhash_grow_to_max_capacity),
-#endif
-  { nullptr, nullptr }
-};
-
-} // namespace TestPLDHash
-
-using namespace TestPLDHash;
-
-int main(int argc, char *argv[])
-{
-  bool success = true;
-  for (const Test* t = tests; t->name != nullptr; ++t) {
-    bool test_result = t->func();
-    printf("%35s : %s\n", t->name, test_result ? "SUCCESS" : "FAILURE");
-    if (!test_result)
-      success = false;
-  }
-  return success ? 0 : -1;
-}
--- a/xpcom/tests/gtest/moz.build
+++ b/xpcom/tests/gtest/moz.build
@@ -6,16 +6,17 @@
 
 UNIFIED_SOURCES += [
     'Helpers.cpp',
     'TestCloneInputStream.cpp',
     'TestCRT.cpp',
     'TestEncoding.cpp',
     'TestExpirationTracker.cpp',
     'TestPipes.cpp',
+    'TestPLDHash.cpp',
     'TestPriorityQueue.cpp',
     'TestSnappyStreams.cpp',
     'TestStorageStream.cpp',
     'TestStrings.cpp',
     'TestStringStream.cpp',
     'TestSynchronization.cpp',
     'TestTArray.cpp',
     'TestThreadPool.cpp',
--- a/xpcom/tests/moz.build
+++ b/xpcom/tests/moz.build
@@ -61,17 +61,16 @@ GeckoCppUnitTests([
     'TestDeque',
     'TestFile',
     'TestHashtables',
     'TestID',
     'TestNsRefPtr',
     'TestObserverArray',
     'TestObserverService',
     'TestPipe',
-    'TestPLDHash',
     'TestStringAPI',
     'TestTArray',
     'TestTextFormatter',
     'TestThreadUtils'
 ])
 
 if CONFIG['MOZ_MEMORY']:
     GeckoCppUnitTests([