1 module testutils; 2 3 version (unittest) { 4 import memgraph; 5 6 // Port where the memgraph container is listening. 7 enum MEMGRAPH_PORT = 7688; 8 9 bool canConnect() { 10 import std.string, std.conv, std.stdio; 11 auto params = mg_session_params_make(); 12 assert(params != null); 13 14 mg_session_params_set_host(params, toStringz("127.0.0.1")); 15 mg_session_params_set_port(params, to!ushort(MEMGRAPH_PORT)); 16 mg_session_params_set_sslmode(params, mg_sslmode.MG_SSLMODE_DISABLE); 17 18 mg_session *session = null; 19 immutable status = mg_connect(params, &session); 20 mg_session_params_destroy(params); 21 22 mg_session_destroy(session); 23 24 return status == 0; 25 } // canConnect() 26 27 // Start a memgraph container for unit testing if it is not already running. 28 // Store the container id in $TMP/memgraph-d.container so it can be used in 29 // other tests without having to start a new container each time. 30 void startContainer() { 31 import std.process, std.stdio, std.file, std.string; 32 33 import std.conv; 34 35 auto containerIdFileName = environment.get("TMP", "/tmp") ~ "/memgraph-d.container"; 36 37 auto startContainer = true; 38 39 if (exists(containerIdFileName)) { 40 // Read container id from temp storage. 41 auto containerIdFile = File(containerIdFileName, "r"); 42 auto containerId = containerIdFile.readln(); 43 containerIdFile.close(); 44 45 // Check if the container is still up and running. 46 auto ps = execute(["docker", "ps", "-q", "--no-trunc"]); 47 assert(ps.status == 0); 48 startContainer = false; 49 50 if (ps.output.indexOf(containerId) < 0) 51 startContainer = true; 52 } 53 54 if (startContainer) { 55 import std.conv; 56 57 // Pull the latest memgraph docker image. 58 immutable pull = execute(["docker", "pull", "memgraph/memgraph"]); 59 assert(pull.status == 0); 60 61 // Start a new memgraph docker container. 62 auto containerIdFile = File(containerIdFileName, "w"); 63 immutable run = execute(["docker", "run", "-d", "-p", 64 to!string(MEMGRAPH_PORT) ~ ":7687", "-d", "memgraph/memgraph"]); 65 assert(run.status == 0); 66 67 // Store container id. 68 auto containerId = run.output; 69 containerIdFile.write(containerId); 70 containerIdFile.close(); 71 72 // Need to wait a while until the container is spun up, otherwise connecting will fail. 73 while (!canConnect()) { 74 import core.thread.osthread, core.time; 75 Thread.sleep(dur!("msecs")(250)); 76 } 77 } 78 } // startContainer() 79 80 // Create a client connection to the running unit test container. 81 auto connectContainer() { 82 startContainer(); // Make sure container is up. 83 Params params; 84 params.port = MEMGRAPH_PORT; 85 return Client.connect(params); 86 } // connectContainer() 87 88 // Create an index on the test data. 89 void createTestIndex(ref Client client) { 90 assert(client.run("CREATE INDEX ON :Person(id);"), client.error); 91 } // createTestIndex() 92 93 // Delete the test data. 94 void deleteTestData(ref Client client) { 95 assert(client.run("MATCH (n) DETACH DELETE n;"), client.error); 96 } // deleteTestData() 97 98 // Create some test data. 99 void createTestData(ref Client client) { 100 // Create a few nodes. 101 assert(client.run( 102 "CREATE (:Person:Entrepreneur {id: 0, age: 40, name: 'John', " ~ 103 "isStudent: false, score: 5.0});"), client.error); 104 assert(client.run( 105 "CREATE (:Person:Entrepreneur {id: 1, age: 20, name: 'Valery', " ~ 106 "isStudent: true, score: 5.0});"), client.error); 107 assert(client.run( 108 "CREATE (:Person:Entrepreneur {id: 2, age: 50, name: 'Peter', " ~ 109 "isStudent: false, score: 4.0});"), client.error); 110 assert(client.run( 111 "CREATE (:Person:Entrepreneur {id: 3, age: 30, name: 'Ray', " ~ 112 "isStudent: false, score: 9.0});"), client.error); 113 assert(client.run( 114 "CREATE (:Person:Entrepreneur {id: 4, age: 25, name: 'Olaf', " ~ 115 "isStudent: true, score: 10.0});"), client.error); 116 117 // Create some relationships. 118 assert(client.run( 119 "MATCH (a:Person), (b:Person) WHERE a.name = 'John' AND b.name = 'Peter' " ~ 120 "CREATE (a)-[r:IS_MANAGER]->(b);"), client.error); 121 assert(client.run( 122 "MATCH (a:Person), (b:Person) WHERE a.name = 'Peter' AND b.name = 'Valery' " ~ 123 "CREATE (a)-[r:IS_MANAGER]->(b);"), client.error); 124 assert(client.run( 125 "MATCH (a:Person), (b:Person) WHERE a.name = 'Valery' AND b.name = 'Olaf' " ~ 126 "CREATE (a)-[r:IS_MANAGER]->(b);"), client.error); 127 } // createTestData() 128 129 }