Added pipe test
authorJeroen van der Heijden <jeroen@transceptor.technology>
Fri, 24 Aug 2018 09:09:40 +0000 (11:09 +0200)
committerJeroen van der Heijden <jeroen@transceptor.technology>
Fri, 24 Aug 2018 09:09:40 +0000 (11:09 +0200)
include/siri/net/pipe.h
src/siri/net/clserver.c
src/siri/net/pipe.c
src/siri/net/stream.c
test/test_pipe.c [new file with mode: 0644]
test/test_pipe_support.py [new file with mode: 0644]
test/testing/__init__.py
test/testing/constants.py
test/testing/pipe_client.py [new file with mode: 0644]
test/testing/server.py
test/testing/siridb.py

index edee0108b256ec1b9998fde28372561452f9bfaf..51bc7de6e3290092460b38dc8a7f7160587e6d00 100644 (file)
@@ -4,5 +4,6 @@
 #include <uv.h>
 
 char * sirinet_pipe_name(uv_pipe_t * client);
+void sirinet_pipe_unlink(uv_pipe_t * client);
 
 #endif  /* SIRINET_PIPE_H_ */
index 54fc40417dafab4206171432f7937bc9ef1553e4..88467609bc3ab082853dddf1a0202ec026427159 100644 (file)
@@ -121,6 +121,7 @@ int sirinet_clserver_init(siri_t * siri)
 
     /* make sure data is set to NULL so we later on can check this value. */
     client_server_tcp.data = NULL;
+    client_server_pipe.data = NULL;
 
     if (siri->cfg->bind_client_addr != NULL)
     {
@@ -169,7 +170,7 @@ int sirinet_clserver_init(siri_t * siri)
     }
 
     rc = uv_listen(
-            (uv_stream_t*) &client_server_tcp,
+            (uv_stream_t *) &client_server_tcp,
             DEFAULT_BACKLOG,
             on_tcp_new_connection);
 
@@ -184,11 +185,9 @@ int sirinet_clserver_init(siri_t * siri)
 
     if (siri->cfg->pipe_support)
     {
-        char *pipe_name = siri->cfg->pipe_client_name;
+        char * pipe_name = siri->cfg->pipe_client_name;
 
-        rc = uv_pipe_bind(
-                &client_server_pipe,
-                pipe_name);
+        rc = uv_pipe_bind(&client_server_pipe, pipe_name);
 
         if (rc)
         {
@@ -197,13 +196,14 @@ int sirinet_clserver_init(siri_t * siri)
         }
 
         rc = uv_listen(
-                (uv_stream_t*) &client_server_pipe,
+                (uv_stream_t *) &client_server_pipe,
                 DEFAULT_BACKLOG,
                 on_pipe_new_connection);
 
         if (rc)
         {
-            log_error("Error listening TCP client server: %s", uv_strerror(rc));
+            log_error(
+                    "Error listening pipe client server: %s", uv_strerror(rc));
             return 1;
         }
 
index d553da9d3878377b4411e91aea09111401fddf8a..14748e7e8472f7ba4d8675779b81dd8546a3f8ad 100644 (file)
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <siri/net/pipe.h>
+#include <siri/siri.h>
 #include <xpath/xpath.h>
 
 #define PIPE_NAME_BUF_SZ SIRI_PATH_MAX
@@ -26,3 +27,17 @@ char * sirinet_pipe_name(uv_pipe_t * client)
     return buffer;
 
 }
+
+void sirinet_pipe_unlink(uv_pipe_t * client)
+{
+    char * pipe_name = sirinet_pipe_name(client);
+    if (pipe_name != NULL)
+    {
+        uv_fs_t * req = malloc(sizeof(uv_fs_t));
+        if (req != NULL)
+        {
+            uv_fs_unlink(siri.loop, req, pipe_name, (uv_fs_cb) free);
+        }
+        free(pipe_name);
+    }
+}
index 050d4cee1f7ec4cd4cce0ab8cb00d6489caeecef..71e925d195438445e6373a1214f0a2f841f28fd6 100644 (file)
@@ -20,7 +20,6 @@
 #include <siri/siri.h>
 #include <stdlib.h>
 #include <string.h>
-#include <siri/siri.h>
 
 #define MAX_ALLOWED_PKG_SIZE 20971520      /* 20 MB  */
 
@@ -275,19 +274,13 @@ void sirinet__stream_free(uv_stream_t * uvclient)
         siri.client = NULL;
         break;
     case STREAM_PIPE_CLIENT:
+        if (client->origin != NULL)
         {
-            char * pipe_name = sirinet_pipe_name((uv_pipe_t *) uvclient);
-            if (pipe_name != NULL)
-            {
-                uv_fs_t * req = malloc(sizeof(uv_fs_t));
-                if (req != NULL)
-                {
-                    uv_fs_unlink(siri.loop, req, pipe_name, (uv_fs_cb) free);
-                }
-                free(pipe_name);
-            }
+            siridb_user_t * user = client->origin;
+            siridb_user_decref(user);
         }
-
+        sirinet_pipe_unlink((uv_pipe_t *) uvclient);
+        break;
     }
     free(client->buf);
     free(client);
diff --git a/test/test_pipe.c b/test/test_pipe.c
new file mode 100644 (file)
index 0000000..98c9dd8
--- /dev/null
@@ -0,0 +1,21 @@
+#include <uv.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void OnConnect(uv_connect_t * connect, int status)
+{
+    printf("Hi!");
+}
+
+int main()
+{
+    uv_loop_t * loop = uv_default_loop();
+    uv_pipe_t * handle = malloc(sizeof(uv_pipe_t));
+    uv_connect_t * connect = malloc(sizeof(uv_connect_t));
+
+    uv_pipe_init(loop, handle, 0);
+    uv_pipe_open(handle, socket(PF_UNIX, SOCK_STREAM, 0));
+    uv_pipe_connect(connect, handle, "/tmp/siridb_pipe_test.sock", OnConnect);
+
+    uv_run(loop, UV_RUN_DEFAULT);
+}
\ No newline at end of file
diff --git a/test/test_pipe_support.py b/test/test_pipe_support.py
new file mode 100644 (file)
index 0000000..0e61699
--- /dev/null
@@ -0,0 +1,72 @@
+import os
+import asyncio
+import functools
+import random
+import time
+from testing import Client
+from testing import default_test_setup
+from testing import gen_data
+from testing import gen_points
+from testing import gen_series
+from testing import InsertError
+from testing import PoolError
+from testing import QueryError
+from testing import run_test
+from testing import Series
+from testing import Server
+from testing import ServerError
+from testing import SiriDB
+from testing import TestBase
+from testing import UserAuthError
+from testing import SiriDBAsyncUnixConnection
+
+PIPE_NAME = '/tmp/siridb_pipe_test.sock'
+
+DATA = {
+    'series num_float': [
+        [1471254705, 1.5],
+        [1471254707, -3.5],
+        [1471254710, -7.3]],
+    'series num_integer': [
+        [1471254705, 5],
+        [1471254708, -3],
+        [1471254710, -7]],
+    'series_log': [
+        [1471254710, 'log line one'],
+        [1471254712, 'log line two'],
+        [1471254714, 'another line (three)'],
+        [1471254716, 'and yet one more']]
+}
+
+if os.path.exists(PIPE_NAME):
+    os.unlink(PIPE_NAME)
+
+class TestPipeSupport(TestBase):
+    title = 'Test pipe support object'
+
+
+    @default_test_setup(1, pipe_name=PIPE_NAME)
+    async def run(self):
+
+        pipe_client = SiriDBAsyncUnixConnection(PIPE_NAME)
+
+        await pipe_client.connect('iris', 'siri', self.db.dbname)
+
+        await pipe_client.insert(DATA)
+
+        self.assertEqual(
+            await pipe_client.query('select * from "series_log"'),
+            {'series_log': DATA['series_log']})
+
+        pipe_client.close()
+
+
+        # return False
+
+
+if __name__ == '__main__':
+    SiriDB.LOG_LEVEL = 'CRITICAL'
+    Server.HOLD_TERM = True
+    Server.MEM_CHECK = True
+    Server.BUILDTYPE = 'Debug'
+    run_test(TestPipeSupport())
index 0f015a599e2e9cbe75e116d1dbfac5c4a5ca9382..54a54e7341c35be72a4771b1ef333284ea946234 100644 (file)
@@ -17,6 +17,7 @@ from .siridb import SiriDB
 from .testbase import default_test_setup
 from .testbase import TestBase
 from .series import Series
+from .pipe_client import PipeClient as SiriDBAsyncUnixConnection
 
 
 async def _run_test(test, loglevel):
index bf5eeb8262ffa30ba4212775fb3af8aa88c95b33..8ec4aca174e053e1737c34a39799015d0570a8d6 100644 (file)
@@ -1,9 +1,7 @@
 BUILDTYPE = 'Debug'
 TEST_DIR = './testdir'
 SIRIDBC = '../{BUILDTYPE}/siridb-server'
-MANAGE = '' # '/usr/sbin/siridb-manage'
 ADMIN = '/usr/local/bin/siridb-admin'
-TOOL = 'ADMIN' # TOOL should be ADMIN or MANAGE. (MANAGE is the old, obsolete tool and ADMIN is preffered)
 # VALGRIND = 'valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --track-origins=yes -v '
 VALGRIND = 'valgrind --tool=memcheck '
 MAX_OPEN_FILES = 512    # Default value is 32768 but with valgrind 512 is max
diff --git a/test/testing/pipe_client.py b/test/testing/pipe_client.py
new file mode 100644 (file)
index 0000000..001f7d0
--- /dev/null
@@ -0,0 +1,30 @@
+import os
+import logging
+import asyncio
+from siridb.connector import SiriDBProtocol
+from siridb.connector.lib.connection import SiriDBAsyncConnection
+
+
+class PipeClient(SiriDBAsyncConnection):
+    def __init__(self, pipe_name, loop=None):
+        self._pipe_name = pipe_name
+        self._protocol = None
+
+    async def connect(self, username, password, dbname, loop=None):
+        loop = loop or asyncio.get_event_loop()
+
+        transport, self._protocol = await loop.create_unix_connection(
+            path=self._pipe_name,
+            protocol_factory=lambda: SiriDBProtocol(
+                username, password, dbname))
+
+        try:
+            res = await self._protocol.auth_future
+        except Exception as exc:
+            logging.debug('Authentication failed: {}'.format(exc))
+            transport.close()
+            raise exc
+        else:
+            self._protocol.on_authenticated()
+
+
index 9a6f37ac347995c6ec4e21b6e6901f83b0a791bc..96edb0994eedd50a221a27f0f2de068b0d0c616c 100644 (file)
@@ -34,9 +34,14 @@ class Server:
                  optimize_interval=30,
                  heartbeat_interval=30,
                  compression=True,
+                 pipe_name=None,
                  **unused):
         self.n = n
         self.compression = compression
+        self.enable_pipe_support = int(bool(pipe_name))
+        self.pipe_name = \
+            'siridb_client.sock' if not self.enable_pipe_support else \
+            pipe_name
         self.listen_client_port = 9000 + n
         self.listen_backend_port = 9010 + n
         self._server_address = self.SERVER_ADDRESS
@@ -74,6 +79,8 @@ class Server:
         config.set('siridb', 'default_db_path', self.dbpath)
         config.set('siridb', 'max_open_files', MAX_OPEN_FILES)
         config.set('siridb', 'enable_shard_compression', int(self.compression))
+        config.set('siridb', 'enable_pipe_support', self.enable_pipe_support)
+        config.set('siridb', 'pipe_client_name',  self.pipe_name)
 
         with open(self.cfgfile, 'w') as configfile:
             config.write(configfile)
index 962b15b7aad54e9583a05a19790b8a4b8103e76f..51445f371b01fb447389408c4b5e9870dde865fe 100644 (file)
@@ -2,9 +2,7 @@ import os
 import logging
 import random
 import asyncio
-from .constants import MANAGE
 from .constants import ADMIN
-from .constants import TOOL
 
 VERBOSE = ' --verbose'
 
@@ -36,44 +34,21 @@ class SiriDB:
             self.dbname,
             server.name))
 
-        if TOOL == 'MANAGE':
-            rc = os.system(
-                '{manage} '
-                '--log-level {log_level} '
-                '--noroot --config {cfgfile} create-new '
-                '--dbname {dbname} '
-                '--time-precision {time_precision} '
-                '{bufpath}'
-                '--duration-log {duration_log} '
-                '--duration-num {duration_num} '
-                '--buffer-size {buffer_size}'.format(
-                    manage=MANAGE,
-                    log_level=self.LOG_LEVEL.lower(),
-                    cfgfile=server.cfgfile,
-                    bufpath='' if not self.buffer_path
-                            else '--buffer-path {}'.format(self.buffer_path),
-                    **vars(self)))
-        elif TOOL == 'ADMIN':
-            rc = os.system(
-                '{admin} '
-                '-u sa -p siri -s {addr} '
-                'new-database '
-                '--db-name {dbname} '
-                '--time-precision {time_precision} '
-                '--duration-log {duration_log} '
-                '--duration-num {duration_num} '
-                '--buffer-size {buffer_size}'
-                '{verbose}'.format(
-                    admin=ADMIN,
-                    addr=server.addr,
-                    verbose=VERBOSE if self.LOG_LEVEL == 'DEBUG'
-                    else ' >/dev/null',
-                    **vars(self)))
-        else:
-            logging.error(
-                'TOOL should be either MANAGE or ADMIN, got: {}'
-                .format(TOOL))
-            rc = 1
+        rc = os.system(
+            '{admin} '
+            '-u sa -p siri -s {addr} '
+            'new-database '
+            '--db-name {dbname} '
+            '--time-precision {time_precision} '
+            '--duration-log {duration_log} '
+            '--duration-num {duration_num} '
+            '--buffer-size {buffer_size}'
+            '{verbose}'.format(
+                admin=ADMIN,
+                addr=server.addr,
+                verbose=VERBOSE if self.LOG_LEVEL == 'DEBUG'
+                else ' >/dev/null',
+                **vars(self)))
 
         assert rc == 0, 'Expected rc = 0 but got rc = {}'.format(rc)
 
@@ -94,55 +69,25 @@ class SiriDB:
         if remote_server is None:
             remote_server = random.choice(self.servers)
 
-        if TOOL == 'MANAGE':
-            rc = os.system(
-                '{manage} '
-                '--log-level {log_level} '
-                '--noroot --config {cfgfile} create-replica '
-                '--dbname {dbname} '
-                '--remote-address {remote_address} '
-                '--remote-port {remote_port} '
-                '--user {user} '
-                '--password {password} '
-                '--pool {pool} '
-                '{bufpath}'
-                '--buffer-size {buffer_size}'.format(
-                    manage=MANAGE,
-                    log_level=self.LOG_LEVEL.lower(),
-                    cfgfile=server.cfgfile,
-                    user=username,
-                    password=password,
-                    pool=pool,
-                    bufpath='' if not self.buffer_path
-                            else '--buffer-path {}'.format(self.buffer_path),
-                    **vars(self),
-                    remote_address=remote_server.server_address,
-                    remote_port=remote_server.listen_client_port))
-        elif TOOL == 'ADMIN':
-            rc = os.system(
-                '{admin} '
-                '-u sa -p siri -s {addr} '
-                'new-replica '
-                '--db-name {dbname} '
-                '--db-server {dbaddr} '
-                '--db-user {dbuser} '
-                '--db-password {dbpassword} '
-                '--pool {pool} '
-                '--force{verbose}'.format(
-                    admin=ADMIN,
-                    addr=server.addr,
-                    dbaddr=remote_server.addr,
-                    dbuser=username,
-                    dbpassword=password,
-                    pool=pool,
-                    verbose=VERBOSE if self.LOG_LEVEL == 'DEBUG'
-                    else ' >/dev/null',
-                    **vars(self)))
-        else:
-            logging.error(
-                'TOOL should be either MANAGE or ADMIN, got: {}'
-                .format(TOOL))
-            rc = 1
+        rc = os.system(
+            '{admin} '
+            '-u sa -p siri -s {addr} '
+            'new-replica '
+            '--db-name {dbname} '
+            '--db-server {dbaddr} '
+            '--db-user {dbuser} '
+            '--db-password {dbpassword} '
+            '--pool {pool} '
+            '--force{verbose}'.format(
+                admin=ADMIN,
+                addr=server.addr,
+                dbaddr=remote_server.addr,
+                dbuser=username,
+                dbpassword=password,
+                pool=pool,
+                verbose=VERBOSE if self.LOG_LEVEL == 'DEBUG'
+                else ' >/dev/null',
+                **vars(self)))
 
         assert rc == 0, 'Expected rc = 0 but got rc = {}'.format(rc)
 
@@ -162,51 +107,23 @@ class SiriDB:
         if remote_server is None:
             remote_server = random.choice(self.servers)
 
-        if TOOL == 'MANAGE':
-            rc = os.system(
-                '{manage} '
-                '--log-level {log_level} '
-                '--noroot --config {cfgfile} create-pool '
-                '--dbname {dbname} '
-                '--remote-address {remote_address} '
-                '--remote-port {remote_port} '
-                '--user {user} '
-                '--password {password} '
-                '{bufpath}'
-                '--buffer-size {buffer_size}'.format(
-                    manage=MANAGE,
-                    log_level=self.LOG_LEVEL.lower(),
-                    cfgfile=server.cfgfile,
-                    user=username,
-                    password=password,
-                    bufpath='' if not self.buffer_path
-                            else '--buffer-path {}'.format(self.buffer_path),
-                    **vars(self),
-                    remote_address=remote_server.server_address,
-                    remote_port=remote_server.listen_client_port))
-        elif TOOL == 'ADMIN':
-            rc = os.system(
-                '{admin} '
-                '-u sa -p siri -s {addr} '
-                'new-pool '
-                '--db-name {dbname} '
-                '--db-server {dbaddr} '
-                '--db-user {dbuser} '
-                '--db-password {dbpassword} '
-                '--force{verbose}'.format(
-                    admin=ADMIN,
-                    addr=server.addr,
-                    dbaddr=remote_server.addr,
-                    dbuser=username,
-                    dbpassword=password,
-                    verbose=VERBOSE if self.LOG_LEVEL == 'DEBUG'
-                    else ' >/dev/null',
-                    **vars(self)))
-        else:
-            logging.error(
-                'TOOL should be either MANAGE or ADMIN, got: {}'
-                .format(TOOL))
-            rc = 1
+        rc = os.system(
+            '{admin} '
+            '-u sa -p siri -s {addr} '
+            'new-pool '
+            '--db-name {dbname} '
+            '--db-server {dbaddr} '
+            '--db-user {dbuser} '
+            '--db-password {dbpassword} '
+            '--force{verbose}'.format(
+                admin=ADMIN,
+                addr=server.addr,
+                dbaddr=remote_server.addr,
+                dbuser=username,
+                dbpassword=password,
+                verbose=VERBOSE if self.LOG_LEVEL == 'DEBUG'
+                else ' >/dev/null',
+                **vars(self)))
 
         assert rc == 0, 'Expected rc = 0 but got rc = {}'.format(rc)