/* Copyright (C) 2000 Stefan Westerfeld stefan@space.twc.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Permission is also granted to link this program with the Qt library, treating Qt like a library that normally accompanies the operating system kernel, whether or not that is in fact the case. */ #include "remotetest.h" #include "value.h" #include "test.h" #include "connect.h" #include #include using namespace std; using namespace Arts; class RemoteTest_impl: virtual public RemoteTest_skel { private: bool alive; public: RemoteTest_impl() { alive = true; _copy(); } ~RemoteTest_impl() { Dispatcher::the()->terminate(); } Object createObject(const string& name) { return SubClass(name); } long fortyTwo() { return 42; } void die() { if(alive) { _release(); alive = false; } } }; REGISTER_IMPLEMENTATION(RemoteTest_impl); /* name of the remote object - should be sufficiently unique */ char objectName[60]; struct TestRemote : public TestCase { TESTCASE(TestRemote); Arts::Dispatcher dispatcher; RemoteTest remoteTest; void setUp() { string globalRef = "global:"; globalRef += objectName; remoteTest = Arts::Reference(globalRef); } void tearDown() { remoteTest = RemoteTest::null(); } void process() { dispatcher.ioManager()->processOneEvent(false); } /* test whether the server is running, and we could connect ok */ TEST(connected) { testEquals(false, remoteTest.isNull()); } /* test method call */ TEST(fortyTwo) { testEquals(42, remoteTest.fortyTwo()); } /* test remote change notifications */ TEST(remoteChangeNotify) { StringValue local; local.value("local"); testEquals("local", local.value()); Object o = remoteTest.createObject("StringValue"); testAssert(!o.isNull()); StringValue remote = Arts::DynamicCast(o); testAssert(!remote.isNull()); remote.value("remote"); testEquals("remote", remote.value()); connect(local,"value_changed",remote,"value"); local.value("transferme"); process(); sleep(1); /* change notifications are asynchronous */ testEquals("transferme", local.value()); testEquals("transferme", remote.value()); disconnect(local,"value_changed",remote,"value"); local.value("notransfer"); testEquals("notransfer", local.value()); testEquals("transferme", remote.value()); } /* terminate server */ TEST(die) { remoteTest.die(); remoteTest = RemoteTest::null(); sleep(1); } /* check if server is dead now */ TEST(dead) { testEquals(true, remoteTest.isNull()); } }; TESTMAINFUNC(TestRemote,performTests); /* * this test case is a bit tricky because we need a client and a server * * we create the server in a fork()ed process, and then evaluate the test * inside the client */ int main() { /* create unique object name for test server/test client */ sprintf(objectName, "RemoteTest_%d_%ld", getpid(), time(0)); int pid = fork(); if(pid == 0) /* child process - we play the server here */ { Dispatcher dispatcher(0, Dispatcher::startUnixServer); ObjectManager::the()->addGlobalReference(RemoteTest(), objectName); dispatcher.run(); return 0; } else if(pid >= 0) /* parent process - do the test here */ { sleep(1); return performTests(); } }