コード例 #1
0
def test_run_isolated_adhoc_command(private_data_dir, rsa_key):
    env = {'AD_HOC_COMMAND_ID': '1'}
    pem, passphrase = rsa_key
    mgr = isolated_manager.IsolatedManager(['pwd'], HERE, env,
                                           cStringIO.StringIO(), '')
    mgr.private_data_dir = private_data_dir
    secrets = {
        'env': env,
        'passwords': {
            r'Enter passphrase for .*:\s*?$': passphrase
        },
        'ssh_key_data': pem
    }
    mgr.build_isolated_job_data()
    stdout = cStringIO.StringIO()
    # Mock environment variables for callback module
    with mock.patch('os.getenv') as env_mock:
        env_mock.return_value = '/path/to/awx/lib'
        status, rc = run.run_isolated_job(private_data_dir, secrets, stdout)
    assert status == 'successful'
    assert rc == 0

    # for ad-hoc jobs, `ansible` is invoked from the `private_data_dir`, so
    # an ad-hoc command that runs `pwd` should print `private_data_dir` to stdout
    assert private_data_dir in stdout.getvalue()

    assert '/path/to/awx/lib' in env['PYTHONPATH']
    assert env['ANSIBLE_STDOUT_CALLBACK'] == 'minimal'
    assert env[
        'ANSIBLE_CALLBACK_PLUGINS'] == '/path/to/awx/lib/isolated_callbacks'
    assert env['AWX_ISOLATED_DATA_DIR'] == private_data_dir
コード例 #2
0
def test_check_isolated_job_timeout(private_data_dir, rsa_key):
    pem, passphrase = rsa_key
    stdout = cStringIO.StringIO()
    extra_update_fields = {}
    mgr = isolated_manager.IsolatedManager(
        ['ls', '-la'],
        HERE, {},
        stdout,
        '',
        job_timeout=1,
        extra_update_fields=extra_update_fields)
    mgr.private_data_dir = private_data_dir
    mgr.instance = mock.Mock(id=123,
                             pk=123,
                             verbosity=5,
                             spec_set=['id', 'pk', 'verbosity'])
    mgr.started_at = time.time()
    mgr.host = 'isolated-host'

    with mock.patch('awx.main.expect.run.run_pexpect') as run_pexpect:

        def _synchronize_job_artifacts(args, cwd, env, buff, **kw):
            buff.write('checking job status...')
            return ('failed', 1)

        run_pexpect.side_effect = _synchronize_job_artifacts
        status, rc = mgr.check(interval=0)

        assert status == 'failed'
        assert rc == 1
        assert stdout.getvalue() == 'checking job status...'

    assert extra_update_fields[
        'job_explanation'] == 'Job terminated due to timeout'
コード例 #3
0
def test_run_isolated_job(private_data_dir, rsa_key):
    env = {'JOB_ID': '1'}
    pem, passphrase = rsa_key
    mgr = isolated_manager.IsolatedManager(['ls', '-la'], HERE, env,
                                           cStringIO.StringIO(), '')
    mgr.private_data_dir = private_data_dir
    secrets = {
        'env': env,
        'passwords': {
            r'Enter passphrase for .*:\s*?$': passphrase
        },
        'ssh_key_data': pem
    }
    mgr.build_isolated_job_data()
    stdout = cStringIO.StringIO()
    # Mock environment variables for callback module
    with mock.patch('os.getenv') as env_mock:
        env_mock.return_value = '/path/to/awx/lib'
        status, rc = run.run_isolated_job(private_data_dir, secrets, stdout)
    assert status == 'successful'
    assert rc == 0
    assert FILENAME in stdout.getvalue()

    assert '/path/to/awx/lib' in env['PYTHONPATH']
    assert env['ANSIBLE_STDOUT_CALLBACK'] == 'awx_display'
    assert env[
        'ANSIBLE_CALLBACK_PLUGINS'] == '/path/to/awx/lib/isolated_callbacks'
    assert env['AWX_ISOLATED_DATA_DIR'] == private_data_dir
コード例 #4
0
def test_build_isolated_job_data(private_data_dir, rsa_key):
    pem, passphrase = rsa_key
    mgr = isolated_manager.IsolatedManager(['ls', '-la'], HERE, {},
                                           cStringIO.StringIO(), '')
    mgr.private_data_dir = private_data_dir
    mgr.build_isolated_job_data()

    path = os.path.join(private_data_dir, 'project')
    assert os.path.isdir(path)

    # <private_data_dir>/project is a soft link to HERE, which is the directory
    # _this_ test file lives in
    assert os.path.exists(os.path.join(path, FILENAME))

    path = os.path.join(private_data_dir, 'artifacts')
    assert os.path.isdir(path)
    assert stat.S_IMODE(
        os.stat(path).st_mode
    ) == stat.S_IXUSR + stat.S_IWUSR + stat.S_IRUSR  # user rwx

    path = os.path.join(private_data_dir, 'args')
    with open(path, 'r') as f:
        assert stat.S_IMODE(os.stat(path).st_mode) == stat.S_IRUSR  # user r/o
        assert f.read() == '["ls", "-la"]'

    path = os.path.join(private_data_dir, '.rsync-filter')
    with open(path, 'r') as f:
        data = f.read()
        assert data == '\n'.join([
            '- /project/.git', '- /project/.svn', '- /project/.hg',
            '- /artifacts/job_events/*-partial.json.tmp', '- /env'
        ])
コード例 #5
0
def test_check_isolated_job(private_data_dir, rsa_key):
    pem, passphrase = rsa_key
    stdout = cStringIO.StringIO()
    mgr = isolated_manager.IsolatedManager(['ls', '-la'], HERE, {}, stdout, '')
    mgr.private_data_dir = private_data_dir
    mgr.instance = mock.Mock(id=123,
                             pk=123,
                             verbosity=5,
                             spec_set=['id', 'pk', 'verbosity'])
    mgr.started_at = time.time()
    mgr.host = 'isolated-host'

    os.mkdir(os.path.join(private_data_dir, 'artifacts'))
    with mock.patch('awx.main.expect.run.run_pexpect') as run_pexpect:

        def _synchronize_job_artifacts(args, cwd, env, buff, **kw):
            buff.write('checking job status...')
            for filename, data in (
                ['status', 'failed'],
                ['rc', '1'],
                ['stdout', 'KABOOM!'],
            ):
                with open(
                        os.path.join(private_data_dir, 'artifacts', filename),
                        'w') as f:
                    f.write(data)
            return ('successful', 0)

        run_pexpect.side_effect = _synchronize_job_artifacts
        with mock.patch.object(mgr, '_missing_artifacts') as missing_artifacts:
            missing_artifacts.return_value = False
            status, rc = mgr.check(interval=0)

        assert status == 'failed'
        assert rc == 1
        assert stdout.getvalue() == 'KABOOM!'

        run_pexpect.assert_called_with([
            'ansible-playbook', 'check_isolated.yml', '-u',
            settings.AWX_ISOLATED_USERNAME, '-T',
            str(settings.AWX_ISOLATED_CONNECTION_TIMEOUT), '-i',
            'isolated-host,', '-e',
            '{"src": "%s"}' % private_data_dir, '-vvvvv'
        ],
                                       '/awx_devel/awx/playbooks',
                                       mgr.management_env,
                                       mock.ANY,
                                       cancelled_callback=None,
                                       idle_timeout=0,
                                       job_timeout=0,
                                       pexpect_timeout=5,
                                       proot_cmd='bwrap')
コード例 #6
0
ファイル: test_expect.py プロジェクト: benwsapp/awx
def test_check_isolated_job_with_multibyte_unicode(private_data_dir):
    """
    Ensure that multibyte unicode is properly synced when stdout only
    contains the first part of the multibyte character

    see: https://github.com/ansible/tower/issues/2315
    """
    def raw_output():
        yield ('failed', '\xe8\xb5\xb7\xe5')  # 起 <partial byte>
        yield ('successful', '\xe8\xb5\xb7\xe5\x8b\x95')  # 起動

    raw_output = raw_output()
    stdout = StringIO.StringIO()
    mgr = isolated_manager.IsolatedManager(['ls', '-la'], HERE, {}, stdout, '')
    mgr.private_data_dir = private_data_dir
    mgr.instance = mock.Mock(id=123,
                             pk=123,
                             verbosity=5,
                             spec_set=['id', 'pk', 'verbosity'])
    mgr.started_at = time.time()
    mgr.host = 'isolated-host'

    os.mkdir(os.path.join(private_data_dir, 'artifacts'))
    with mock.patch('awx.main.expect.run.run_pexpect') as run_pexpect:

        def _synchronize_job_artifacts(args, cwd, env, buff, **kw):
            buff.write('checking job status...')
            status, out = next(raw_output)
            for filename, data in (['status', status], ['rc',
                                                        '0'], ['stdout', out]):
                with open(
                        os.path.join(private_data_dir, 'artifacts', filename),
                        'w') as f:
                    f.write(data)
                    f.flush()
            return (status, 0)

        run_pexpect.side_effect = _synchronize_job_artifacts
        with mock.patch.object(mgr, '_missing_artifacts') as missing_artifacts:
            missing_artifacts.return_value = False
            status, rc = mgr.check(interval=0)

        assert stdout.getvalue() == '起動'
コード例 #7
0
def test_run_isolated_job(private_data_dir, rsa_key):
    env = {'JOB_ID': '1'}
    pem, passphrase = rsa_key
    mgr = isolated_manager.IsolatedManager(
        ['ls', '-la'], HERE, env, StringIO(), ''
    )
    mgr.private_data_dir = private_data_dir
    secrets = {
        'env': env,
        'passwords': {
            r'Enter passphrase for .*:\s*?$': passphrase
        },
        'ssh_key_data': pem
    }
    mgr.build_isolated_job_data()
    stdout = StringIO()
    # Mock environment variables for callback module
    status, rc = run.run_isolated_job(private_data_dir, secrets, stdout)
    assert status == 'successful'
    assert rc == 0
    assert FILENAME in stdout.getvalue()

    assert env['AWX_ISOLATED_DATA_DIR'] == private_data_dir