|
|
|
/*
|
|
|
|
|
|
|
|
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 <iostream.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|