Commit 324be1ac authored by Jelte Jansen's avatar Jelte Jansen
Browse files

[1678] initial test multiinstance auth only

test fails because of 1705
parent 38fdfa77
{"version": 2, "Auth": {"listen_on": [{"port": 47806, "address": "0.0.0.0"}]}, "Boss": {"components": {"b10-auth": {"kind": "needed", "special": "auth"}, "b10-cmdctl": {"kind": "needed", "special": "cmdctl"}}}}
Feature: Multiple instances
This feature tests whether multiple instances can be run, and whether
removing them does not affect the running of other instances
Scenario: Multiple instances
Given I have bind10 running with configuration multi_instance/multi_auth.config
And bind10 module Auth should be running
# this also checks whether the process is running according to Boss
If I remember the pid of process b10-auth
And remember the pid of process b10-auth-2
A query for example.com should have rcode REFUSED
When I remove bind10 configuration Boss/components value b10-auth-2
Then the pid of process b10-auth should not have changed
# From here on out it fails because of #1705
And a query for example.com should have rcode REFUSED
When I send bind10 the following commands
"""
config add Boss/components b10-auth-2
config set Boss/components/b10-auth-2/special auth
config set Boss/components/b10-auth-2/process b10-auth
config set Boss/components/b10-auth-2/kind needed
config commit
"""
And wait for new bind10 stderr message AUTH_SERVER_STARTED
And remember the pid of process b10-auth-2
Then the pid of process b10-auth should not have changed
A query for example.com should have rcode REFUSED
When I remove bind10 configuration Boss/components value b10-auth
Then the pid of process b10-auth-2 should not have changed
A query for example.com should have rcode REFUSED
......@@ -16,6 +16,7 @@
from lettuce import *
import subprocess
import re
import json
@step('start bind10(?: with configuration (\S+))?' +\
'(?: with cmdctl port (\d+))?' +\
......@@ -167,6 +168,81 @@ def check_bindctl_output(step, stderr, notv, string):
"' was found in bindctl output:\n" +\
output
def parse_bindctl_output_as_data_structure():
"""Helper function for data-related command tests: evaluates the
last output of bindctl as a data structure that can then be
inspected.
If the bindctl output is not valid (json) data, this call will
fail with an assertion failure.
If it is valid, it is parsed and returned as whatever data
structure it represented.
"""
# strip the 'Exit from bindctl' message. Why is it even there?
output = world.last_bindctl_stdout.replace("Exit from bindctl", "")
try:
return json.loads(output)
except ValueError as ve:
assert False, "Last bindctl output does not appear to be a " +\
"parseable data structure: " + str(ve)
@step("remember the pid of process ([\S]+)")
def remember_pid(step, process_name):
"""Stores the PID of the process with the given name as returned by
Boss show_processes command.
Fails if the process with the given name does not appear to exist.
Stores the component_name->pid value in the dict world.process_pids.
This should only be used by the related step
'the pid of process <name> should (not) have changed'
Arguments:
process name ('process <name>') the name of the component to store
the pid of.
"""
step.given('send bind10 the command Boss show_processes')
running_processes = parse_bindctl_output_as_data_structure()
# show_processes output is a list of lists, where the inner lists
# are of the form [ pid, "name" ]
# Not checking data form; errors will show anyway (if these turn
# out to be too vague, we can change this)
found = False
if world.process_pids is None:
world.process_pids = {}
for process in running_processes:
if process[1] == process_name:
world.process_pids[process_name] = process[0]
found = True
assert found, "Process named " + process_name +\
" not found in output of Boss show_processes";
@step('pid of process ([\S]+) should not have changed')
def check_pid(step, process_name):
"""Checks the PID of the process with the given name as returned by
Boss show_processes command.
Fails if the process with the given name does not appear to exist.
Fails if the process with the given name exists, but has a different
pid than it had when the step 'remember the pid of process' was
called.
Fails if that step has not been called (since world.process_pids
does not exist).
"""
step.given('send bind10 the command Boss show_processes')
running_processes = parse_bindctl_output_as_data_structure()
# show_processes output is a list of lists, where the inner lists
# are of the form [ pid, "name" ]
# Not checking data form; errors will show anyway (if these turn
# out to be too vague, we can change this)
found = False
assert world.process_pids is not None, "No process pids stored"
assert process_name in world.process_pids, "Process named " +\
process_name +\
" was not stored"
for process in running_processes:
if process[1] == process_name:
assert world.process_pids[process_name] == process[0]
found = True
assert found, "Process named " + process_name +\
" not found in output of Boss show_processes";
@step('set bind10 configuration (\S+) to (.*)(?: with cmdctl port (\d+))?')
def config_set_command(step, name, value, cmdctl_port):
"""
......@@ -183,6 +259,20 @@ def config_set_command(step, name, value, cmdctl_port):
"quit"]
run_bindctl(commands, cmdctl_port)
@step('send bind10 the following commands(?: with cmdctl port (\d+))?')
def send_multiple_commands(step, cmdctl_port):
"""
Run bindctl, and send it the given multiline set of commands.
A quit command is always appended.
cmdctl_port ('with cmdctl port <portnr>', optional): cmdctl port to send
the command to. Defaults to 47805.
Fails if cmdctl does not exit with status code 0.
"""
commands = step.multiline.split("\n")
# Always add quit
commands.append("quit")
run_bindctl(commands, cmdctl_port)
@step('remove bind10 configuration (\S+)(?: value (\S+))?(?: with cmdctl port (\d+))?')
def config_remove_command(step, name, value, cmdctl_port):
"""
......
......@@ -45,7 +45,9 @@ copylist = [
["configurations/example.org.config.orig",
"configurations/example.org.config"],
["configurations/resolver/resolver_basic.config.orig",
"configurations/resolver/resolver_basic.config"]
"configurations/resolver/resolver_basic.config"],
["configurations/multi_instance/multi_auth.config.orig",
"configurations/multi_instance/multi_auth.config"]
]
# This is a list of files that, if present, will be removed before a scenario
......@@ -343,6 +345,10 @@ def initialize(scenario):
# Convenience variable to access the last query result from querying.py
world.last_query_result = None
# For slightly better errors, initialize a process_pids for the relevant
# steps
world.process_pids = None
# Some tests can modify the settings. If the tests fail half-way, or
# don't clean up, this can leave configurations or data in a bad state,
# so we copy them from originals before each scenario
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment