Skip to content

Commit

Permalink
Adapt the turtle env node test to use the new TestNode
Browse files Browse the repository at this point in the history
  • Loading branch information
Gavin Norman committed Aug 23, 2018
1 parent 1beae0a commit 49137d7
Showing 1 changed file with 197 additions and 54 deletions.
251 changes: 197 additions & 54 deletions integrationtest/turtleenv/main.d
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
Test of the abstract turtle node extension.
Test of the turtle swarm node extension.
Copyright:
Copyright (c) 2018 dunnhumby Germany GmbH. All rights reserved.
Expand All @@ -12,103 +12,246 @@

module integrationtest.turtleenv.main;

import swarm.neo.AddrPort;
import turtle.env.model.Node;
import ocean.transition;
import ocean.task.Scheduler;
import ocean.task.Task;
import ocean.util.test.DirectorySandbox;
import ocean.core.Test;
import ocean.io.device.File;
import swarm.Const : ICommandCodes, NodeItem;
import swarm.node.connection.ConnectionHandler;
import turtle.env.model.TestNode;

/// Node used to the turtle test
private class TurtleNode
version (UnitTest){}
else
void main()
{
/// Address and the port of the node
AddrPort addrport;
AddrPort neo_address;
auto sandbox = DirectorySandbox.create();
scope (success)
sandbox.remove();

this (AddrPort addrport)
{
this.addrport = addrport;
this.neo_address = AddrPort(this.addrport.address());
this.neo_address.port = cast(ushort)(this.addrport.port() + 100);
}
initScheduler(Scheduler.Configuration.init);

auto node = new MyNode("127.0.0.1", 10000);
node.start();

theScheduler.schedule(new Tests(node));
theScheduler.eventLoop();
}

/// The turlte TurtleNode class
private class TestNode : Node!(TurtleNode, "turtleNode")
/*******************************************************************************
Task that performs tests on the test node passed to the ctor.
*******************************************************************************/

class Tests : Task
{
/***********************************************************************
import integrationtest.neo.client.Client;
import ocean.core.Test;
import ocean.io.device.File;

/// Node instance to test.
private MyNode node;

/// Client instance to use for checking network availability of the node.
private Client client;

Creates a fake node at the specified address/port.
/***************************************************************************
Constructor.
Params:
node_item = address/port
node = node to test
***************************************************************************/

public this ( MyNode node )
{
this.node = node;
}

/***************************************************************************
***********************************************************************/
Task entry point. Runs a series of tests on the node then shuts down the
scheduler.
override protected TurtleNode createNode ( AddrPort addrport )
***************************************************************************/

public override void run ( )
{
return new TurtleNode(addrport);
// Test config file generation.
this.node.genConfigFiles(".");
test!("==")(File.get("testnode.nodes"), "127.0.0.1:9999\n");
test!("==")(File.get("testnode.neo.nodes"), "127.0.0.1:10000\n");

// Initialise client and connect.
this.client = new Client(theScheduler.epoll, "127.0.0.1", 10000,
&this.connNotifier);
client.blocking.waitAllNodesConnected();

// Try to talk to the node.
auto ok = this.talkToNode();
test(ok);

// Stop the node, then try to talk to it (failure expected).
this.node.stop();
ok = this.talkToNode();
test(!ok);

// Restart the node, reconnect the client, then try to talk to the node.
this.node.restart();
client.blocking.waitAllNodesConnected();
ok = this.talkToNode();
test(ok);

// Finished.
theScheduler.shutdown();
}

/***********************************************************************
/***************************************************************************
Uses the client to put a record to the node, then read it back.
Returns:
address/port on which node is listening
true if everything succeeded, false on error
***********************************************************************/
***************************************************************************/

override public AddrPort node_addrport ( )
private bool talkToNode ( )
{
assert(this.node);
return this.node.addrport;
auto ok = client.blocking.put(1, "hello",
( Client.Neo.Put.Notification, Const!(Client.Neo.Put.Args) ) { });
if ( !ok )
return false;

void[] value;
ok = client.blocking.get(1, value,
( Client.Neo.Get.Notification, Const!(Client.Neo.Get.Args) ) { });
if ( !ok )
return false;

return true;
}

/***********************************************************************
/***************************************************************************
Fake node service stop implementation.
Dummy connection notifier. Required by the client, but unused.
***********************************************************************/
***************************************************************************/

protected override void stopImpl ( )
private void connNotifier ( Client.Neo.ConnNotification info )
{
}
}

/*******************************************************************************
Test node implementing the protocol defined in integrationtest.neo.node.
*******************************************************************************/

public class MyNode : TestNode!(ConnHandler)
{
import swarm.neo.AddrPort;

/***********************************************************************
import integrationtest.neo.node.Node;
import integrationtest.neo.node.Storage;
import integrationtest.neo.node.request.Get;
import integrationtest.neo.node.request.Put;

/***************************************************************************
Constructor.
Params:
addr = address to bind to
neo_port = port to bind to for neo protocol (legacy protocol binds
to a port one lower)
***************************************************************************/

public this ( cstring addr, ushort neo_port )
{
// In this simple example node implementation, we don't need any shared
// resources except the reference to the storage.
this.shared_resources = new Storage;

Options options;
options.epoll = theScheduler.epoll;
options.requests.addHandler!(GetImpl_v0)();
options.credentials_map["dummy"] = Key.init;
options.shared_resources = this.shared_resources;

options.requests.addHandler!(GetImpl_v0)();
options.requests.addHandler!(PutImpl_v0)();

const backlog = 1_000;
AddrPort legacy_addr_port;
legacy_addr_port.setAddress(addr);
legacy_addr_port.port = cast(ushort)(neo_port - 1);
super(legacy_addr_port, neo_port, new ConnectionSetupParams,
options, backlog);
}

/***************************************************************************
Removes all data from the fake node service.
***********************************************************************/
***************************************************************************/

override public void clear ( )
{
// Unused in this test.
}

/***************************************************************************
Returns:
identifier string for this node
***************************************************************************/

protected override cstring id ( )
{
return "testnode";
}

/***********************************************************************
/***************************************************************************
Suppresses log output from the fake node if used version of proto
supports it.
Scope allocates a request resource acquirer backed by the protected
`shared_resources`. (Passed as a generic Object to avoid templatising
this class and others that depend on it.)
***********************************************************************/
Params:
handle_request_dg = delegate that receives a resources acquirer and
initiates handling of a request
***************************************************************************/

override public void log_errors ( bool log_errors )
override protected void getResourceAcquirer (
void delegate ( Object resource_acquirer ) handle_request_dg )
{
static if (is(typeof(this.node.log_errors(log_errors))))
this.node.log_errors(log_errors);
handle_request_dg(this.shared_resources);
}
}

version (UnitTest){}
else
void main()
/*******************************************************************************
Legacy protocol connection handler. Required by NodeBase but unused in this
example.
*******************************************************************************/

private class ConnHandler : ConnectionHandlerTemplate!(ICommandCodes)
{
auto sandbox = DirectorySandbox.create();
scope (success)
sandbox.remove();
import ocean.net.server.connection.IConnectionHandler;

public this ( void delegate(IConnectionHandler) finaliser,
ConnectionSetupParams params )
{
super(finaliser, params);
}

auto node = new TestNode();
node.start("127.0.0.1", 10000);
node.genConfigFiles(".");
override protected void handleCommand () {}

test!("==")(File.get("turtleNode.nodes"), "127.0.0.1:10000\n");
test!("==")(File.get("turtleNode.neo.nodes"), "127.0.0.1:10100\n");
override protected void handleNone () {}
}

0 comments on commit 49137d7

Please sign in to comment.