summaryrefslogtreecommitdiff
path: root/cpp/test
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2005-06-17 15:25:02 +0000
committerBenoit Foucher <benoit@zeroc.com>2005-06-17 15:25:02 +0000
commit2bc0f2b81423bb51c8649fefdeae23c602a56558 (patch)
treeda5dc69eda441fe23345267d1606da5266413f94 /cpp/test
parentbuild fix (diff)
downloadice-2bc0f2b81423bb51c8649fefdeae23c602a56558.tar.bz2
ice-2bc0f2b81423bb51c8649fefdeae23c602a56558.tar.xz
ice-2bc0f2b81423bb51c8649fefdeae23c602a56558.zip
Fixed bugs + added "update" test suite
Diffstat (limited to 'cpp/test')
-rw-r--r--cpp/test/IceGrid/update/.depend0
-rw-r--r--cpp/test/IceGrid/update/AllTests.cpp507
-rw-r--r--cpp/test/IceGrid/update/Client.cpp55
-rw-r--r--cpp/test/IceGrid/update/Makefile48
-rw-r--r--cpp/test/IceGrid/update/Server.cpp63
-rw-r--r--cpp/test/IceGrid/update/Test.cpp471
-rw-r--r--cpp/test/IceGrid/update/Test.ice25
-rw-r--r--cpp/test/IceGrid/update/TestI.cpp29
-rw-r--r--cpp/test/IceGrid/update/db/.dummy0
-rwxr-xr-xcpp/test/IceGrid/update/run.py58
10 files changed, 1256 insertions, 0 deletions
diff --git a/cpp/test/IceGrid/update/.depend b/cpp/test/IceGrid/update/.depend
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/cpp/test/IceGrid/update/.depend
diff --git a/cpp/test/IceGrid/update/AllTests.cpp b/cpp/test/IceGrid/update/AllTests.cpp
new file mode 100644
index 00000000000..ef29323fd87
--- /dev/null
+++ b/cpp/test/IceGrid/update/AllTests.cpp
@@ -0,0 +1,507 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/Thread.h>
+#include <Ice/Ice.h>
+#include <IceGrid/Observer.h>
+#include <TestCommon.h>
+#include <Test.h>
+
+using namespace std;
+using namespace Test;
+using namespace IceGrid;
+
+class SessionKeepAliveThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ SessionKeepAliveThread(const Ice::LoggerPtr& logger, const IceUtil::Time& timeout) :
+ _logger(logger),
+ _timeout(timeout),
+ _terminated(false)
+ {
+ }
+
+ virtual void
+ run()
+ {
+ Lock sync(*this);
+ while(!_terminated)
+ {
+ timedWait(_timeout);
+ if(!_terminated)
+ {
+ vector<SessionPrx>::iterator p = _sessions.begin();
+ while(p != _sessions.end())
+ {
+ try
+ {
+ (*p)->keepAlive();
+ ++p;
+ }
+ catch(const Ice::Exception& ex)
+ {
+ p = _sessions.erase(p);
+ }
+ }
+ }
+ }
+ }
+
+ void
+ add(const SessionPrx& session)
+ {
+ Lock sync(*this);
+ _sessions.push_back(session);
+ }
+
+ void
+ terminate()
+ {
+ Lock sync(*this);
+ _terminated = true;
+ notify();
+ }
+
+private:
+
+ const Ice::LoggerPtr _logger;
+ vector<SessionPrx> _sessions;
+ const IceUtil::Time _timeout;
+ bool _terminated;
+};
+typedef IceUtil::Handle<SessionKeepAliveThread> SessionKeepAliveThreadPtr;
+
+class RegistryObserverI : public RegistryObserver, public IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ RegistryObserverI() : _updated(false)
+ {
+ }
+
+ virtual void
+ init(int serial, const ApplicationDescriptorSeq& apps, const Ice::StringSeq& nodes, const Ice::Current&)
+ {
+ Lock sync(*this);
+ for(ApplicationDescriptorSeq::const_iterator p = apps.begin(); p != apps.end(); ++p)
+ {
+ this->applications.insert(make_pair((*p)->name, *p));
+ }
+ this->nodes = nodes;
+ updated(serial);
+ }
+
+ virtual void
+ applicationAdded(int serial, const ApplicationDescriptorPtr& app, const Ice::Current&)
+ {
+ Lock sync(*this);
+ this->applications.insert(make_pair(app->name, app));
+ updated(serial);
+ }
+
+ virtual void
+ applicationRemoved(int serial, const std::string& name, const Ice::Current&)
+ {
+ Lock sync(*this);
+ this->applications.erase(name);
+ updated(serial);
+ }
+
+ virtual void
+ applicationUpdated(int serial, const ApplicationUpdateDescriptor& desc, const Ice::Current&)
+ {
+ Lock sync(*this);
+ for(map<string, string>::const_iterator p = desc.variables.begin(); p != desc.variables.end(); ++p)
+ {
+ this->applications[desc.name]->variables[p->first] = p->second;
+ }
+ updated(serial);
+ }
+
+ virtual void
+ applicationSynced(int serial, const ApplicationDescriptorPtr& app, const Ice::Current&)
+ {
+ Lock sync(*this);
+ this->applications[app->name] = app;
+ updated(serial);
+ }
+
+ virtual void
+ nodeUp(const string& name, const Ice::Current& current)
+ {
+ }
+
+ virtual void
+ nodeDown(const string& name, const Ice::Current& current)
+ {
+ }
+
+ void
+ waitForUpdate(const char* file, int line)
+ {
+ Lock sync(*this);
+ while(!_updated)
+ {
+ if(!timedWait(IceUtil::Time::seconds(10)))
+ {
+ cerr << "wait timed out " << file << ":" << line << endl;
+ test(false); // Timeout
+ }
+ }
+ _updated = false;
+ }
+
+ int serial;
+ map<string, ApplicationDescriptorPtr> applications;
+ Ice::StringSeq nodes;
+
+private:
+
+ void
+ updated(int serial)
+ {
+ this->serial = serial;
+ _updated = true;
+ notifyAll();
+ }
+
+ bool _updated;
+};
+
+class NodeObserverI : public NodeObserver
+{
+public:
+
+ virtual void
+ init(const NodeDynamicInfoSeq& info, const Ice::Current&)
+ {
+ }
+
+ virtual void
+ initNode(const NodeDynamicInfo& info, const Ice::Current&)
+ {
+ }
+
+ virtual void
+ updateServer(const string& node, const ServerDynamicInfo& info, const Ice::Current&)
+ {
+ }
+
+ virtual void
+ updateAdapter(const string& node, const AdapterDynamicInfo& info, const Ice::Current& current)
+ {
+ }
+};
+
+void
+allTests(const Ice::CommunicatorPtr& communicator)
+{
+ SessionManagerPrx manager = SessionManagerPrx::checkedCast(communicator->stringToProxy("IceGrid/SessionManager"));
+ test(manager);
+
+ SessionKeepAliveThreadPtr keepAlive;
+ keepAlive = new SessionKeepAliveThread(communicator->getLogger(), IceUtil::Time::seconds(5));
+ keepAlive->start();
+
+ {
+ cout << "testing sessions... " << flush;
+ SessionPrx session1 = manager->createLocalSession("Observer1");
+ SessionPrx session2 = manager->createLocalSession("Observer2");
+
+ keepAlive->add(session1);
+ keepAlive->add(session2);
+
+ Ice::ObjectAdapterPtr adpt1 = communicator->createObjectAdapter("Observer1");
+ RegistryObserverI* regObs1 = new RegistryObserverI();
+ Ice::ObjectPrx ro1 = adpt1->addWithUUID(regObs1);
+ NodeObserverI* nodeObs1 = new NodeObserverI();
+ Ice::ObjectPrx no1 = adpt1->addWithUUID(nodeObs1);
+ adpt1->activate();
+ manager->ice_connection()->setAdapter(adpt1);
+ session1->setObserversByIdentity(ro1->ice_getIdentity(), no1->ice_getIdentity());
+
+ Ice::ObjectAdapterPtr adpt2 = communicator->createObjectAdapterWithEndpoints("Observer2", "default");
+ RegistryObserverI* regObs2 = new RegistryObserverI();
+ Ice::ObjectPrx ro2 = adpt2->addWithUUID(regObs2);
+ NodeObserverI* nodeObs2 = new NodeObserverI();
+ Ice::ObjectPrx no2 = adpt2->addWithUUID(nodeObs2);
+ adpt2->activate();
+ session2->setObservers(RegistryObserverPrx::uncheckedCast(ro2), NodeObserverPrx::uncheckedCast(no2));
+
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ regObs2->waitForUpdate(__FILE__, __LINE__);
+
+ int serial = regObs1->serial;
+ test(serial == regObs2->serial);
+
+ try
+ {
+ session1->startUpdate(serial + 1);
+ test(false);
+ }
+ catch(const CacheOutOfDate&)
+ {
+ }
+ catch(const AccessDenied&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ session1->startUpdate(serial);
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ session2->startUpdate(regObs2->serial);
+ test(false);
+ }
+ catch(const AccessDenied& ex)
+ {
+ test(ex.lockUserId == "Observer1");
+ }
+
+ try
+ {
+ session1->finishUpdate();
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ session2->startUpdate(regObs2->serial);
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ ApplicationDescriptorPtr app = new ApplicationDescriptor();
+ app->name = "Application";
+ session2->addApplication(app);
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ session1->addApplication(new ApplicationDescriptor());
+ test(false);
+ }
+ catch(const AccessDenied& ex)
+ {
+ }
+
+ try
+ {
+ session2->finishUpdate();
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ regObs2->waitForUpdate(__FILE__, __LINE__);
+
+ test(serial + 1 == regObs1->serial);
+ test(serial + 1 == regObs2->serial);
+ ++serial;
+
+ try
+ {
+ session1->startUpdate(serial);
+ ApplicationUpdateDescriptor update;
+ update.name = "Application";
+ update.variables.insert(make_pair("test", "test"));
+ session1->updateApplication(update);
+ session1->finishUpdate();
+ }
+ catch(const Ice::UserException& ex)
+ {
+ cerr << ex << endl;
+ test(false);
+ }
+
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ regObs2->waitForUpdate(__FILE__, __LINE__);
+
+ test(serial + 1 == regObs1->serial);
+ test(serial + 1 == regObs2->serial);
+ ++serial;
+
+ try
+ {
+ ApplicationUpdateDescriptor update;
+ update.name = "Application";
+ session1->updateApplication(update);
+ test(false);
+ }
+ catch(const AccessDenied&)
+ {
+ }
+
+ try
+ {
+ session2->startUpdate(serial);
+ session2->removeApplication("Application");
+ session2->finishUpdate();
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ regObs2->waitForUpdate(__FILE__, __LINE__);
+
+ test(serial + 1 == regObs1->serial);
+ test(serial + 1 == regObs2->serial);
+ ++serial;
+
+ try
+ {
+ session1->startUpdate(serial);
+ }
+ catch(const Ice::UserException& ex)
+ {
+ test(false);
+ }
+ session1->destroy();
+
+ try
+ {
+ session2->startUpdate(serial);
+ session2->finishUpdate();
+ }
+ catch(const Ice::UserException& ex)
+ {
+ test(false);
+ }
+ session2->destroy();
+
+ adpt1->deactivate();
+ adpt2->deactivate();
+
+ adpt1->waitForDeactivate();
+ adpt2->waitForDeactivate();
+
+ //
+ // TODO: test session reaping?
+ //
+
+ cout << "ok" << endl;
+ }
+
+ {
+ cout << "testing observers... " << flush;
+ SessionPrx session1 = manager->createLocalSession("Observer1");
+
+ keepAlive->add(session1);
+
+ Ice::ObjectAdapterPtr adpt1 = communicator->createObjectAdapter("Observer1.1");
+ RegistryObserverI* regObs1 = new RegistryObserverI();
+ Ice::ObjectPrx ro1 = adpt1->addWithUUID(regObs1);
+ NodeObserverI* nodeObs1 = new NodeObserverI();
+ Ice::ObjectPrx no1 = adpt1->addWithUUID(nodeObs1);
+ adpt1->activate();
+ manager->ice_connection()->setAdapter(adpt1);
+ session1->setObserversByIdentity(ro1->ice_getIdentity(), no1->ice_getIdentity());
+
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+
+ int serial = regObs1->serial;
+ test(find(regObs1->nodes.begin(), regObs1->nodes.end(), "localnode") != regObs1->nodes.end());
+ test(regObs1->applications.empty());
+
+ try
+ {
+ ApplicationDescriptorPtr app = new ApplicationDescriptor();
+ app->name = "Application";
+ session1->startUpdate(serial);
+ session1->addApplication(app);
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ test(regObs1->applications["Application"]);
+ test(++serial == regObs1->serial);
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ ApplicationUpdateDescriptor update;
+ update.name = "Application";
+ update.variables.insert(make_pair("test", "test"));
+ session1->updateApplication(update);
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ test(regObs1->applications["Application"]);
+ test(regObs1->applications["Application"]->variables["test"] == "test");
+ test(++serial == regObs1->serial);
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ ApplicationDescriptorPtr app;
+ app = ApplicationDescriptorPtr::dynamicCast(regObs1->applications["Application"]->ice_clone());
+ app->variables.clear();
+ app->variables["test1"] = "test";
+ session1->syncApplication(app);
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ test(regObs1->applications["Application"]);
+ test(regObs1->applications["Application"]->variables.size() == 1);
+ test(regObs1->applications["Application"]->variables["test1"] == "test");
+ test(++serial == regObs1->serial);
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ try
+ {
+ session1->removeApplication("Application");
+ regObs1->waitForUpdate(__FILE__, __LINE__);
+ test(regObs1->applications.empty());
+ test(++serial == regObs1->serial);
+ }
+ catch(const Ice::UserException&)
+ {
+ test(false);
+ }
+
+ session1->destroy();
+ adpt1->deactivate();
+ adpt1->waitForDeactivate();
+
+ cout << "ok" << endl;
+ }
+
+ keepAlive->terminate();
+ keepAlive->getThreadControl().join();
+ keepAlive = 0;
+}
diff --git a/cpp/test/IceGrid/update/Client.cpp b/cpp/test/IceGrid/update/Client.cpp
new file mode 100644
index 00000000000..4e4c921ec05
--- /dev/null
+++ b/cpp/test/IceGrid/update/Client.cpp
@@ -0,0 +1,55 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <TestCommon.h>
+#include <Test.h>
+
+using namespace std;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ void allTests(const Ice::CommunicatorPtr&);
+ allTests(communicator);
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ communicator = Ice::initialize(argc, argv);
+ status = run(argc, argv, communicator);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ try
+ {
+ communicator->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/test/IceGrid/update/Makefile b/cpp/test/IceGrid/update/Makefile
new file mode 100644
index 00000000000..27e0fd7113f
--- /dev/null
+++ b/cpp/test/IceGrid/update/Makefile
@@ -0,0 +1,48 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../../..
+
+CLIENT = client
+SERVER = server
+
+TARGETS = $(CLIENT) $(SERVER)
+
+OBJS = Test.o
+
+COBJS = Client.o \
+ AllTests.o
+
+SOBJS = TestI.o \
+ Server.o
+
+SRCS = $(OBJS:.o=.cpp) \
+ $(COBJS:.o=.cpp) \
+ $(SOBJS:.o=.cpp)
+
+SLICE_SRCS = Test.ice
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../../include $(CPPFLAGS)
+LINKWITH := -lIce -lIceUtil
+
+$(CLIENT): $(OBJS) $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(COBJS) -lIceGrid -lGlacier2 $(LIBS)
+
+$(SERVER): $(OBJS) $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(SOBJS) $(LIBS)
+
+clean::
+ rm -rf db/node/servers
+ rm -f db/registry/*
+
+include .depend
diff --git a/cpp/test/IceGrid/update/Server.cpp b/cpp/test/IceGrid/update/Server.cpp
new file mode 100644
index 00000000000..5d4ce7a465b
--- /dev/null
+++ b/cpp/test/IceGrid/update/Server.cpp
@@ -0,0 +1,63 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <TestI.h>
+#include <TestCommon.h>
+
+using namespace std;
+
+class Server : public Ice::Application
+{
+public:
+
+ virtual int run(int argc, char* argv[]);
+};
+
+int
+Server::run(int argc, char* argv[])
+{
+ Ice::PropertiesPtr properties = communicator()->getProperties();
+
+ Ice::StringSeq args = Ice::argsToStringSeq(argc, argv);
+ args = properties->parseCommandLineOptions("Test", args);
+ Ice::stringSeqToArgs(args, argc, argv);
+
+ string name = properties->getProperty("Ice.ProgramName");
+
+ Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Server");
+ Ice::ObjectPtr object = new TestI(adapter, properties);
+ adapter->add(object, Ice::stringToIdentity(name));
+
+ shutdownOnInterrupt();
+ try
+ {
+ adapter->activate();
+ }
+ catch(const Ice::ObjectAdapterDeactivatedException&)
+ {
+ }
+ communicator()->waitForShutdown();
+ ignoreInterrupt();
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ //
+ // Test if MY_ENV_VARIABLE is set.
+ //
+ char* value = getenv("MY_ENV_VARIABLE");
+ test(value != 0 && string(value) == "12");
+
+ Server app;
+ int rc = app.main(argc, argv);
+ return rc;
+}
diff --git a/cpp/test/IceGrid/update/Test.cpp b/cpp/test/IceGrid/update/Test.cpp
new file mode 100644
index 00000000000..48e5c2fd087
--- /dev/null
+++ b/cpp/test/IceGrid/update/Test.cpp
@@ -0,0 +1,471 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+// Ice version 2.1.0
+// Generated from file `Test.ice'
+
+#include <Test.h>
+#include <Ice/LocalException.h>
+#include <Ice/ObjectFactory.h>
+#include <Ice/BasicStream.h>
+#include <Ice/Object.h>
+
+#ifndef ICE_IGNORE_VERSION
+# if ICE_INT_VERSION / 100 != 201
+# error Ice version mismatch!
+# endif
+# if ICE_INT_VERSION % 100 < 0
+# error Ice patch level mismatch!
+# endif
+#endif
+
+void
+IceInternal::incRef(::Test::TestIntf* p)
+{
+ p->__incRef();
+}
+
+void
+IceInternal::decRef(::Test::TestIntf* p)
+{
+ p->__decRef();
+}
+
+void
+IceInternal::incRef(::IceProxy::Test::TestIntf* p)
+{
+ p->__incRef();
+}
+
+void
+IceInternal::decRef(::IceProxy::Test::TestIntf* p)
+{
+ p->__decRef();
+}
+
+void
+Test::__write(::IceInternal::BasicStream* __os, const ::Test::TestIntfPrx& v)
+{
+ __os->write(::Ice::ObjectPrx(v));
+}
+
+void
+Test::__read(::IceInternal::BasicStream* __is, ::Test::TestIntfPrx& v)
+{
+ ::Ice::ObjectPrx proxy;
+ __is->read(proxy);
+ if(!proxy)
+ {
+ v = 0;
+ }
+ else
+ {
+ v = new ::IceProxy::Test::TestIntf;
+ v->__copyFrom(proxy);
+ }
+}
+
+void
+Test::__write(::IceInternal::BasicStream* __os, const ::Test::TestIntfPtr& v)
+{
+ __os->write(::Ice::ObjectPtr(v));
+}
+
+void
+IceProxy::Test::TestIntf::shutdown()
+{
+ shutdown(__defaultContext());
+}
+
+void
+IceProxy::Test::TestIntf::shutdown(const ::Ice::Context& __ctx)
+{
+ int __cnt = 0;
+ while(true)
+ {
+ try
+ {
+ ::IceInternal::Handle< ::IceDelegate::Ice::Object> __delBase = __getDelegate();
+ ::IceDelegate::Test::TestIntf* __del = dynamic_cast< ::IceDelegate::Test::TestIntf*>(__delBase.get());
+ __del->shutdown(__ctx);
+ return;
+ }
+ catch(const ::IceInternal::NonRepeatable& __ex)
+ {
+ __rethrowException(*__ex.get());
+ }
+ catch(const ::Ice::LocalException& __ex)
+ {
+ __handleException(__ex, __cnt);
+ }
+ }
+}
+
+::std::string
+IceProxy::Test::TestIntf::getProperty(const ::std::string& name)
+{
+ return getProperty(name, __defaultContext());
+}
+
+::std::string
+IceProxy::Test::TestIntf::getProperty(const ::std::string& name, const ::Ice::Context& __ctx)
+{
+ int __cnt = 0;
+ while(true)
+ {
+ try
+ {
+ __checkTwowayOnly("getProperty");
+ ::IceInternal::Handle< ::IceDelegate::Ice::Object> __delBase = __getDelegate();
+ ::IceDelegate::Test::TestIntf* __del = dynamic_cast< ::IceDelegate::Test::TestIntf*>(__delBase.get());
+ return __del->getProperty(name, __ctx);
+ }
+ catch(const ::IceInternal::NonRepeatable& __ex)
+ {
+ __rethrowException(*__ex.get());
+ }
+ catch(const ::Ice::LocalException& __ex)
+ {
+ __handleException(__ex, __cnt);
+ }
+ }
+}
+
+const ::std::string&
+IceProxy::Test::TestIntf::ice_staticId()
+{
+ return ::Test::TestIntf::ice_staticId();
+}
+
+::IceInternal::Handle< ::IceDelegateM::Ice::Object>
+IceProxy::Test::TestIntf::__createDelegateM()
+{
+ return ::IceInternal::Handle< ::IceDelegateM::Ice::Object>(new ::IceDelegateM::Test::TestIntf);
+}
+
+::IceInternal::Handle< ::IceDelegateD::Ice::Object>
+IceProxy::Test::TestIntf::__createDelegateD()
+{
+ return ::IceInternal::Handle< ::IceDelegateD::Ice::Object>(new ::IceDelegateD::Test::TestIntf);
+}
+
+bool
+IceProxy::Test::operator==(const ::IceProxy::Test::TestIntf& l, const ::IceProxy::Test::TestIntf& r)
+{
+ return static_cast<const ::IceProxy::Ice::Object&>(l) == static_cast<const ::IceProxy::Ice::Object&>(r);
+}
+
+bool
+IceProxy::Test::operator!=(const ::IceProxy::Test::TestIntf& l, const ::IceProxy::Test::TestIntf& r)
+{
+ return static_cast<const ::IceProxy::Ice::Object&>(l) != static_cast<const ::IceProxy::Ice::Object&>(r);
+}
+
+bool
+IceProxy::Test::operator<(const ::IceProxy::Test::TestIntf& l, const ::IceProxy::Test::TestIntf& r)
+{
+ return static_cast<const ::IceProxy::Ice::Object&>(l) < static_cast<const ::IceProxy::Ice::Object&>(r);
+}
+
+static const ::std::string __Test__TestIntf__shutdown_name = "shutdown";
+
+void
+IceDelegateM::Test::TestIntf::shutdown(const ::Ice::Context& __context)
+{
+ ::IceInternal::Outgoing __og(__connection.get(), __reference.get(), __Test__TestIntf__shutdown_name, static_cast< ::Ice::OperationMode>(0), __context, __compress);
+ bool __ok = __og.invoke();
+ try
+ {
+ ::IceInternal::BasicStream* __is = __og.is();
+ if(!__ok)
+ {
+ __is->throwException();
+ }
+ }
+ catch(const ::Ice::UserException&)
+ {
+ throw ::Ice::UnknownUserException(__FILE__, __LINE__);
+ }
+ catch(const ::Ice::LocalException& __ex)
+ {
+ throw ::IceInternal::NonRepeatable(__ex);
+ }
+}
+
+static const ::std::string __Test__TestIntf__getProperty_name = "getProperty";
+
+::std::string
+IceDelegateM::Test::TestIntf::getProperty(const ::std::string& name, const ::Ice::Context& __context)
+{
+ ::IceInternal::Outgoing __og(__connection.get(), __reference.get(), __Test__TestIntf__getProperty_name, static_cast< ::Ice::OperationMode>(0), __context, __compress);
+ try
+ {
+ ::IceInternal::BasicStream* __os = __og.os();
+ __os->write(name);
+ }
+ catch(const ::Ice::LocalException& __ex)
+ {
+ __og.abort(__ex);
+ }
+ bool __ok = __og.invoke();
+ try
+ {
+ ::IceInternal::BasicStream* __is = __og.is();
+ if(!__ok)
+ {
+ __is->throwException();
+ }
+ ::std::string __ret;
+ __is->read(__ret);
+ return __ret;
+ }
+ catch(const ::Ice::UserException&)
+ {
+ throw ::Ice::UnknownUserException(__FILE__, __LINE__);
+ }
+ catch(const ::Ice::LocalException& __ex)
+ {
+ throw ::IceInternal::NonRepeatable(__ex);
+ }
+}
+
+void
+IceDelegateD::Test::TestIntf::shutdown(const ::Ice::Context& __context)
+{
+ ::Ice::Current __current;
+ __initCurrent(__current, "shutdown", static_cast< ::Ice::OperationMode>(0), __context);
+ while(true)
+ {
+ ::IceInternal::Direct __direct(__current);
+ ::Test::TestIntf* __servant = dynamic_cast< ::Test::TestIntf*>(__direct.servant().get());
+ if(!__servant)
+ {
+ ::Ice::OperationNotExistException __opEx(__FILE__, __LINE__);
+ __opEx.id = __current.id;
+ __opEx.facet = __current.facet;
+ __opEx.operation = __current.operation;
+ throw __opEx;
+ }
+ try
+ {
+ __servant->shutdown(__current);
+ return;
+ }
+ catch(const ::Ice::LocalException& __ex)
+ {
+ throw ::IceInternal::NonRepeatable(__ex);
+ }
+ }
+}
+
+::std::string
+IceDelegateD::Test::TestIntf::getProperty(const ::std::string& name, const ::Ice::Context& __context)
+{
+ ::Ice::Current __current;
+ __initCurrent(__current, "getProperty", static_cast< ::Ice::OperationMode>(0), __context);
+ while(true)
+ {
+ ::IceInternal::Direct __direct(__current);
+ ::Test::TestIntf* __servant = dynamic_cast< ::Test::TestIntf*>(__direct.servant().get());
+ if(!__servant)
+ {
+ ::Ice::OperationNotExistException __opEx(__FILE__, __LINE__);
+ __opEx.id = __current.id;
+ __opEx.facet = __current.facet;
+ __opEx.operation = __current.operation;
+ throw __opEx;
+ }
+ try
+ {
+ return __servant->getProperty(name, __current);
+ }
+ catch(const ::Ice::LocalException& __ex)
+ {
+ throw ::IceInternal::NonRepeatable(__ex);
+ }
+ }
+}
+
+static const ::std::string __Test__TestIntf_ids[2] =
+{
+ "::Ice::Object",
+ "::Test::TestIntf"
+};
+
+bool
+Test::TestIntf::ice_isA(const ::std::string& _s, const ::Ice::Current&) const
+{
+ return ::std::binary_search(__Test__TestIntf_ids, __Test__TestIntf_ids + 2, _s);
+}
+
+::std::vector< ::std::string>
+Test::TestIntf::ice_ids(const ::Ice::Current&) const
+{
+ return ::std::vector< ::std::string>(&__Test__TestIntf_ids[0], &__Test__TestIntf_ids[2]);
+}
+
+const ::std::string&
+Test::TestIntf::ice_id(const ::Ice::Current&) const
+{
+ return __Test__TestIntf_ids[1];
+}
+
+const ::std::string&
+Test::TestIntf::ice_staticId()
+{
+ return __Test__TestIntf_ids[1];
+}
+
+::IceInternal::DispatchStatus
+Test::TestIntf::___shutdown(::IceInternal::Incoming& __inS, const ::Ice::Current& __current)
+{
+ shutdown(__current);
+ return ::IceInternal::DispatchOK;
+}
+
+::IceInternal::DispatchStatus
+Test::TestIntf::___getProperty(::IceInternal::Incoming& __inS, const ::Ice::Current& __current)
+{
+ ::IceInternal::BasicStream* __is = __inS.is();
+ ::IceInternal::BasicStream* __os = __inS.os();
+ ::std::string name;
+ __is->read(name);
+ ::std::string __ret = getProperty(name, __current);
+ __os->write(__ret);
+ return ::IceInternal::DispatchOK;
+}
+
+static ::std::string __Test__TestIntf_all[] =
+{
+ "getProperty",
+ "ice_id",
+ "ice_ids",
+ "ice_isA",
+ "ice_ping",
+ "shutdown"
+};
+
+::IceInternal::DispatchStatus
+Test::TestIntf::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)
+{
+ ::std::pair< ::std::string*, ::std::string*> r = ::std::equal_range(__Test__TestIntf_all, __Test__TestIntf_all + 6, current.operation);
+ if(r.first == r.second)
+ {
+ return ::IceInternal::DispatchOperationNotExist;
+ }
+
+ switch(r.first - __Test__TestIntf_all)
+ {
+ case 0:
+ {
+ return ___getProperty(in, current);
+ }
+ case 1:
+ {
+ return ___ice_id(in, current);
+ }
+ case 2:
+ {
+ return ___ice_ids(in, current);
+ }
+ case 3:
+ {
+ return ___ice_isA(in, current);
+ }
+ case 4:
+ {
+ return ___ice_ping(in, current);
+ }
+ case 5:
+ {
+ return ___shutdown(in, current);
+ }
+ }
+
+ assert(false);
+ return ::IceInternal::DispatchOperationNotExist;
+}
+
+void
+Test::TestIntf::__write(::IceInternal::BasicStream* __os) const
+{
+ __os->writeTypeId(ice_staticId());
+ __os->startWriteSlice();
+ __os->endWriteSlice();
+#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug
+ Object::__write(__os);
+#else
+ ::Ice::Object::__write(__os);
+#endif
+}
+
+void
+Test::TestIntf::__read(::IceInternal::BasicStream* __is, bool __rid)
+{
+ if(__rid)
+ {
+ ::std::string myId;
+ __is->readTypeId(myId);
+ }
+ __is->startReadSlice();
+ __is->endReadSlice();
+#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug
+ Object::__read(__is, true);
+#else
+ ::Ice::Object::__read(__is, true);
+#endif
+}
+
+void
+Test::TestIntf::__write(const ::Ice::OutputStreamPtr&) const
+{
+ Ice::MarshalException ex(__FILE__, __LINE__);
+ ex.reason = "type Test::TestIntf was not generated with stream support";
+ throw ex;
+}
+
+void
+Test::TestIntf::__read(const ::Ice::InputStreamPtr&, bool)
+{
+ Ice::MarshalException ex(__FILE__, __LINE__);
+ ex.reason = "type Test::TestIntf was not generated with stream support";
+ throw ex;
+}
+
+void
+Test::__patch__TestIntfPtr(void* __addr, ::Ice::ObjectPtr& v)
+{
+ ::Test::TestIntfPtr* p = static_cast< ::Test::TestIntfPtr*>(__addr);
+ assert(p);
+ *p = ::Test::TestIntfPtr::dynamicCast(v);
+ if(v && !*p)
+ {
+ ::Ice::NoObjectFactoryException e(__FILE__, __LINE__);
+ e.type = ::Test::TestIntf::ice_staticId();
+ throw e;
+ }
+}
+
+bool
+Test::operator==(const ::Test::TestIntf& l, const ::Test::TestIntf& r)
+{
+ return static_cast<const ::Ice::Object&>(l) == static_cast<const ::Ice::Object&>(r);
+}
+
+bool
+Test::operator!=(const ::Test::TestIntf& l, const ::Test::TestIntf& r)
+{
+ return static_cast<const ::Ice::Object&>(l) != static_cast<const ::Ice::Object&>(r);
+}
+
+bool
+Test::operator<(const ::Test::TestIntf& l, const ::Test::TestIntf& r)
+{
+ return static_cast<const ::Ice::Object&>(l) < static_cast<const ::Ice::Object&>(r);
+}
diff --git a/cpp/test/IceGrid/update/Test.ice b/cpp/test/IceGrid/update/Test.ice
new file mode 100644
index 00000000000..1d7c73a9d88
--- /dev/null
+++ b/cpp/test/IceGrid/update/Test.ice
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef TEST_ICE
+#define TEST_ICE
+
+module Test
+{
+
+interface TestIntf
+{
+ void shutdown();
+
+ string getProperty(string name);
+};
+
+};
+
+#endif
diff --git a/cpp/test/IceGrid/update/TestI.cpp b/cpp/test/IceGrid/update/TestI.cpp
new file mode 100644
index 00000000000..f33c9a227a9
--- /dev/null
+++ b/cpp/test/IceGrid/update/TestI.cpp
@@ -0,0 +1,29 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <TestI.h>
+
+TestI::TestI(const Ice::ObjectAdapterPtr& adapter, const Ice::PropertiesPtr& properties) :
+ _adapter(adapter),
+ _properties(properties)
+{
+}
+
+void
+TestI::shutdown(const Ice::Current&)
+{
+ _adapter->getCommunicator()->shutdown();
+}
+
+std::string
+TestI::getProperty(const std::string& name, const Ice::Current&)
+{
+ return _properties->getProperty(name);
+}
diff --git a/cpp/test/IceGrid/update/db/.dummy b/cpp/test/IceGrid/update/db/.dummy
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/cpp/test/IceGrid/update/db/.dummy
diff --git a/cpp/test/IceGrid/update/run.py b/cpp/test/IceGrid/update/run.py
new file mode 100755
index 00000000000..6f94ef3559b
--- /dev/null
+++ b/cpp/test/IceGrid/update/run.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys
+
+for toplevel in [".", "..", "../..", "../../..", "../../../.."]:
+ toplevel = os.path.normpath(toplevel)
+ if os.path.exists(os.path.join(toplevel, "config", "TestUtil.py")):
+ break
+else:
+ raise "can't find toplevel directory!"
+
+sys.path.append(os.path.join(toplevel, "config"))
+import TestUtil
+import IceGridAdmin
+
+name = os.path.join("IceGrid", "update")
+testdir = os.path.join(toplevel, "test", name)
+client = os.path.join(testdir, "client")
+
+#
+# Add locator options for the client and server. Since the server
+# invokes on the locator it's also considered to be a client.
+#
+additionalOptions = " --Ice.Default.Locator=\"IceGrid/Locator:default -p 12345\" " + \
+ "--Ice.PrintAdapterReady=0 --Ice.PrintProcessId=0"
+
+IceGridAdmin.cleanDbDir(os.path.join(testdir, "db"))
+iceGridRegistryThread = IceGridAdmin.startIceGridRegistry("12345", testdir)
+iceGridNodeThread = IceGridAdmin.startIceGridNode(testdir)
+
+print "starting client...",
+clientPipe = os.popen(client + TestUtil.clientServerOptions + additionalOptions + " 2>&1")
+print "ok"
+
+try:
+ TestUtil.printOutputFromPipe(clientPipe)
+except:
+ pass
+
+clientStatus = clientPipe.close()
+if clientStatus:
+ TestUtil.killServers()
+ sys.exit(1)
+
+IceGridAdmin.shutdownIceGridNode()
+iceGridNodeThread.join()
+IceGridAdmin.shutdownIceGridRegistry()
+iceGridRegistryThread.join()
+
+sys.exit(0)