summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2012-09-13 15:33:46 +0200
committerBenoit Foucher <benoit@zeroc.com>2012-09-13 15:33:46 +0200
commit0ed3e3fff565b80f84ec7e23d821fd30fac89b86 (patch)
treec9f4157f23727413b34d33f12f67e891879d3a77 /cpp
parentMerge remote-tracking branch 'origin/mx' into mx (diff)
downloadice-0ed3e3fff565b80f84ec7e23d821fd30fac89b86.tar.bz2
ice-0ed3e3fff565b80f84ec7e23d821fd30fac89b86.tar.xz
ice-0ed3e3fff565b80f84ec7e23d821fd30fac89b86.zip
Added Ice/metrics test
Diffstat (limited to 'cpp')
-rwxr-xr-xcpp/allTests.py1
-rw-r--r--cpp/src/Ice/InstrumentationI.cpp15
-rw-r--r--cpp/src/Ice/MetricsAdminI.h5
-rw-r--r--cpp/src/Ice/MetricsObserverI.h7
-rw-r--r--cpp/src/Ice/Outgoing.cpp6
-rw-r--r--cpp/src/Ice/PropertiesAdminI.cpp179
-rw-r--r--cpp/src/Ice/PropertiesAdminI.h4
-rw-r--r--cpp/test/Ice/Makefile3
-rw-r--r--cpp/test/Ice/Makefile.mak3
-rw-r--r--cpp/test/Ice/metrics/.gitignore7
-rw-r--r--cpp/test/Ice/metrics/AllTests.cpp840
-rw-r--r--cpp/test/Ice/metrics/Client.cpp66
-rw-r--r--cpp/test/Ice/metrics/Makefile42
-rw-r--r--cpp/test/Ice/metrics/Makefile.mak64
-rw-r--r--cpp/test/Ice/metrics/Server.cpp78
-rw-r--r--cpp/test/Ice/metrics/Test.ice50
-rw-r--r--cpp/test/Ice/metrics/TestI.cpp80
-rw-r--r--cpp/test/Ice/metrics/TestI.h51
-rwxr-xr-xcpp/test/Ice/metrics/run.py23
19 files changed, 1428 insertions, 96 deletions
diff --git a/cpp/allTests.py b/cpp/allTests.py
index 80bef55a2d0..ffee2ff94e1 100755
--- a/cpp/allTests.py
+++ b/cpp/allTests.py
@@ -69,6 +69,7 @@ tests = [
("Ice/plugin", ["core"]),
("Ice/hash", ["once"]),
("Ice/admin", ["core"]),
+ ("Ice/metrics", ["core"]),
("IceSSL/configuration", ["once", "novalgrind"]), # valgrind doesn't work well with openssl
("IceBox/configuration", ["core", "noipv6", "novc6", "nomingw"]),
("IceBox/admin", ["core", "noipv6", "novc6", "nomingw"]),
diff --git a/cpp/src/Ice/InstrumentationI.cpp b/cpp/src/Ice/InstrumentationI.cpp
index 139e304a673..718d132f053 100644
--- a/cpp/src/Ice/InstrumentationI.cpp
+++ b/cpp/src/Ice/InstrumentationI.cpp
@@ -257,6 +257,7 @@ public:
add("parent", &DispatchHelper::getParent);
add("id", &DispatchHelper::getId);
add("endpoint", &DispatchHelper::getEndpoint);
+ add("connection", &DispatchHelper::getConnection);
addConnectionAttributes<DispatchHelper>(*this);
@@ -333,6 +334,12 @@ public:
return _current.con->getEndpoint();
}
+ const ConnectionPtr&
+ getConnection() const
+ {
+ return _current.con;
+ }
+
const EndpointInfoPtr&
getEndpointInfo() const
{
@@ -656,7 +663,7 @@ public:
{
add("parent", &EndpointHelper::getParent);
add("id", &EndpointHelper::getId);
- add("endpoint", &EndpointHelper::getId);
+ add("endpoint", &EndpointHelper::getEndpoint);
addEndpointAttributes<EndpointHelper>(*this);
}
};
@@ -701,6 +708,12 @@ public:
return _id;
}
+ string
+ getEndpoint() const
+ {
+ return _endpoint->toString();
+ }
+
private:
const EndpointPtr _endpoint;
diff --git a/cpp/src/Ice/MetricsAdminI.h b/cpp/src/Ice/MetricsAdminI.h
index ffc32850fa2..16f21d9971a 100644
--- a/cpp/src/Ice/MetricsAdminI.h
+++ b/cpp/src/Ice/MetricsAdminI.h
@@ -144,6 +144,11 @@ public:
_subMaps.find(mapName);
if(p == _subMaps.end())
{
+ Lock sync(*this);
+ if(_map == 0)
+ {
+ return 0;
+ }
std::pair<MetricsMapIPtr, SubMapMember> map = _map->createSubMap(mapName);
if(map.first)
{
diff --git a/cpp/src/Ice/MetricsObserverI.h b/cpp/src/Ice/MetricsObserverI.h
index e39caf38644..0f04232bca1 100644
--- a/cpp/src/Ice/MetricsObserverI.h
+++ b/cpp/src/Ice/MetricsObserverI.h
@@ -15,6 +15,7 @@
#include <Ice/Instrumentation.h>
#include <Ice/Metrics.h>
#include <Ice/Endpoint.h>
+#include <Ice/Connection.h>
#include <Ice/MetricsAdminI.h>
#include <Ice/MetricsFunctional.h>
@@ -235,6 +236,12 @@ protected:
}
static std::string
+ toString(const Ice::ConnectionPtr& e)
+ {
+ return e->toString();
+ }
+
+ static std::string
toString(bool v)
{
return v ? "true" : "false";
diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp
index 31c706c65a8..53e50da60d1 100644
--- a/cpp/src/Ice/Outgoing.cpp
+++ b/cpp/src/Ice/Outgoing.cpp
@@ -539,8 +539,12 @@ IceInternal::Outgoing::throwUserException()
_is.startReadEncaps();
_is.throwException();
}
- catch(const Ice::UserException&)
+ catch(const Ice::UserException& ex)
{
+ if(_observer)
+ {
+ _observer.failed(ex.ice_name());
+ }
_is.endReadEncaps();
throw;
}
diff --git a/cpp/src/Ice/PropertiesAdminI.cpp b/cpp/src/Ice/PropertiesAdminI.cpp
index 898f0414f13..64d55718568 100644
--- a/cpp/src/Ice/PropertiesAdminI.cpp
+++ b/cpp/src/Ice/PropertiesAdminI.cpp
@@ -24,14 +24,14 @@ Ice::PropertiesAdminI::PropertiesAdminI(const string& name, const PropertiesPtr&
string
Ice::PropertiesAdminI::getProperty(const string& name, const Ice::Current&)
{
- IceUtil::Mutex::Lock sync(*this);
+ Lock sync(*this);
return _properties->getProperty(name);
}
Ice::PropertyDict
Ice::PropertiesAdminI::getPropertiesForPrefix(const string& prefix, const Ice::Current&)
{
- IceUtil::Mutex::Lock sync(*this);
+ Lock sync(*this);
return _properties->getPropertiesForPrefix(prefix);
}
@@ -39,122 +39,117 @@ void
Ice::PropertiesAdminI::setProperties_async(const AMD_PropertiesAdmin_setPropertiesPtr& cb, const PropertyDict& props,
const Ice::Current&)
{
+ Lock sync(*this);
+
+ PropertyDict old = _properties->getPropertiesForPrefix("");
+ PropertyDict::const_iterator p;
+ const int traceLevel = _properties->getPropertyAsInt("Ice.Trace.Admin.Properties");
+
+ //
+ // Compute the difference between the new property set and the existing property set:
+ //
+ // 1) Any properties in the new set that were not defined in the existing set.
+ //
+ // 2) Any properties that appear in both sets but with different values.
+ //
+ // 3) Any properties not present in the new set but present in the existing set.
+ // In other words, the property has been removed.
+ //
PropertyDict added, changed, removed;
- vector<PropertiesAdminUpdateCallbackPtr> callbacks;
+ for(p = props.begin(); p != props.end(); ++p)
{
- IceUtil::Mutex::Lock sync(*this);
-
- PropertyDict old = _properties->getPropertiesForPrefix("");
- PropertyDict::const_iterator p;
- const int traceLevel = _properties->getPropertyAsInt("Ice.Trace.Admin.Properties");
-
- //
- // Compute the difference between the new property set and the existing property set:
- //
- // 1) Any properties in the new set that were not defined in the existing set.
- //
- // 2) Any properties that appear in both sets but with different values.
- //
- // 3) Any properties not present in the new set but present in the existing set.
- // In other words, the property has been removed.
- //
- for(p = props.begin(); p != props.end(); ++p)
+ PropertyDict::iterator q = old.find(p->first);
+ if(q == old.end())
{
- PropertyDict::iterator q = old.find(p->first);
- if(q == old.end())
+ if(!p->second.empty())
{
- if(!p->second.empty())
+ //
+ // This property is new.
+ //
+ added.insert(*p);
+ }
+ }
+ else
+ {
+ if(p->second != q->second)
+ {
+ if(p->second.empty())
{
//
- // This property is new.
+ // This property was removed.
//
- added.insert(*p);
+ removed.insert(*p);
}
- }
- else
- {
- if(p->second != q->second)
+ else
{
- if(p->second.empty())
- {
- //
- // This property was removed.
- //
- removed.insert(*p);
- }
- else
- {
- //
- // This property has changed.
- //
- changed.insert(*p);
- }
+ //
+ // This property has changed.
+ //
+ changed.insert(*p);
}
}
}
-
- if(traceLevel > 0 && (!added.empty() || !changed.empty() || !removed.empty()))
+ }
+
+ if(traceLevel > 0 && (!added.empty() || !changed.empty() || !removed.empty()))
+ {
+ Trace out(_logger, _name);
+
+ out << "Summary of property changes";
+
+ if(!added.empty())
{
- Trace out(_logger, _name);
-
- out << "Summary of property changes";
-
- if(!added.empty())
+ out << "\nNew properties:";
+ for(p = added.begin(); p != added.end(); ++p)
{
- out << "\nNew properties:";
- for(p = added.begin(); p != added.end(); ++p)
+ out << "\n " << p->first;
+ if(traceLevel > 1)
{
- out << "\n " << p->first;
- if(traceLevel > 1)
- {
- out << " = " << p->second;
- }
+ out << " = " << p->second;
}
}
+ }
- if(!changed.empty())
+ if(!changed.empty())
+ {
+ out << "\nChanged properties:";
+ for(p = changed.begin(); p != changed.end(); ++p)
{
- out << "\nChanged properties:";
- for(p = changed.begin(); p != changed.end(); ++p)
+ out << "\n " << p->first;
+ if(traceLevel > 1)
{
- out << "\n " << p->first;
- if(traceLevel > 1)
- {
- out << " = " << p->second << " (old value = " << _properties->getProperty(p->first) << ")";
- }
+ out << " = " << p->second << " (old value = " << _properties->getProperty(p->first) << ")";
}
}
+ }
- if(!removed.empty())
+ if(!removed.empty())
+ {
+ out << "\nRemoved properties:";
+ for(p = removed.begin(); p != removed.end(); ++p)
{
- out << "\nRemoved properties:";
- for(p = removed.begin(); p != removed.end(); ++p)
- {
- out << "\n " << p->first;
- }
+ out << "\n " << p->first;
}
}
+ }
- //
- // Update the property set.
- //
-
- for(p = added.begin(); p != added.end(); ++p)
- {
- _properties->setProperty(p->first, p->second);
- }
+ //
+ // Update the property set.
+ //
- for(p = changed.begin(); p != changed.end(); ++p)
- {
- _properties->setProperty(p->first, p->second);
- }
+ for(p = added.begin(); p != added.end(); ++p)
+ {
+ _properties->setProperty(p->first, p->second);
+ }
- for(p = removed.begin(); p != removed.end(); ++p)
- {
- _properties->setProperty(p->first, "");
- }
+ for(p = changed.begin(); p != changed.end(); ++p)
+ {
+ _properties->setProperty(p->first, p->second);
+ }
- callbacks = _updateCallbacks;
+ for(p = removed.begin(); p != removed.end(); ++p)
+ {
+ _properties->setProperty(p->first, "");
}
//
@@ -163,6 +158,10 @@ Ice::PropertiesAdminI::setProperties_async(const AMD_PropertiesAdmin_setProperti
//
cb->ice_response();
+ //
+ // Copy the callbacks to allow callbacks to update the callbacks.
+ //
+ vector<PropertiesAdminUpdateCallbackPtr> callbacks = _updateCallbacks;
if(!callbacks.empty())
{
PropertyDict changes = added;
@@ -185,13 +184,13 @@ Ice::PropertiesAdminI::setProperties_async(const AMD_PropertiesAdmin_setProperti
void
Ice::PropertiesAdminI::addUpdateCallback(const PropertiesAdminUpdateCallbackPtr& cb)
{
- IceUtil::Mutex::Lock sync(*this);
+ Lock sync(*this);
_updateCallbacks.push_back(cb);
}
void
Ice::PropertiesAdminI::removeUpdateCallback(const PropertiesAdminUpdateCallbackPtr& cb)
{
- IceUtil::Mutex::Lock sync(*this);
+ Lock sync(*this);
_updateCallbacks.erase(remove(_updateCallbacks.begin(), _updateCallbacks.end(), cb), _updateCallbacks.end());
}
diff --git a/cpp/src/Ice/PropertiesAdminI.h b/cpp/src/Ice/PropertiesAdminI.h
index 17235ddb313..c0c22a9a0ff 100644
--- a/cpp/src/Ice/PropertiesAdminI.h
+++ b/cpp/src/Ice/PropertiesAdminI.h
@@ -10,14 +10,14 @@
#ifndef ICE_PROPERTIES_ADMIN_I_H
#define ICE_PROPERTIES_ADMIN_I_H
-#include <IceUtil/Mutex.h>
+#include <IceUtil/RecMutex.h>
#include <Ice/PropertiesAdmin.h>
#include <Ice/LoggerF.h>
namespace Ice
{
-class ICE_API PropertiesAdminI : public PropertiesAdmin, public NativePropertiesAdmin, private IceUtil::Mutex
+class ICE_API PropertiesAdminI : public PropertiesAdmin, public NativePropertiesAdmin, private IceUtil::RecMutex
{
public:
diff --git a/cpp/test/Ice/Makefile b/cpp/test/Ice/Makefile
index 5129afcc199..733e54498d5 100644
--- a/cpp/test/Ice/Makefile
+++ b/cpp/test/Ice/Makefile
@@ -44,7 +44,8 @@ SUBDIRS = proxy \
invoke \
properties \
plugin \
- admin
+ admin \
+ metrics
.PHONY: $(EVERYTHING) $(SUBDIRS)
diff --git a/cpp/test/Ice/Makefile.mak b/cpp/test/Ice/Makefile.mak
index f9972660ece..984a1120a33 100644
--- a/cpp/test/Ice/Makefile.mak
+++ b/cpp/test/Ice/Makefile.mak
@@ -31,7 +31,8 @@ SUBDIRS = proxy \
udp \
admin \
plugin \
- stream
+ stream \
+ metrics
!if "$(WINRT)" != "yes"
SUBDIRS = $(SUBDIRS) \
diff --git a/cpp/test/Ice/metrics/.gitignore b/cpp/test/Ice/metrics/.gitignore
new file mode 100644
index 00000000000..67872faa673
--- /dev/null
+++ b/cpp/test/Ice/metrics/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+server
+Test.cpp
+Test.h
diff --git a/cpp/test/Ice/metrics/AllTests.cpp b/cpp/test/Ice/metrics/AllTests.cpp
new file mode 100644
index 00000000000..39ec038f527
--- /dev/null
+++ b/cpp/test/Ice/metrics/AllTests.cpp
@@ -0,0 +1,840 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 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;
+using namespace Test;
+
+namespace
+{
+
+// void
+// printMetricsView(const IceMX::MetricsView& view)
+// {
+// for(IceMX::MetricsView::const_iterator q = view.begin(); q != view.end(); ++q)
+// {
+// cout << endl << q->first << " Map:" << endl;
+// for(IceMX::MetricsMap::const_iterator p = q->second.begin(); p != q->second.end(); ++p)
+// {
+// cout << (*p)->id << " current = " << (*p)->current << " total = " << (*p)->total << " failures = "
+// << (*p)->failures << endl;
+// }
+// }
+// }
+
+Ice::PropertyDict
+getClientProps(const Ice::PropertiesAdminPrx& p, const Ice::PropertyDict& orig, const string& m = string())
+{
+ Ice::PropertyDict props = p->getPropertiesForPrefix("IceMX.Metrics");
+ for(Ice::PropertyDict::iterator p = props.begin(); p != props.end(); ++p)
+ {
+ p->second = "";
+ }
+ for(Ice::PropertyDict::const_iterator p = orig.begin(); p != orig.end(); ++p)
+ {
+ props[p->first] = p->second;
+ }
+ string map;
+ if(!m.empty())
+ {
+ map += "Map." + m + '.';
+ }
+ props["IceMX.Metrics.View." + map + "Reject.parent"] = "Ice\\.Admin";
+ props["IceMX.Metrics.View." + map + "Accept.endpointPort"] = "12010";
+ props["IceMX.Metrics.View." + map + "Reject.identity"] = ".*/admin|controller";
+ return props;
+}
+
+Ice::PropertyDict
+getServerProps(const Ice::PropertiesAdminPrx& p, const Ice::PropertyDict& orig, const string& m = string())
+{
+ Ice::PropertyDict props = p->getPropertiesForPrefix("IceMX.Metrics");
+ for(Ice::PropertyDict::iterator p = props.begin(); p != props.end(); ++p)
+ {
+ p->second = "";
+ }
+ for(Ice::PropertyDict::const_iterator p = orig.begin(); p != orig.end(); ++p)
+ {
+ props[p->first] = p->second;
+ }
+ string map;
+ if(!m.empty())
+ {
+ map += "Map." + m + '.';
+ }
+ props["IceMX.Metrics.View." + map + "Reject.parent"] = "Ice\\.Admin|Controller";
+ props["IceMX.Metrics.View." + map + "Accept.endpointPort"] = "12010";
+ return props;
+}
+
+class UpdateCallbackI : public Ice::PropertiesAdminUpdateCallback, private IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ UpdateCallbackI(const Ice::PropertiesAdminPrx& serverProps) : _updated(false), _serverProps(serverProps)
+ {
+ }
+
+ void
+ waitForUpdate()
+ {
+ Lock sync(*this);
+ while(!_updated)
+ {
+ wait();
+ }
+ // Ensure that the previous updates were committed, the setProperties call returns before
+ // notifying the callbacks so to ensure all the update callbacks have be notified we call
+ // a second time, this will block until all the notifications from the first update have
+ // completed.
+ _serverProps->setProperties(Ice::PropertyDict());
+ _updated = false;
+ }
+
+ void
+ updated(const Ice::PropertyDict& dict)
+ {
+ Lock sync(*this);
+ _updated = true;
+ notify();
+ }
+
+private:
+
+ bool _updated;
+ Ice::PropertiesAdminPrx _serverProps;
+};
+
+void
+waitForCurrent(const IceMX::MetricsAdminPrx& metrics, const string& viewName, const string& map, int value)
+{
+ while(true)
+ {
+ IceMX::MetricsView view = metrics->getMetricsView(viewName);
+ test(view.find(map) != view.end());
+ bool ok = true;
+ for(IceMX::MetricsMap::const_iterator m = view[map].begin(); m != view[map].end(); ++m)
+ {
+ if((*m)->current != value)
+ {
+ ok = false;
+ break;
+ }
+ }
+ if(ok)
+ {
+ break;
+ }
+ IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(50));
+ }
+}
+
+template<typename T> void
+testAttribute(const IceMX::MetricsAdminPrx& metrics,
+ const Ice::PropertiesAdminPrx& props,
+ UpdateCallbackI* update,
+ const string& map,
+ const string& attr,
+ const string& value,
+ const T& func)
+{
+ Ice::PropertyDict dict;
+ dict["IceMX.Metrics.View.Map." + map + ".GroupBy"] = attr;
+ if(props->ice_getIdentity().category == "client")
+ {
+ props->setProperties(getClientProps(props, dict, map));
+ update->waitForUpdate();
+ }
+ else
+ {
+ props->setProperties(getServerProps(props, dict, map));
+ props->setProperties(Ice::PropertyDict());
+ }
+
+ func();
+
+ IceMX::MetricsView view = metrics->getMetricsView("View");
+ test(view.find(map) != view.end());
+ if(view[map][0]->id != value)
+ {
+ cerr << "invalid attribute value: " << attr << " = " << value << " got " << view[map][0]->id << endl;
+ test(false);
+ }
+
+ dict.clear();
+ if(props->ice_getIdentity().category == "client")
+ {
+ props->setProperties(getClientProps(props, dict, map));
+ update->waitForUpdate();
+ }
+ else
+ {
+ props->setProperties(getServerProps(props, dict, map));
+ props->setProperties(Ice::PropertyDict());
+ }
+}
+
+struct Void
+{
+ void
+ operator()() const
+ {
+ }
+};
+
+struct Connect
+{
+ Connect(const Ice::ObjectPrx& proxy) : proxy(proxy)
+ {
+ }
+
+ void
+ operator()() const
+ {
+ if(proxy->ice_getCachedConnection())
+ {
+ proxy->ice_getCachedConnection()->close(false);
+ }
+ try
+ {
+ proxy->ice_ping();
+ }
+ catch(const Ice::LocalException&)
+ {
+ }
+ if(proxy->ice_getCachedConnection())
+ {
+ proxy->ice_getCachedConnection()->close(false);
+ }
+ }
+
+ Ice::ObjectPrx proxy;
+};
+
+struct InvokeOp
+{
+ InvokeOp(const Test::MetricsPrx& proxy) : proxy(proxy)
+ {
+ }
+
+ void
+ operator()() const
+ {
+ Ice::Context ctx;
+ ctx["entry1"] = "test";
+ ctx["entry2"] = "";
+ proxy->op(ctx);
+ }
+
+ Test::MetricsPrx proxy;
+};
+
+void
+testAttribute(const IceMX::MetricsAdminPrx& metrics,
+ const Ice::PropertiesAdminPrx& props,
+ UpdateCallbackI* update,
+ const string& map,
+ const string& attr,
+ const string& value)
+{
+ testAttribute(metrics, props, update, map, attr, value, Void());
+}
+
+void
+updateProps(const Ice::PropertiesAdminPrx& cprops,
+ const Ice::PropertiesAdminPrx& sprops,
+ UpdateCallbackI* callback,
+ const Ice::PropertyDict& props,
+ const string& map = string())
+{
+ cprops->setProperties(getClientProps(cprops, props, map));
+ sprops->setProperties(getServerProps(sprops, props, map));
+ callback->waitForUpdate();
+}
+
+void
+clearView(const Ice::PropertiesAdminPrx& cprops, const Ice::PropertiesAdminPrx& sprops, UpdateCallbackI* callback)
+{
+ Ice::PropertyDict dict;
+
+ dict = cprops->getPropertiesForPrefix("IceMX.Metrics");
+ dict["IceMX.Metrics.View.Disabled"] = "1";
+ cprops->setProperties(dict);
+
+ dict = sprops->getPropertiesForPrefix("IceMX.Metrics");
+ dict["IceMX.Metrics.View.Disabled"] = "1";
+ sprops->setProperties(dict);
+
+ callback->waitForUpdate();
+
+ dict = cprops->getPropertiesForPrefix("IceMX.Metrics");
+ dict["IceMX.Metrics.View.Disabled"] = "";
+ cprops->setProperties(dict);
+
+ dict = sprops->getPropertiesForPrefix("IceMX.Metrics");
+ dict["IceMX.Metrics.View.Disabled"] = "";
+ sprops->setProperties(dict);
+
+ callback->waitForUpdate();
+}
+
+void
+checkFailure(const IceMX::MetricsAdminPrx& m, const string& map, const string& id, const string& failure, int count)
+{
+ IceMX::MetricsFailures f = m->getMetricsFailures("View", map, id);
+ if(f.failures.find(failure) == f.failures.end())
+ {
+ cerr << "couldn't find failure `" << failure << "' for `" << id << "'" << endl;
+ test(false);
+ }
+ if(f.failures[failure] != count)
+ {
+ cerr << "count for failure `" << failure << "' of `" << id << "' is different from expected: ";
+ cerr << count << " != " << f.failures[failure] << endl;
+ test(false);
+ }
+}
+
+}
+
+MetricsPrx
+allTests(const Ice::CommunicatorPtr& communicator)
+{
+ MetricsPrx metrics = MetricsPrx::checkedCast(communicator->stringToProxy("metrics:default -p 12010"));
+
+ cout << "testing metrics admin facet checkedCast... " << flush;
+ Ice::ObjectPrx admin = communicator->getAdmin()->ice_collocationOptimized(false);
+ Ice::PropertiesAdminPrx clientProps = Ice::PropertiesAdminPrx::checkedCast(admin, "Properties");
+ IceMX::MetricsAdminPrx clientMetrics = IceMX::MetricsAdminPrx::checkedCast(admin, "MetricsAdmin");
+ test(clientProps && clientMetrics);
+
+ admin = metrics->getAdmin();
+ Ice::PropertiesAdminPrx serverProps = Ice::PropertiesAdminPrx::checkedCast(admin, "Properties");
+ IceMX::MetricsAdminPrx serverMetrics = IceMX::MetricsAdminPrx::checkedCast(admin, "MetricsAdmin");
+ test(serverProps && serverMetrics);
+
+ UpdateCallbackI* update = new UpdateCallbackI(serverProps);
+ Ice::NativePropertiesAdminPtr::dynamicCast(communicator->findAdminFacet("Properties"))->addUpdateCallback(update);
+
+ cout << "ok" << endl;
+
+ Ice::PropertyDict props;
+
+ cout << "testing group by none..." << flush;
+
+ props["IceMX.Metrics.View.GroupBy"] = "none";
+ updateProps(clientProps, serverProps, update, props);
+
+ IceMX::MetricsView view = clientMetrics->getMetricsView("View");
+ test(view["Connection"].size() == 1 && view["Connection"][0]->current == 1 && view["Connection"][0]->total == 1);
+ test(view["Thread"].size() == 1 && view["Thread"][0]->current == 4 && view["Thread"][0]->total == 4);
+ cout << "ok" << endl;
+
+ cout << "testing group by id..." << flush;
+
+ props["IceMX.Metrics.View.GroupBy"] = "id";
+ updateProps(clientProps, serverProps, update, props);
+
+ metrics->ice_ping();
+ metrics->ice_ping();
+ metrics->ice_connectionId("Con1")->ice_ping();
+ metrics->ice_connectionId("Con1")->ice_ping();
+ metrics->ice_connectionId("Con1")->ice_ping();
+
+ view = clientMetrics->getMetricsView("View");
+ test(view["Thread"].size() == 4);
+ test(view["Connection"].size() == 2);
+ test(view["Invocation"].size() == 1);
+
+ IceMX::InvocationMetricsPtr invoke = IceMX::InvocationMetricsPtr::dynamicCast(view["Invocation"][0]);
+ test(invoke->id.find("[ice_ping]") > 0 && invoke->current == 0 && invoke->total == 5);
+ test(invoke->remotes.size() == 2);
+ test(invoke->remotes[0]->total = 2);
+ test(invoke->remotes[1]->total = 3);
+
+ view = serverMetrics->getMetricsView("View");
+ test(view["Thread"].size() > 4);
+ test(view["Connection"].size() == 2);
+ test(view["Dispatch"].size() == 1);
+ test(view["Dispatch"][0]->current == 0 && view["Dispatch"][0]->total == 5);
+ test(view["Dispatch"][0]->id.find("[ice_ping]") > 0);
+
+ metrics->ice_getConnection()->close(false);
+ metrics->ice_connectionId("Con1")->ice_getConnection()->close(false);
+
+ waitForCurrent(clientMetrics, "View", "Connection", 0);
+ waitForCurrent(serverMetrics, "View", "Connection", 0);
+
+ clearView(clientProps, serverProps, update);
+
+ cout << "ok" << endl;
+
+ cout << "testing connection metrics... " << flush;
+
+ props["IceMX.Metrics.View.Map.Connection.GroupBy"] = "none";
+ updateProps(clientProps, serverProps, update, props, "Connection");
+
+ test(clientMetrics->getMetricsView("View")["Connection"].empty());
+ test(serverMetrics->getMetricsView("View")["Connection"].empty());
+
+ metrics->ice_ping();
+
+ IceMX::ConnectionMetricsPtr cm1, sm1, cm2, sm2;
+ cm1 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+ test(cm1->total == 1 && sm1->total == 1);
+
+ metrics->ice_ping();
+
+ cm2 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm2 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+
+ test(cm2->sentBytes - cm1->sentBytes == 45); // 45 for ice_ping request
+ test(cm2->receivedBytes - cm1->receivedBytes == 25); // 25 bytes for ice_ping response
+ test(sm2->receivedBytes - sm1->receivedBytes == 45);
+ test(sm2->sentBytes - sm1->sentBytes == 25);
+
+ cm1 = cm2;
+ sm1 = sm2;
+
+ Test::ByteSeq bs;
+ metrics->opByteS(bs);
+
+ cm2 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm2 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+ int requestSz = cm2->sentBytes - cm1->sentBytes;
+ int replySz = cm2->receivedBytes - cm1->receivedBytes;
+
+ cm1 = cm2;
+ sm1 = sm2;
+
+ bs.resize(456);
+ metrics->opByteS(bs);
+
+ cm2 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm2 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+
+ test(cm2->sentBytes - cm1->sentBytes == requestSz + bs.size() + 4); // 4 is for the seq variable size
+ test(cm2->receivedBytes - cm1->receivedBytes == replySz);
+ test(sm2->receivedBytes - sm1->receivedBytes == requestSz + bs.size() + 4);
+ test(sm2->sentBytes - sm1->sentBytes == replySz);
+
+ cm1 = cm2;
+ sm1 = sm2;
+
+ bs.resize(1024 * 1024 * 10); // Try with large amount of data which should be sent in several chunks
+ metrics->opByteS(bs);
+
+ cm2 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm2 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+
+ test(cm2->sentBytes - cm1->sentBytes == requestSz + bs.size() + 4); // 4 is for the seq variable size
+ test(cm2->receivedBytes - cm1->receivedBytes == replySz);
+ test(sm2->receivedBytes - sm1->receivedBytes == requestSz + bs.size() + 4);
+ test(sm2->sentBytes - sm1->sentBytes == replySz);
+
+ sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+ test(sm1->active == 1);
+
+ ControllerPrx controller = ControllerPrx::checkedCast(communicator->stringToProxy("controller:default -p 12011"));
+ controller->hold();
+
+ cm1 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+ test(cm1->active == 1 && sm1->holding == 1);
+
+ metrics->ice_getConnection()->close(false);
+
+ cm1 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+ test(cm1->active == 0 && cm1->closing == 1 && sm1->active == 0 && sm1->holding == 1);
+
+ controller->resume();
+
+ sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+ test(sm1->holding == 0);
+
+ waitForCurrent(clientMetrics, "View", "Connection", 0);
+ waitForCurrent(serverMetrics, "View", "Connection", 0);
+
+ clearView(clientProps, serverProps, update);
+
+ metrics->ice_timeout(500)->ice_ping();
+ controller->hold();
+ try
+ {
+ metrics->ice_timeout(500)->ice_ping();
+ test(false);
+ }
+ catch(const Ice::TimeoutException&)
+ {
+ }
+ controller->resume();
+
+ cm1 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View")["Connection"][0]);
+ sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View")["Connection"][0]);
+ test(cm1->failures == 2 && sm1->failures >= 1);
+
+ checkFailure(clientMetrics, "Connection", cm1->id, "Ice::TimeoutException", 1);
+ checkFailure(clientMetrics, "Connection", cm1->id, "Ice::ConnectTimeoutException", 1);
+ checkFailure(serverMetrics, "Connection", sm1->id, "Ice::ConnectionLostException", 2);
+
+ MetricsPrx m = metrics->ice_timeout(500)->ice_connectionId("Con1");
+ m->ice_ping();
+
+ testAttribute(clientMetrics, clientProps, update, "Connection", "parent", "Communicator");
+ //testAttribute(clientMetrics, clientProps, update, "Connection", "id", "");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpoint",
+ "tcp -e 1.1 -h 127.0.0.1 -p 12010 -t 500");
+
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointType", "1");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointIsDatagram", "false");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointIsSecure", "false");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointProtocolVersion", "1.0");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointEncodingVersion", "1.1");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointTimeout", "500");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointCompress", "false");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointHost", "127.0.0.1");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "endpointPort", "12010");
+
+ testAttribute(clientMetrics, clientProps, update, "Connection", "incoming", "false");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "adapterName", "");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "connectionId", "Con1");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "localHost", "127.0.0.1");
+ //testAttribute(clientMetrics, clientProps, update, "Connection", "localPort", "");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "remoteHost", "127.0.0.1");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "remotePort", "12010");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "mcastHost", "unknown");
+ testAttribute(clientMetrics, clientProps, update, "Connection", "mcastPort", "unknown");
+
+ m->ice_getConnection()->close(false);
+
+ waitForCurrent(clientMetrics, "View", "Connection", 0);
+ waitForCurrent(serverMetrics, "View", "Connection", 0);
+
+ cout << "ok" << endl;
+
+ cout << "testing connection establishment metrics... " << flush;
+
+ props["IceMX.Metrics.View.Map.ConnectionEstablishment.GroupBy"] = "id";
+ updateProps(clientProps, serverProps, update, props, "ConnectionEstablishment");
+ test(clientMetrics->getMetricsView("View")["ConnectionEstablishment"].empty());
+
+ metrics->ice_ping();
+
+ test(clientMetrics->getMetricsView("View")["ConnectionEstablishment"].size() == 1);
+ IceMX::MetricsPtr m1 = clientMetrics->getMetricsView("View")["ConnectionEstablishment"][0];
+ test(m1->current == 0 && m1->total == 1 && m1->id == "127.0.0.1:12010");
+
+ metrics->ice_getConnection()->close(false);
+
+ try
+ {
+ communicator->stringToProxy("test:tcp -p 12010 -h 127.0.0.50")->ice_timeout(10)->ice_ping();
+ test(false);
+ }
+ catch(const Ice::ConnectTimeoutException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ test(false);
+ }
+ test(clientMetrics->getMetricsView("View")["ConnectionEstablishment"].size() == 2);
+ m1 = clientMetrics->getMetricsView("View")["ConnectionEstablishment"][1];
+ test(m1->id == "127.0.0.50:12010" && m1->total == 2 && m1->failures == 2);
+
+ checkFailure(clientMetrics, "ConnectionEstablishment", m1->id, "Ice::ConnectTimeoutException", 2);
+
+ Connect c(metrics);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "parent", "Communicator", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "id", "127.0.0.1:12010", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpoint",
+ "tcp -e 1.1 -h 127.0.0.1 -p 12010", c);
+
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointType", "1", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointIsDatagram", "false", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointIsSecure", "false", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointProtocolVersion", "1.0", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointEncodingVersion", "1.1", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointTimeout", "-1", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointCompress", "false", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointHost", "127.0.0.1", c);
+ testAttribute(clientMetrics, clientProps, update, "ConnectionEstablishment", "endpointPort", "12010", c);
+
+ cout << "ok" << endl;
+
+ cout << "testing endpoint lookup metrics... " << flush;
+
+ props["IceMX.Metrics.View.Map.ConnectionEstablishment.GroupBy"] = "id";
+ updateProps(clientProps, serverProps, update, props, "EndpointLookup");
+ test(clientMetrics->getMetricsView("View")["EndpointLookup"].empty());
+
+ Ice::ObjectPrx prx = communicator->stringToProxy("metrics:default -p 12010 -h localhost");
+ prx->ice_ping();
+
+ test(clientMetrics->getMetricsView("View")["EndpointLookup"].size() == 1);
+ m1 = clientMetrics->getMetricsView("View")["EndpointLookup"][0];
+ test(m1->current == 0 && m1->total == 1 && m1->id == "tcp -e 1.1 -h localhost -p 12010");
+
+ prx->ice_getConnection()->close(false);
+
+ try
+ {
+ communicator->stringToProxy("test:tcp -p 12010 -h unknownfoo.zeroc.com")->ice_ping();
+ test(false);
+ }
+ catch(const Ice::DNSException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ test(false);
+ }
+ test(clientMetrics->getMetricsView("View")["EndpointLookup"].size() == 2);
+ m1 = clientMetrics->getMetricsView("View")["EndpointLookup"][1];
+ test(m1->id == "tcp -e 1.1 -h unknownfoo.zeroc.com -p 12010" && m1->total == 2 && m1->failures == 2);
+
+ checkFailure(clientMetrics, "EndpointLookup", m1->id, "Ice::DNSException", 2);
+
+ c = Connect(prx);
+
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "parent", "Communicator", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "id", "tcp -e 1.1 -h localhost -p 12010", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpoint",
+ "tcp -e 1.1 -h localhost -p 12010", c);
+
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointType", "1", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointIsDatagram", "false", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointIsSecure", "false", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointProtocolVersion", "1.0", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointEncodingVersion", "1.1", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointTimeout", "-1", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointCompress", "false", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointHost", "localhost", c);
+ testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpointPort", "12010", c);
+
+ cout << "ok" << endl;
+
+ cout << "testing dispatch metrics... " << flush;
+
+ props["IceMX.Metrics.View.Map.Dispatch.GroupBy"] = "operation";
+ updateProps(clientProps, serverProps, update, props, "Dispatch");
+ test(serverMetrics->getMetricsView("View")["Dispatch"].empty());
+
+ metrics->op();
+ try
+ {
+ metrics->opWithUserException();
+ test(false);
+ }
+ catch(const Test::UserEx&)
+ {
+ }
+ try
+ {
+ metrics->opWithRequestFailedException();
+ test(false);
+ }
+ catch(const Ice::RequestFailedException&)
+ {
+ }
+ try
+ {
+ metrics->opWithLocalException();
+ test(false);
+ }
+ catch(const Ice::LocalException&)
+ {
+ }
+ try
+ {
+ metrics->opWithUnknownException();
+ test(false);
+ }
+ catch(const Ice::UnknownException&)
+ {
+ }
+ try
+ {
+ metrics->fail();
+ test(false);
+ }
+ catch(const Ice::ConnectionLostException&)
+ {
+ }
+
+ IceMX::MetricsMap mmap = serverMetrics->getMetricsView("View")["Dispatch"];
+ test(mmap.size() == 6);
+ map<string, IceMX::MetricsPtr> map;
+ for(IceMX::MetricsMap::const_iterator p = mmap.begin(); p != mmap.end(); ++p)
+ {
+ map.insert(make_pair((*p)->id, *p));
+ }
+ m1 = map["op"];
+ test(m1->current == 0 && m1->total == 1 && m1->failures == 0);
+
+ m1 = map["opWithUserException"];
+ test(m1->current == 0 && m1->total == 1 && m1->failures == 1);
+ checkFailure(serverMetrics, "Dispatch", m1->id, "Test::UserEx", 1);
+
+ m1 = map["opWithLocalException"];
+ test(m1->current == 0 && m1->total == 1 && m1->failures == 1);
+ checkFailure(serverMetrics, "Dispatch", m1->id, "Ice::SyscallException", 1);
+
+ m1 = map["opWithRequestFailedException"];
+ test(m1->current == 0 && m1->total == 1 && m1->failures == 1);
+ checkFailure(serverMetrics, "Dispatch", m1->id, "Ice::ObjectNotExistException", 1);
+
+ m1 = map["opWithUnknownException"];
+ test(m1->current == 0 && m1->total == 1 && m1->failures == 1);
+ checkFailure(serverMetrics, "Dispatch", m1->id, "unknown", 1);
+
+ InvokeOp op(metrics);
+
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "parent", "TestAdapter", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "id", "metrics [op]", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpoint", "tcp -e 1.1 -h 127.0.0.1 -p 12010", op);
+ //testAttribute(serverMetrics, serverProps, update, "Dispatch", "connection", "", op);
+
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointType", "1", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointIsDatagram", "false", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointIsSecure", "false", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointProtocolVersion", "1.0", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointEncodingVersion", "1.1", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointTimeout", "-1", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointCompress", "false", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointHost", "127.0.0.1", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "endpointPort", "12010", op);
+
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "incoming", "true", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "adapterName", "TestAdapter", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "connectionId", "", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "localHost", "127.0.0.1", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "localPort", "12010", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "remoteHost", "127.0.0.1", op);
+ //testAttribute(serverMetrics, serverProps, update, "Dispatch", "remotePort", "12010", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "mcastHost", "unknown", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "mcastPort", "unknown", op);
+
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "operation", "op", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "identity", "metrics", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "facet", "", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "encoding", "1.1", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "mode", "twoway", op);
+
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "context.entry1", "test", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "context.entry2", "", op);
+ testAttribute(serverMetrics, serverProps, update, "Dispatch", "context.entry3", "unknown", op);
+
+ cout << "ok" << endl;
+
+ cout << "testing invocation metrics... " << flush;
+
+ props["IceMX.Metrics.View.Map.Invocation.GroupBy"] = "operation";
+ props["IceMX.Metrics.View.Map.Invocation.Map.Remote.GroupBy"] = "localPort";
+ updateProps(clientProps, serverProps, update, props, "Invocation");
+ test(serverMetrics->getMetricsView("View")["Invocation"].empty());
+
+ metrics->op();
+ try
+ {
+ metrics->opWithUserException();
+ test(false);
+ }
+ catch(const Test::UserEx&)
+ {
+ }
+ try
+ {
+ metrics->opWithRequestFailedException();
+ test(false);
+ }
+ catch(const Ice::RequestFailedException&)
+ {
+ }
+ try
+ {
+ metrics->opWithLocalException();
+ test(false);
+ }
+ catch(const Ice::LocalException&)
+ {
+ }
+ try
+ {
+ metrics->opWithUnknownException();
+ test(false);
+ }
+ catch(const Ice::UnknownException&)
+ {
+ }
+ try
+ {
+ metrics->fail();
+ test(false);
+ }
+ catch(const Ice::ConnectionLostException&)
+ {
+ }
+
+ mmap = clientMetrics->getMetricsView("View")["Invocation"];
+ test(mmap.size() == 6);
+ map.clear();
+ for(IceMX::MetricsMap::const_iterator p = mmap.begin(); p != mmap.end(); ++p)
+ {
+ map.insert(make_pair((*p)->id, *p));
+ }
+ IceMX::InvocationMetricsPtr im1;
+ im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["op"]);
+ test(im1->current == 0 && im1->total == 1 && im1->failures == 0 && im1->retry == 0 && im1->remotes.size() == 1);
+
+ im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithUserException"]);
+ test(im1->current == 0 && im1->total == 1 && im1->failures == 1 && im1->retry == 0 && im1->remotes.size() == 1);
+ checkFailure(clientMetrics, "Invocation", im1->id, "Test::UserEx", 1);
+
+ im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithLocalException"]);
+ test(im1->current == 0 && im1->total == 1 && im1->failures == 1 && im1->retry == 0 && im1->remotes.size() == 1);
+ checkFailure(clientMetrics, "Invocation", im1->id, "Ice::UnknownLocalException", 1);
+
+ im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithRequestFailedException"]);
+ test(im1->current == 0 && im1->total == 1 && im1->failures == 1 && im1->retry == 0 && im1->remotes.size() == 1);
+ checkFailure(clientMetrics, "Invocation", im1->id, "Ice::ObjectNotExistException", 1);
+
+ im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithUnknownException"]);
+ test(im1->current == 0 && im1->total == 1 && im1->failures == 1 && im1->retry == 0 && im1->remotes.size() == 1);
+ checkFailure(clientMetrics, "Invocation", im1->id, "Ice::UnknownException", 1);
+
+ im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["fail"]);
+ test(im1->current == 0 && im1->total == 1 && im1->failures == 1 && im1->retry == 1 && im1->remotes.size() == 2);
+ checkFailure(clientMetrics, "Invocation", im1->id, "Ice::ConnectionLostException", 1);
+
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "parent", "Communicator", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "id",
+ "metrics -t:tcp -e 1.1 -h 127.0.0.1 -p 12010 [op]", op);
+
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "operation", "op", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "identity", "metrics", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "facet", "", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "encoding", "1.1", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "mode", "twoway", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "proxy",
+ "metrics -t:tcp -e 1.1 -h 127.0.0.1 -p 12010", op);
+
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "context.entry1", "test", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "context.entry2", "", op);
+ testAttribute(clientMetrics, clientProps, update, "Invocation", "context.entry3", "unknown", op);
+
+ cout << "ok" << endl;
+
+ return metrics;
+}
diff --git a/cpp/test/Ice/metrics/Client.cpp b/cpp/test/Ice/metrics/Client.cpp
new file mode 100644
index 00000000000..22af896c547
--- /dev/null
+++ b/cpp/test/Ice/metrics/Client.cpp
@@ -0,0 +1,66 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 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>
+
+DEFINE_TEST("client")
+
+using namespace std;
+using namespace Test;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ MetricsPrx allTests(const Ice::CommunicatorPtr&);
+ MetricsPrx metrics = allTests(communicator);
+ metrics->shutdown();
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+ initData.properties->setProperty("Ice.Admin.Endpoints", "tcp");
+ initData.properties->setProperty("Ice.Admin.InstanceName", "client");
+ initData.properties->setProperty("Ice.Admin.DelayCreation", "1");
+ initData.properties->setProperty("Ice.Warn.Connections", "0");
+ initData.properties->setProperty("Ice.MessageSizeMax", "50000");
+ communicator = Ice::initialize(argc, argv, initData);
+ 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/Ice/metrics/Makefile b/cpp/test/Ice/metrics/Makefile
new file mode 100644
index 00000000000..e91c05fde02
--- /dev/null
+++ b/cpp/test/Ice/metrics/Makefile
@@ -0,0 +1,42 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2012 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)
+
+COBJS = Test.o \
+ Client.o \
+ AllTests.o
+
+SOBJS = Test.o \
+ TestI.o \
+ Server.o
+
+SRCS = $(COBJS:.o=.cpp) \
+ $(SOBJS:.o=.cpp)
+
+SLICE_SRCS = Test.ice
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(COBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(COBJS) $(LIBS)
+
+$(SERVER): $(SOBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(SOBJS) $(LIBS)
+
+include .depend
diff --git a/cpp/test/Ice/metrics/Makefile.mak b/cpp/test/Ice/metrics/Makefile.mak
new file mode 100644
index 00000000000..afefb4981e2
--- /dev/null
+++ b/cpp/test/Ice/metrics/Makefile.mak
@@ -0,0 +1,64 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2012 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 = ..\..\..
+
+!if "$(WINRT)" != "yes"
+NAME_PREFIX =
+EXT = .exe
+!else
+NAME_PREFIX = Ice_metrics_
+EXT = .dll
+!endif
+
+CLIENT = $(NAME_PREFIX)client
+SERVER = $(NAME_PREFIX)server
+
+TARGETS = $(CLIENT)$(EXT) $(SERVER)$(EXT)
+
+COBJS = Test.obj \
+ Client.obj \
+ AllTests.obj
+
+SOBJS = Test.obj \
+ TestI.obj \
+ Server.obj
+
+SRCS = $(COBJS:.obj=.cpp) \
+ $(SOBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(WINRT)" != "yes"
+LD_TESTFLAGS = $(LD_EXEFLAGS) $(SETARGV)
+!else
+LD_TESTFLAGS = $(LD_DLLFLAGS) /export:dllMain
+!endif
+
+!if "$(GENERATE_PDB)" == "yes"
+CPDBFLAGS = /pdb:$(CLIENT).pdb
+SPDBFLAGS = /pdb:$(SERVER).pdb
+!endif
+
+$(CLIENT)$(EXT): $(COBJS)
+ $(LINK) $(LD_TESTFLAGS) $(CPDBFLAGS) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+$(SERVER)$(EXT): $(SOBJS)
+ $(LINK) $(LD_TESTFLAGS) $(SPDBFLAGS) $(SOBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q Test.cpp Test.h
+
+!include .depend.mak
diff --git a/cpp/test/Ice/metrics/Server.cpp b/cpp/test/Ice/metrics/Server.cpp
new file mode 100644
index 00000000000..f0a1105483b
--- /dev/null
+++ b/cpp/test/Ice/metrics/Server.cpp
@@ -0,0 +1,78 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 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 <TestI.h>
+
+DEFINE_TEST("server")
+
+using namespace std;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ communicator->getProperties()->setProperty("TestAdapter.Endpoints", "default -p 12010");
+ Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("TestAdapter");
+ Ice::ObjectPtr object = new MetricsI;
+ adapter->add(object, communicator->stringToIdentity("metrics"));
+ adapter->activate();
+
+ communicator->getProperties()->setProperty("ControllerAdapter.Endpoints", "default -p 12011");
+ Ice::ObjectAdapterPtr controllerAdapter = communicator->createObjectAdapter("ControllerAdapter");
+ controllerAdapter->add(new ControllerI(adapter), communicator->stringToIdentity("controller"));
+ controllerAdapter->activate();
+
+ TEST_READY
+ communicator->waitForShutdown();
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ Ice::InitializationData initData;
+ initData.properties = Ice::createProperties(argc, argv);
+ //initData.properties->setProperty("Ice.ThreadPool.Server.Size", "1");
+ //initData.properties->setProperty("Ice.ThreadPool.Server.SizeMax", "1");
+ initData.properties->setProperty("Ice.Admin.Endpoints", "tcp");
+ initData.properties->setProperty("Ice.Admin.InstanceName", "server");
+ initData.properties->setProperty("Ice.Warn.Connections", "0");
+ initData.properties->setProperty("Ice.Warn.Dispatch", "0");
+ initData.properties->setProperty("Ice.MessageSizeMax", "50000");
+ communicator = Ice::initialize(argc, argv, initData);
+ 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/Ice/metrics/Test.ice b/cpp/test/Ice/metrics/Test.ice
new file mode 100644
index 00000000000..2f43a06fd37
--- /dev/null
+++ b/cpp/test/Ice/metrics/Test.ice
@@ -0,0 +1,50 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 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.
+//
+// **********************************************************************
+
+#pragma once
+
+module Test
+{
+
+exception UserEx
+{
+};
+
+sequence<byte> ByteSeq;
+
+interface Metrics
+{
+ void op();
+
+ idempotent void fail();
+
+ void opWithUserException()
+ throws UserEx;
+
+ void opWithRequestFailedException();
+
+ void opWithLocalException();
+
+ void opWithUnknownException();
+
+ void opByteS(ByteSeq bs);
+
+ Object* getAdmin();
+
+ void shutdown();
+};
+
+interface Controller
+{
+ void hold();
+
+ void resume();
+};
+
+};
diff --git a/cpp/test/Ice/metrics/TestI.cpp b/cpp/test/Ice/metrics/TestI.cpp
new file mode 100644
index 00000000000..52384c3736c
--- /dev/null
+++ b/cpp/test/Ice/metrics/TestI.cpp
@@ -0,0 +1,80 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 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>
+
+void
+MetricsI::op(const Ice::Current&)
+{
+}
+
+void
+MetricsI::fail(const Ice::Current& current)
+{
+ current.con->close(true);
+}
+
+void
+MetricsI::opWithUserException(const Ice::Current&)
+{
+ throw Test::UserEx();
+}
+
+void
+MetricsI::opWithRequestFailedException(const Ice::Current&)
+{
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+}
+
+void
+MetricsI::opWithLocalException(const Ice::Current&)
+{
+ throw Ice::SyscallException(__FILE__, __LINE__);
+}
+
+void
+MetricsI::opWithUnknownException(const Ice::Current&)
+{
+ throw "TEST";
+}
+
+void
+MetricsI::opByteS(const Test::ByteSeq& bs, const Ice::Current&)
+{
+}
+
+Ice::ObjectPrx
+MetricsI::getAdmin(const Ice::Current& current)
+{
+ return current.adapter->getCommunicator()->getAdmin();
+}
+
+void
+MetricsI::shutdown(const Ice::Current& current)
+{
+ current.adapter->getCommunicator()->shutdown();
+}
+
+ControllerI::ControllerI(const Ice::ObjectAdapterPtr& adapter) : _adapter(adapter)
+{
+}
+
+void
+ControllerI::hold(const Ice::Current&)
+{
+ _adapter->hold();
+ _adapter->waitForHold();
+}
+
+void
+ControllerI::resume(const Ice::Current&)
+{
+ _adapter->activate();
+}
diff --git a/cpp/test/Ice/metrics/TestI.h b/cpp/test/Ice/metrics/TestI.h
new file mode 100644
index 00000000000..2ca10db010a
--- /dev/null
+++ b/cpp/test/Ice/metrics/TestI.h
@@ -0,0 +1,51 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 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_I_H
+#define TEST_I_H
+
+#include <Test.h>
+
+class MetricsI : public Test::Metrics
+{
+ virtual void op(const Ice::Current&);
+
+ virtual void fail(const Ice::Current&);
+
+ virtual void opWithUserException(const Ice::Current&);
+
+ virtual void opWithRequestFailedException(const Ice::Current&);
+
+ virtual void opWithLocalException(const Ice::Current&);
+
+ virtual void opWithUnknownException(const Ice::Current&);
+
+ virtual void opByteS(const Test::ByteSeq&, const Ice::Current&);
+
+ virtual Ice::ObjectPrx getAdmin(const Ice::Current&);
+
+ virtual void shutdown(const Ice::Current&);
+};
+
+class ControllerI : public Test::Controller
+{
+public:
+
+ ControllerI(const Ice::ObjectAdapterPtr&);
+
+ virtual void hold(const Ice::Current&);
+
+ virtual void resume(const Ice::Current&);
+
+private:
+
+ const Ice::ObjectAdapterPtr _adapter;
+};
+
+#endif
diff --git a/cpp/test/Ice/metrics/run.py b/cpp/test/Ice/metrics/run.py
new file mode 100755
index 00000000000..751a8e1d456
--- /dev/null
+++ b/cpp/test/Ice/metrics/run.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2012 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
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise RuntimeError("can't find toplevel directory!")
+sys.path.append(os.path.join(path[0], "scripts"))
+import TestUtil
+
+TestUtil.clientServerTest()