bug 518126, part 2: add infrastructure for C++ tests of IPDL-generated code. r=ted,bsmedberg

This commit is contained in:
Chris Jones 2009-10-06 13:02:26 -05:00
parent fe26eff4e3
commit 826a18e082
26 changed files with 1142 additions and 20 deletions

View File

@ -104,7 +104,8 @@ MOZ_EXTENSIONS = @MOZ_EXTENSIONS@
MOZ_IMG_DECODERS= @MOZ_IMG_DECODERS@
MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@
MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@
MOZ_IPC = @MOZ_IPC@
MOZ_IPC = @MOZ_IPC@
MOZ_IPDL_TESTS = @MOZ_IPDL_TESTS@
MOZ_LEAKY = @MOZ_LEAKY@
MOZ_MEMORY = @MOZ_MEMORY@
MOZ_JPROF = @MOZ_JPROF@

View File

@ -5243,6 +5243,26 @@ fi
AC_SUBST(MOZ_IPC)
dnl ========================================================
dnl = Enable IPDL's "expensive" unit tests
dnl ========================================================
MOZ_IPDL_TESTS=
MOZ_ARG_ENABLE_BOOL(ipdl-tests,
[ --enable-ipdl-tests Enable expensive IPDL tests],
MOZ_IPDL_TESTS=1,
MOZ_IPDL_TESTS=)
if test -z "$MOZ_IPC" -a -n "$MOZ_IPDL_TESTS"; then
AC_MSG_ERROR([--enable-ipdl-tests requires --enable-ipc])
fi
if test -n "$MOZ_IPDL_TESTS"; then
AC_DEFINE(MOZ_IPDL_TESTS)
fi
AC_SUBST(MOZ_IPDL_TESTS)
dnl ========================================================
dnl = Disable plugin support
dnl ========================================================

View File

@ -40,18 +40,16 @@ srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS += test
include $(topsrcdir)/config/rules.mk
IPDLDIRS = \
dom/plugins \
dom/ipc \
netwerk/ipc \
netwerk/protocol/http/src \
ipc/test-harness \
ipc/testshell \
IPDLDIRS = \
dom/plugins \
dom/ipc \
netwerk/ipc \
netwerk/protocol/http/src \
ipc/ipdl/test/cxx \
ipc/test-harness \
ipc/testshell \
$(NULL)
vpath %.ipdl $(topsrcdir)

View File

@ -41,6 +41,12 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS += ipdl cxx
# we ignore MOZ_IPDL_TESTS for the IPDL-compiler-only tests, since they're
# quick and painless
DIRS += ipdl
ifdef MOZ_IPDL_TESTS
DIRS += cxx
endif
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,56 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla IPDL Test Harness.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "IPDLUnitTestSubprocess.h"
using mozilla::ipc::GeckoChildProcessHost;
namespace mozilla {
namespace _ipdltest {
IPDLUnitTestSubprocess::IPDLUnitTestSubprocess() :
GeckoChildProcessHost(GeckoProcessType_IPDLUnitTest)
{
}
IPDLUnitTestSubprocess::~IPDLUnitTestSubprocess()
{
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,70 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla IPDL Test Harness.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla__ipdltest_IPDLUnitTestTestSubprocess_h
#define mozilla__ipdltest_IPDLUnitTestTestSubprocess_h 1
#include "mozilla/ipc/GeckoChildProcessHost.h"
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
class IPDLUnitTestSubprocess : public mozilla::ipc::GeckoChildProcessHost
{
public:
IPDLUnitTestSubprocess();
~IPDLUnitTestSubprocess();
/**
* Asynchronously launch the plugin process.
*/
// Could override parent Launch, but don't need to here
//bool Launch();
private:
DISALLOW_EVIL_CONSTRUCTORS(IPDLUnitTestSubprocess);
};
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_IPDLUnitTestTestSubprocess_h

View File

@ -0,0 +1,72 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla IPC.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "IPDLUnitTestThreadChild.h"
#include "IPDLUnitTests.h"
using mozilla::ipc::GeckoThread;
namespace mozilla {
namespace _ipdltest {
IPDLUnitTestThreadChild::IPDLUnitTestThreadChild() :
GeckoThread()
{
}
IPDLUnitTestThreadChild::~IPDLUnitTestThreadChild()
{
}
void
IPDLUnitTestThreadChild::Init()
{
GeckoThread::Init();
IPDLUnitTestChildInit(channel(), owner_loop());
}
void
IPDLUnitTestThreadChild::CleanUp()
{
GeckoThread::CleanUp();
IPDLUnitTestChildCleanUp();
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,61 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla IPC.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla__ipdltest_IPDLUnitTestThreadChild_h
#define mozilla__ipdltest_IPDLUnitTestThreadChild_h 1
#include "mozilla/ipc/GeckoThread.h"
namespace mozilla {
namespace _ipdltest {
class IPDLUnitTestThreadChild : public mozilla::ipc::GeckoThread
{
public:
IPDLUnitTestThreadChild();
~IPDLUnitTestThreadChild();
protected:
virtual void Init();
virtual void CleanUp();
};
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_IPDLUnitTestThreadChild_h

View File

@ -0,0 +1,93 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla IPC.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Jones <jones.chris.g@gmail.com>.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla__ipdltest_IPDLUnitTests_h
#define mozilla__ipdltest_IPDLUnitTests_h 1
#include "base/message_loop.h"
#include "chrome/common/ipc_channel.h"
#define MOZ_IPDL_TESTFAIL_LABEL "TEST-UNEXPECTED-FAIL"
#define MOZ_IPDL_TESTPASS_LABEL "TEST-PASS"
// NB: these are named like the similar functions in
// xpcom/test/TestHarness.h. The names should nominally be kept in
// sync.
#define fail(fmt, ...) \
do { \
fprintf(stderr, MOZ_IPDL_TESTFAIL_LABEL " | %s | " fmt "\n", \
IPDLUnitTestName(), ## __VA_ARGS__); \
NS_RUNTIMEABORT("failed test"); \
} while (0)
#define passed(fmt, ...) \
fprintf(stderr, MOZ_IPDL_TESTPASS_LABEL " | %s | " fmt "\n", \
IPDLUnitTestName(), ## __VA_ARGS__)
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// both processes
const char* const IPDLUnitTestName();
//-----------------------------------------------------------------------------
// parent process only
void IPDLUnitTestMain(void* aData);
// TODO: could clean up parent actor/subprocess
//-----------------------------------------------------------------------------
// child process only
void IPDLUnitTestChildInit(IPC::Channel* transport, MessageLoop* worker);
void IPDLUnitTestChildCleanUp();
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_IPDLUnitTests_h

View File

@ -0,0 +1,198 @@
//
// Autogenerated from Python template. Hands off.
//
#include "IPDLUnitTests.h"
#include <string.h>
#include "base/command_line.h"
#include "base/string_util.h"
#include "IPDLUnitTestSubprocess.h"
#include "IPDLUnitTestThreadChild.h"
//-----------------------------------------------------------------------------
//===== TEMPLATED =====
${INCLUDES}
//-----------------------------------------------------------------------------
using mozilla::_ipdltest::IPDLUnitTestSubprocess;
using mozilla::_ipdltest::IPDLUnitTestThreadChild;
//-----------------------------------------------------------------------------
// data/functions accessed by both parent and child processes
namespace {
char* gIPDLUnitTestName = NULL; // "leaks"
}
namespace mozilla {
namespace _ipdltest {
const char* const
IPDLUnitTestName()
{
if (!gIPDLUnitTestName) {
std::vector<std::wstring> args =
CommandLine::ForCurrentProcess()->GetLooseValues();
gIPDLUnitTestName = strdup(WideToUTF8(args[args.size()-1]).c_str());
}
return gIPDLUnitTestName;
}
} // namespace _ipdltest
} // namespace mozilla
namespace {
enum IPDLUnitTestType {
NoneTest = 0,
//-----------------------------------------------------------------------------
//===== TEMPLATED =====
${ENUM_VALUES}
LastTest = ${LAST_ENUM}
//-----------------------------------------------------------------------------
};
IPDLUnitTestType
IPDLUnitTestFromString(const char* const aString)
{
if (!aString)
return static_cast<IPDLUnitTestType>(0);
//-----------------------------------------------------------------------------
//===== TEMPLATED =====
${STRING_TO_ENUMS}
//-----------------------------------------------------------------------------
else
return static_cast<IPDLUnitTestType>(0);
}
const char* const
IPDLUnitTestToString(IPDLUnitTestType aTest)
{
switch (aTest) {
//-----------------------------------------------------------------------------
//===== TEMPLATED =====
${ENUM_TO_STRINGS}
//-----------------------------------------------------------------------------
default:
return NULL;
}
}
IPDLUnitTestType
IPDLUnitTest()
{
return IPDLUnitTestFromString(mozilla::_ipdltest::IPDLUnitTestName());
}
} // namespace <anon>
//-----------------------------------------------------------------------------
// parent process only
namespace {
void* gParentActor = NULL;
}
namespace mozilla {
namespace _ipdltest {
void
IPDLUnitTestMain(void* aData)
{
char* testString = reinterpret_cast<char*>(aData);
IPDLUnitTestType test = IPDLUnitTestFromString(testString);
if (!test) {
// use this instead of |fail()| because we don't know what the test is
fprintf(stderr, MOZ_IPDL_TESTFAIL_LABEL "| %s | unknown unit test %s\\n",
"<--->", testString);
NS_RUNTIMEABORT("can't continue");
}
gIPDLUnitTestName = testString;
std::wstring testWString = UTF8ToWide(testString);
std::vector<std::wstring> testCaseArgs;
testCaseArgs.push_back(testWString);
IPDLUnitTestSubprocess* subprocess = new IPDLUnitTestSubprocess();
if (!subprocess->SyncLaunch(testCaseArgs))
fail("problem launching subprocess");
IPC::Channel* transport = subprocess->GetChannel();
if (!transport)
fail("no transport");
switch (test) {
//-----------------------------------------------------------------------------
//===== TEMPLATED =====
${PARENT_MAIN_CASES}
//-----------------------------------------------------------------------------
default:
fail("not reached");
return; // unreached
}
}
} // namespace _ipdltest
} // namespace mozilla
//-----------------------------------------------------------------------------
// child process only
namespace {
void* gChildActor = NULL;
}
namespace mozilla {
namespace _ipdltest {
void
IPDLUnitTestChildInit(IPC::Channel* transport, MessageLoop* worker)
{
switch (IPDLUnitTest()) {
//-----------------------------------------------------------------------------
//===== TEMPLATED =====
${CHILD_INIT_CASES}
//-----------------------------------------------------------------------------
default:
fail("not reached");
return; // unreached
}
}
void IPDLUnitTestChildCleanUp()
{
if (!gChildActor)
return;
switch (IPDLUnitTest()) {
//-----------------------------------------------------------------------------
//===== TEMPLATED =====
${CHILD_CLEANUP_CASES}
//-----------------------------------------------------------------------------
default:
fail("not reached");
return; // unreached
}
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -40,8 +40,54 @@ srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
TOOL_DIRS += app
MODULE = ipdlunittest
EXPORTS_NAMESPACES = mozilla/_ipdltest
EXPORTS_mozilla/_ipdltest = \
IPDLUnitTests.h \
IPDLUnitTestThreadChild.h \
$(NULL)
LIBRARY_NAME = $(MODULE)_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
IPDLTESTS = \
TestSanity \
$(NULL)
IPDLTESTSRCS = $(addsuffix .cpp,$(IPDLTESTS))
IPDLTESTHDRS = $(addprefix $(srcdir)/,$(addsuffix .h,$(IPDLTESTS)))
TESTER_TEMPLATE := $(srcdir)/IPDLUnitTests.template.cpp
GENTESTER := $(srcdir)/genIPDLUnitTests.py
CPPSRCS = \
IPDLUnitTests.cpp \
IPDLUnitTestSubprocess.cpp \
IPDLUnitTestThreadChild.cpp \
$(IPDLTESTSRCS) \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
RUNIPDLTEST := $(RUN_TEST_PROGRAM) $(DEPTH)/dist/bin/ipdlunittest$(BIN_SUFFIX)
IPDLUnitTests.cpp : $(GENTESTER) $(TESTER_TEMPLATE) $(IPDLTESTHDRS)
$(PYTHON) $< $(TESTER_TEMPLATE) $(IPDLTESTS) > $@
check::
echo "TODO: C++/IPDL unit tests"
@$(EXIT_ON_ERROR) \
for test in $(IPDLTESTS); do \
$(RUNIPDLTEST) $$test ; \
done

View File

@ -0,0 +1,31 @@
namespace mozilla {
namespace _ipdltest {
protocol PTestSanity {
child:
Ping(int zero);
parent:
Pong(int one);
both:
UNREACHED();
state PING:
send Ping goto PONG;
state PONG:
recv Pong goto DEAD;
// hmm ... maybe support this idiom natively?
state DEAD:
send UNREACHED goto DEAD;
};
} // namespace mozilla
} // namespace _ipdltest

View File

@ -0,0 +1,47 @@
To add a new IPDL C++ unit test, you need to create (at least) the
following files (for a test "TestFoo"):
- PTestFoo.ipdl, specifying the top-level protocol used for the test
- TestFoo.h, declaring the top-level parent/child actors used for
the test
- TestFoo.cpp, defining the top-level actors
Next
- add PTestFoo.ipdl to ipdl.mk
- append TestFoo to the variable IPDLTESTS in Makefile.in
The IPDL test harness will try to execute |testFooParentActor->Main()|
to kick off your test. Make sure you define |TestFooParent::Main()|.
If your test passes its criteria, please call
|MOZ_IPDL_TESTPASS("msg")| and "exit gracefully".
If your tests fails, please call |MOZ_IPDL_TESTFAIL("msg")| and "exit
ungracefully", preferably by abort()ing.
If all goes well, running
make -C $OBJDIR/ipc/ipdl/test/cxx
will update the file IPDLUnitTests.cpp (the test launcher), and your
new code will be built automatically.
You can launch your new test by invoking
make -C $OBJDIR/ipc/ipdl/test/cxx check
If you want to launch only your test, run
cd $OBJDIR/dist/bin
./run-mozilla.sh ./ipdlunittest TestFoo
For a bare-bones example of adding a test, take a look at
PTestSanity.ipdl, TestSanity.h, TestSanity.cpp, and how "TestSanity"
is included in ipdl.mk and Makefile.in.

View File

@ -0,0 +1,91 @@
#include "TestSanity.h"
#include "nsIAppShell.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h" // do_GetService()
#include "nsWidgetsCID.h" // NS_APPSHELL_CID
#include "IPDLUnitTests.h" // fail etc.
namespace mozilla {
namespace _ipdltest {
//-----------------------------------------------------------------------------
// parent
TestSanityParent::TestSanityParent()
{
MOZ_COUNT_CTOR(TestSanityParent);
}
TestSanityParent::~TestSanityParent()
{
MOZ_COUNT_DTOR(TestSanityParent);
}
void
TestSanityParent::Main()
{
if (!SendPing(0))
fail("sending Ping");
}
bool
TestSanityParent::RecvPong(const int& one)
{
if (1 != one)
fail("invalid argument `%d', should have been `1'", one);
passed("sent ping/received pong");
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
nsCOMPtr<nsIAppShell> appShell (do_GetService(kAppShellCID));
appShell->Exit();
return true;
}
bool
TestSanityParent::RecvUNREACHED()
{
fail("unreached");
return false; // not reached
}
//-----------------------------------------------------------------------------
// child
TestSanityChild::TestSanityChild()
{
MOZ_COUNT_CTOR(TestSanityChild);
}
TestSanityChild::~TestSanityChild()
{
MOZ_COUNT_DTOR(TestSanityChild);
}
bool
TestSanityChild::RecvPing(const int& zero)
{
if (0 != zero)
fail("invalid argument `%d', should have been `0'", zero);
if (!SendPong(1))
fail("sending Pong");
return true;
}
bool
TestSanityChild::RecvUNREACHED()
{
fail("unreached");
return false; // not reached
}
} // namespace _ipdltest
} // namespace mozilla

View File

@ -0,0 +1,44 @@
#ifndef mozilla__ipdltest_TestSanity_h
#define mozilla__ipdltest_TestSanity_h 1
#include "mozilla/_ipdltest/PTestSanityParent.h"
#include "mozilla/_ipdltest/PTestSanityChild.h"
namespace mozilla {
namespace _ipdltest {
class TestSanityParent :
public PTestSanityParent
{
public:
TestSanityParent();
virtual ~TestSanityParent();
void Main();
protected:
virtual bool RecvPong(const int& one);
virtual bool RecvUNREACHED();
};
class TestSanityChild :
public PTestSanityChild
{
public:
TestSanityChild();
virtual ~TestSanityChild();
protected:
virtual bool RecvPing(const int& zero);
virtual bool RecvUNREACHED();
};
} // namespace _ipdltest
} // namespace mozilla
#endif // ifndef mozilla__ipdltest_TestSanity_h

View File

@ -0,0 +1,72 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla IPC.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = ipdlunittest
PROGRAM = $(MODULE)$(BIN_SUFFIX)
ENABLE_CXX_EXCEPTIONS = 1
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
CPPSRCS = \
TestIPDL.cpp \
$(NULL)
LIBS = \
$(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
$(LIBXUL_LIBS) \
$(MOZ_JS_LIBS) \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/config.mk
ifdef _MSC_VER
ifdef WINCE
WIN32_EXE_LDFLAGS += -ENTRY:mainWCRTStartup
else
WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
endif
endif
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,52 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla IPC.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsXULAppAPI.h"
#if defined(XP_WIN)
#include <windows.h>
#include "nsWindowsWMain.cpp"
#endif
int
main(int argc, char** argv)
{
// the first argument specifies which IPDL test case/suite to load
if (argc < 2)
return 1;
return XRE_RunIPDLTest(argc, argv);
}

View File

@ -0,0 +1,107 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Firefox.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation <http://www.mozilla.org/>.
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Chris Jones <jones.chris.g@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import string, sys
def main(argv):
template = argv[1]
unittests = argv[2:]
includes = '\n'.join([
'#include "%s.h"'% (t) for t in unittests ])
enum_values = '\n'.join([
' %s,'% (t) for t in unittests ])
last_enum = unittests[-1]
string_to_enums = '\n'.join([
''' else if (!strcmp(aString, "%s"))
return %s;'''% (t, t) for t in unittests ])
enum_to_strings = '\n'.join([
''' case %s:
return "%s";'''%(t, t) for t in unittests ])
parent_main_cases = '\n'.join([
''' case %s: {
%sParent** parent =
reinterpret_cast<%sParent**>(&gParentActor);
*parent = new %sParent();
(*parent)->Open(transport);
return (*parent)->Main();
}
'''% (t, t, t, t) for t in unittests ])
child_init_cases = '\n'.join([
''' case %s: {
%sChild** child =
reinterpret_cast<%sChild**>(&gChildActor);
*child = new %sChild();
(*child)->Open(transport, worker);
return;
}
'''% (t, t, t, t) for t in unittests ])
child_cleanup_cases = '\n'.join([
''' case %s: {
%sChild** child =
reinterpret_cast<%sChild**>(&gChildActor);
delete *child;
*child = 0;
return;
}
'''% (t, t, t) for t in unittests ])
templatefile = open(template, 'r')
sys.stdout.write(
string.Template(templatefile.read()).substitute(
INCLUDES=includes,
ENUM_VALUES=enum_values, LAST_ENUM=last_enum,
STRING_TO_ENUMS=string_to_enums,
ENUM_TO_STRINGS=enum_to_strings,
PARENT_MAIN_CASES=parent_main_cases,
CHILD_INIT_CASES=child_init_cases,
CHILD_CLEANUP_CASES=child_cleanup_cases))
templatefile.close()
if __name__ == '__main__':
main(sys.argv)

View File

@ -0,0 +1,3 @@
IPDLSRCS = \
PTestSanity.ipdl \
$(NULL)

View File

@ -46,10 +46,10 @@ OKTESTS := $(wildcard $(srcdir)/ok/*.ipdl)
ERRORTESTS := $(wildcard $(srcdir)/error/*.ipdl)
check::
@$(PYTHON) $(srcdir)/runtests.py \
$(srcdir)/ok $(srcdir)/error \
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply \
$(topsrcdir)/ipc/ipdl/ipdl.py \
OKTESTS $(OKTESTS) \
@$(PYTHON) $(srcdir)/runtests.py \
$(srcdir)/ok $(srcdir)/error \
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/other-licenses/ply \
$(topsrcdir)/ipc/ipdl/ipdl.py \
OKTESTS $(OKTESTS) \
ERRORTESTS $(ERRORTESTS)

View File

@ -101,6 +101,10 @@ STATIC_LIBS += \
ipctestharness_s \
$(NULL)
ifdef MOZ_IPDL_TESTS
STATIC_LIBS += ipdlunittest_s
endif
ifeq (Linux,$(OS_ARCH))
OS_LIBS += -lrt
endif

View File

@ -170,6 +170,10 @@ ifdef ACCESSIBILITY
tier_gecko_dirs += accessible
endif
ifdef MOZ_IPDL_TESTS
tier_gecko_dirs += ipc/ipdl/test
endif
#
# tier "toolkit" - xpfe & toolkit
#

View File

@ -727,9 +727,10 @@ SYNC_ENUMS(DEFAULT, Default)
SYNC_ENUMS(PLUGIN, Plugin)
SYNC_ENUMS(CONTENT, Content)
SYNC_ENUMS(TESTHARNESS, TestHarness)
SYNC_ENUMS(IPDLUNITTEST, IPDLUnitTest)
// .. and ensure that that is all of them:
PR_STATIC_ASSERT(GeckoProcessType_TestHarness + 1 == GeckoProcessType_End);
PR_STATIC_ASSERT(GeckoProcessType_IPDLUnitTest + 1 == GeckoProcessType_End);
NS_IMETHODIMP
nsXULAppInfo::GetProcessType(PRUint32* aResult)

View File

@ -83,6 +83,13 @@
#include "mozilla/test/TestThreadChild.h"
#include "mozilla/Monitor.h"
#ifdef MOZ_IPDL_TESTS
#include "mozilla/_ipdltest/IPDLUnitTests.h"
#include "mozilla/_ipdltest/IPDLUnitTestThreadChild.h"
using mozilla::_ipdltest::IPDLUnitTestThreadChild;
#endif // ifdef MOZ_IPDL_TESTS
using mozilla::ipc::GeckoChildProcessHost;
using mozilla::ipc::GeckoThread;
using mozilla::ipc::BrowserProcessSubThread;
@ -283,6 +290,14 @@ XRE_InitChildProcess(int aArgc,
mainThread = new TestThreadChild();
break;
case GeckoProcessType_IPDLUnitTest:
#ifdef MOZ_IPDL_TESTS
mainThread = new IPDLUnitTestThreadChild();
#else
NS_RUNTIMEABORT("rebuild with --enable-ipdl-tests");
#endif
break;
default:
NS_RUNTIMEABORT("Unknown main thread class");
}
@ -410,6 +425,29 @@ XRE_RunIPCTestHarness(int aArgc, char* aArgv[])
return 0;
}
#ifdef MOZ_IPDL_TESTS
//-----------------------------------------------------------------------------
// IPDL unit test
int
XRE_RunIPDLTest(int aArgc, char** aArgv)
{
if (aArgc < 2) {
fprintf(stderr, "TEST-UNEXPECTED-FAIL | <---> | insufficient #args, need at least 2\n");
return 1;
}
void* data = reinterpret_cast<void*>(aArgv[aArgc-1]);
nsresult rv =
XRE_InitParentProcess(
--aArgc, aArgv, mozilla::_ipdltest::IPDLUnitTestMain, data);
NS_ENSURE_SUCCESS(rv, 1);
return 0;
}
#endif // ifdef MOZ_IPDL_TESTS
nsresult
XRE_RunAppShell()
{

View File

@ -426,6 +426,7 @@ enum GeckoProcessType {
GeckoProcessType_Content,
GeckoProcessType_TestHarness,
GeckoProcessType_IPDLUnitTest,
GeckoProcessType_End,
GeckoProcessType_Invalid = GeckoProcessType_End
@ -436,6 +437,7 @@ static const char* const kGeckoProcessTypeString[] = {
"plugin",
"tab",
"testharness",
"ipdlunittest"
};
PR_STATIC_ASSERT(sizeof(kGeckoProcessTypeString) /
@ -469,6 +471,10 @@ XRE_API(int,
XRE_RunIPCTestHarness, (int aArgc,
char* aArgv[]))
XRE_API(int,
XRE_RunIPDLTest, (int aArgc,
char* aArgv[]))
XRE_API(nsresult,
XRE_RunAppShell, ())

View File

@ -94,6 +94,7 @@ interface nsIXULRuntime : nsISupports
const unsigned long PROCESS_TYPE_PLUGIN = 1;
const unsigned long PROCESS_TYPE_CONTENT = 2;
const unsigned long PROCESS_TYPE_TESTHARNESS = 3;
const unsigned long PROCESS_TYPE_IPDLUNITTEST = 4;
/**
* The type of the caller's process. Returns one of the values above.