Enforce data-type checks for step matcher

and increase default timeout for patroni start
This commit is contained in:
Alexander Kukushkin
2016-03-11 14:46:14 +01:00
parent 8b81d270bc
commit 5f6beae22f
4 changed files with 40 additions and 26 deletions
+3 -3
View File
@@ -1,8 +1,8 @@
import os.path
import os
import psycopg2
import requests
import subprocess
import shutil
import subprocess
import tempfile
import time
import yaml
@@ -50,7 +50,7 @@ class PatroniController(object):
return None
return content.strip()
def start(self, pg_name, max_wait_limit=15, tags=None):
def start(self, pg_name, max_wait_limit=20, tags=None):
if not self._is_running(pg_name):
if pg_name in self._processes:
del self._processes[pg_name]
+8 -8
View File
@@ -4,22 +4,22 @@ from behave import step, then
from time import sleep, time
@step('I start {name}')
@step('I start {name:w}')
def start_patroni(context, name):
return context.pctl.start(name)
@step('I shut down {name}')
@step('I shut down {name:w}')
def stop_patroni(context, name):
return context.pctl.stop(name)
@step('I kill {name}')
@step('I kill {name:w}')
def kill_patroni(context, name):
return context.pctl.stop(name, kill=True)
@step('I add the table {table_name} to {pg_name}')
@step('I add the table {table_name:w} to {pg_name:w}')
def add_table(context, table_name, pg_name):
# parse the configuration file and get the port
try:
@@ -28,7 +28,7 @@ def add_table(context, table_name, pg_name):
assert False, "Error creating table {0} on {1}: {2}".format(table_name, pg_name, e)
@then('Table {table_name} is present on {pg_name} after {max_replication_delay} seconds')
@then('Table {table_name:w} is present on {pg_name:w} after {max_replication_delay:d} seconds')
def table_is_present_on(context, table_name, pg_name, max_replication_delay):
for _ in range(int(max_replication_delay)):
if context.pctl.query(pg_name, "SELECT 1 FROM {0}".format(table_name), fail_ok=True) is not None:
@@ -39,15 +39,15 @@ def table_is_present_on(context, table_name, pg_name, max_replication_delay):
"Table {0} is not present on {1} after {2} seconds".format(table_name, pg_name, max_replication_delay)
@then('{pg_name} role is the {pg_role} after {max_promotion_timeout} seconds')
@then('{pg_name:w} role is the {pg_role:w} after {max_promotion_timeout:d} seconds')
def check_role(context, pg_name, pg_role, max_promotion_timeout):
if not context.pctl.check_role_has_changed_to(pg_name, pg_role, timeout=int(max_promotion_timeout)):
assert False,\
"{0} role didn't change to {1} after {2} seconds".format(pg_name, pg_role, max_promotion_timeout)
@step('replication works from {master} to {replica} after {time_limit} seconds')
@then('replication works from {master} to {replica} after {time_limit} seconds')
@step('replication works from {master:w} to {replica:w} after {time_limit:d} seconds')
@then('replication works from {master:w} to {replica:w} after {time_limit:d} seconds')
def replication_works(context, master, replica, time_limit):
context.execute_steps(u"""
When I add the table test_{0} to {1}
+3 -3
View File
@@ -1,17 +1,17 @@
from behave import step, then
@step('I configure and start {name} with a tag {tag_name} {tag_value}')
@step('I configure and start {name:w} with a tag {tag_name:w} {tag_value:w}')
def start_patroni_with_a_name_value_tag(context, name, tag_name, tag_value):
return context.pctl.start(name, tags={tag_name: tag_value})
@then('There is a label with "{content}" in {name} data directory')
@then('There is a label with "{content:w}" in {name:w} data directory')
def check_label(context, content, name):
label = context.pctl.read_label(name)
assert label == content, "{0} is not equal to {1}".format(label, content)
@step('I create label with "{content}" in {name} data directory')
@step('I create label with "{content:w}" in {name:w} data directory')
def write_label(context, content, name):
context.pctl.write_label(name, content)
+26 -12
View File
@@ -1,9 +1,23 @@
import time
import parse
import pytz
import requests
import time
from behave import register_type, step, then
from datetime import datetime, timedelta
from behave import step, then
@parse.with_pattern(r'https?://(?:\w|\.|:|/)+')
def parse_url(text):
return text
@parse.with_pattern(r'(?:\w+=(?:\w|\.|:|-|\+|\s)+,?)+')
def parse_data(text):
return text
register_type(url=parse_url, data=parse_data)
# there is no way we can find out if the node has already
@@ -11,8 +25,8 @@ from behave import step, then
# just rely on the database availability, since there is
# a short gap between the time PostgreSQL becomes available
# and Patroni assuming the leader role.
@step('{name} is a leader after {time_limit} seconds')
@then('{name} is a leader after {time_limit} seconds')
@step('{name:w} is a leader after {time_limit:d} seconds')
@then('{name:w} is a leader after {time_limit:d} seconds')
def is_a_leader(context, name, time_limit):
max_time = time.time() + int(time_limit)
while (context.etcd_ctl.query("leader") != name):
@@ -21,12 +35,12 @@ def is_a_leader(context, name, time_limit):
assert False, "{0} is not a leader in etcd after {1} seconds".format(name, time_limit)
@step('I sleep for {value} seconds')
@step('I sleep for {value:d} seconds')
def sleep_for_n_seconds(context, value):
time.sleep(int(value))
@step('I issue a GET request to {url}')
@step('I issue a GET request to {url:url}')
def do_get(context, url):
try:
r = requests.get(url)
@@ -41,12 +55,12 @@ def do_get(context, url):
context.response = r.content.decode('utf-8')
@step('I issue an empty POST request to {url}')
@step('I issue an empty POST request to {url:url}')
def do_post_empty(context, url):
do_post(context, url, None)
@step('I issue a POST request to {url} with {data}')
@step('I issue a POST request to {url:url} with {data:data}')
def do_post(context, url, data):
post_data = {}
if data:
@@ -68,7 +82,7 @@ def do_post(context, url, data):
context.response = r.content.decode('utf-8')
@then('I receive a response {component} {data}')
@then('I receive a response {component:w} {data}')
def check_response(context, component, data):
if component == 'code':
assert context.status_code == int(data),\
@@ -80,8 +94,8 @@ def check_response(context, component, data):
assert context.response[component] == data, "{0} does not contain {1}".format(component, data)
@step('I issue a scheduled failover at {at_url} from {from_host} to {to_host} in {in_seconds} seconds')
def scheduld_failover(context, at_url, from_host, to_host, in_seconds):
context.execute_steps("""
@step('I issue a scheduled failover at {at_url:url} from {from_host:w} to {to_host:w} in {in_seconds:d} seconds')
def scheduled_failover(context, at_url, from_host, to_host, in_seconds):
context.execute_steps(u"""
Given I issue a POST request to {0}/failover with leader={1},candidate={2},scheduled_at={3}
""".format(at_url, from_host, to_host, datetime.now(pytz.utc) + timedelta(seconds=int(in_seconds))))