Skip to content

Commit

Permalink
Fixes #16772: Add an upgrade scenario in rtf
Browse files Browse the repository at this point in the history
  • Loading branch information
Fdall authored and Jenkins CI committed Mar 6, 2020
1 parent 7103006 commit 12fa2c3
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 190 deletions.
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()

0 comments on commit 12fa2c3

Please sign in to comment.