Bug 1313473 - Part 2: Convert XPCOM test TestHashtables to a gtest. r=froydnj
☠☠ backed out by 561b87e98ada ☠ ☠
authorEric Rahm <erahm@mozilla.com>
Mon, 31 Oct 2016 16:58:42 -0700
changeset 320852 e8d20bdd13d447998e73974644d42787afe2dc43
parent 320851 643bdd25166eef38dafe3428eca0a2b0c2e62946
child 320853 5b5686e1bcd1a736f9d6f48f29122c8bd5148501
push id83473
push usererahm@mozilla.com
push dateFri, 04 Nov 2016 00:56:12 +0000
treeherdermozilla-inbound@5b5686e1bcd1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1313473
milestone52.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 1313473 - Part 2: Convert XPCOM test TestHashtables to a gtest. r=froydnj MozReview-Commit-ID: DTOeKiesYBP
testing/cppunittest.ini
xpcom/tests/TestHashtables.cpp
xpcom/tests/gtest/TestHashtables.cpp
xpcom/tests/gtest/moz.build
xpcom/tests/moz.build
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -28,17 +28,16 @@ skip-if = os != 'win'
 [TestEndian]
 [TestEnumeratedArray]
 [TestEnumSet]
 [TestEnumTypeTraits]
 [TestFastBernoulliTrial]
 [TestFloatingPoint]
 [TestFunction]
 [TestGetURL]
-[TestHashtables]
 [TestID]
 [TestIntegerPrintfMacros]
 [TestIntegerRange]
 [TestIsCertBuiltInRoot]
 [TestJSONWriter]
 [TestJemalloc]
 [TestLinkedList]
 [TestMacroArgs]
rename from xpcom/tests/TestHashtables.cpp
rename to xpcom/tests/gtest/TestHashtables.cpp
--- a/xpcom/tests/TestHashtables.cpp
+++ b/xpcom/tests/gtest/TestHashtables.cpp
@@ -10,32 +10,30 @@
 #include "nsInterfaceHashtable.h"
 #include "nsClassHashtable.h"
 
 #include "nsCOMPtr.h"
 #include "nsISupports.h"
 #include "nsCOMArray.h"
 #include "mozilla/Attributes.h"
 
-#include <stdio.h>
+#include "gtest/gtest.h"
 
 namespace TestHashtables {
 
 class TestUniChar // for nsClassHashtable
 {
 public:
   explicit TestUniChar(uint32_t aWord)
   {
-    printf("    TestUniChar::TestUniChar() %u\n", aWord);
     mWord = aWord;
   }
 
   ~TestUniChar()
   {
-    printf("    TestUniChar::~TestUniChar() %u\n", mWord);
   }
 
   uint32_t GetChar() const { return mWord; }
 
 private:
   uint32_t mWord;
 };
 
@@ -83,96 +81,59 @@ public:
   const EntityNode* mNode;
 };
 
 static uint32_t
 nsTIterPrint(nsTHashtable<EntityToUnicodeEntry>& hash)
 {
   uint32_t n = 0;
   for (auto iter = hash.Iter(); !iter.Done(); iter.Next()) {
-    EntityToUnicodeEntry* entry = iter.Get();
-    printf("  enumerated \"%s\" = %u\n",
-           entry->mNode->mStr, entry->mNode->mUnicode);
     n++;
   }
   return n;
 }
 
 static uint32_t
 nsTIterPrintRemove(nsTHashtable<EntityToUnicodeEntry>& hash)
 {
   uint32_t n = 0;
   for (auto iter = hash.Iter(); !iter.Done(); iter.Next()) {
-    EntityToUnicodeEntry* entry = iter.Get();
-    printf("  enumerated \"%s\" = %u\n",
-           entry->mNode->mStr, entry->mNode->mUnicode);
     iter.Remove();
     n++;
   }
   return n;
 }
 
 void
 testTHashtable(nsTHashtable<EntityToUnicodeEntry>& hash, uint32_t numEntries) {
-  printf("Filling hash with %d entries.\n", numEntries);
-
   uint32_t i;
   for (i = 0; i < numEntries; ++i) {
-    printf("  Putting entry \"%s\"...", gEntities[i].mStr);
     EntityToUnicodeEntry* entry =
       hash.PutEntry(gEntities[i].mStr);
 
-    if (!entry) {
-      printf("FAILED\n");
-      exit (2);
-    }
-    printf("OK...");
+    EXPECT_TRUE(entry);
 
-    if (entry->mNode) {
-      printf("entry already exists!\n");
-      exit (3);
-    }
-    printf("\n");
-
+    EXPECT_FALSE(entry->mNode);
     entry->mNode = &gEntities[i];
   }
 
-  printf("Testing Get:\n");
-
   for (i = 0; i < numEntries; ++i) {
-    printf("  Getting entry \"%s\"...", gEntities[i].mStr);
     EntityToUnicodeEntry* entry =
       hash.GetEntry(gEntities[i].mStr);
 
-    if (!entry) {
-      printf("FAILED\n");
-      exit (4);
-    }
-
-    printf("Found %u\n", entry->mNode->mUnicode);
+    EXPECT_TRUE(entry);
   }
 
-  printf("Testing nonexistent entries...");
-
   EntityToUnicodeEntry* entry =
     hash.GetEntry("xxxy");
 
-  if (entry) {
-    printf("FOUND! BAD!\n");
-    exit (5);
-  }
-
-  printf("not found; good.\n");
+  EXPECT_FALSE(entry);
 
-  printf("Enumerating:\n");
   uint32_t count = nsTIterPrint(hash);
-  if (count != numEntries) {
-    printf("  Bad count!\n");
-    exit (6);
-  }
+  EXPECT_EQ(count, numEntries);
 }
 
 //
 // all this nsIFoo stuff was copied wholesale from TestCOMPtr.cpp
 //
 
 #define NS_IFOO_IID \
 { 0x6f7652e0,  0xee43, 0x11d1, \
@@ -207,68 +168,51 @@ class IFoo final : public nsISupports
 NS_DEFINE_STATIC_IID_ACCESSOR(IFoo, NS_IFOO_IID)
 
 unsigned int IFoo::total_constructions_;
 unsigned int IFoo::total_destructions_;
 
 void
 IFoo::print_totals()
   {
-    printf("total constructions/destructions --> %d/%d\n",
-           total_constructions_, total_destructions_);
   }
 
 IFoo::IFoo()
     : refcount_(0)
   {
     ++total_constructions_;
-    printf("  new IFoo@%p [#%d]\n",
-           static_cast<void*>(this), total_constructions_);
   }
 
 IFoo::~IFoo()
   {
     ++total_destructions_;
-    printf("IFoo@%p::~IFoo() [#%d]\n",
-           static_cast<void*>(this), total_destructions_);
   }
 
 MozExternalRefCountType
 IFoo::AddRef()
   {
     ++refcount_;
-    printf("IFoo@%p::AddRef(), refcount --> %d\n", 
-           static_cast<void*>(this), refcount_);
     return refcount_;
   }
 
 MozExternalRefCountType
 IFoo::Release()
   {
     int newcount = --refcount_;
     if ( newcount == 0 )
-      printf(">>");
-
-    printf("IFoo@%p::Release(), refcount --> %d\n",
-           static_cast<void*>(this), refcount_);
-
-    if ( newcount == 0 )
       {
-        printf("  delete IFoo@%p\n", static_cast<void*>(this));
-        printf("<<IFoo@%p::Release()\n", static_cast<void*>(this));
         delete this;
       }
 
     return newcount;
   }
 
 nsresult
 IFoo::QueryInterface( const nsIID& aIID, void** aResult )
   {
-    printf("IFoo@%p::QueryInterface()\n", static_cast<void*>(this));
     nsISupports* rawPtr = 0;
     nsresult status = NS_OK;
 
     if ( aIID.Equals(NS_GET_IID(IFoo)) )
       rawPtr = this;
     else
       {
         nsID iid_of_ISupports = NS_ISUPPORTS_IID;
@@ -297,382 +241,195 @@ IFoo::GetString(nsACString& aString)
   aString = mString;
   return NS_OK;
 }
 
 nsresult
 CreateIFoo( IFoo** result )
     // a typical factory function (that calls AddRef)
   {
-    printf("    >>CreateIFoo() --> ");
     IFoo* foop = new IFoo();
-    printf("IFoo@%p\n", static_cast<void*>(foop));
 
     foop->AddRef();
     *result = foop;
 
-    printf("<<CreateIFoo()\n");
     return NS_OK;
   }
 
 } // namespace TestHashtables
 
 using namespace TestHashtables;
 
-void THashtable()
+TEST(Hashtable, THashtable)
 {
   // check an nsTHashtable
-  printf("Initializing nsTHashtable...");
   nsTHashtable<EntityToUnicodeEntry> EntityToUnicode(ENTITY_COUNT);
-  printf("OK\n");
 
-  printf("Partially filling nsTHashtable:\n");
   testTHashtable(EntityToUnicode, 5);
 
-  printf("Enumerate-removing...\n");
   uint32_t count = nsTIterPrintRemove(EntityToUnicode);
-  if (count != 5) {
-    printf("wrong count\n");
-    exit (7);
-  }
-  printf("OK\n");
+  ASSERT_EQ(count, uint32_t(5));
 
-  printf("Check enumeration...");
   count = nsTIterPrint(EntityToUnicode);
-  if (count != 0) {
-    printf("entries remain in table!\n");
-    exit (8);
-  }
-  printf("OK\n");
+  ASSERT_EQ(count, uint32_t(0));
 
-  printf("Filling nsTHashtable:\n");
   testTHashtable(EntityToUnicode, ENTITY_COUNT);
 
-  printf("Clearing...");
   EntityToUnicode.Clear();
-  printf("OK\n");
 
-  printf("Check enumeration...");
   count = nsTIterPrint(EntityToUnicode);
-  if (count != 0) {
-    printf("entries remain in table!\n");
-    exit (9);
-  }
-  printf("OK\n");
+  ASSERT_EQ(count, uint32_t(0));
 }
 
-void DataHashtable()
+TEST(Hashtables, DataHashtable)
 {
-  //
-  // now check a data-hashtable
-  //
-
-  printf("Initializing nsDataHashtable...");
+  // check a data-hashtable
   nsDataHashtable<nsUint32HashKey,const char*> UniToEntity(ENTITY_COUNT);
-  printf("OK\n");
-
-  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
 
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Putting entry %u...", gEntities[i].mUnicode);
     UniToEntity.Put(gEntities[i].mUnicode, gEntities[i].mStr);
-    printf("OK...\n");
   }
 
-  printf("Testing Get:\n");
   const char* str;
 
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Getting entry %u...", gEntities[i].mUnicode);
-    if (!UniToEntity.Get(gEntities[i].mUnicode, &str)) {
-      printf("FAILED\n");
-      exit (12);
-    }
-
-    printf("Found %s\n", str);
+    ASSERT_TRUE(UniToEntity.Get(gEntities[i].mUnicode, &str));
   }
 
-  printf("Testing nonexistent entries...");
-  if (UniToEntity.Get(99446, &str)) {
-    printf("FOUND! BAD!\n");
-    exit (13);
-  }
-
-  printf("not found; good.\n");
-
-  printf("Enumerating:\n");
+  ASSERT_FALSE(UniToEntity.Get(99446, &str));
 
   uint32_t count = 0;
   for (auto iter = UniToEntity.Iter(); !iter.Done(); iter.Next()) {
-    printf("  enumerated %u = \"%s\"\n", iter.Key(), iter.UserData());
     count++;
   }
-  if (count != ENTITY_COUNT) {
-    printf("  Bad count!\n");
-    exit (14);
-  }
+  ASSERT_EQ(count, ENTITY_COUNT);
 
-  printf("Clearing...");
   UniToEntity.Clear();
-  printf("OK\n");
 
-  printf("Checking count...");
   count = 0;
   for (auto iter = UniToEntity.Iter(); !iter.Done(); iter.Next()) {
     printf("  enumerated %u = \"%s\"\n", iter.Key(), iter.Data());
     count++;
   }
-  if (count != 0) {
-    printf("  Clear did not remove all entries.\n");
-    exit (15);
-  }
-
-  printf("OK\n");
+  ASSERT_EQ(count, uint32_t(0));
 }
 
-void ClassHashtable()
+TEST(Hashtables, ClassHashtable)
 {
-  //
-  // now check a class-hashtable
-  //
-
-  printf("Initializing nsClassHashtable...");
+  // check a class-hashtable
   nsClassHashtable<nsCStringHashKey,TestUniChar> EntToUniClass(ENTITY_COUNT);
-  printf("OK\n");
-
-  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
 
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Putting entry %u...", gEntities[i].mUnicode);
     TestUniChar* temp = new TestUniChar(gEntities[i].mUnicode);
-
     EntToUniClass.Put(nsDependentCString(gEntities[i].mStr), temp);
-    printf("OK...\n");
   }
 
-  printf("Testing Get:\n");
   TestUniChar* myChar;
 
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Getting entry %s...", gEntities[i].mStr);
-    if (!EntToUniClass.Get(nsDependentCString(gEntities[i].mStr), &myChar)) {
-      printf("FAILED\n");
-      exit (18);
-    }
-
-    printf("Found %c\n", myChar->GetChar());
+    ASSERT_TRUE(EntToUniClass.Get(nsDependentCString(gEntities[i].mStr), &myChar));
   }
 
-  printf("Testing nonexistent entries...");
-  if (EntToUniClass.Get(NS_LITERAL_CSTRING("xxxx"), &myChar)) {
-    printf("FOUND! BAD!\n");
-    exit (19);
-  }
-
-  printf("not found; good.\n");
-
-  printf("Enumerating:\n");
+  ASSERT_FALSE(EntToUniClass.Get(NS_LITERAL_CSTRING("xxxx"), &myChar));
 
   uint32_t count = 0;
   for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
-    printf("  enumerated \"%s\" = %c\n",
-           PromiseFlatCString(iter.Key()).get(), iter.UserData()->GetChar());
-    count++;
-  }
-  if (count != ENTITY_COUNT) {
-    printf("  Bad count!\n");
-    exit (20);
-  }
-
-  printf("Clearing...\n");
-  EntToUniClass.Clear();
-  printf("  Clearing OK\n");
-
-  printf("Checking count...");
-  count = 0;
-  for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
-    printf("  enumerated \"%s\" = %c\n",
-           PromiseFlatCString(iter.Key()).get(), iter.Data()->GetChar());
     count++;
   }
-  if (count != 0) {
-    printf("  Clear did not remove all entries.\n");
-    exit (21);
+  ASSERT_EQ(count, ENTITY_COUNT);
+
+  EntToUniClass.Clear();
+
+  count = 0;
+  for (auto iter = EntToUniClass.Iter(); !iter.Done(); iter.Next()) {
+    count++;
   }
-
-  printf("OK\n");
+  ASSERT_EQ(count, uint32_t(0));
 }
 
-void DataHashtableWithInterfaceKey()
+TEST(Hashtables, DataHashtableWithInterfaceKey)
 {
-  //
-  // now check a data-hashtable with an interface key
-  //
-
-  printf("Initializing nsDataHashtable with interface key...");
+  // check a data-hashtable with an interface key
   nsDataHashtable<nsISupportsHashKey,uint32_t> EntToUniClass2(ENTITY_COUNT);
-  printf("OK\n");
-
-  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
 
   nsCOMArray<IFoo> fooArray;
 
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Putting entry %u...", gEntities[i].mUnicode);
     nsCOMPtr<IFoo> foo;
     CreateIFoo(getter_AddRefs(foo));
     foo->SetString(nsDependentCString(gEntities[i].mStr));
 
     fooArray.InsertObjectAt(foo, i);
 
     EntToUniClass2.Put(foo, gEntities[i].mUnicode);
-    printf("OK...\n");
   }
 
-  printf("Testing Get:\n");
   uint32_t myChar2;
 
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Getting entry %s...", gEntities[i].mStr);
-
-    if (!EntToUniClass2.Get(fooArray[i], &myChar2)) {
-      printf("FAILED\n");
-      exit (24);
-    }
-
-    printf("Found %c\n", myChar2);
+    ASSERT_TRUE(EntToUniClass2.Get(fooArray[i], &myChar2));
   }
 
-  printf("Testing nonexistent entries...");
-  if (EntToUniClass2.Get((nsISupports*) 0x55443316, &myChar2)) {
-    printf("FOUND! BAD!\n");
-    exit (25);
-  }
-
-  printf("not found; good.\n");
-
-  printf("Enumerating:\n");
+  ASSERT_FALSE(EntToUniClass2.Get((nsISupports*) 0x55443316, &myChar2));
 
   uint32_t count = 0;
   for (auto iter = EntToUniClass2.Iter(); !iter.Done(); iter.Next()) {
     nsAutoCString s;
     nsCOMPtr<IFoo> foo = do_QueryInterface(iter.Key());
     foo->GetString(s);
-    printf("  enumerated \"%s\" = %u\n", s.get(), iter.UserData());
     count++;
   }
-  if (count != ENTITY_COUNT) {
-    printf("  Bad count!\n");
-    exit (26);
-  }
+  ASSERT_EQ(count, ENTITY_COUNT);
 
-  printf("Clearing...\n");
   EntToUniClass2.Clear();
-  printf("  Clearing OK\n");
 
-  printf("Checking count...");
   count = 0;
   for (auto iter = EntToUniClass2.Iter(); !iter.Done(); iter.Next()) {
     nsAutoCString s;
     nsCOMPtr<IFoo> foo = do_QueryInterface(iter.Key());
     foo->GetString(s);
-    printf("  enumerated \"%s\" = %u\n", s.get(), iter.Data());
     count++;
   }
-  if (count != 0) {
-    printf("  Clear did not remove all entries.\n");
-    exit (27);
-  }
-
-  printf("OK\n");
+  ASSERT_EQ(count, uint32_t(0));
 }
 
-void InterfaceHashtable()
+TEST(Hashtables, InterfaceHashtable)
 {
-  //
-  // now check an interface-hashtable with an uint32_t key
-  //
-
-  printf("Initializing nsInterfaceHashtable...");
+  // check an interface-hashtable with an uint32_t key
   nsInterfaceHashtable<nsUint32HashKey,IFoo> UniToEntClass2(ENTITY_COUNT);
-  printf("OK\n");
-
-  printf("Filling hash with %u entries.\n", ENTITY_COUNT);
 
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Putting entry %u...", gEntities[i].mUnicode);
     nsCOMPtr<IFoo> foo;
     CreateIFoo(getter_AddRefs(foo));
     foo->SetString(nsDependentCString(gEntities[i].mStr));
 
     UniToEntClass2.Put(gEntities[i].mUnicode, foo);
-    printf("OK...\n");
   }
 
-  printf("Testing Get:\n");
-
   for (uint32_t i = 0; i < ENTITY_COUNT; ++i) {
-    printf("  Getting entry %s...", gEntities[i].mStr);
-
     nsCOMPtr<IFoo> myEnt;
-    if (!UniToEntClass2.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
-      printf("FAILED\n");
-      exit (30);
-    }
+    ASSERT_TRUE(UniToEntClass2.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt)));
 
     nsAutoCString myEntStr;
     myEnt->GetString(myEntStr);
-    printf("Found %s\n", myEntStr.get());
   }
 
-  printf("Testing nonexistent entries...");
   nsCOMPtr<IFoo> myEnt;
-  if (UniToEntClass2.Get(9462, getter_AddRefs(myEnt))) {
-    printf("FOUND! BAD!\n");
-    exit (31);
-  }
-
-  printf("not found; good.\n");
-
-  printf("Enumerating:\n");
+  ASSERT_FALSE(UniToEntClass2.Get(9462, getter_AddRefs(myEnt)));
 
   uint32_t count = 0;
   for (auto iter = UniToEntClass2.Iter(); !iter.Done(); iter.Next()) {
     nsAutoCString s;
     iter.UserData()->GetString(s);
-    printf("  enumerated %u = \"%s\"\n", iter.Key(), s.get());
     count++;
   }
-  if (count != ENTITY_COUNT) {
-    printf("  Bad count!\n");
-    exit (32);
-  }
+  ASSERT_EQ(count, ENTITY_COUNT);
 
-  printf("Clearing...\n");
   UniToEntClass2.Clear();
-  printf("  Clearing OK\n");
 
-  printf("Checking count...");
   count = 0;
   for (auto iter = UniToEntClass2.Iter(); !iter.Done(); iter.Next()) {
     nsAutoCString s;
     iter.Data()->GetString(s);
-    printf("  enumerated %u = \"%s\"\n", iter.Key(), s.get());
     count++;
   }
-  if (count != 0) {
-    printf("  Clear did not remove all entries.\n");
-    exit (33);
-  }
-
-  printf("OK\n");
+  ASSERT_EQ(count, uint32_t(0));
 }
-
-int
-main(void) {
-  THashtable();
-  DataHashtable();
-  ClassHashtable();
-  DataHashtableWithInterfaceKey();
-  InterfaceHashtable();
-
-  return 0;
-}
--- a/xpcom/tests/gtest/moz.build
+++ b/xpcom/tests/gtest/moz.build
@@ -37,15 +37,16 @@ UNIFIED_SOURCES += [
     'TestXPIDLString.cpp',
 ]
 
 # Compile TestAllocReplacement separately so Windows headers don't pollute
 # the global namespace for other files.
 SOURCES += [
     'TestAllocReplacement.cpp',
     'TestCOMPtr.cpp', # Redefines IFoo and IBar
+    'TestHashtables.cpp', # Redefines IFoo
 ]
 
 LOCAL_INCLUDES += [
     '../../base',
 ]
 
 FINAL_LIBRARY = 'xul-gtest'
--- a/xpcom/tests/moz.build
+++ b/xpcom/tests/moz.build
@@ -41,17 +41,16 @@ if CONFIG['OS_TARGET'] == 'WINNT':
 if CONFIG['WRAP_STL_INCLUDES'] and not CONFIG['CLANG_CL']:
     GeckoSimplePrograms([
         'TestSTLWrappers',
     ])
 
 XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
 
 GeckoCppUnitTests([
-    'TestHashtables',
     'TestID',
     'TestNsRefPtr',
     'TestObserverArray',
     'TestObserverService',
     'TestStringAPI',
     'TestTArray',
     'TestTextFormatter',
     'TestThreadUtils',