Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adapt the turtle env node test to use the new TestNode
Browse files Browse the repository at this point in the history
Gavin Norman committed Aug 14, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent a212c52 commit c159506
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.
@@ -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, Client.Neo.Put.Args ) { });
if ( !ok )
return false;

void[] value;
ok = client.blocking.get(1, value,
( Client.Neo.Get.Notification, 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 c159506

Please sign in to comment.