Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #16772: Add an upgrade scenario in rtf #194

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 21 additions & 15 deletions rtf
Expand Up @@ -23,7 +23,7 @@ Usage:
rtf scenario env <platform>
rtf scenario ncf_tests <platform> <version> [--cfengine-version=<cfengine_version>]
rtf scenario ncf_tests <platform> <pull-request-number> [--cfengine-version=<cfengine_version>]
rtf scenario run <platform> <scenario> [--no-finally] [--stop] [--filter=<test1>,<test2>,...] [--format=<format>] [<KEY>=<VALUE>]... [--destroy-on-error]
rtf scenario run <platform> <scenario> [--no-finally] [--stop] [--filter=<test1>,<test2>,...] [--format=<format>] [<KEY>=<VALUE>]... [--destroy-on-error] [--json=<json>]
rtf scenario technique <platform> <directory> [--technique=<pattern>] [--last-version] [--no-finally] [--stop] [--filter=<test1>,<test2>,...] [--format=<format>] [--start=<test number>] [--destroy-on-error]
rtf test from-rule <platform> <uuid> <test_name> [--create-scenario]
rtf test from-directive <platform> <uuid> <test_name> <path>
Expand Down Expand Up @@ -613,6 +613,10 @@ class Platform:
self.hosts = {}
self.plugins = {}
self.provider = "virtualbox"

# Initialized at setup time
script_dir = os.path.dirname(os.path.realpath(__file__))
self.client_path = script_dir + "/rudder-api-client"
# manage default values
default = platform_info['default']

Expand Down Expand Up @@ -702,7 +706,7 @@ class Platform:
# Environment setup
rudder_url = host.get_url()
token = host.run('cat /var/rudder/run/api-token')
setenv(client_path, rudder_url, token)
scenario.lib.setenv(client_path, rudder_url, token)
for relay in relay_list:
# Accept the relay
rcli = "rudder-cli --skip-verify --url=" + rudder_url + " --token=" + token
Expand Down Expand Up @@ -907,7 +911,7 @@ class Platform:
# exit(2)
return (rudder_url, token)

def run_scenario(self, name, frmt, run_finally, err_stop, run_only, client_path, params, startTestNumber, destroyOnError=False):
def run_scenario(self, name, frmt, run_finally, err_stop, run_only, client_path, params, startTestNumber, destroyOnError=False, json_file=None):
""" Run a scenario on this platform """
try:
# test ruby binary
Expand All @@ -934,8 +938,18 @@ class Platform:
kv = param.split('=')
parameters[kv[0]] = kv[1]
scenario.lib.scenario = scenario.lib.Scenario(self, rspec, rcli, frmt, run_only, run_finally, err_stop, parameters, startTestNumber)
setenv(client_path, rudder_url, token)
importlib.import_module("scenario." + name)
scenario.lib.setenv(client_path, rudder_url, token)
module = importlib.import_module("scenario." + name)

scenario_to_run = getattr(module, "Scenario")
if json_file is not None:
with open(json_file) as f:
data = json.load(f)
else:
data = None
s = scenario_to_run(data)
s.run()

if scenario.lib.scenario.errors:
print("Test scenario '"+ name +"' failed on platform '" + self.name + "'")
exit(5)
Expand All @@ -946,7 +960,7 @@ class Platform:
def print_environment(self, client_path):
""" Print environment used to run tests on this platform """
(rudder_url, token) = self.api_connection_info()
setenv(client_path, rudder_url, token)
scenario.lib.setenv(client_path, rudder_url, token)
print("export PATH=" + os.environ['PATH'])
print("export PYTHONPATH=" + os.environ['PYTHONPATH'])
print("export RUDDER_SERVER=" + os.environ['RUDDER_SERVER'])
Expand Down Expand Up @@ -1063,14 +1077,6 @@ The test content has been generated in %s, it contains:
def empty_handler(signum, frame):
pass

def setenv(client_path, url, token):
""" Set environment variables for command calls """
if client_path is not None:
os.environ['PATH'] += ":" + client_path + "/cli"
os.environ['PYTHONPATH'] = client_path + "/lib.python"
os.environ['RUDDER_SERVER'] = url
os.environ['RUDDER_TOKEN'] = token

def load_json(filename):
""" Load a commented json """
# read json from file
Expand Down Expand Up @@ -1383,7 +1389,7 @@ if __name__ == "__main__":
if filter == []:
filter = None
platform = get_platform(args['<platform>'])
platform.run_scenario(args['<scenario>'], args['--format'], not args['--no-finally'], args['--stop'], filter, client_path, args['<KEY>=<VALUE>'], args['--start'], destroyOnError=args['--destroy-on-error'])
platform.run_scenario(args['<scenario>'], args['--format'], not args['--no-finally'], args['--stop'], filter, client_path, args['<KEY>=<VALUE>'], args['--start'], destroyOnError=args['--destroy-on-error'], json_file=args['--json'])
elif args['ncf_tests']:
platform = get_platform(args['<platform>'], {})
platform.setup(client_path)
Expand Down
19 changes: 19 additions & 0 deletions scenario/accept_nodes.py
@@ -0,0 +1,19 @@
"""
Scenario: accept_nodes
Run inventory and accept all agents of the platform
"""
from scenario.lib import *

class Scenario():
def __init__(self, data):
self.data = data
def run(self):
# test begins, register start time
start(__doc__)

# Run inventory and accept nodes
for host in scenario.nodes("agent"):
run_on(host, 'run_agent', Err.CONTINUE, PARAMS="inventory")
run_retry_and_dump('localhost', 'agent_accept', 5, RudderLog.APACHE, ACCEPT=host)

finish()
33 changes: 33 additions & 0 deletions scenario/create_user.py
@@ -0,0 +1,33 @@
"""
Scenario: create_user

Create a user directive with the given name and directive_id.
It will triggers the agents run to apply it.

"""
from scenario.lib import *

class Scenario():
def __init__(self, data):
self.data = data

def run(self):
# test begins, register start time
start(__doc__)

# Add a rule
date0 = host_date('wait', Err.CONTINUE, "server")
run('localhost', 'user_rule', Err.BREAK, NAME="Test User " + self.data['username'], GROUP="special:all", USERNAME=self.data['username'], DIRECTIVE_ID=self.data['directive_id'])
for host in scenario.nodes("agent"):
wait_for_generation('wait', Err.CONTINUE, "server", date0, host, 10)

# Run agent
run_on("server", 'run_agent', Err.CONTINUE, PARAMS="run")
run_and_dump("agent", 'run_agent', Err.CONTINUE, RudderLog.APACHE, PARAMS="update")
run_on("agent", 'run_agent', Err.CONTINUE, PARAMS="run")

# Test rule result
run_on("agent", 'user_test', Err.CONTINUE, USERNAME=self.data['username'])

# test end, print summary
finish()
22 changes: 15 additions & 7 deletions scenario/lib.py
Expand Up @@ -12,7 +12,7 @@
from pprint import pprint

class Scenario:
""" Holds a scenario data
""" Holds a scenario data
Most scenario related methods are global and not in this class to make scenario writing look like script writing
"""
def __init__(self, platform, rspec, rcli, frmt, run_only, run_finally, err_stop, params, startTestNumber):
Expand Down Expand Up @@ -46,7 +46,7 @@ def host_rudder_version(self, hostname):
match = re.match(r'^Rudder agent (\d+)\.(\d+)\..*', version_line)
if match:
return (match.group(1), match.group(2))
else:
else:
return ("", "")

def server_rudder_version(self):
Expand Down Expand Up @@ -95,7 +95,7 @@ def run(target, test, error_mode, **kwargs):

def run_and_dump(target, test, error_mode, rudder_log, **kwargs):
""" Run one test in a scenario and rudder_log <rudder_log> log file if it fails
error_mode can be :
error_mode can be :
- CONTINUE: continue testing even if this fail, should be the default
- BREAK: stop the scenario if this fail, for tests that change a state
- FINALLY: always run this test, for cleaning after a scenario, broken or not
Expand Down Expand Up @@ -345,15 +345,15 @@ def get_tests():
root = os.path.abspath(os.path.dirname(metadata_file))
metadata['local_root'] = root
metadata['remote_root'] = root.replace(technique_root, "/var/rudder/configuration-repository/techniques/")

# make directives path absolute
directives = []
for directive in metadata['directives']:
path = root+'/'+directive
_file_must_exist(path)
directives.append(path)
metadata['directives'] = directives

# make checks path absolute
checks = []
for check in metadata['checks']:
Expand All @@ -367,15 +367,15 @@ def get_tests():
for init in metadata['inits']:
path = root+'/'+init
_file_must_exist(path)
inits.append(path)
inits.append(path)
metadata['inits'] = inits

# make sharedFiles path absolute
sharedFiles = []
for iFile in metadata['sharedFiles']:
path = root+'/'+iFile
_file_must_exist(path)
sharedFiles.append(path)
sharedFiles.append(path)
metadata['sharedFiles'] = sharedFiles

tests.append(metadata)
Expand Down Expand Up @@ -409,3 +409,11 @@ def get_issue_pr(issue):
pr_counter += 1
if pr_counter == 1:
return pr_url

def setenv(client_path, url, token):
""" Set environment variables for command calls """
if client_path is not None:
os.environ['PATH'] += ":" + client_path + "/cli"
os.environ['PYTHONPATH'] = client_path + "/lib.python"
os.environ['RUDDER_SERVER'] = url
os.environ['RUDDER_TOKEN'] = token
119 changes: 62 additions & 57 deletions scenario/ncf_tests.py
Expand Up @@ -11,69 +11,74 @@
import re
from pprint import pprint

# Test begins, register start time
start(__doc__)
need_external_setup = ["ubuntu10_04", "ubuntu12_04", "ubuntu12_10", "ubuntu13_04", "sles11"]
class Scenario():
def __init__(self, data):
self.data = data

def external_setup():
tag = get_param("tag", "")
vagrant_shared = scenario.platform.hosts['agent'].info['sync_file'] if 'sync_file' in scenario.platform.hosts['agent'].info else '/vagrant'
test_shell_on("localhost", "$(pwd)/scripts/external_setup_host " + scenario.pf + " " + tag, live_output=True)
test_shell_on("agent", "mv " + vagrant_shared + "/external_files/" + scenario.pf + "/* /tmp/", live_output=True)
shell_on("agent", "rpm --import /tmp/rudder_rpm_key.pub", live_output=True)
shell_on("agent", "apt-key add /tmp/rudder_apt_key.pub", live_output=True)
return "/tmp/ncf"
def run(self):
# Test begins, register start time
start(__doc__)
need_external_setup = ["ubuntu10_04", "ubuntu12_04", "ubuntu12_10", "ubuntu13_04", "sles11"]

# Get CFEngine version used for the tests
cfengine_version = get_param("cfengine_version", "")
export_prefix = ""
try:
download_user = os.environ['DOWNLOAD_USER']
download_password = os.environ['DOWNLOAD_PASSWORD']
def external_setup():
tag = get_param("tag", "")
vagrant_shared = scenario.platform.hosts['agent'].info['sync_file'] if 'sync_file' in scenario.platform.hosts['agent'].info else '/vagrant'
test_shell_on("localhost", "$(pwd)/scripts/external_setup_host " + scenario.pf + " " + tag, live_output=True)
test_shell_on("agent", "mv " + vagrant_shared + "/external_files/" + scenario.pf + "/* /tmp/", live_output=True)
shell_on("agent", "rpm --import /tmp/rudder_rpm_key.pub", live_output=True)
shell_on("agent", "apt-key add /tmp/rudder_apt_key.pub", live_output=True)
return "/tmp/ncf"

if (download_user):
export_prefix = "export DOWNLOAD_USER=" + download_user + " DOWNLOAD_PASSWORD=" + download_password
except:
export_prefix = ""
# Get CFEngine version used for the tests
cfengine_version = get_param("cfengine_version", "")
export_prefix = ""
try:
download_user = os.environ['DOWNLOAD_USER']
download_password = os.environ['DOWNLOAD_PASSWORD']

# Get setup_ncf
if scenario.platform.hosts ['agent'].info['system'] in need_external_setup:
ncf_version = external_setup()
else:
test_shell_on("agent", "wget -O /tmp/ncf-setup https://repository.rudder.io/tools/ncf-setup", live_output=True)
if (download_user):
export_prefix = "export DOWNLOAD_USER=" + download_user + " DOWNLOAD_PASSWORD=" + download_password
except:
export_prefix = ""

# Get TAG
tag = get_param("tag", "")
# Testing a pull request
if re.match(r"^[0-9]+$", tag):
issue = extract_redmine_issue_infos(tag)
m = re.match(".*/(?P<pull_id>[0-9]+)", get_issue_pr(issue))
redmine_branch = get_issue_rudder_branch(issue)
redmine_version = redmine_branch
pull_id = m.groups('pull_id')[0]
print(pull_id)
if redmine_branch == "master":
branch_version = redmine_branch
agent_version = get_issue_rudder_version(issue) +"-nightly"
else:
ret = requests.get("http://www.rudder-project.org/release-info/rudder/versions/" + redmine_version + "/git_branch")
branch_version = ret.text
agent_version = redmine_version
# Get setup_ncf
if scenario.platform.hosts ['agent'].info['system'] in need_external_setup:
ncf_version = external_setup()
else:
test_shell_on("agent", "wget -O /tmp/ncf-setup https://repository.rudder.io/tools/ncf-setup", live_output=True)

test_shell_on("agent", export_prefix + ";sh /tmp/ncf-setup test-pr https://github.com/Normation/ncf.git#" + branch_version + " ci/rudder-" + agent_version + " " + pull_id + " --testinfra", live_output=True)
# Testing a ncf version
else:
if not cfengine_version:
cfengine_version = "ci/rudder-" + tag + "-nightly"
ret = requests.get("http://www.rudder-project.org/release-info/rudder/versions/" + tag + "/git_branch")
branch_version = ret.text
# Get TAG
tag = get_param("tag", "")
# Testing a pull request
if re.match(r"^[0-9]+$", tag):
issue = extract_redmine_issue_infos(tag)
m = re.match(".*/(?P<pull_id>[0-9]+)", get_issue_pr(issue))
redmine_branch = get_issue_rudder_branch(issue)
redmine_version = redmine_branch
pull_id = m.groups('pull_id')[0]
print(pull_id)
if redmine_branch == "master":
branch_version = redmine_branch
agent_version = get_issue_rudder_version(issue) +"-nightly"
else:
ret = requests.get("http://www.rudder-project.org/release-info/rudder/versions/" + redmine_version + "/git_branch")
branch_version = ret.text
agent_version = redmine_version

if scenario.platform.hosts ['agent'].info['system'] not in need_external_setup:
ncf_version = "https://github.com/Normation/ncf.git#" + branch_version
test_shell_on("agent", export_prefix + ";sh /tmp/ncf-setup test-local " + ncf_version + " " + cfengine_version + " --testinfra", live_output=True)
test_shell_on("agent", export_prefix + ";sh /tmp/ncf-setup test-pr https://github.com/Normation/ncf.git#" + branch_version + " ci/rudder-" + agent_version + " " + pull_id + " --testinfra", live_output=True)
# Testing a ncf version
else:
if not cfengine_version:
cfengine_version = "ci/rudder-" + tag + "-nightly"
ret = requests.get("http://www.rudder-project.org/release-info/rudder/versions/" + tag + "/git_branch")
branch_version = ret.text

# Re-dumping test results
shell_on("agent", "find /tmp/tmp* -name \"test.log\" | xargs cat", live_output=True);
shell_on("agent", "find /tmp/tmp* -name \"summary.log\" | xargs cat", live_output=True);
if scenario.platform.hosts ['agent'].info['system'] not in need_external_setup:
ncf_version = "https://github.com/Normation/ncf.git#" + branch_version
test_shell_on("agent", export_prefix + ";sh /tmp/ncf-setup test-local " + ncf_version + " " + cfengine_version + " --testinfra", live_output=True)

finish()
# Re-dumping test results
shell_on("agent", "find /tmp/tmp* -name \"test.log\" | xargs cat", live_output=True);
shell_on("agent", "find /tmp/tmp* -name \"summary.log\" | xargs cat", live_output=True);

finish()
20 changes: 12 additions & 8 deletions scenario/reset.py
Expand Up @@ -8,14 +8,18 @@
"""

from scenario.lib import *
class Scenario():
def __init__(self, data):
self.data = data

# test begins, register start time
start(__doc__)
def run(self):
# test begins, register start time
start(__doc__)

# remove everything
delete = get_param("nodes", "yes")
for host in scenario.nodes("agent"):
run('localhost', 'delete_all', Err.FINALLY, DELETE_NODES=delete)
# remove everything
delete = get_param("nodes", "yes")
for host in scenario.nodes("agent"):
run('localhost', 'delete_all', Err.FINALLY, DELETE_NODES=delete)

# test end, print summary
finish()
# test end, print summary
finish()