<commit_before>#include "TTModular.h"

#include <iostream>
#include <string>

// A class for our application
class DemoApp {

public:

    DemoApp(){};
    ~DemoApp(){};

    // This application is divided into four main functions
    void Setup();
    void Export();
    void Execute(std::string command);
    void Quit();

private:

    // Declare the application manager, our application and another one
    TTObject mApplicationManager;
    TTObject mApplicationDemo;
    TTObject mApplicationRemote;

    // Declare protocol units to use
    TTObject mProtocolMinuit;
    TTObject mProtocolWebSocket;

public:

    // Declare publicly all datas of our application to retreive them from the callback function
    TTObject mDataDemoParameter;     // a parameter is relative to the state of our application
    TTObject mDataDemoMessage;       // a message is a kind of command to send to our application
    TTObject mDataDemoReturn;        // a return is a kind of notification sent by our application

    // Be friend with the callback function
    friend TTErr DemoAppDataReturnValueCallback(const TTValue& baton, const TTValue& v);
};

// Callback function to get data's value back
TTErr DemoAppDataReturnValueCallback(const TTValue& baton, const TTValue& v);

int
main(int argc, char **argv)
{
    DemoApp app;

    TTLogMessage("\n*** Start of Jamoma Modular demonstration ***\n");

    app.Setup();

    // read command from console
    do {
        TTLogMessage("\nType a command : \n");

        std::string s;
        std::getline(std::cin, s);

        // quit the application
        if (!s.compare("quit")) {

            app.Quit();

            TTLogMessage("\n*** End of Jamoma Modular demonstration ***\n");
            return EXIT_SUCCESS;
        }
        // dump informations about the application
        else if (!s.compare("export")) {

             app.Export();
        }
        // parse a command and execute it
        else {

            app.Execute(s);
        }
    }
    while (YES);
}

void
DemoApp::Setup()
{
    TTValue     args, v, out, none;
    TTAddress   address;
    TTErr       err;

    TTLogMessage("\n*** Initialisation of Modular environnement ***\n");
    /////////////////////////////////////////////////////////////////////

    // Init the Modular library (passing the folder path where all the dylibs are)
    TTModularInit("/usr/local/jamoma");

    // Create an application manager
    mApplicationManager = TTObject("ApplicationManager");

    TTLogMessage("\n*** Creation of myDemoApp and myRemoteApp applications ***\n");
    ////////////////////////////////////////////////////////////////////////////////

    // Create a local application called "demo" and get it back
    err = mApplicationManager.send("ApplicationInstantiateLocal", "demo", out);

    if (err) {
        TTLogError("Error : can't create myDemoApp application \n");
        return;
    }
    else
        mApplicationDemo = out[0];

    // Create a distant application called "i-score" and get it back
    err = mApplicationManager.send("ApplicationInstantiateDistant", "i-score", out);

    if (err) {
        TTLogError("Error : can't create myRemoteApp application \n");
        return;
    }
    else
        mApplicationRemote = out[0];

    // Get registered application names
    mApplicationManager.get("applicationNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTLogMessage("%s application is well registered into the application manager \n", name.c_str());
    }

    TTLogMessage("\n*** Enable Minuit communication ***\n");
    ////////////////////////////////////////////////////////////////////////

    // Create a Minuit protocol unit
    err = mApplicationManager.send("ProtocolInstantiate", "Minuit", out);

    if (err) {
        TTLogError("Error : can't create Minuit protocol unit \n");
        return;
    }
    else
        mProtocolMinuit = out[0];

    // Get Minuit Protocol attribute names and types
    mProtocolMinuit.get("parameterNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTSymbol type = mProtocolMinuit.attributeType(name);
        TTLogMessage("Minuit %s parameter is a %s \n", name.c_str(), type.c_str());
    }

    // Register myDemoApp and myRemoteApp to the Minuit protocol
    mProtocolMinuit.send("ApplicationRegister", "demo", out);
    mProtocolMinuit.send("ApplicationRegister", "i-score", out);

    // Select myDemoApp to set its protocol parameters
    mProtocolMinuit.send("ApplicationSelect", "demo", out);
    mProtocolMinuit.set("port", 9998);
    mProtocolMinuit.set("ip", "127.0.0.1");

    // Select myRemoteApp to set its protocol parameters
    mProtocolMinuit.send("ApplicationSelect", "i-score", out);
    mProtocolMinuit.set("port", 13579);
    mProtocolMinuit.set("ip", "127.0.0.1");

    // Get Minuit parameters for each registered application
    mProtocolMinuit.get("applicationNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);

        mProtocolMinuit.send("ApplicationSelect", name, out);
        TTLogMessage("Minuit setup for %s application : \n", name.c_str());

        mProtocolMinuit.get("ip", v);
        TTSymbol ip = v[0];
        TTLogMessage("- ip = %s \n", ip.c_str());

        mProtocolMinuit.get("port", v);
        TTUInt16 port = v[0];
        TTLogMessage("- port = %d \n", port);
    }

    // Enable Minuit communication
    mProtocolMinuit.send("Run");

/*
    TTLogMessage("\n*** Enable WebSocket communication ***\n");
    ////////////////////////////////////////////////////////////////////////

    // Create a WebSocket protocol unit
    err = mApplicationManager.send("ProtocolInstantiate", "WebSocket", out);

    if (err) {
        TTLogError("Error : can't create WebSocket protocol unit \n");
        return;
    }
    else
        mProtocolWebSocket = out[0];

    // Get WebSocket Protocol attribute names and types
    mProtocolMinuit.get("parameterNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTLogMessage("WebSocket::%s is a %s \n", name.c_str(), mProtocolWebSocket.attributeType(name).c_str());
    }

    // Register myDemoApp and myRemoteApp to the WebSocket protocol
    mProtocolWebSocket.send("ApplicationRegister", "demo", out);
    mProtocolWebSocket.send("ApplicationRegister", "i-score", out);

    // Select myDemoApp to set its protocol parameters
    mProtocolWebSocket.send("ApplicationSelect", "demo", out);
    mProtocolWebSocket.set("???", none);

    // Select myRemoteApp to set its protocol parameters
    mProtocolWebSocket.send("ApplicationSelect", "i-score", out);
    mProtocolWebSocket.set("???", none);

    // Enable WebSocket communication
    mProtocolWebSocket.send("Run");
*/

    TTLogMessage("\n*** Current Protocol Setup ***\n");
    // Get protocol names
    mApplicationManager.get("protocolNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTLogMessage("%s protocol is well registered into the application manager \n", name.c_str());
    }

	TTLogMessage("\n*** Creation of myDemoApp datas ***\n");
    /////////////////////////////////////////////////////////

    // Create a parameter data and set its callback function and baton and some attributes
    mDataDemoParameter = TTObject("Data", "parameter");

    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoParameter);
    mDataDemoParameter.set("baton", args);
    mDataDemoParameter.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoParameter.set("type", "decimal");
    mDataDemoParameter.set("rangeBounds", TTValue(-1., 1.));
    mDataDemoParameter.set("rangeClipmode", "both");
    mDataDemoParameter.set("rampDrive", "System");
    mDataDemoParameter.set("description", "this parameter is useful for demo purpose");

    // Register the parameter data into myDemoApp at an address
    args = TTValue("/myParameter", mDataDemoParameter);
    err = mApplicationDemo.send("ObjectRegister", args, out);

    if (err)
        TTLogError("Error : can't register data at /myParameter address \n");

    else {
        address = out[0];
        TTLogMessage("\n /myParameter : effective registration address is %s \n", address.c_str());
    }

    // Create a message data and set its callback function and baton and some attributes
    mDataDemoMessage = TTObject("Data", "message");

    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoMessage);
    mDataDemoMessage.set("baton", args);
    mDataDemoMessage.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoMessage.set("type", "none");
    mDataDemoMessage.set("description", "this message is useful for demo purpose");

    // Register the message data into myDemoApp at an address
    args = TTValue("/myMessage", mDataDemoMessage);
    mApplicationDemo.send("ObjectRegister", args, out);

    if (err)
        TTLogError("Error : can't register data at /myMessage address \n");

    else {
        address = out[0];
        TTLogMessage("\n /myMessage : effective registration address is %s \n", address.c_str());
    }

    // Create a return data and set its callback function and baton and some attributes
    mDataDemoReturn = TTObject("Data", "return");

    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoReturn);
    mDataDemoReturn.set("baton", args);
    mDataDemoReturn.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoReturn.set("type", "integer");
    mDataDemoReturn.set("description", "this return is useful for demo purpose");

    // Register the return data into myDemoApp at an address
    args = TTValue("/myReturn", mDataDemoReturn);
    mApplicationDemo.send("ObjectRegister", args, out);

    if (err)
        TTLogError("Error : can't register data at /myReturn address \n");

    else {
        address = out[0];
        TTLogMessage("\n /myReturn : effective registration address is %s \n", address.c_str());
    }
}

void
DemoApp::Export()
{
    TTValue     out;
    TTObject    xmlHandler("XmlHandler");

    // export the namespace of myDemoApp
    xmlHandler.set("object", mApplicationDemo);
    xmlHandler.send("Write", "./myDemoApp.xml", out);
}

void
DemoApp::Execute(std::string command)
{
    // parse the command : address value
    TTValue v = TTString(command);
    v.fromString();

    // a command has to start with a symbol
    if (v.size() > 1) {

        if (v[0].type() == kTypeSymbol) {

            TTSymbol    address = v[0];
            TTValue     args, out, none;

            args.copyFrom(v, 1);

            // Retreive a data object
            TTErr err = mApplicationDemo.send("ObjectRetreive", address, out);

            if (!err) {

                TTObject aData = out[0];

                // Set data's value and check his validity
                aData.send("Command", args, none);
            }
        }
    }
}

void
DemoApp::Quit()
{
    TTValue out;

    TTLogMessage("\n*** Release myDemoApp datas ***\n");
    /////////////////////////////////////////////////////

    // Unregister the parameter
    if ( mApplicationDemo.send("ObjectUnregister", "/myParameter", out))
        TTLogError("Error : can't unregister data at /myParameter address \n");

    // Unregister the message
    if (mApplicationDemo.send("ObjectUnregister", "/myMessage", out))
        TTLogError("Error : can't unregister data at /myMessage address \n");

    // Unregister the return
    if (mApplicationDemo.send("ObjectUnregister", "/myReturn", out))
        TTLogError("Error : can't unregister data at /myReturn address \n");

    TTLogMessage("\n*** Release protocols ***\n");
    ///////////////////////////////////////////////

    mApplicationManager.send("ProtocolRelease", "Minuit", out);
    //mApplicationManager.send("ProtocolRelease", "WebSocket", out);

    TTLogMessage("\n*** Release applications ***\n");
    //////////////////////////////////////////////////

    mApplicationManager.send("ApplicationRelease", "i-score", out);
    mApplicationManager.send("ApplicationRelease", "demo", out);
}

TTErr
DemoAppDataReturnValueCallback(const TTValue& baton, const TTValue& value)
{
    DemoApp*    demoApp = (DemoApp*)TTPtr(baton[0]);
    TTObject    anObject = baton[1];

	// Reteive which data has been updated
    if (anObject.instance() == demoApp->mDataDemoParameter.instance()) {

        // print the returned value
        TTLogMessage("/myParameter has been updated to %s \n", value.toString().data());
        return kTTErrNone;
    }

    if (anObject.instance() == demoApp->mDataDemoMessage.instance()) {

        // print the returned value
        TTLogMessage("/myMessage has been updated to %s \n", value.toString().data());
        return kTTErrNone;
    }

    if (anObject.instance() == demoApp->mDataDemoReturn.instance()) {

        // print the returned value
        TTLogMessage("/myReturn has been updated to %s \n", value.toString().data());
        return kTTErrNone;
    }

    return kTTErrGeneric;
}<commit_msg>Using new TTApplication::ObjectSend message<commit_after>#include "TTModular.h"

#include <iostream>
#include <string>

// A class for our application
class DemoApp {

public:

    DemoApp(){};
    ~DemoApp(){};

    // This application is divided into four main functions
    void Setup();
    void Export();
    void Execute(std::string command);
    void Quit();

private:

    // Declare the application manager, our application and another one
    TTObject mApplicationManager;
    TTObject mApplicationDemo;
    TTObject mApplicationRemote;

    // Declare protocol units to use
    TTObject mProtocolMinuit;
    TTObject mProtocolWebSocket;

public:

    // Declare publicly all datas of our application to retreive them from the callback function
    TTObject mDataDemoParameter;     // a parameter is relative to the state of our application
    TTObject mDataDemoMessage;       // a message is a kind of command to send to our application
    TTObject mDataDemoReturn;        // a return is a kind of notification sent by our application

    // Be friend with the callback function
    friend TTErr DemoAppDataReturnValueCallback(const TTValue& baton, const TTValue& v);
};

// Callback function to get data's value back
TTErr DemoAppDataReturnValueCallback(const TTValue& baton, const TTValue& v);

int
main(int argc, char **argv)
{
    DemoApp app;

    TTLogMessage("\n*** Start of Jamoma Modular demonstration ***\n");

    app.Setup();

    // read command from console
    do {
        TTLogMessage("\nType a command : \n");

        std::string s;
        std::getline(std::cin, s);

        // quit the application
        if (!s.compare("quit")) {

            app.Quit();

            TTLogMessage("\n*** End of Jamoma Modular demonstration ***\n");
            return EXIT_SUCCESS;
        }
        // dump informations about the application
        else if (!s.compare("export")) {

             app.Export();
        }
        // parse a command and execute it
        else {

            app.Execute(s);
        }
    }
    while (YES);
}

void
DemoApp::Setup()
{
    TTValue     args, v, out, none;
    TTAddress   address;
    TTErr       err;

    TTLogMessage("\n*** Initialisation of Modular environnement ***\n");
    /////////////////////////////////////////////////////////////////////

    // Init the Modular library (passing the folder path where all the dylibs are)
    TTModularInit("/usr/local/jamoma");

    // Create an application manager
    mApplicationManager = TTObject("ApplicationManager");

    TTLogMessage("\n*** Creation of myDemoApp and myRemoteApp applications ***\n");
    ////////////////////////////////////////////////////////////////////////////////

    // Create a local application called "demo" and get it back
    err = mApplicationManager.send("ApplicationInstantiateLocal", "demo", out);

    if (err) {
        TTLogError("Error : can't create myDemoApp application \n");
        return;
    }
    else
        mApplicationDemo = out[0];

    // Create a distant application called "i-score" and get it back
    err = mApplicationManager.send("ApplicationInstantiateDistant", "i-score", out);

    if (err) {
        TTLogError("Error : can't create myRemoteApp application \n");
        return;
    }
    else
        mApplicationRemote = out[0];

    // Get registered application names
    mApplicationManager.get("applicationNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTLogMessage("%s application is well registered into the application manager \n", name.c_str());
    }

    TTLogMessage("\n*** Enable Minuit communication ***\n");
    ////////////////////////////////////////////////////////////////////////

    // Create a Minuit protocol unit
    err = mApplicationManager.send("ProtocolInstantiate", "Minuit", out);

    if (err) {
        TTLogError("Error : can't create Minuit protocol unit \n");
        return;
    }
    else
        mProtocolMinuit = out[0];

    // Get Minuit Protocol attribute names and types
    mProtocolMinuit.get("parameterNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTSymbol type = mProtocolMinuit.attributeType(name);
        TTLogMessage("Minuit %s parameter is a %s \n", name.c_str(), type.c_str());
    }

    // Register myDemoApp and myRemoteApp to the Minuit protocol
    mProtocolMinuit.send("ApplicationRegister", "demo", out);
    mProtocolMinuit.send("ApplicationRegister", "i-score", out);

    // Select myDemoApp to set its protocol parameters
    mProtocolMinuit.send("ApplicationSelect", "demo", out);
    mProtocolMinuit.set("port", 9998);
    mProtocolMinuit.set("ip", "127.0.0.1");

    // Select myRemoteApp to set its protocol parameters
    mProtocolMinuit.send("ApplicationSelect", "i-score", out);
    mProtocolMinuit.set("port", 13579);
    mProtocolMinuit.set("ip", "127.0.0.1");

    // Get Minuit parameters for each registered application
    mProtocolMinuit.get("applicationNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);

        mProtocolMinuit.send("ApplicationSelect", name, out);
        TTLogMessage("Minuit setup for %s application : \n", name.c_str());

        mProtocolMinuit.get("ip", v);
        TTSymbol ip = v[0];
        TTLogMessage("- ip = %s \n", ip.c_str());

        mProtocolMinuit.get("port", v);
        TTUInt16 port = v[0];
        TTLogMessage("- port = %d \n", port);
    }

    // Enable Minuit communication
    mProtocolMinuit.send("Run");

/*
    TTLogMessage("\n*** Enable WebSocket communication ***\n");
    ////////////////////////////////////////////////////////////////////////

    // Create a WebSocket protocol unit
    err = mApplicationManager.send("ProtocolInstantiate", "WebSocket", out);

    if (err) {
        TTLogError("Error : can't create WebSocket protocol unit \n");
        return;
    }
    else
        mProtocolWebSocket = out[0];

    // Get WebSocket Protocol attribute names and types
    mProtocolMinuit.get("parameterNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTLogMessage("WebSocket::%s is a %s \n", name.c_str(), mProtocolWebSocket.attributeType(name).c_str());
    }

    // Register myDemoApp and myRemoteApp to the WebSocket protocol
    mProtocolWebSocket.send("ApplicationRegister", "demo", out);
    mProtocolWebSocket.send("ApplicationRegister", "i-score", out);

    // Select myDemoApp to set its protocol parameters
    mProtocolWebSocket.send("ApplicationSelect", "demo", out);
    mProtocolWebSocket.set("???", none);

    // Select myRemoteApp to set its protocol parameters
    mProtocolWebSocket.send("ApplicationSelect", "i-score", out);
    mProtocolWebSocket.set("???", none);

    // Enable WebSocket communication
    mProtocolWebSocket.send("Run");
*/

    TTLogMessage("\n*** Current Protocol Setup ***\n");
    // Get protocol names
    mApplicationManager.get("protocolNames", out);
    for (TTElementIter it = out.begin() ; it != out.end() ; it++) {
        TTSymbol name = TTElement(*it);
        TTLogMessage("%s protocol is well registered into the application manager \n", name.c_str());
    }

	TTLogMessage("\n*** Creation of myDemoApp datas ***\n");
    /////////////////////////////////////////////////////////

    // Create a parameter data and set its callback function and baton and some attributes
    mDataDemoParameter = TTObject("Data", "parameter");

    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoParameter);
    mDataDemoParameter.set("baton", args);
    mDataDemoParameter.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoParameter.set("type", "decimal");
    mDataDemoParameter.set("rangeBounds", TTValue(-1., 1.));
    mDataDemoParameter.set("rangeClipmode", "both");
    mDataDemoParameter.set("rampDrive", "System");
    mDataDemoParameter.set("description", "this parameter is useful for demo purpose");

    // Register the parameter data into myDemoApp at an address
    args = TTValue("/myParameter", mDataDemoParameter);
    err = mApplicationDemo.send("ObjectRegister", args, out);

    if (err)
        TTLogError("Error : can't register data at /myParameter address \n");

    else {
        address = out[0];
        TTLogMessage("\n /myParameter : effective registration address is %s \n", address.c_str());
    }

    // Create a message data and set its callback function and baton and some attributes
    mDataDemoMessage = TTObject("Data", "message");

    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoMessage);
    mDataDemoMessage.set("baton", args);
    mDataDemoMessage.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoMessage.set("type", "none");
    mDataDemoMessage.set("description", "this message is useful for demo purpose");

    // Register the message data into myDemoApp at an address
    args = TTValue("/myMessage", mDataDemoMessage);
    mApplicationDemo.send("ObjectRegister", args, out);

    if (err)
        TTLogError("Error : can't register data at /myMessage address \n");

    else {
        address = out[0];
        TTLogMessage("\n /myMessage : effective registration address is %s \n", address.c_str());
    }

    // Create a return data and set its callback function and baton and some attributes
    mDataDemoReturn = TTObject("Data", "return");

    // Setup the callback mechanism to get the value back
    args = TTValue(TTPtr(this), mDataDemoReturn);
    mDataDemoReturn.set("baton", args);
    mDataDemoReturn.set("function", TTPtr(&DemoAppDataReturnValueCallback));

    // Setup the data attributes depending of its use inside the application
    mDataDemoReturn.set("type", "integer");
    mDataDemoReturn.set("description", "this return is useful for demo purpose");

    // Register the return data into myDemoApp at an address
    args = TTValue("/myReturn", mDataDemoReturn);
    mApplicationDemo.send("ObjectRegister", args, out);

    if (err)
        TTLogError("Error : can't register data at /myReturn address \n");

    else {
        address = out[0];
        TTLogMessage("\n /myReturn : effective registration address is %s \n", address.c_str());
    }
}

void
DemoApp::Export()
{
    TTValue     out;
    TTObject    xmlHandler("XmlHandler");

    // export the namespace of myDemoApp
    xmlHandler.set("object", mApplicationDemo);
    xmlHandler.send("Write", "./myDemoApp.xml", out);
}

void
DemoApp::Execute(std::string command)
{
    // parse the command : address value
    TTValue out, v = TTString(command);
    v.fromString();

    // Send the command to the object at the given address
    mApplicationDemo.send("ObjectSend", v, out);
}

void
DemoApp::Quit()
{
    TTValue out;

    TTLogMessage("\n*** Release myDemoApp datas ***\n");
    /////////////////////////////////////////////////////

    // Unregister the parameter
    if ( mApplicationDemo.send("ObjectUnregister", "/myParameter", out))
        TTLogError("Error : can't unregister data at /myParameter address \n");

    // Unregister the message
    if (mApplicationDemo.send("ObjectUnregister", "/myMessage", out))
        TTLogError("Error : can't unregister data at /myMessage address \n");

    // Unregister the return
    if (mApplicationDemo.send("ObjectUnregister", "/myReturn", out))
        TTLogError("Error : can't unregister data at /myReturn address \n");

    TTLogMessage("\n*** Release protocols ***\n");
    ///////////////////////////////////////////////

    mApplicationManager.send("ProtocolRelease", "Minuit", out);
    //mApplicationManager.send("ProtocolRelease", "WebSocket", out);

    TTLogMessage("\n*** Release applications ***\n");
    //////////////////////////////////////////////////

    mApplicationManager.send("ApplicationRelease", "i-score", out);
    mApplicationManager.send("ApplicationRelease", "demo", out);
}

TTErr
DemoAppDataReturnValueCallback(const TTValue& baton, const TTValue& value)
{
    DemoApp*    demoApp = (DemoApp*)TTPtr(baton[0]);
    TTObject    anObject = baton[1];

	// Reteive which data has been updated
    if (anObject.instance() == demoApp->mDataDemoParameter.instance()) {

        // print the returned value
        TTLogMessage("/myParameter has been updated to %s \n", value.toString().data());
        return kTTErrNone;
    }

    if (anObject.instance() == demoApp->mDataDemoMessage.instance()) {

        // print the returned value
        TTLogMessage("/myMessage has been updated to %s \n", value.toString().data());
        return kTTErrNone;
    }

    if (anObject.instance() == demoApp->mDataDemoReturn.instance()) {

        // print the returned value
        TTLogMessage("/myReturn has been updated to %s \n", value.toString().data());
        return kTTErrNone;
    }

    return kTTErrGeneric;
}<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#ifndef mitkCLPolyToNrrd_cpp
#define mitkCLPolyToNrrd_cpp

#include "time.h"
#include <sstream>

#include <mitkIOUtil.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <mitkSurface.h>

#include "mitkCommandLineParser.h"

#include <mitkSurfaceToImageFilter.h>
#include <vtkSmartPointer.h>
#include <vtkLinearExtrusionFilter.h>
#include <mitkSurfaceToImageFilter.h>
#include <mitkConvert2Dto3DImageFilter.h>

typedef itk::Image< double, 3 >                 FloatImageType;
typedef itk::Image< unsigned char, 3 >          MaskImageType;

int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;
  parser.setArgumentPrefix("--", "-");
  // required params
  parser.addArgument("polydata", "p", mitkCommandLineParser::InputDirectory, "Input Polydata", "Path to the input VTK polydata", us::Any(), false);
  parser.addArgument("image", "i", mitkCommandLineParser::OutputDirectory, "Input Image", "Image which defines the dimensions of the Segmentation", us::Any(), false);
  parser.addArgument("output", "o", mitkCommandLineParser::InputFile, "Output file", "Output files. Two files are create, a .nrrd image and a 3d-vtk.", us::Any(), false);
  // Miniapp Infos
  parser.setCategory("Classification Tools");
  parser.setTitle("2D-Polydata to Nrrd Segmentation");
  parser.setDescription("Creates a Nrrd segmentation based on a 2d-vtk polydata.");
  parser.setContributor("MBI");

  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);

  if (parsedArgs.size()==0)
  {
    return EXIT_FAILURE;
  }
  if ( parsedArgs.count("help") || parsedArgs.count("h"))
  {
    return EXIT_SUCCESS;
  }

  mitk::BaseData::Pointer data = mitk::IOUtil::LoadBaseData(parsedArgs["polydata"].ToString());
  mitk::Image::Pointer image = mitk::IOUtil::LoadImage(parsedArgs["image"].ToString());

  //MITK_INFO << data;
  mitk::Surface::Pointer surf = dynamic_cast<mitk::Surface*>(data.GetPointer());
  vtkSmartPointer<vtkPolyData> circle = surf->GetVtkPolyData();

  vtkSmartPointer<vtkLinearExtrusionFilter> extruder =
      vtkSmartPointer<vtkLinearExtrusionFilter>::New();

  extruder->SetInputData(circle);
  image->GetGeometry()->GetSpacing()[2];
  extruder->SetScaleFactor(1.);
  extruder->SetExtrusionTypeToNormalExtrusion();
  extruder->SetVector(0, 0,   image->GetGeometry()->GetSpacing()[2]);
  extruder->Update();
  surf->SetVtkPolyData(extruder->GetOutput());

  mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
  surfaceToImageFilter->MakeOutputBinaryOn();
  surfaceToImageFilter->SetInput(surf);
  surfaceToImageFilter->SetImage(image);
  surfaceToImageFilter->Update();
  mitk::Image::Pointer resultImage = surfaceToImageFilter->GetOutput();

  mitk::Convert2Dto3DImageFilter::Pointer multiFilter = mitk::Convert2Dto3DImageFilter::New();
  multiFilter->SetInput(resultImage);
  multiFilter->Update();
  resultImage = multiFilter->GetOutput();

  std::string saveAs = parsedArgs["output"].ToString();
  MITK_INFO << "Save as: " << saveAs;
  saveAs = saveAs + ".vtk";
  mitk::IOUtil::SaveSurface(surf.GetPointer(),saveAs);

  saveAs = argv[4];
  MITK_INFO << "Save as: " << saveAs;
  saveAs = saveAs + ".nrrd";
  mitk::IOUtil::SaveImage(resultImage,saveAs);

  return 0;
}

#endif<commit_msg>Corrected smaller error in PolyToNrrd<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#ifndef mitkCLPolyToNrrd_cpp
#define mitkCLPolyToNrrd_cpp

#include "time.h"
#include <sstream>

#include <mitkIOUtil.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <mitkSurface.h>

#include "mitkCommandLineParser.h"

#include <mitkSurfaceToImageFilter.h>
#include <vtkSmartPointer.h>
#include <vtkLinearExtrusionFilter.h>
#include <mitkSurfaceToImageFilter.h>
#include <mitkConvert2Dto3DImageFilter.h>

typedef itk::Image< double, 3 >                 FloatImageType;
typedef itk::Image< unsigned char, 3 >          MaskImageType;

int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;
  parser.setArgumentPrefix("--", "-");
  // required params
  parser.addArgument("polydata", "p", mitkCommandLineParser::InputDirectory, "Input Polydata", "Path to the input VTK polydata", us::Any(), false);
  parser.addArgument("image", "i", mitkCommandLineParser::OutputDirectory, "Input Image", "Image which defines the dimensions of the Segmentation", us::Any(), false);
  parser.addArgument("output", "o", mitkCommandLineParser::InputFile, "Output file", "Output files. Two files are create, a .nrrd image and a 3d-vtk.", us::Any(), false);
  // Miniapp Infos
  parser.setCategory("Classification Tools");
  parser.setTitle("2D-Polydata to Nrrd Segmentation");
  parser.setDescription("Creates a Nrrd segmentation based on a 2d-vtk polydata.");
  parser.setContributor("MBI");

  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);

  if (parsedArgs.size()==0)
  {
    return EXIT_FAILURE;
  }
  if ( parsedArgs.count("help") || parsedArgs.count("h"))
  {
    return EXIT_SUCCESS;
  }

  mitk::BaseData::Pointer data = mitk::IOUtil::LoadBaseData(parsedArgs["polydata"].ToString());
  mitk::Image::Pointer image = mitk::IOUtil::LoadImage(parsedArgs["image"].ToString());

  //MITK_INFO << data;
  mitk::Surface::Pointer surf = dynamic_cast<mitk::Surface*>(data.GetPointer());
  vtkSmartPointer<vtkPolyData> circle = surf->GetVtkPolyData();

  vtkSmartPointer<vtkLinearExtrusionFilter> extruder =
      vtkSmartPointer<vtkLinearExtrusionFilter>::New();

  extruder->SetInputData(circle);
  image->GetGeometry()->GetSpacing()[2];
  extruder->SetScaleFactor(1.);
  extruder->SetExtrusionTypeToNormalExtrusion();
  extruder->SetVector(0, 0,   image->GetGeometry()->GetSpacing()[2]);
  extruder->Update();
  surf->SetVtkPolyData(extruder->GetOutput());

  mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
  surfaceToImageFilter->MakeOutputBinaryOn();
  surfaceToImageFilter->SetInput(surf);
  surfaceToImageFilter->SetImage(image);
  surfaceToImageFilter->Update();
  mitk::Image::Pointer resultImage = surfaceToImageFilter->GetOutput();

  mitk::Convert2Dto3DImageFilter::Pointer multiFilter = mitk::Convert2Dto3DImageFilter::New();
  multiFilter->SetInput(resultImage);
  multiFilter->Update();
  resultImage = multiFilter->GetOutput();

  std::string saveAs = parsedArgs["output"].ToString();
  MITK_INFO << "Save as: " << saveAs;
  saveAs = saveAs + ".vtk";
  mitk::IOUtil::SaveSurface(surf.GetPointer(),saveAs);

  saveAs = parsedArgs["output"].ToString();
  MITK_INFO << "Save as: " << saveAs;
  saveAs = saveAs + ".nrrd";
  mitk::IOUtil::SaveImage(resultImage,saveAs);

  return 0;
}

#endif<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2019 Esteban Tovagliari, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/math/cdf.h"
#include "foundation/math/filter.h"
#include "foundation/math/filtersamplingtable.h"
#include "foundation/math/rng/distribution.h"
#include "foundation/math/rng/xoroshiro128plus.h"
#include "foundation/utility/test.h"

// Standard headers.
#include <cstddef>
#include <cstdio>
#include <fstream>

using namespace foundation;
using namespace std;

namespace
{
    template <typename Filter1, typename Filter2>
    void generate_sample_plot_compare(
        const Filter1&  filter1,
        const Filter2&  filter2,
        const size_t    sample_count,
        const char*     filename)
    {
        ofstream ofs(filename);
        Xoroshiro128plus rng;

        // Generate samples using the table.
        FilterSamplingTable table(filter1);

        ofs << "points1 = [\n";

        for (size_t i = 0; i < sample_count; ++i)
        {
            const float sx = rand_float1(rng);
            const float sy = rand_float1(rng);
            const Vector2f p(table.sample(sx), table.sample(sy));

            if (p.x < 0.0f)
            {
                ofs << "(" << p.x << ", " << p.y << ")";

                if (i != sample_count - 1)
                    ofs << ", ";

                ofs << "\n";
            }
        }

        ofs << "]\n";
        ofs << "\n";

        // Generate samples using the 2D filter and rejection sampling.
        const float rx = filter2.get_xradius();
        const float ry = filter2.get_yradius();
        const float rcp_norm = 1.0f / compute_normalization_factor(filter2);

        ofs << "points2 = [\n";

        for (size_t i = 0; i < sample_count; ++i)
        {
            while (true)
            {
                const float sx = rand_float1(rng);
                const float sy = rand_float1(rng);

                const float x = lerp(-rx, rx, sx);
                const float y = lerp(-ry, ry, sy);

                const float value = filter2.evaluate(x, y) * rcp_norm;

                if (value > rand_float1(rng))
                {
                    if (x > 0.0f)
                    {
                        ofs << "(" << x << ", " << y << ")";

                        if (i != sample_count - 1)
                            ofs << ", ";

                        ofs << "\n";
                        break;
                    }
                }
            }
        }

        ofs << "]\n";
        ofs << "\n";

        ofs << "import matplotlib.pyplot as plt\n";

        ofs << "plt.axis('equal')\n";
        ofs << "plt.axis(["
             << -rx << ", " << rx * 1.25f << ", "
             << -ry << ", " << ry * 1.25f << "])\n";

        ofs << "x, y = zip(*points1)\n";
        ofs << "plt.scatter(x, y,s=1, c='r')\n";

        ofs << "x, y = zip(*points2)\n";
        ofs << "plt.scatter(x, y,s=1, c='b')\n";

        ofs << "plt.show()\n";

        ofs.close();
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_BoxFilter)
{
    TEST_CASE(PlotSamples)
    {
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const BoxFilter1<float> filter1(Radius);
        const BoxFilter2<float> filter2(Radius, Radius);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/FIS_plot_box.py");
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_TriangleFilter)
{
    TEST_CASE(PlotSamples)
    {
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const TriangleFilter1<float> filter1(Radius);
        const TriangleFilter2<float> filter2(Radius, Radius);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/FIS_plot_triangle.py");
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_GaussianFilter)
{
    const float Alpha = 8.0f;

    TEST_CASE(PlotSamples)
    {
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const GaussianFilter1<float> filter1(Radius, Alpha);
        const GaussianFilter2<float> filter2(Radius, Radius, Alpha);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/FIS_plot_gaussian.py");
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_BlackmanFilter)
{
    TEST_CASE(PlotSamples)
    {
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const BlackmanHarrisFilter1<float> filter1(Radius);
        const BlackmanHarrisFilter2<float> filter2(Radius, Radius);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/FIS_plot_blackman.py");
    }
}
<commit_msg>Code tweaks<commit_after>
//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2019 Esteban Tovagliari, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/math/cdf.h"
#include "foundation/math/filter.h"
#include "foundation/math/filtersamplingtable.h"
#include "foundation/math/rng/distribution.h"
#include "foundation/math/rng/xoroshiro128plus.h"
#include "foundation/utility/test.h"

// Standard headers.
#include <cstddef>
#include <cstdio>
#include <fstream>

using namespace foundation;
using namespace std;

namespace
{
    template <typename Filter1, typename Filter2>
    void generate_sample_plot_compare(
        const Filter1&  filter1,
        const Filter2&  filter2,
        const size_t    sample_count,
        const char*     filename)
    {
        ofstream ofs(filename);
        Xoroshiro128plus rng;

        // Generate samples using the table.
        FilterSamplingTable table(filter1);

        ofs << "points1 = [\n";

        for (size_t i = 0; i < sample_count; ++i)
        {
            const float sx = rand_float1(rng);
            const float sy = rand_float1(rng);
            const Vector2f p(table.sample(sx), table.sample(sy));

            if (p.x < 0.0f)
            {
                ofs << "(" << p.x << ", " << p.y << ")";

                if (i != sample_count - 1)
                    ofs << ", ";

                ofs << "\n";
            }
        }

        ofs << "]\n";
        ofs << "\n";

        // Generate samples using the 2D filter and rejection sampling.
        const float rx = filter2.get_xradius();
        const float ry = filter2.get_yradius();
        const float rcp_norm = 1.0f / compute_normalization_factor(filter2);

        ofs << "points2 = [\n";

        for (size_t i = 0; i < sample_count; ++i)
        {
            while (true)
            {
                const float sx = rand_float1(rng);
                const float sy = rand_float1(rng);

                const float x = lerp(-rx, rx, sx);
                const float y = lerp(-ry, ry, sy);

                const float value = filter2.evaluate(x, y) * rcp_norm;

                if (value > rand_float1(rng))
                {
                    if (x > 0.0f)
                    {
                        ofs << "(" << x << ", " << y << ")";

                        if (i != sample_count - 1)
                            ofs << ", ";

                        ofs << "\n";
                        break;
                    }
                }
            }
        }

        ofs << "]\n";
        ofs << "\n";

        ofs << "import matplotlib.pyplot as plt\n";

        ofs << "plt.axis('equal')\n";
        ofs << "plt.axis(["
            << -rx << ", " << rx * 1.25f << ", "
            << -ry << ", " << ry * 1.25f << "])\n";

        ofs << "x, y = zip(*points1)\n";
        ofs << "plt.scatter(x, y,s=1, c='r')\n";

        ofs << "x, y = zip(*points2)\n";
        ofs << "plt.scatter(x, y,s=1, c='b')\n";

        ofs << "plt.show()\n";

        ofs.close();
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_BoxFilter)
{
    TEST_CASE(PlotSamples)
    {
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const BoxFilter1<float> filter1(Radius);
        const BoxFilter2<float> filter2(Radius, Radius);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/test_fis_plot_box.py");
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_TriangleFilter)
{
    TEST_CASE(PlotSamples)
    {
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const TriangleFilter1<float> filter1(Radius);
        const TriangleFilter2<float> filter2(Radius, Radius);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/test_fis_plot_triangle.py");
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_GaussianFilter)
{
    TEST_CASE(PlotSamples)
    {
        const float Alpha = 8.0f;
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const GaussianFilter1<float> filter1(Radius, Alpha);
        const GaussianFilter2<float> filter2(Radius, Radius, Alpha);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/test_fis_plot_gaussian.py");
    }
}

TEST_SUITE(Foundation_Image_FilterSamplingTable_BlackmanFilter)
{
    TEST_CASE(PlotSamples)
    {
        const float Radius = 1.5f;
        const size_t SampleCount = 2048;

        const BlackmanHarrisFilter1<float> filter1(Radius);
        const BlackmanHarrisFilter2<float> filter2(Radius, Radius);
        generate_sample_plot_compare(
            filter1,
            filter2,
            SampleCount,
            "unit tests/outputs/test_fis_plot_blackman.py");
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/socket/socks_client_socket_pool.h"

#include <vector>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/time.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/mock_network_change_notifier.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

const int kMaxSockets = 32;
const int kMaxSocketsPerGroup = 6;

class MockTCPClientSocketPool : public TCPClientSocketPool {
 public:
  class MockConnectJob {
   public:
    MockConnectJob(ClientSocket* socket, ClientSocketHandle* handle,
                   CompletionCallback* callback)
        : socket_(socket),
          handle_(handle),
          user_callback_(callback),
          ALLOW_THIS_IN_INITIALIZER_LIST(
              connect_callback_(this, &MockConnectJob::OnConnect)) {}

    int Connect(const BoundNetLog& net_log) {
      int rv = socket_->Connect(&connect_callback_, net_log);
      if (rv == OK) {
        user_callback_ = NULL;
        OnConnect(OK);
      }
      return rv;
    }

    bool CancelHandle(const ClientSocketHandle* handle) {
      if (handle != handle_)
        return false;
      socket_.reset(NULL);
      handle_ = NULL;
      user_callback_ = NULL;
      return true;
    }

   private:
    void OnConnect(int rv) {
      if (!socket_.get())
        return;
      if (rv == OK)
        handle_->set_socket(socket_.get());

      socket_.release();
      handle_ = NULL;

      if (user_callback_) {
        CompletionCallback* callback = user_callback_;
        user_callback_ = NULL;
        callback->Run(rv);
      }
    }

    scoped_ptr<ClientSocket> socket_;
    ClientSocketHandle* handle_;
    CompletionCallback* user_callback_;
    CompletionCallbackImpl<MockConnectJob> connect_callback_;

    DISALLOW_COPY_AND_ASSIGN(MockConnectJob);
  };

  MockTCPClientSocketPool(int max_sockets, int max_sockets_per_group,
                          const std::string& name,
                          ClientSocketFactory* socket_factory,
                          NetworkChangeNotifier* network_change_notifier)
      : TCPClientSocketPool(max_sockets, max_sockets_per_group, name,
                            NULL, NULL, network_change_notifier),
        client_socket_factory_(socket_factory),
        release_count_(0),
        cancel_count_(0) {}

  int release_count() { return release_count_; };
  int cancel_count() { return cancel_count_; };

  // TCPClientSocketPool methods.
  virtual int RequestSocket(const std::string& group_name,
                            const void* socket_params,
                            RequestPriority priority,
                            ClientSocketHandle* handle,
                            CompletionCallback* callback,
                            const BoundNetLog& net_log) {
    ClientSocket* socket = client_socket_factory_->CreateTCPClientSocket(
        AddressList());
    MockConnectJob* job = new MockConnectJob(socket, handle, callback);
    job_list_.push_back(job);
    return job->Connect(net_log);
  }

  virtual void CancelRequest(const std::string& group_name,
                             const ClientSocketHandle* handle) {
    std::vector<MockConnectJob*>::iterator i;
    for (i = job_list_.begin(); i != job_list_.end(); ++i) {
      if ((*i)->CancelHandle(handle)) {
        cancel_count_++;
        break;
      }
    }
  }

  virtual void ReleaseSocket(const std::string& group_name,
                             ClientSocket* socket) {
    release_count_++;
    delete socket;
  }

 protected:
  virtual ~MockTCPClientSocketPool() {}

 private:
  ClientSocketFactory* client_socket_factory_;
  int release_count_;
  int cancel_count_;
  std::vector<MockConnectJob*> job_list_;

  DISALLOW_COPY_AND_ASSIGN(MockTCPClientSocketPool);
};

class SOCKSClientSocketPoolTest : public ClientSocketPoolTest {
 protected:
  class SOCKS5MockData {
   public:
    explicit SOCKS5MockData(bool async) {
      writes_.reset(new MockWrite[3]);
      writes_[0] = MockWrite(async, kSOCKS5GreetRequest,
                             kSOCKS5GreetRequestLength);
      writes_[1] = MockWrite(async, kSOCKS5OkRequest, kSOCKS5OkRequestLength);
      writes_[2] = MockWrite(async, 0);

      reads_.reset(new MockRead[3]);
      reads_[0] = MockRead(async, kSOCKS5GreetResponse,
                           kSOCKS5GreetResponseLength);
      reads_[1] = MockRead(async, kSOCKS5OkResponse, kSOCKS5OkResponseLength);
      reads_[2] = MockRead(async, 0);

      data_.reset(new StaticSocketDataProvider(reads_.get(), 3,
                                               writes_.get(), 3));
    }

    SocketDataProvider* data_provider() { return data_.get(); }

   private:
    scoped_ptr<StaticSocketDataProvider> data_;
    scoped_array<MockWrite> writes_;
    scoped_array<MockWrite> reads_;
  };

  SOCKSClientSocketPoolTest()
      : ignored_tcp_socket_params_("proxy", 80, MEDIUM, GURL(), false),
        tcp_socket_pool_(new MockTCPClientSocketPool(
            kMaxSockets, kMaxSocketsPerGroup, "MockTCP",
            &tcp_client_socket_factory_, &tcp_notifier_)),
        ignored_socket_params_(ignored_tcp_socket_params_, true, "host", 80,
            MEDIUM, GURL()),
        pool_(new SOCKSClientSocketPool(kMaxSockets, kMaxSocketsPerGroup,
            "SOCKSUnitTest", NULL, tcp_socket_pool_.get(), &socks_notifier_)) {
  }

  int StartRequest(const std::string& group_name, RequestPriority priority) {
    return StartRequestUsingPool(
        pool_, group_name, priority, ignored_socket_params_);
  }

  TCPSocketParams ignored_tcp_socket_params_;
  MockClientSocketFactory tcp_client_socket_factory_;
  MockNetworkChangeNotifier tcp_notifier_;
  scoped_refptr<MockTCPClientSocketPool> tcp_socket_pool_;

  SOCKSSocketParams ignored_socket_params_;
  MockNetworkChangeNotifier socks_notifier_;
  scoped_refptr<SOCKSClientSocketPool> pool_;
};

TEST_F(SOCKSClientSocketPoolTest, Simple) {
  SOCKS5MockData data(false);
  data.data_provider()->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());

  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, NULL, pool_, NULL);
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, Async) {
  SOCKS5MockData data(true);
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, &callback, pool_,
                       NULL);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, TCPConnectError) {
  SocketDataProvider* socket_data = new StaticSocketDataProvider();
  socket_data->set_connect_data(MockConnect(false, ERR_CONNECTION_REFUSED));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data);

  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, NULL, pool_, NULL);
  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, AsyncTCPConnectError) {
  SocketDataProvider* socket_data = new StaticSocketDataProvider();
  socket_data->set_connect_data(MockConnect(true, ERR_CONNECTION_REFUSED));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data);

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, &callback, pool_,
                       NULL);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, SOCKSConnectError) {
  MockRead failed_read[] = {
    MockRead(false, 0),
  };
  SocketDataProvider* socket_data =
      new StaticSocketDataProvider(failed_read, arraysize(failed_read),
                                   NULL, 0);
  socket_data->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data);

  ClientSocketHandle handle;
  EXPECT_EQ(0, tcp_socket_pool_->release_count());
  int rv = handle.Init("a", ignored_socket_params_, LOW, NULL, pool_, NULL);
  EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());
}

TEST_F(SOCKSClientSocketPoolTest, AsyncSOCKSConnectError) {
  MockRead failed_read[] = {
    MockRead(true, 0),
  };
  SocketDataProvider* socket_data =
      new StaticSocketDataProvider(failed_read, arraysize(failed_read),
                                   NULL, 0);
  socket_data->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data);

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  EXPECT_EQ(0, tcp_socket_pool_->release_count());
  int rv = handle.Init("a", ignored_socket_params_, LOW, &callback, pool_,
                       NULL);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());
}

TEST_F(SOCKSClientSocketPoolTest, CancelDuringTCPConnect) {
  SOCKS5MockData data(false);
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());
  // We need two connections because the pool base lets one cancelled
  // connect job proceed for potential future use.
  SOCKS5MockData data2(false);
  tcp_client_socket_factory_.AddSocketDataProvider(data2.data_provider());

  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  int rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  pool_->CancelRequest("a", requests_[0]->handle());
  pool_->CancelRequest("a", requests_[1]->handle());
  EXPECT_EQ(1, tcp_socket_pool_->cancel_count());

  // Now wait for the TCP sockets to connect.
  MessageLoop::current()->RunAllPending();

  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(1));
  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(2));
  EXPECT_EQ(1, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(1, pool_->IdleSocketCount());

  requests_[0]->handle()->Reset();
  requests_[1]->handle()->Reset();
}

TEST_F(SOCKSClientSocketPoolTest, CancelDuringSOCKSConnect) {
  SOCKS5MockData data(true);
  data.data_provider()->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());
  // We need two connections because the pool base lets one cancelled
  // connect job proceed for potential future use.
  SOCKS5MockData data2(true);
  data2.data_provider()->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(data2.data_provider());

  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(0, tcp_socket_pool_->release_count());
  int rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  pool_->CancelRequest("a", requests_[0]->handle());
  pool_->CancelRequest("a", requests_[1]->handle());
  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());

  // Now wait for the async data to reach the SOCKS connect jobs.
  MessageLoop::current()->RunAllPending();

  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(1));
  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(2));
  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());
  EXPECT_EQ(1, pool_->IdleSocketCount());

  requests_[0]->handle()->Reset();
  requests_[1]->handle()->Reset();
}

// It would be nice to also test the timeouts in SOCKSClientSocketPool.

}  // namespace

}  // namespace net
<commit_msg>Cleanup testing objects.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/socket/socks_client_socket_pool.h"

#include <vector>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/time.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/mock_network_change_notifier.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

const int kMaxSockets = 32;
const int kMaxSocketsPerGroup = 6;

class MockTCPClientSocketPool : public TCPClientSocketPool {
 public:
  class MockConnectJob {
   public:
    MockConnectJob(ClientSocket* socket, ClientSocketHandle* handle,
                   CompletionCallback* callback)
        : socket_(socket),
          handle_(handle),
          user_callback_(callback),
          ALLOW_THIS_IN_INITIALIZER_LIST(
              connect_callback_(this, &MockConnectJob::OnConnect)) {}

    int Connect(const BoundNetLog& net_log) {
      int rv = socket_->Connect(&connect_callback_, net_log);
      if (rv == OK) {
        user_callback_ = NULL;
        OnConnect(OK);
      }
      return rv;
    }

    bool CancelHandle(const ClientSocketHandle* handle) {
      if (handle != handle_)
        return false;
      socket_.reset(NULL);
      handle_ = NULL;
      user_callback_ = NULL;
      return true;
    }

   private:
    void OnConnect(int rv) {
      if (!socket_.get())
        return;
      if (rv == OK)
        handle_->set_socket(socket_.get());
      else
        socket_.reset(NULL);

      socket_.release();
      handle_ = NULL;

      if (user_callback_) {
        CompletionCallback* callback = user_callback_;
        user_callback_ = NULL;
        callback->Run(rv);
      }
    }

    scoped_ptr<ClientSocket> socket_;
    ClientSocketHandle* handle_;
    CompletionCallback* user_callback_;
    CompletionCallbackImpl<MockConnectJob> connect_callback_;

    DISALLOW_COPY_AND_ASSIGN(MockConnectJob);
  };

  MockTCPClientSocketPool(int max_sockets, int max_sockets_per_group,
                          const std::string& name,
                          ClientSocketFactory* socket_factory,
                          NetworkChangeNotifier* network_change_notifier)
      : TCPClientSocketPool(max_sockets, max_sockets_per_group, name,
                            NULL, NULL, network_change_notifier),
        client_socket_factory_(socket_factory),
        release_count_(0),
        cancel_count_(0) {}

  int release_count() { return release_count_; };
  int cancel_count() { return cancel_count_; };

  // TCPClientSocketPool methods.
  virtual int RequestSocket(const std::string& group_name,
                            const void* socket_params,
                            RequestPriority priority,
                            ClientSocketHandle* handle,
                            CompletionCallback* callback,
                            const BoundNetLog& net_log) {
    ClientSocket* socket = client_socket_factory_->CreateTCPClientSocket(
        AddressList());
    MockConnectJob* job = new MockConnectJob(socket, handle, callback);
    job_list_.push_back(job);
    return job->Connect(net_log);
  }

  virtual void CancelRequest(const std::string& group_name,
                             const ClientSocketHandle* handle) {
    std::vector<MockConnectJob*>::iterator i;
    for (i = job_list_.begin(); i != job_list_.end(); ++i) {
      if ((*i)->CancelHandle(handle)) {
        cancel_count_++;
        break;
      }
    }
  }

  virtual void ReleaseSocket(const std::string& group_name,
                             ClientSocket* socket) {
    release_count_++;
    delete socket;
  }

 protected:
  virtual ~MockTCPClientSocketPool() {}

 private:
  ClientSocketFactory* client_socket_factory_;
  int release_count_;
  int cancel_count_;
  ScopedVector<MockConnectJob> job_list_;

  DISALLOW_COPY_AND_ASSIGN(MockTCPClientSocketPool);
};

class SOCKSClientSocketPoolTest : public ClientSocketPoolTest {
 protected:
  class SOCKS5MockData {
   public:
    explicit SOCKS5MockData(bool async) {
      writes_.reset(new MockWrite[3]);
      writes_[0] = MockWrite(async, kSOCKS5GreetRequest,
                             kSOCKS5GreetRequestLength);
      writes_[1] = MockWrite(async, kSOCKS5OkRequest, kSOCKS5OkRequestLength);
      writes_[2] = MockWrite(async, 0);

      reads_.reset(new MockRead[3]);
      reads_[0] = MockRead(async, kSOCKS5GreetResponse,
                           kSOCKS5GreetResponseLength);
      reads_[1] = MockRead(async, kSOCKS5OkResponse, kSOCKS5OkResponseLength);
      reads_[2] = MockRead(async, 0);

      data_.reset(new StaticSocketDataProvider(reads_.get(), 3,
                                               writes_.get(), 3));
    }

    SocketDataProvider* data_provider() { return data_.get(); }

   private:
    scoped_ptr<StaticSocketDataProvider> data_;
    scoped_array<MockWrite> writes_;
    scoped_array<MockWrite> reads_;
  };

  SOCKSClientSocketPoolTest()
      : ignored_tcp_socket_params_("proxy", 80, MEDIUM, GURL(), false),
        tcp_socket_pool_(new MockTCPClientSocketPool(
            kMaxSockets, kMaxSocketsPerGroup, "MockTCP",
            &tcp_client_socket_factory_, &tcp_notifier_)),
        ignored_socket_params_(ignored_tcp_socket_params_, true, "host", 80,
            MEDIUM, GURL()),
        pool_(new SOCKSClientSocketPool(kMaxSockets, kMaxSocketsPerGroup,
            "SOCKSUnitTest", NULL, tcp_socket_pool_.get(), &socks_notifier_)) {
  }

  int StartRequest(const std::string& group_name, RequestPriority priority) {
    return StartRequestUsingPool(
        pool_, group_name, priority, ignored_socket_params_);
  }

  TCPSocketParams ignored_tcp_socket_params_;
  MockClientSocketFactory tcp_client_socket_factory_;
  MockNetworkChangeNotifier tcp_notifier_;
  scoped_refptr<MockTCPClientSocketPool> tcp_socket_pool_;

  SOCKSSocketParams ignored_socket_params_;
  MockNetworkChangeNotifier socks_notifier_;
  scoped_refptr<SOCKSClientSocketPool> pool_;
};

TEST_F(SOCKSClientSocketPoolTest, Simple) {
  SOCKS5MockData data(false);
  data.data_provider()->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());

  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, NULL, pool_, NULL);
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, Async) {
  SOCKS5MockData data(true);
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, &callback, pool_,
                       NULL);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, TCPConnectError) {
  scoped_ptr<SocketDataProvider> socket_data(new StaticSocketDataProvider());
  socket_data->set_connect_data(MockConnect(false, ERR_CONNECTION_REFUSED));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data.get());

  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, NULL, pool_, NULL);
  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, AsyncTCPConnectError) {
  scoped_ptr<SocketDataProvider> socket_data(new StaticSocketDataProvider());
  socket_data->set_connect_data(MockConnect(true, ERR_CONNECTION_REFUSED));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data.get());

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  int rv = handle.Init("a", ignored_socket_params_, LOW, &callback, pool_,
                       NULL);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, SOCKSConnectError) {
  MockRead failed_read[] = {
    MockRead(false, 0),
  };
  scoped_ptr<SocketDataProvider> socket_data(new StaticSocketDataProvider(
        failed_read, arraysize(failed_read), NULL, 0));
  socket_data->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data.get());

  ClientSocketHandle handle;
  EXPECT_EQ(0, tcp_socket_pool_->release_count());
  int rv = handle.Init("a", ignored_socket_params_, LOW, NULL, pool_, NULL);
  EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());
}

TEST_F(SOCKSClientSocketPoolTest, AsyncSOCKSConnectError) {
  MockRead failed_read[] = {
    MockRead(true, 0),
  };
  scoped_ptr<SocketDataProvider> socket_data(new StaticSocketDataProvider(
        failed_read, arraysize(failed_read), NULL, 0));
  socket_data->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(socket_data.get());

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  EXPECT_EQ(0, tcp_socket_pool_->release_count());
  int rv = handle.Init("a", ignored_socket_params_, LOW, &callback, pool_,
                       NULL);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());
}

TEST_F(SOCKSClientSocketPoolTest, CancelDuringTCPConnect) {
  SOCKS5MockData data(false);
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());
  // We need two connections because the pool base lets one cancelled
  // connect job proceed for potential future use.
  SOCKS5MockData data2(false);
  tcp_client_socket_factory_.AddSocketDataProvider(data2.data_provider());

  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  int rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  pool_->CancelRequest("a", requests_[0]->handle());
  pool_->CancelRequest("a", requests_[1]->handle());
  EXPECT_EQ(1, tcp_socket_pool_->cancel_count());

  // Now wait for the TCP sockets to connect.
  MessageLoop::current()->RunAllPending();

  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(1));
  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(2));
  EXPECT_EQ(1, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(1, pool_->IdleSocketCount());

  requests_[0]->handle()->Reset();
  requests_[1]->handle()->Reset();
}

TEST_F(SOCKSClientSocketPoolTest, CancelDuringSOCKSConnect) {
  SOCKS5MockData data(true);
  data.data_provider()->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(data.data_provider());
  // We need two connections because the pool base lets one cancelled
  // connect job proceed for potential future use.
  SOCKS5MockData data2(true);
  data2.data_provider()->set_connect_data(MockConnect(false, 0));
  tcp_client_socket_factory_.AddSocketDataProvider(data2.data_provider());

  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(0, tcp_socket_pool_->release_count());
  int rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  rv = StartRequest("a", LOW);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  pool_->CancelRequest("a", requests_[0]->handle());
  pool_->CancelRequest("a", requests_[1]->handle());
  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());

  // Now wait for the async data to reach the SOCKS connect jobs.
  MessageLoop::current()->RunAllPending();

  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(1));
  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(2));
  EXPECT_EQ(0, tcp_socket_pool_->cancel_count());
  EXPECT_EQ(1, tcp_socket_pool_->release_count());
  EXPECT_EQ(1, pool_->IdleSocketCount());

  requests_[0]->handle()->Reset();
  requests_[1]->handle()->Reset();
}

// It would be nice to also test the timeouts in SOCKSClientSocketPool.

}  // namespace

}  // namespace net
<|endoftext|>


<commit_before>AliAnalysisTask_JPsi_EMCal *AddTask_JPsi_EMCal(

			Bool_t 	isMC 			= kFALSE,
			Bool_t 	isAOD 			= kTRUE,
			char * period			= "16l",
			Int_t trigger_index=3,
            Int_t config=0,
            Bool_t     isTender             = kFALSE,
            TString estimator="profile_SPD_from_c1",
            TString estimatorV0="profile2D",
            Bool_t local = kTRUE,
            Bool_t alienconf = kFALSE,
            Bool_t V0correction = kFALSE,
            Bool_t SPDcorrection = kTRUE,
            TString cfg = "Config_JPsi_EMCal",
            Bool_t is_ESparse,
            Bool_t is_MSparse

                                               //kFALSE, kFALSE, "16l", 4, 0, kFALSE, "profile_SPD_16l", "2dprofile_V0_16l", kFALSE, kFALSE, kFALSE, kFALSE, "Config_JPsi_EMCal"
)
{
	AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

	if (!mgr) {
	::Error("AddTask_JPsi_EMCal", "No analysis manager to connect to.");
	return NULL;
	}

	if (!mgr->GetInputEventHandler()) {
	::Error("AddTask_JPsi_EMCal", "This task requires an input event handler");
	return NULL;
	}

	//_______________________
	//Config Task
    TString alienPath("alien:///alice/cern.ch/user/c/cjahnke/MacrosJPsi");
    TString alirootPath("$ALICE_PHYSICS/PWGDQ/dielectron/files");
    TString alirootPath_config("$ALICE_PHYSICS/PWGDQ/dielectron/macrosJPSI");

    TString configFile("");
    if(cfg.IsNull()) cfg="Config_JPsi_EMCal";

    // >>> local config
    if(local){
        configFile="Config_JPsi_EMCal.C";
    }

    // >>> aliroot config
    else if(!alienconf){
        configFile=alirootPath_config.Data();
        printf("Configuration file from aliphysics\n");
    }
    // >>> alien config
    else{
        if(!gSystem->Exec(Form("alien_cp %s/%s.C .",alienPath.Data(),cfg.Data()))) {
            configFile=gSystem->pwd();
            printf("Configuration file from alien cjahnke\n");
        }
        else {
            printf("ERROR: couldn't copy file %s/%s.C from grid \n", alienPath.Data(),cfg.Data() );
            return;
        }
    }
    // add config to path
    if(!local){
        configFile+="/";
        configFile+=cfg.Data();
        configFile+=".C";
    }

    // load dielectron configuration file (only once)
    if (!gROOT->GetListOfGlobalFunctions()->FindObject("Config_JPsi_EMCal")){
        gROOT->LoadMacro(configFile.Data());
    }

	//gROOT->LoadMacro("Config_JPsi_EMCal.C");
	AliAnalysisTask_JPsi_EMCal *task = Config_JPsi_EMCal(isMC,isAOD, period,trigger_index, config, isTender, is_ESparse, is_MSparse);

	//_______________________
	//Trigger
	if(!isMC)
	{
		if(trigger_index==0){
			task->SelectCollisionCandidates(AliVEvent::kINT7);

		}
		if(trigger_index==1){
			task->SelectCollisionCandidates(AliVEvent::kEMC7);

		}
		if(trigger_index==3){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);

		}
		if(trigger_index==4){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}

		if(trigger_index==6){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}

		//For DCAL trigger -> Separated by trigger word, not physics selection!!!
		if(trigger_index==7){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}
		if(trigger_index==8){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}

    }

//===========================================================================================================================
//Including SPD corrections
//TString estimatorFilename="estimators.root";

    if(SPDcorrection){
        printf("SPD correction enabled\n");
        TString estimatorFilename("");

        if(local){
            estimatorFilename="profile_SPD_from_c1.root";
        }
        else if(!alienconf){
            estimatorFilename=alirootPath.Data();
        }
        else{

            if(!gSystem->Exec(Form("alien_cp %s/%s.root .",alienPath.Data(),estimator.Data()))) {
                estimatorFilename=gSystem->pwd();
                printf("Not sure if copy or not from alien!!!\n");
            }
            else {
                printf("ERROR: couldn't copy file %s/%s.root from grid \n", alienPath.Data(),estimator.Data() );
                return;
            }
        }

        if(!local){
            estimatorFilename+="/";
            estimatorFilename+=estimator.Data();
            estimatorFilename+=".root";
        }

        printf("SPD estimator name: %s\n",estimatorFilename.Data());

        TFile* fileEstimator=TFile::Open(estimatorFilename.Data());
        if(!fileEstimator)  {
            AliFatal("File with multiplicity estimator not found ");
            return;
        }
        // task->SetReferenceMultiplicity(refMult);
        //const Char_t* profilebasename="SPDmult10";
        //const Char_t* profilebasename="profile_SPD";

        // const Char_t* periodNames[2] = {"LHC16l", "LHC16k"};
        //const Char_t* periodNames[1] = {"LHC16l"};
        //const Char_t* periodNames[1] = {"16l"};
        //TProfile* multEstimatorAvg[2];

        TProfile2D* multEstimatorAvg[1];
        for(Int_t ip=0; ip<1; ip++) {
            cout<< " Estimator SPD used: " << Form("%s",estimatorFilename.Data())<<endl;
            multEstimatorAvg[ip] = (TProfile2D*)(fileEstimator->Get("profile")->Clone("profile_clone"));

            //multEstimatorAvg[ip] = (TProfile2D*)(fileEstimator->Get("RunGroup_Vtx_Mult"));
        /*
            printf("TEST\n\n");
            estimator_test = (TProfile2D*)(fileEstimator->Get("profile"));

            TH1F *hx0= (TH1F*) estimator_test->ProfileX();
            TH1F *hy0= (TH1F*) estimator_test->ProfileY();

            Int_t BinX=hx0->FindBin(4);
            Int_t BinY=hy0->FindBin(-2.977679);

            printf("TEST AddTask print values (estimator without clone):    binX = %d, binY=%d \n", BinX, BinY);

            TH1F *hx1= (TH1F*) multEstimatorAvg[ip]->ProfileX();
            TH1F *hy1= (TH1F*) multEstimatorAvg[ip]->ProfileY();

            Int_t BinX=hx1->FindBin(4);
            Int_t BinY=hy1->FindBin(-2.977679);

            printf("TEST AddTask print values (estimator USED):    binX = %d, binY=%d \n", BinX, BinY);
         */

            if (!multEstimatorAvg[ip]) {
                AliFatal(Form("SPD Multiplicity estimator not found! Please check your estimator file"));
            return;
            }
        }

        task->SetMultiProfileSPD(multEstimatorAvg[0]);

    }//close if SPDcorrection

//===========================================================================================================================
//including V0 corrections

  // TString estimatorV0Filename="2dprofile_V0_16l.root";
    if(V0correction){
        printf("V0 correction enabled\n");
        TString estimatorV0Filename("");

        if(local){
            estimatorV0Filename="profile2D.root";
        }
        else if(!alienconf){
            estimatorV0Filename=alirootPath.Data();
        }
        else{

            if(!gSystem->Exec(Form("alien_cp %s/%s.root .",alienPath.Data(),estimatorV0.Data()))) {
                estimatorV0Filename=gSystem->pwd();
                printf("Not sure if copy V0  or not from alien!!!\n");
            }
            else {
                printf("ERROR: couldn't copy file %s/%s.root from grid \n", alienPath.Data(),estimatorV0.Data() );
                return;
            }
        }

        if(!local){
            estimatorV0Filename+="/";
            estimatorV0Filename+=estimatorV0.Data();
            estimatorV0Filename+=".root";
        }

        printf("V0 estimator name: %s\n",estimatorV0Filename.Data());

        TFile* fileEstimatorV0=TFile::Open(estimatorV0Filename.Data());
        if(!fileEstimatorV0)  {
            AliFatal("File with multiplicity estimator for V0 not found\n");
            return;
        }

        TProfile2D* multEstimatorV0[1];
        for(Int_t iv=0; iv<1; iv++) {
            cout<< " Estimator V0 used: "<<Form("%s",estimatorV0Filename.Data())<<endl;
            multEstimatorV0[iv] = (TProfile2D*)(fileEstimatorV0->Get("RunID_vtx_v0m")->Clone("RunID_vtx_v0m_clone"));

            /*
            TH1F *hx= (TH1F*) multEstimatorV0[iv]->ProfileX();
            TH1F *hy= (TH1F*) multEstimatorV0[iv]->ProfileY();

            Int_t BinX=hx->FindBin(258454);
            Int_t BinY=hy->FindBin(-1.0);

            printf("run= %d, vtx=%f ==>   Bins inside task are binx = %d, biny = %d \n", 258454, -1, BinX, BinY);

            Double_t localV0 = multEstimatorV0[iv]->GetBinContent(BinX, BinY);//first argument is run number/group, second is vertex on Y axis
            printf("AddTask_localV0 = %f\n", localV0);
            */

            if (!multEstimatorV0[iv]) {
                AliFatal("Multiplicity estimator for V0 not found! Please check your estimator file");
                return;
            }
        }
        task->SetMultiProfileV0(multEstimatorV0[0]);
    }//close if V0 correction

	mgr->AddTask(task);

	//Create containers for input/output
	AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
	AliAnalysisDataContainer *coutput = mgr->CreateContainer(Form("hist_%d_config_%d", trigger_index, config),  TList::Class(),    AliAnalysisManager::kOutputContainer, "OutPutData.root");

	//Connect input/output
	mgr->ConnectInput(task, 0, cinput);
	mgr->ConnectOutput(task, 1, coutput);

    mgr->ConnectOutput(task,2,mgr->CreateContainer(Form("Multi_%d_config_%d", trigger_index, config), TList::Class(), AliAnalysisManager::kOutputContainer, "OutPutData.root"));

	return task;
}
<commit_msg> adding combined trigger for EMCal and DCal<commit_after>AliAnalysisTask_JPsi_EMCal *AddTask_JPsi_EMCal(

			Bool_t 	isMC 			= kFALSE,
			Bool_t 	isAOD 			= kTRUE,
			char * period			= "16l",
			Int_t trigger_index=3,
            Int_t config=0,
            Bool_t     isTender             = kFALSE,
            TString estimator="profile_SPD_from_c1",
            TString estimatorV0="profile2D",
            Bool_t local = kTRUE,
            Bool_t alienconf = kFALSE,
            Bool_t V0correction = kFALSE,
            Bool_t SPDcorrection = kTRUE,
            TString cfg = "Config_JPsi_EMCal",
            Bool_t is_ESparse,
            Bool_t is_MSparse

                                               //kFALSE, kFALSE, "16l", 4, 0, kFALSE, "profile_SPD_16l", "2dprofile_V0_16l", kFALSE, kFALSE, kFALSE, kFALSE, "Config_JPsi_EMCal"
)
{
	AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

	if (!mgr) {
	::Error("AddTask_JPsi_EMCal", "No analysis manager to connect to.");
	return NULL;
	}

	if (!mgr->GetInputEventHandler()) {
	::Error("AddTask_JPsi_EMCal", "This task requires an input event handler");
	return NULL;
	}

	//_______________________
	//Config Task
    TString alienPath("alien:///alice/cern.ch/user/c/cjahnke/MacrosJPsi");
    TString alirootPath("$ALICE_PHYSICS/PWGDQ/dielectron/files");
    TString alirootPath_config("$ALICE_PHYSICS/PWGDQ/dielectron/macrosJPSI");

    TString configFile("");
    if(cfg.IsNull()) cfg="Config_JPsi_EMCal";

    // >>> local config
    if(local){
        configFile="Config_JPsi_EMCal.C";
    }

    // >>> aliroot config
    else if(!alienconf){
        configFile=alirootPath_config.Data();
        printf("Configuration file from aliphysics\n");
    }
    // >>> alien config
    else{
        if(!gSystem->Exec(Form("alien_cp %s/%s.C .",alienPath.Data(),cfg.Data()))) {
            configFile=gSystem->pwd();
            printf("Configuration file from alien cjahnke\n");
        }
        else {
            printf("ERROR: couldn't copy file %s/%s.C from grid \n", alienPath.Data(),cfg.Data() );
            return;
        }
    }
    // add config to path
    if(!local){
        configFile+="/";
        configFile+=cfg.Data();
        configFile+=".C";
    }

    // load dielectron configuration file (only once)
    if (!gROOT->GetListOfGlobalFunctions()->FindObject("Config_JPsi_EMCal")){
        gROOT->LoadMacro(configFile.Data());
    }

	//gROOT->LoadMacro("Config_JPsi_EMCal.C");
	AliAnalysisTask_JPsi_EMCal *task = Config_JPsi_EMCal(isMC,isAOD, period,trigger_index, config, isTender, is_ESparse, is_MSparse);

	//_______________________
	//Trigger
	if(!isMC)
	{
		if(trigger_index==0){
			task->SelectCollisionCandidates(AliVEvent::kINT7);

		}
		if(trigger_index==1){
			task->SelectCollisionCandidates(AliVEvent::kEMC7);

		}
		if(trigger_index==3){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);

		}
		if(trigger_index==4){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}

		if(trigger_index==6){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}

		//For DCAL trigger -> Separated by trigger word, not physics selection!!!
		if(trigger_index==7){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}
		if(trigger_index==8){
			task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
		}

        //Trigger number to run EMCal+DCal as a single detector
        if(trigger_index==10){
            task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
        }
        if(trigger_index==11){
            task->SelectCollisionCandidates(AliVEvent::kEMCEGA);
        }

    }

//===========================================================================================================================
//Including SPD corrections
//TString estimatorFilename="estimators.root";

    if(SPDcorrection){
        printf("SPD correction enabled\n");
        TString estimatorFilename("");

        if(local){
            estimatorFilename="profile_SPD_from_c1.root";
        }
        else if(!alienconf){
            estimatorFilename=alirootPath.Data();
        }
        else{

            if(!gSystem->Exec(Form("alien_cp %s/%s.root .",alienPath.Data(),estimator.Data()))) {
                estimatorFilename=gSystem->pwd();
                printf("Not sure if copy or not from alien!!!\n");
            }
            else {
                printf("ERROR: couldn't copy file %s/%s.root from grid \n", alienPath.Data(),estimator.Data() );
                return;
            }
        }

        if(!local){
            estimatorFilename+="/";
            estimatorFilename+=estimator.Data();
            estimatorFilename+=".root";
        }

        printf("SPD estimator name: %s\n",estimatorFilename.Data());

        TFile* fileEstimator=TFile::Open(estimatorFilename.Data());
        if(!fileEstimator)  {
            AliFatal("File with multiplicity estimator not found ");
            return;
        }
        // task->SetReferenceMultiplicity(refMult);
        //const Char_t* profilebasename="SPDmult10";
        //const Char_t* profilebasename="profile_SPD";

        // const Char_t* periodNames[2] = {"LHC16l", "LHC16k"};
        //const Char_t* periodNames[1] = {"LHC16l"};
        //const Char_t* periodNames[1] = {"16l"};
        //TProfile* multEstimatorAvg[2];

        TProfile2D* multEstimatorAvg[1];
        for(Int_t ip=0; ip<1; ip++) {
            cout<< " Estimator SPD used: " << Form("%s",estimatorFilename.Data())<<endl;
            multEstimatorAvg[ip] = (TProfile2D*)(fileEstimator->Get("profile")->Clone("profile_clone"));

            //multEstimatorAvg[ip] = (TProfile2D*)(fileEstimator->Get("RunGroup_Vtx_Mult"));
        /*
            printf("TEST\n\n");
            estimator_test = (TProfile2D*)(fileEstimator->Get("profile"));

            TH1F *hx0= (TH1F*) estimator_test->ProfileX();
            TH1F *hy0= (TH1F*) estimator_test->ProfileY();

            Int_t BinX=hx0->FindBin(4);
            Int_t BinY=hy0->FindBin(-2.977679);

            printf("TEST AddTask print values (estimator without clone):    binX = %d, binY=%d \n", BinX, BinY);

            TH1F *hx1= (TH1F*) multEstimatorAvg[ip]->ProfileX();
            TH1F *hy1= (TH1F*) multEstimatorAvg[ip]->ProfileY();

            Int_t BinX=hx1->FindBin(4);
            Int_t BinY=hy1->FindBin(-2.977679);

            printf("TEST AddTask print values (estimator USED):    binX = %d, binY=%d \n", BinX, BinY);
         */

            if (!multEstimatorAvg[ip]) {
                AliFatal(Form("SPD Multiplicity estimator not found! Please check your estimator file"));
            return;
            }
        }

        task->SetMultiProfileSPD(multEstimatorAvg[0]);

    }//close if SPDcorrection

//===========================================================================================================================
//including V0 corrections

  // TString estimatorV0Filename="2dprofile_V0_16l.root";
    if(V0correction){
        printf("V0 correction enabled\n");
        TString estimatorV0Filename("");

        if(local){
            estimatorV0Filename="profile2D.root";
        }
        else if(!alienconf){
            estimatorV0Filename=alirootPath.Data();
        }
        else{

            if(!gSystem->Exec(Form("alien_cp %s/%s.root .",alienPath.Data(),estimatorV0.Data()))) {
                estimatorV0Filename=gSystem->pwd();
                printf("Not sure if copy V0  or not from alien!!!\n");
            }
            else {
                printf("ERROR: couldn't copy file %s/%s.root from grid \n", alienPath.Data(),estimatorV0.Data() );
                return;
            }
        }

        if(!local){
            estimatorV0Filename+="/";
            estimatorV0Filename+=estimatorV0.Data();
            estimatorV0Filename+=".root";
        }

        printf("V0 estimator name: %s\n",estimatorV0Filename.Data());

        TFile* fileEstimatorV0=TFile::Open(estimatorV0Filename.Data());
        if(!fileEstimatorV0)  {
            AliFatal("File with multiplicity estimator for V0 not found\n");
            return;
        }

        TProfile2D* multEstimatorV0[1];
        for(Int_t iv=0; iv<1; iv++) {
            cout<< " Estimator V0 used: "<<Form("%s",estimatorV0Filename.Data())<<endl;
            multEstimatorV0[iv] = (TProfile2D*)(fileEstimatorV0->Get("RunID_vtx_v0m")->Clone("RunID_vtx_v0m_clone"));

            /*
            TH1F *hx= (TH1F*) multEstimatorV0[iv]->ProfileX();
            TH1F *hy= (TH1F*) multEstimatorV0[iv]->ProfileY();

            Int_t BinX=hx->FindBin(258454);
            Int_t BinY=hy->FindBin(-1.0);

            printf("run= %d, vtx=%f ==>   Bins inside task are binx = %d, biny = %d \n", 258454, -1, BinX, BinY);

            Double_t localV0 = multEstimatorV0[iv]->GetBinContent(BinX, BinY);//first argument is run number/group, second is vertex on Y axis
            printf("AddTask_localV0 = %f\n", localV0);
            */

            if (!multEstimatorV0[iv]) {
                AliFatal("Multiplicity estimator for V0 not found! Please check your estimator file");
                return;
            }
        }
        task->SetMultiProfileV0(multEstimatorV0[0]);
    }//close if V0 correction

	mgr->AddTask(task);

	//Create containers for input/output
	AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
	AliAnalysisDataContainer *coutput = mgr->CreateContainer(Form("hist_%d_config_%d", trigger_index, config),  TList::Class(),    AliAnalysisManager::kOutputContainer, "OutPutData.root");

	//Connect input/output
	mgr->ConnectInput(task, 0, cinput);
	mgr->ConnectOutput(task, 1, coutput);

    mgr->ConnectOutput(task,2,mgr->CreateContainer(Form("Multi_%d_config_%d", trigger_index, config), TList::Class(), AliAnalysisManager::kOutputContainer, "OutPutData.root"));

	return task;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// Copyright (c) 2016 by contributors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//------------------------------------------------------------------------------

/*
Author: Chao Ma (mctt90@gmail.com)

This file tests the Momentum class.
*/

#include "gtest/gtest.h"

#include "src/base/common.h"

#include "src/updater/updater.h"
#include "src/updater/momentum_updater.h"

namespace xLearn {

HyperParam param;
const int kLength = _MMX_INCREMENT * 1000000;
const int kFactor = _MMX_INCREMENT * 3;

class MomentumTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    param.learning_rate = 0.1;
    param.decay_rate = 1.0;
    param.num_param = kLength;
  }
};

TEST_F(MomentumTest, update_func) {
  Model model(kLength, false);
  std::vector<real_t> grad_vec(kLength, 1.0);
  std::vector<real_t>* w = model.GetParameter();
  Momentum updater;
  updater.Initialize(param);
  for (int n = 0; n < 3; ++n) {
    for (int i = 0; i < kLength; ++i) {
      updater.Update(i, grad_vec[i], *w);
    }
  }
  for (int i = 0; i < kLength; ++i) {
    EXPECT_FLOAT_EQ((*w)[i], (real_t)(-3.3));
  }
}

TEST_F(MomentumTest, batch_update_func) {
  std::vector<real_t> K(kFactor, 0.0);
  std::vector<real_t> grad_vec(kFactor, 1.0);
  Momentum updater;
  updater.Initialize(param);
  for (int n = 0; n < 3; ++n) {
    updater.BatchUpdate(grad_vec, 0, K);
  }
  for (int i = 0; i < kFactor; ++i) {
    EXPECT_FLOAT_EQ(K[i], (real_t)(-3.3));
  }
}

} // namespace xLearn
<commit_msg>update momentum<commit_after>//------------------------------------------------------------------------------
// Copyright (c) 2016 by contributors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//------------------------------------------------------------------------------

/*
Author: Chao Ma (mctt90@gmail.com)

This file tests the Momentum class.
*/

#include "gtest/gtest.h"

#include "src/base/common.h"

#include "src/updater/updater.h"
#include "src/updater/momentum_updater.h"

namespace xLearn {

HyperParam param;
const int kLength = _MMX_INCREMENT * 1000000;
const int kFactor = _MMX_INCREMENT * 3;

class MomentumTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    param.learning_rate = 0.1;
    param.decay_rate = 1.0;
    param.num_param = kLength;
  }
};

TEST_F(MomentumTest, update_func) {
  Model model(kLength, false);
  std::vector<real_t> grad_vec(kLength, 1.0);
  std::vector<real_t>* w = model.GetParameter();
  Momentum updater;
  updater.Initialize(param);
  for (int n = 0; n < 3; ++n) {
    for (int i = 0; i < kLength; ++i) {
      updater.Update(i, grad_vec[i], *w);
    }
    std::cout << "w: " << (*w)[0] << std::endl;
  }
  for (int i = 0; i < kLength; ++i) {
    EXPECT_FLOAT_EQ((*w)[i], (real_t)(-0.6));
  }
}

TEST_F(MomentumTest, batch_update_func) {
  std::vector<real_t> K(kFactor, 0.0);
  std::vector<real_t> grad_vec(kFactor, 1.0);
  Momentum updater;
  updater.Initialize(param);
  for (int n = 0; n < 3; ++n) {
    updater.BatchUpdate(grad_vec, 0, K);
  }
  for (int i = 0; i < kFactor; ++i) {
    EXPECT_FLOAT_EQ(K[i], (real_t)(-0.6));
  }
}

} // namespace xLearn
<|endoftext|>