Beispiel #1
0
def command_for(name):
    cls = Command.named(name)
    env = {"MERKELY_COMMAND": name}
    external = External(env=env)
    return cls(external)
def test_raises_when_is_a_dir(capsys):
    with dry_run(core_env_vars()) as env:
        external = External(env=env)
        with ScopedDirCopier("/app/tests/data", "/data/Merkelypipe.json"):
            with raises(ChangeError):
                run(external)
Beispiel #3
0
def test_green(capsys):
    with dry_run(core_env_vars()) as env, scoped_merkelypipe_json():
        run(External(env=env))

    verify_approval(capsys)
def test_raises_when_not_found(capsys):
    with dry_run(core_env_vars()) as env, raises(ChangeError):
        # no /data/Merkelypipe.json
        run(External(env=env))
def test_raises_when_invalid_json(capsys):
    with dry_run(core_env_vars()) as env:
        external = External(env=env)
        with ScopedFileCopier("/app/tests/data/Merkelypipe.bad.json", "/Merkelypipe.json"):
            with raises(ChangeError):
                run(external)
def test_bitbucket(capsys):
    env = {
        "CDB_COMMAND": "control_junit",
        "CDB_PIPELINE_DEFINITION": "tests/data/pipefile.json",
        "CDB_API_TOKEN": API_TOKEN,
        "CDB_ARTIFACT_SHA": SHA256,
        "CDB_TEST_RESULTS_DIR": "/app/tests/data/control_junit/xml-with-fails",
        "BITBUCKET_COMMIT": COMMIT,
        "BITBUCKET_BUILD_NUMBER": BUILD_NUMBER,
        "BITBUCKET_WORKSPACE": BB_ORG,
        "BITBUCKET_REPO_SLUG": BB_REPO,
    }
    set_env_vars = {
        'CDB_ARTIFACT_GIT_URL':
        f'https://{BB}/{BB_ORG}/{BB_REPO}/commits/{COMMIT}',
        'CDB_ARTIFACT_GIT_COMMIT':
        COMMIT,
        'CDB_BUILD_NUMBER':
        BUILD_NUMBER,
        'CDB_CI_BUILD_URL':
        f'https://{BB}/{BB_ORG}/{BB_REPO}/addon/pipelines/home#!/results/{BUILD_NUMBER}'
    }
    with dry_run(env, set_env_vars):
        pipe = BitbucketPipe(pipe_metadata='/pipe.yml', schema=schema)
        pipe.run()

    verify_approval(capsys)

    # extract data from approved cdb text file
    import inspect
    this_test = inspect.stack()[0].function
    approved = f"{APPROVAL_DIR}/{APPROVAL_FILE}.{this_test}.approved.txt"
    with open(approved) as file:
        old_approval = file.read()
    _old_blurb, old_method, old_payload, old_url = extract_blurb_method_payload_url(
        old_approval)

    expected_method = "Putting"
    expected_url = f"https://{DOMAIN}/api/v1/projects/{OWNER}/{PIPELINE}/artifacts/{SHA256}"
    expected_payload = {
        "contents": {
            "description":
            "JUnit results xml verified by compliancedb/cdb_controls: Tests contain failures",
            "is_compliant":
            False,
            "url":
            f"https://{BB}/{BB_ORG}/{BB_REPO}/addon/pipelines/home#!/results/{BUILD_NUMBER}"
        },
        "evidence_type": EVIDENCE_TYPE
    }

    # verify data from approved cdb text file
    assert old_payload == expected_payload
    assert old_method == expected_method
    assert old_url == expected_url

    # make merkely call
    ev = new_log_test_env()
    with dry_run(ev) as env:
        with ScopedDirCopier('/app/tests/data/control_junit/xml-with-fails',
                             '/data/junit'):
            with MockDockerFingerprinter(IMAGE_NAME, SHA256) as fingerprinter:
                external = External(env=env,
                                    docker_fingerprinter=fingerprinter)
                method, url, payload = run(external)

    capsys_read(capsys)

    # verify matching data
    assert method == expected_method
    assert url == expected_url

    # image name has changed
    old_description = expected_payload['contents']['description']
    new_description = old_description.replace('compliancedb/cdb_controls',
                                              'merkely/change')
    expected_payload['contents']['description'] = new_description

    # user_data works did not work in cdb code
    expected_payload["user_data"] = {'status': 'deployed'}

    assert payload == expected_payload
def test_env_var_can_override_the_default():
    os_env = {"MERKELY_PIPE_PATH": "/app/tests/data/Merkelypipe.acme-roadrunner.json"}
    external = External(env=os_env)
    json = external.merkelypipe
    assert json['owner'] == 'acme'
def test_all_env_vars_file(capsys, mocker):
    """
    New: MERKELY_COMMAND=log_evidence
         MERKELY_FINGERPRINT="file://${FILE_PATH}"
         docker run ... merkely/change
    Old: CDB_ARTIFACT_FILENAME=${FILE_PATH}
         docker run ... cdb.put_artifact ...
    """
    # input data
    commit = "abc50c8a53f79974d615df335669b59fb56a4444"
    sha256 = "ccdd89ccdc05772d90dc6929ad4f1fbc14aa105addf3326aa5cf575a104f5115"
    directory = "app/tests/data"
    filename = "jam.jar"
    artifact_name = f"{directory}/{filename}"
    build_url = "https://gitlab/build/1456"
    build_number = '23'

    # make cdb call
    old_env = old_put_artifact_env(commit)
    old_env["CDB_ARTIFACT_FILENAME"] = artifact_name
    set_env_vars = {'CDB_ARTIFACT_SHA': sha256}
    with dry_run(old_env, set_env_vars):
        mocker.patch('cdb.cdb_utils.calculate_sha_digest_for_file', return_value=sha256)
        put_artifact("tests/integration/test-pipefile.json")

    # compare with approved cdb text file
    verify_approval(capsys, ["out"])

    # extract data from approved cdb text file
    this_test = "test_all_env_vars_file"
    approved = f"{APPROVAL_DIR}/{APPROVAL_FILE}.{this_test}.approved.txt"
    with open(approved) as file:
        old_approval = file.read()
    _old_blurb, old_method, old_payload, old_url = extract_blurb_method_payload_url(old_approval)

    expected_method = "Putting"
    expected_url = f"https://{DOMAIN}/api/v1/projects/{OWNER}/{PIPELINE}/artifacts/"
    expected_payload = {
        'build_url': build_url,
        'commit_url': commit_url(commit),
        'description': f'Created by build {build_number}',
        'filename': artifact_name,
        'git_commit': commit,
        'is_compliant': True,
        'sha256': sha256,
    }

    # verify data from approved cdb text file
    assert old_method == expected_method
    assert old_url == expected_url
    assert old_payload == expected_payload

    # make merkely call
    protocol = "file://"
    ev = new_log_artifact_env(commit)
    ev["MERKELY_FINGERPRINT"] = f"{protocol}{artifact_name}"
    with dry_run(ev) as env:
        with MockFileFingerprinter(artifact_name, sha256) as fingerprinter:
            external = External(env=env, file_fingerprinter=fingerprinter)
            method, url, payload = run(external)

    # verify matching data
    assert method == expected_method
    assert url == expected_url

    # CHANGE IN BEHAVIOUR
    expected_payload['user_data'] = {}
    expected_payload['filename'] = filename
    assert payload == expected_payload

    assert extract_blurb(capsys_read(capsys)) == [
        'MERKELY_COMMAND=log_artifact',
        'MERKELY_IS_COMPLIANT: True',
    ]
def test_zero_exit_status_when_there_is_a_data_directory(capsys, mocker):
    """
    The cdb code looks at CDB_USER_DATA but the line to add
    the json (in cdb_utils.py build_evidence_dict) is this:

    if user_data is not None:
        evidence["user_data"]: user_data

    which should be

    if user_data is not None:
        evidence["user_data"] = user_data

    So that functionality does not exist in the old cdb code.
    """
    image_name = "acme/widget:4.67"
    sha256 = "aecdaef69c676c2466571d3233380d559ccc2032b258fc5e73f99a103db462ef"
    build_url = "https://gitlab/build/1457"
    evidence_type = "coverage"
    env = old_control_junit_env()
    set_env_vars = {}
    with dry_run(env, set_env_vars):
        with ScopedDirCopier(
                '/app/tests/data/control_junit/xml-with-passed-results',
                '/data/junit'):
            mocker.patch('cdb.cdb_utils.calculate_sha_digest_for_docker_image',
                         return_value=sha256)
            control_junit("tests/integration/test-pipefile.json")

    verify_approval(capsys, ["out"])

    # extract data from approved cdb text file
    import inspect
    this_test = inspect.stack()[0].function
    approved = f"{APPROVAL_DIR}/{APPROVAL_FILE}.{this_test}.approved.txt"
    with open(approved) as file:
        old_approval = file.read()
    _old_blurb, old_method, old_payload, old_url = extract_blurb_method_payload_url(
        old_approval)

    expected_method = "Putting"
    expected_url = f"https://{DOMAIN}/api/v1/projects/{OWNER}/{PIPELINE}/artifacts/{sha256}"
    expected_payload = {
        "contents": {
            "description":
            "JUnit results xml verified by compliancedb/cdb_controls: All tests passed in 2 test suites",
            "is_compliant": True,
            "url": build_url
        },
        "evidence_type": evidence_type
    }

    # verify data from approved cdb text file
    assert old_method == expected_method
    assert old_url == expected_url
    assert old_payload == expected_payload

    # make merkely call
    ev = new_log_test_env()
    with dry_run(ev) as env:
        with MockDockerFingerprinter(image_name, sha256) as fingerprinter:
            with ScopedDirCopier(
                    '/app/tests/data/control_junit/xml-with-passed-results',
                    '/data/junit'):
                external = External(env=env,
                                    docker_fingerprinter=fingerprinter)
                method, url, payload = run(external)

    capsys_read(capsys)

    # verify matching data
    assert method == expected_method
    assert url == expected_url

    # image name has changed
    string = expected_payload['contents']['description']
    string = string.replace('compliancedb/cdb_controls', 'merkely/change')
    expected_payload['contents']['description'] = string

    # user_data works in new code
    expected_payload["user_data"] = {'status': 'deployed'}

    assert payload == expected_payload
def test_all_env_vars_sha(capsys):
    """
    New: MERKELY_COMMAND=log_evidence
         MERKELY_FINGERPRINT="sha256://${SHA256}/${FILE_PATH}"
         docker run ... merkely/change
    Old: CDB_ARTIFACT_FILENAME=${FILE_PATH}
         CDB_ARTIFACT_SHA=${SHA256}
         docker run ... cdb.put_artifact ...
    """

    commit = "abc50c8a53f79974d615df335669b59fb56a4ed4"
    artifact_name = "door-is-a.jar"
    sha256 = "444daef69c676c2466571d3211180d559ccc2032b258fc5e73f99a103db462ef"
    build_url = "https://gitlab/build/1456"
    build_number = '23'

    env = old_put_artifact_env(commit)
    env["CDB_ARTIFACT_FILENAME"] = artifact_name
    env["CDB_ARTIFACT_SHA"] = sha256
    set_env_vars = {}
    with dry_run(env, set_env_vars):
        put_artifact("tests/integration/test-pipefile.json")

    verify_approval(capsys, ["out"])

    # extract data from approved cdb text file
    this_test = "test_all_env_vars_sha"
    approved = f"{APPROVAL_DIR}/{APPROVAL_FILE}.{this_test}.approved.txt"
    with open(approved) as file:
        old_approval = file.read()
    _old_blurb, old_method, old_payload, old_url = extract_blurb_method_payload_url(old_approval)

    expected_method = "Putting"
    expected_url = f"https://{DOMAIN}/api/v1/projects/{OWNER}/{PIPELINE}/artifacts/"
    expected_payload = {
        "build_url": build_url,
        "commit_url": commit_url(commit),
        "description": f"Created by build {build_number}",
        "filename": artifact_name,
        "git_commit": commit,
        "is_compliant": True,
        "sha256": sha256
    }

    # verify data from approved cdb text file
    assert old_method == expected_method
    assert old_url == expected_url
    assert old_payload == expected_payload

    # make merkely call
    protocol = "sha256://"
    ev = new_log_artifact_env(commit)
    ev["MERKELY_FINGERPRINT"] = f"{protocol}{sha256}/{artifact_name}"
    with dry_run(ev) as env:
        method, url, payload = run(External(env=env))

    # CHANGE IN BEHAVIOUR
    expected_payload['user_data'] = {}

    # verify matching data
    assert method == expected_method
    assert url == expected_url
    assert payload == expected_payload

    assert extract_blurb(capsys_read(capsys)) == [
        'MERKELY_COMMAND=log_artifact',
        'MERKELY_IS_COMPLIANT: True',
    ]
def make_command_env_vars():
    klass = Command.named('log_artifact')
    env = new_log_artifact_env()
    external = External(env=env)
    return klass(external).merkely_env_vars
def test_all_env_vars_image(capsys, mocker):
    """
    Old: CDB_ARTIFACT_DOCKER_IMAGE=${IMAGE_NAME}
         docker run ... cdb.put_artifact_image ...

    New: MERKELY_COMMAND=log_evidence
         MERKELY_FINGERPRINT="docker://${IMAGE_NAME}"
         docker run ... merkely/change
    """
    # input data
    sha256 = "ddcdaef69c676c2466571d3233380d559ccc2032b258fc5e73f99a103db462ee"
    commit = "12037940e4e7503055d8a8eea87e177f04f14616"
    image_name = "acme/widget:3.4"
    build_url = "https://gitlab/build/1456"
    build_number = "23"

    # make cdb call
    env = old_put_artifact_env(commit)
    env["CDB_ARTIFACT_DOCKER_IMAGE"] = image_name
    with dry_run(env):
        mocker.patch('cdb.cdb_utils.calculate_sha_digest_for_docker_image', return_value=sha256)
        put_artifact_image("tests/integration/test-pipefile.json")  # <<<<<<

    # compare with approved cdb text file
    verify_approval(capsys, ["out"])

    # extract data from approved cdb text file
    this_test = "test_all_env_vars_image"
    approved = f"{APPROVAL_DIR}/{APPROVAL_FILE}.{this_test}.approved.txt"
    with open(approved) as file:
        old_approval = file.read()
    _old_blurb, old_method, old_payload, old_url = extract_blurb_method_payload_url(old_approval)

    expected_method = "Putting"
    expected_url = f"https://{DOMAIN}/api/v1/projects/{OWNER}/{PIPELINE}/artifacts/"
    expected_payload = {
        "build_url": build_url,
        "commit_url": commit_url(commit),
        "description": f"Created by build {build_number}",
        "filename": image_name,
        "git_commit": commit,
        "is_compliant": True,
        "sha256": sha256
    }

    # verify data from approved cdb text file
    assert old_method == expected_method
    assert old_url == expected_url
    assert old_payload == expected_payload

    # make merkely call
    protocol = "docker://"
    ev = new_log_artifact_env(commit)
    ev["MERKELY_FINGERPRINT"] = f"{protocol}{image_name}"
    with dry_run(ev) as env:
        with MockDockerFingerprinter(image_name, sha256) as fingerprinter:
            external = External(env=env, docker_fingerprinter=fingerprinter)
            method, url, payload = run(external)

    # CHANGE IN BEHAVIOUR
    expected_payload['user_data'] = {}

    # verify matching data
    assert method == expected_method
    assert url == expected_url
    assert payload == expected_payload

    assert extract_blurb(capsys_read(capsys)) == [
        'MERKELY_COMMAND=log_artifact',
        'MERKELY_IS_COMPLIANT: True',
    ]
def test_docker_image(capsys, mocker):
    image_name = "acme/runner:4.56"
    sha256 = "bbcdaef69c676c2466571d3233380d559ccc2032b258fc5e73f99a103db46212"
    merkleypipe_dir = "tests/data"
    merkelypipe = "test-pipefile.json"
    mock_artifacts_for_commit = {"artifacts": [{"sha256": sha256}]}
    env = {
        "CDB_API_TOKEN": API_TOKEN,
        "CDB_ARTIFACT_DOCKER_IMAGE": image_name,
        "CDB_BASE_SRC_COMMITISH": "production",
        "CDB_TARGET_SRC_COMMITISH": "master",
        "CDB_DESCRIPTION": "The approval description here",
        "CDB_IS_APPROVED_EXTERNALLY": "TRUE",
    }
    set_env_vars = {"CDB_ARTIFACT_SHA": sha256}
    with dry_run(env,
                 set_env_vars) as env, ScopedDirCopier("/test_src", "/src"):
        mocker.patch('cdb.cdb_utils.calculate_sha_digest_for_docker_image',
                     return_value=sha256)
        mocker.patch('cdb.create_release.get_artifacts_for_commit',
                     return_value=mock_artifacts_for_commit)
        create_approval(f"{merkleypipe_dir}/{merkelypipe}", env)

    verify_approval(capsys, ["out"])

    # extract data from approved cdb text file
    this_test = "test_docker_image"
    approved = f"{APPROVAL_DIR}/{APPROVAL_FILE}.{this_test}.approved.txt"
    with open(approved) as file:
        old_approval = file.read()
    _old_blurb, old_method, old_payload, old_url = extract_blurb_method_payload_url(
        old_approval)

    expected_method = "Posting"
    expected_url = f"https://{DOMAIN}/api/v1/projects/{OWNER}/{PIPELINE}/approvals/"
    expected_payload = {
        "artifact_sha256":
        sha256,
        "description":
        "The approval description here",
        "is_approved":
        True,
        "src_commit_list": [
            "8f5b384644eb83e7f2a6d9499539a077e7256b8b",
            "e0ad84e1a2464a9486e777c1ecde162edff930a9"
        ],
    }

    # verify data from approved cdb text file
    assert old_method == expected_method
    assert old_url == expected_url
    assert old_payload == expected_payload

    # make merkely call
    ev = new_log_approval_env()
    with dry_run(ev) as env:
        with ScopedDirCopier("/test_src", "/src"):
            with MockDockerFingerprinter(image_name, sha256) as fingerprinter:
                external = External(env=env,
                                    docker_fingerprinter=fingerprinter)
                method, url, payload = run(external)

    capsys_read(capsys)

    # CHANGE IN BEHAVIOUR
    expected_payload['user_data'] = {}
    del expected_payload['is_approved']
    expected_payload['approvals'] = [{
        "state": "APPROVED",
        "comment": expected_payload["description"],
        "approved_by": "External",
        "approval_url": "undefined"
    }]

    # verify matching data
    assert method == expected_method
    assert url == expected_url
    assert payload == expected_payload
def make_fingerprint_env_var(fingerprint):
    env = {"MERKELY_FINGERPRINT": fingerprint}
    return FingerprintEnvVar(External(env=env))
def test_required_is_true():
    env = core_env_vars()
    command = DeclarePipeline(External(env=env))
    assert command.api_token.is_required('bitbucket')
def test_defaults_to_Merkelypipe_dot_json_in_data_dir():
    os_env = {}
    external = External(env=os_env)
    with ScopedFileCopier('/app/tests/data/Merkelypipe.json', '/data/Merkelypipe.json'):
        json = external.merkelypipe
    assert json['owner'] == 'merkely-test'
Beispiel #17
0
from commands import External, main
import sys

if __name__ == '__main__':
    external = External()
    sys.exit(main(external))
def test_docker_protocol(capsys, mocker):
    # input data
    build_url = "https://gitlab/build/1956"
    sha256 = "bbcdaef69c676c2466571d3233380d559ccc2032b258fc5e73f99a103db462ef"
    protocol = "docker://"
    image_name = "acme/widget:4.67"

    # make cdb call
    cdb_env = {
        "CDB_API_TOKEN": API_TOKEN,
        "CDB_ARTIFACT_DOCKER_IMAGE": image_name,
        "CDB_IS_COMPLIANT": "TRUE",
        "CDB_EVIDENCE_TYPE": "unit_test",
        "CDB_DESCRIPTION": "branch coverage",
        "CDB_CI_BUILD_URL": build_url,
    }
    with dry_run(cdb_env):
        mocker.patch('cdb.cdb_utils.calculate_sha_digest_for_docker_image', return_value=sha256)
        put_evidence("tests/integration/test-pipefile.json")
        
    # compare with approved cdb text file
    verify_approval(capsys, ["out"])

    # extract data from approved cdb text file
    this_test = "test_docker_protocol"
    approved = f"{APPROVAL_DIR}/{APPROVAL_FILE}.{this_test}.approved.txt"
    with open(approved) as file:
        old_approval = file.read()
    _old_blurb, old_method, old_payload, old_url = extract_blurb_method_payload_url(old_approval)

    expected_method = "Putting"
    expected_url = f"https://{DOMAIN}/api/v1/projects/{OWNER}/{PIPELINE}/artifacts/{sha256}"
    expected_payload = {
        "contents": {
            "description": "branch coverage",
            "is_compliant": True,
            "url": build_url
        },
        "evidence_type": "unit_test"
    }

    # verify data from approved cdb text file
    assert old_method == expected_method
    assert old_url == expected_url
    assert old_payload == expected_payload

    # make merkely call
    ev = new_log_evidence_env()
    ev["MERKELY_FINGERPRINT"] = f"{protocol}{image_name}"
    with dry_run(ev) as env:
        with MockDockerFingerprinter(image_name, sha256) as fingerprinter:
            external = External(env=env, docker_fingerprinter=fingerprinter)
            method, url, payload = run(external)

    # CHANGE IN BEHAVIOUR
    expected_payload['user_data'] = {}

    # verify matching data
    assert method == expected_method
    assert url == expected_url
    assert payload == expected_payload

    assert extract_blurb(capsys_read(capsys)) == [
        'MERKELY_COMMAND=log_evidence',
        'MERKELY_IS_COMPLIANT: True',
    ]