def test_invalid_tags(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        tags="a,b,c")
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        tags=["a", "ab,c"])
def test_set_failed_reason(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)

    job = runner.request_job()
    with pytest.raises(ValueError):
        job.set_failed(failure_reason="unknown_failure")

    job = runner.request_job()
    job.set_failed(failure_reasons.ApiFailure())
    gitlab_api.completed_jobs[-1].failure_reason == "api_failure"

    job = runner.request_job()
    job.set_failed(failure_reasons.MissingDependencyFailure())
    gitlab_api.completed_jobs[-1].failure_reason == "missing_dependency_failure"

    job = runner.request_job()
    job.set_failed(failure_reasons.RunnerSystemFailure())
    gitlab_api.completed_jobs[-1].failure_reason == "runner_system_failure"

    job = runner.request_job()
    job.set_failed(failure_reasons.ScriptFailure())
    gitlab_api.completed_jobs[-1].failure_reason == "script_failure"

    job = runner.request_job()
    job.set_failed(failure_reasons.StuckOrTimeoutFailure())
    gitlab_api.completed_jobs[-1].failure_reason == "stuck_or_timeout_failure"

    job = runner.request_job()
    job.set_failed(failure_reasons.UnknownFailure())
    gitlab_api.completed_jobs[-1].failure_reason == "unknown_failure"

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 3
    assert len(gitlab_api.running_jobs) == 1
    assert len(gitlab_api.completed_jobs) == 6
def test_serialise(gitlab_api):
    runner = Runner.register(
        "https://gitlab.cern.ch",
        gitlab_api.token,
        name="The runner name",
        description="The runner description",
        active=True,
        locked=False,
        run_untagged=True,
        tags=["dirac", "docker", "cvmfs"],
        maximum_timeout=24 * 60 * 60,
        version="1.0",
        revision="a94b1e",
        platform="linux",
        architecture="x86_64",
        executor="dirac",
    )

    as_string = runner.dumps()
    runner_from_string = Runner.loads(as_string)
    assert runner == runner_from_string

    with tempfile.NamedTemporaryFile() as fp:
        runner.dump(fp.name)
        runner_from_file = Runner.load(fp.name)
    assert runner == runner_from_file
def test_set_state(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)

    job = runner.request_job()
    assert job.state == "running"

    with pytest.raises(ValueError):
        job.state = "badstate"
    assert job.state == "running"

    job.state = "success"
    assert job.state == "success"

    with pytest.raises(AlreadyFinishedExcpetion):
        job.state = "running"
    assert job.state == "success"

    with pytest.raises(AlreadyFinishedExcpetion):
        job.state = "success"
    assert job.state == "success"

    with pytest.raises(AlreadyFinishedExcpetion):
        job.state = "failed"
    assert job.state == "success"

    with pytest.raises(ValueError):
        job.state = "badstate"
def test_set_success_with_log(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()
    job.log += "test log text"
    job.set_success()

    # Check the API's internal state
    check_finished(1, 0, 1, "success", "test log text", None)
def test_set_failed_with_log(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()
    job.log += "test log text"
    job.set_failed()

    # Check the API's internal state
    check_finished(1, 0, 1, "failed", "test log text", "unknown_failure")
def test_request_job(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    assert isinstance(runner.request_job(), Job)
    assert isinstance(runner.request_job(), Job)
    assert runner.request_job() is None

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 0
    assert len(gitlab_api.running_jobs) == 2
    assert len(gitlab_api.completed_jobs) == 0
def test_set_success_twice(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()

    job.set_success()

    with pytest.raises(AlreadyFinishedExcpetion):
        job.set_success()

    # Check the API's internal state
    check_finished(1, 0, 1, "success", "", None)
def test_bad_log(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()

    with pytest.raises(TypeError):
        job.log += 3456789

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 1
    assert len(gitlab_api.running_jobs) == 1
    assert len(gitlab_api.completed_jobs) == 0
def test_set_failed_twice(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()

    job.set_failed()

    with pytest.raises(AlreadyFinishedExcpetion):
        job.set_failed()

    # Check the API's internal state
    check_finished(1, 0, 1, "failed", "", "unknown_failure")
def test_request_job_invalid_token(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    runner.request_job()
    runner._token = "invalid_token"
    with pytest.raises(AuthException):
        runner.request_job()

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 1
    assert len(gitlab_api.running_jobs) == 1
    assert len(gitlab_api.completed_jobs) == 0
def test_variables(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()

    api_variables = gitlab_api.running_jobs[0].as_dict()["variables"]
    job_variables = {v.key: v for v in job.variables}
    assert len(api_variables) == len(job.variables) - 3
    for api_var in api_variables:
        job_variable = job_variables[api_var["key"]]
        assert api_var["key"] == job_variable.key
        assert api_var["value"] == job_variable.value
        assert api_var["public"] is job_variable.is_public
def test_repr(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()
    print(repr(job))
    assert str(job.id) in repr(job)
    assert str(job.token) in repr(job)
    assert str(job.state) in repr(job)

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 1
    assert len(gitlab_api.running_jobs) == 1
    assert len(gitlab_api.completed_jobs) == 0
def test_bad_job_info(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()

    job_info = deepcopy(job._job_info)
    del job_info["variables"]
    with pytest.raises(KeyError):
        Job(runner, job_info, fail_on_error=False)

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 1
    assert len(gitlab_api.running_jobs) == 1
    assert len(gitlab_api.completed_jobs) == 0
def test_serialise_invalid_version(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    serialised_runner = json.loads(runner.dumps())
    serialised_runner[0] = 2
    as_string = json.dumps(serialised_runner)

    with pytest.raises(ValueError):
        Runner.loads(as_string)

    with tempfile.NamedTemporaryFile(mode="wt") as fp:
        json.dump(as_string, fp)
        fp.flush()
        with pytest.raises(ValueError):
            Runner.load(fp.name)
def test_serialise(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()

    as_string = job.dumps()
    job_from_string = Job.loads(as_string)
    assert job == job_from_string

    with tempfile.NamedTemporaryFile() as fp:
        job.dump(fp.name)
        job_from_file = Job.load(fp.name)
    assert job == job_from_file

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 1
    assert len(gitlab_api.running_jobs) == 1
    assert len(gitlab_api.completed_jobs) == 0
def test_bad_job_info_and_fail(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()

    job_info = deepcopy(job._job_info)
    del job_info["variables"]
    with pytest.raises(KeyError):
        Job(runner, job_info)

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 1
    assert len(gitlab_api.running_jobs) == 0
    assert len(gitlab_api.completed_jobs) == 1

    assert gitlab_api.completed_jobs[0].status == "failed"
    assert "KeyError" in gitlab_api.completed_jobs[0].log
    assert gitlab_api.completed_jobs[0].failure_reason == "runner_system_failure"
def test_register_with_parameters(gitlab_api):
    runner = Runner.register(
        "https://gitlab.cern.ch",
        gitlab_api.token,
        name="The runner name",
        description="The runner description",
        active=True,
        locked=False,
        run_untagged=True,
        tags=["dirac", "docker", "cvmfs"],
        maximum_timeout=24 * 60 * 60,
        version="1.0",
        revision="a94b1e",
        platform="linux",
        architecture="x86_64",
        executor="dirac",
    )
    check_runner(gitlab_api, runner)
def test_serialise_invalid_version(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()
    serialised_job = json.loads(job.dumps())
    serialised_job[0] = 2
    as_string = json.dumps(serialised_job)

    with pytest.raises(ValueError):
        Job.loads(as_string)

    with tempfile.NamedTemporaryFile(mode="wt") as fp:
        json.dump(as_string, fp)
        fp.flush()
        with pytest.raises(ValueError):
            Job.load(fp.name)

    # Check the API's internal state
    assert len(gitlab_api.pending_jobs) == 1
    assert len(gitlab_api.running_jobs) == 1
    assert len(gitlab_api.completed_jobs) == 0
def test_invalid_active(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        active="True")
def test_invalid_run_untagged(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        run_untagged="True")
def test_register_without_parameters(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    check_runner(gitlab_api, runner)
def test_set_failed_with_artifacts(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    job = runner.request_job()
    job.set_failed(artifacts=[])
def test_invalid_maximum_timeout(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        maximum_timeout="100")
def test_invalid_revision(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch", gitlab_api.token, revision=1)
def test_invalid_platform(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        platform=[])
def test_invalid_architecture(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        architecture=[])
def test_invalid_executor(gitlab_api):
    with pytest.raises(ValueError):
        Runner.register("https://gitlab.cern.ch",
                        gitlab_api.token,
                        executor=[])
def test_equality(gitlab_api):
    runner_1 = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    runner_2 = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    assert runner_1 == runner_1
    assert runner_2 == runner_2
    assert runner_1 != runner_2
def test_repr(gitlab_api):
    runner = Runner.register("https://gitlab.cern.ch", gitlab_api.token)
    print(repr(runner))
    assert runner.token in repr(runner)