Bug 1313470 - Part 2: Convert TestCOMPtr to a gtest. r=froydnj
☠☠ backed out by 561b87e98ada ☠ ☠
authorEric Rahm <erahm@mozilla.com>
Thu, 03 Nov 2016 17:55:25 -0700
changeset 320846 00f7b342bb29c4f26c7e78fade11b631054aadc4
parent 320845 f012923cfd8b903bc342910ec81cff508624906a
child 320847 5d82bc9436abbb89a05ae727027a78f5e9492fec
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
bugs1313470
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 1313470 - Part 2: Convert TestCOMPtr to a gtest. r=froydnj MozReview-Commit-ID: HfcLTmvkRc8
testing/cppunittest.ini
xpcom/tests/TestCOMPtr.cpp
xpcom/tests/gtest/TestCOMPtr.cpp
xpcom/tests/gtest/moz.build
xpcom/tests/moz.build
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -6,17 +6,16 @@
 [TestAudioBuffers]
 skip-if = os == 'b2g'  # Bug 1062937
 [TestAudioMixer]
 [TestBinarySearch]
 [TestBind]
 [TestBloomFilter]
 [TestCOM]
 skip-if = os != 'win'
-[TestCOMPtr]
 [TestCOMPtrEq]
 [TestCSPParser]
 skip-if = os == 'b2g' || (os == 'android' && debug) # Bug 1054246
 [TestCasting]
 [TestCeilingFloor]
 [TestCertDB]
 [TestCheckedInt]
 [TestCookie]
rename from xpcom/tests/TestCOMPtr.cpp
rename to xpcom/tests/gtest/TestCOMPtr.cpp
--- a/xpcom/tests/TestCOMPtr.cpp
+++ b/xpcom/tests/gtest/TestCOMPtr.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 <assert.h>
-#include <stdio.h>
 #include "nsCOMPtr.h"
-#include "nsISupports.h"
+#include "gtest/gtest.h"
+
 #include "mozilla/Unused.h"
 
 #define NS_IFOO_IID \
 { 0x6f7652e0,  0xee43, 0x11d1, \
   { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
 
 class IFoo : public nsISupports
 {
@@ -22,119 +21,65 @@ public:
   IFoo();
   // virtual dtor because IBar uses our Release()
   virtual ~IFoo();
 
   NS_IMETHOD_(MozExternalRefCountType) AddRef();
   NS_IMETHOD_(MozExternalRefCountType) Release();
   NS_IMETHOD QueryInterface( const nsIID&, void** );
 
-  static void print_totals();
-
-private:
   unsigned int refcount_;
 
-  static unsigned int total_constructions_;
-  static unsigned int total_destructions_;
+  static int total_constructions_;
+  static int total_destructions_;
+  static int total_queries_;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(IFoo, NS_IFOO_IID)
 
-class IBar;
-
-// some types I'll need
-typedef unsigned long NS_RESULT;
-
-// some functions I'll need (and define below)
-nsresult  CreateIFoo( void** );
-nsresult  CreateIBar( void** result );
-void  AnIFooPtrPtrContext( IFoo** );
-void	AnISupportsPtrPtrContext( nsISupports** );
-void  AVoidPtrPtrContext( void** );
-void  set_a_IFoo( nsCOMPtr<IFoo>* result );
-nsCOMPtr<IFoo>  return_a_IFoo();
-
-
-
-
-unsigned int IFoo::total_constructions_;
-unsigned int IFoo::total_destructions_;
-
-class test_message
-{
-  public:
-    test_message()
-    {
-      printf("BEGIN unit tests for |nsCOMPtr|, compiled " __DATE__ "\n");
-    }
-
-    ~test_message()
-    {
-      IFoo::print_totals();
-      printf("END unit tests for |nsCOMPtr|.\n");
-    }
-};
-
-test_message gTestMessage;
-
-void
-IFoo::print_totals()
-{
-  printf("total constructions/destructions --> %d/%d\n", 
-      total_constructions_, total_destructions_);
-}
+int IFoo::total_constructions_;
+int IFoo::total_destructions_;
+int IFoo::total_queries_;
 
 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));
+  total_queries_++;
+
   nsISupports* rawPtr = 0;
   nsresult status = NS_OK;
 
   if ( aIID.Equals(NS_GET_IID(IFoo)) )
     rawPtr = this;
   else
   {
     nsID iid_of_ISupports = NS_ISUPPORTS_IID;
@@ -149,82 +94,76 @@ IFoo::QueryInterface( const nsIID& aIID,
 
   return status;
 }
 
 nsresult
 CreateIFoo( void** 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;
 }
 
 void
 set_a_IFoo( nsCOMPtr<IFoo>* result )
 {
-  printf(">>set_a_IFoo()\n");
-  assert(result);
-
   nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
   *result = foop;
-  printf("<<set_a_IFoo()\n");
 }
 
 nsCOMPtr<IFoo>
 return_a_IFoo()
 {
-  printf(">>return_a_IFoo()\n");
   nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
-  printf("<<return_a_IFoo()\n");
   return foop;
 }
 
-
-
-
 #define NS_IBAR_IID \
 { 0x6f7652e1,  0xee43, 0x11d1, \
   { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
 
 class IBar : public IFoo
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IBAR_IID)
 
 public:
   IBar();
   virtual ~IBar();
 
   NS_IMETHOD QueryInterface( const nsIID&, void** );
+
+  static int total_destructions_;
+  static int total_queries_;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(IBar, NS_IBAR_IID)
 
+int IBar::total_destructions_;
+int IBar::total_queries_;
+
 IBar::IBar()
 {
-  printf("  new IBar@%p\n", static_cast<void*>(this));
 }
 
 IBar::~IBar()
 {
-  printf("IBar@%p::~IBar()\n", static_cast<void*>(this));
+  total_destructions_++;
 }
 
 nsresult
 IBar::QueryInterface( const nsID& aIID, void** aResult )
 {
-  printf("IBar@%p::QueryInterface()\n", static_cast<void*>(this));
+  total_queries_++;
+
   nsISupports* rawPtr = 0;
   nsresult status = NS_OK;
 
   if ( aIID.Equals(NS_GET_IID(IBar)) )
     rawPtr = this;
   else if ( aIID.Equals(NS_GET_IID(IFoo)) )
     rawPtr = static_cast<IFoo*>(this);
   else
@@ -243,24 +182,21 @@ IBar::QueryInterface( const nsID& aIID, 
 }
 
 
 
 nsresult
 CreateIBar( void** result )
   // a typical factory function (that calls AddRef)
 {
-  printf(">>CreateIBar() --> ");
   IBar* barp = new IBar;
-  printf("IBar@%p\n", static_cast<void*>(barp));
 
   barp->AddRef();
   *result = barp;
 
-  printf("<<CreateIBar()\n");
   return NS_OK;
 }
 
 void
 AnIFooPtrPtrContext( IFoo** )
 {
 }
 
@@ -269,288 +205,255 @@ AVoidPtrPtrContext( void** )
 {
 }
 
 void
 AnISupportsPtrPtrContext( nsISupports** )
 {
 }
 
-static
-nsresult
-TestBloat_Raw_Unsafe()
+TEST(COMPtr, Bloat_Raw_Unsafe)
 {
+  // ER: I'm not sure what this is testing...
   IBar* barP = 0;
-  nsresult result = CreateIBar(reinterpret_cast<void**>(&barP));
+  nsresult rv = CreateIBar(reinterpret_cast<void**>(&barP));
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_TRUE(barP);
 
-  if ( barP )
-  {
-    IFoo* fooP = 0;
-    if ( NS_SUCCEEDED( result = barP->QueryInterface(NS_GET_IID(IFoo), reinterpret_cast<void**>(&fooP)) ) )
-    {
-      fooP->print_totals();
-      NS_RELEASE(fooP);
-    }
+  IFoo* fooP = 0;
+  rv = barP->QueryInterface(NS_GET_IID(IFoo), reinterpret_cast<void**>(&fooP));
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_TRUE(fooP);
 
-    NS_RELEASE(barP);
-  }
-
-  return result;
+  NS_RELEASE(fooP);
+  NS_RELEASE(barP);
 }
 
-
-static
-nsresult
-TestBloat_Smart()
+TEST(COMPtr, Bloat_Smart)
 {
+  // ER: I'm not sure what this is testing...
   nsCOMPtr<IBar> barP;
-  nsresult result = CreateIBar( getter_AddRefs(barP) );
-
-  nsCOMPtr<IFoo> fooP( do_QueryInterface(barP, &result) );
+  nsresult rv = CreateIBar( getter_AddRefs(barP) );
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_TRUE(barP);
 
-  if ( fooP )
-    fooP->print_totals();
-
-  return result;
+  nsCOMPtr<IFoo> fooP( do_QueryInterface(barP, &rv) );
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_TRUE(fooP);
 }
 
-void AddRefAndRelease()
+TEST(COMPtr, AddRefAndRelease)
 {
+  IFoo::total_constructions_ = 0;
+  IFoo::total_destructions_ = 0;
+  IBar::total_destructions_ = 0;
+
   {
-    printf("\n### Test  1: will a |nsCOMPtr| call |AddRef| on a pointer assigned into it?\n");
     nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
+    ASSERT_EQ(foop->refcount_, (unsigned int)1);
+    ASSERT_EQ(IFoo::total_constructions_, 1);
+    ASSERT_EQ(IFoo::total_destructions_, 0);
 
-    printf("\n### Test  2: will a |nsCOMPtr| |Release| its old pointer when a new one is assigned in?\n");
     foop = do_QueryInterface(new IFoo);
+    ASSERT_EQ(foop->refcount_, (unsigned int)1);
+    ASSERT_EQ(IFoo::total_constructions_, 2);
+    ASSERT_EQ(IFoo::total_destructions_, 1);
 
     // [Shouldn't compile] Is it a compile time error to try to |AddRef| by hand?
     //foop->AddRef();
 
     // [Shouldn't compile] Is it a compile time error to try to |Release| be hand?
     //foop->Release();
 
     // [Shouldn't compile] Is it a compile time error to try to |delete| an |nsCOMPtr|?
     //delete foop;
 
-    printf("\n### Test  3: can you |AddRef| if you must?\n");
     static_cast<IFoo*>(foop)->AddRef();
+    ASSERT_EQ(foop->refcount_, (unsigned int)2);
+    ASSERT_EQ(IFoo::total_constructions_, 2);
+    ASSERT_EQ(IFoo::total_destructions_, 1);
 
-    printf("\n### Test  4: can you |Release| if you must?\n");
     static_cast<IFoo*>(foop)->Release();
-
-    printf("\n### Test  5: will a |nsCOMPtr| |Release| when it goes out of scope?\n");
+    ASSERT_EQ(foop->refcount_, (unsigned int)1);
+    ASSERT_EQ(IFoo::total_constructions_, 2);
+    ASSERT_EQ(IFoo::total_destructions_, 1);
   }
 
+  ASSERT_EQ(IFoo::total_constructions_, 2);
+  ASSERT_EQ(IFoo::total_destructions_, 2);
+
   {
-    printf("\n### Test  6: will a |nsCOMPtr| call the correct destructor?\n");
     nsCOMPtr<IFoo> foop( do_QueryInterface(new IBar) );
     mozilla::Unused << foop;
   }
+
+  ASSERT_EQ(IBar::total_destructions_, 1);
 }
 
 void Comparison()
 {
-  {
-    printf("\n### Test  7: can you compare one |nsCOMPtr| with another [!=]?\n");
-
-    nsCOMPtr<IFoo> foo1p( do_QueryInterface(new IFoo) );
+  IFoo::total_constructions_ = 0;
+  IFoo::total_destructions_ = 0;
 
-    // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
-    //AnIFooPtrPtrContext(&foo1p);
-
-    // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
-    //AVoidPtrPtrContext(&foo1p);
-
+  {
+    nsCOMPtr<IFoo> foo1p( do_QueryInterface(new IFoo) );
     nsCOMPtr<IFoo> foo2p( do_QueryInterface(new IFoo) );
 
-    if ( foo1p != foo2p )
-      printf("foo1p != foo2p\n");
-    else
-      printf("foo1p == foo2p\n");
-
-
-    IFoo* raw_foo2p = foo2p.get();
+    ASSERT_EQ(IFoo::total_constructions_, 2);
 
-    printf("\n### Test  8: can you compare a |nsCOMPtr| with a raw interface pointer [!=]?\n");
-    if ( foo1p.get() != raw_foo2p )
-      printf("foo1p != raw_foo2p\n");
-    else
-      printf("foo1p == raw_foo2p\n");
+    // Test != operator
+    ASSERT_NE(foo1p, foo2p);
+    ASSERT_NE(foo1p, foo2p.get());
 
-
-    printf("\n### Test  9: can you assign one |nsCOMPtr| into another?\n");
+    // Test == operator
     foo1p = foo2p;
 
-    printf("\n### Test 10: can you compare one |nsCOMPtr| with another [==]?\n");
-    if ( foo1p == foo2p )
-      printf("foo1p == foo2p\n");
-    else
-      printf("foo1p != foo2p\n");
+    ASSERT_EQ(IFoo::total_destructions_, 1);
 
-    printf("\n### Test 11: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
-    if ( raw_foo2p == foo2p.get() )
-      printf("raw_foo2p == foo2p\n");
-    else
-      printf("raw_foo2p != foo2p\n");
+    ASSERT_EQ(foo1p, foo2p);
+    ASSERT_EQ(foo2p, foo2p.get());
+    ASSERT_EQ(foo2p.get(), foo2p);
 
-#if 1
-    printf("\n### Test 11.5: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
-    if ( nsCOMPtr<IFoo>( raw_foo2p ) == foo2p )
-      printf("raw_foo2p == foo2p\n");
-    else
-      printf("raw_foo2p != foo2p\n");
-#endif
+    // Test () operator
+    ASSERT_TRUE(foo1p);
 
-    printf("\n### Test 12: bare pointer test?\n");
-    if ( foo1p )
-      printf("foo1p is not NULL\n");
-    else
-      printf("foo1p is NULL\n");
+    ASSERT_EQ(foo1p->refcount_, (unsigned int)2);
+    ASSERT_EQ(foo2p->refcount_, (unsigned int)2);
+  }
 
-#if 0
-    if ( foo1p == 1 )
-      printf("foo1p allowed compare with in\n");
-#endif
-
-    printf("\n### Test 13: how about when two |nsCOMPtr|s referring to the same object go out of scope?\n");
-  }
+  ASSERT_EQ(IFoo::total_destructions_, 2);
 }
 
 void DontAddRef()
 {
   {
-    printf("\n### Test 14,15 ...setup...\n");
     IFoo* raw_foo1p = new IFoo;
     raw_foo1p->AddRef();
 
     IFoo* raw_foo2p = new IFoo;
     raw_foo2p->AddRef();
 
-    printf("\n### Test 14: what if I don't want to |AddRef| when I construct?\n");
     nsCOMPtr<IFoo> foo1p( dont_AddRef(raw_foo1p) );
-    //nsCOMPtr<IFoo> foo1p = dont_AddRef(raw_foo1p);
+    ASSERT_EQ(raw_foo1p, foo1p);
+    ASSERT_EQ(foo1p->refcount_, (unsigned int)1);
 
-    printf("\n### Test 15: what if I don't want to |AddRef| when I assign in?\n");
     nsCOMPtr<IFoo> foo2p;
     foo2p = dont_AddRef(raw_foo2p);
+    ASSERT_EQ(raw_foo2p, foo2p);
+    ASSERT_EQ(foo2p->refcount_, (unsigned int)1);
   }
 }
 
-void AssignmentHelpers()
+TEST(COMPtr, AssignmentHelpers)
 {
-  {
-    printf("\n### setup for Test 16\n");
-    nsCOMPtr<IFoo> foop;
-    printf("### Test 16: basic parameter behavior?\n");
-    CreateIFoo( nsGetterAddRefs<IFoo>(foop) );
-  }
-  printf("### End Test 16\n");
-
+  IFoo::total_constructions_ = 0;
+  IFoo::total_destructions_ = 0;
 
   {
-    printf("\n### setup for Test 17\n");
     nsCOMPtr<IFoo> foop;
-    printf("### Test 17: basic parameter behavior, using the short form?\n");
+    ASSERT_FALSE(foop);
+    CreateIFoo( nsGetterAddRefs<IFoo>(foop) );
+    ASSERT_TRUE(foop);
+  }
+
+  ASSERT_EQ(IFoo::total_constructions_, 1);
+  ASSERT_EQ(IFoo::total_destructions_, 1);
+
+  {
+    nsCOMPtr<IFoo> foop;
+    ASSERT_FALSE(foop);
     CreateIFoo( getter_AddRefs(foop) );
+    ASSERT_TRUE(foop);
   }
-  printf("### End Test 17\n");
 
+  ASSERT_EQ(IFoo::total_constructions_, 2);
+  ASSERT_EQ(IFoo::total_destructions_, 2);
 
   {
-    printf("\n### setup for Test 18, 19\n");
     nsCOMPtr<IFoo> foop;
-    printf("### Test 18: reference parameter behavior?\n");
+    ASSERT_FALSE(foop);
     set_a_IFoo(address_of(foop));
+    ASSERT_TRUE(foop);
+
+    ASSERT_EQ(IFoo::total_constructions_, 3);
+    ASSERT_EQ(IFoo::total_destructions_, 2);
 
-    printf("### Test 19: return value behavior?\n");
     foop = return_a_IFoo();
+    ASSERT_TRUE(foop);
+
+    ASSERT_EQ(IFoo::total_constructions_, 4);
+    ASSERT_EQ(IFoo::total_destructions_, 3);
   }
-  printf("### End Test 18, 19\n");
+
+  ASSERT_EQ(IFoo::total_constructions_, 4);
+  ASSERT_EQ(IFoo::total_destructions_, 4);
 
   {
-    printf("\n### setup for Test 23\n");
     nsCOMPtr<IFoo> fooP( do_QueryInterface(new IFoo) );
+    ASSERT_TRUE(fooP);
+
+    ASSERT_EQ(IFoo::total_constructions_, 5);
+    ASSERT_EQ(IFoo::total_destructions_, 4);
 
-    printf("### Test 23: does |forget| avoid an AddRef/Release when assigning to another nsCOMPtr?\n");
     nsCOMPtr<IFoo> fooP2( fooP.forget() );
+    ASSERT_TRUE(fooP2);
+
+    ASSERT_EQ(IFoo::total_constructions_, 5);
+    ASSERT_EQ(IFoo::total_destructions_, 4);
   }
-  printf("### End Test 23\n");
+
+  ASSERT_EQ(IFoo::total_constructions_, 5);
+  ASSERT_EQ(IFoo::total_destructions_, 5);
 }
 
-void QueryInterface()
+TEST(COMPtr, QueryInterface)
 {
-  {
-    printf("\n### setup for Test 20\n");
-    nsCOMPtr<IFoo> fooP;
-
-    printf("### Test 20: is |QueryInterface| called on assigning in a raw pointer?\n");
-    fooP = do_QueryInterface(new IFoo);
-  }
-  printf("### End Test 20\n");
+  IFoo::total_queries_ = 0;
+  IBar::total_queries_ = 0;
 
   {
-    printf("\n### setup for Test 21\n");
     nsCOMPtr<IFoo> fooP;
+    ASSERT_FALSE(fooP);
     fooP = do_QueryInterface(new IFoo);
+    ASSERT_TRUE(fooP);
+    ASSERT_EQ(IFoo::total_queries_, 1);
 
     nsCOMPtr<IFoo> foo2P;
 
-    printf("### Test 21: is |QueryInterface| _not_ called when assigning in a smart-pointer of the same type?\n");
+    // Test that |QueryInterface| _not_ called when assigning a smart-pointer
+    // of the same type.);
     foo2P = fooP;
+    ASSERT_EQ(IFoo::total_queries_, 1);
   }
-  printf("### End Test 21\n");
 
   {
-    printf("\n### setup for Test 22\n");
     nsCOMPtr<IBar> barP( do_QueryInterface(new IBar) );
-
-    printf("### Test 22: is |QueryInterface| called when assigning in a smart-pointer of a different type?\n");
+    ASSERT_EQ(IBar::total_queries_, 1);
 
+    // Test that |QueryInterface| is called when assigning a smart-pointer of
+    // a different type.
     nsCOMPtr<IFoo> fooP( do_QueryInterface(barP) );
-    if ( fooP )
-      printf("an IBar* is an IFoo*\n");
+    ASSERT_EQ(IBar::total_queries_, 2);
+    ASSERT_EQ(IFoo::total_queries_, 1);
+    ASSERT_TRUE(fooP);
   }
-  printf("### End Test 22\n");
 }
 
-void GetterConversions()
+TEST(COMPtr, GetterConversions)
 {
+  // This is just a compilation test. We add a few asserts to keep gtest happy.
   {
     nsCOMPtr<IFoo> fooP;
+    ASSERT_FALSE(fooP);
 
     AnIFooPtrPtrContext( getter_AddRefs(fooP) );
     AVoidPtrPtrContext( getter_AddRefs(fooP) );
   }
 
 
   {
     nsCOMPtr<nsISupports> supportsP;
+    ASSERT_FALSE(supportsP);
 
     AVoidPtrPtrContext( getter_AddRefs(supportsP) );
     AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
   }
 }
-
-nsCOMPtr<IFoo> gFoop;
-
-int
-main()
-{
-  printf(">>main()\n");
-
-  printf("sizeof(nsCOMPtr<IFoo>) --> %u\n", unsigned(sizeof(nsCOMPtr<IFoo>)));
-
-  TestBloat_Raw_Unsafe();
-  TestBloat_Smart();
-
-  AddRefAndRelease();
-  Comparison();
-  DontAddRef();
-  AssignmentHelpers();
-  QueryInterface();
-  GetterConversions();
-
-  printf("\n### Test 24: will a static |nsCOMPtr| |Release| before program termination?\n");
-  gFoop = do_QueryInterface(new IFoo);
-
-  printf("<<main()\n");
-  return 0;
-}
--- a/xpcom/tests/gtest/moz.build
+++ b/xpcom/tests/gtest/moz.build
@@ -34,15 +34,16 @@ UNIFIED_SOURCES += [
     'TestUTF.cpp',
     '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
 ]
 
 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([
-    'TestCOMPtr',
     'TestCOMPtrEq',
     'TestFile',
     'TestHashtables',
     'TestID',
     'TestNsRefPtr',
     'TestObserverArray',
     'TestObserverService',
     'TestStringAPI',