Пример #1
0
bool AgentAdapter::init(const ::Ice::StringSeq& defaultAgents,const bool is_udp_protocol, const bool is_compress)
{  
    if (defaultAgents.empty())
    {
        XLOG_ERROR("AgentAdapter::init defaultAgent is empty!");
        return false;
    }

    srand(unsigned(time(NULL)));
    Ice::PropertiesPtr props=Ice::createProperties();
    props->setProperty("Ice.MessageSizeMax", ICE_MESSAGE_SIZE_MAX);
    props->setProperty("Ice.Override.Timeout", ICE_TIMEOUT_MILLISECONDS);
	Ice::InitializationData id;
    id.properties=props;
    _ic = ::Ice::initialize(id);

    srand((unsigned) time(NULL));
    current_agent_prx_number=0;

    std::vector<slice::AgentPrx> _prxs;
    for (::Ice::StringSeq::const_iterator it = defaultAgents.begin(); it != defaultAgents.end();
            ++it)
    {
        slice::AgentPrx prx = Util::getPrx<slice::AgentPrx>(_ic, *it, is_udp_protocol, 1000, is_compress);
	_prxs.push_back(prx);
    }
    agent_prxs.swap(_prxs);

    return true;
}
Пример #2
0
void
LibraryI::remove(const BookDescription& description)
{
    IceUtil::Mutex::Lock lock(*this);
    
    //
    // Note: no need to catch and retry on deadlock since all access to
    // _authors is serialized.
    //

    try
    {
        StringIsbnSeqDict::iterator p = _authors.find(description.authors);
        
        assert(p != _authors.end());

        //
        // Remove the isbn number from the sequence.
        //
        Ice::StringSeq isbnSeq  = p->second;
        isbnSeq.erase(remove_if(isbnSeq.begin(), isbnSeq.end(), bind2nd(equal_to<string>(), description.isbn)),
                         isbnSeq.end());
        
        if(isbnSeq.empty())
        {
            //
            // If there are no further associated isbn numbers then remove
            // the record.
            //
            _authors.erase(p);
        }
        else
        {
            //
            // Otherwise, write back the new record.
            //
            p.set(isbnSeq);
        }

        //
        // This can throw EvictorDeactivatedException (which indicates
        // an internal error). The exception is currently ignored.
        //
        _evictor->remove(createBookIdentity(description.isbn));
    }
    catch(const Freeze::DatabaseException& ex)
    {
        DatabaseException e;
        e.message = ex.message;
        throw e;
    }
}
Пример #3
0
int
Activator::activate(const string& name,
                    const string& exePath,
                    const string& pwdPath,
#ifndef _WIN32
                    uid_t uid,
                    gid_t gid,
#endif
                    const Ice::StringSeq& options,
                    const Ice::StringSeq& envs,
                    const ServerIPtr& server)
{
    IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);

    if(_deactivating)
    {
        throw string("The node is being shutdown.");
    }

    string path = exePath;
    if(path.empty())
    {
        throw string("The server executable path is empty.");
    }

    string pwd = IcePatch2Internal::simplify(pwdPath);
#ifdef _WIN32
    if(!IceUtilInternal::isAbsolutePath(path))
    {
        if(path.find('/') == string::npos)
        {
            //
            // Get the absolute pathname of the executable.
            //
            wchar_t absbuf[_MAX_PATH];
            wchar_t* fPart;
            wstring ext = path.size() <= 4 || path[path.size() - 4] != '.' ? L".exe" : L"";

            //
            // IceGrid doesn't support to use string converters, so don't need to use
            // any string converter in wstringToString conversions.
            //
            if(SearchPathW(NULL, IceUtil::stringToWstring(path).c_str(), ext.c_str(), _MAX_PATH, absbuf, &fPart) == 0)
            {
                if(_traceLevels->activator > 0)
                {
                    Trace out(_traceLevels->logger, _traceLevels->activatorCat);
                    out << "couldn't find `" << path << "' executable.";
                }
                throw string("Couldn't find `" + path + "' executable.");
            }
            path = IceUtil::wstringToString(absbuf);
        }
        else if(!pwd.empty())
        {
            path = pwd + "/" + path;
        }
    }

    //
    // Get the absolute pathname of the working directory.
    //
    // IceGrid doesn't support to use string converters, so
    // don't need to use any string converter in stringToWstring
    // conversions.
    //
    if(!pwd.empty())
    {
        wchar_t absbuf[_MAX_PATH];
        if(_wfullpath(absbuf, IceUtil::stringToWstring(pwd).c_str(), _MAX_PATH) == NULL)
        {
            if(_traceLevels->activator > 0)
            {
                Trace out(_traceLevels->logger, _traceLevels->activatorCat);
                out << "cannot convert `" << pwd << "' into an absolute path";
            }
            throw string("The server working directory path `" + pwd + "' can't be converted into an absolute path.");
        }
        pwd = IceUtil::wstringToString(absbuf);
    }
#endif

    //
    // Setup arguments.
    //
    StringSeq args;
    args.push_back(path);
    args.insert(args.end(), options.begin(), options.end());

    if(_traceLevels->activator > 0)
    {
        Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
        out << "activating server `" << name << "'";
        if(_traceLevels->activator > 1)
        {
            out << "\n";
            out << "path = " << path << "\n";
            if(pwd.empty())
            {
                string cwd;
                if(IceUtilInternal::getcwd(cwd) == 0)
                {
                    out << "pwd = " << cwd << "\n";
                }
            }
            else
            {
                out << "pwd = " << pwd << "\n";
            }
#ifndef _WIN32
            out << "uid/gid = " << uid << "/" << gid << "\n";
#endif
            if(!envs.empty())
            {
                out << "envs = " << toString(envs, ", ") << "\n";
            }
            if(!args.empty())
            {
                out << "args = " << toString(args);
            }
        }
    }

    //
    // Activate and create.
    //
#ifdef _WIN32

    //
    // Compose command line.
    //
    string cmd;
    for(StringSeq::const_iterator p = args.begin(); p != args.end(); ++p)
    {
        if(p != args.begin())
        {
            cmd.push_back(' ');
        }
        //
        // Enclose arguments containing spaces in double quotes.
        //
        if((*p).find(' ') != string::npos)
        {
            cmd.push_back('"');
            cmd.append(*p);
            cmd.push_back('"');
        }
        else
        {
            cmd.append(*p);
        }
    }

    //
    // IceGrid doesn't support to use string converters, so don't need to use
    // any string converter in stringToWstring conversions.
    //
    wstring wpwd = IceUtil::stringToWstring(pwd);
    const wchar_t* dir = !wpwd.empty() ? wpwd.c_str() : NULL;

    //
    // Make a copy of the command line.
    //
    wchar_t* cmdbuf = _wcsdup(IceUtil::stringToWstring(cmd).c_str());

    //
    // Create the environment block for the child process. We start with the environment
    // of this process, and then merge environment variables from the server description.
    // Since Windows is case insensitive wrt environment variables we convert the keys to
    // uppercase to ensure matches are found.
    //
    const wchar_t* env = NULL;
    wstring envbuf;
    if(!envs.empty())
    {
        map<wstring, wstring, UnicodeStringLess> envMap;
        LPVOID parentEnv = GetEnvironmentStringsW();
        const wchar_t* var = reinterpret_cast<const wchar_t*>(parentEnv);
        if(*var == L'=')
        {
            //
            // The environment block may start with some information about the
            // current drive and working directory. This is indicated by a leading
            // '=' character, so we skip to the first '\0' byte.
            //
            while(*var != L'\0')
                var++;
            var++;
        }
        while(*var != L'\0')
        {
            wstring s(var);
            wstring::size_type pos = s.find(L'=');
            if(pos != wstring::npos)
            {
                envMap[s.substr(0, pos)] = s.substr(pos + 1);
            }
            var += s.size();
            var++; // Skip the '\0' byte
        }
        FreeEnvironmentStringsW(static_cast<wchar_t*>(parentEnv));
        for(StringSeq::const_iterator p = envs.begin(); p != envs.end(); ++p)
        {
            //
            // IceGrid doesn't support to use string converters, so don't need to use
            // any string converter in stringToWstring conversions.
            //
            wstring s = IceUtil::stringToWstring(*p);
            wstring::size_type pos = s.find(L'=');
            if(pos != wstring::npos)
            {
                envMap[s.substr(0, pos)] = s.substr(pos + 1);
            }
        }

        for(map<wstring, wstring, UnicodeStringLess>::const_iterator q = envMap.begin(); q != envMap.end(); ++q)
        {
            envbuf.append(q->first);
            envbuf.push_back(L'=');
            envbuf.append(q->second);
            envbuf.push_back(L'\0');
        }
        envbuf.push_back(L'\0');
        env = envbuf.c_str();
    }

    Process process;

    STARTUPINFOW si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));
    BOOL b = CreateProcessW(
        NULL,                     // Executable
        cmdbuf,                   // Command line
        NULL,                     // Process attributes
        NULL,                     // Thread attributes
        FALSE,                    // Do NOT inherit handles
        CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT, // Process creation flags
        (LPVOID)env,              // Process environment
        dir,                      // Current directory
        &si,                      // Startup info
        &pi                       // Process info
    );

    free(cmdbuf);

    if(!b)
    {
        throw IceUtilInternal::lastErrorToString();
    }

    //
    // Caller is responsible for closing handles in PROCESS_INFORMATION. We don't need to
    // keep the thread handle, so we close it now. The process handle will be closed later.
    //
    CloseHandle(pi.hThread);
    process.activator = this;
    process.pid = pi.dwProcessId;
    process.hnd = pi.hProcess;
    process.server = server;
    map<string, Process>::iterator it = _processes.insert(make_pair(name, process)).first;

    Process* pp = &it->second;
    if(!RegisterWaitForSingleObject(&pp->waithnd, pp->hnd, activatorWaitCallback, pp, INFINITE,
                                    WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE))
    {
        throw IceUtilInternal::lastErrorToString();
    }

    //
    // Don't print the following trace, this might interfer with the
    // output of the started process if it fails with an error message.
    //
//     if(_traceLevels->activator > 0)
//     {
//         Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
//         out << "activated server `" << name << "' (pid = " << pi.dwProcessId << ")";
//     }

    return static_cast<Ice::Int>(process.pid);
#else
    int fds[2];
    if(pipe(fds) != 0)
    {
        SyscallException ex(__FILE__, __LINE__);
        ex.error = getSystemErrno();
        throw ex;
    }

    int errorFds[2];
    if(pipe(errorFds) != 0)
    {
        SyscallException ex(__FILE__, __LINE__);
        ex.error = getSystemErrno();
        throw ex;
    }


    //
    // Convert to standard argc/argv.
    //
    IceUtilInternal::ArgVector av(args);
    IceUtilInternal::ArgVector env(envs);

    //
    // Current directory
    //
    const char* pwdCStr = pwd.c_str();

    pid_t pid = fork();
    if(pid == -1)
    {
        SyscallException ex(__FILE__, __LINE__);
        ex.error = getSystemErrno();
        throw ex;
    }

    if(pid == 0) // Child process.
    {
        //
        // Until exec, we can only use async-signal safe functions
        //

        //
        // Unblock signals blocked by IceUtil::CtrlCHandler.
        //
        sigset_t sigs;
        sigemptyset(&sigs);
        sigaddset(&sigs, SIGHUP);
        sigaddset(&sigs, SIGINT);
        sigaddset(&sigs, SIGTERM);
        sigprocmask(SIG_UNBLOCK, &sigs, 0);

        //
        // Change the uid/gid under which the process will run.
        //
        if(setgid(gid) == -1)
        {
            ostringstream os;
            os << gid;
            reportChildError(getSystemErrno(), errorFds[1], "cannot set process group id", os.str().c_str(),
                             _traceLevels);
        }

        errno = 0;
        struct passwd* pw = getpwuid(uid);
        if(!pw)
        {
            if(errno)
            {
                reportChildError(getSystemErrno(), errorFds[1], "cannot read the password database", "",
                                 _traceLevels);
            }
            else
            {
                ostringstream os;
                os << uid;
                reportChildError(getSystemErrno(), errorFds[1], "unknown user uid"  , os.str().c_str(),
                                 _traceLevels);
            }
        }

        //
        // Don't initialize supplementary groups if we are not running as root.
        //
        if(getuid() == 0 && initgroups(pw->pw_name, gid) == -1)
        {
            ostringstream os;
            os << pw->pw_name;
            reportChildError(getSystemErrno(), errorFds[1], "cannot initialize process supplementary group access list for user",
                             os.str().c_str(), _traceLevels);
        }

        if(setuid(uid) == -1)
        {
            ostringstream os;
            os << uid;
            reportChildError(getSystemErrno(), errorFds[1], "cannot set process user id", os.str().c_str(),
                             _traceLevels);
        }

        //
        // Assign a new process group for this process.
        //
        setpgid(0, 0);

        //
        // Close all file descriptors, except for standard input,
        // standard output, standard error, and the write side
        // of the newly created pipe.
        //
        int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
        for(int fd = 3; fd < maxFd; ++fd)
        {
            if(fd != fds[1] && fd != errorFds[1])
            {
                close(fd);
            }
        }

        for(int i = 0; i < env.argc; i++)
        {
            //
            // Each env is leaked on purpose ... see man putenv().
            //
            if(putenv(strdup(env.argv[i])) != 0)
            {
                reportChildError(errno, errorFds[1], "cannot set environment variable",  env.argv[i],
                                 _traceLevels);
            }
        }

        //
        // Change working directory.
        //
        if(strlen(pwdCStr) != 0)
        {
            if(chdir(pwdCStr) == -1)
            {
                reportChildError(errno, errorFds[1], "cannot change working directory to",  pwdCStr,
                                 _traceLevels);
            }
        }

        //
        // Close on exec the error message file descriptor.
        //
        int flags = fcntl(errorFds[1], F_GETFD);
        flags |= 1; // FD_CLOEXEC
        if(fcntl(errorFds[1], F_SETFD, flags) == -1)
        {
            close(errorFds[1]);
            errorFds[1] = -1;
        }

        if(execvp(av.argv[0], av.argv) == -1)
        {
            if(errorFds[1] != -1)
            {
                reportChildError(errno, errorFds[1], "cannot execute",  av.argv[0], _traceLevels);
            }
            else
            {
                reportChildError(errno, fds[1], "cannot execute",  av.argv[0], _traceLevels);
            }
        }
    }
    else // Parent process.
    {
        close(fds[1]);
        close(errorFds[1]);

        //
        // Read a potential error message over the error message pipe.
        //
        char s[16];
        ssize_t rs;
        string message;
        while((rs = read(errorFds[0], &s, 16)) > 0)
        {
            message.append(s, rs);
        }

        //
        // If an error occured before the exec() we do some cleanup and throw.
        //
        if(!message.empty())
        {
            close(fds[0]);
            close(errorFds[0]);
            waitPid(pid);
            throw message;
        }

        //
        // Otherwise, the exec() was successfull and we don't need the error message
        // pipe anymore.
        //
        close(errorFds[0]);

        Process process;
        process.pid = pid;
        process.pipeFd = fds[0];
        process.server = server;
        _processes.insert(make_pair(name, process));

        int flags = fcntl(process.pipeFd, F_GETFL);
        flags |= O_NONBLOCK;
        fcntl(process.pipeFd, F_SETFL, flags);

        setInterrupt();

    //
    // Don't print the following trace, this might interfere with the
    // output of the started process if it fails with an error message.
    //
//      if(_traceLevels->activator > 0)
//      {
//          Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
//          out << "activated server `" << name << "' (pid = " << pid << ")";
//      }
    }

    return pid;
#endif
}
Пример #4
0
void
allTests(const Ice::CommunicatorPtr& communicator)
{
    string ref = "DemoIceBox/admin:default -p 9996 -t 10000";
    Ice::ObjectPrx admin = communicator->stringToProxy(ref);

    TestFacetPrx facet;

    cout << "testing custom facet... " << flush;
    {
        //
        // Test: Verify that the custom facet is present.
        //
        facet = Test::TestFacetPrx::checkedCast(admin, "TestFacet");
        facet->ice_ping();
    }
    cout << "ok" << endl;

    cout << "testing properties facet... " << flush;
    {
        Ice::PropertiesAdminPrx pa =
            Ice::PropertiesAdminPrx::checkedCast(admin, "IceBox.Service.TestService.Properties");

        //
        // Test: PropertiesAdmin::getProperty()
        //
        test(pa->getProperty("Prop1") == "1");
        test(pa->getProperty("Bogus") == "");

        //
        // Test: PropertiesAdmin::getProperties()
        //
        Ice::PropertyDict pd = pa->getPropertiesForPrefix("");
        test(pd.size() == 5);
        test(pd["Prop1"] == "1");
        test(pd["Prop2"] == "2");
        test(pd["Prop3"] == "3");
        test(pd["Ice.Config"] == "config.service");
        test(pd["Ice.ProgramName"] == "IceBox-TestService");

        Ice::PropertyDict changes;

        //
        // Test: PropertiesAdmin::setProperties()
        //
        Ice::PropertyDict setProps;
        setProps["Prop1"] = "10"; // Changed
        setProps["Prop2"] = "20"; // Changed
        setProps["Prop3"] = ""; // Removed
        setProps["Prop4"] = "4"; // Added
        setProps["Prop5"] = "5"; // Added
        pa->setProperties(setProps);
        test(pa->getProperty("Prop1") == "10");
        test(pa->getProperty("Prop2") == "20");
        test(pa->getProperty("Prop3") == "");
        test(pa->getProperty("Prop4") == "4");
        test(pa->getProperty("Prop5") == "5");
        changes = facet->getChanges();
        test(changes.size() == 5);
        test(changes["Prop1"] == "10");
        test(changes["Prop2"] == "20");
        test(changes["Prop3"] == "");
        test(changes["Prop4"] == "4");
        test(changes["Prop5"] == "5");
        pa->setProperties(setProps);
        changes = facet->getChanges();
        test(changes.empty());
    }
    cout << "ok" << endl;

    cout << "testing metrics admin facet... " << flush;
    {
        IceMX::MetricsAdminPrx ma = IceMX::MetricsAdminPrx::checkedCast(admin, "IceBox.Service.TestService.Metrics");

        Ice::PropertiesAdminPrx pa =
            Ice::PropertiesAdminPrx::checkedCast(admin, "IceBox.Service.TestService.Properties");

        Ice::StringSeq views;
        Ice::StringSeq disabledViews;
        views = ma->getMetricsViewNames(disabledViews);
        test(views.empty());

        Ice::PropertyDict setProps;
        setProps["IceMX.Metrics.Debug.GroupBy"] = "id";
        setProps["IceMX.Metrics.All.GroupBy"] = "none";
        setProps["IceMX.Metrics.Parent.GroupBy"] = "parent";
        pa->setProperties(setProps);
        pa->setProperties(Ice::PropertyDict());

        views = ma->getMetricsViewNames(disabledViews);
        test(views.size() == 3);
        
        // Make sure that the IceBox communicator metrics admin is a separate instance.
        test(IceMX::MetricsAdminPrx::checkedCast(admin, "Metrics")->getMetricsViewNames(disabledViews).empty());
    }
    cout << "ok" << endl;
}
Пример #5
0
MetricsPrx
allTests(const Ice::CommunicatorPtr& communicator, const CommunicatorObserverIPtr& obsv)
{
    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, "Metrics");
    test(clientProps && clientMetrics);

    admin = metrics->getAdmin();
    Ice::PropertiesAdminPrx serverProps = Ice::PropertiesAdminPrx::checkedCast(admin, "Properties");
    IceMX::MetricsAdminPrx serverMetrics = IceMX::MetricsAdminPrx::checkedCast(admin, "Metrics");
    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);
    
#ifndef ICE_OS_WINRT
    int threadCount = 4;
#else
    int threadCount = 3; // No endpoint host resolver thread with WinRT.
#endif

    Ice::Long timestamp;
    IceMX::MetricsView view = clientMetrics->getMetricsView("View", timestamp);
    test(view["Connection"].size() == 1 && view["Connection"][0]->current == 1 && view["Connection"][0]->total == 1);
    test(view["Thread"].size() == 1 && view["Thread"][0]->current == threadCount && 
         view["Thread"][0]->total == threadCount);
    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", timestamp);
    test(static_cast<int>(view["Thread"].size()) == threadCount);
    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", timestamp);
    test(view["Thread"].size() > 4);
    test(view["Connection"].size() == 2);
    test(view["Dispatch"].size() == 1);
    test(view["Dispatch"][0]->current <= 1 && 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", timestamp)["Connection"].empty());
    test(serverMetrics->getMetricsView("View", timestamp)["Connection"].empty());

    metrics->ice_ping();

    IceMX::ConnectionMetricsPtr cm1, sm1, cm2, sm2;
    cm1 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View", timestamp)["Connection"][0]);
    sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(serverMetrics->getMetricsView("View", timestamp)["Connection"][0]);
    sm1 = getServerConnectionMetrics(serverMetrics, 25);
    test(cm1->total == 1 && sm1->total == 1);

    metrics->ice_ping();

    cm2 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View", timestamp)["Connection"][0]);
    sm2 = getServerConnectionMetrics(serverMetrics, 50);

    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", timestamp)["Connection"][0]);
    sm2 = getServerConnectionMetrics(serverMetrics, sm1->sentBytes + cm2->receivedBytes - cm1->receivedBytes);
    Ice::Long requestSz = cm2->sentBytes - cm1->sentBytes;
    Ice::Long replySz = cm2->receivedBytes - cm1->receivedBytes;

    cm1 = cm2;
    sm1 = sm2;

    bs.resize(456);
    metrics->opByteS(bs);

    cm2 = IceMX::ConnectionMetricsPtr::dynamicCast(clientMetrics->getMetricsView("View", timestamp)["Connection"][0]);
    sm2 = getServerConnectionMetrics(serverMetrics, sm1->sentBytes + replySz);

    // 4 is for the seq variable size
    test(cm2->sentBytes - cm1->sentBytes == requestSz + static_cast<int>(bs.size()) + 4);
    test(cm2->receivedBytes - cm1->receivedBytes == replySz);
    test(sm2->receivedBytes - sm1->receivedBytes == requestSz + static_cast<int>(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", timestamp)["Connection"][0]);
    sm2 = getServerConnectionMetrics(serverMetrics, sm1->sentBytes + replySz);

    // 4 is for the seq variable size
    test(cm2->sentBytes - cm1->sentBytes == requestSz + static_cast<int>(bs.size()) + 4);
    test(cm2->receivedBytes - cm1->receivedBytes == replySz);
    test(sm2->receivedBytes - sm1->receivedBytes == requestSz + static_cast<int>(bs.size()) + 4);
    test(sm2->sentBytes - sm1->sentBytes == replySz);
    
    props["IceMX.Metrics.View.Map.Connection.GroupBy"] = "state";
    updateProps(clientProps, serverProps, update, props, "Connection");

    map<string, IceMX::MetricsPtr> map;
    
    map = toMap(serverMetrics->getMetricsView("View", timestamp)["Connection"]);

    test(map["active"]->current == 1);

    ControllerPrx controller = ControllerPrx::checkedCast(communicator->stringToProxy("controller:default -p 12011"));
    controller->hold();

    map = toMap(clientMetrics->getMetricsView("View", timestamp)["Connection"]);
    test(map["active"]->current == 1);
    map = toMap(serverMetrics->getMetricsView("View", timestamp)["Connection"]);
    test(map["holding"]->current == 1);

    metrics->ice_getConnection()->close(false);

    map = toMap(clientMetrics->getMetricsView("View", timestamp)["Connection"]);
    test(map["closing"]->current == 1);
    map = toMap(serverMetrics->getMetricsView("View", timestamp)["Connection"]);
    test(map["holding"]->current == 1);

    controller->resume();

    map = toMap(serverMetrics->getMetricsView("View", timestamp)["Connection"]);
    test(map["holding"]->current == 0);

    props["IceMX.Metrics.View.Map.Connection.GroupBy"] = "none";
    updateProps(clientProps, serverProps, update, props, "Connection");

    metrics->ice_getConnection()->close(false);

    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", timestamp)["Connection"][0]);
    while(true)
    {
        sm1 = IceMX::ConnectionMetricsPtr::dynamicCast(
            serverMetrics->getMetricsView("View", timestamp)["Connection"][0]);
        if(sm1-> failures >= 2)
        {
            break;
        }
        IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10));
    }

    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");

    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 -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", "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", "");
    testAttribute(clientMetrics, clientProps, update, "Connection", "mcastPort", "");
    
    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", timestamp)["ConnectionEstablishment"].empty());

    metrics->ice_ping();
    
    test(clientMetrics->getMetricsView("View", timestamp)["ConnectionEstablishment"].size() == 1);
    IceMX::MetricsPtr m1 = clientMetrics->getMetricsView("View", timestamp)["ConnectionEstablishment"][0];
    test(m1->current == 0 && m1->total == 1 && m1->id == "127.0.0.1:12010");

    metrics->ice_getConnection()->close(false);
    controller->hold();
    try
    {
        communicator->stringToProxy("test:tcp -p 12010 -h 127.0.0.1")->ice_timeout(10)->ice_ping();
        test(false);
    }
    catch(const Ice::ConnectTimeoutException&)
    {
    }
    catch(const Ice::LocalException&)
    {
        test(false);
    }
    controller->resume();
    test(clientMetrics->getMetricsView("View", timestamp)["ConnectionEstablishment"].size() == 1);
    m1 = clientMetrics->getMetricsView("View", timestamp)["ConnectionEstablishment"][0];
    test(m1->id == "127.0.0.1:12010" && m1->total == 3 && 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 -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", "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;

    //
    // Ice doesn't do any endpoint lookup with WinRT, the WinRT
    // runtime takes care of if.
    //
#ifndef ICE_OS_WINRT
    cout << "testing endpoint lookup metrics... " << flush;

    props["IceMX.Metrics.View.Map.ConnectionEstablishment.GroupBy"] = "id";
    updateProps(clientProps, serverProps, update, props, "EndpointLookup");
    test(clientMetrics->getMetricsView("View", timestamp)["EndpointLookup"].empty());

    Ice::ObjectPrx prx = communicator->stringToProxy("metrics:default -p 12010 -h localhost");
    prx->ice_ping();
    
    test(clientMetrics->getMetricsView("View", timestamp)["EndpointLookup"].size() == 1);
    m1 = clientMetrics->getMetricsView("View", timestamp)["EndpointLookup"][0];

    test(m1->current <= 1 && m1->total == 1 && m1->id == "tcp -h localhost -p 12010");

    prx->ice_getConnection()->close(false);

    bool dnsException = false;
    try
    {
        communicator->stringToProxy("test:tcp -t 500 -p 12010 -h unknownfoo.zeroc.com")->ice_ping();
        test(false);
    }
    catch(const Ice::DNSException&)
    {
        dnsException = true;
    }
    catch(const Ice::LocalException&)
    {
        // Some DNS servers don't fail on unknown DNS names.
    }
    test(clientMetrics->getMetricsView("View", timestamp)["EndpointLookup"].size() == 2);
    m1 = clientMetrics->getMetricsView("View", timestamp)["EndpointLookup"][1];
    test(m1->id == "tcp -h unknownfoo.zeroc.com -p 12010 -t 500" && m1->total == 2 && 
         (!dnsException || m1->failures == 2));
    if(dnsException)
    {
        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 -h localhost -p 12010", c);
    testAttribute(clientMetrics, clientProps, update, "EndpointLookup", "endpoint", 
                  "tcp -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", "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;
#endif

    cout << "testing dispatch metrics... " << flush;

    props["IceMX.Metrics.View.Map.Dispatch.GroupBy"] = "operation";
    updateProps(clientProps, serverProps, update, props, "Dispatch");
    test(serverMetrics->getMetricsView("View", timestamp)["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&)
    {
    }

    map = toMap(serverMetrics->getMetricsView("View", timestamp)["Dispatch"]);
    test(map.size() == 6);

    IceMX::DispatchMetricsPtr dm1 = IceMX::DispatchMetricsPtr::dynamicCast(map["op"]);
    test(dm1->current <= 1 && dm1->total == 1 && dm1->failures == 0 && dm1->userException == 0);
    test(dm1->size == 21 && dm1->replySize == 7);

    dm1 = IceMX::DispatchMetricsPtr::dynamicCast(map["opWithUserException"]);
    test(dm1->current <= 1 && dm1->total == 1 && dm1->failures == 0 && dm1->userException == 1);
    test(dm1->size == 38 && dm1->replySize == 23);

    dm1 = IceMX::DispatchMetricsPtr::dynamicCast(map["opWithLocalException"]);
    test(dm1->current <= 1 && dm1->total == 1 && dm1->failures == 1 && dm1->userException == 0);
    checkFailure(serverMetrics, "Dispatch", dm1->id, "Ice::SyscallException", 1);
    test(dm1->size == 39 && dm1->replySize > 7); // Reply contains the exception stack depending on the OS.

    dm1 = IceMX::DispatchMetricsPtr::dynamicCast(map["opWithRequestFailedException"]);
    test(dm1->current <= 1 && dm1->total == 1 && dm1->failures == 1 && dm1->userException == 0);
    checkFailure(serverMetrics, "Dispatch", dm1->id, "Ice::ObjectNotExistException", 1);
    test(dm1->size == 47 && dm1->replySize == 40);

    dm1 = IceMX::DispatchMetricsPtr::dynamicCast(map["opWithUnknownException"]);
    test(dm1->current <= 1 && dm1->total == 1 && dm1->failures == 1 && dm1->userException == 0);
    checkFailure(serverMetrics, "Dispatch", dm1->id, "unknown", 1);
    test(dm1->size == 41 && dm1->replySize == 23);

    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 -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", "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", "", op);
    testAttribute(serverMetrics, serverProps, update, "Dispatch", "mcastPort", "", 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", "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", "", 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", timestamp)["Invocation"].empty());

    CallbackPtr cb = new Callback();
    metrics->op();
    metrics->end_op(metrics->begin_op());
    metrics->begin_op(newCallback_Metrics_op(cb, &Callback::response, &Callback::exception));
    cb->waitForResponse();

    // User exception
    try
    {
        metrics->opWithUserException();
        test(false);
    }
    catch(const Test::UserEx&)
    {
    }
    try
    {
        metrics->end_opWithUserException(metrics->begin_opWithUserException());
        test(false);
    }
    catch(const Test::UserEx&)
    {
    }
    metrics->begin_opWithUserException(newCallback_Metrics_opWithUserException(
                                           cb, &Callback::response, &Callback::exception));
    cb->waitForResponse();

    // Request failed exception
    try
    {
        metrics->opWithRequestFailedException();
        test(false);
    }
    catch(const Ice::RequestFailedException&)
    {
    }
    try
    {
        metrics->end_opWithRequestFailedException(metrics->begin_opWithRequestFailedException());
        test(false);
    }
    catch(const Ice::RequestFailedException&)
    {
    }
    metrics->begin_opWithRequestFailedException(newCallback_Metrics_opWithRequestFailedException(
                                                    cb, &Callback::response, &Callback::exception));
    cb->waitForResponse();

    // Local exception
    try
    {
        metrics->opWithLocalException();
        test(false);
    }
    catch(const Ice::LocalException&)
    {
    }
    try
    {
        metrics->end_opWithLocalException(metrics->begin_opWithLocalException());
        test(false);
    }
    catch(const Ice::LocalException&)
    {
    }
    metrics->begin_opWithLocalException(newCallback_Metrics_opWithLocalException(
                                            cb, &Callback::response, &Callback::exception));
    cb->waitForResponse();

    // Unknown exception
    try
    {
        metrics->opWithUnknownException();
        test(false);
    }
    catch(const Ice::UnknownException&)
    {
    }
    try
    {
        metrics->end_opWithUnknownException(metrics->begin_opWithUnknownException());
        test(false);
    }
    catch(const Ice::UnknownException&)
    {
    }
    metrics->begin_opWithUnknownException(newCallback_Metrics_opWithUnknownException(
                                              cb, &Callback::response, &Callback::exception));
    cb->waitForResponse();

    // Fail
    try
    {
        metrics->fail();
        test(false);
    }
    catch(const Ice::ConnectionLostException&)
    {
    }
    try
    {
        metrics->end_fail(metrics->begin_fail());
        test(false);
    }
    catch(const Ice::ConnectionLostException&)
    {
    }
    metrics->begin_fail(newCallback_Metrics_fail(cb, &Callback::response, &Callback::exception));
    cb->waitForResponse();

    map = toMap(clientMetrics->getMetricsView("View", timestamp)["Invocation"]);
    test(map.size() == 6);

    IceMX::InvocationMetricsPtr im1;
    IceMX::RemoteMetricsPtr rim1;
    im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["op"]);
    test(im1->current <= 1 && im1->total == 3 && im1->failures == 0 && im1->retry == 0 && im1->remotes.size() == 1);
    rim1 = IceMX::RemoteMetricsPtr::dynamicCast(im1->remotes[0]);
    test(rim1->current == 0 && rim1->total == 3 && rim1->failures == 0);
    test(rim1->size == 63 && rim1->replySize == 21);
    
    im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithUserException"]);
    test(im1->current <= 1 && im1->total == 3 && im1->failures == 0 && im1->retry == 0 && im1->remotes.size() == 1);
    rim1 = IceMX::RemoteMetricsPtr::dynamicCast(im1->remotes[0]);
    test(rim1->current == 0 && rim1->total == 3 && rim1->failures == 0);
    test(rim1->size == 114 && rim1->replySize == 69);
    test(im1->userException == 3);

    im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithLocalException"]);
    test(im1->current <= 1 && im1->total == 3 && im1->failures == 3 && im1->retry == 0 && im1->remotes.size() == 1);
    rim1 = IceMX::RemoteMetricsPtr::dynamicCast(im1->remotes[0]);
    test(rim1->current == 0 && rim1->total == 3 && rim1->failures == 0);
    test(rim1->size == 117 && rim1->replySize > 7);
    checkFailure(clientMetrics, "Invocation", im1->id, "Ice::UnknownLocalException", 3);

    im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithRequestFailedException"]);
    test(im1->current <= 1 && im1->total == 3 && im1->failures == 3 && im1->retry == 0 && im1->remotes.size() == 1);
    rim1 = IceMX::RemoteMetricsPtr::dynamicCast(im1->remotes[0]);
    test(rim1->current == 0 && rim1->total == 3 && rim1->failures == 0);
    test(rim1->size == 141 && rim1->replySize == 120);
    checkFailure(clientMetrics, "Invocation", im1->id, "Ice::ObjectNotExistException", 3);

    im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["opWithUnknownException"]);
    test(im1->current <= 1 && im1->total == 3 && im1->failures == 3 && im1->retry == 0 && im1->remotes.size() == 1);
    rim1 = IceMX::RemoteMetricsPtr::dynamicCast(im1->remotes[0]);
    test(rim1->current == 0 && rim1->total == 3 && rim1->failures == 0);
    test(rim1->size == 123 && rim1->replySize == 69);
    checkFailure(clientMetrics, "Invocation", im1->id, "Ice::UnknownException", 3);

    im1 = IceMX::InvocationMetricsPtr::dynamicCast(map["fail"]);
    test(im1->current <= 1 && im1->total == 3 && im1->failures == 3 && im1->retry == 3 && im1->remotes.size() == 6);
    test(im1->remotes[0]->current == 0 && im1->remotes[0]->total == 1 && im1->remotes[0]->failures == 1);
    test(im1->remotes[1]->current == 0 && im1->remotes[1]->total == 1 && im1->remotes[1]->failures == 1);
    test(im1->remotes[2]->current == 0 && im1->remotes[2]->total == 1 && im1->remotes[2]->failures == 1);
    test(im1->remotes[3]->current == 0 && im1->remotes[3]->total == 1 && im1->remotes[3]->failures == 1);
    test(im1->remotes[4]->current == 0 && im1->remotes[4]->total == 1 && im1->remotes[4]->failures == 1);
    test(im1->remotes[5]->current == 0 && im1->remotes[5]->total == 1 && im1->remotes[5]->failures == 1);
    checkFailure(clientMetrics, "Invocation", im1->id, "Ice::ConnectionLostException", 3);

    testAttribute(clientMetrics, clientProps, update, "Invocation", "parent", "Communicator", op);
    testAttribute(clientMetrics, clientProps, update, "Invocation", "id", "metrics -t -e 1.1 [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 -e 1.1:tcp -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", "", op);

    cout << "ok" << endl;

    cout << "testing metrics view enable/disable..." << flush;

    Ice::StringSeq disabledViews;
    props["IceMX.Metrics.View.GroupBy"] = "none";
    props["IceMX.Metrics.View.Disabled"] = "0";
    updateProps(clientProps, serverProps, update, props, "Thread");
    test(!clientMetrics->getMetricsView("View", timestamp)["Thread"].empty());
    test(clientMetrics->getMetricsViewNames(disabledViews).size() == 1 && disabledViews.empty());

    props["IceMX.Metrics.View.Disabled"] = "1";
    updateProps(clientProps, serverProps, update, props, "Thread");
    test(clientMetrics->getMetricsView("View", timestamp)["Thread"].empty());
    test(clientMetrics->getMetricsViewNames(disabledViews).empty() && disabledViews.size() == 1);

    clientMetrics->enableMetricsView("View");
    test(!clientMetrics->getMetricsView("View", timestamp)["Thread"].empty());
    test(clientMetrics->getMetricsViewNames(disabledViews).size() == 1 && disabledViews.empty());

    clientMetrics->disableMetricsView("View");
    test(clientMetrics->getMetricsView("View", timestamp)["Thread"].empty());
    test(clientMetrics->getMetricsViewNames(disabledViews).empty() && disabledViews.size() == 1);

    try
    {
        clientMetrics->enableMetricsView("UnknownView");
    }
    catch(const IceMX::UnknownMetricsView&)
    {
    }

    cout << "ok" << endl;

    cout << "testing instrumentation observer delegate... " << flush;

    test(obsv->threadObserver->getTotal() > 0);
    test(obsv->connectionObserver->getTotal() > 0);
    test(obsv->connectionEstablishmentObserver->getTotal() > 0);
#ifndef ICE_OS_WINRT
    test(obsv->endpointLookupObserver->getTotal() > 0);
#endif
    test(obsv->dispatchObserver->getTotal() > 0);
    test(obsv->invocationObserver->getTotal() > 0);
    test(obsv->invocationObserver->remoteObserver->getTotal() > 0);

    test(obsv->threadObserver->getCurrent() > 0);
    test(obsv->connectionObserver->getCurrent() > 0);
    test(obsv->connectionEstablishmentObserver->getCurrent() == 0);
#ifndef ICE_OS_WINRT
    test(obsv->endpointLookupObserver->getCurrent() == 0);
#endif
    test(obsv->dispatchObserver->getCurrent() == 0);
    test(obsv->invocationObserver->getCurrent() == 0);
    test(obsv->invocationObserver->remoteObserver->getCurrent() == 0);

    test(obsv->threadObserver->getFailedCount() == 0);
    test(obsv->connectionObserver->getFailedCount() > 0);
    test(obsv->connectionEstablishmentObserver->getFailedCount() > 0);
#ifndef ICE_OS_WINRT
    test(obsv->endpointLookupObserver->getFailedCount() > 0);
#endif
    //test(obsv->dispatchObserver->getFailedCount() > 0);
    test(obsv->invocationObserver->getFailedCount() > 0);
    test(obsv->invocationObserver->remoteObserver->getFailedCount() > 0);

    test(obsv->threadObserver->states > 0);
    test(obsv->connectionObserver->received > 0 && obsv->connectionObserver->sent > 0);
    //test(obsv->dispatchObserver->userExceptionCount > 0);
    test(obsv->invocationObserver->userExceptionCount > 0 && obsv->invocationObserver->retriedCount > 0);
    test(obsv->invocationObserver->remoteObserver->replySize > 0);

    cout << "ok" << endl;

    return metrics;
}
Пример #6
0
bool
NodeI::canRemoveServerDirectory(const string& name)
{
    //
    // Check if there's files which we didn't create.
    //
    Ice::StringSeq c = readDirectory(_serversDir + "/" + name);
    set<string> contents(c.begin(), c.end());
    contents.erase("dbs");
    contents.erase("config");
    contents.erase("distrib");
    contents.erase("revision");
    contents.erase("data");
    Ice::StringSeq serviceDataDirs;
    for(set<string>::const_iterator p = contents.begin(); p != contents.end(); ++p)
    {
        if(p->find("data_") != 0)
        {
            return false;
        }
        serviceDataDirs.push_back(*p);
    }
    if(!contents.empty())
    {
        return false;
    }

    c = readDirectory(_serversDir + "/" + name + "/config");
    for(Ice::StringSeq::const_iterator p = c.begin() ; p != c.end(); ++p)
    {
        if(p->find("config") != 0)
        {
            return false;
        }
    }

    if(IceUtilInternal::directoryExists(_serversDir + "/" + name + "/dbs"))
    {
        c = readDirectory(_serversDir + "/" + name + "/dbs");
        for(Ice::StringSeq::const_iterator p = c.begin() ; p != c.end(); ++p)
        {
            try
            {
                Ice::StringSeq files = readDirectory(_serversDir + "/" + name + "/dbs/" + *p);
                files.erase(remove(files.begin(), files.end(), "DB_CONFIG"), files.end());
                files.erase(remove(files.begin(), files.end(), "__Freeze"), files.end());
                if(!files.empty())
                {
                    return false;
                }
            }
            catch(const string&)
            {
                return false;
            }
        }
    }

    if(IceUtilInternal::directoryExists(_serversDir + "/" + name + "/data"))
    {
        if(!readDirectory(_serversDir + "/" + name + "/data").empty())
        {
            return false;
        }
    }

    for(Ice::StringSeq::const_iterator p = serviceDataDirs.begin(); p != serviceDataDirs.end(); ++p)
    {
        try
        {
            if(!readDirectory(_serversDir + "/" + name + "/" + *p).empty())
            {
                return false;
            }
        }
        catch(const string&)
        {
            return false;
        }
    }
    return true;
}
Пример #7
0
void
logTests(const Ice::CommunicatorPtr& comm, const AdminSessionPrx& session)
{
    cout << "testing stderr/stdout/log files... " << flush;
    string testDir = comm->getProperties()->getProperty("TestDir");
    assert(!testDir.empty());
    try
    {
        session->openServerStdErr("LogServer", -1);
        test(false);
    }
    catch(const FileNotAvailableException&)
    {
    }
    try
    {
        session->openServerStdOut("LogServer", -1);
        test(false);
    }
    catch(const FileNotAvailableException&)
    {
    }
    try
    {
        session->openServerLog("LogServer", "unknown.txt", -1);
        test(false);
    }
    catch(const FileNotAvailableException&)
    {
    }

    Ice::ObjectPrx obj = TestIntfPrx::checkedCast(comm->stringToProxy("LogServer"));
    try
    {
        session->openServerStdErr("LogServer", -1)->destroy();
        session->openServerStdOut("LogServer", -1)->destroy();
    }
    catch(const FileNotAvailableException& ex)
    {
        cerr << ex.reason << endl;
        test(false);
    }

    FileIteratorPrx it;
    Ice::StringSeq lines;
    try
    {
        //
        // Test with empty file.
        //
        string path = testDir + "/log1.txt";
        ofstream os(path.c_str());
        os.close();

        it = session->openServerLog("LogServer", testDir + "/log1.txt", -1);
        test(it->read(1024, lines) && lines.empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log1.txt", 0);
        test(it->read(1024, lines) && lines.empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log1.txt", 100);
        test(it->read(1024, lines) && lines.empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();
    }
    catch(const FileNotAvailableException& ex)
    {
        cerr << ex.reason << endl;
        test(false);
    }

    try
    {
        //
        // Test with log file with one line with no EOL on last line.
        //
        string path = testDir + "/log2.txt";
        ofstream os(path.c_str());
        os << "one line file with no EOL on last line";
        os.close();

        it = session->openServerLog("LogServer", testDir + "/log2.txt", -1);
        test(it->read(1024, lines) && lines.size() == 1);
        test(lines[0] == "one line file with no EOL on last line");
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log2.txt", 0);
        test(it->read(1024, lines) && lines.empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log2.txt", 1);
        test(it->read(1024, lines) && lines.size() == 1);
        test(lines[0] == "one line file with no EOL on last line");
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log2.txt", 100);
        test(it->read(1024, lines) && lines.size() == 1);
        test(lines[0] == "one line file with no EOL on last line");
        test(it->read(1024, lines) && lines.empty());
        it->destroy();
    }
    catch(const FileNotAvailableException& ex)
    {
        cerr << ex.reason << endl;
        test(false);
    }

    try
    {
        //
        // Test with log file with one line with EOL on last line.
        //
        string path = testDir + "/log3.txt";
        ofstream os(path.c_str());
        os << "one line file with EOL on last line" << endl;
        os.close();

        it = session->openServerLog("LogServer", testDir + "/log3.txt", -1);
        test(it->read(1024, lines) && lines.size() == 2);
        test(lines[0] == "one line file with EOL on last line");
        test(lines[1].empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log3.txt", 0);
        test(it->read(1024, lines) && lines.empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log3.txt", 1);
        test(it->read(1024, lines) && lines.size() == 2);
        test(lines[0] == "one line file with EOL on last line");
        test(lines[1].empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log3.txt", 100);
        test(it->read(1024, lines) && lines.size() == 2);
        test(lines[0] == "one line file with EOL on last line");
        test(lines[1].empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log3.txt", 2);
        test(it->read(1024, lines) && lines.size() == 2);
        test(lines[0] == "one line file with EOL on last line");
        test(lines[1].empty());
        it->destroy();
    }
    catch(const FileNotAvailableException& ex)
    {
        cerr << ex.reason << endl;
        test(false);
    }

    try
    {
        //
        // Test with log file with multiple lines
        //
        string path = testDir + "/log4.txt";
        ofstream os(path.c_str());
        os << "line 1" << endl;
        os << "line 2" << endl;
        os << "line 3" << endl;
        os.close();

        it = session->openServerLog("LogServer", testDir + "/log4.txt", -1);
        test(it->read(1024, lines) && lines.size() == 4);
        test(lines[0] == "line 1");
        test(lines[1] == "line 2");
        test(lines[2] == "line 3");
        test(lines[3].empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log4.txt", 0);
        test(it->read(1024, lines) && lines.empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log4.txt", 1);
        test(it->read(1024, lines) && lines.size() == 2);
        test(lines[0] == "line 3");
        test(lines[1].empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log4.txt", 2);
        test(it->read(1024, lines) && lines.size() == 3);
        test(lines[0] == "line 2");
        test(lines[1] == "line 3");
        test(lines[2].empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log4.txt", 100);
        test(it->read(1024, lines) && lines.size() == 4);
        test(lines[0] == "line 1");
        test(lines[1] == "line 2");
        test(lines[2] == "line 3");
        test(lines[3].empty());
        it->destroy();
    }
    catch(const FileNotAvailableException& ex)
    {
        cerr << ex.reason << endl;
        test(false);
    }

    try
    {
        string path = testDir + "/log1.txt";
        ofstream os(path.c_str(), ios_base::out | ios_base::trunc);
        os << flush;

        it = session->openServerLog("LogServer", testDir + "/log1.txt", -1);
        test(it->read(1024, lines) && lines.empty());

        os << "started a line" << flush;
        test(it->read(1024, lines) && lines.size() == 1 && lines[0] == "started a line");
        os << ", continuing the line" << flush;
        test(it->read(1024, lines) && lines.size() == 1 && lines[0] == ", continuing the line");
        os << ", finished" << endl;
        test(it->read(1024, lines) && lines.size() == 2);
        test(lines[0] == ", finished");
        test(lines[1].empty());

        os << "started a line" << flush;
        test(it->read(1024, lines) && lines.size() == 1 && lines[0] == "started a line");
        os << endl << flush;
        test(it->read(1024, lines) && lines.size() == 2 && lines[0].empty() && lines[1].empty());
        os << "and another line" << endl;
        test(it->read(1024, lines) && lines.size() == 2 && !lines[0].empty() && lines[1].empty());

        os << "starting a long line now, " << flush;
        test(it->read(1024, lines) && lines.size() == 1 && lines[0] == "starting a long line now, ");
        writeLongLine(os);
        os.flush();
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineStart(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineContent(lines[0]));
        test(it->read(1024, lines) && lines.size() == 1 && isLongLineEnd(lines[0]));
        test(it->read(1024, lines) && lines.empty());
        os << endl;
        test(it->read(1024, lines) && lines.size() == 2 && lines[0].empty() && lines[1].empty());

        os << "starting multiple long line now, " << flush;
        test(it->read(1024, lines) && lines.size() == 1 && lines[0] == "starting multiple long line now, ");
        writeLongLine(os);
        os << endl;
        writeLongLine(os);
        os << endl;
        writeLongLine(os);
        os.flush();
        test(!it->read(1024, lines) && lines.size() == 1 &&  isLongLineStart(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 1 &&  isLongLineContent(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 2 && isLongLineEnd(lines[0]) && isLongLineStart(lines[1]));
        test(!it->read(1024, lines) && lines.size() == 1 &&  isLongLineContent(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 2 && isLongLineEnd(lines[0]) && isLongLineStart(lines[1]));
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineContent(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineContent(lines[0]));
        test(it->read(1024, lines) && lines.size() == 1 && isLongLineEnd(lines[0]));
        os << endl;
        test(it->read(1024, lines) && lines.size() == 2 && lines[0].empty() && lines[1].empty());

        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log1.txt", 0);
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log1.txt", 1);
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineStart(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineContent(lines[0]));
        test(it->read(1024, lines) && lines.size() == 2 && isLongLineEnd(lines[0]) && lines[1].empty());
        test(it->read(1024, lines) && lines.empty());
        it->destroy();

        it = session->openServerLog("LogServer", testDir + "/log1.txt", 2);
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineStart(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineContent(lines[0]));
        test(!it->read(1024, lines) && lines.size() == 2 && isLongLineEnd(lines[0]) && isLongLineStart(lines[1]));
        test(!it->read(1024, lines) && lines.size() == 1 && isLongLineContent(lines[0]));
        test(it->read(1024, lines) && lines.size() == 2 && isLongLineEnd(lines[0]) && lines[1].empty());
        it->destroy();
    }
    catch(const FileNotAvailableException& ex)
    {
        cerr << ex.reason << endl;
        test(false);
    }

    cout << "ok" << endl;
}