[Pkg-privacy-commits] [onionbalance] 87/117: Add functional tests which run the onionbalance-config tool

Donncha O'Cearbahill donncha-guest at moszumanska.debian.org
Wed Dec 16 23:18:51 UTC 2015


This is an automated email from the git hooks/post-receive script.

donncha-guest pushed a commit to branch debian/sid
in repository onionbalance.

commit 6e02cc0cdabd9ea28f35a0b842d7f62fc032519c
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date:   Fri Jul 3 16:12:18 2015 +0100

    Add functional tests which run the onionbalance-config tool
    
    Squashed commit of the following:
    
    commit 47544997963e5fdb0ca542b63a27416407ef7e2d
    Author: Donncha O'Cearbhaill <donncha at donncha.is>
    Date:   Fri Jul 3 15:50:02 2015 +0100
    
        Add functional tests which run the onionbalance-config tool
    
    commit e08330aae9429c2d81154d78f4b93291cf60e56e
    Author: Donncha O'Cearbhaill <donncha at donncha.is>
    Date:   Fri Jul 3 14:40:20 2015 +0100
    
        Fix bug when generating service port line in non-interactive mode
    
    commit d842fb39754dcd44976f4c3f1bae74ad19275541
    Author: Donncha O'Cearbhaill <donncha at donncha.is>
    Date:   Thu Jul 2 10:48:09 2015 +0100
    
        Improve UI when specifying hidden service virtual port and target in onionbalance-config
---
 onionbalance/settings.py                    |  38 +++++--
 test/functional/test_onionbalance_config.py | 154 ++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 9 deletions(-)

diff --git a/onionbalance/settings.py b/onionbalance/settings.py
index e3c7897..4e9eed1 100644
--- a/onionbalance/settings.py
+++ b/onionbalance/settings.py
@@ -144,10 +144,16 @@ def parse_cmd_args():
                         "in ascending order: debug, info, warning, error, "
                         "critical).  The default is info.")
 
-    parser.add_argument("--service-port-line", type=str,
-                        default="HiddenServicePort 80 127.0.0.1:80",
-                        help="Port line for each instance's torrc file "
-                        "(default: %(default)s).")
+    parser.add_argument("--service-virtual-port", type=str,
+                        default="80",
+                        help="Onion service port for external client "
+                        "connections (default: %(default)s).")
+
+    # TODO: Add validator to check if the target host:port line makes sense.
+    parser.add_argument("--service-target", type=str,
+                        default="127.0.0.1:80",
+                        help="Target IP and port where your service is "
+                        "listening (default: %(default)s).")
 
     # .. todo:: Add option to specify HS host and port for instance torrc
 
@@ -257,12 +263,26 @@ def generate_config():
                     "[{}]: ".format(args.tag))
     tag = tag or args.tag
 
-    torrc_port_line = None
+    # Create HiddenServicePort line for instance torrc file
+    service_virtual_port = None
+    if interactive:
+        service_virtual_port = input("Specify the service virtual port (for "
+                                     "client connections) [{}]: ".format(
+                                         args.service_virtual_port))
+    service_virtual_port = service_virtual_port or args.service_virtual_port
+
+    service_target = None
     if interactive:
-        torrc_port_line = input("Specify a HiddenServicePort option for each "
-                                "instance's torrc file [{}]: ".format(
-                                    args.service_port_line))
-    torrc_port_line = torrc_port_line or args.service_port_line
+        # In interactive mode, change default target to match the specified
+        # virtual port
+        default_service_target = u'127.0.0.1:{}'.format(service_virtual_port)
+        service_target = input("Specify the service target IP and port (where "
+                               "your service is listening) [{}]: ".format(
+                                   default_service_target))
+        service_target = service_target or default_service_target
+    service_target = service_target or args.service_target
+    torrc_port_line = u'HiddenServicePort {} {}'.format(service_virtual_port,
+                                                        service_target)
 
     instances = []
     for i in range(0, num_instances):
diff --git a/test/functional/test_onionbalance_config.py b/test/functional/test_onionbalance_config.py
new file mode 100644
index 0000000..00a1729
--- /dev/null
+++ b/test/functional/test_onionbalance_config.py
@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*-
+"""
+Functional tests which run the onionbalance-config tool and check
+the created output files.
+"""
+import sys
+
+import pexpect
+import Crypto.PublicKey.RSA
+
+import onionbalance.util
+
+
+def onionbalance_config_interact(cli, cli_input):
+    """
+    Send each input line to the onionbalance-config CLI interface
+    """
+    cli.expect(u"store generated config")
+    cli.send("{}\n".format(cli_input.get('config_dir', u'')))
+
+    cli.expect(u"path to master service private key")
+    cli.send(u"{}\n".format(cli_input.get('private_key_path', u'')))
+
+    cli.expect(u"Number of instance services")
+    cli.send(u"{}\n".format(cli_input.get('num_instances', u'')))
+
+    cli.expect(u"Provide a tag name")
+    cli.send(u"{}\n".format(cli_input.get('tag_name', u'')))
+
+    cli.expect(u"service virtual port")
+    cli.send(u"{}\n".format(cli_input.get('virtual_port', u'')))
+
+    cli.expect(u"service target IP and port")
+    cli.send(u"{}\n".format(cli_input.get('target_ip', u'')))
+
+    cli.expect(u"optional password")
+    cli.send(u"{}\n".format(cli_input.get('password', u'')))
+
+    return None
+
+
+def check_basic_config_output(config_dir):
+    """
+    Run basic tests on the generated config files and keys to check
+    that they look reasonable.
+    """
+
+    assert len(config_dir.listdir()) == 1 + 2
+
+    # Find generated instance addresses
+    instance_addresses = []
+    for directory in config_dir.listdir():
+        if directory.basename != 'master':
+            instance_addresses.extend(
+                [str(name.basename) for name in directory.listdir()
+                 if 'torrc' not in name.basename])
+
+    # Correct number of directories created
+    assert len(config_dir.listdir()) == 1 + 2
+
+    assert config_dir.join('master', 'torrc-server').check()
+    assert config_dir.join('master', 'config.yaml').check()
+
+    config_file = config_dir.join('master', 'config.yaml').read_text('utf-8')
+    assert all(address in config_file for address in instance_addresses)
+
+    return True
+
+
+def test_onionbalance_config_interactive(tmpdir):
+    """
+    Functional test to run onion-balance config in interactive mode.
+    """
+    # Start onionbalance-config in interactive mode (no command line arguments)
+    cli = pexpect.spawnu("onionbalance-config", logfile=sys.stdout)
+    cli.expect(u"entering interactive mode")
+
+    # Interact with the running onionbalance-config process
+    onionbalance_config_interact(
+        cli, cli_input={'config_dir': str(tmpdir.join(u"configdir"))})
+    cli.expect(u"Done! Successfully generated")
+
+    check_basic_config_output(tmpdir.join(u"configdir"))
+
+
+def test_onionbalance_config_automatic(tmpdir):
+    """
+    Functional test to run onion-balance config in automatic mode.
+    """
+    # Start onionbalance-config in automatic mode
+    cli = pexpect.spawnu("onionbalance-config", logfile=sys.stdout,
+                         args=[
+                             '--output', str(tmpdir.join(u"configdir")),
+                         ])
+    cli.expect(u"Done! Successfully generated")
+
+    check_basic_config_output(tmpdir.join(u"configdir"))
+
+
+def test_onionbalance_config_automatic_custom_ports(tmpdir):
+    """
+    Run onionbalance-config in interactive mode, providing a custom port line.
+    """
+    cli = pexpect.spawnu("onionbalance-config", logfile=sys.stdout,
+                         args=[
+                             '--output', str(tmpdir.join(u"configdir")),
+                             '--service-virtual-port', u'443',
+                             '--service-target', u'127.0.0.1:8443',
+                         ])
+    cli.expect(u"Done! Successfully generated")
+
+    # Read one of the generated torrc files
+    for directory in tmpdir.join(u"configdir").listdir():
+        if directory.basename != 'master':
+            torrc_file = [name for name in directory.listdir()
+                          if name.basename == 'instance_torrc'][0]
+            break
+    assert torrc_file.check()
+
+    # Check torrc line contains the correct HiddenServicePort line
+    torrc_contents = torrc_file.read_text('utf-8')
+    assert u'HiddenServicePort 443 127.0.0.1:8443' in torrc_contents
+
+
+def test_onionbalance_config_automatic_key_with_password(tmpdir, mocker):
+    """
+    Run onionbalance-config with an existing key, export as password protected
+    key.
+    """
+
+    # Create input private_key
+    private_key = Crypto.PublicKey.RSA.generate(1024)
+    key_path = tmpdir.join('private_key')
+    key_path.write(private_key.exportKey())
+
+    # Start onionbalance-config in automatic mode
+    cli = pexpect.spawnu("onionbalance-config", logfile=sys.stdout,
+                         args=[
+                             '--output', str(tmpdir.join(u"configdir")),
+                             '--key', str(key_path),
+                             '--password', 'testpassword',
+                         ])
+    cli.expect(u"Done! Successfully generated")
+
+    # Check master config was generated with password protected key.
+    master_dir = tmpdir.join('configdir', 'master')
+    output_key_path = [fpath for fpath in master_dir.listdir()
+                       if fpath.ext == '.key'][0]
+    assert output_key_path.check()
+
+    # Check key decrypts and is valid
+    mocker.patch('getpass.getpass', lambda *_: 'testpassword')
+    output_key = onionbalance.util.key_decrypt_prompt(str(output_key_path))
+    assert isinstance(output_key, Crypto.PublicKey.RSA._RSAobj)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onionbalance.git



More information about the Pkg-privacy-commits mailing list