%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod:
{acl, [
    % Access Control Lists (ACLs) define service name prefixes that can be
    % referenced instead of the literal service name prefixes for the
    % destination allow list and/or the destination deny list.  The ACLs may
    % reference other ACLs (cyclic references and missing references
    % in this list generate errors).  ACLs can be provided as service name
    % patterns to match before a send operation and non-patterns are made
    % into service name patterns by appending a '*' character.
    {all, [database, tests]},
    {database, ["/db/"]},
    {tests, ["/tests/"]},
    {api, ["/cloudi/api/"]}
]}.
{services, [
    % an internal service is a native Erlang service,
    % using the cloudi_service behavior

    % this particular service handles the CloudI Service API which provides
    % dynamic configuration of CloudI
    {internal,
        % prefix specified for all subscriptions
        "/cloudi/api/",
        % module name of a module in a reachable path
        cloudi_service_api_requests,
        % module arguments are supplied as a list for the
        % cloudi_service_init/2 function
        [],
        % destination refresh controls how quickly service membership propogates
        % Any process that sends to long-lived processes can use
        % a 'lazy' prefix destination refresh (otherwise, if sending to
        % short-lived provesses, use an 'immediate' prefix destination refresh).
        % The 'lazy' prefix makes the service cache service name lookup data
        % while the 'immediate' prefix uses a central local process to do 
        % service name lookups.
        % A 'closest' suffix destination refresh always prefers local
        % processes rather than using remote processes
        % (processes on other nodes).
        % A 'furthest' suffix destination refresh always prefers remote
        % processes rather than using local processes.
        % A 'random' suffix load balances across all connected nodes.
        % A 'local' suffix will only send to local processes, which will
        % cause less request latency.
        % A 'remote' suffix will always send to remote processes, which can
        % provide more fault-tolerance guarantees.
        % If the process doesn't send to any other processes, then 'none' can
        % be used and the process will die if it attempts to send to another
        % process (it is as if the destination deny list contains all services).
        % (so the choices are:
        %  'lazy_closest', 'immediate_closest',
        %  'lazy_furthest', 'immediate_furthest',
        %  'lazy_random', 'immediate_random',
        %  'lazy_local', 'immediate_local',
        %  'lazy_remote', 'immediate_remote',
        %  'lazy_newest', 'immediate_newest',
        %  'lazy_oldest', 'immediate_oldest',
        %  'none')
        none,
        % timeout for executing the cloudi_service_init/2 function
        5000,
        % default timeout for asynchronous calls
        5000,
        % default timeout for synchronous calls
        5000,
        % destination deny list is used as an ACL (Access Control List) that
        % prevents the process from sending to destinations with the specified
        % prefixes.  if atoms are used within the list, they must exist as an
        % associative entry in the acl configuration list.
        % if the destination deny list is 'undefined' any destination is valid.
        % a blocked request will just return a timeout
        % (earlier than the timeout specified for the request).
        undefined,
        % destination allow list is used as an ACL (Access Control List) that
        % allows the process to send to destinations with the specified
        % prefixes.  if atoms are used within the list, they must exist as an
        % associative entry in the acl configuration list.
        % if the destination allow list is 'undefined' any destination is valid.
        % a blocked request will just return a timeout
        % (earlier than the timeout specified for the request).
        undefined,
        % specify how many processes should be created with this configuration
        1,
        % If more than MaxR restarts occur within MaxT seconds,
        % CloudI terminates the process
        % MaxR (maximum restarts)
        5,
        % MaxT (maximum time)
        300, % seconds
        % options, e.g.:
        % {queue_limit, 1024} % to limit the service's queue to a maximum
        %                     % of 1024 requests (to prevent excessive memory
        %                     % consumption while the service is busy,
        %                     % handling a previous request)
        % (see config_service_options in
        %  lib/cloudi_core/src/cloudi_configuration.hrl)
        []},

    % an external service is an OS process connected
    % with a socket to the loopback device for each thread
    % the service below processes the Hexidecimal digits of PI (as a test)
    {external,
        % prefix specified for all subscriptions
        "/tests/",
        % executable file path
        "tests/hexpi/priv/hexpi",
        % command line arguments for the executable
        "",
        % {Key, Value} pairs to specify environment variables
        [{"LD_LIBRARY_PATH", "api/c/lib/"},
         {"DYLD_LIBRARY_PATH", "api/c/lib/"}],
        % destination refresh controls how quickly service membership propogates
        % Any process that sends to long-lived processes can use
        % a 'lazy' prefix destination refresh (otherwise, if sending to
        % short-lived provesses, use an 'immediate' prefix destination refresh).
        % The 'lazy' prefix makes the service cache service name lookup data
        % while the 'immediate' prefix uses a central local process to do 
        % service name lookups.
        % A 'closest' suffix destination refresh always prefers local
        % processes rather than using remote processes
        % (processes on other nodes).
        % A 'furthest' suffix destination refresh always prefers remote
        % processes rather than using local processes.
        % A 'random' suffix load balances across all connected nodes.
        % A 'local' suffix will only send to local processes, which will
        % cause less request latency.
        % A 'remote' suffix will always send to remote processes, which can
        % provide more fault-tolerance guarantees.
        % If the process doesn't send to any other processes, then 'none' can
        % be used and the process will die if it attempts to send to another
        % process (it is as if the destination deny list contains all services).
        % (so the choices are:
        %  'lazy_closest', 'immediate_closest',
        %  'lazy_furthest', 'immediate_furthest',
        %  'lazy_random', 'immediate_random',
        %  'lazy_local', 'immediate_local',
        %  'lazy_remote', 'immediate_remote',
        %  'lazy_newest', 'immediate_newest',
        %  'lazy_oldest', 'immediate_oldest',
        %  'none')
        none,
        % protocol used for each socket
        tcp,
        % buffer size used for each socket
        default, % bytes
        % timeout for receiving an initialization message from a socket
        20000,
        % default timeout for asynchronous calls
        5000,
        % default timeout for synchronous calls
        5000,
        % destination deny list is used as an ACL (Access Control List) that
        % prevents the process from sending to destinations with the specified
        % prefixes.  if atoms are used within the list, they must exist as an
        % associative entry in the acl configuration list.
        % if the destination deny list is 'undefined' any destination is valid.
        % a blocked request will just return a timeout
        % (earlier than the timeout specified for the request).
        undefined, % with 'none' destination refresh method, this is not checked
        % destination allow list is used as an ACL (Access Control List) that
        % allows the process to send to destinations with the specified
        % prefixes.  if atoms are used within the list, they must exist as an
        % associative entry in the acl configuration list.
        % if the destination allow list is 'undefined' any destination is valid.
        % a blocked request will just return a timeout
        % (earlier than the timeout specified for the request).
        undefined,
        % specify how many processes should be created with this configuration
        % (a float is a multiplier for the erlang VM scheduler count, i.e.,
        %  the desired cpu count)
        1,
        % specify how many threads should be created with this configuration
        % (i.e., how many sockets should be opened to each OS process)
        % (a float is a multiplier for the erlang VM scheduler count, i.e.,
        %  the desired cpu count)
        1.5,
        % If more than MaxR restarts occur within MaxT seconds,
        % CloudI terminates the process
        % MaxR (maximum restarts)
        5,
        % MaxT (maximum time)
        300, % seconds
        % options, e.g.:
        % {queue_limit, 1024} % to limit the service's queue to a maximum
        %                     % of 1024 requests (to prevent excessive memory
        %                     % consumption while the service is busy,
        %                     % handling a previous request)
        % (see config_service_options in
        %  lib/cloudi_core/src/cloudi_configuration.hrl)
        [{request_timeout_adjustment, true},
         {nice, 15}%,
         %{cgroup,
         % [{name, "cloudi/integration_tests/hexpi"},
         %  {parameters,
         %   [{"memory.limit_in_bytes", "64m"}]}]}
        ]},
    % (using the proplist method of specifying the configuration data...
    %  it provides defaults automatically)
    [%{type, internal}, % gets inferred
     {prefix, "/cloudi/"},
     {module, cloudi_service_filesystem},
     {args,
      [{directory, "service_api/dashboard/"}]},
     {dest_refresh, none},
     {count_process, 4}],
    [{prefix, "/cloudi/log/"},
     {module, cloudi_service_filesystem},
     {args,
      [{directory, "@prefix@/var/log/cloudi"},
       {read, [{"/cloudi/log/cloudi.log", -16384}]},
       {refresh, 10}]},
     {dest_refresh, none}],
    [{prefix, "/tests/websockets/"},
     {module, cloudi_service_http_cowboy},
     {args, 
      [{port, 6464}, {output, external}, {use_websockets, true},
       {query_get_format, text_pairs},
       {use_x_method_override, true},
       {websocket_connect_sync,
        "/tests/websockets/bounce/websocket/connect"},
       {websocket_disconnect_async,
        "/tests/websockets/bounce/websocket/disconnect"},
       {websocket_ping, 30000}, % milliseconds
       {websocket_subscriptions,
        [% also, subscribe to "on" a "bounce"
         {"b*u*ce", % <-- valid pattern
          [{parameters_selected, [1, 2]},
           {service_name,
            % wildcards for substitution don't need to be in a valid pattern
            "**/websocket"}]},
         % second subscription, "notification"
         {"b*u*ce",
          [{parameters_selected, [2, 1]},
           {service_name,
            "**tification/websocket"}]}
         ]}]}],
    % tests/http/ services
    {internal,
        "/tests/http/",
        cloudi_service_http_cowboy,
        [{port, 6466}, {output, external},
         {query_get_format, text_pairs},
         {use_x_method_override, true}],
        immediate_closest,
        5000, 5000, 5000, [api], undefined, 1, 5, 300,
        []},
    {internal,
        "/tests/http/",
        cloudi_service_http_cowboy,
        [{port, 6467}, {output, internal},
         {query_get_format, text_pairs},
         {use_x_method_override, true}],
        immediate_closest, % quickstart testing, to avoid false negatives
        5000, 5000, 5000, undefined, undefined, 1, 5, 300,
        []},
    {internal,
        "/tests/http/",
        cloudi_service_http_elli,
        [{port, 6468}, {output, external},
         {query_get_format, text_pairs},
         {use_x_method_override, true}],
        immediate_closest,
        5000, 5000, 5000, [api], undefined, 1, 5, 300,
        []},
    {internal,
        "/queue",
        cloudi_service_queue,
        [% a maximum of 3 retries will occur if the service request
         % fails to receive a response within the timeout period
         % (e.g., the destination service crashes without providing a response)
         {retry, 3},
         % a write ahead logging (WAL) file path for all requests
         % (n.b., for efficiency reasons all requests are also held in memory)
         {file, "../../var/log/cloudi/example_queue_${I}.log"}],
        immediate_closest,
        5000, 5000, 5000, undefined, undefined, 4, 5, 300,
        % make sure the cloudi_service_queue gets a timeout as
        % quickly as possible to allow it to retry
        [{request_timeout_immediate_max, limit_min},
         {response_timeout_immediate_max, limit_min}]},
    {internal,
        "/byzantine",
        cloudi_service_quorum,
        [{quorum, byzantine}],
        immediate_closest,
        5000, 5000, 5000, undefined, undefined, 1, 5, 300, []},
    {external,
        "/tests/http/",
        "@PYTHON@",
        "tests/http/service/service.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 15}]},
    {external,
        "/tests/http/",
        "@JAVA@",
        % enable assertions
        "-ea:org.cloudi... "
        "-jar tests/http/service/jar/service.jar",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 15}]},
    {external,
        "/tests/http/",
        "@RUBY@",
        "tests/http/service/service.rb", [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 15}]},
@CONFIG_TESTS_GO_COUNT@
@CONFIG_TESTS_HASKELL_COUNT@
@CONFIG_TESTS_OCAML_COUNT@
    {external,
        "/tests/count/",
        "tests/count/priv/count", "",
        [{"LD_LIBRARY_PATH", "api/c/lib/"},
         {"DYLD_LIBRARY_PATH", "api/c/lib/"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 4, 1, 5, 300,
        [{nice, 10}]},
    {external,
        "/tests/count/",
        "@JAVA@",
        % enable assertions
        "-ea:org.cloudi... "
        "-jar tests/count/jar/count.jar",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 10}]},
    {external,
        "/tests/count/",
        "@NODE@",
        "tests/count/count.js",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 4, 1, 5, 300,
        [{nice, 10}]},
    {external,
        "/tests/count/",
        "@PERL@",
        "tests/count/CountTask.pm",
        [{"PERL5LIB", "api/perl"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 10}]},
    {external,
        "/tests/count/",
        "@PHP@",
        "-f tests/count/count.php",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 4, 1, 5, 300,
        [{nice, 10}]},
    {external,
        "/tests/count/",
        "@PYTHON@",
        "tests/count/count.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 10}]},
    {external,
        "/tests/count/",
        "@PYTHON@",
        "tests/count/count_c.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 10}]},
    {external,
        "/tests/count/",
        "@RUBY@",
        "tests/count/count.rb", [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 4, 5, 300,
        [{nice, 10}]},
    {internal,
        "/tests/count/",
        cloudi_service_count,
        [],
        none, 5000, 5000, 5000, undefined, undefined, 4, 5, 300,
        []},
@CONFIG_TESTS_GO_HTTP_REQ@
@CONFIG_TESTS_HASKELL_HTTP_REQ@
@CONFIG_TESTS_OCAML_HTTP_REQ@
    {external,
        "/tests/http_req/",
        "tests/http_req/priv/http_req", "",
        [{"LD_LIBRARY_PATH", "api/c/lib/"},
         {"DYLD_LIBRARY_PATH", "api/c/lib/"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {nice, 10}]},
    {external,
        "/tests/http_req/",
        "@JAVA@",
        % enable assertions
        "-ea:org.cloudi... "
        "-jar tests/http_req/jar/http_req.jar",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {nice, 10}]},
    {external,
        "/tests/http_req/",
        "@NODE@",
        "tests/http_req/http_req.js",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {nice, 10}]},
    {external,
        "/tests/http_req/",
        "@PERL@",
        "tests/http_req/http_req.pl",
        [{"PERL5LIB", "api/perl"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {nice, 10}]},
    {external,
        "/tests/http_req/",
        "@PHP@",
        "-f tests/http_req/http_req.php",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {nice, 10}]},
    {external,
        "/tests/http_req/",
        "@PYTHON@",
        "tests/http_req/http_req.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {nice, 10}]},
    {external,
        "/tests/http_req/",
        "@PYTHON@",
        "tests/http_req/http_req_c.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined,
        1.0, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {count_process_dynamic,
          [{rate_request_max, 1.1},
           {rate_request_min, 0.9},
           {count_max, 4.0},
           {count_min, 0.25}]},
         {nice, 10}]},
    {external,
        "/tests/http_req/",
        "@RUBY@",
        "tests/http_req/http_req.rb", [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {nice, 10}]},
    {internal,
        "/tests/http_req/",
        cloudi_service_http_req,
        [],
        none,
        limit_max, limit_max, limit_max, % test limits
        undefined, undefined, 1.0, 5, 300,
        [{timeout_terminate, limit_max},
         {request_timeout_adjustment, true},
         {hibernate,
          [{rate_request_min, 0.9}]},
         {count_process_dynamic,
          [{rate_request_max, 1.1},
           {rate_request_min, 0.9},
           {count_max, 2.0},
           {count_min, 0.25}]}]},
    {internal,
        "/tests/http_req/",
        cloudi_service_http_req,
        [],
        none,
        limit_min, limit_min, limit_min, % test limits
        undefined, undefined, 1.0, 5, 300,
        [{timeout_terminate, limit_min},
         {request_timeout_adjustment, true},
         {hibernate,
          [{rate_request_min, 0.9}]},
         {count_process_dynamic,
          [{rate_request_max, 1.1},
           {rate_request_min, 0.9},
           {count_max, 2.0},
           {count_min, 0.25}]}]},
@CONFIG_TESTS_GO_NULL@
@CONFIG_TESTS_HASKELL_NULL@
@CONFIG_TESTS_OCAML_NULL@
    {external,
        "/tests/null/response/",
        "tests/null/priv/null", "",
        [{"LD_LIBRARY_PATH", "api/c/lib/"},
         {"DYLD_LIBRARY_PATH", "api/c/lib/"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {external,
        "/tests/null/response/",
        "@JAVA@",
        % enable assertions
        "-ea:org.cloudi... "
        "-jar tests/null/jar/null_.jar",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {external,
        "/tests/null/response/",
        "@NODE@",
        "tests/null/null.js",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {external,
        "/tests/null/response/",
        "@PERL@",
        "tests/null/null.pl",
        [{"PERL5LIB", "api/perl"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {external,
        "/tests/null/response/",
        "@PHP@",
        "-f tests/null/null.php",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {external,
        "/tests/null/response/",
        "@PYTHON@",
        "tests/null/null.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {external,
        "/tests/null/response/",
        "@PYTHON@",
        "tests/null/null_c.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {external,
        "/tests/null/response/",
        "@RUBY@",
        "tests/null/null.rb", [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min},
         {nice, 10}]},
    {internal,
        "/tests/null/response/",
        cloudi_service_null,
        [],
        none, 5000, 5000, 5000, undefined, undefined, 1, 5, 300,
        [{response_timeout_immediate_max, limit_min}]},
    {external,
        "/tests/null/timeout/",
        "tests/null/priv/null", "",
        [{"LD_LIBRARY_PATH", "api/c/lib/"},
         {"DYLD_LIBRARY_PATH", "api/c/lib/"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {external,
        "/tests/null/timeout/",
        "@JAVA@",
        % enable assertions
        "-ea:org.cloudi... "
        "-jar tests/null/jar/null_.jar",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {external,
        "/tests/null/timeout/",
        "@NODE@",
        "tests/null/null.js",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {external,
        "/tests/null/timeout/",
        "@PERL@",
        "tests/null/null.pl",
        [{"PERL5LIB", "api/perl"}],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {external,
        "/tests/null/timeout/",
        "@PHP@",
        "-f tests/null/null.php",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {external,
        "/tests/null/timeout/",
        "@PYTHON@",
        "tests/null/null.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {external,
        "/tests/null/timeout/",
        "@PYTHON@",
        "tests/null/null_c.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {external,
        "/tests/null/timeout/",
        "@RUBY@",
        "tests/null/null.rb", [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max},
         {nice, 10}]},
    {internal,
        "/tests/null/timeout/",
        cloudi_service_null,
        [],
        none, 5000, 5000, 5000, undefined, undefined, 1, 5, 300,
        [{response_timeout_immediate_max, limit_max}]},
    {internal,
        "/tests/",
        cloudi_service_router,
        [{destinations,
          [{"http_req/any.xml/get",
            [{mode, round_robin},
             {service_names,
              ["http_req/c.xml/get",
               "http_req/java.xml/get",
               "http_req/perl.xml/get",
               "http_req/php.xml/get",
               "http_req/python.xml/get",
               "http_req/python_c.xml/get",
               "http_req/ruby.xml/get"]}]},
           {"null/response/any/get",
            [{mode, round_robin},
             {service_names,
              ["null/response/c/get",
               "null/response/java/get",
               "null/response/perl/get",
               "null/response/php/get",
               "null/response/python/get",
               "null/response/python_c/get",
               "null/response/ruby/get"]}]},
           {"null/timeout/any/get",
            [{mode, round_robin},
             {service_names,
              ["null/timeout/c/get",
               "null/timeout/java/get",
               "null/timeout/perl/get",
               "null/timeout/php/get",
               "null/timeout/python/get",
               "null/timeout/python_c/get",
               "null/timeout/ruby/get"]}]}]}],
        immediate_closest,
        5000, 5000, 5000, [api], undefined, 1, 5, 300,
        [{request_name_lookup, async}]},
    % normal echo in python
    {external,
        "/tests/",
        "@PYTHON@",
        "tests/echo/echo.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        [{nice, 15}]},
    % unstable 50% chance (coin toss) echo in python
    {external,
        "/tests/coin/",
        "@PYTHON@",
        "tests/echo/echo.py",
        [],
        none, default, default,
        5000, 5000, 5000, undefined, undefined, 1, 1, 5, 300,
        % give this service instance a 50% of failure on a service request
        [{monkey_chaos, [{probability_request, 0.5}]},
         {nice, 15}]},
    {internal,
        "/tests/http_req/",
        cloudi_service_filesystem,
        [{directory, "tests/http_req/public_html/"},
         {write_append, ["/tests/http_req/hexpi.txt"]},
         {refresh, 5}, % seconds
         {cache, 300}, % seconds
         {notify_one, [{"/tests/http_req/index.html/get", "/tests/echo/put"}]}
         ],
        immediate_closest,
        5000, 5000, 5000, undefined, undefined, 1, 5, 300, []},
    %{internal,
    %    "/db/pgsql/",
    %    cloudi_service_db_pgsql,
    %    [{hostname, "127.0.0.1"},
    %     {username, "cloudi_tests"},
    %     {password, "cloudi_tests"},
    %     {port, 5432},
    %     {database, "cloudi_tests"}],
    %    none,
    %    5000, 5000, 5000, undefined, undefined, 1, 5, 300, []},
    % the service below manages the Hexidecimal PI test
    [{prefix, "/tests/"},
     {module, cloudi_service_map_reduce},
     {args, [{map_reduce, cloudi_service_hexpi}, % map-reduce module
             {map_reduce_args, [1, 65536]},  % index start, index end
             {concurrency, 1.5}]},
     {timeout_init, 20000},
     {dest_list_deny, [api]},
     {options, [{request_timeout_adjustment, true}]}],
    {external,
        "/tests/websockets/",
        "@PYTHON@",
        "tests/websockets/websockets.py",
        [],
        immediate_local, default, default,
        5000, 5000, 5000, [api], undefined, 1, 4, 5, 300,
        [{nice, 15}]},
    {external,
        "/tests/environment/",
        "@PYTHON@",
        "tests/environment/environment.py",
        [{"USER", "${USER}"},
         {"$USER", "user"},
         {"${USER}_$USER", "user_user"},
         {"$USER${USER}", "useruser"},
         {"${USER}123$USER", "user123user"},
         {"USER_D", "user_\\$"}, % \\ is needed to escape $
         {"USER_", "user_$"}], % "$" is ignored
        immediate_local, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{nice, 15}]},
    % too many file descriptors being used here for a default config
    %% Zig-Zag test
    %% (separate configurations to avoid overwriting the ipc file)
    %{internal,
    %    "/tests/zeromq/",
    %    % inbound/outbound message paths much be acyclic
    %    % (if they are not, you will receive a erlzmq EFSM error
    %    %  because the ZeroMQ REQ has received 2 zmq_send calls)
    %    cloudi_service_zeromq,
    %    % outbound ZeroMQ requests connect a CloudI name to a ZeroMQ endpoint
    %    [{options,
    %      [{process_metadata, true}]},
    %     {outbound, {"zigzag_start", ["ipc:///tmp/cloudizigzagstarta"]}},
    %    % inbound ZeroMQ replies connect a ZeroMQ endpoint to a CloudI name
    %     {inbound, {"zigzag_step1", ["ipc:///tmp/cloudizigzagstarta"]}},
    %     {outbound, {"zigzag_step1", ["inproc://zigzagstep1"]}},
    %     {inbound, {"zigzag_step2", ["inproc://zigzagstep1"]}},
    %    % ZeroMQ publish connects a CloudI name to a ZeroMQ (subscribe) name
    %    % as {CloudI name (suffix), ZeroMQ name for message prefix}
    %    % for any number of endpoints
    %     {publish, {[{"zigzag_step2", "/zeromq/step2"}],
    %                ["inproc://zigzagstep2a",
    %                 "ipc:///tmp/cloudizigzagstep2ba",
    %                 "inproc://zigzagstep2c",
    %                 "ipc:///tmp/cloudizigzagstep2da"]}},
    %    % ZeroMQ subscribe connects a CloudI name to a ZeroMQ (subscribe) name
    %    % as {CloudI name (suffix), ZeroMQ name for subscribe setsocketopt}
    %    % for any number of endpoints
    %     {subscribe, {[{"zigzag_step3a", "/zeromq/step2"},
    %                   {"zigzag_step3b", "/zeromq/step2"}],
    %                  ["inproc://zigzagstep2a",
    %                   "ipc:///tmp/cloudizigzagstep2ba",
    %                   "inproc://zigzagstep2c",
    %                   "ipc:///tmp/cloudizigzagstep2da"]}},
    %     {outbound, {"zigzag_step3a", ["inproc://zigzagstep3"]}},
    %     {inbound, {"zigzag_finish", ["inproc://zigzagstep3"]}}],
    %    immediate_closest,
    %    5000, 5000, 5000, [api], undefined, 1, 5, 300,
    %    [{scope, cloudi_service_zeromq}]},
    %{internal,
    %    "/tests/zeromq/",
    %    % inbound/outbound message paths much be acyclic
    %    % (if they are not, you will receive a erlzmq EFSM error
    %    %  because the ZeroMQ REQ has received 2 zmq_send calls)
    %    cloudi_service_zeromq,
    %    % outbound ZeroMQ requests connect a CloudI name to a ZeroMQ endpoint
    %    [{options,
    %      [{process_metadata, true}]},
    %     {outbound, {"zigzag_start", ["ipc:///tmp/cloudizigzagstartb"]}},
    %    % inbound ZeroMQ replies connect a ZeroMQ endpoint to a CloudI name
    %     {inbound, {"zigzag_step1", ["ipc:///tmp/cloudizigzagstartb"]}},
    %     {outbound, {"zigzag_step1", ["inproc://zigzagstep1"]}},
    %     {inbound, {"zigzag_step2", ["inproc://zigzagstep1"]}},
    %    % ZeroMQ publish connects a CloudI name to a ZeroMQ (subscribe) name
    %    % as {CloudI name (suffix), ZeroMQ name for message prefix}
    %    % for any number of endpoints
    %     {publish, {[{"zigzag_step2", "/zeromq/step2"}],
    %                ["inproc://zigzagstep2a",
    %                 "ipc:///tmp/cloudizigzagstep2bb",
    %                 "inproc://zigzagstep2c",
    %                 "ipc:///tmp/cloudizigzagstep2db"]}},
    %    % ZeroMQ subscribe connects a CloudI name to a ZeroMQ (subscribe) name
    %    % as {CloudI name (suffix), ZeroMQ name for subscribe setsocketopt}
    %    % for any number of endpoints
    %     {subscribe, {[{"zigzag_step3a", "/zeromq/step2"},
    %                   {"zigzag_step3b", "/zeromq/step2"}],
    %                  ["inproc://zigzagstep2a",
    %                   "ipc:///tmp/cloudizigzagstep2bb",
    %                   "inproc://zigzagstep2c",
    %                   "ipc:///tmp/cloudizigzagstep2db"]}},
    %     {outbound, {"zigzag_step3a", ["inproc://zigzagstep3"]}},
    %     {inbound, {"zigzag_finish", ["inproc://zigzagstep3"]}}],
    %    immediate_closest,
    %    5000, 5000, 5000, [api], undefined, 1, 5, 300,
    %    [{scope, cloudi_service_zeromq}]},
    %% Chain inproc test (50 endpoints in a sequential call path)
    %{internal,
    %    "/tests/zeromq/",
    %    cloudi_service_zeromq,
    %    [{options,
    %      [{process_metadata, true}]},
    %     {outbound, {"chain_inproc_start", ["inproc://chainstep1"]}},
    %     {inbound, {"chain_inproc_step1", ["inproc://chainstep1"]}},
    %     {outbound, {"chain_inproc_step1", ["inproc://chainstep2"]}},
    %     {inbound, {"chain_inproc_step2", ["inproc://chainstep2"]}},
    %     {outbound, {"chain_inproc_step2", ["inproc://chainstep3"]}},
    %     {inbound, {"chain_inproc_step3", ["inproc://chainstep3"]}},
    %     {outbound, {"chain_inproc_step3", ["inproc://chainstep4"]}},
    %     {inbound, {"chain_inproc_step4", ["inproc://chainstep4"]}},
    %     {outbound, {"chain_inproc_step4", ["inproc://chainstep5"]}},
    %     {inbound, {"chain_inproc_step5", ["inproc://chainstep5"]}},
    %     {outbound, {"chain_inproc_step5", ["inproc://chainstep6"]}},
    %     {inbound, {"chain_inproc_step6", ["inproc://chainstep6"]}},
    %     {outbound, {"chain_inproc_step6", ["inproc://chainstep7"]}},
    %     {inbound, {"chain_inproc_step7", ["inproc://chainstep7"]}},
    %     {outbound, {"chain_inproc_step7", ["inproc://chainstep8"]}},
    %     {inbound, {"chain_inproc_step8", ["inproc://chainstep8"]}},
    %     {outbound, {"chain_inproc_step8", ["inproc://chainstep9"]}},
    %     {inbound, {"chain_inproc_step9", ["inproc://chainstep9"]}},
    %     {outbound, {"chain_inproc_step9", ["inproc://chainstep10"]}},
    %     {inbound, {"chain_inproc_step10", ["inproc://chainstep10"]}},
    %     {outbound, {"chain_inproc_step10", ["inproc://chainstep11"]}},
    %     {inbound, {"chain_inproc_step11", ["inproc://chainstep11"]}},
    %     {outbound, {"chain_inproc_step11", ["inproc://chainstep12"]}},
    %     {inbound, {"chain_inproc_step12", ["inproc://chainstep12"]}},
    %     {outbound, {"chain_inproc_step12", ["inproc://chainstep13"]}},
    %     {inbound, {"chain_inproc_step13", ["inproc://chainstep13"]}},
    %     {outbound, {"chain_inproc_step13", ["inproc://chainstep14"]}},
    %     {inbound, {"chain_inproc_step14", ["inproc://chainstep14"]}},
    %     {outbound, {"chain_inproc_step14", ["inproc://chainstep15"]}},
    %     {inbound, {"chain_inproc_step15", ["inproc://chainstep15"]}},
    %     {outbound, {"chain_inproc_step15", ["inproc://chainstep16"]}},
    %     {inbound, {"chain_inproc_step16", ["inproc://chainstep16"]}},
    %     {outbound, {"chain_inproc_step16", ["inproc://chainstep17"]}},
    %     {inbound, {"chain_inproc_step17", ["inproc://chainstep17"]}},
    %     {outbound, {"chain_inproc_step17", ["inproc://chainstep18"]}},
    %     {inbound, {"chain_inproc_step18", ["inproc://chainstep18"]}},
    %     {outbound, {"chain_inproc_step18", ["inproc://chainstep19"]}},
    %     {inbound, {"chain_inproc_step19", ["inproc://chainstep19"]}},
    %     {outbound, {"chain_inproc_step19", ["inproc://chainstep20"]}},
    %     {inbound, {"chain_inproc_step20", ["inproc://chainstep20"]}},
    %     {outbound, {"chain_inproc_step20", ["inproc://chainstep21"]}},
    %     {inbound, {"chain_inproc_step21", ["inproc://chainstep21"]}},
    %     {outbound, {"chain_inproc_step21", ["inproc://chainstep22"]}},
    %     {inbound, {"chain_inproc_step22", ["inproc://chainstep22"]}},
    %     {outbound, {"chain_inproc_step22", ["inproc://chainstep23"]}},
    %     {inbound, {"chain_inproc_step23", ["inproc://chainstep23"]}},
    %     {outbound, {"chain_inproc_step23", ["inproc://chainstep24"]}},
    %     {inbound, {"chain_inproc_step24", ["inproc://chainstep24"]}},
    %     {outbound, {"chain_inproc_step24", ["inproc://chainstep25"]}},
    %     {inbound, {"chain_inproc_step25", ["inproc://chainstep25"]}},
    %     {outbound, {"chain_inproc_step25", ["inproc://chainstep26"]}},
    %     {inbound, {"chain_inproc_step26", ["inproc://chainstep26"]}},
    %     {outbound, {"chain_inproc_step26", ["inproc://chainstep27"]}},
    %     {inbound, {"chain_inproc_step27", ["inproc://chainstep27"]}},
    %     {outbound, {"chain_inproc_step27", ["inproc://chainstep28"]}},
    %     {inbound, {"chain_inproc_step28", ["inproc://chainstep28"]}},
    %     {outbound, {"chain_inproc_step28", ["inproc://chainstep29"]}},
    %     {inbound, {"chain_inproc_step29", ["inproc://chainstep29"]}},
    %     {outbound, {"chain_inproc_step29", ["inproc://chainstep30"]}},
    %     {inbound, {"chain_inproc_step30", ["inproc://chainstep30"]}},
    %     {outbound, {"chain_inproc_step30", ["inproc://chainstep31"]}},
    %     {inbound, {"chain_inproc_step31", ["inproc://chainstep31"]}},
    %     {outbound, {"chain_inproc_step31", ["inproc://chainstep32"]}},
    %     {inbound, {"chain_inproc_step32", ["inproc://chainstep32"]}},
    %     {outbound, {"chain_inproc_step32", ["inproc://chainstep33"]}},
    %     {inbound, {"chain_inproc_step33", ["inproc://chainstep33"]}},
    %     {outbound, {"chain_inproc_step33", ["inproc://chainstep34"]}},
    %     {inbound, {"chain_inproc_step34", ["inproc://chainstep34"]}},
    %     {outbound, {"chain_inproc_step34", ["inproc://chainstep35"]}},
    %     {inbound, {"chain_inproc_step35", ["inproc://chainstep35"]}},
    %     {outbound, {"chain_inproc_step35", ["inproc://chainstep36"]}},
    %     {inbound, {"chain_inproc_step36", ["inproc://chainstep36"]}},
    %     {outbound, {"chain_inproc_step36", ["inproc://chainstep37"]}},
    %     {inbound, {"chain_inproc_step37", ["inproc://chainstep37"]}},
    %     {outbound, {"chain_inproc_step37", ["inproc://chainstep38"]}},
    %     {inbound, {"chain_inproc_step38", ["inproc://chainstep38"]}},
    %     {outbound, {"chain_inproc_step38", ["inproc://chainstep39"]}},
    %     {inbound, {"chain_inproc_step39", ["inproc://chainstep39"]}},
    %     {outbound, {"chain_inproc_step39", ["inproc://chainstep40"]}},
    %     {inbound, {"chain_inproc_step40", ["inproc://chainstep40"]}},
    %     {outbound, {"chain_inproc_step40", ["inproc://chainstep41"]}},
    %     {inbound, {"chain_inproc_step41", ["inproc://chainstep41"]}},
    %     {outbound, {"chain_inproc_step41", ["inproc://chainstep42"]}},
    %     {inbound, {"chain_inproc_step42", ["inproc://chainstep42"]}},
    %     {outbound, {"chain_inproc_step42", ["inproc://chainstep43"]}},
    %     {inbound, {"chain_inproc_step43", ["inproc://chainstep43"]}},
    %     {outbound, {"chain_inproc_step43", ["inproc://chainstep44"]}},
    %     {inbound, {"chain_inproc_step44", ["inproc://chainstep44"]}},
    %     {outbound, {"chain_inproc_step44", ["inproc://chainstep45"]}},
    %     {inbound, {"chain_inproc_step45", ["inproc://chainstep45"]}},
    %     {outbound, {"chain_inproc_step45", ["inproc://chainstep46"]}},
    %     {inbound, {"chain_inproc_step46", ["inproc://chainstep46"]}},
    %     {outbound, {"chain_inproc_step46", ["inproc://chainstep47"]}},
    %     {inbound, {"chain_inproc_step47", ["inproc://chainstep47"]}},
    %     {outbound, {"chain_inproc_step47", ["inproc://chainstep48"]}},
    %     {inbound, {"chain_inproc_step48", ["inproc://chainstep48"]}},
    %     {outbound, {"chain_inproc_step48", ["inproc://chainstep49"]}},
    %     {inbound, {"chain_inproc_step49", ["inproc://chainstep49"]}},
    %     {outbound, {"chain_inproc_step49", ["inproc://chainstep50"]}},
    %     {inbound, {"chain_inproc_finish", ["inproc://chainstep50"]}}],
    %    immediate_closest,
    %    5000, 5000, 5000, [api], undefined, 2, 5, 300,
    %    [{scope, cloudi_service_zeromq}]},
    %% Chain ipc test (25 endpoints in a sequential call path)
    %{internal,
    %    "/tests/zeromq/",
    %    cloudi_service_zeromq,
    %    [{options,
    %      [{process_metadata, true}]},
    %     {outbound, {"chain_ipc_start", ["ipc:///tmp/cloudichainstep1a"]}},
    %     {inbound, {"chain_ipc_step1", ["ipc:///tmp/cloudichainstep1a"]}},
    %     {outbound, {"chain_ipc_step1", ["ipc:///tmp/cloudichainstep2a"]}},
    %     {inbound, {"chain_ipc_step2", ["ipc:///tmp/cloudichainstep2a"]}},
    %     {outbound, {"chain_ipc_step2", ["ipc:///tmp/cloudichainstep3a"]}},
    %     {inbound, {"chain_ipc_step3", ["ipc:///tmp/cloudichainstep3a"]}},
    %     {outbound, {"chain_ipc_step3", ["ipc:///tmp/cloudichainstep4a"]}},
    %     {inbound, {"chain_ipc_step4", ["ipc:///tmp/cloudichainstep4a"]}},
    %     {outbound, {"chain_ipc_step4", ["ipc:///tmp/cloudichainstep5a"]}},
    %     {inbound, {"chain_ipc_step5", ["ipc:///tmp/cloudichainstep5a"]}},
    %     {outbound, {"chain_ipc_step5", ["ipc:///tmp/cloudichainstep6a"]}},
    %     {inbound, {"chain_ipc_step6", ["ipc:///tmp/cloudichainstep6a"]}},
    %     {outbound, {"chain_ipc_step6", ["ipc:///tmp/cloudichainstep7a"]}},
    %     {inbound, {"chain_ipc_step7", ["ipc:///tmp/cloudichainstep7a"]}},
    %     {outbound, {"chain_ipc_step7", ["ipc:///tmp/cloudichainstep8a"]}},
    %     {inbound, {"chain_ipc_step8", ["ipc:///tmp/cloudichainstep8a"]}},
    %     {outbound, {"chain_ipc_step8", ["ipc:///tmp/cloudichainstep9a"]}},
    %     {inbound, {"chain_ipc_step9", ["ipc:///tmp/cloudichainstep9a"]}},
    %     {outbound, {"chain_ipc_step9", ["ipc:///tmp/cloudichainstep10a"]}},
    %     {inbound, {"chain_ipc_step10", ["ipc:///tmp/cloudichainstep10a"]}},
    %     {outbound, {"chain_ipc_step10", ["ipc:///tmp/cloudichainstep11a"]}},
    %     {inbound, {"chain_ipc_step11", ["ipc:///tmp/cloudichainstep11a"]}},
    %     {outbound, {"chain_ipc_step11", ["ipc:///tmp/cloudichainstep12a"]}},
    %     {inbound, {"chain_ipc_step12", ["ipc:///tmp/cloudichainstep12a"]}},
    %     {outbound, {"chain_ipc_step12", ["ipc:///tmp/cloudichainstep13a"]}},
    %     {inbound, {"chain_ipc_step13", ["ipc:///tmp/cloudichainstep13a"]}},
    %     {outbound, {"chain_ipc_step13", ["ipc:///tmp/cloudichainstep14a"]}},
    %     {inbound, {"chain_ipc_step14", ["ipc:///tmp/cloudichainstep14a"]}},
    %     {outbound, {"chain_ipc_step14", ["ipc:///tmp/cloudichainstep15a"]}},
    %     {inbound, {"chain_ipc_step15", ["ipc:///tmp/cloudichainstep15a"]}},
    %     {outbound, {"chain_ipc_step15", ["ipc:///tmp/cloudichainstep16a"]}},
    %     {inbound, {"chain_ipc_step16", ["ipc:///tmp/cloudichainstep16a"]}},
    %     {outbound, {"chain_ipc_step16", ["ipc:///tmp/cloudichainstep17a"]}},
    %     {inbound, {"chain_ipc_step17", ["ipc:///tmp/cloudichainstep17a"]}},
    %     {outbound, {"chain_ipc_step17", ["ipc:///tmp/cloudichainstep18a"]}},
    %     {inbound, {"chain_ipc_step18", ["ipc:///tmp/cloudichainstep18a"]}},
    %     {outbound, {"chain_ipc_step18", ["ipc:///tmp/cloudichainstep19a"]}},
    %     {inbound, {"chain_ipc_step19", ["ipc:///tmp/cloudichainstep19a"]}},
    %     {outbound, {"chain_ipc_step19", ["ipc:///tmp/cloudichainstep20a"]}},
    %     {inbound, {"chain_ipc_step20", ["ipc:///tmp/cloudichainstep20a"]}},
    %     {outbound, {"chain_ipc_step20", ["ipc:///tmp/cloudichainstep21a"]}},
    %     {inbound, {"chain_ipc_step21", ["ipc:///tmp/cloudichainstep21a"]}},
    %     {outbound, {"chain_ipc_step21", ["ipc:///tmp/cloudichainstep22a"]}},
    %     {inbound, {"chain_ipc_step22", ["ipc:///tmp/cloudichainstep22a"]}},
    %     {outbound, {"chain_ipc_step22", ["ipc:///tmp/cloudichainstep23a"]}},
    %     {inbound, {"chain_ipc_step23", ["ipc:///tmp/cloudichainstep23a"]}},
    %     {outbound, {"chain_ipc_step23", ["ipc:///tmp/cloudichainstep24a"]}},
    %     {inbound, {"chain_ipc_step24", ["ipc:///tmp/cloudichainstep24a"]}},
    %     {outbound, {"chain_ipc_step24", ["ipc:///tmp/cloudichainstep25a"]}},
    %     {inbound, {"chain_ipc_finish", ["ipc:///tmp/cloudichainstep25a"]}}],
    %    immediate_closest,
    %    5000, 5000, 5000, [api], undefined, 1, 5, 300,
    %    [{scope, cloudi_service_zeromq}]},
    %{internal,
    %    "/tests/zeromq/",
    %    cloudi_service_zeromq,
    %    [{options,
    %      [{process_metadata, true}]},
    %     {outbound, {"chain_ipc_start", ["ipc:///tmp/cloudichainstep1b"]}},
    %     {inbound, {"chain_ipc_step1", ["ipc:///tmp/cloudichainstep1b"]}},
    %     {outbound, {"chain_ipc_step1", ["ipc:///tmp/cloudichainstep2b"]}},
    %     {inbound, {"chain_ipc_step2", ["ipc:///tmp/cloudichainstep2b"]}},
    %     {outbound, {"chain_ipc_step2", ["ipc:///tmp/cloudichainstep3b"]}},
    %     {inbound, {"chain_ipc_step3", ["ipc:///tmp/cloudichainstep3b"]}},
    %     {outbound, {"chain_ipc_step3", ["ipc:///tmp/cloudichainstep4b"]}},
    %     {inbound, {"chain_ipc_step4", ["ipc:///tmp/cloudichainstep4b"]}},
    %     {outbound, {"chain_ipc_step4", ["ipc:///tmp/cloudichainstep5b"]}},
    %     {inbound, {"chain_ipc_step5", ["ipc:///tmp/cloudichainstep5b"]}},
    %     {outbound, {"chain_ipc_step5", ["ipc:///tmp/cloudichainstep6b"]}},
    %     {inbound, {"chain_ipc_step6", ["ipc:///tmp/cloudichainstep6b"]}},
    %     {outbound, {"chain_ipc_step6", ["ipc:///tmp/cloudichainstep7b"]}},
    %     {inbound, {"chain_ipc_step7", ["ipc:///tmp/cloudichainstep7b"]}},
    %     {outbound, {"chain_ipc_step7", ["ipc:///tmp/cloudichainstep8b"]}},
    %     {inbound, {"chain_ipc_step8", ["ipc:///tmp/cloudichainstep8b"]}},
    %     {outbound, {"chain_ipc_step8", ["ipc:///tmp/cloudichainstep9b"]}},
    %     {inbound, {"chain_ipc_step9", ["ipc:///tmp/cloudichainstep9b"]}},
    %     {outbound, {"chain_ipc_step9", ["ipc:///tmp/cloudichainstep10b"]}},
    %     {inbound, {"chain_ipc_step10", ["ipc:///tmp/cloudichainstep10b"]}},
    %     {outbound, {"chain_ipc_step10", ["ipc:///tmp/cloudichainstep11b"]}},
    %     {inbound, {"chain_ipc_step11", ["ipc:///tmp/cloudichainstep11b"]}},
    %     {outbound, {"chain_ipc_step11", ["ipc:///tmp/cloudichainstep12b"]}},
    %     {inbound, {"chain_ipc_step12", ["ipc:///tmp/cloudichainstep12b"]}},
    %     {outbound, {"chain_ipc_step12", ["ipc:///tmp/cloudichainstep13b"]}},
    %     {inbound, {"chain_ipc_step13", ["ipc:///tmp/cloudichainstep13b"]}},
    %     {outbound, {"chain_ipc_step13", ["ipc:///tmp/cloudichainstep14b"]}},
    %     {inbound, {"chain_ipc_step14", ["ipc:///tmp/cloudichainstep14b"]}},
    %     {outbound, {"chain_ipc_step14", ["ipc:///tmp/cloudichainstep15b"]}},
    %     {inbound, {"chain_ipc_step15", ["ipc:///tmp/cloudichainstep15b"]}},
    %     {outbound, {"chain_ipc_step15", ["ipc:///tmp/cloudichainstep16b"]}},
    %     {inbound, {"chain_ipc_step16", ["ipc:///tmp/cloudichainstep16b"]}},
    %     {outbound, {"chain_ipc_step16", ["ipc:///tmp/cloudichainstep17b"]}},
    %     {inbound, {"chain_ipc_step17", ["ipc:///tmp/cloudichainstep17b"]}},
    %     {outbound, {"chain_ipc_step17", ["ipc:///tmp/cloudichainstep18b"]}},
    %     {inbound, {"chain_ipc_step18", ["ipc:///tmp/cloudichainstep18b"]}},
    %     {outbound, {"chain_ipc_step18", ["ipc:///tmp/cloudichainstep19b"]}},
    %     {inbound, {"chain_ipc_step19", ["ipc:///tmp/cloudichainstep19b"]}},
    %     {outbound, {"chain_ipc_step19", ["ipc:///tmp/cloudichainstep20b"]}},
    %     {inbound, {"chain_ipc_step20", ["ipc:///tmp/cloudichainstep20b"]}},
    %     {outbound, {"chain_ipc_step20", ["ipc:///tmp/cloudichainstep21b"]}},
    %     {inbound, {"chain_ipc_step21", ["ipc:///tmp/cloudichainstep21b"]}},
    %     {outbound, {"chain_ipc_step21", ["ipc:///tmp/cloudichainstep22b"]}},
    %     {inbound, {"chain_ipc_step22", ["ipc:///tmp/cloudichainstep22b"]}},
    %     {outbound, {"chain_ipc_step22", ["ipc:///tmp/cloudichainstep23b"]}},
    %     {inbound, {"chain_ipc_step23", ["ipc:///tmp/cloudichainstep23b"]}},
    %     {outbound, {"chain_ipc_step23", ["ipc:///tmp/cloudichainstep24b"]}},
    %     {inbound, {"chain_ipc_step24", ["ipc:///tmp/cloudichainstep24b"]}},
    %     {outbound, {"chain_ipc_step24", ["ipc:///tmp/cloudichainstep25b"]}},
    %     {inbound, {"chain_ipc_finish", ["ipc:///tmp/cloudichainstep25b"]}}],
    %    immediate_closest,
    %    5000, 5000, 5000, [api], undefined, 1, 5, 300,
    %    [{scope, cloudi_service_zeromq}]},
    %{external,
    %    "/tests/zeromq/",
    %    "@PYTHON@",
    %    "tests/zeromq/run.py",
    %    [],
    %    immediate_closest, default, default,
    %    5000, 5000, 5000, [api], undefined, 1, 4, 5, 300,
    %    [{scope, cloudi_service_zeromq},
    %     {nice, 15}]},
    % msg_size tests can not use the udp protocol with the default buffer size
@CONFIG_TESTS_GO_MSG_SIZE@
@CONFIG_TESTS_HASKELL_MSG_SIZE@
@CONFIG_TESTS_OCAML_MSG_SIZE@
    {internal,
        "/tests/msg_size/",
        cloudi_service_msg_size,
        [],
        immediate_closest,
        5000, 5000, 5000, [api], undefined, 2, 5, 300,
        [{request_timeout_adjustment, true},
         {duo_mode, true},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {restart_delay, []},
         {scope, cloudi_service_msg_size}]},
    {external,
        "/tests/msg_size/",
        "tests/msg_size/priv/msg_size",
        "",
        [{"LD_LIBRARY_PATH", "api/c/lib/"},
         {"DYLD_LIBRARY_PATH", "api/c/lib/"}],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 2, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
    {external,
        "/tests/msg_size/",
        "@JAVA@",
        % enable assertions
        "-ea:org.cloudi... "
        "-jar tests/msg_size/jar/msg_size.jar",
        [],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
    {external,
        "/tests/msg_size/",
        "@NODE@",
        "tests/msg_size/msg_size.js",
        [],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
    {external,
        "/tests/msg_size/",
        "@PERL@",
        "tests/msg_size/msg_size.pl",
        [{"PERL5LIB", "api/perl"}],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
    {external,
        "/tests/msg_size/",
        "@PHP@",
        "tests/msg_size/msg_size.php",
        [],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
    {external,
        "/tests/msg_size/",
        "@PYTHON@",
        "tests/msg_size/msg_size.py",
        [],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
    {external,
        "/tests/msg_size/",
        "@PYTHON@",
        "tests/msg_size/msg_size_c.py",
        [],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
    {external,
        "/tests/msg_size/",
        "@RUBY@",
        "tests/msg_size/msg_size.rb", [],
        immediate_closest, default, default,
        5000, 5000, 5000, [api], undefined, 1, 1, 5, 300,
        [{request_timeout_adjustment, true},
         {aspects_init_after,
          [{cloudi_service_msg_size, aspect_init}]},
         {aspects_request_before,
          [{cloudi_service_msg_size, aspect_request}]},
         {aspects_terminate_before,
          [{cloudi_service_msg_size, aspect_terminate}]},
         {scope, cloudi_service_msg_size},
         {nice, 15}]},
@CONFIG_TESTS_GO_MESSAGING@
@CONFIG_TESTS_HASKELL_MESSAGING@
@CONFIG_TESTS_OCAML_MESSAGING@
    {external,
        "/tests/messaging/perl/",
        "@PERL@",
        "tests/messaging/MessagingTask.pm",
        [{"PERL5LIB", "api/perl"}],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 1, 4, 5, 300,
        [{scope, cloudi_service_messaging_perl},
         {nice, 15}]},
    {external,
        "/tests/messaging/javascript/",
        "@NODE@",
        "tests/messaging/messaging.js",
        [],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 4, 1, 5, 300,
        [{scope, cloudi_service_messaging_javascript},
         {nice, 15}]},
    {external,
        "/tests/messaging/php/",
        "@PHP@",
        "tests/messaging/messaging.php",
        [],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 4, 1, 5, 300,
        [{scope, cloudi_service_messaging_php},
         {nice, 15}]},
    {external,
        "/tests/messaging/python/",
        "@PYTHON@",
        "tests/messaging/messaging.py",
        [],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 1, 4, 5, 300,
        [{scope, cloudi_service_messaging_python},
         {nice, 15}]},
    {external,
        "/tests/messaging/python_c/",
        "@PYTHON@",
        "tests/messaging/messaging_c.py",
        [],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 1, 4, 5, 300,
        [{scope, cloudi_service_messaging_python_c},
         {nice, 15}]},
    {external,
        "/tests/messaging/ruby/",
        "@RUBY@",
        "tests/messaging/messaging.rb",
        [],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 1, 4, 5, 300,
        [{scope, cloudi_service_messaging_ruby},
         {nice, 15}]},
    {external,
        "/tests/messaging/cxx/",
        "tests/messaging/priv/messaging",
        "",
        [{"LD_LIBRARY_PATH", "api/c/lib/"},
         {"DYLD_LIBRARY_PATH", "api/c/lib/"}],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 1, 4, 5, 300,
        [{scope, cloudi_service_messaging_cxx},
         {nice, 15}]},
    {external,
        "/tests/messaging/java/",
        "@JAVA@",
        % based on http://www.infoq.com/articles/benchmarking-jvm
        "-Xbatch -server -Xmx1G -Xms1G "
        % enable assertions
        "-ea:org.cloudi... "
        "-jar tests/messaging/jar/messaging.jar",
        [],
        immediate_local, default, default,
        5000, 10000, 10000, [api], undefined, 1, 4, 5, 300,
        [{scope, cloudi_service_messaging_java},
         {nice, 15}]},
    {internal,
        "/tests/messaging/erlang/variation0/",
        cloudi_service_messaging_sequence1,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, false},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation0}]},
    {internal,
        "/tests/messaging/erlang/variation0/",
        cloudi_service_messaging_sequence2,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, false},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation0}]},
    {internal,
        "/tests/messaging/erlang/variation0/",
        cloudi_service_messaging_sequence3,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, false},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation0}]},
    {internal,
        "/tests/messaging/erlang/variation0/",
        cloudi_service_messaging_sequence4,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, false},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation0}]},
    {internal,
        "/tests/messaging/erlang/variation1/",
        cloudi_service_messaging_sequence1,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation1}]},
    {internal,
        "/tests/messaging/erlang/variation1/",
        cloudi_service_messaging_sequence2,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation1}]},
    {internal,
        "/tests/messaging/erlang/variation1/",
        cloudi_service_messaging_sequence3,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation1}]},
    {internal,
        "/tests/messaging/erlang/variation1/",
        cloudi_service_messaging_sequence4,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 1000},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation1}]},
    {internal,
        "/tests/messaging/erlang/variation2/",
        cloudi_service_messaging_sequence1,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 4},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation2}]},
    {internal,
        "/tests/messaging/erlang/variation2/",
        cloudi_service_messaging_sequence2,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 4},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation2}]},
    {internal,
        "/tests/messaging/erlang/variation2/",
        cloudi_service_messaging_sequence3,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 4},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation2}]},
    {internal,
        "/tests/messaging/erlang/variation2/",
        cloudi_service_messaging_sequence4,
        [],
        immediate_local,
        5000, 10000, 10000, [api], undefined, 4, 5, 300,
        [{application_name, cloudi_service_messaging_sequence},
         {duo_mode, true},
         {hibernate, true},
         {request_pid_uses, 4},
         {reload, true},
         {timeout_terminate, 10},
         {scope, cloudi_service_messaging_erlang_variation2}]}
]}.
% automatic node detection with a UDP multicast group
{nodes, automatic}.
% is equivalent to:
%{nodes, [{discovery, [{multicast, []}]}]}.
% manually specified node names
%{nodes, ['cloudi@host1', 'cloudi@host2']}.
% is equivalent to:
%{nodes, [{nodes, ['cloudi@host1', 'cloudi@host2']}]}.
% (see http://cloudi.org/api.html#2_nodes_set for all the options)
{logging, [
    %{file, "path/to/logfile"},
    %{level, trace}, % levels: off, fatal, error, warn, info, debug, trace
    %{syslog,
    % [{identity, "CloudI"},
    %  {facility, local0},
    %  {level, trace}]}, % CloudI log levels are mapped to syslog levels
    %{formatters,
    % [{any,
    %   [{formatter, cloudi_core_i_logger},
    %    {formatter_config,
    %     [{mode, legacy}]}]},
    %  {['STDOUT'],
    %   [{formatter, cloudi_core_i_logger},
    %    {formatter_config,
    %     [{mode, legacy_stdout}]}]},
    %  {['STDERR'],
    %   [{formatter, cloudi_core_i_logger},
    %    {formatter_config,
    %     [{mode, legacy_stderr}]}]}]},
    %{redirect, undefined}
]}.

