You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2018/03/23 21:23:53 UTC

qpid-dispatch git commit: DISPATCH-940: Fernando Giorgetti - Config files use relative paths

Repository: qpid-dispatch
Updated Branches:
  refs/heads/master ce04365d5 -> 645d87e45


DISPATCH-940: Fernando Giorgetti - Config files use relative paths

In addition to the original PR this commit includes test fixes:
* tests shared test.pid file
* test.pid file was not located well in directory hierarchy
* wait_port added to prove that routers came on line
* minor tweaks and class duplication to work around framework
  creation of config files but then starting routers with popen


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/645d87e4
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/645d87e4
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/645d87e4

Branch: refs/heads/master
Commit: 645d87e45c64f50e22a846de7cd9a352c1a568cc
Parents: ce04365
Author: Chuck Rolke <cr...@redhat.com>
Authored: Fri Mar 23 17:09:07 2018 -0400
Committer: Chuck Rolke <cr...@redhat.com>
Committed: Fri Mar 23 17:20:35 2018 -0400

----------------------------------------------------------------------
 router/src/main.c                     |  45 ++++++++-
 tests/CMakeLists.txt                  |   1 +
 tests/system_tests_cmdline_parsing.py | 157 +++++++++++++++++++++++++++++
 3 files changed, 202 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/645d87e4/router/src/main.c
----------------------------------------------------------------------
diff --git a/router/src/main.c b/router/src/main.c
index b525dda..b6c9d53 100644
--- a/router/src/main.c
+++ b/router/src/main.c
@@ -26,6 +26,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
+#include <stdlib.h>
 #include <getopt.h>
 #include <errno.h>
 #include "config.h"
@@ -176,6 +177,46 @@ static void daemon_process(const char *config_path, const char *python_pkgdir,
             //
             umask(0);
 
+
+            //
+            // If config path is not represented by its full path, then
+            // save current path before changing to /
+            //
+            char *config_path_full = NULL;
+            if (strncmp("/", config_path, 1)) {
+                char *cur_path = NULL;
+                size_t path_size = 256;
+                int getcwd_error = 0;
+                cur_path = (char *) calloc(path_size, sizeof(char));
+
+                while ( getcwd(cur_path, path_size) == NULL ) {
+                    free(cur_path);
+                    if ( errno != ERANGE ) {
+                        // If unable to get current directory
+                        getcwd_error = 1;
+                        break;
+                    }
+                    // If current path does not fit, allocate more memory
+                    path_size += 256;
+                    cur_path = (char *) calloc(path_size, sizeof(char));
+                }
+
+                // Populating fully qualified config file name
+                if (!getcwd_error) {
+                    size_t cpf_len = path_size + strlen(config_path) + 1;
+                    config_path_full = calloc(cpf_len, sizeof(char));
+                    snprintf(config_path_full, cpf_len, "%s%s%s",
+                             cur_path,
+                             !strcmp("/", cur_path)? "":"/",
+                             config_path);
+                }
+
+                // Releasing temporary path variable
+                memset(cur_path, 0, path_size * sizeof(char));
+                free(cur_path);
+
+            }
+
             //
             // Set the current directory to "/" to avoid blocking
             // mount points
@@ -203,7 +244,9 @@ static void daemon_process(const char *config_path, const char *python_pkgdir,
                 //if (setgid(pwd->pw_gid) < 0) fail(pipefd[1], "Can't set group ID for user %s, errno=%d", user, errno);
             }
 
-            main_process(config_path, python_pkgdir, pipefd[1]);
+            main_process((config_path_full ? config_path_full : config_path), python_pkgdir, pipefd[1]);
+
+            free(config_path_full);
         } else
             //
             // Exit first child

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/645d87e4/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b2f0f2e..939b51f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -108,6 +108,7 @@ foreach(py_test_module
     system_tests_topology_addition
     system_tests_disallow_link_resumable_link_route
     system_tests_exchange_bindings
+    system_tests_cmdline_parsing
     ${SYSTEM_TESTS_HTTP}
     )
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/645d87e4/tests/system_tests_cmdline_parsing.py
----------------------------------------------------------------------
diff --git a/tests/system_tests_cmdline_parsing.py b/tests/system_tests_cmdline_parsing.py
new file mode 100644
index 0000000..eca8e0c
--- /dev/null
+++ b/tests/system_tests_cmdline_parsing.py
@@ -0,0 +1,157 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+"""
+This is a unit test class used to validate how qdrouterd
+behaves with different command line arguments combinations,
+in order to ensure it won't break, causing bad experiences
+to the users.
+"""
+
+import os
+import signal
+from subprocess import PIPE, STDOUT
+import unittest2 as unittest
+from system_test import TestCase, Qdrouterd, main_module, Process, wait_port
+
+class CommandLineTest(TestCase):
+    """
+    System tests for command line arguments parsing
+    """
+    testport = 0
+    testname = ""
+
+    @classmethod
+    def setUpClass(cls):
+        """Uses a default config for testing"""
+
+        super(CommandLineTest, cls).setUpClass()
+        cls.name = "test-router-1"
+        CommandLineTest.testname = cls.name
+        CommandLineTest.testport = cls.tester.get_port()
+        cls.config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': CommandLineTest.name}),
+            ('listener', {'port': CommandLineTest.testport}),
+            ('log',{'module':'DEFAULT', 'enable':'trace+', 'source': 'true', 'output': os.getcwd()+"/"+CommandLineTest.name+'.log'})
+        ])
+
+    def run_qdrouterd_as_daemon(self, config_file_name,
+                                pid_file_name):
+        """
+        Runs qdrouterd as a daemon, using the provided config_file_name
+        in order to ensure router is able to load it, be it using a
+        full or relative path.
+
+        :param config_file_name: The configuration file name to be written
+        :param pid_file_name: PID file name (must be full path)
+        :return:
+        """
+        pipe = self.popen(
+            ['qdrouterd', '-d', '-c',
+             self.config.write(config_file_name), '-P', pid_file_name],
+            stdout=PIPE, stderr=STDOUT, expect=Process.EXIT_OK)
+        out = pipe.communicate()[0]
+        wait_port(CommandLineTest.testport)
+
+        try:
+            pipe.teardown()
+            # kill qdrouterd running as a daemon
+            with open(pid_file_name, 'r') as pidfile:
+                for line in pidfile:
+                    os.kill(int(line), signal.SIGTERM)
+            pidfile.close()
+        except OSError as ex:
+            raise Exception("%s\n%s" % (ex, out))
+
+
+    def test_01_config_relative_path(self):
+        """
+        Starts qdrouterd as daemon, enforcing a config file name with
+        relative path.
+        """
+
+        try:
+            self.run_qdrouterd_as_daemon("test-router", os.getcwd()+'/test.pid')
+        except OSError as ex:
+            self.fail(ex)
+
+class CommandLineTest2(TestCase):
+    """
+    System tests for command line arguments parsing
+    """
+    testport = 0
+    testname = ""
+
+    @classmethod
+    def setUpClass(cls):
+        """Uses a default config for testing"""
+
+        super(CommandLineTest2, cls).setUpClass()
+        cls.name = "test-router-2"
+        CommandLineTest2.testname = cls.name
+        CommandLineTest2.testport = cls.tester.get_port()
+        cls.config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': CommandLineTest2.testname}),
+            ('listener', {'port': CommandLineTest2.testport}),
+            ('log',{'module':'DEFAULT', 'enable':'trace+', 'source': 'true', 'output': os.getcwd()+"/"+CommandLineTest2.name+'.log'})
+        ])
+
+    def run_qdrouterd_as_daemon(self, config_file_name, pid_file_name):
+        """
+        Runs qdrouterd as a daemon, using the provided config_file_name
+        in order to ensure router is able to load it, be it using a
+        full or relative path.
+
+        :param config_file_name: The configuration file name to be written
+        :param pid_file_name: PID file name (must be full path)
+        :return:
+        """
+        pipe = self.popen(
+            ['qdrouterd', '-d', '-c',
+             self.config.write(config_file_name), '-P', pid_file_name],
+            stdout=PIPE, stderr=STDOUT, expect=Process.EXIT_OK)
+        out = pipe.communicate()[0]
+        wait_port(CommandLineTest2.testport)
+
+        try:
+            pipe.teardown()
+            # kill qdrouterd running as a daemon
+            with open(pid_file_name, 'r') as pidfile:
+                for line in pidfile:
+                    os.kill(int(line), signal.SIGTERM)
+            pidfile.close()
+        except OSError as ex:
+            raise Exception("%s\n%s" % (ex, out))
+
+
+    def test_02_config_full_path(self):
+        """
+        Starts qdrouterd as daemon, enforcing a config file name with
+        full path.
+        """
+
+        try:
+            self.run_qdrouterd_as_daemon(os.getcwd() + "/test-router-2.conf",
+                                pid_file_name=os.getcwd()+'/test.pid')
+        except OSError as ex:
+            self.fail(ex)
+
+
+if __name__ == '__main__':
+    unittest.main(main_module())


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org