From 6d33ae5d7a54e544358e6290752e329c419e4eb6 Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Sat, 12 Jul 2008 16:27:27 -0500 Subject: [PATCH] Bug 397227 - "Reduce the effort needed to write C++ tests" [r=ted/luser] --- config/rules.mk | 177 ++++++++++-------- content/base/test/Makefile.in | 15 -- .../base/test/TestNativeXMLHttpRequest.cpp | 22 +-- content/base/test/TestPlainTextSerializer.cpp | 15 +- xpcom/tests/Makefile.in | 123 +++++------- xpcom/tests/TestPipe.cpp | 22 +-- xpcom/tests/TestTextFormatter.cpp | 50 +++-- 7 files changed, 198 insertions(+), 226 deletions(-) diff --git a/config/rules.mk b/config/rules.mk index 9350702ffada..cc042ebb1624 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -117,6 +117,104 @@ ifdef EXTRA_DSO_LIBS EXTRA_DSO_LIBS := $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS)) endif +################################################################################ +# Testing frameworks support +################################################################################ + +ifdef ENABLE_TESTS + +ifdef XPCSHELL_TESTS +ifndef MODULE +$(error Must define MODULE when defining XPCSHELL_TESTS.) +endif + +# Test file installation +libs:: + @$(EXIT_ON_ERROR) \ + for testdir in $(XPCSHELL_TESTS); do \ + $(INSTALL) \ + $(srcdir)/$$testdir/*.js \ + $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir; \ + done + +# Path formats on Windows are hard. We require a topsrcdir formatted so that +# it may be passed to nsILocalFile.initWithPath (in other words, an absolute +# path of the form X:\path\to\topsrcdir), which we store in NATIVE_TOPSRCDIR. +# We require a forward-slashed path to topsrcdir so that it may be combined +# with a relative forward-slashed path for loading scripts, both dynamically +# and statically for head/test/tail JS files. Of course, on non-Windows none +# of this matters, and things will work correctly because everything's +# forward-slashed, everywhere, always. +ifdef CYGWIN_WRAPPER +NATIVE_TOPSRCDIR := `cygpath -wa $(topsrcdir)` +FWDSLASH_TOPSRCDIR := `cygpath -ma $(topsrcdir)` +else +FWDSLASH_TOPSRCDIR := $(topsrcdir) +ifeq ($(HOST_OS_ARCH),WINNT) +NATIVE_TOPSRCDIR := $(subst /,\\,$(WIN_TOP_SRC)) +else +NATIVE_TOPSRCDIR := $(topsrcdir) +endif +endif # CYGWIN_WRAPPER + +# Test execution +check:: + @$(EXIT_ON_ERROR) \ + for testdir in $(XPCSHELL_TESTS); do \ + $(RUN_TEST_PROGRAM) \ + $(topsrcdir)/tools/test-harness/xpcshell-simple/test_all.sh \ + $(DIST)/bin/xpcshell \ + $(FWDSLASH_TOPSRCDIR) \ + $(NATIVE_TOPSRCDIR) \ + $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir; \ + done + +# Test execution +check-interactive:: + @$(EXIT_ON_ERROR) \ + $(RUN_TEST_PROGRAM) \ + $(topsrcdir)/tools/test-harness/xpcshell-simple/test_one.sh \ + $(DIST)/bin/xpcshell \ + $(FWDSLASH_TOPSRCDIR) \ + $(NATIVE_TOPSRCDIR) \ + $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir \ + $(SOLO_FILE) 1; + +# Test execution +check-one:: + @$(EXIT_ON_ERROR) \ + $(RUN_TEST_PROGRAM) \ + $(topsrcdir)/tools/test-harness/xpcshell-simple/test_one.sh \ + $(DIST)/bin/xpcshell \ + $(FWDSLASH_TOPSRCDIR) \ + $(NATIVE_TOPSRCDIR) \ + $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir \ + $(SOLO_FILE) 0; + +endif # XPCSHELL_TESTS + +ifdef CPP_UNIT_TESTS + +# Compile the tests to $(DIST)/bin. Make lots of niceties available by default +# through TestHarness.h, by modifying the list of includes and the libs against +# which stuff links. +CPPSRCS += $(CPP_UNIT_TESTS) +SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX)) +REQUIRES += testing xpcom +LIBS += $(XPCOM_LIBS) $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS) + +# ...and run them the usual way +check:: + @$(EXIT_ON_ERROR) \ + for f in $(subst .cpp,,$(CPP_UNIT_TESTS)); do \ + XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \ + done + +endif # CPP_UNIT_TESTS + +endif # ENABLE_TESTS + + # # Library rules # @@ -1888,85 +1986,6 @@ REGCHROME_INSTALL = $(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/add-ch $(_JAR_REGCHROME_DISABLE_JAR) -################################################################################ -# Testing frameworks support -################################################################################ - -ifdef ENABLE_TESTS - -ifdef XPCSHELL_TESTS -ifndef MODULE -$(error Must define MODULE when defining XPCSHELL_TESTS.) -endif - -# Test file installation -libs:: - @$(EXIT_ON_ERROR) \ - for testdir in $(XPCSHELL_TESTS); do \ - $(INSTALL) \ - $(srcdir)/$$testdir/*.js \ - $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir; \ - done - -# Path formats on Windows are hard. We require a topsrcdir formatted so that -# it may be passed to nsILocalFile.initWithPath (in other words, an absolute -# path of the form X:\path\to\topsrcdir), which we store in NATIVE_TOPSRCDIR. -# We require a forward-slashed path to topsrcdir so that it may be combined -# with a relative forward-slashed path for loading scripts, both dynamically -# and statically for head/test/tail JS files. Of course, on non-Windows none -# of this matters, and things will work correctly because everything's -# forward-slashed, everywhere, always. -ifdef CYGWIN_WRAPPER -NATIVE_TOPSRCDIR := `cygpath -wa $(topsrcdir)` -FWDSLASH_TOPSRCDIR := `cygpath -ma $(topsrcdir)` -else -FWDSLASH_TOPSRCDIR := $(topsrcdir) -ifeq ($(HOST_OS_ARCH),WINNT) -NATIVE_TOPSRCDIR := $(subst /,\\,$(WIN_TOP_SRC)) -else -NATIVE_TOPSRCDIR := $(topsrcdir) -endif -endif # CYGWIN_WRAPPER - -# Test execution -check:: - @$(EXIT_ON_ERROR) \ - for testdir in $(XPCSHELL_TESTS); do \ - $(RUN_TEST_PROGRAM) \ - $(topsrcdir)/tools/test-harness/xpcshell-simple/test_all.sh \ - $(DIST)/bin/xpcshell \ - $(FWDSLASH_TOPSRCDIR) \ - $(NATIVE_TOPSRCDIR) \ - $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir; \ - done - -# Test execution -check-interactive:: - @$(EXIT_ON_ERROR) \ - $(RUN_TEST_PROGRAM) \ - $(topsrcdir)/tools/test-harness/xpcshell-simple/test_one.sh \ - $(DIST)/bin/xpcshell \ - $(FWDSLASH_TOPSRCDIR) \ - $(NATIVE_TOPSRCDIR) \ - $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir \ - $(SOLO_FILE) 1; - -# Test execution -check-one:: - @$(EXIT_ON_ERROR) \ - $(RUN_TEST_PROGRAM) \ - $(topsrcdir)/tools/test-harness/xpcshell-simple/test_one.sh \ - $(DIST)/bin/xpcshell \ - $(FWDSLASH_TOPSRCDIR) \ - $(NATIVE_TOPSRCDIR) \ - $(DEPTH)/_tests/xpcshell-simple/$(MODULE)/$$testdir \ - $(SOLO_FILE) 0; - -endif # XPCSHELL_TESTS - -endif # ENABLE_TESTS - - ############################################################################# # Dependency system ############################################################################# diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 395b4ab42ee9..2c7b17e4966d 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -63,15 +63,6 @@ REQUIRES += \ htmlparser \ $(NULL) -CPPSRCS += $(CPP_UNIT_TESTS) - -SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX)) - -LIBS += \ - $(XPCOM_GLUE_LDOPTS) \ - $(NSPR_LIBS) \ - $(NULL) - include $(topsrcdir)/config/rules.mk _TEST_FILES = test_bug5141.html \ @@ -188,9 +179,3 @@ _TEST_FILES = test_bug5141.html \ libs:: $(_TEST_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) - -check:: - @$(EXIT_ON_ERROR) \ - for f in $(subst .cpp,,$(CPP_UNIT_TESTS)); do \ - XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \ - done diff --git a/content/base/test/TestNativeXMLHttpRequest.cpp b/content/base/test/TestNativeXMLHttpRequest.cpp index 98915ccc195c..dda68a67ea94 100644 --- a/content/base/test/TestNativeXMLHttpRequest.cpp +++ b/content/base/test/TestNativeXMLHttpRequest.cpp @@ -41,22 +41,12 @@ #include "nsIScriptSecurityManager.h" #include "nsIXMLHttpRequest.h" -#include "nsServiceManagerUtils.h" -#include "nsStringGlue.h" - -#define REPORT_ERROR(_msg) \ - printf("FAIL " _msg "\n") - -#define TEST_FAIL(_msg) \ - PR_BEGIN_MACRO \ - REPORT_ERROR(_msg); \ - return NS_ERROR_FAILURE; \ - PR_END_MACRO #define TEST_ENSURE_BASE(_test, _msg) \ PR_BEGIN_MACRO \ if (_test) { \ - TEST_FAIL(_msg); \ + fail(_msg); \ + return NS_ERROR_FAILURE; \ } \ PR_END_MACRO @@ -113,7 +103,8 @@ nsresult TestNativeXMLHttpRequest() TEST_ENSURE_SUCCESS(rv, "GetResponse failed!"); if (!response.EqualsLiteral(TEST_URL_CONTENT)) { - TEST_FAIL("Response text does not match!"); + fail("Response text does not match!"); + return NS_ERROR_FAILURE; } nsCOMPtr dom; @@ -121,10 +112,11 @@ nsresult TestNativeXMLHttpRequest() TEST_ENSURE_SUCCESS(rv, "GetResponseXML failed!"); if (!dom) { - TEST_FAIL("No DOM document constructed!"); + fail("No DOM document constructed!"); + return NS_ERROR_FAILURE; } - printf("Native XMLHttpRequest PASSED!\n"); + passed("Native XMLHttpRequest"); return NS_OK; } diff --git a/content/base/test/TestPlainTextSerializer.cpp b/content/base/test/TestPlainTextSerializer.cpp index 065cfc98fda2..62c354c05f08 100644 --- a/content/base/test/TestPlainTextSerializer.cpp +++ b/content/base/test/TestPlainTextSerializer.cpp @@ -46,15 +46,6 @@ #include "nsStringGlue.h" #include "nsParserCIID.h" -#define REPORT_ERROR(_msg) \ - printf("FAIL " _msg "\n") - -#define TEST_FAIL(_msg) \ - PR_BEGIN_MACRO \ - REPORT_ERROR(_msg); \ - return NS_ERROR_FAILURE; \ - PR_END_MACRO - static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID); void @@ -85,9 +76,11 @@ TestPlainTextSerializer() "body"); ConvertBufToPlainText(test); if (!test.EqualsLiteral("basespanbody")) { - TEST_FAIL("Wrong html to text serialization"); + fail("Wrong html to text serialization"); + return NS_ERROR_FAILURE; } - printf("HTML to text serialization test PASSED!\n"); + + passed("HTML to text serialization test"); // Add new tests here... return NS_OK; diff --git a/xpcom/tests/Makefile.in b/xpcom/tests/Makefile.in index c41e13b4ada3..dd8a79c8fa59 100644 --- a/xpcom/tests/Makefile.in +++ b/xpcom/tests/Makefile.in @@ -65,61 +65,64 @@ CPPSRCS = \ nsIFileEnumerator.cpp \ nsIFileTest.cpp \ TestCallTemplates.cpp \ - TestCOMPtr.cpp \ - TestCOMPtrEq.cpp \ - TestFactory.cpp \ - TestHashtables.cpp \ - TestID.cpp \ TestINIParser.cpp \ - TestObserverService.cpp \ - TestServMgr.cpp \ - TestAutoPtr.cpp \ TestVersionComparator.cpp \ - TestTextFormatter.cpp \ - TestPipe.cpp \ TestRegistrationOrder.cpp \ - TestProxies.cpp \ $(NULL) ifndef MOZ_ENABLE_LIBXUL CPPSRCS += \ - TestArray.cpp \ - TestTArray.cpp \ TestAtoms.cpp \ - TestAutoLock.cpp \ - TestCRT.cpp \ - TestEncoding.cpp \ TestPermanentAtoms.cpp \ - TestPipes.cpp \ - TestThreads.cpp \ - TestThreadPool.cpp \ - TestXPIDLString.cpp \ - TestDeque.cpp \ - TestStrings.cpp \ - TestStorageStream.cpp \ - TestExpirationTracker.cpp \ $(NULL) endif +SIMPLE_PROGRAMS := $(CPPSRCS:.cpp=$(BIN_SUFFIX)) + +CPP_UNIT_TESTS = \ + TestAutoPtr.cpp \ + TestCOMPtr.cpp \ + TestCOMPtrEq.cpp \ + TestFactory.cpp \ + TestHashtables.cpp \ + TestID.cpp \ + TestObserverService.cpp \ + TestPipe.cpp \ + TestServMgr.cpp \ + TestTextFormatter.cpp \ + $(NULL) + +ifndef MOZ_ENABLE_LIBXUL +CPP_UNIT_TESTS += \ + TestArray.cpp \ + TestAutoLock.cpp \ + TestCRT.cpp \ + TestEncoding.cpp \ + TestExpirationTracker.cpp \ + TestPipes.cpp \ + TestProxies.cpp \ + TestThreads.cpp \ + TestThreadPool.cpp \ + TestXPIDLString.cpp \ + TestDeque.cpp \ + TestStrings.cpp \ + TestStorageStream.cpp \ + TestTArray.cpp \ + $(NULL) +endif + ifndef MOZILLA_INTERNAL_API -CPPSRCS += \ - TestStringAPI.cpp \ - $(NULL) +CPP_UNIT_TESTS += \ + TestStringAPI.cpp \ + $(NULL) endif -SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX)) - include $(topsrcdir)/config/config.mk ifndef MOZILLA_INTERNAL_API LIBS += $(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) endif -LIBS += \ - $(XPCOM_LIBS) \ - $(NSPR_LIBS) \ - $(NULL) - # Needed to resolve __yylex (?) ifeq ($(OS_ARCH)$(OS_RELEASE),FreeBSD2) LIBS += -lpcap @@ -129,44 +132,6 @@ ENABLE_CXX_EXCEPTIONS = 1 XPCSHELL_TESTS = unit -CPP_UNIT_TESTS = \ - TestAutoPtr \ - TestCOMPtr \ - TestCOMPtrEq \ - TestFactory \ - TestHashtables \ - TestID \ - TestObserverService \ - TestPipe \ - TestServMgr \ - TestTextFormatter \ - $(NULL) - -ifndef MOZ_ENABLE_LIBXUL -CPP_UNIT_TESTS += \ - TestArray \ - TestAutoLock \ - TestCRT \ - TestEncoding \ - TestExpirationTracker \ - TestPipes \ - TestProxies \ - TestThreads \ - TestThreadPool \ - TestXPIDLString \ - TestDeque \ - TestStrings \ - TestStorageStream \ - TestTArray \ - $(NULL) -endif - -ifndef MOZILLA_INTERNAL_API -CPP_UNIT_TESTS += \ - TestStringAPI \ - $(NULL) -endif - include $(topsrcdir)/config/rules.mk LOCAL_INCLUDES = \ @@ -177,6 +142,12 @@ LOCAL_INCLUDES = \ libs:: $(INSTALL) $(srcdir)/test.properties $(DIST)/bin/res +# Copy TestHarness.h into its own module, for ease of setting up includes +# correctly. +export:: + $(NSINSTALL) -D $(DIST)/include/testing + $(INSTALL) $(srcdir)/TestHarness.h $(DIST)/include/testing + install:: $(SYSINSTALL) $(IFLAGS1) $(srcdir)/test.properties $(DESTDIR)$(mozappdir)/res @@ -192,14 +163,6 @@ abs_srcdir = $(shell cd $(srcdir) && pwd) check:: @echo "Running TestVersionComparator tests" @$(PERL) -w $(srcdir)/TestVersionComparatorRunner.pl "$(RUN_TEST_PROGRAM) $(FINAL_TARGET)/TestVersionComparator$(BIN_SUFFIX)" - @echo "Running nsTextFormatter tests" - @$(RUN_TEST_PROGRAM) $(FINAL_TARGET)/TestTextFormatter$(BIN_SUFFIX) - @$(EXIT_ON_ERROR) \ - for f in $(CPP_UNIT_TESTS); do \ - echo Running $$f; \ - XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \ - echo Finished running $$f; \ - done @echo "Running XPIDL tests" $(XPIDL_COMPILE) -m header $(srcdir)/TestScriptable.idl @if grep Notscriptable TestScriptable.h | grep -q NS_SCRIPTABLE ; then \ diff --git a/xpcom/tests/TestPipe.cpp b/xpcom/tests/TestPipe.cpp index 65100818c539..8229d01cc245 100644 --- a/xpcom/tests/TestPipe.cpp +++ b/xpcom/tests/TestPipe.cpp @@ -113,14 +113,14 @@ nsresult BackwardsAllocator::Init(PRUint32 count, size_t size) { if (mMemory) { - printf("FAIL allocator already initialized!\n"); + fail("allocator already initialized!"); return NS_ERROR_ALREADY_INITIALIZED; } mMemory = new PRUint8[count * size + count]; if (!mMemory) { - printf("FAIL failed to allocate mMemory!\n"); + fail("failed to allocate mMemory!"); return NS_ERROR_OUT_OF_MEMORY; } memset(mMemory, 0, count * size + count); @@ -188,7 +188,7 @@ nsresult TestBackwardsAllocator() nsRefPtr allocator = new BackwardsAllocator(); if (!allocator) { - printf("Allocation of BackwardsAllocator failed!\n"); + fail("Allocation of BackwardsAllocator failed!"); return NS_ERROR_OUT_OF_MEMORY; } nsresult rv = allocator->Init(SEGMENT_COUNT, SEGMENT_SIZE); @@ -204,7 +204,7 @@ nsresult TestBackwardsAllocator() SEGMENT_SIZE, SEGMENT_COUNT, allocator); if (NS_FAILED(rv)) { - printf("FAIL NS_NewPipe2 failed: %x\n", rv); + fail("NS_NewPipe2 failed: %x", rv); return rv; } @@ -222,7 +222,7 @@ nsresult TestBackwardsAllocator() "9123456789"; // not just a memset, to ensure the allocator works correctly if (sizeof(written) < BUFFER_LENGTH) { - printf("FAIL test error with string size\n"); + fail("test error with string size"); return NS_ERROR_FAILURE; } @@ -230,8 +230,8 @@ nsresult TestBackwardsAllocator() rv = output->Write(written, BUFFER_LENGTH, &writeCount); if (NS_FAILED(rv) || writeCount != BUFFER_LENGTH) { - printf("FAIL writing %d bytes (wrote %d bytes) to output failed: %x\n", - BUFFER_LENGTH, writeCount, rv); + fail("writing %d bytes (wrote %d bytes) to output failed: %x", + BUFFER_LENGTH, writeCount, rv); return rv; } @@ -240,18 +240,18 @@ nsresult TestBackwardsAllocator() rv = input->Read(read, BUFFER_LENGTH, &readCount); if (NS_FAILED(rv) || readCount != BUFFER_LENGTH) { - printf("FAIL reading %d bytes (got %d bytes) from input failed: %x\n", - BUFFER_LENGTH, readCount, rv); + fail("reading %d bytes (got %d bytes) from input failed: %x", + BUFFER_LENGTH, readCount, rv); return rv; } if (0 != memcmp(written, read, BUFFER_LENGTH)) { - printf("FAIL didn't read the written data correctly!\n"); + fail("didn't read the written data correctly!"); return NS_ERROR_FAILURE; } - printf("TestBackwardsAllocator PASSED!\n"); + passed("TestBackwardsAllocator"); return NS_OK; } diff --git a/xpcom/tests/TestTextFormatter.cpp b/xpcom/tests/TestTextFormatter.cpp index 1d29be7402f6..1ac67cd323fd 100644 --- a/xpcom/tests/TestTextFormatter.cpp +++ b/xpcom/tests/TestTextFormatter.cpp @@ -36,33 +36,53 @@ * * ***** END LICENSE BLOCK ***** */ +#include "TestHarness.h" + #include -#include -#include - -int main() -{ - int test_ok = true; +nsresult TestSnprintf() +{ nsAutoString fmt(NS_LITERAL_STRING("%3$s %4$S %1$d %2$d")); char utf8[] = "Hello"; - PRUnichar ucs2[]={'W', 'o', 'r', 'l', 'd', 0x4e00, 0xAc00, 0xFF45, 0x0103, 0x00}; - int d=3; + PRUnichar ucs2[] = {'W', 'o', 'r', 'l', 'd', 0x4e00, 0xAc00, 0xFF45, 0x0103, 0x00}; + int d = 3; PRUnichar buf[256]; nsTextFormatter::snprintf(buf, 256, fmt.get(), d, 333, utf8, ucs2); nsAutoString out(buf); - if(strcmp("Hello World", NS_LossyConvertUTF16toASCII(out).get())) - test_ok = false; + if (strcmp("Hello World", NS_LossyConvertUTF16toASCII(out).get())) + { + fail("Unexpected string created by nsTextFormatter::snprintf!"); + return NS_ERROR_FAILURE; + } - const PRUnichar *uout = out.get(); const PRUnichar expected[] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x4E00, 0xAC00, 0xFF45, 0x0103, 0x20, 0x33, 0x20, 0x33, 0x33, 0x33}; - for(PRUint32 i=0;i