Browse Source

[5137] A few fixes and many python style improvements

Francis Dupont 8 years ago
parent
commit
f0494b2149

+ 11 - 2
configure.ac

@@ -470,7 +470,10 @@ AC_ARG_ENABLE(shell, [AC_HELP_STRING([--enable-shell],
 
 
 if test "x$enable_shell" != xno ; then
 if test "x$enable_shell" != xno ; then
 # If kea-shell is enabled, we really need python. 2.7 or anything newer will do.
 # If kea-shell is enabled, we really need python. 2.7 or anything newer will do.
-  AM_PATH_PYTHON([2.7])
+  AM_PATH_PYTHON([3], [found="yes"], [found="no"])
+  if test "x$found" = xno ; then
+    AM_PATH_PYTHON([2.7])
+  fi
 else
 else
   PYTHON=no
   PYTHON=no
 fi
 fi
@@ -1628,8 +1631,10 @@ AC_CONFIG_FILES([compatcheck/Makefile
                  src/bin/admin/tests/cql_tests.sh
                  src/bin/admin/tests/cql_tests.sh
                  src/bin/agent/tests/test_libraries.h
                  src/bin/agent/tests/test_libraries.h
                  src/bin/shell/Makefile
                  src/bin/shell/Makefile
+                 src/bin/shell/kea-shell
                  src/bin/shell/tests/Makefile
                  src/bin/shell/tests/Makefile
                  src/bin/shell/tests/shell_process_tests.sh
                  src/bin/shell/tests/shell_process_tests.sh
+                 src/bin/shell/tests/shell_unittest.py
                  src/hooks/Makefile
                  src/hooks/Makefile
                  src/hooks/dhcp/Makefile
                  src/hooks/dhcp/Makefile
                  src/hooks/dhcp/user_chk/Makefile
                  src/hooks/dhcp/user_chk/Makefile
@@ -1720,11 +1725,14 @@ AC_CONFIG_FILES([compatcheck/Makefile
 ])
 ])
 
 
  AC_CONFIG_COMMANDS([permissions], [
  AC_CONFIG_COMMANDS([permissions], [
+           chmod +x src/bin/admin/kea-admin
            chmod +x src/bin/dhcp4/tests/dhcp4_process_tests.sh
            chmod +x src/bin/dhcp4/tests/dhcp4_process_tests.sh
            chmod +x src/bin/dhcp6/tests/dhcp6_process_tests.sh
            chmod +x src/bin/dhcp6/tests/dhcp6_process_tests.sh
            chmod +x src/bin/keactrl/keactrl
            chmod +x src/bin/keactrl/keactrl
            chmod +x src/bin/keactrl/tests/keactrl_tests.sh
            chmod +x src/bin/keactrl/tests/keactrl_tests.sh
-           chmod +x src/bin/admin/kea-admin
+           chmod +x src/bin/shell/kea-shell
+           chmod +x src/bin/shell/tests/shell_process_tests.sh
+           chmod +x src/bin/shell/tests/shell_unittest.py
            chmod +x src/lib/dns/gen-rdatacode.py
            chmod +x src/lib/dns/gen-rdatacode.py
            chmod +x src/lib/log/tests/console_test.sh
            chmod +x src/lib/log/tests/console_test.sh
            chmod +x src/lib/log/tests/destination_test.sh
            chmod +x src/lib/log/tests/destination_test.sh
@@ -1800,6 +1808,7 @@ if test "$PYTHON" != "no" ; then
 cat >> config.report << END
 cat >> config.report << END
 
 
 Python:
 Python:
+  PYTHON:          ${PYTHON}
   PYTHON_VERSION:  ${PYTHON_VERSION}
   PYTHON_VERSION:  ${PYTHON_VERSION}
 
 
 END
 END

+ 2 - 1
src/bin/agent/tests/Makefile.am

@@ -5,7 +5,6 @@ SHTESTS += ca_process_tests.sh
 
 
 noinst_SCRIPTS = ca_process_tests.sh
 noinst_SCRIPTS = ca_process_tests.sh
 EXTRA_DIST  = ca_process_tests.sh.in
 EXTRA_DIST  = ca_process_tests.sh.in
-noinst_LTLIBRARIES = libbasic.la
 
 
 # test using command-line arguments, so use check-local target instead of TESTS
 # test using command-line arguments, so use check-local target instead of TESTS
 check-local:
 check-local:
@@ -40,6 +39,8 @@ TESTS_ENVIRONMENT = \
 TESTS =
 TESTS =
 if HAVE_GTEST
 if HAVE_GTEST
 
 
+noinst_LTLIBRARIES = libbasic.la
+
 TESTS += ca_unittests
 TESTS += ca_unittests
 
 
 ca_unittests_SOURCES  = ca_cfg_mgr_unittests.cc
 ca_unittests_SOURCES  = ca_cfg_mgr_unittests.cc

+ 3 - 11
src/bin/shell/Makefile.am

@@ -5,7 +5,7 @@ EXTRA_DIST =
 if KEA_SHELL
 if KEA_SHELL
 
 
 # Kea-shell is enabled, here are proper rules for it.
 # Kea-shell is enabled, here are proper rules for it.
-kea_shell_PYTHON = kea-shell.py kea_conn.py kea_connector2.py kea_connector3.py
+kea_shell_PYTHON = kea_conn.py kea_connector2.py kea_connector3.py
 kea_shelldir = @localstatedir@/@PACKAGE@
 kea_shelldir = @localstatedir@/@PACKAGE@
 
 
 bin_SCRIPTS = kea-shell
 bin_SCRIPTS = kea-shell
@@ -13,12 +13,11 @@ bin_SCRIPTS = kea-shell
 else
 else
 
 
 # Kea-shell is disabled, simply keep the files for make dist
 # Kea-shell is disabled, simply keep the files for make dist
-EXTRA_DIST += kea-shell.py kea_conn.py kea_connector2.py kea_connector3.py
+EXTRA_DIST += kea-shell kea_conn.py kea_connector2.py kea_connector3.py
 
 
 endif
 endif
 
 
-CLEANFILES = kea-shell kea-shell.pyc
-
+CLEANFILES = *.pyc
 
 
 man_MANS = kea-shell.8
 man_MANS = kea-shell.8
 DISTCLEANFILES = $(man_MANS)
 DISTCLEANFILES = $(man_MANS)
@@ -38,13 +37,6 @@ $(man_MANS):
 
 
 endif
 endif
 
 
-# This is done here since configure.ac AC_OUTPUT doesn't expand certain variables.
-kea-shell: kea-shell.py
-	$(SED) "s|@@PYTHONPATH@@|@pyexecdir@|" kea-shell.py > kea-shell.tmp
-	$(SED) "s|REPORTED_VERSION|@PACKAGE_VERSION@|" kea-shell.tmp >$@
-	rm -f kea-shell.tmp
-	chmod a+x $@
-
 install-data-local:
 install-data-local:
 	$(mkinstalldirs) $(DESTDIR)/@localstatedir@/@PACKAGE@
 	$(mkinstalldirs) $(DESTDIR)/@localstatedir@/@PACKAGE@
 
 

+ 112 - 0
src/bin/shell/kea-shell.in

@@ -0,0 +1,112 @@
+#!@PYTHON@
+
+# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+"""
+Text client for Control Agent process
+"""
+
+# First, let's import the right kea_connector.
+# We have two versions: one for python 2.x and another for python 3.x.
+# Sadly, there's no unified way to handle http connections. The recommended
+# way is to use Requests (http://docs.python-requests.org/en/master/), but
+# that's a stand alone package that requires separate installation. One of
+# the design requirements was to not require any additional packages, so
+# the code uses standard libraries available in python. Hence two versions.
+import sys
+import signal
+import argparse
+
+from kea_conn import CARequest # CAResponse
+
+if sys.version_info[0] == 2:
+    # This is Python 2.x
+    import kea_connector2 as kea_connector
+elif sys.version_info[0] == 3:
+    # This is Python 3.x
+    import kea_connector3 as kea_connector
+else:
+    # This is... have no idea what it is.
+    raise SystemExit("Unknown python version:" + str(sys.version_info[0]))
+
+def timeout_handler(signum, frame):
+    """Connection timeoout handler"""
+    del signum, frame
+    print("Connection timeout")
+    sys.exit(1)
+
+VERSION = "@PACKAGE_VERSION@"
+
+def shell_body():
+    """
+    Second step: Need to parse command line parameters. We will use
+    argparse for that purpose. It does great job with having default
+    values, taking care of the help and sanity checking input
+    parameters.
+    """
+    parser = argparse.ArgumentParser(description='kea-shell is a simple text '
+                                     'client that uses REST interface to '
+                                     'connect to Kea Control Agent.')
+    parser.add_argument('--host', type=str, default='127.0.0.1',
+                        help='hostname of the CA to connect to '
+                        '(defaul:; 127.0.0.1)')
+    parser.add_argument('--port', type=int, default=8000,
+                        help='TCP port of the CA to connect to '
+                        '(default: 8000)')
+    parser.add_argument('--timeout', type=int, default='10',
+                        help='Timeout (in seconds) when attempting to '
+                        'connect to CA (default: 10)')
+    parser.add_argument('command', type=str, nargs="?",
+                        default='list-commands',
+                        help='command to be executed. If not specified, '
+                        '"list-commands" is used')
+    parser.add_argument('-v', action="store_true", help="Prints version")
+    cmd_args = parser.parse_args()
+
+    if cmd_args.v:
+        print(VERSION)
+        exit(0)
+
+    # Ok, now time to put the parameters parsed into the structure to be
+    # used by the connection.
+    params = CARequest()
+    params.command = cmd_args.command
+    params.http_host = cmd_args.host
+    params.http_port = cmd_args.port
+    params.timeout = cmd_args.timeout
+    params.version = VERSION
+
+    params.generate_body()
+    params.generate_headers()
+
+    # Load command processor
+    # @todo - command specific processing will be added as part of
+    # future work (either #5138 or #5139, whichever is implemented
+    # first)
+
+    # Read parameters from stdin (they're optional for some commands)
+    for line in sys.stdin:
+        params.params += line
+
+    # Set the timeout timer. If the connection takes too long,
+    # it will send a signal to us.
+    signal.signal(signal.SIGALRM, timeout_handler)
+    signal.alarm(params.timeout)
+
+    # Ok, everything is ready. Let's send the command and get a response.
+    try:
+        resp = kea_connector.send_to_control_agent(params)
+    except Exception as exc:
+        print("Failed to run: " + str(exc))
+        sys.exit(1)
+
+    resp.print_response()
+
+    sys.exit(0)
+
+if __name__ == "__main__":
+    shell_body()

+ 0 - 92
src/bin/shell/kea-shell.py

@@ -1,92 +0,0 @@
-#!/usr/bin/python
-
-# This is going to be replaced with the actual version (see kea-shell target
-# in Makefile.am)
-VERSION = "REPORTED_VERSION"
-
-# First, let's import the right kea_connector.
-# We have two versions: one for python 2.x and another for python 3.x.
-# Sadly, there's no unified way to handle http connections. The recommended
-# way is to use Requests (http://docs.python-requests.org/en/master/), but
-# that's a stand alone package that requires separate installation. One of
-# the design requirements was to not require any additional packages, so
-# the code uses standard libraries available in python. Hence two versions.
-import sys
-import signal
-import argparse
-
-if (sys.version_info[0] == 2):
-    # This is Python 2.x
-    import kea_connector2 as kea_connector
-else:
-    if (sys.version_info[0] == 3):
-        # This is Python 3.x
-        import kea_connector3 as kea_connector
-    else:
-        # This is... have no idea what it is.
-        raise SystemExit("Unknown python version:" + str(sys.version_info[0]))
-
-from kea_conn import CARequest, CAResponse
-
-# Second step: Need to parse command line parameters. We will use argparse for
-# that purpose. It does great job with having default values, taking care of
-# the help and sanity checking input parameters.
-
-parser = argparse.ArgumentParser(description='kea-shell is a simple text client that uses REST '
-                                 'interface to connect to Kea Control Agent.')
-parser.add_argument('--host', type=str, default='127.0.0.1',
-                    help='hostname of the CA to connect to (default; 127.0.0.1)')
-parser.add_argument('--port', type=int, default=8000,
-                    help='TCP port of the CA to connect to (default: 8000)')
-parser.add_argument('--timeout', type=int, default='10',
-                    help='Timeout (in seconds) when attempting to connect to CA (default: 10)')
-parser.add_argument('command', type=str, nargs="?", default='list-commands',
-                    help='command to be executed. If not specified, "list-commands" is used')
-parser.add_argument('-v', action="store_true", help="Prints version")
-cmd_args = parser.parse_args()
-
-if (cmd_args.v):
-    print (VERSION)
-    exit(0)
-
-# Ok, now time to put the parameters parsed into the structure to be used by the
-# connection.
-params = CARequest()
-params.command = cmd_args.command
-params.http_host = cmd_args.host
-params.http_port = cmd_args.port
-params.timeout = cmd_args.timeout
-params.version = VERSION
-
-params.generateBody()
-params.generateHeaders()
-
-conn = kea_connector.KeaConnector()
-
-def timeout_handler(signum, frame):
-    print ("Connection timeout")
-    sys.exit(1)
-
-# Load command processor
-# @todo - command specific processing will be added as part of future work
-# (either #5138 or #5139, whichever is implemented first)
-
-# Read parameters from stdin (they're optional for some commands)
-for line in sys.stdin:
-    params.params += line
-
-# Set the timeout timer. If the connection takes too long,
-# it will send a signal to us.
-signal.signal(signal.SIGALRM, timeout_handler)
-signal.alarm(params.timeout)
-
-# Ok, everything is ready. Let's send the command and get a response.
-try:
-    resp = conn.sendCA(params)
-except Exception as e:
-    print("Failed to run: " + str(e))
-    sys.exit(1)
-
-resp.printResp()
-
-sys.exit(0)

+ 8 - 7
src/bin/shell/kea-shell.xml

@@ -49,9 +49,10 @@
     <cmdsynopsis>
     <cmdsynopsis>
       <command>kea-shell</command>
       <command>kea-shell</command>
       <arg><option>-h</option></arg>
       <arg><option>-h</option></arg>
+      <arg><option>-v</option></arg>
       <arg><option>--host</option></arg>
       <arg><option>--host</option></arg>
       <arg><option>--port</option></arg>
       <arg><option>--port</option></arg>
-      <arg><option>-v</option></arg>
+      <arg><option>--timeout</option></arg>
       <arg><option>command</option></arg>
       <arg><option>command</option></arg>
     </cmdsynopsis>
     </cmdsynopsis>
   </refsynopsisdiv>
   </refsynopsisdiv>
@@ -64,8 +65,8 @@
       Kea Control Agent (CA). It takes command as a command-line parameter
       Kea Control Agent (CA). It takes command as a command-line parameter
       that is being sent to CA with proper JSON
       that is being sent to CA with proper JSON
       encapsulation. Optional parameters may be specified on the
       encapsulation. Optional parameters may be specified on the
-      stdin. The request it sent of HTTP and a response is
-      retrieved. That response is printed out on stdout.
+      standard input. The request it sent of HTTP and a response is
+      retrieved. That response is displayed out on the standard output.
     </para>
     </para>
 
 
   </refsect1>
   </refsect1>
@@ -78,16 +79,16 @@
     <variablelist>
     <variablelist>
 
 
       <varlistentry>
       <varlistentry>
-        <term><option>-v</option></term>
+        <term><option>-h</option></term>
         <listitem><para>
         <listitem><para>
-          Display the version.
+          Displays help regarding command line parameters.
         </para></listitem>
         </para></listitem>
       </varlistentry>
       </varlistentry>
 
 
       <varlistentry>
       <varlistentry>
-        <term><option>-h</option></term>
+        <term><option>-v</option></term>
         <listitem><para>
         <listitem><para>
-          Displays help regarding command line parameters.
+          Display the version.
         </para></listitem>
         </para></listitem>
       </varlistentry>
       </varlistentry>
 
 

+ 53 - 35
src/bin/shell/kea_conn.py

@@ -1,17 +1,25 @@
-#!/usr/bin/python
+# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-# This file contains classes used for communication with Control Agent.
+"""
+This file contains classes used for communication with Control Agent.
+"""
 
 
-# This class defines the HTTP request to be sent.
-# The supported parameters listed are:
-# - path (specifies the path on the server, CA uses only /)
-# - http_host - hostname of the CA
-# - http-port - TCP port of the CA
-# - command - specifies the command to send (e.g. list-commands)
-# - timeout - timeout (in ms)
-# - headers - extra HTTP headers may be added here
-# - version - version to be reported in HTTP header
 class CARequest:
 class CARequest:
+    """
+    This class defines the HTTP request to be sent.
+    The supported parameters listed are:
+     - path (specifies the path on the server, CA uses only /)
+     - http_host - hostname of the CA
+     - http-port - TCP port of the CA
+     - command - specifies the command to send (e.g. list-commands)
+     - timeout - timeout (in ms)
+     - headers - extra HTTP headers may be added here
+     - version - version to be reported in HTTP header
+    """
     path = '/'
     path = '/'
     http_host = ''
     http_host = ''
     http_port = 0
     http_port = 0
@@ -20,39 +28,47 @@ class CARequest:
     params = ''
     params = ''
     headers = {}
     headers = {}
     version = ""
     version = ""
+    # This is a storage for generated command (input data to be sent over POST)
+    content = ''
 
 
-    # Generates the content, out of specified command line
-    # and optional content.
-    # @todo: Add support for parameters
-    # this stores the output in self.content
-    def generateBody(self):
+    def generate_body(self):
+        """
+        Generates the content, out of specified command line
+        and optional content.
+        @todo: Add support for parameters
+        this stores the output in self.content
+        """
         self.content = '{ "command": "' + self.command + '"'
         self.content = '{ "command": "' + self.command + '"'
-        if (len(self.params)):
+        if len(self.params):
             self.content += ', "parameters": { ' + self.params + ' }'
             self.content += ', "parameters": { ' + self.params + ' }'
         self.content += ' }'
         self.content += ' }'
 
 
-    # Generate HTTP headers
-    #
-    # In particular, this method generates Content-Length and its value.
-    def generateHeaders(self):
+    def generate_headers(self):
+        """
+        Generate HTTP headers
+
+        In particular, this method generates Content-Length and its value.
+        """
         self.headers['Content-Type'] = 'application/json'
         self.headers['Content-Type'] = 'application/json'
         self.headers['User-Agent'] = "Kea-shell/%s"%(self.version)
         self.headers['User-Agent'] = "Kea-shell/%s"%(self.version)
         self.headers['Accept'] = '*/*'
         self.headers['Accept'] = '*/*'
         self.headers['Content-Length'] = "%d"%(len(self.content))
         self.headers['Content-Length'] = "%d"%(len(self.content))
 
 
-    # This is a storage for generated command (input data to be sent over POST)
-    content = ''
 
 
-# This class represents the HTTP response
 class CAResponse:
 class CAResponse:
+    """
+    This class represents the HTTP response
+    """
 
 
-    # Constructor
-    #
-    # Three mandatory parameters are:
-    # status - numerical number the describe the status (e.g. 200 = OK)
-    # reason - textual explanation of what happened
-    # body - the actual body structure of the response
     def __init__(self, status, reason, body):
     def __init__(self, status, reason, body):
+        """
+        Constructor
+
+        Three mandatory parameters are:
+         status - numerical number the describe the status (e.g. 200 = OK)
+         reason - textual explanation of what happened
+         body - the actual body structure of the response
+        """
         self.status = status
         self.status = status
         self.reason = reason
         self.reason = reason
         self.body = body
         self.body = body
@@ -61,11 +77,13 @@ class CAResponse:
     reason = ''
     reason = ''
     body = ''
     body = ''
 
 
-    # Used for debugging
-    #
-    # if defug is true, this prints even more information
-    def printResp(self, debug = False):
-        if (debug):
+    def print_response(self, debug=False):
+        """
+        Used for debugging
+
+        if debug is true, this prints even more information
+        """
+        if debug:
             print(self.status)
             print(self.status)
             print(self.reason)
             print(self.reason)
         print(self.body)
         print(self.body)

+ 29 - 24
src/bin/shell/kea_connector2.py

@@ -1,34 +1,39 @@
-#!/usr/bin/python
+# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-# This is PYTHON 2.x version of HTTP connection establishment
-
-from kea_conn import CARequest, CAResponse
+"""
+This is PYTHON 2.x version of HTTP connection establishment
+"""
 
 
 import httplib
 import httplib
 
 
-class KeaConnector:
-    def sendCA(self, params):
-        # Estalbish HTTP connection first.
-        conn = httplib.HTTPConnection(params.http_host, params.http_port)
-        conn.connect()
+from kea_conn import CAResponse # CARequest
+
+def send_to_control_agent(params):
+    """Establish HTTP connection first."""
+    conn = httplib.HTTPConnection(params.http_host, params.http_port)
+    conn.connect()
 
 
-        # Use POST to send it
-        request = conn.putrequest('POST', params.path)
+    # Use POST to send it
+    _ = conn.putrequest('POST', params.path)
 
 
-        # Send the headers first
-        for k in params.headers:
-            conn.putheader(k, params.headers[k])
-        conn.endheaders()
+    # Send the headers first
+    for k in params.headers:
+        conn.putheader(k, params.headers[k])
+    conn.endheaders()
 
 
-        # Send the content
-        conn.send(params.content)
+    # Send the content
+    conn.send(params.content)
 
 
-        # Now get the response
-        resp = conn.getresponse()
+    # Now get the response
+    resp = conn.getresponse()
 
 
-        # Now get the response details, put it in CAResponse and
-        # return it
-        x = CAResponse(resp.status, resp.reason, resp.read())
-        conn.close()
+    # Now get the response details, put it in CAResponse and
+    # return it
+    result = CAResponse(resp.status, resp.reason, resp.read())
+    conn.close()
 
 
-        return (x)
+    return result

+ 23 - 14
src/bin/shell/kea_connector3.py

@@ -1,20 +1,29 @@
-#!/usr/bin/python
+# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
-from kea_conn import CARequest, CAResponse
+"""
+This is PYTHON 3.x version of HTTP connection establishment
+"""
 
 
 import urllib.request
 import urllib.request
 
 
-class KeaConnector:
-    def sendCA(self, params):
-        # Estalbish HTTP connection first.
-        url = "http://" + params.http_host + ":" + str(params.http_port) + str(params.path)
-        
-        req = urllib.request.Request(url = url, data = str.encode(params.content),
-                                     headers = params.headers)
-        resp = urllib.request.urlopen(req)
+from kea_conn import CAResponse # CARequest
 
 
-        # Now get the response details, put it in CAResponse and
-        # return it
-        x = CAResponse(resp.getcode(), resp.reason, resp.read().decode("utf-8"))
+def send_to_control_agent(params):
+    """Establish HTTP connection first."""
+    url = "http://" + params.http_host + ":"
+    url += str(params.http_port) + str(params.path)
 
 
-        return (x)
+    req = urllib.request.Request(url=url,
+                                 data=str.encode(params.content),
+                                 headers=params.headers)
+    resp = urllib.request.urlopen(req)
+
+    # Now get the response details, put it in CAResponse and return it
+    result = CAResponse(resp.getcode(), resp.reason,
+                        resp.read().decode("utf-8"))
+
+    return result

+ 17 - 12
src/bin/shell/tests/shell_process_tests.sh.in

@@ -36,8 +36,8 @@ CONFIG="{
 }"
 }"
 
 
 # In these tests we need to use two binaries: Control Agent and Kea shell.
 # In these tests we need to use two binaries: Control Agent and Kea shell.
-# Using bin and bin_path would be confusing, so we omit defining bin and bin_path
-# on purpose.
+# Using bin and bin_path would be confusing, so we omit defining bin
+# and bin_path on purpose.
 ca_bin="kea-ctrl-agent"
 ca_bin="kea-ctrl-agent"
 ca_bin_path=@abs_top_builddir@/src/bin/agent
 ca_bin_path=@abs_top_builddir@/src/bin/agent
 
 
@@ -83,8 +83,8 @@ shell_command_test() {
     # of configuration failure).
     # of configuration failure).
     get_pid ${ca_bin}
     get_pid ${ca_bin}
     if [ ${_GET_PIDS_NUM} -ne 1 ]; then
     if [ ${_GET_PIDS_NUM} -ne 1 ]; then
-        printf "ERROR: expected one Control Agent process to be started. Found %d processes\
- started.\n" ${_GET_PIDS_NUM}
+        printf "ERROR: expected one Control Agent process to be started.\
+ Found %d processes started.\n" ${_GET_PIDS_NUM}
         clean_exit 1
         clean_exit 1
     fi
     fi
 
 
@@ -92,22 +92,26 @@ shell_command_test() {
     # It should be just once on startup.
     # It should be just once on startup.
     get_reconfigs
     get_reconfigs
     if [ ${_GET_RECONFIGS} -ne 1 ]; then
     if [ ${_GET_RECONFIGS} -ne 1 ]; then
-        printf "ERROR: server been configured ${_GET_RECONFIGS} time(s), but exactly 1 was expected.\n"
+        printf "ERROR: server been configured ${_GET_RECONFIGS} time(s),\
+ but exactly 1 was expected.\n"
         clean_exit 1
         clean_exit 1
     else
     else
         printf "Server successfully configured.\n"
         printf "Server successfully configured.\n"
     fi
     fi
 
 
     # Main test phase: send command, check response.
     # Main test phase: send command, check response.
-    tmp="echo \"${params}\" | ${shell_bin_path}/${shell_bin} --host 127.0.0.1 --port 8081 ${cmd} > ${tmpfile_path}/shell-stdout.txt"
+    tmp="echo \"${params}\" | ${shell_bin_path}/${shell_bin} --host \
+ 127.0.0.1 --port 8081 ${cmd} > ${tmpfile_path}/shell-stdout.txt"
     echo "Executing kea-shell ($tmp)"
     echo "Executing kea-shell ($tmp)"
     
     
-    echo "${params}" | ${shell_bin_path}/${shell_bin} --host 127.0.0.1 --port 8081 ${cmd} > ${tmpfile_path}/shell-stdout.txt
+    echo "${params}" | ${shell_bin_path}/${shell_bin} --host 127.0.0.1 \
+ --port 8081 ${cmd} > ${tmpfile_path}/shell-stdout.txt
 
 
     # Check the exit code
     # Check the exit code
     shell_exit_code=$?
     shell_exit_code=$?
     if [ ${shell_exit_code} -ne 0 ]; then
     if [ ${shell_exit_code} -ne 0 ]; then
-        echo "ERROR: kea-shell returned ${shell_exit_code} exit code, expected 0."
+        echo "ERROR:" \
+	"kea-shell returned ${shell_exit_code} exit code,  expected 0."
     else
     else
         echo "kea-shell returned ${shell_exit_code} exit code as expected."
         echo "kea-shell returned ${shell_exit_code} exit code as expected."
     fi
     fi
@@ -118,7 +122,9 @@ shell_command_test() {
     diff ${tmpfile_path}/shell-stdout.txt ${tmpfile_path}/shell-expected.txt
     diff ${tmpfile_path}/shell-stdout.txt ${tmpfile_path}/shell-expected.txt
     diff_code=$?
     diff_code=$?
     if [ ${diff_code} -ne 0 ]; then
     if [ ${diff_code} -ne 0 ]; then
-        echo "ERROR: content returned is different than expected. See ${tmpfile_path}/shell-*.txt"
+        echo "ERROR:" \
+	"content returned is different than expected." \
+	"See ${tmpfile_path}/shell-*.txt"
         echo "EXPECTED:"
         echo "EXPECTED:"
         cat ${tmpfile_path}/shell-expected.txt
         cat ${tmpfile_path}/shell-expected.txt
         echo "ACTUAL RESULT:"
         echo "ACTUAL RESULT:"
@@ -164,7 +170,8 @@ version_test() {
     if test "${REPORTED_VERSION}" == "${EXPECTED_VERSION}"; then
     if test "${REPORTED_VERSION}" == "${EXPECTED_VERSION}"; then
         test_finish 0
         test_finish 0
     else
     else
-        printf "ERROR: Expected version ${EXPECTED_VERSION}, got ${REPORTED_VERSION}\n"
+        echo "ERROR:" \
+	"Expected version ${EXPECTED_VERSION}, got ${REPORTED_VERSION}"
         test_finish 1
         test_finish 1
     fi
     fi
 }
 }
@@ -174,5 +181,3 @@ shell_command_test "shell.list-commands" "list-commands" \
     "[ { \"arguments\": [ \"list-commands\" ], \"result\": 0 } ]" ""
     "[ { \"arguments\": [ \"list-commands\" ], \"result\": 0 } ]" ""
 shell_command_test "shell.bogus" "give-me-a-beer" \
 shell_command_test "shell.bogus" "give-me-a-beer" \
     "[ { \"result\": 1, \"text\": \"'give-me-a-beer' command not supported.\" } ]" ""
     "[ { \"result\": 1, \"text\": \"'give-me-a-beer' command not supported.\" } ]" ""
-
-

+ 0 - 104
src/bin/shell/tests/shell_unittest.py

@@ -1,104 +0,0 @@
-# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import unittest
-
-from kea_conn import CARequest
-
-class CARequestUnitTest(unittest.TestCase):
-    """
-    This class is dedicated to testing CARequest class. That class
-    is responsible for generation of the body and headers.
-    """
-
-    def setUp(self):
-        """
-        This method is called before each test. Currently it does nothing.
-        """
-        pass
-
-    def test_bodyWithoutParams(self):
-        """
-        This test verifies if the CARequest object generates the request
-        content properly when there are no parameters.
-        """
-
-        x = CARequest()
-        x.command = "foo"
-        x.generateBody()
-        self.assertEqual(x.content, '{ "command": "foo" }')
-
-    def test_bodyWithParams(self):
-        """
-        This test verifies if the CARequest object generates the request
-        content properly when there are parameters.
-        """
-
-        x = CARequest()
-        x.command = "foo"
-        x.params = '"bar": "baz"'
-        x.generateBody()
-        self.assertEqual(x.content, '{ "command": "foo", "parameters": { "bar": "baz" } }')
-
-    def checkHeader(self, headers, header_name, value):
-        """
-        Checks if headers array contains an entry specified by header_name and that
-        its value matches specified value
-        """
-
-        if header_name in headers:
-            if (headers[header_name] == value):
-                return True
-            else:
-                print ("Expected value: " + value + " does not match actual value: "
-                       + headers[header_name])
-            return ()
-        else:
-            print ("Expected header: " + header_name + " missing")
-            return (false)
-
-    def test_headers(self):
-        """
-        This test checks if the headers are generated properly. Note that since
-        the content is not specified, it is 0. Therefore Content-Length is 0.
-        """
-        x = CARequest()
-        x.generateHeaders()
-
-        self.assertTrue(self.checkHeader(x.headers, 'Content-Type', 'application/json'))
-        self.assertTrue(self.checkHeader(x.headers, 'Accept', '*/*'))
-        self.assertTrue(self.checkHeader(x.headers, 'Content-Length', "0"))
-
-    def test_headerLength(self):
-        """
-        This test checks if the headers are generated properly. In this test there
-        is specific content of non-zero length, and its size should be reflected
-        in the header.
-        """
-        x = CARequest()
-        x.content = '{ "command": "foo" }'
-        x.generateHeaders()
-
-        self.assertTrue(self.checkHeader(x.headers, 'Content-Length', str(len(x.content))))
-
-    def test_headerVersion(self):
-        """
-        This test checks if the version reported in HTTP headers is generated properly.
-        """
-        x = CARequest()
-        x.version = "1.2.3"
-        x.generateHeaders()
-        self.assertTrue(self.checkHeader(x.headers, 'User-Agent', 'Kea-shell/1.2.3'))
-
-    def tearDown(self):
-        """
-        This method is called after each test. Currently it does nothing.
-        """
-        pass
-
-
-if __name__ == '__main__':
-    unittest.main()

+ 115 - 0
src/bin/shell/tests/shell_unittest.py.in

@@ -0,0 +1,115 @@
+#!@PYTHON@
+
+# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+"""
+Kea shell unittest (python part)
+"""
+
+import unittest
+
+from kea_conn import CARequest
+
+class CARequestUnitTest(unittest.TestCase):
+    """
+    This class is dedicated to testing CARequest class. That class
+    is responsible for generation of the body and headers.
+    """
+
+    def setUp(self):
+        """
+        This method is called before each test. Currently it does nothing.
+        """
+        pass
+
+    def test_body_without_params(self):
+        """
+        This test verifies if the CARequest object generates the request
+        content properly when there are no parameters.
+        """
+        request = CARequest()
+        request.command = "foo"
+        request.generate_body()
+        self.assertEqual(request.content, '{ "command": "foo" }')
+
+    def test_body_with_params(self):
+        """
+        This test verifies if the CARequest object generates the request
+        content properly when there are parameters.
+        """
+        request = CARequest()
+        request.command = "foo"
+        request.params = '"bar": "baz"'
+        request.generate_body()
+        self.assertEqual(request.content,
+                         '{ "command": "foo", "parameters": { "bar": "baz" } }')
+
+    @staticmethod
+    def check_header(headers, header_name, value):
+        """
+        Checks if headers array contains an entry specified by
+        header_name and that its value matches specified value
+        """
+        if header_name in headers:
+            if headers[header_name] == value:
+                return True
+            else:
+                print("Expected value: " + value +
+                      " does not match actual value: " +
+                      headers[header_name])
+            return False
+        else:
+            print("Expected header: " + header_name + " missing")
+            return False
+
+    def test_headers(self):
+        """
+        This test checks if the headers are generated properly. Note that since
+        the content is not specified, it is 0. Therefore Content-Length is 0.
+        """
+        request = CARequest()
+        request.generate_headers()
+
+        self.assertTrue(self.check_header(request.headers,
+                                          'Content-Type', 'application/json'))
+        self.assertTrue(self.check_header(request.headers,
+                                          'Accept', '*/*'))
+        self.assertTrue(self.check_header(request.headers,
+                                          'Content-Length', '0'))
+
+    def test_header_length(self):
+        """
+        This test checks if the headers are generated properly. In
+        this test there is specific content of non-zero length, and
+        its size should be reflected in the header.
+        """
+        request = CARequest()
+        request.content = '{ "command": "foo" }'
+        request.generate_headers()
+
+        self.assertTrue(self.check_header(request.headers, 'Content-Length',
+                                          str(len(request.content))))
+
+    def test_header_version(self):
+        """
+        This test checks if the version reported in HTTP headers is
+        generated properly.
+        """
+        request = CARequest()
+        request.version = "1.2.3"
+        request.generate_headers()
+        self.assertTrue(self.check_header(request.headers, 'User-Agent',
+                                          'Kea-shell/1.2.3'))
+
+    def tearDown(self):
+        """
+        This method is called after each test. Currently it does nothing.
+        """
+        pass
+
+if __name__ == '__main__':
+    unittest.main()