diff --git a/night_rally.py b/night_rally.py index 32e718099814d..fff3ecce892cf 100644 --- a/night_rally.py +++ b/night_rally.py @@ -1,10 +1,13 @@ import argparse +import collections import datetime +import errno import logging import os -import time import re -import collections +import shlex +import socket +import time ROOT = os.path.dirname(os.path.realpath(__file__)) RALLY_BINARY = "rally --skip-update" @@ -28,6 +31,81 @@ logger = logging.getLogger("night_rally") +class NightRallyError(Exception): + """ + Base class for all Night Rally exceptions + """ + + def __init__(self, message, cause=None): + super().__init__(message, cause) + self.message = message + self.cause = cause + + def __repr__(self): + return self.message + + +class RemotePortNotFree(NightRallyError): + """ + Thrown whenever the specified port in --target-host is not free + """ + + +class RemotePortNotDefined(NightRallyError): + """ + Thrown whenever there was no port specified in --target-host + """ + + +def wait_until_port_is_free(target_hosts, connector=socket, wait_time=5): + max_attempts = 5 + attempt = 1 + port_free = True + connect_result = None + + from elasticsearch.client import _normalize_hosts + for node in _normalize_hosts(target_hosts): + if "port" not in node: + raise RemotePortNotDefined( + message="No port specified for target host: [{}]. Please check your target-host parameter.".format(node["host"]), + cause="Missing target port error." + ) + + while attempt <= max_attempts: + c = connector.socket() + connect_result = c.connect_ex((node["host"], node["port"])) + try: + if connect_result == errno.ECONNREFUSED: + port_free = True + c.close() + break + else: + port_free = False + logger.info("Port [%s] on host [%d] is not free. " + "Waiting for %d seconds now, attempt %d/%d.", + node["host"], + node["port"], + wait_time, + attempt, + max_attempts) + c.close() + time.sleep(wait_time) + attempt += 1 + except OSError: + logger.exception( + "Ignoring error while trying to close the socket after connecting to " + "node: [{}:{}]".format(node["host"], + node["port"])) + if not port_free: + # target host port occupied or some other socket error + raise RemotePortNotFree( + message="Port [{}] on host [{}] is not free, " + "or another persistent issue while attempting to connect to it.".format(node["port"], node["host"]), + cause="errno = {}".format(connect_result if connect_result == 0 else errno.errorcode[connect_result])) + + return port_free + + def date_for_cmd_param(d): return "{:%Y-%m-%d %H:%M:%S}".format(d) @@ -206,11 +284,11 @@ def command_line(self, race_config): cmd = RALLY_BINARY for k, v in cmd_line_params.items(): if isinstance(v, list): - cmd += " --{}=\"{}\"".format(k, join_nullables(*v)) + cmd += " --{}={}".format(k, shlex.quote(join_nullables(*v))) elif v is None: cmd += " --{}".format(k) else: - cmd += " --{}=\"{}\"".format(k, v) + cmd += " --{}={}".format(k, shlex.quote(str(v))) return cmd @@ -402,15 +480,25 @@ def run_rally(tracks, available_hosts, command, dry_run=False, skip_ansible=Fals if not skip_ansible: logger.info("Resetting benchmark environment...") fixtures_dir = os.path.join(os.path.dirname(__file__), "fixtures", "ansible") - runner("cd \"%s\" && ansible-playbook -i inventory/production -u rally playbooks/setup.yml " - "--tags=\"drop-caches,trim\" && cd -" % fixtures_dir) + shell_command = "cd {} && " \ + "ansible-playbook -i inventory/production -u rally playbooks/setup.yml " \ + "--tags={} && cd -".format(fixtures_dir, + shlex.quote("drop-caches,trim")) + runner(shell_command) logger.info("Running Rally on [%s]", race_cfg) start = time.perf_counter() - if runner(command.command_line(race_cfg)): - rally_failure = True - logger.error("Failed to run [%s]. Please check the logs.", race_cfg) - stop = time.perf_counter() - logger.info("Finished running on [%s] in [%f] seconds.", race_cfg, (stop - start)) + try: + wait_until_port_is_free(available_hosts) + if runner(command.command_line(race_cfg)): + rally_failure = True + logger.error("Failed to run [%s]. Please check the logs.", race_cfg) + stop = time.perf_counter() + logger.info("Finished running on [%s] in [%f] seconds.", race_cfg, (stop - start)) + except (RemotePortNotFree, RemotePortNotDefined) as remote_port_exception: + logger.error("Skipped running [%s].", race_cfg) + logger.error(remote_port_exception.message) + logger.error(remote_port_exception.cause) + break else: logger.info("Skipping [%s] (not supported by command).", race_cfg) else: @@ -481,7 +569,7 @@ def copy_results_for_release_comparison(effective_start_date, dry_run): def deactivate_outdated_results(effective_start_date, environment, release, env_tag, dry_run): """ - Sets all results for the same major release version, environment and tag to active=False except for the records with the provided + Sets all results for the same major release version, environment and tag to active=False except for the records with the provided effective start date. """ import client diff --git a/tests.py b/tests.py index edf74c1b862fe..7711c511dadf5 100644 --- a/tests.py +++ b/tests.py @@ -1,5 +1,10 @@ import datetime import unittest +import errno +import shlex + +from unittest import mock + if __name__ == "__main__" and __package__ is None: __package__ = "night_rally" @@ -17,6 +22,23 @@ def __call__(self, *args, **kwargs): return self.return_value +class DummySocketConnector: + def __init__(self, port_listening=None): + self.port_listening = port_listening if port_listening else False + + def socket(self): + return self + + def connect_ex(self, host_port): + if self.port_listening: + return 0 + else: + return errno.ECONNREFUSED + + def close(self): + pass + + class VersionsTests(unittest.TestCase): def test_finds_components_for_valid_version(self): self.assertEqual((5, 0, 3, None), night_rally.components("5.0.3")) @@ -28,6 +50,43 @@ def test_components_ignores_invalid_versions(self): self.assertEqual("version string '5.0.0a' does not conform to pattern '^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$'", ctx.exception.args[0]) +class WaitUntilPortFreeTests(unittest.TestCase): + multi_host_string = "192.168.14.3:39200,192.168.14.4:39200,192.168.14.5:39200".split(",") + single_host_string = "192.168.2.3:9200".split(",") + single_host_no_port = "192.168.2.4" + + def test_fail_if_es_http_port_listening(self): + with self.assertRaises(night_rally.RemotePortNotFree): + night_rally.wait_until_port_is_free( + WaitUntilPortFreeTests.multi_host_string, + connector=DummySocketConnector(port_listening=True), + wait_time=0) + + with self.assertRaises(night_rally.RemotePortNotFree): + self.assertFalse(night_rally.wait_until_port_is_free( + WaitUntilPortFreeTests.single_host_string, + connector=DummySocketConnector(port_listening=True), + wait_time=0)) + + def test_succeed_if_es_http_port_available(self): + self.assertTrue(night_rally.wait_until_port_is_free( + WaitUntilPortFreeTests.multi_host_string, + connector=DummySocketConnector(port_listening=False), + wait_time=0)) + + self.assertTrue(night_rally.wait_until_port_is_free( + WaitUntilPortFreeTests.single_host_string, + connector=DummySocketConnector(port_listening=False), + wait_time=0)) + + def test_fail_if_port_missing_from_target_host(self): + with self.assertRaises(night_rally.RemotePortNotDefined): + night_rally.wait_until_port_is_free( + WaitUntilPortFreeTests.single_host_no_port, + connector=DummySocketConnector(port_listening=False), + wait_time=0) + + class NightRallyTests(unittest.TestCase): def test_sanitize(self): self.assertEqual("lucene-7-upgrade", night_rally.sanitize("Lucene 7 Upgrade")) @@ -39,7 +98,8 @@ def test_join(self): self.assertEqual("name:test", night_rally.join_nullables(None, "name:test")) self.assertEqual("", night_rally.join_nullables(None)) - def test_run_two_challenges_successfully(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_two_challenges_successfully(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -67,21 +127,22 @@ def test_run_two_challenges_successfully(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"nightly\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults\" --user-tag=\"env:bare,name:geonames-defaults\" --car-params=\"verbose_iw_logging_enabled:true\" " - "--pipeline=\"from-sources-complete\" --revision=\"@2016-01-01T00:00:00Z\"", - - "rally --skip-update --configuration-name=\"nightly\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap\" --user-tag=\"env:bare,name:geonames-4g\" --pipeline=\"from-sources-skip-build\" " - "--revision=\"@2016-01-01T00:00:00Z\"" + "rally --skip-update --configuration-name=nightly --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=defaults --user-tag=env:bare,name:geonames-defaults --car-params=verbose_iw_logging_enabled:true " + "--pipeline=from-sources-complete --revision=@2016-01-01T00:00:00Z", + + "rally --skip-update --configuration-name=nightly --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=4gheap --user-tag=env:bare,name:geonames-4g --pipeline=from-sources-skip-build " + "--revision=@2016-01-01T00:00:00Z" ] , system_call.calls ) - def test_run_two_tracks_successfully(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_two_tracks_successfully(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -114,21 +175,22 @@ def test_run_two_tracks_successfully(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"nightly\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-10-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults\" --user-tag=\"env:bare,name:geonames-defaults\" --pipeline=\"from-sources-complete\" " - "--revision=\"@2016-10-01T00:00:00Z\"", - - "rally --skip-update --configuration-name=\"nightly\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-10-01 00:00:00\" --track=\"percolator\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap\" --user-tag=\"env:bare,name:percolator-4g\" --pipeline=\"from-sources-skip-build\" " - "--revision=\"@2016-10-01T00:00:00Z\"" + "rally --skip-update --configuration-name=nightly --quiet --target-host=localhost " + "--effective-start-date=\'2016-10-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=defaults --user-tag=env:bare,name:geonames-defaults --pipeline=from-sources-complete " + "--revision=@2016-10-01T00:00:00Z", + + "rally --skip-update --configuration-name=nightly --quiet --target-host=localhost " + "--effective-start-date=\'2016-10-01 00:00:00\' --track=percolator --challenge=append-no-conflicts " + "--car=4gheap --user-tag=env:bare,name:percolator-4g --pipeline=from-sources-skip-build " + "--revision=@2016-10-01T00:00:00Z" ] , system_call.calls ) - def test_run_adhoc_benchmark(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_adhoc_benchmark(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -162,20 +224,20 @@ def test_run_adhoc_benchmark(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"lucene-7\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-10-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults\" --user-tag=\"env:bare,name:geonames-defaults\" --pipeline=\"from-sources-complete\" " - "--revision=\"66202dc\"", - - "rally --skip-update --configuration-name=\"lucene-7\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-10-01 00:00:00\" --track=\"percolator\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap\" --user-tag=\"env:bare,name:percolator-4g\" --pipeline=\"from-sources-skip-build\" --revision=\"66202dc\"" + "rally --skip-update --configuration-name=lucene-7 --quiet --target-host=localhost " + "--effective-start-date='2016-10-01 00:00:00' --track=geonames --challenge=append-no-conflicts " + "--car=defaults --user-tag=env:bare,name:geonames-defaults --pipeline=from-sources-complete " + "--revision=66202dc", + "rally --skip-update --configuration-name=lucene-7 --quiet --target-host=localhost " + "--effective-start-date='2016-10-01 00:00:00' --track=percolator --challenge=append-no-conflicts " + "--car=4gheap --user-tag=env:bare,name:percolator-4g --pipeline=from-sources-skip-build --revision=66202dc" ] , system_call.calls ) - def test_run_release_benchmark_without_plugins(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_release_benchmark_without_plugins(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -202,21 +264,22 @@ def test_run_release_benchmark_without_plugins(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults\" --user-tag=\"env:bare,name:geonames-defaults\" --distribution-version=\"5.3.0\" " - "--pipeline=\"from-distribution\"", - - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap\" --user-tag=\"env:bare,name:geonames-4g\" --distribution-version=\"5.3.0\" " - "--pipeline=\"from-distribution\"" + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=defaults --user-tag=env:bare,name:geonames-defaults --distribution-version=5.3.0 " + "--pipeline=from-distribution", + + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=4gheap --user-tag=env:bare,name:geonames-4g --distribution-version=5.3.0 " + "--pipeline=from-distribution" ] , system_call.calls ) - def test_run_release_benchmark_with_plugins(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_release_benchmark_with_plugins(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -252,25 +315,32 @@ def test_run_release_benchmark_with_plugins(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults\" --user-tag=\"env:x-pack,name:geonames-defaults,x-pack:true\" " - "--client-options=\"timeout:60,use_ssl:true,verify_certs:false,basic_auth_user:'rally'," - "basic_auth_password:'rally-password'\" --elasticsearch-plugins=\"x-pack:security,monitoring\" " - "--track-params=\"cluster_health:'yellow'\" --distribution-version=\"5.3.0\" --pipeline=\"from-distribution\"", - - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap\" --user-tag=\"env:x-pack,name:geonames-4g,x-pack:true\" --client-options=\"timeout:60,use_ssl:true" - ",verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'\" " - "--elasticsearch-plugins=\"x-pack:security,monitoring\" --track-params=\"cluster_health:'yellow'\" " - "--distribution-version=\"5.3.0\" --pipeline=\"from-distribution\"", + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=defaults --user-tag=env:x-pack,name:geonames-defaults,x-pack:true " + "--client-options=" + + shlex.quote("timeout:60,use_ssl:true,verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'") + " " + "--elasticsearch-plugins=x-pack:security,monitoring " + "--track-params=" + + shlex.quote("cluster_health:'yellow'") + " " + "--distribution-version=5.3.0 --pipeline=from-distribution", + + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=4gheap --user-tag=env:x-pack,name:geonames-4g,x-pack:true " + "--client-options=" + + shlex.quote("timeout:60,use_ssl:true,verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'") + " " + "--elasticsearch-plugins=x-pack:security,monitoring " + "--track-params=" + + shlex.quote("cluster_health:'yellow'") + " " + "--distribution-version=5.3.0 --pipeline=from-distribution", ] , system_call.calls ) - def test_run_release_benchmark_with_x_pack_module(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_release_benchmark_with_x_pack_module(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -307,25 +377,32 @@ def test_run_release_benchmark_with_x_pack_module(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults,x-pack-security,x-pack-monitoring\" --user-tag=\"env:x-pack,name:geonames-defaults,x-pack:true\" " - "--client-options=\"timeout:60,use_ssl:true,verify_certs:false,basic_auth_user:'rally'," - "basic_auth_password:'rally-password'\" --track-params=\"cluster_health:'yellow'\" --distribution-version=\"6.3.0\" " - "--pipeline=\"from-distribution\"", - - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap,x-pack-security,x-pack-monitoring\" --user-tag=\"env:x-pack,name:geonames-4g,x-pack:true\" " - "--client-options=\"timeout:60,use_ssl:true,verify_certs:false,basic_auth_user:'rally'," - "basic_auth_password:'rally-password'\" --track-params=\"cluster_health:'yellow'\" --distribution-version=\"6.3.0\" " - "--pipeline=\"from-distribution\"", + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=defaults,x-pack-security,x-pack-monitoring --user-tag=env:x-pack,name:geonames-defaults,x-pack:true " + + "--client-options=" + + shlex.quote("timeout:60,use_ssl:true,verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'") + " " + "--track-params=" + + shlex.quote("cluster_health:'yellow'") + " " + "--distribution-version=6.3.0 " + "--pipeline=from-distribution", + + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date=\'2016-01-01 00:00:00\' --track=geonames --challenge=append-no-conflicts " + "--car=4gheap,x-pack-security,x-pack-monitoring --user-tag=env:x-pack,name:geonames-4g,x-pack:true " + + "--client-options=" + + shlex.quote("timeout:60,use_ssl:true,verify_certs:false,basic_auth_user:'rally',basic_auth_password:'rally-password'") + " " + "--track-params=" + + shlex.quote("cluster_health:'yellow'") + " " + "--distribution-version=6.3.0 " + "--pipeline=from-distribution" ] , system_call.calls ) - def test_run_docker_benchmark(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_docker_benchmark(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -353,21 +430,26 @@ def test_run_docker_benchmark(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults\" --user-tag=\"env:docker,name:geonames-defaults\" --track-params=\"cluster_health:'yellow'\" " - "--distribution-version=\"5.3.0\" --pipeline=\"docker\"", - - "rally --skip-update --configuration-name=\"release\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-01-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap\" --user-tag=\"env:docker,name:geonames-4g\" --track-params=\"cluster_health:'yellow'\" " - "--distribution-version=\"5.3.0\" --pipeline=\"docker\"" + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date='2016-01-01 00:00:00' --track=geonames --challenge=append-no-conflicts " + "--car=defaults --user-tag=env:docker,name:geonames-defaults "+ + "--track-params=" + + shlex.quote("cluster_health:'yellow'") + " " + "--distribution-version=5.3.0 --pipeline=docker", + + "rally --skip-update --configuration-name=release --quiet --target-host=localhost " + "--effective-start-date='2016-01-01 00:00:00' --track=geonames --challenge=append-no-conflicts " + "--car=4gheap --user-tag=env:docker,name:geonames-4g "+ + "--track-params=" + + shlex.quote("cluster_health:'yellow'") + " " + "--distribution-version=5.3.0 --pipeline=docker" ] , system_call.calls ) - def test_run_continues_on_error(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_continues_on_error(self, mocked_wait_until_port_is_free): self.maxDiff = None system_call = RecordingSystemCall(return_value=True) @@ -402,21 +484,22 @@ def test_run_continues_on_error(self): self.assertEqual(2, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --configuration-name=\"nightly\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-10-01 00:00:00\" --track=\"geonames\" --challenge=\"append-no-conflicts\" " - "--car=\"defaults\" --user-tag=\"env:bare,name:geonames-defaults\" --pipeline=\"from-sources-complete\" " - "--revision=\"@2016-10-01T00:00:00Z\"", - - "rally --skip-update --configuration-name=\"nightly\" --quiet --target-host=\"localhost\" " - "--effective-start-date=\"2016-10-01 00:00:00\" --track=\"percolator\" --challenge=\"append-no-conflicts\" " - "--car=\"4gheap\" --user-tag=\"env:bare,name:percolator-4g\" --pipeline=\"from-sources-skip-build\" " - "--revision=\"@2016-10-01T00:00:00Z\"" + "rally --skip-update --configuration-name=nightly --quiet --target-host=localhost " + "--effective-start-date='2016-10-01 00:00:00' --track=geonames --challenge=append-no-conflicts " + "--car=defaults --user-tag=env:bare,name:geonames-defaults --pipeline=from-sources-complete " + "--revision=@2016-10-01T00:00:00Z", + + "rally --skip-update --configuration-name=nightly --quiet --target-host=localhost " + "--effective-start-date='2016-10-01 00:00:00' --track=percolator --challenge=append-no-conflicts " + "--car=4gheap --user-tag=env:bare,name:percolator-4g --pipeline=from-sources-skip-build " + "--revision=@2016-10-01T00:00:00Z" ] , system_call.calls ) - def test_run_with_telemetry(self): + @mock.patch('night_rally.wait_until_port_is_free', return_value=True) + def test_run_with_telemetry(self, mocked_wait_until_port_is_free): system_call = RecordingSystemCall(return_value=False) tracks = [ @@ -445,10 +528,10 @@ def test_run_with_telemetry(self): self.assertEqual(1, len(system_call.calls)) self.assertEqual( [ - "rally --skip-update --telemetry=\"jfr,gc,jit\" --telemetry-params=\"recording-template:profile\" " - "--configuration-name=\"nightly\" --quiet --target-host=\"localhost\" --effective-start-date=\"2016-01-01 00:00:00\" " - "--track=\"geonames\" --challenge=\"append-no-conflicts\" --car=\"defaults\" --user-tag=\"env:bare,name:geonames-defaults\"" - " --pipeline=\"from-sources-complete\" --revision=\"@2016-01-01T00:00:00Z\"" + "rally --skip-update --telemetry=jfr,gc,jit --telemetry-params=recording-template:profile " + "--configuration-name=nightly --quiet --target-host=localhost --effective-start-date=\'2016-01-01 00:00:00\' " + "--track=geonames --challenge=append-no-conflicts --car=defaults --user-tag=env:bare,name:geonames-defaults" + " --pipeline=from-sources-complete --revision=@2016-01-01T00:00:00Z" ] , system_call.calls