summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/IceGrid/DescriptorHelper.cpp104
-rw-r--r--cpp/src/IceGrid/DescriptorHelper.h16
-rw-r--r--cpp/src/IceGrid/DescriptorParser.cpp53
-rw-r--r--cpp/src/IceGrid/LocatorI.cpp5
-rw-r--r--cpp/src/IceGrid/TraceLevels.cpp2
-rw-r--r--cpp/test/IceGrid/deployer/AllTests.cpp17
-rw-r--r--cpp/test/IceGrid/deployer/Client.cpp10
-rw-r--r--cpp/test/IceGrid/deployer/application.xml1
-rw-r--r--cpp/test/IceGrid/deployer/application_with_templates.xml102
-rwxr-xr-xcpp/test/IceGrid/deployer/run.py14
10 files changed, 249 insertions, 75 deletions
diff --git a/cpp/src/IceGrid/DescriptorHelper.cpp b/cpp/src/IceGrid/DescriptorHelper.cpp
index b78818e2b39..0439111e33d 100644
--- a/cpp/src/IceGrid/DescriptorHelper.cpp
+++ b/cpp/src/IceGrid/DescriptorHelper.cpp
@@ -9,6 +9,7 @@
#include <Ice/Ice.h>
#include <IceGrid/DescriptorHelper.h>
+#include <IceGrid/Util.h>
#include <iterator>
@@ -20,7 +21,7 @@ namespace IceGrid
struct Substitute : unary_function<string&, void>
{
- Substitute(const DescriptorVariablesPtr& variables, vector<string>& missing) :
+ Substitute(const DescriptorVariablesPtr& variables, set<string>& missing) :
_variables(variables), _missing(missing)
{
}
@@ -31,18 +32,20 @@ struct Substitute : unary_function<string&, void>
}
const DescriptorVariablesPtr& _variables;
- vector<string>& _missing;
+ set<string>& _missing;
};
}
DescriptorVariables::DescriptorVariables() :
- _ignoreMissing(false)
+ _ignoreMissing(false),
+ _escape(true)
{
}
DescriptorVariables::DescriptorVariables(const map<string, string>& variables) :
- _ignoreMissing(false)
+ _ignoreMissing(false),
+ _escape(true)
{
reset(variables);
}
@@ -50,12 +53,12 @@ DescriptorVariables::DescriptorVariables(const map<string, string>& variables) :
string
DescriptorVariables::substitute(const string& v) const
{
- vector<string> missing;
+ set<string> missing;
return substituteImpl(v, _ignoreMissing, missing);
}
string
-DescriptorVariables::substituteWithMissing(const string& v, vector<string>& missing) const
+DescriptorVariables::substituteWithMissing(const string& v, set<string>& missing) const
{
return substituteImpl(v, true, missing);
}
@@ -144,6 +147,12 @@ DescriptorVariables::ignoreMissing(bool ignoreMissing)
_ignoreMissing = ignoreMissing;
}
+void
+DescriptorVariables::escape(bool escape)
+{
+ _escape = escape;
+}
+
string&
DescriptorVariables::operator[](const string& name)
{
@@ -151,7 +160,7 @@ DescriptorVariables::operator[](const string& name)
}
string
-DescriptorVariables::substituteImpl(const string& v, bool ignoreMissing, vector<string>& missing) const
+DescriptorVariables::substituteImpl(const string& v, bool ignoreMissing, set<string>& missing) const
{
string value(v);
string::size_type beg = 0;
@@ -159,23 +168,26 @@ DescriptorVariables::substituteImpl(const string& v, bool ignoreMissing, vector<
while((beg = value.find("${", beg)) != string::npos)
{
- if(beg > 0 && value[beg - 1] == '$')
+ if(_escape)
{
- string::size_type escape = beg - 1;
- while(escape > 0 && value[escape - 1] == '$')
- {
- --escape;
- }
-
- value.replace(escape, beg - escape, (beg - escape) / 2, '$');
- if((beg - escape) % 2)
- {
- ++beg;
- continue;
- }
- else
+ if(beg > 0 && value[beg - 1] == '$')
{
- beg -= (beg - escape) / 2;
+ string::size_type escape = beg - 1;
+ while(escape > 0 && value[escape - 1] == '$')
+ {
+ --escape;
+ }
+
+ value.replace(escape, beg - escape, (beg - escape) / 2, '$');
+ if((beg - escape) % 2)
+ {
+ ++beg;
+ continue;
+ }
+ else
+ {
+ beg -= (beg - escape) / 2;
+ }
}
}
@@ -195,7 +207,7 @@ DescriptorVariables::substituteImpl(const string& v, bool ignoreMissing, vector<
}
else
{
- missing.push_back(name);
+ missing.insert(name);
++beg;
continue;
}
@@ -203,15 +215,8 @@ DescriptorVariables::substituteImpl(const string& v, bool ignoreMissing, vector<
else
{
string val = getVariable(name);
- if(val != value.substr(beg, end - beg + 1))
- {
- value.replace(beg, end - beg + 1, val);
- }
- else
- {
- ++beg;
- continue;
- }
+ value.replace(beg, end - beg + 1, val);
+ beg += val.length();
}
}
@@ -236,7 +241,7 @@ DescriptorTemplates::instantiateServer(const DescriptorHelper& helper, const str
throw "unknown template `" + name + "'";
}
- vector<string> missing;
+ set<string> missing;
Substitute substitute(helper.getVariables(), missing);
map<string, string> attributes = attrs;
for(map<string, string>::iterator p = attributes.begin(); p != attributes.end(); ++p)
@@ -269,7 +274,7 @@ DescriptorTemplates::instantiateService(const DescriptorHelper& helper, const st
throw "unknown template `" + name + "'";
}
- vector<string> missing;
+ set<string> missing;
Substitute substitute(helper.getVariables(), missing);
map<string, string> attributes = attrs;
for(map<string, string>::iterator p = attributes.begin(); p != attributes.end(); ++p)
@@ -615,7 +620,7 @@ ComponentDescriptorHelper::addDbEnvProperty(const IceXML::Attributes& attrs)
}
void
-ComponentDescriptorHelper::instantiateImpl(const ComponentDescriptorPtr& desc, vector<string>& missing) const
+ComponentDescriptorHelper::instantiateImpl(const ComponentDescriptorPtr& desc, set<string>& missing) const
{
Substitute substitute(_variables, missing);
substitute(desc->name);
@@ -929,7 +934,7 @@ ServerDescriptorHelper::addJvmOption(const string& option)
}
ServerDescriptorPtr
-ServerDescriptorHelper::instantiate(vector<string>& missing) const
+ServerDescriptorHelper::instantiate(set<string>& missing) const
{
ServerDescriptorPtr desc = ServerDescriptorPtr::dynamicCast(_descriptor->ice_clone());
instantiateImpl(desc, missing);
@@ -937,11 +942,12 @@ ServerDescriptorHelper::instantiate(vector<string>& missing) const
}
void
-ServerDescriptorHelper::instantiateImpl(const ServerDescriptorPtr& desc, vector<string>& missing) const
+ServerDescriptorHelper::instantiateImpl(const ServerDescriptorPtr& desc, set<string>& missing) const
{
ComponentDescriptorHelper::instantiateImpl(desc, missing);
Substitute substitute(_variables, missing);
+ substitute(desc->node);
substitute(desc->exe);
substitute(desc->pwd);
for_each(desc->options.begin(), desc->options.end(), substitute);
@@ -952,6 +958,26 @@ ServerDescriptorHelper::instantiateImpl(const ServerDescriptorPtr& desc, vector<
substitute(javaDesc->className);
for_each(javaDesc->jvmOptions.begin(), javaDesc->jvmOptions.end(), substitute);
}
+
+ ServiceDescriptorSeq services = IceGrid::getServices(desc);
+ if(!services.empty())
+ {
+ ServiceDescriptorSeq newServices;
+ for(ServiceDescriptorSeq::const_iterator p = services.begin(); p != services.end(); ++p)
+ {
+ newServices.push_back(ServiceDescriptorHelper(*this, *p).instantiate(missing));
+ }
+ CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(desc);
+ if(cppIceBox)
+ {
+ cppIceBox->services.swap(newServices);
+ }
+ JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(desc);
+ if(javaIceBox)
+ {
+ javaIceBox->services.swap(newServices);
+ }
+ }
}
ServiceDescriptorHelper::ServiceDescriptorHelper(const DescriptorHelper& helper, const ServiceDescriptorPtr& desc) :
@@ -988,7 +1014,7 @@ ServiceDescriptorHelper::operator==(const ServiceDescriptorHelper& helper) const
}
ServiceDescriptorPtr
-ServiceDescriptorHelper::instantiate(vector<string>& missing) const
+ServiceDescriptorHelper::instantiate(set<string>& missing) const
{
ServiceDescriptorPtr desc = ServiceDescriptorPtr::dynamicCast(_descriptor->ice_clone());
instantiateImpl(desc, missing);
@@ -1002,7 +1028,7 @@ ServiceDescriptorHelper::getDescriptor() const
}
void
-ServiceDescriptorHelper::instantiateImpl(const ServiceDescriptorPtr& desc, vector<string>& missing) const
+ServiceDescriptorHelper::instantiateImpl(const ServiceDescriptorPtr& desc, set<string>& missing) const
{
ComponentDescriptorHelper::instantiateImpl(desc, missing);
diff --git a/cpp/src/IceGrid/DescriptorHelper.h b/cpp/src/IceGrid/DescriptorHelper.h
index 13367095b01..d06da6224ee 100644
--- a/cpp/src/IceGrid/DescriptorHelper.h
+++ b/cpp/src/IceGrid/DescriptorHelper.h
@@ -24,7 +24,7 @@ public:
DescriptorVariables(const std::map<std::string, std::string>&);
std::string substitute(const std::string&) const;
- std::string substituteWithMissing(const std::string&, std::vector<std::string>&) const;
+ std::string substituteWithMissing(const std::string&, std::set<std::string>&) const;
std::string getVariable(const std::string&) const;
bool hasVariable(const std::string&) const;
void remove(const std::string&);
@@ -37,13 +37,15 @@ public:
std::string& operator[](const std::string&);
void ignoreMissing(bool);
+ void escape(bool);
private:
- std::string substituteImpl(const std::string&, bool, std::vector<std::string>&) const;
+ std::string substituteImpl(const std::string&, bool, std::set<std::string>&) const;
std::vector<std::map<std::string, std::string> > _variables;
bool _ignoreMissing;
+ bool _escape;
};
typedef IceUtil::Handle<DescriptorVariables> DescriptorVariablesPtr;
@@ -145,7 +147,7 @@ public:
protected:
void init(const ComponentDescriptorPtr&, const IceXML::Attributes& = IceXML::Attributes());
- virtual void instantiateImpl(const ComponentDescriptorPtr&, std::vector<std::string>&) const;
+ virtual void instantiateImpl(const ComponentDescriptorPtr&, std::set<std::string>&) const;
private:
@@ -161,7 +163,7 @@ public:
ServerDescriptorHelper(const Ice::CommunicatorPtr&, const DescriptorVariablesPtr&, const IceXML::Attributes&);
bool operator==(const ServerDescriptorHelper&) const;
- virtual ServerDescriptorPtr instantiate(std::vector<std::string>&) const;
+ virtual ServerDescriptorPtr instantiate(std::set<std::string>&) const;
const ServerDescriptorPtr& getDescriptor() const;
ServiceDescriptorHelper* addService(const IceXML::Attributes&);
@@ -172,7 +174,7 @@ public:
private:
void initFromXml(const IceXML::Attributes&);
- virtual void instantiateImpl(const ServerDescriptorPtr&, std::vector<std::string>&) const;
+ virtual void instantiateImpl(const ServerDescriptorPtr&, std::set<std::string>&) const;
ServerDescriptorPtr _descriptor;
};
@@ -185,12 +187,12 @@ public:
ServiceDescriptorHelper(const DescriptorHelper&, const IceXML::Attributes&);
bool operator==(const ServiceDescriptorHelper&) const;
- virtual ServiceDescriptorPtr instantiate(std::vector<std::string>&) const;
+ virtual ServiceDescriptorPtr instantiate(std::set<std::string>&) const;
const ServiceDescriptorPtr& getDescriptor() const;
private:
- virtual void instantiateImpl(const ServiceDescriptorPtr&, std::vector<std::string>&) const;
+ virtual void instantiateImpl(const ServiceDescriptorPtr&, std::set<std::string>&) const;
ServiceDescriptorPtr _descriptor;
};
diff --git a/cpp/src/IceGrid/DescriptorParser.cpp b/cpp/src/IceGrid/DescriptorParser.cpp
index 0f05254b19d..f18f4fd8bdc 100644
--- a/cpp/src/IceGrid/DescriptorParser.cpp
+++ b/cpp/src/IceGrid/DescriptorParser.cpp
@@ -229,6 +229,8 @@ DescriptorHandler::startElement(const string& name, const IceXML::Attributes& at
error("the <server> element can only be a child of a <node> element");
}
+ _variables->push();
+
if(!_currentApplication.get())
{
_currentServer.reset(new ServerDescriptorHelper(_communicator, _variables, attrs));
@@ -246,7 +248,12 @@ DescriptorHandler::startElement(const string& name, const IceXML::Attributes& at
{
error("element <server-template> inside a server definition");
}
+
+ _variables->push();
_variables->ignoreMissing(true);
+ _variables->escape(false);
+ (*_variables)["node"] = "${node}";
+
_currentServer.reset(_currentApplication->addServerTemplate(attrs));
_currentComponent = _currentServer.get();
(*_variables)["server"] = _currentServer->getDescriptor()->name;
@@ -257,6 +264,8 @@ DescriptorHandler::startElement(const string& name, const IceXML::Attributes& at
{
error("element <service> inside a service definition");
}
+
+ _variables->push();
_currentService.reset(_currentServer->addService(attrs));
_currentComponent = _currentService.get();
@@ -268,10 +277,16 @@ DescriptorHandler::startElement(const string& name, const IceXML::Attributes& at
{
error("element <service-template> inside a service definition");
}
+
+ _variables->push();
_variables->ignoreMissing(true);
+ _variables->escape(false);
+
+ (*_variables)["node"] = "${node}";
+ (*_variables)["server"] = "${server}";
+
_currentService.reset(_currentApplication->addServiceTemplate(attrs));
_currentComponent = _currentService.get();
- (*_variables)["server"] = "${server}";
(*_variables)["service"] = _currentService->getDescriptor()->name;
}
else if(name == "variable")
@@ -382,16 +397,23 @@ DescriptorHandler::endElement(const string& name, int line, int column)
_currentServer.reset(0);
}
_currentComponent = 0;
- _variables->ignoreMissing(false);
- _variables->remove("server");
+ if(name == "server-template")
+ {
+ _variables->ignoreMissing(false);
+ _variables->escape(true);
+ }
+ _variables->pop();
}
else if(name == "service" || name == "service-template")
{
_currentService.reset(0);
_currentComponent = _currentServer.get();
- _variables->ignoreMissing(false);
- _variables->remove("service");
- _variables->remove("server");
+ if(name == "service-template")
+ {
+ _variables->ignoreMissing(false);
+ _variables->escape(true);
+ }
+ _variables->pop();
}
else if(name == "comment")
{
@@ -578,28 +600,19 @@ DescriptorHandler::isTargetDeployable(const string& target) const
string fqn;
if(!application.empty())
{
- fqn = application;
- if(!node.empty())
- {
- fqn += "." + node;
- }
+ fqn += (fqn.empty() ? "" : ".") + application;
}
- else
+ if(!node.empty())
{
- if(!node.empty())
- {
- fqn = node;
- }
+ fqn += (fqn.empty() ? "" : ".") + node;
}
if(!server.empty())
{
- assert(!node.empty());
- fqn += "." + server;
+ fqn += (fqn.empty() ? "" : ".") + server;
}
if(!service.empty())
{
- assert(!server.empty());
- fqn += "." + service;
+ fqn += (fqn.empty() ? "" : ".") + service;
}
//
diff --git a/cpp/src/IceGrid/LocatorI.cpp b/cpp/src/IceGrid/LocatorI.cpp
index 16986ada9b0..7b6a4e3c840 100644
--- a/cpp/src/IceGrid/LocatorI.cpp
+++ b/cpp/src/IceGrid/LocatorI.cpp
@@ -210,6 +210,11 @@ LocatorI::findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr& cb,
{
throw Ice::AdapterNotFoundException();
}
+ catch(const NodeUnreachableException&)
+ {
+ cb->ice_response(0);
+ return;
+ }
LocatorIPtr self = const_cast<LocatorI*>(this);
if(self->getDirectProxyRequest(cb, adapter))
diff --git a/cpp/src/IceGrid/TraceLevels.cpp b/cpp/src/IceGrid/TraceLevels.cpp
index 39b71017c86..ec4e913b83b 100644
--- a/cpp/src/IceGrid/TraceLevels.cpp
+++ b/cpp/src/IceGrid/TraceLevels.cpp
@@ -28,7 +28,7 @@ TraceLevels::TraceLevels(const Ice::PropertiesPtr& properties, const Ice::Logger
activatorCat("Activator"),
logger(theLogger)
{
- string keyBase = isNode ? "IceGrid.Node." : "IceGrid.Registry.";
+ string keyBase = isNode ? "IceGrid.Node.Trace." : "IceGrid.Registry.Trace.";
const_cast<int&>(application) = properties->getPropertyAsInt(keyBase + applicationCat);
const_cast<int&>(node) = properties->getPropertyAsInt(keyBase + nodeCat);
const_cast<int&>(server) = properties->getPropertyAsInt(keyBase + serverCat);
diff --git a/cpp/test/IceGrid/deployer/AllTests.cpp b/cpp/test/IceGrid/deployer/AllTests.cpp
index a6d3d3194e8..bb282ef98fd 100644
--- a/cpp/test/IceGrid/deployer/AllTests.cpp
+++ b/cpp/test/IceGrid/deployer/AllTests.cpp
@@ -86,7 +86,7 @@ allCommonTests(const Ice::CommunicatorPtr& communicator)
}
void
-allTests(const Ice::CommunicatorPtr& communicator)
+allTests(const Ice::CommunicatorPtr& communicator, bool withTemplates)
{
allCommonTests(communicator);
@@ -128,12 +128,17 @@ allTests(const Ice::CommunicatorPtr& communicator)
test(obj->getProperty("ManyEscape") == "$$$${name}");
obj = TestIntfPrx::checkedCast(communicator->stringToProxy("Server2@Server2.Server"));
- test(obj->getProperty("Target1") == "1");
- test(obj->getProperty("Target2") == "1");
+ if(!withTemplates)
+ {
+ test(obj->getProperty("Target1") == "1");
+ test(obj->getProperty("Target2") == "1");
+ }
test(obj->getProperty("Variable") == "val0prop");
- test(obj->getProperty("Variable1") == "val0target1");
- test(obj->getProperty("Variable2") == "val0target2");
-
+ if(!withTemplates)
+ {
+ test(obj->getProperty("Variable1") == "val0target1");
+ test(obj->getProperty("Variable2") == "val0target2");
+ }
cout << "ok" << endl;
cout << "testing service configuration... " << flush;
diff --git a/cpp/test/IceGrid/deployer/Client.cpp b/cpp/test/IceGrid/deployer/Client.cpp
index ccd7533ff93..785c8e43120 100644
--- a/cpp/test/IceGrid/deployer/Client.cpp
+++ b/cpp/test/IceGrid/deployer/Client.cpp
@@ -17,6 +17,7 @@ int
run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
{
bool withTarget = false;
+ bool withTemplates = false;
if(argc > 1)
{
int i = 1;
@@ -27,14 +28,19 @@ run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
withTarget = true;
break;
}
+ else if(strcmp(argv[i], "-e") == 0)
+ {
+ withTemplates = true;
+ break;
+ }
i++;
}
}
if(!withTarget)
{
- void allTests(const Ice::CommunicatorPtr&);
- allTests(communicator);
+ void allTests(const Ice::CommunicatorPtr&, bool);
+ allTests(communicator, withTemplates);
}
else
{
diff --git a/cpp/test/IceGrid/deployer/application.xml b/cpp/test/IceGrid/deployer/application.xml
index 554d6a7ac9f..8353d994da0 100644
--- a/cpp/test/IceGrid/deployer/application.xml
+++ b/cpp/test/IceGrid/deployer/application.xml
@@ -10,6 +10,7 @@
<include name="Server2" descriptor="server.xml" targets="target1 target2"/>
</node>
+
</application>
</icegrid> \ No newline at end of file
diff --git a/cpp/test/IceGrid/deployer/application_with_templates.xml b/cpp/test/IceGrid/deployer/application_with_templates.xml
new file mode 100644
index 00000000000..f999c931b98
--- /dev/null
+++ b/cpp/test/IceGrid/deployer/application_with_templates.xml
@@ -0,0 +1,102 @@
+<icegrid>
+
+ <application name="test">
+
+ <server-template id="ServerTemplate" name="${name}" kind="cpp" exe="${test.dir}/server" activation="on-demand">
+ <variable name="var0" value="val0"/>
+
+ <option>--Test.Test=2</option>
+ <option>--Test.Test1=0</option>
+
+ <target name="manual">
+ <properties>
+ <property name="Mode" value="manual"/>
+ </properties>
+ </target>
+
+ <adapters>
+ <adapter name="Server" endpoints="default">
+ <object identity="${server}" type="::Test"/>
+ </adapter>
+ </adapters>
+
+ <properties>
+ <variable name="var0" value="val0prop"/>
+ <property name="Variable" value="${var0}"/>
+ <property name="Type" value="Server"/>
+ <property name="Name" value="${name}"/>
+ <property name="NameName" value="${name}${name}"/>
+ <property name="NameEscaped" value="$${name}"/>
+ <property name="NameEscapeEscaped" value="$$${name}"/>
+ <property name="NameEscapedEscapeEscaped" value="$$$${name}"/>
+ <property name="ManyEscape" value="$$$$$$$${name}"/>
+ <property name="Ice.Warn.Connections" value="1"/>
+ </properties>
+
+ <envs>
+ <env>MY_ENV_VARIABLE=12</env>
+ </envs>
+ </server-template>
+
+ <service-template id="ServiceTemplate" name="${name}" entry="TestService:create">
+ <adapters>
+ <adapter name="${service}" endpoints="default">
+ <object identity="${server}-${service}" type="::Test"/>
+ </adapter>
+ </adapters>
+
+ <properties>
+ <property name="${name}.InheritedVariable" value="${inheritedvar}"/>
+ <property name="${name}.Identity" value="${server}-${name}"/>
+ <property name="${name}.Type" value="standard"/>
+ <property name="${name}.ServiceName" value="${name}"/>
+ </properties>
+
+ </service-template>
+
+ <service-template id="FreezeServiceTemplate" name="${name}" entry="TestService:create">
+
+ <adapters>
+ <adapter name="${name}" endpoints="default" id="${server}${name}Adapter">
+ <object identity="${server}-${name}" type="::Test"/>
+ </adapter>
+ </adapters>
+
+ <properties>
+ <property name="${name}.Identity" value="${server}-${name}"/>
+ <property name="${name}.Type" value="freeze"/>
+ <property name="${name}.ServiceName" value="${name}"/>
+
+ </properties>
+
+ <dbenv name="${name}">
+ <dbproperty name="set_cachesize" value="0 52428800 1"/>
+ </dbenv>
+
+ </service-template>
+
+ <server-template id="IceBoxTemplate" name="${name}" kind="cpp-icebox" endpoints="default"
+ exe="${ice.dir}/bin/icebox" activation="on-demand">
+
+ <variable name="inheritedvar" value="inherited"/>
+
+ <service template="ServiceTemplate" name="Service1"/>
+ <service template="FreezeServiceTemplate" name="Service2"/>
+
+ <properties>
+ <property name="Ice.Warn.Connections" value="1"/>
+ </properties>
+ </server-template>
+
+ <node name="localnode">
+
+ <server template="IceBoxTemplate" name="IceBox1"/>
+ <server template="IceBoxTemplate" name="IceBox2"/>
+ <server template="ServerTemplate" name="Server1"/>
+ <server template="ServerTemplate" name="Server2"/>
+
+ </node>
+
+ </application>
+
+</icegrid> \ No newline at end of file
diff --git a/cpp/test/IceGrid/deployer/run.py b/cpp/test/IceGrid/deployer/run.py
index 838849fd7fd..85ebe5efad1 100755
--- a/cpp/test/IceGrid/deployer/run.py
+++ b/cpp/test/IceGrid/deployer/run.py
@@ -90,6 +90,20 @@ IceGridAdmin.removeApplication("test");
print "ok"
#
+# Deploy the application with templates, run the client and remove the application.
+#
+print "deploying application with templates...",
+IceGridAdmin.addApplication(os.path.join(testdir, "application_with_templates.xml"), \
+ "ice.dir=" + toplevel + " " + "test.dir=" + testdir);
+print "ok"
+
+startClient("-e")
+
+print "removing application...",
+IceGridAdmin.removeApplication("test");
+print "ok"
+
+#
# Shutdown IceGrid.
#
IceGridAdmin.shutdownIceGridNode()