def test_python_cmd(tmpdir, capfd): tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" test: commands: - python: print("single_line") - python: "for letter in ['a', 'b', 'c']: print(letter)" - python: | for index in range(3): with open("file_%s" % index, "w") as output: output.write("") """).format(version=SCHEMA_VERSION)) service = 'circle' environment = dict(os.environ) enable_service(service, environment) with push_dir(str(tmpdir)), push_env(**environment): execute_step("test", with_dependencies=False) output_lines, _ = strip_ascii_art(captured_lines(capfd)) assert output_lines[1] == "single_line" assert output_lines[3] == "a" assert output_lines[4] == "b" assert output_lines[5] == "c" assert tmpdir.join("file_0").exists() assert tmpdir.join("file_1").exists() assert tmpdir.join("file_2").exists()
def test_multi_line_shell_command(tmpdir, capfd): if platform.system().lower() == "windows": tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" install: commands: - | for %%G in (foo bar) do ^ python -c "print('var %%G')" if "bar" == "bar" echo "bar is bar" """).format(version=SCHEMA_VERSION)) service = 'appveyor' offset = 4 else: tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" install: commands: - | for var in foo bar; do python -c "print('var $var')" done if [[ "bar" == "bar" ]]; then echo "bar is bar" fi # This is a comment # .. and an other one for letter in $(echo a) \ $(echo b); do echo the letter $letter -in "/text/" done """).format(version=SCHEMA_VERSION)) service = 'circle' # Number of lines in the command (without line continuation) offset = 13 for step, system, environment in scikit_steps(tmpdir, service): with push_dir(str(tmpdir)), push_env(**environment): execute_step(step) output_lines, _ = strip_ascii_art(captured_lines(capfd)) if step == 'install': assert output_lines[offset + 1] == "var foo" assert output_lines[offset + 2] == "var bar" assert output_lines[offset + 3] == "bar is bar" assert output_lines[offset + 4] == "the letter a -in /text/" assert output_lines[offset + 5] == "the letter b -in /text/" else: assert len(output_lines) == 0
def test_shell_for_loop(tmpdir, capfd): if platform.system().lower() == "windows": # Since executing windows terminal command is not supported # on appveyor, we do not test for it. # That said, here is an example of should be expected to work: # FOR %G IN (foo bar) DO python -c "print('var %G')" tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" install: commands: - | echo var foo echo var bar """).format(version=SCHEMA_VERSION)) service = 'appveyor' else: tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" install: commands: - for var in foo bar; do python -c "print('var $var')"; done - "for var in oof rab; do python -c \"print('var: $var')\"; done" """ # noqa: E501 ).format(version=SCHEMA_VERSION)) service = 'circle' for step, system, environment in scikit_steps(tmpdir, service): with push_dir(str(tmpdir)), push_env(**environment): execute_step(step) output_lines, _ = strip_ascii_art(captured_lines(capfd)) if step == 'install': if platform.system().lower() == "windows": assert output_lines[3] == "var foo" assert output_lines[4] == "var bar" else: assert output_lines[1] == "var foo" assert output_lines[2] == "var bar" assert output_lines[4] == "var: oof" assert output_lines[5] == "var: rab" else: assert len(output_lines) == 0
def test_ci_name_environment_variable(tmpdir, capfd): quote = "" if HAS_COMSPEC else "\"" tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" before_install: environment: FOO: $<CI_NAME> commands: - echo {quote}ci_name [$<CI_NAME>] foo [$<FOO>]{quote} """).format(quote=quote, version=SCHEMA_VERSION)) service = 'circle' with push_dir(str(tmpdir)), push_env(): enable_service(service) execute_step("before_install") output_lines, _ = strip_ascii_art(captured_lines(capfd)) assert output_lines[1] == "ci_name [%s] foo [%s]" % (service, service)
def test_within_environment_expansion(tmpdir, capfd): quote = "" if HAS_COMSPEC else "\"" tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" before_install: environment: FOO: hello BAR: $<WHAT> REAL_DIR: $<VERY_DIR>\\real commands: - echo {quote}[$<FOO> $<BAR> $<STRING>]{quote} - echo {quote}[\\the\\thing]{quote} - echo {quote}[$<FOO_DIR>\\the\\thing]{quote} - echo {quote}[$<FOO_DIR>\\the$<REAL_DIR>\\thing]{quote} """).format(quote=quote, version=SCHEMA_VERSION)) service = 'circle' environment = dict(os.environ) enable_service(service, environment) # quote_type = "'" if HAS_COMSPEC else "\"" # backslashes = "\\\\\\\\" if HAS_COMSPEC else "\\" quote_type = "'" # if HAS_COMSPEC else "\"" backslashes = "\\" environment["WHAT"] = "world" environment["STRING"] = "of " + quote_type + "wonders" + quote_type environment["FOO_DIR"] = "C:\\path\\to" environment["VERY_DIR"] = "\\very" with push_dir(str(tmpdir)), push_env(**environment): execute_step("before_install") output_lines, _ = strip_ascii_art(captured_lines(capfd)) assert output_lines[ 1] == "[hello world of " + quote_type + "wonders" + quote_type + "]" # noqa: E501 assert output_lines[3] == "[\\the\\thing]".replace("\\", backslashes) assert output_lines[5] == "[C:\\path\\to\\the\\thing]".replace( "\\", backslashes) # noqa: E501 assert output_lines[7] == "[C:\\path\\to\\the\\very\\real\\thing]".replace( "\\", backslashes) # noqa: E501
def test_driver(service, tmpdir, capfd): tmpdir.join('scikit-ci.yml').write(_generate_scikit_yml_content(service)) outputs = [] with push_env(): for step, system, environment in scikit_steps(tmpdir, service): if "PYTHON" not in environment: environment["PYTHON"] = "python" with push_dir(str(tmpdir)), push_env(**environment): execute_step(step) output_lines, error_lines = strip_ascii_art( captured_lines(capfd)) outputs.append((step, system, output_lines, error_lines)) with capfd.disabled(): for step, system, output_lines, error_lines in outputs: second_line = "%s / %s" % (step, service) if system: second_line = "%s-%s / %s" % (second_line, system, system) try: extra_space = "" if HAS_COMSPEC else " " assert output_lines[1] == "%s" % step assert output_lines[3] == "expand:%s%s" % (extra_space, step) assert output_lines[5] == "expand-2:%s" % (step if HAS_COMSPEC else "$<WHAT>") assert output_lines[7] == "%s.%s.%s" % sys.version_info[:3] assert output_lines[9] == second_line except AssertionError as error: context = service + (("-" + system) if system else "") print("\n[%s: %s]" % (context, step)) display_captured_text(output_lines, error_lines) if sys.version_info[0] > 2: raise error.with_traceback(sys.exc_info()[2]) else: raise
def test_not_all_operating_system(tmpdir): tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" install: travis: osx: environment: FOO: BAR """ # noqa: E501 ).format(version=SCHEMA_VERSION)) service = 'travis' environment = dict(os.environ) enable_service(service, environment, "linux") with push_dir(str(tmpdir)), push_env(**environment): execute_step("install")
def test_ci_name_reserved_environment_variable(tmpdir): quote = "" if HAS_COMSPEC else "\"" tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" before_install: environment: CI_NAME: foo """).format(quote=quote, version=SCHEMA_VERSION)) service = 'circle' environment = dict(os.environ) enable_service(service, environment) failed = False try: with push_dir(str(tmpdir)), push_env(**environment): execute_step("before_install") except ValueError: failed = True assert failed
def test_expand_environment(tmpdir, capfd): quote = "" if HAS_COMSPEC else "\"" tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" before_install: environment: SYMBOLS: b;$<SYMBOLS> circle: environment: SYMBOLS: a;$<SYMBOLS> commands: - echo {quote}before_install [$<SYMBOLS>]{quote} install: environment: SYMBOLS: 9;$<SYMBOLS> circle: environment: SYMBOLS: 8;$<SYMBOLS> commands: - echo {quote}install [$<SYMBOLS>]{quote} """).format(quote=quote, version=SCHEMA_VERSION)) service = 'circle' output_lines = [] with push_dir(str(tmpdir)), push_env(SYMBOLS="c;d;e"): enable_service(service) execute_step("before_install") output_lines.extend(strip_ascii_art(captured_lines(capfd))[0]) execute_step("install") output_lines.extend(strip_ascii_art(captured_lines(capfd))[0]) assert output_lines[1] == "before_install [a;b;c;d;e]" assert output_lines[3] == "install [8;9;a;b;c;d;e]"
def test_environment_persist(tmpdir, capfd): quote = "" if HAS_COMSPEC else "\"" tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" before_install: environment: FOO: hello BAR: world EMPTY: "" commands: - echo {quote}1 [$<FOO>] [$<BAR>] [$<EMPTY>]{quote} circle: environment: BAR: under world install: environment: BAR: beautiful world commands: - echo {quote}2 [$<FOO>] [$<BAR>] [$<EMPTY>]{quote} """).format(quote=quote, version=SCHEMA_VERSION)) service = 'circle' output_lines = [] with push_dir(str(tmpdir)), push_env(): enable_service(service) execute_step("before_install") output_lines.extend(strip_ascii_art(captured_lines(capfd))[0]) execute_step("install") output_lines.extend(strip_ascii_art(captured_lines(capfd))[0]) assert output_lines[1] == "1 [hello] [under world] []" assert output_lines[3] == "2 [hello] [beautiful world] []"
def test_clear_env(tmpdir): """This test checks that the 'env.json' file is removed when the force option is specified. """ tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" """).format(version=SCHEMA_VERSION)) service = 'circle' environment = dict(os.environ) enable_service(service, environment) with push_dir(str(tmpdir)), push_env(**environment): execute_step("test") env = Driver.read_env() assert env['SCIKIT_CI_TEST'] == '1' # Add variable to check env file is effectively removed assert 'CLEAR_ENV_TEST' not in env env['CLEAR_ENV_TEST'] = '1' Driver.save_env(env) assert 'CLEAR_ENV_TEST' in Driver.read_env() # # Re-execute 'test' step clearing environment # execute_step("test", clear_cached_env=True) env = Driver.read_env() assert env['SCIKIT_CI_TEST'] == '1' assert 'CLEAR_ENV_TEST' not in env
def test_step_ordering_and_dependency(tmpdir): tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" before_install: commands: - "python -c \"with open('before_install', 'w') as file: file.write('')\"" install: commands: - "python -c \"with open('install', 'w') as file: file.write('')\"" before_build: commands: - "python -c \"with open('before_build', 'w') as file: file.write('')\"" build: commands: - "python -c \"with open('build', 'w') as file: file.write('')\"" test: commands: - "python -c \"exit(1)\"" after_test: commands: - "python -c \"with open('after_test', 'w') as file: file.write('')\"" """ # noqa: E501 ).format(version=SCHEMA_VERSION)) service = 'circle' environment = dict(os.environ) enable_service(service, environment) with push_dir(str(tmpdir)), push_env(**environment): execute_step("install") # # Check that steps `before_install` and `install` were executed # env = Driver.read_env() assert env['SCIKIT_CI_BEFORE_INSTALL'] == '1' assert env['SCIKIT_CI_INSTALL'] == '1' assert tmpdir.join('before_install').exists() assert tmpdir.join('install').exists() # Remove files - This is to make sure the steps are not re-executed tmpdir.join('before_install').remove() tmpdir.join('install').remove() # Check files have been removed assert not tmpdir.join('before_install').exists() assert not tmpdir.join('install').exists() execute_step("build") # # Check that only `before_build` and `build` steps were executed # env = Driver.read_env() assert env['SCIKIT_CI_BEFORE_INSTALL'] == '1' assert env['SCIKIT_CI_INSTALL'] == '1' assert env['SCIKIT_CI_BEFORE_BUILD'] == '1' assert env['SCIKIT_CI_BUILD'] == '1' assert not tmpdir.join('before_install').exists() assert not tmpdir.join('install').exists() assert tmpdir.join('before_build').exists() assert tmpdir.join('build').exists() # Remove files - This will to make sure the steps are not re-executed tmpdir.join('before_build').remove() tmpdir.join('build').remove() failed = False try: execute_step("after_test") except SKCIStepExecutionError as exc: failed = "exit(1)" in exc.cmd # # Check that `after_test` step was NOT executed. It should not be # execute because `test` step is failing. # assert failed env = Driver.read_env() assert env['SCIKIT_CI_BEFORE_INSTALL'] == '1' assert env['SCIKIT_CI_INSTALL'] == '1' assert env['SCIKIT_CI_BEFORE_BUILD'] == '1' assert env['SCIKIT_CI_BUILD'] == '1' assert 'SCIKIT_CI_TEST' not in env assert 'SCIKIT_CI_AFTER_TEST' not in env assert not tmpdir.join('before_install').exists() assert not tmpdir.join('install').exists() assert not tmpdir.join('before_install').exists() assert not tmpdir.join('install').exists() assert not tmpdir.join('test').exists() assert not tmpdir.join('after_test').exists() # # Check `force=True` works as expected # execute_step("install", force=True) # Check that steps `before_install` and `install` were re-executed env = Driver.read_env() assert env['SCIKIT_CI_BEFORE_INSTALL'] == '1' assert env['SCIKIT_CI_INSTALL'] == '1' assert tmpdir.join('before_install').exists() assert tmpdir.join('install').exists() tmpdir.join('before_install').remove() tmpdir.join('install').remove() # # Check `force=True` and `with_dependencies=True` work as expected # execute_step("install", force=True, with_dependencies=False) # Check that only step `install` was re-executed env = Driver.read_env() assert env['SCIKIT_CI_BEFORE_INSTALL'] == '1' assert env['SCIKIT_CI_INSTALL'] == '1' assert not tmpdir.join('before_install').exists() assert tmpdir.join('install').exists() tmpdir.join('install').remove() # # Check `force=False` and `with_dependencies=True` work as expected # tmpdir.join('env.json').remove() execute_step("install", with_dependencies=False) # Check that only step `install` was executed env = Driver.read_env() assert 'SCIKIT_CI_BEFORE_INSTALL' not in env assert env['SCIKIT_CI_INSTALL'] == '1' assert not tmpdir.join('before_install').exists() assert tmpdir.join('install').exists()
def test_shell_command_with_quoted_args(tmpdir, capfd): program = tmpdir.join("program.py") program.write( textwrap.dedent(""" import sys for index, arg in enumerate(sys.argv): if index == 0: continue print("arg_%s [%s]" % (index, sys.argv[index])) """)) tmpdir.join('scikit-ci.yml').write( textwrap.dedent(r""" schema_version: "{version}" install: commands: - echo Hello1 - echo "Hello2" - echo 'Hello3' - python -c "print('Hello4')" - python -c 'print("Hello5")' - python -c "print('Hello6\'World')" - python program.py --things "foo" "bar" --more-things "doo" 'dar' - python program.py --the-foo="foo" -the-bar='bar' """ # noqa: E501 ).format(version=SCHEMA_VERSION)) service = 'appveyor' if platform.system().lower( ) == "windows" else "circle" for step, system, environment in scikit_steps(tmpdir, service): with push_dir(str(tmpdir)), push_env(**environment): execute_step(step) output_lines, _ = strip_ascii_art(captured_lines(capfd)) if step == 'install': # Command 1 offset = 0 output_line_count = 1 assert output_lines[1 + offset] == "Hello1" # Command 2 offset = offset + 1 + output_line_count output_line_count = 1 if HAS_COMSPEC: assert output_lines[1 + offset] == "\"Hello2\"" else: assert output_lines[1 + offset] == "Hello2" # Command 3 offset = offset + 1 + output_line_count output_line_count = 1 if HAS_COMSPEC: assert output_lines[1 + offset] == "'Hello3'" else: assert output_lines[1 + offset] == "Hello3" # Command 4 offset = offset + 1 + output_line_count output_line_count = 1 assert output_lines[1 + offset] == "Hello4" # Command 5 offset = offset + 1 + output_line_count if HAS_COMSPEC: output_line_count = 0 else: output_line_count = 1 assert output_lines[1 + offset] == "Hello5" # Command 6 offset = offset + 1 + output_line_count output_line_count = 1 assert output_lines[1 + offset] == "Hello6'World" # Command 7 offset = offset + 1 + output_line_count output_line_count = 6 assert output_lines[1 + offset] == "arg_1 [--things]" assert output_lines[2 + offset] == "arg_2 [foo]" assert output_lines[3 + offset] == "arg_3 [bar]" assert output_lines[4 + offset] == "arg_4 [--more-things]" assert output_lines[5 + offset] == "arg_5 [doo]" if HAS_COMSPEC: assert output_lines[6 + offset] == "arg_6 ['dar']" else: assert output_lines[6 + offset] == "arg_6 [dar]" # Command 8 offset = offset + 1 + output_line_count # output_line_count = 2 assert output_lines[1 + offset] == "arg_1 [--the-foo=foo]" if HAS_COMSPEC: assert output_lines[2 + offset] == "arg_2 [-the-bar='bar']" else: assert output_lines[2 + offset] == "arg_2 [-the-bar=bar]" else: assert len(output_lines) == 0