From 7b0ac8a40a9151b1e3a5e0f4eb3227478e7987e1 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Wed, 11 Jun 2025 21:04:20 +0000 Subject: [PATCH 01/20] test with setup-sigstore-env Signed-off-by: Ramon Petgrave --- .../test-with-setup-sigstore-env.yml | 36 +++++++++++++++++++ test/unit/conftest.py | 23 ++++++++++++ test/unit/test_sign.py | 4 ++- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test-with-setup-sigstore-env.yml diff --git a/.github/workflows/test-with-setup-sigstore-env.yml b/.github/workflows/test-with-setup-sigstore-env.yml new file mode 100644 index 000000000..274a3b04c --- /dev/null +++ b/.github/workflows/test-with-setup-sigstore-env.yml @@ -0,0 +1,36 @@ +name: test-with-setup-sigstore-env + +on: + push: + branches: + - main + - series/* + pull_request: + schedule: + - cron: '0 12 * * *' + +jobs: + test: + runs-on: ubuntu-latest + steps: + # TODO: use new release + - id: setup-sigstore-env + uses: sigstore/scaffolding/actions/setup-sigstore-env@c1697866accfa0fbe21caf7e16ab85f236695428 # main + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + # use the version specified by this project. + python-version-file: pyproject.toml + allow-prereleases: true + cache: "pip" + cache-dependency-path: pyproject.toml + - run: | + export TEST_SETUP_SIGSTORE_ENV="any non-empty value" + export SIGSTORE_IDENTITY_TOKEN_local=$( cat ${{ steps.setup-sigstore-env.outputs.oidc-token }} ) + export TRUST_CONFIG=${{ steps.setup-sigstore-env.outputs.trust-config }} + + set -o pipefail + make test TEST_ARGS="-k test_sign_rekor_entry_consistent-rs" | tee output + ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) diff --git a/test/unit/conftest.py b/test/unit/conftest.py index d40d8d7fc..521296f69 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -48,6 +48,16 @@ assert _TUF_ASSETS.is_dir() TEST_CLIENT_ID = "sigstore" +LOCAL = "local" + + +def _has_setup_sigstore_env() -> bool: + """ + Checks whether the TEST_SETUP_SIGSTORE_ENV variable is set to true, + This means we are using the sigstore/scaffolding/actions/setup-sigstore-env + that has the sigstore services in containers available for us to use. + """ + return bool(os.getenv("TEST_SETUP_SIGSTORE_ENV", False)) @pytest.fixture @@ -194,6 +204,8 @@ def sign_ctx_and_ident_for_env( """ Returns a SigningContext and IdentityToken for the given environment. The SigningContext is behind a callable so that it may be lazily evaluated. + + The local tests require setup by the test-with-setup-sigstore-env.yml workflow. """ if env == "staging": @@ -205,6 +217,17 @@ def ctx_cls(): def ctx_cls(): return SigningContext.from_trust_config(ClientTrustConfig.production()) + elif env == "local": + print("HAS", _has_setup_sigstore_env()) + if not _has_setup_sigstore_env(): + pytest.skip( + "skipping test that use the local environment due to unset `TEST_SETUP_SIGSTORE_ENV` env variable" + ) + def ctx_cls(): + return SigningContext.from_trust_config(ClientTrustConfig.from_json( + Path(os.getenv("TRUST_CONFIG")).read_text() + )) + else: raise ValueError(f"Unknown env {env}") diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index 244cfc8e7..79ef0665c 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -19,6 +19,8 @@ import pytest from sigstore_protobuf_specs.dev.sigstore.common.v1 import HashAlgorithm +from .conftest import LOCAL + import sigstore.oidc from sigstore._internal.timestamp import TimestampAuthorityClient from sigstore._internal.trust import ClientTrustConfig @@ -29,7 +31,7 @@ from sigstore.verify.policy import UnsafeNoOp -@pytest.mark.parametrize("env", ["staging", "production"]) +@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) @pytest.mark.ambient_oidc def test_sign_rekor_entry_consistent(sign_ctx_and_ident_for_env): ctx_cls, identity = sign_ctx_and_ident_for_env From 9a711f379193a45ba9b0696bd367730c52f43021 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Wed, 11 Jun 2025 21:31:17 +0000 Subject: [PATCH 02/20] typo Signed-off-by: Ramon Petgrave --- .github/workflows/test-with-setup-sigstore-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-with-setup-sigstore-env.yml b/.github/workflows/test-with-setup-sigstore-env.yml index 274a3b04c..af836667a 100644 --- a/.github/workflows/test-with-setup-sigstore-env.yml +++ b/.github/workflows/test-with-setup-sigstore-env.yml @@ -32,5 +32,5 @@ jobs: export TRUST_CONFIG=${{ steps.setup-sigstore-env.outputs.trust-config }} set -o pipefail - make test TEST_ARGS="-k test_sign_rekor_entry_consistent-rs" | tee output + make test TEST_ARGS="-k test_sign_rekor_entry_consistent -rs" | tee output ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) From 5e43e008a5e95bed0cce0e4aa34c2bb8b56e753a Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Wed, 11 Jun 2025 21:57:19 +0000 Subject: [PATCH 03/20] -v Signed-off-by: Ramon Petgrave --- .github/workflows/test-with-setup-sigstore-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-with-setup-sigstore-env.yml b/.github/workflows/test-with-setup-sigstore-env.yml index af836667a..3f45e28f2 100644 --- a/.github/workflows/test-with-setup-sigstore-env.yml +++ b/.github/workflows/test-with-setup-sigstore-env.yml @@ -32,5 +32,5 @@ jobs: export TRUST_CONFIG=${{ steps.setup-sigstore-env.outputs.trust-config }} set -o pipefail - make test TEST_ARGS="-k test_sign_rekor_entry_consistent -rs" | tee output + make test TEST_ARGS="-k test_sign_rekor_entry_consistent -rs -v" | tee output ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) From 84534f06ba51f8825d96a9f4fd188a52e08f6e6c Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 12 Jun 2025 21:28:08 +0000 Subject: [PATCH 04/20] clean whitespace Signed-off-by: Ramon Petgrave --- .github/workflows/test-with-setup-sigstore-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-with-setup-sigstore-env.yml b/.github/workflows/test-with-setup-sigstore-env.yml index 3f45e28f2..c40a9d5c2 100644 --- a/.github/workflows/test-with-setup-sigstore-env.yml +++ b/.github/workflows/test-with-setup-sigstore-env.yml @@ -30,7 +30,7 @@ jobs: export TEST_SETUP_SIGSTORE_ENV="any non-empty value" export SIGSTORE_IDENTITY_TOKEN_local=$( cat ${{ steps.setup-sigstore-env.outputs.oidc-token }} ) export TRUST_CONFIG=${{ steps.setup-sigstore-env.outputs.trust-config }} - + set -o pipefail make test TEST_ARGS="-k test_sign_rekor_entry_consistent -rs -v" | tee output ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) From 4eb0659afd3d851f3e9f94211e63050b31a10d6f Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 12 Jun 2025 21:32:28 +0000 Subject: [PATCH 05/20] lint Signed-off-by: Ramon Petgrave --- test/unit/conftest.py | 7 ++++--- test/unit/test_sign.py | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/unit/conftest.py b/test/unit/conftest.py index 521296f69..cd35635be 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -223,10 +223,11 @@ def ctx_cls(): pytest.skip( "skipping test that use the local environment due to unset `TEST_SETUP_SIGSTORE_ENV` env variable" ) + def ctx_cls(): - return SigningContext.from_trust_config(ClientTrustConfig.from_json( - Path(os.getenv("TRUST_CONFIG")).read_text() - )) + return SigningContext.from_trust_config( + ClientTrustConfig.from_json(Path(os.getenv("TRUST_CONFIG")).read_text()) + ) else: raise ValueError(f"Unknown env {env}") diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index 79ef0665c..d84075c0c 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -19,8 +19,6 @@ import pytest from sigstore_protobuf_specs.dev.sigstore.common.v1 import HashAlgorithm -from .conftest import LOCAL - import sigstore.oidc from sigstore._internal.timestamp import TimestampAuthorityClient from sigstore._internal.trust import ClientTrustConfig @@ -30,6 +28,8 @@ from sigstore.sign import SigningContext from sigstore.verify.policy import UnsafeNoOp +from .conftest import LOCAL + @pytest.mark.parametrize("env", ["staging", "production", LOCAL]) @pytest.mark.ambient_oidc From c8654d21eeb75b49463f3e377e17a566ee3afe59 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 12 Jun 2025 21:37:19 +0000 Subject: [PATCH 06/20] sign_ctx_and_ident_for_env with LOCAL for all Signed-off-by: Ramon Petgrave --- test/unit/test_sign.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index d84075c0c..0b87d5436 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -53,7 +53,7 @@ def test_sign_rekor_entry_consistent(sign_ctx_and_ident_for_env): assert expected_entry.log_index == actual_entry.log_index -@pytest.mark.parametrize("env", ["staging", "production"]) +@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) @pytest.mark.ambient_oidc def test_sct_verify_keyring_lookup_error(sign_ctx_and_ident_for_env, monkeypatch): ctx, identity = sign_ctx_and_ident_for_env @@ -72,7 +72,7 @@ def test_sct_verify_keyring_lookup_error(sign_ctx_and_ident_for_env, monkeypatch signer.sign_artifact(payload) -@pytest.mark.parametrize("env", ["staging", "production"]) +@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) @pytest.mark.ambient_oidc def test_sct_verify_keyring_error(sign_ctx_and_ident_for_env, monkeypatch): ctx, identity = sign_ctx_and_ident_for_env @@ -92,7 +92,7 @@ def test_sct_verify_keyring_error(sign_ctx_and_ident_for_env, monkeypatch): signer.sign_artifact(payload) -@pytest.mark.parametrize("env", ["staging", "production"]) +@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) @pytest.mark.ambient_oidc def test_identity_proof_claim_lookup(sign_ctx_and_ident_for_env, monkeypatch): ctx_cls, identity = sign_ctx_and_ident_for_env From 58dce198cf4fee283fe2a0213297f716f1fe2505 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 12 Jun 2025 21:37:55 +0000 Subject: [PATCH 07/20] rename to preprod Signed-off-by: Ramon Petgrave --- test/unit/conftest.py | 2 +- test/unit/test_sign.py | 12 ++++++------ test/unit/verify/test_verifier.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/unit/conftest.py b/test/unit/conftest.py index cd35635be..494217331 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -241,7 +241,7 @@ def ctx_cls(): @pytest.fixture -def staging() -> tuple[type[SigningContext], type[Verifier], IdentityToken]: +def preprod() -> tuple[type[SigningContext], type[Verifier], IdentityToken]: """ Returns a SigningContext, Verifier, and IdentityToken for the staging environment. The SigningContext and Verifier are both behind callables so that they may be lazily evaluated. diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index 0b87d5436..a2eb764ee 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -117,8 +117,8 @@ def test_identity_proof_claim_lookup(sign_ctx_and_ident_for_env, monkeypatch): @pytest.mark.staging @pytest.mark.ambient_oidc -def test_sign_prehashed(staging): - sign_ctx_cls, verifier_cls, identity = staging +def test_sign_prehashed(preprod): + sign_ctx_cls, verifier_cls, identity = preprod sign_ctx = sign_ctx_cls() verifier = verifier_cls() @@ -142,8 +142,8 @@ def test_sign_prehashed(staging): @pytest.mark.staging @pytest.mark.ambient_oidc -def test_sign_dsse(staging): - sign_ctx, _, identity = staging +def test_sign_dsse(preprod): + sign_ctx, _, identity = preprod ctx = sign_ctx() stmt = ( @@ -181,8 +181,8 @@ def sig_ctx(self, asset, tsa_url) -> SigningContext: return SigningContext.from_trust_config(trust_config) @pytest.fixture - def identity(self, staging): - _, _, identity = staging + def identity(self, preprod): + _, _, identity = preprod return identity @pytest.fixture diff --git a/test/unit/verify/test_verifier.py b/test/unit/verify/test_verifier.py index 057b35e50..23f8c4c26 100644 --- a/test/unit/verify/test_verifier.py +++ b/test/unit/verify/test_verifier.py @@ -170,8 +170,8 @@ def test_verifier_fail_expiry(signing_materials, null_policy, monkeypatch): @pytest.mark.staging @pytest.mark.ambient_oidc -def test_verifier_dsse_roundtrip(staging): - signer_cls, verifier_cls, identity = staging +def test_verifier_dsse_roundtrip(preprod): + signer_cls, verifier_cls, identity = preprod ctx = signer_cls() stmt = ( From bfc27967f31c70e17704c0d0ac0d31d7b2283592 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 12 Jun 2025 22:05:11 +0000 Subject: [PATCH 08/20] add param for local Signed-off-by: Ramon Petgrave --- test/unit/conftest.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/test/unit/conftest.py b/test/unit/conftest.py index 494217331..701b99b4c 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -240,20 +240,42 @@ def ctx_cls(): return ctx_cls, IdentityToken(token) -@pytest.fixture -def preprod() -> tuple[type[SigningContext], type[Verifier], IdentityToken]: +@pytest.fixture( + params=[ + pytest.param( + (ClientTrustConfig.staging(), os.getenv("SIGSTORE_IDENTITY_TOKEN_staging")), + id="preprod-staging", + ), + pytest.param( + ( + ClientTrustConfig.from_json( + Path(os.getenv("TRUST_CONFIG")).read_text() + ), + os.getenv("SIGSTORE_IDENTITY_TOKEN_local"), + ), + id="preprod-local", + marks=pytest.mark.skipif( + not _has_setup_sigstore_env(), + reason="skipping test that use the local environment due to unset `TEST_SETUP_SIGSTORE_ENV` env variable", + ), + ), + ] +) +def preprod(request) -> tuple[type[SigningContext], type[Verifier], IdentityToken]: """ Returns a SigningContext, Verifier, and IdentityToken for the staging environment. The SigningContext and Verifier are both behind callables so that they may be lazily evaluated. """ + trust_config, token = request.param + ctx = SigningContext.from_trust_config(trust_config) def signer(): - return SigningContext.from_trust_config(ClientTrustConfig.staging()) + return ctx - verifier = Verifier.staging + def verifier(): + return Verifier(trusted_root=ctx._trusted_root) # Detect env variable for local interactive tests. - token = os.getenv("SIGSTORE_IDENTITY_TOKEN_staging") if not token: # If the variable is not defined, try getting an ambient token. token = detect_credential(TEST_CLIENT_ID) From bbbfa1f427f5c28ae484ea953bb06feaed7c3177 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 12 Jun 2025 22:36:02 +0000 Subject: [PATCH 09/20] -vv and all Signed-off-by: Ramon Petgrave --- .github/workflows/test-with-setup-sigstore-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-with-setup-sigstore-env.yml b/.github/workflows/test-with-setup-sigstore-env.yml index c40a9d5c2..fcf00818d 100644 --- a/.github/workflows/test-with-setup-sigstore-env.yml +++ b/.github/workflows/test-with-setup-sigstore-env.yml @@ -32,5 +32,5 @@ jobs: export TRUST_CONFIG=${{ steps.setup-sigstore-env.outputs.trust-config }} set -o pipefail - make test TEST_ARGS="-k test_sign_rekor_entry_consistent -rs -v" | tee output + make test TEST_ARGS=" -rs -vv" | tee output ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) From a87fb7683487461dca6d827b864000dbbc9d46ab Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 02:16:59 +0000 Subject: [PATCH 10/20] grant token to workflow Signed-off-by: Ramon Petgrave --- .github/workflows/test-with-setup-sigstore-env.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-with-setup-sigstore-env.yml b/.github/workflows/test-with-setup-sigstore-env.yml index fcf00818d..408a12e85 100644 --- a/.github/workflows/test-with-setup-sigstore-env.yml +++ b/.github/workflows/test-with-setup-sigstore-env.yml @@ -12,6 +12,9 @@ on: jobs: test: runs-on: ubuntu-latest + permissions: + # Needed to access the workflow's OIDC identity. + id-token: write steps: # TODO: use new release - id: setup-sigstore-env @@ -32,5 +35,5 @@ jobs: export TRUST_CONFIG=${{ steps.setup-sigstore-env.outputs.trust-config }} set -o pipefail - make test TEST_ARGS=" -rs -vv" | tee output + make test TEST_ARGS=" -rs -vv --showlocals" | tee output ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) From 82ff7a089d97d03fa3623c7052c126d7b1628ef2 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 15:11:02 +0000 Subject: [PATCH 11/20] lazy load trust config Signed-off-by: Ramon Petgrave --- output | 312 ++++++++++++++++++++++++++++++++++++++++++ test/unit/conftest.py | 11 +- 2 files changed, 319 insertions(+), 4 deletions(-) create mode 100644 output diff --git a/output b/output new file mode 100644 index 000000000..b26bb59ac --- /dev/null +++ b/output @@ -0,0 +1,312 @@ +. ../.venv/bin/activate && \ + pytest --cov-append --cov=sigstore test/unit test/integration -rs -vv && \ + python -m coverage report -m +========================================================================================================================= test session starts ========================================================================================================================== +platform linux -- Python 3.13.2, pytest-8.4.0, pluggy-1.6.0 -- /usr/local/google/home/rpetgrave/workspaces/rekorv2/.venv/bin/python +cachedir: .pytest_cache +rootdir: /usr/local/google/home/rpetgrave/workspaces/rekorv2/sigstore-python +configfile: pyproject.toml +plugins: cov-6.2.1 +collecting ...  collected 215 items  + +test/unit/internal/oidc/test_issuer.py::test_fail_init_url PASSED [ 0%] +test/unit/internal/oidc/test_issuer.py::test_init_url PASSED [ 0%] +test/unit/internal/oidc/test_issuer.py::test_get_identity_token_bad_code PASSED [ 1%] +test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[3] PASSED [ 1%] +test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[255] PASSED [ 2%] +test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[1024] PASSED [ 2%] +test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[16777215] PASSED [ 3%] +test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_sign_request SKIPPED (skipping test that requires a Timestamp Authority) [ 3%] +test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_sign_request_invalid_url SKIPPED (skipping test that requires a Timestamp Authority) [ 4%] +test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_sign_request_invalid_request SKIPPED (skipping test that requires a Timestamp Authority) [ 4%] +test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_invalid_response SKIPPED (skipping test that requires a Timestamp Authority) [ 5%] +test/unit/internal/test_trust.py::TestCertificateAuthority::test_good PASSED [ 5%] +test/unit/internal/test_trust.py::TestCertificateAuthority::test_missing_root PASSED [ 6%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_good PASSED [ 6%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[base case] PASSED [ 6%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[multiple services, same operator: expect 1 service in result] PASSED [ 7%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[2 services, different operator: expect 2 services in result] PASSED [ 7%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[3 services, one is not yet valid: expect 2 services in result] PASSED [ 8%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[ANY selector: expect 1 service only in result] PASSED [ 8%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[EXACT selector: expect configured number of services in result] PASSED [ 9%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[services with different version: expect highest version] PASSED [ 9%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[services with different version: expect the supported version] PASSED [ 10%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[No supported versions: expect no results] PASSED [ 10%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[services without ServiceConfiguration: expect all supported] PASSED [ 11%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services_fail[services0-versions0-config0] PASSED [ 11%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services_fail[services1-versions1-config1] PASSED [ 12%] +test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services_fail[services2-versions2-config2] PASSED [ 12%] +test/unit/internal/test_trust.py::TestTrustedRoot::test_good[trusted_root/trustedroot.v1.json] PASSED [ 13%] +test/unit/internal/test_trust.py::TestTrustedRoot::test_good[trusted_root/trustedroot.v1.local_tlog_ed25519_rekor-tiles.json] PASSED [ 13%] +test/unit/internal/test_trust.py::TestTrustedRoot::test_bad_media_type PASSED [ 13%] +test/unit/internal/test_trust.py::test_trust_root_tuf_caches_and_requests PASSED [ 14%] +test/unit/internal/test_trust.py::test_trust_root_tuf_offline PASSED [ 14%] +test/unit/internal/test_trust.py::test_is_timerange_valid PASSED [ 15%] +test/unit/internal/test_trust.py::test_trust_root_bundled_get PASSED [ 15%] +test/unit/internal/test_trust.py::test_trust_root_tuf_instance_error PASSED [ 16%] +test/unit/internal/test_trust.py::test_trust_root_tuf_ctfe_keys_error PASSED [ 16%] +test/unit/internal/test_trust.py::test_trust_root_fulcio_certs_error PASSED [ 17%] +test/unit/internal/test_trust.py::TestClientTrustConfig::test_good PASSED [ 17%] +test/unit/internal/test_trust.py::TestClientTrustConfig::test_bad_media_type PASSED [ 18%] +test/unit/test_dsse.py::TestEnvelope::test_roundtrip PASSED [ 18%] +test/unit/test_dsse.py::TestEnvelope::test_missing_signature PASSED [ 19%] +test/unit/test_dsse.py::TestEnvelope::test_empty_signature PASSED [ 19%] +test/unit/test_dsse.py::TestEnvelope::test_multiple_signatures PASSED [ 20%] +test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA2_256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855] PASSED [ 20%] +test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA2_384-38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b] PASSED [ 20%] +test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA2_512-cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e] PASSED [ 21%] +test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA3_256-a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a] PASSED [ 21%] +test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA3_384-0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004] PASSED [ 22%] +test/unit/test_models.py::TestLogEntry::test_missing_inclusion_proof[0] PASSED [ 22%] +test/unit/test_models.py::TestLogEntry::test_missing_inclusion_proof[1746819403] PASSED [ 23%] +test/unit/test_models.py::TestLogEntry::test_missing_inclusion_promise_and_integrated_time_round_trip PASSED [ 23%] +test/unit/test_models.py::TestLogEntry::test_logentry_roundtrip PASSED [ 24%] +test/unit/test_models.py::TestLogInclusionProof::test_valid PASSED [ 24%] +test/unit/test_models.py::TestLogInclusionProof::test_negative_log_index PASSED [ 25%] +test/unit/test_models.py::TestLogInclusionProof::test_negative_tree_size PASSED [ 25%] +test/unit/test_models.py::TestLogInclusionProof::test_log_index_outside_tree_size PASSED [ 26%] +test/unit/test_models.py::TestLogInclusionProof::test_checkpoint_missing PASSED [ 26%] +test/unit/test_models.py::TestTimestampVerificationData::test_valid_timestamp PASSED [ 26%] +test/unit/test_models.py::TestTimestampVerificationData::test_no_timestamp PASSED [ 27%] +test/unit/test_models.py::TestTimestampVerificationData::test_invalid_timestamp PASSED [ 27%] +test/unit/test_models.py::TestVerificationMaterial::test_valid_verification_material PASSED [ 28%] +test/unit/test_models.py::TestBundle::test_invalid_bundle_version PASSED [ 28%] +test/unit/test_models.py::TestBundle::test_invalid_empty_cert_chain PASSED [ 29%] +test/unit/test_models.py::TestBundle::test_invalid_no_log_entry PASSED [ 29%] +test/unit/test_models.py::TestBundle::test_verification_materials_offline_no_checkpoint PASSED [ 30%] +test/unit/test_models.py::TestBundle::test_bundle_roundtrip PASSED [ 30%] +test/unit/test_models.py::TestBundle::test_bundle_missing_signed_time PASSED [ 31%] +test/unit/test_models.py::TestKnownBundleTypes::test_str PASSED [ 31%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_jwt PASSED [ 32%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_iss PASSED [ 32%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_aud PASSED [ 33%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_aud[None] PASSED [ 33%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_aud[not-sigstore] PASSED [ 33%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_iat PASSED [ 34%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_iat[None] PASSED [ 34%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_iat[not-an-int] PASSED [ 35%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_nbf_ok PASSED [ 35%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_nbf PASSED [ 36%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_exp PASSED [ 36%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_exp PASSED [ 37%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_identity_claim[https://accounts.google.com] PASSED [ 37%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_identity_claim[https://oauth2.sigstore.dev/auth] PASSED [ 38%] +test/unit/test_oidc.py::TestIdentityToken::test_missing_identity_claim[https://oauth2.sigstage.dev/auth] PASSED [ 38%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_federated_claims[notadict] PASSED [ 39%] +test/unit/test_oidc.py::TestIdentityToken::test_invalid_federated_claims[fed1] PASSED [ 39%] +test/unit/test_oidc.py::TestIdentityToken::test_ok[https://accounts.google.com-email-example@example.com-None] PASSED [ 40%] +test/unit/test_oidc.py::TestIdentityToken::test_ok[https://oauth2.sigstore.dev/auth-email-example@example.com-https://accounts.google.com] PASSED [ 40%] +test/unit/test_oidc.py::TestIdentityToken::test_ok[https://oauth2.sigstore.dev/auth-email-example@example.com-None] PASSED [ 40%] +test/unit/test_oidc.py::TestIdentityToken::test_ok[https://token.actions.githubusercontent.com-sub-some-subject-None] PASSED [ 41%] +test/unit/test_oidc.py::TestIdentityToken::test_ok[hxxps://unknown.issuer.example.com/auth-sub-some-subject-None] PASSED [ 41%] +test/unit/test_sign.py::test_sign_rekor_entry_consistent[staging] PASSED [ 42%] +test/unit/test_sign.py::test_sign_rekor_entry_consistent[production] PASSED [ 42%] +test/unit/test_sign.py::test_sign_rekor_entry_consistent[local] PASSED [ 43%] +test/unit/test_sign.py::test_sct_verify_keyring_lookup_error[staging] PASSED [ 43%] +test/unit/test_sign.py::test_sct_verify_keyring_lookup_error[production] PASSED [ 44%] +test/unit/test_sign.py::test_sct_verify_keyring_lookup_error[local] PASSED [ 44%] +test/unit/test_sign.py::test_sct_verify_keyring_error[staging] PASSED [ 45%] +test/unit/test_sign.py::test_sct_verify_keyring_error[production] PASSED [ 45%] +test/unit/test_sign.py::test_sct_verify_keyring_error[local] PASSED [ 46%] +test/unit/test_sign.py::test_identity_proof_claim_lookup[staging] PASSED [ 46%] +test/unit/test_sign.py::test_identity_proof_claim_lookup[production] PASSED [ 46%] +test/unit/test_sign.py::test_identity_proof_claim_lookup[local] PASSED [ 47%] +test/unit/test_sign.py::test_sign_prehashed[preprod-staging] PASSED [ 47%] +test/unit/test_sign.py::test_sign_prehashed[preprod-local] PASSED [ 48%] +test/unit/test_sign.py::test_sign_dsse[preprod-staging] PASSED [ 48%] +test/unit/test_sign.py::test_sign_dsse[preprod-local] PASSED [ 49%] +test/unit/test_sign.py::TestSignWithTSA::test_sign_artifact[preprod-staging] SKIPPED (skipping test that requires a Timestamp Authority) [ 49%] +test/unit/test_sign.py::TestSignWithTSA::test_sign_artifact[preprod-local] SKIPPED (skipping test that requires a Timestamp Authority) [ 50%] +test/unit/test_sign.py::TestSignWithTSA::test_sign_dsse[preprod-staging] SKIPPED (skipping test that requires a Timestamp Authority) [ 50%] +test/unit/test_sign.py::TestSignWithTSA::test_sign_dsse[preprod-local] SKIPPED (skipping test that requires a Timestamp Authority) [ 51%] +test/unit/test_sign.py::TestSignWithTSA::test_with_timestamp_error[preprod-staging] SKIPPED (skipping test that requires a Timestamp Authority) [ 51%] +test/unit/test_sign.py::TestSignWithTSA::test_with_timestamp_error[preprod-local] SKIPPED (skipping test that requires a Timestamp Authority) [ 52%] +test/unit/test_store.py::test_store_reads_root_json[https://tuf-repo-cdn.sigstore.dev] PASSED [ 52%] +test/unit/test_store.py::test_store_reads_root_json[https://tuf-repo-cdn.sigstage.dev] PASSED [ 53%] +test/unit/test_store.py::test_store_reads_targets_json[https://tuf-repo-cdn.sigstore.dev] PASSED [ 53%] +test/unit/test_store.py::test_store_reads_targets_json[https://tuf-repo-cdn.sigstage.dev] PASSED [ 53%] +test/unit/test_utils.py::test_key_id PASSED [ 54%] +test/unit/test_utils.py::test_sha256_streaming[0] PASSED [ 54%] +test/unit/test_utils.py::test_sha256_streaming[1] PASSED [ 55%] +test/unit/test_utils.py::test_sha256_streaming[2] PASSED [ 55%] +test/unit/test_utils.py::test_sha256_streaming[4] PASSED [ 56%] +test/unit/test_utils.py::test_sha256_streaming[8] PASSED [ 56%] +test/unit/test_utils.py::test_sha256_streaming[32] PASSED [ 57%] +test/unit/test_utils.py::test_sha256_streaming[128] PASSED [ 57%] +test/unit/test_utils.py::test_sha256_streaming[1024] PASSED [ 58%] +test/unit/test_utils.py::test_sha256_streaming[131072] PASSED [ 58%] +test/unit/test_utils.py::test_sha256_streaming[1048576] PASSED [ 59%] +test/unit/test_utils.py::test_sha256_streaming[134217728] PASSED [ 59%] +test/unit/test_utils.py::test_load_pem_public_key_format PASSED [ 60%] +test/unit/test_utils.py::test_load_pem_public_key_serialization PASSED [ 60%] +test/unit/test_utils.py::test_cert_is_ca[bogus-root.pem-True] PASSED [ 60%] +test/unit/test_utils.py::test_cert_is_ca[bogus-intermediate.pem-True] PASSED [ 61%] +test/unit/test_utils.py::test_cert_is_ca[bogus-leaf.pem-False] PASSED [ 61%] +test/unit/test_utils.py::test_cert_is_ca_invalid_states[bogus-root-noncritical-bc.pem] PASSED [ 62%] +test/unit/test_utils.py::test_cert_is_ca_invalid_states[bogus-root-invalid-ku.pem] PASSED [ 62%] +test/unit/test_utils.py::test_cert_is_ca_invalid_states[bogus-root-missing-ku.pem] PASSED [ 63%] +test/unit/test_utils.py::test_cert_is_root_ca[bogus-root.pem-True] PASSED [ 63%] +test/unit/test_utils.py::test_cert_is_root_ca[bogus-intermediate.pem-False] PASSED [ 64%] +test/unit/test_utils.py::test_cert_is_root_ca[bogus-leaf.pem-False] PASSED [ 64%] +test/unit/test_utils.py::test_cert_is_root_ca[bogus-leaf-invalid-ku.pem-False] PASSED [ 65%] +test/unit/test_utils.py::test_cert_is_leaf[bogus-root.pem-False] PASSED [ 65%] +test/unit/test_utils.py::test_cert_is_leaf[bogus-intermediate.pem-False] PASSED [ 66%] +test/unit/test_utils.py::test_cert_is_leaf[bogus-intermediate-with-eku.pem-False] PASSED [ 66%] +test/unit/test_utils.py::test_cert_is_leaf[bogus-leaf.pem-True] PASSED [ 66%] +test/unit/test_utils.py::test_cert_is_leaf[bogus-leaf-invalid-eku.pem-False] PASSED [ 67%] +test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-root-invalid-ku.pem] PASSED [ 67%] +test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-root-missing-ku.pem] PASSED [ 68%] +test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-leaf-invalid-ku.pem] PASSED [ 68%] +test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-leaf-missing-eku.pem] PASSED [ 69%] +test/unit/test_utils.py::test_cert_is_leaf_invalid_version[cert_is_leaf] PASSED [ 69%] +test/unit/test_utils.py::test_cert_is_leaf_invalid_version[cert_is_ca] PASSED [ 70%] +test/unit/test_utils.py::test_cert_is_leaf_invalid_version[cert_is_root_ca] PASSED [ 70%] +test/unit/test_version.py::test_version PASSED [ 71%] +test/unit/verify/test_policy.py::TestVerificationPolicy::test_does_not_init PASSED [ 71%] +test/unit/verify/test_policy.py::TestUnsafeNoOp::test_succeeds PASSED [ 72%] +test/unit/verify/test_policy.py::TestAnyOf::test_trivially_false PASSED [ 72%] +test/unit/verify/test_policy.py::TestAnyOf::test_fails_no_children_match PASSED [ 73%] +test/unit/verify/test_policy.py::TestAnyOf::test_succeeds PASSED [ 73%] +test/unit/verify/test_policy.py::TestAllOf::test_trivially_false PASSED [ 73%] +test/unit/verify/test_policy.py::TestAllOf::test_certificate_extension_not_found PASSED [ 74%] +test/unit/verify/test_policy.py::TestAllOf::test_fails_not_all_children_match PASSED [ 74%] +test/unit/verify/test_policy.py::TestAllOf::test_succeeds PASSED [ 75%] +test/unit/verify/test_policy.py::TestIdentity::test_fails_no_san_match PASSED [ 75%] +test/unit/verify/test_policy.py::TestSingleExtPolicy::test_succeeds PASSED [ 76%] +test/unit/verify/test_verifier.py::test_verifier_production PASSED [ 76%] +test/unit/verify/test_verifier.py::test_verifier_staging PASSED [ 77%] +test/unit/verify/test_verifier.py::test_verifier_one_verification PASSED [ 77%] +test/unit/verify/test_verifier.py::test_verifier_inconsistent_log_entry PASSED [ 78%] +test/unit/verify/test_verifier.py::test_verifier_multiple_verifications PASSED [ 78%] +test/unit/verify/test_verifier.py::test_verifier_bundle[bundle.txt] PASSED [ 79%] +test/unit/verify/test_verifier.py::test_verifier_bundle[bundle_v3.txt] PASSED [ 79%] +test/unit/verify/test_verifier.py::test_verifier_bundle[bundle_v3_alt.txt] PASSED [ 80%] +test/unit/verify/test_verifier.py::test_verifier_bundle_offline[bundle.txt] PASSED [ 80%] +test/unit/verify/test_verifier.py::test_verifier_bundle_offline[bundle_v3.txt] PASSED [ 80%] +test/unit/verify/test_verifier.py::test_verifier_bundle_offline[bundle_v3_alt.txt] PASSED [ 81%] +test/unit/verify/test_verifier.py::test_verifier_email_identity PASSED [ 81%] +test/unit/verify/test_verifier.py::test_verifier_uri_identity PASSED [ 82%] +test/unit/verify/test_verifier.py::test_verifier_policy_check PASSED [ 82%] +test/unit/verify/test_verifier.py::test_verifier_fail_expiry XFAIL [ 83%] +test/unit/verify/test_verifier.py::test_verifier_dsse_roundtrip[preprod-staging] PASSED [ 83%] +test/unit/verify/test_verifier.py::test_verifier_dsse_roundtrip[preprod-local] PASSED [ 84%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_verify_timestamp PASSED [ 84%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_no_validity_end PASSED [ 85%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete0] PASSED [ 85%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete1] PASSED [ 86%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete2] XFAIL [ 86%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete3] PASSED [ 86%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_without_timestamp PASSED [ 87%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_too_many_timestamp PASSED [ 87%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_duplicate_timestamp PASSED [ 88%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_outside_validity_range PASSED [ 88%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_rfc3161_error PASSED [ 89%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_no_authorities PASSED [ 89%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_late_timestamp PASSED [ 90%] +test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_not_enough_timestamp PASSED [ 90%] +test/integration/cli/test_attest.py::test_attest_success_default_output_bundle[https://slsa.dev/provenance/v0.2-slsa_predicate_v0_2.json] PASSED [ 91%] +test/integration/cli/test_attest.py::test_attest_success_default_output_bundle[https://slsa.dev/provenance/v1-slsa_predicate_v1_0.json] PASSED [ 91%] +test/integration/cli/test_attest.py::test_attest_success_custom_output_bundle PASSED [ 92%] +test/integration/cli/test_attest.py::test_attest_overwrite_existing_bundle PASSED [ 92%] +test/integration/cli/test_attest.py::test_attest_invalid_predicate_type PASSED [ 93%] +test/integration/cli/test_attest.py::test_attest_mismatching_predicate PASSED [ 93%] +test/integration/cli/test_attest.py::test_attest_missing_predicate PASSED [ 93%] +test/integration/cli/test_attest.py::test_attest_invalid_json_predicate PASSED [ 94%] +test/integration/cli/test_plumbing.py::test_fix_bundle_fixes_missing_checkpoint PASSED [ 94%] +test/integration/cli/test_plumbing.py::test_fix_bundle_upgrades_bundle PASSED [ 95%] +test/integration/cli/test_sign.py::test_sign_success_default_output_bundle PASSED [ 95%] +test/integration/cli/test_sign.py::test_sign_success_custom_outputs PASSED [ 96%] +test/integration/cli/test_sign.py::test_sign_success_custom_output_dir PASSED [ 96%] +test/integration/cli/test_sign.py::test_sign_success_no_default_files PASSED [ 97%] +test/integration/cli/test_sign.py::test_sign_overwrite_existing_bundle PASSED [ 97%] +test/integration/cli/test_sign.py::test_sign_fails_with_default_files_and_bundle_options PASSED [ 98%] +test/integration/cli/test_sign.py::test_sign_fails_with_multiple_inputs_and_custom_output PASSED [ 98%] +test/integration/cli/test_sign.py::test_sign_fails_with_output_dir_and_custom_output_files PASSED [ 99%] +test/integration/cli/test_sign.py::test_sign_fails_without_both_output_cert_and_signature PASSED [ 99%] +test/integration/cli/test_verify.py::test_regression_verify_legacy_bundle PASSED [100%] + +=========================================================================================================================== warnings summary =========================================================================================================================== +test/unit/internal/test_trust.py: 51 warnings +test/unit/test_sign.py: 60 warnings +test/unit/verify/test_verifier.py: 149 warnings +test/integration/cli/test_attest.py: 35 warnings +test/integration/cli/test_plumbing.py: 6 warnings +test/integration/cli/test_sign.py: 35 warnings +test/integration/cli/test_verify.py: 5 warnings + /usr/local/google/home/rpetgrave/workspaces/rekorv2/.venv/lib/python3.13/site-packages/sigstore_protobuf_specs/dev/sigstore/trustroot/v1/__init__.py:139: DeprecationWarning: TransparencyLogInstance.log_id is deprecated + warnings.warn( + +test/unit/test_sign.py: 8 warnings +test/unit/verify/test_verifier.py: 2 warnings + /usr/local/google/home/rpetgrave/workspaces/rekorv2/sigstore-python/sigstore/_internal/sct.py:176: UserWarning: Attribute's length must be >= 2 and <= 2, but it was 3 + _logger.debug(f"Found {cert.subject} as issuer, verifying if it is a ca") + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +============================================================================================================================ tests coverage ============================================================================================================================ +___________________________________________________________________________________________________________ coverage: platform linux, python 3.13.2-final-0 ____________________________________________________________________________________________________________ + +Name Stmts Miss Branch BrPart Cover +-------------------------------------------------------------------------- +sigstore/__init__.py 1 0 0 0 100% +sigstore/__main__.py 3 3 2 0 0% +sigstore/_internal/__init__.py 3 0 0 0 100% +sigstore/_internal/fulcio/__init__.py 2 0 0 0 100% +sigstore/_internal/fulcio/client.py 84 21 10 2 69% +sigstore/_internal/merkle.py 42 2 10 2 92% +sigstore/_internal/oidc/__init__.py 0 0 0 0 100% +sigstore/_internal/oidc/oauth.py 100 25 8 1 70% +sigstore/_internal/rekor/__init__.py 8 0 0 0 100% +sigstore/_internal/rekor/checkpoint.py 86 12 22 9 81% +sigstore/_internal/rekor/client.py 106 25 12 3 73% +sigstore/_internal/sct.py 86 16 22 11 75% +sigstore/_internal/timestamp.py 42 0 0 0 100% +sigstore/_internal/trust.py 264 16 62 8 92% +sigstore/_internal/tuf.py 80 7 18 1 92% +sigstore/_store/__init__.py 0 0 0 0 100% +sigstore/_utils.py 111 6 30 2 94% +sigstore/dsse/__init__.py 113 20 18 3 76% +sigstore/dsse/_predicate.py 79 1 2 1 98% +sigstore/errors.py 33 11 2 0 63% +sigstore/hashes.py 21 2 4 2 84% +sigstore/models.py 227 12 52 10 91% +sigstore/oidc.py 132 27 30 3 77% +sigstore/sign.py 93 4 12 4 92% +sigstore/verify/__init__.py 3 0 0 0 100% +sigstore/verify/policy.py 138 5 16 3 95% +sigstore/verify/verifier.py 165 15 44 7 89% +-------------------------------------------------------------------------- +TOTAL 2022 230 376 72 86% +======================================================================================================================= short test summary info ======================================================================================================================== +SKIPPED [10] test/conftest.py:115: skipping test that requires a Timestamp Authority +====================================================================================================== 203 passed, 10 skipped, 2 xfailed, 351 warnings in 26.98s ======================================================================================================= +Name Stmts Miss Branch BrPart Cover Missing +------------------------------------------------------------------------------------ +sigstore/__init__.py 1 0 0 0 100% +sigstore/__main__.py 3 3 2 0 0% 19-22 +sigstore/_internal/__init__.py 3 0 0 0 100% +sigstore/_internal/fulcio/__init__.py 2 0 0 0 100% +sigstore/_internal/fulcio/client.py 84 21 10 2 69% 113-115, 122-123, 128, 144-158, 195 +sigstore/_internal/merkle.py 42 2 10 2 92% 107, 127 +sigstore/_internal/oidc/__init__.py 0 0 0 0 100% +sigstore/_internal/oidc/oauth.py 100 25 8 1 70% 134, 137-166, 202, 234, 239, 243 +sigstore/_internal/rekor/__init__.py 8 0 0 0 100% +sigstore/_internal/rekor/checkpoint.py 86 12 22 9 81% 77, 81, 99, 131, 140, 144, 153, 176, 184-185, 215, 229 +sigstore/_internal/rekor/client.py 106 25 12 3 73% 56, 74-83, 101-106, 131, 136, 142-143, 160-161, 196-199, 210->208, 256 +sigstore/_internal/sct.py 86 16 22 11 75% 57-58, 61, 73, 82, 108, 147, 162-163, 168, 179-181, 202->222, 211, 216, 225 +sigstore/_internal/timestamp.py 42 0 0 0 100% +sigstore/_internal/trust.py 264 16 62 8 92% 154, 181-191, 256, 316, 334, 347-348, 356, 366, 441, 465, 518, 571, 631 +sigstore/_internal/tuf.py 80 7 18 1 92% 123-124, 135, 140-144, 163-167 +sigstore/_store/__init__.py 0 0 0 0 100% +sigstore/_utils.py 111 6 30 2 94% 42, 110-111, 114, 138-139 +sigstore/dsse/__init__.py 113 20 18 3 76% 94-98, 110-120, 180-181, 239, 292, 298-299 +sigstore/dsse/_predicate.py 79 1 2 1 98% 171 +sigstore/errors.py 33 11 2 0 63% 31, 36-49, 93-98, 110, 118 +sigstore/hashes.py 21 2 4 2 84% 49, 57 +sigstore/models.py 227 12 52 10 91% 188, 196, 309, 412, 477, 502, 509-510, 547, 549, 554, 634 +sigstore/oidc.py 132 27 30 3 77% 128-129, 213, 256-257, 269-270, 297, 307-315, 339-340, 349-354, 365, 369-397, 411-412 +sigstore/sign.py 93 4 12 4 92% 103->exit, 113-114, 130, 136 +sigstore/verify/__init__.py 3 0 0 0 100% +sigstore/verify/policy.py 138 5 16 3 95% 126-127, 136, 347, 454, 461->465 +sigstore/verify/verifier.py 165 15 44 7 89% 261-262, 336-337, 343, 347, 370, 404, 425-426, 433, 435, 448, 485-486 +------------------------------------------------------------------------------------ +TOTAL 2022 230 376 72 86% diff --git a/test/unit/conftest.py b/test/unit/conftest.py index 701b99b4c..c1c5f71b3 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -243,12 +243,12 @@ def ctx_cls(): @pytest.fixture( params=[ pytest.param( - (ClientTrustConfig.staging(), os.getenv("SIGSTORE_IDENTITY_TOKEN_staging")), + (ClientTrustConfig.staging, os.getenv("SIGSTORE_IDENTITY_TOKEN_staging")), id="preprod-staging", ), pytest.param( ( - ClientTrustConfig.from_json( + lambda: ClientTrustConfig.from_json( Path(os.getenv("TRUST_CONFIG")).read_text() ), os.getenv("SIGSTORE_IDENTITY_TOKEN_local"), @@ -265,9 +265,12 @@ def preprod(request) -> tuple[type[SigningContext], type[Verifier], IdentityToke """ Returns a SigningContext, Verifier, and IdentityToken for the staging environment. The SigningContext and Verifier are both behind callables so that they may be lazily evaluated. + + We paramaterize this fixture so that consuming tests can run multiple times, once for each of + the params. https://docs.pytest.org/en/stable/how-to/fixtures.html#fixture-parametrize """ - trust_config, token = request.param - ctx = SigningContext.from_trust_config(trust_config) + trust_config_func, token = request.param + ctx = SigningContext.from_trust_config(trust_config_func()) def signer(): return ctx From 1ebebc813c1858fd681a98e8532a0b08154a934b Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 16:25:24 +0000 Subject: [PATCH 12/20] fix timestamp tests Signed-off-by: Ramon Petgrave --- .../test-with-setup-sigstore-env.yml | 7 +- output | 312 ------------------ test/unit/test_sign.py | 22 +- 3 files changed, 17 insertions(+), 324 deletions(-) delete mode 100644 output diff --git a/.github/workflows/test-with-setup-sigstore-env.yml b/.github/workflows/test-with-setup-sigstore-env.yml index 408a12e85..936ef841e 100644 --- a/.github/workflows/test-with-setup-sigstore-env.yml +++ b/.github/workflows/test-with-setup-sigstore-env.yml @@ -31,9 +31,14 @@ jobs: cache-dependency-path: pyproject.toml - run: | export TEST_SETUP_SIGSTORE_ENV="any non-empty value" - export SIGSTORE_IDENTITY_TOKEN_local=$( cat ${{ steps.setup-sigstore-env.outputs.oidc-token }} ) export TRUST_CONFIG=${{ steps.setup-sigstore-env.outputs.trust-config }} + export SIGSTORE_IDENTITY_TOKEN_local=$( cat ${{ steps.setup-sigstore-env.outputs.oidc-token }} ) + export TEST_SIGSTORE_TIMESTAMP_AUTHORITY_URL="${{ steps.setup-sigstore-env.outputs.tsa-url }}/api/v1/timestamp" set -o pipefail make test TEST_ARGS=" -rs -vv --showlocals" | tee output ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) + + make test TEST_ARGS="-m timestamp_authority -rs -vv --showlocals" | tee output + ! grep -q "skipping test that use the local environment" output || (echo "ERROR: Found skip message" && exit 1) + ! grep -q "skipping test that requires a Timestamp Authority" output || (echo "ERROR: Found skip message" && exit 1) diff --git a/output b/output deleted file mode 100644 index b26bb59ac..000000000 --- a/output +++ /dev/null @@ -1,312 +0,0 @@ -. ../.venv/bin/activate && \ - pytest --cov-append --cov=sigstore test/unit test/integration -rs -vv && \ - python -m coverage report -m -========================================================================================================================= test session starts ========================================================================================================================== -platform linux -- Python 3.13.2, pytest-8.4.0, pluggy-1.6.0 -- /usr/local/google/home/rpetgrave/workspaces/rekorv2/.venv/bin/python -cachedir: .pytest_cache -rootdir: /usr/local/google/home/rpetgrave/workspaces/rekorv2/sigstore-python -configfile: pyproject.toml -plugins: cov-6.2.1 -collecting ...  collected 215 items  - -test/unit/internal/oidc/test_issuer.py::test_fail_init_url PASSED [ 0%] -test/unit/internal/oidc/test_issuer.py::test_init_url PASSED [ 0%] -test/unit/internal/oidc/test_issuer.py::test_get_identity_token_bad_code PASSED [ 1%] -test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[3] PASSED [ 1%] -test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[255] PASSED [ 2%] -test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[1024] PASSED [ 2%] -test/unit/internal/test_sct.py::test_pack_digitally_signed_precertificate[16777215] PASSED [ 3%] -test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_sign_request SKIPPED (skipping test that requires a Timestamp Authority) [ 3%] -test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_sign_request_invalid_url SKIPPED (skipping test that requires a Timestamp Authority) [ 4%] -test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_sign_request_invalid_request SKIPPED (skipping test that requires a Timestamp Authority) [ 4%] -test/unit/internal/test_timestamping.py::TestTimestampAuthorityClient::test_invalid_response SKIPPED (skipping test that requires a Timestamp Authority) [ 5%] -test/unit/internal/test_trust.py::TestCertificateAuthority::test_good PASSED [ 5%] -test/unit/internal/test_trust.py::TestCertificateAuthority::test_missing_root PASSED [ 6%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_good PASSED [ 6%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[base case] PASSED [ 6%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[multiple services, same operator: expect 1 service in result] PASSED [ 7%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[2 services, different operator: expect 2 services in result] PASSED [ 7%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[3 services, one is not yet valid: expect 2 services in result] PASSED [ 8%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[ANY selector: expect 1 service only in result] PASSED [ 8%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[EXACT selector: expect configured number of services in result] PASSED [ 9%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[services with different version: expect highest version] PASSED [ 9%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[services with different version: expect the supported version] PASSED [ 10%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[No supported versions: expect no results] PASSED [ 10%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services[services without ServiceConfiguration: expect all supported] PASSED [ 11%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services_fail[services0-versions0-config0] PASSED [ 11%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services_fail[services1-versions1-config1] PASSED [ 12%] -test/unit/internal/test_trust.py::TestSigningcconfig::test_get_valid_services_fail[services2-versions2-config2] PASSED [ 12%] -test/unit/internal/test_trust.py::TestTrustedRoot::test_good[trusted_root/trustedroot.v1.json] PASSED [ 13%] -test/unit/internal/test_trust.py::TestTrustedRoot::test_good[trusted_root/trustedroot.v1.local_tlog_ed25519_rekor-tiles.json] PASSED [ 13%] -test/unit/internal/test_trust.py::TestTrustedRoot::test_bad_media_type PASSED [ 13%] -test/unit/internal/test_trust.py::test_trust_root_tuf_caches_and_requests PASSED [ 14%] -test/unit/internal/test_trust.py::test_trust_root_tuf_offline PASSED [ 14%] -test/unit/internal/test_trust.py::test_is_timerange_valid PASSED [ 15%] -test/unit/internal/test_trust.py::test_trust_root_bundled_get PASSED [ 15%] -test/unit/internal/test_trust.py::test_trust_root_tuf_instance_error PASSED [ 16%] -test/unit/internal/test_trust.py::test_trust_root_tuf_ctfe_keys_error PASSED [ 16%] -test/unit/internal/test_trust.py::test_trust_root_fulcio_certs_error PASSED [ 17%] -test/unit/internal/test_trust.py::TestClientTrustConfig::test_good PASSED [ 17%] -test/unit/internal/test_trust.py::TestClientTrustConfig::test_bad_media_type PASSED [ 18%] -test/unit/test_dsse.py::TestEnvelope::test_roundtrip PASSED [ 18%] -test/unit/test_dsse.py::TestEnvelope::test_missing_signature PASSED [ 19%] -test/unit/test_dsse.py::TestEnvelope::test_empty_signature PASSED [ 19%] -test/unit/test_dsse.py::TestEnvelope::test_multiple_signatures PASSED [ 20%] -test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA2_256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855] PASSED [ 20%] -test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA2_384-38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b] PASSED [ 20%] -test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA2_512-cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e] PASSED [ 21%] -test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA3_256-a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a] PASSED [ 21%] -test/unit/test_hashes.py::TestHashes::test_hashed_repr[SHA3_384-0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004] PASSED [ 22%] -test/unit/test_models.py::TestLogEntry::test_missing_inclusion_proof[0] PASSED [ 22%] -test/unit/test_models.py::TestLogEntry::test_missing_inclusion_proof[1746819403] PASSED [ 23%] -test/unit/test_models.py::TestLogEntry::test_missing_inclusion_promise_and_integrated_time_round_trip PASSED [ 23%] -test/unit/test_models.py::TestLogEntry::test_logentry_roundtrip PASSED [ 24%] -test/unit/test_models.py::TestLogInclusionProof::test_valid PASSED [ 24%] -test/unit/test_models.py::TestLogInclusionProof::test_negative_log_index PASSED [ 25%] -test/unit/test_models.py::TestLogInclusionProof::test_negative_tree_size PASSED [ 25%] -test/unit/test_models.py::TestLogInclusionProof::test_log_index_outside_tree_size PASSED [ 26%] -test/unit/test_models.py::TestLogInclusionProof::test_checkpoint_missing PASSED [ 26%] -test/unit/test_models.py::TestTimestampVerificationData::test_valid_timestamp PASSED [ 26%] -test/unit/test_models.py::TestTimestampVerificationData::test_no_timestamp PASSED [ 27%] -test/unit/test_models.py::TestTimestampVerificationData::test_invalid_timestamp PASSED [ 27%] -test/unit/test_models.py::TestVerificationMaterial::test_valid_verification_material PASSED [ 28%] -test/unit/test_models.py::TestBundle::test_invalid_bundle_version PASSED [ 28%] -test/unit/test_models.py::TestBundle::test_invalid_empty_cert_chain PASSED [ 29%] -test/unit/test_models.py::TestBundle::test_invalid_no_log_entry PASSED [ 29%] -test/unit/test_models.py::TestBundle::test_verification_materials_offline_no_checkpoint PASSED [ 30%] -test/unit/test_models.py::TestBundle::test_bundle_roundtrip PASSED [ 30%] -test/unit/test_models.py::TestBundle::test_bundle_missing_signed_time PASSED [ 31%] -test/unit/test_models.py::TestKnownBundleTypes::test_str PASSED [ 31%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_jwt PASSED [ 32%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_iss PASSED [ 32%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_aud PASSED [ 33%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_aud[None] PASSED [ 33%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_aud[not-sigstore] PASSED [ 33%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_iat PASSED [ 34%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_iat[None] PASSED [ 34%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_iat[not-an-int] PASSED [ 35%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_nbf_ok PASSED [ 35%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_nbf PASSED [ 36%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_exp PASSED [ 36%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_exp PASSED [ 37%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_identity_claim[https://accounts.google.com] PASSED [ 37%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_identity_claim[https://oauth2.sigstore.dev/auth] PASSED [ 38%] -test/unit/test_oidc.py::TestIdentityToken::test_missing_identity_claim[https://oauth2.sigstage.dev/auth] PASSED [ 38%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_federated_claims[notadict] PASSED [ 39%] -test/unit/test_oidc.py::TestIdentityToken::test_invalid_federated_claims[fed1] PASSED [ 39%] -test/unit/test_oidc.py::TestIdentityToken::test_ok[https://accounts.google.com-email-example@example.com-None] PASSED [ 40%] -test/unit/test_oidc.py::TestIdentityToken::test_ok[https://oauth2.sigstore.dev/auth-email-example@example.com-https://accounts.google.com] PASSED [ 40%] -test/unit/test_oidc.py::TestIdentityToken::test_ok[https://oauth2.sigstore.dev/auth-email-example@example.com-None] PASSED [ 40%] -test/unit/test_oidc.py::TestIdentityToken::test_ok[https://token.actions.githubusercontent.com-sub-some-subject-None] PASSED [ 41%] -test/unit/test_oidc.py::TestIdentityToken::test_ok[hxxps://unknown.issuer.example.com/auth-sub-some-subject-None] PASSED [ 41%] -test/unit/test_sign.py::test_sign_rekor_entry_consistent[staging] PASSED [ 42%] -test/unit/test_sign.py::test_sign_rekor_entry_consistent[production] PASSED [ 42%] -test/unit/test_sign.py::test_sign_rekor_entry_consistent[local] PASSED [ 43%] -test/unit/test_sign.py::test_sct_verify_keyring_lookup_error[staging] PASSED [ 43%] -test/unit/test_sign.py::test_sct_verify_keyring_lookup_error[production] PASSED [ 44%] -test/unit/test_sign.py::test_sct_verify_keyring_lookup_error[local] PASSED [ 44%] -test/unit/test_sign.py::test_sct_verify_keyring_error[staging] PASSED [ 45%] -test/unit/test_sign.py::test_sct_verify_keyring_error[production] PASSED [ 45%] -test/unit/test_sign.py::test_sct_verify_keyring_error[local] PASSED [ 46%] -test/unit/test_sign.py::test_identity_proof_claim_lookup[staging] PASSED [ 46%] -test/unit/test_sign.py::test_identity_proof_claim_lookup[production] PASSED [ 46%] -test/unit/test_sign.py::test_identity_proof_claim_lookup[local] PASSED [ 47%] -test/unit/test_sign.py::test_sign_prehashed[preprod-staging] PASSED [ 47%] -test/unit/test_sign.py::test_sign_prehashed[preprod-local] PASSED [ 48%] -test/unit/test_sign.py::test_sign_dsse[preprod-staging] PASSED [ 48%] -test/unit/test_sign.py::test_sign_dsse[preprod-local] PASSED [ 49%] -test/unit/test_sign.py::TestSignWithTSA::test_sign_artifact[preprod-staging] SKIPPED (skipping test that requires a Timestamp Authority) [ 49%] -test/unit/test_sign.py::TestSignWithTSA::test_sign_artifact[preprod-local] SKIPPED (skipping test that requires a Timestamp Authority) [ 50%] -test/unit/test_sign.py::TestSignWithTSA::test_sign_dsse[preprod-staging] SKIPPED (skipping test that requires a Timestamp Authority) [ 50%] -test/unit/test_sign.py::TestSignWithTSA::test_sign_dsse[preprod-local] SKIPPED (skipping test that requires a Timestamp Authority) [ 51%] -test/unit/test_sign.py::TestSignWithTSA::test_with_timestamp_error[preprod-staging] SKIPPED (skipping test that requires a Timestamp Authority) [ 51%] -test/unit/test_sign.py::TestSignWithTSA::test_with_timestamp_error[preprod-local] SKIPPED (skipping test that requires a Timestamp Authority) [ 52%] -test/unit/test_store.py::test_store_reads_root_json[https://tuf-repo-cdn.sigstore.dev] PASSED [ 52%] -test/unit/test_store.py::test_store_reads_root_json[https://tuf-repo-cdn.sigstage.dev] PASSED [ 53%] -test/unit/test_store.py::test_store_reads_targets_json[https://tuf-repo-cdn.sigstore.dev] PASSED [ 53%] -test/unit/test_store.py::test_store_reads_targets_json[https://tuf-repo-cdn.sigstage.dev] PASSED [ 53%] -test/unit/test_utils.py::test_key_id PASSED [ 54%] -test/unit/test_utils.py::test_sha256_streaming[0] PASSED [ 54%] -test/unit/test_utils.py::test_sha256_streaming[1] PASSED [ 55%] -test/unit/test_utils.py::test_sha256_streaming[2] PASSED [ 55%] -test/unit/test_utils.py::test_sha256_streaming[4] PASSED [ 56%] -test/unit/test_utils.py::test_sha256_streaming[8] PASSED [ 56%] -test/unit/test_utils.py::test_sha256_streaming[32] PASSED [ 57%] -test/unit/test_utils.py::test_sha256_streaming[128] PASSED [ 57%] -test/unit/test_utils.py::test_sha256_streaming[1024] PASSED [ 58%] -test/unit/test_utils.py::test_sha256_streaming[131072] PASSED [ 58%] -test/unit/test_utils.py::test_sha256_streaming[1048576] PASSED [ 59%] -test/unit/test_utils.py::test_sha256_streaming[134217728] PASSED [ 59%] -test/unit/test_utils.py::test_load_pem_public_key_format PASSED [ 60%] -test/unit/test_utils.py::test_load_pem_public_key_serialization PASSED [ 60%] -test/unit/test_utils.py::test_cert_is_ca[bogus-root.pem-True] PASSED [ 60%] -test/unit/test_utils.py::test_cert_is_ca[bogus-intermediate.pem-True] PASSED [ 61%] -test/unit/test_utils.py::test_cert_is_ca[bogus-leaf.pem-False] PASSED [ 61%] -test/unit/test_utils.py::test_cert_is_ca_invalid_states[bogus-root-noncritical-bc.pem] PASSED [ 62%] -test/unit/test_utils.py::test_cert_is_ca_invalid_states[bogus-root-invalid-ku.pem] PASSED [ 62%] -test/unit/test_utils.py::test_cert_is_ca_invalid_states[bogus-root-missing-ku.pem] PASSED [ 63%] -test/unit/test_utils.py::test_cert_is_root_ca[bogus-root.pem-True] PASSED [ 63%] -test/unit/test_utils.py::test_cert_is_root_ca[bogus-intermediate.pem-False] PASSED [ 64%] -test/unit/test_utils.py::test_cert_is_root_ca[bogus-leaf.pem-False] PASSED [ 64%] -test/unit/test_utils.py::test_cert_is_root_ca[bogus-leaf-invalid-ku.pem-False] PASSED [ 65%] -test/unit/test_utils.py::test_cert_is_leaf[bogus-root.pem-False] PASSED [ 65%] -test/unit/test_utils.py::test_cert_is_leaf[bogus-intermediate.pem-False] PASSED [ 66%] -test/unit/test_utils.py::test_cert_is_leaf[bogus-intermediate-with-eku.pem-False] PASSED [ 66%] -test/unit/test_utils.py::test_cert_is_leaf[bogus-leaf.pem-True] PASSED [ 66%] -test/unit/test_utils.py::test_cert_is_leaf[bogus-leaf-invalid-eku.pem-False] PASSED [ 67%] -test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-root-invalid-ku.pem] PASSED [ 67%] -test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-root-missing-ku.pem] PASSED [ 68%] -test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-leaf-invalid-ku.pem] PASSED [ 68%] -test/unit/test_utils.py::test_cert_is_leaf_invalid_states[bogus-leaf-missing-eku.pem] PASSED [ 69%] -test/unit/test_utils.py::test_cert_is_leaf_invalid_version[cert_is_leaf] PASSED [ 69%] -test/unit/test_utils.py::test_cert_is_leaf_invalid_version[cert_is_ca] PASSED [ 70%] -test/unit/test_utils.py::test_cert_is_leaf_invalid_version[cert_is_root_ca] PASSED [ 70%] -test/unit/test_version.py::test_version PASSED [ 71%] -test/unit/verify/test_policy.py::TestVerificationPolicy::test_does_not_init PASSED [ 71%] -test/unit/verify/test_policy.py::TestUnsafeNoOp::test_succeeds PASSED [ 72%] -test/unit/verify/test_policy.py::TestAnyOf::test_trivially_false PASSED [ 72%] -test/unit/verify/test_policy.py::TestAnyOf::test_fails_no_children_match PASSED [ 73%] -test/unit/verify/test_policy.py::TestAnyOf::test_succeeds PASSED [ 73%] -test/unit/verify/test_policy.py::TestAllOf::test_trivially_false PASSED [ 73%] -test/unit/verify/test_policy.py::TestAllOf::test_certificate_extension_not_found PASSED [ 74%] -test/unit/verify/test_policy.py::TestAllOf::test_fails_not_all_children_match PASSED [ 74%] -test/unit/verify/test_policy.py::TestAllOf::test_succeeds PASSED [ 75%] -test/unit/verify/test_policy.py::TestIdentity::test_fails_no_san_match PASSED [ 75%] -test/unit/verify/test_policy.py::TestSingleExtPolicy::test_succeeds PASSED [ 76%] -test/unit/verify/test_verifier.py::test_verifier_production PASSED [ 76%] -test/unit/verify/test_verifier.py::test_verifier_staging PASSED [ 77%] -test/unit/verify/test_verifier.py::test_verifier_one_verification PASSED [ 77%] -test/unit/verify/test_verifier.py::test_verifier_inconsistent_log_entry PASSED [ 78%] -test/unit/verify/test_verifier.py::test_verifier_multiple_verifications PASSED [ 78%] -test/unit/verify/test_verifier.py::test_verifier_bundle[bundle.txt] PASSED [ 79%] -test/unit/verify/test_verifier.py::test_verifier_bundle[bundle_v3.txt] PASSED [ 79%] -test/unit/verify/test_verifier.py::test_verifier_bundle[bundle_v3_alt.txt] PASSED [ 80%] -test/unit/verify/test_verifier.py::test_verifier_bundle_offline[bundle.txt] PASSED [ 80%] -test/unit/verify/test_verifier.py::test_verifier_bundle_offline[bundle_v3.txt] PASSED [ 80%] -test/unit/verify/test_verifier.py::test_verifier_bundle_offline[bundle_v3_alt.txt] PASSED [ 81%] -test/unit/verify/test_verifier.py::test_verifier_email_identity PASSED [ 81%] -test/unit/verify/test_verifier.py::test_verifier_uri_identity PASSED [ 82%] -test/unit/verify/test_verifier.py::test_verifier_policy_check PASSED [ 82%] -test/unit/verify/test_verifier.py::test_verifier_fail_expiry XFAIL [ 83%] -test/unit/verify/test_verifier.py::test_verifier_dsse_roundtrip[preprod-staging] PASSED [ 83%] -test/unit/verify/test_verifier.py::test_verifier_dsse_roundtrip[preprod-local] PASSED [ 84%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_verify_timestamp PASSED [ 84%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_no_validity_end PASSED [ 85%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete0] PASSED [ 85%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete1] PASSED [ 86%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete2] XFAIL [ 86%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_vierifier_verify_no_inclusion_promise_and_integrated_time[fields_to_delete3] PASSED [ 86%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_without_timestamp PASSED [ 87%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_too_many_timestamp PASSED [ 87%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_duplicate_timestamp PASSED [ 88%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_outside_validity_range PASSED [ 88%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_rfc3161_error PASSED [ 89%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_no_authorities PASSED [ 89%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_late_timestamp PASSED [ 90%] -test/unit/verify/test_verifier.py::TestVerifierWithTimestamp::test_verifier_not_enough_timestamp PASSED [ 90%] -test/integration/cli/test_attest.py::test_attest_success_default_output_bundle[https://slsa.dev/provenance/v0.2-slsa_predicate_v0_2.json] PASSED [ 91%] -test/integration/cli/test_attest.py::test_attest_success_default_output_bundle[https://slsa.dev/provenance/v1-slsa_predicate_v1_0.json] PASSED [ 91%] -test/integration/cli/test_attest.py::test_attest_success_custom_output_bundle PASSED [ 92%] -test/integration/cli/test_attest.py::test_attest_overwrite_existing_bundle PASSED [ 92%] -test/integration/cli/test_attest.py::test_attest_invalid_predicate_type PASSED [ 93%] -test/integration/cli/test_attest.py::test_attest_mismatching_predicate PASSED [ 93%] -test/integration/cli/test_attest.py::test_attest_missing_predicate PASSED [ 93%] -test/integration/cli/test_attest.py::test_attest_invalid_json_predicate PASSED [ 94%] -test/integration/cli/test_plumbing.py::test_fix_bundle_fixes_missing_checkpoint PASSED [ 94%] -test/integration/cli/test_plumbing.py::test_fix_bundle_upgrades_bundle PASSED [ 95%] -test/integration/cli/test_sign.py::test_sign_success_default_output_bundle PASSED [ 95%] -test/integration/cli/test_sign.py::test_sign_success_custom_outputs PASSED [ 96%] -test/integration/cli/test_sign.py::test_sign_success_custom_output_dir PASSED [ 96%] -test/integration/cli/test_sign.py::test_sign_success_no_default_files PASSED [ 97%] -test/integration/cli/test_sign.py::test_sign_overwrite_existing_bundle PASSED [ 97%] -test/integration/cli/test_sign.py::test_sign_fails_with_default_files_and_bundle_options PASSED [ 98%] -test/integration/cli/test_sign.py::test_sign_fails_with_multiple_inputs_and_custom_output PASSED [ 98%] -test/integration/cli/test_sign.py::test_sign_fails_with_output_dir_and_custom_output_files PASSED [ 99%] -test/integration/cli/test_sign.py::test_sign_fails_without_both_output_cert_and_signature PASSED [ 99%] -test/integration/cli/test_verify.py::test_regression_verify_legacy_bundle PASSED [100%] - -=========================================================================================================================== warnings summary =========================================================================================================================== -test/unit/internal/test_trust.py: 51 warnings -test/unit/test_sign.py: 60 warnings -test/unit/verify/test_verifier.py: 149 warnings -test/integration/cli/test_attest.py: 35 warnings -test/integration/cli/test_plumbing.py: 6 warnings -test/integration/cli/test_sign.py: 35 warnings -test/integration/cli/test_verify.py: 5 warnings - /usr/local/google/home/rpetgrave/workspaces/rekorv2/.venv/lib/python3.13/site-packages/sigstore_protobuf_specs/dev/sigstore/trustroot/v1/__init__.py:139: DeprecationWarning: TransparencyLogInstance.log_id is deprecated - warnings.warn( - -test/unit/test_sign.py: 8 warnings -test/unit/verify/test_verifier.py: 2 warnings - /usr/local/google/home/rpetgrave/workspaces/rekorv2/sigstore-python/sigstore/_internal/sct.py:176: UserWarning: Attribute's length must be >= 2 and <= 2, but it was 3 - _logger.debug(f"Found {cert.subject} as issuer, verifying if it is a ca") - --- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html -============================================================================================================================ tests coverage ============================================================================================================================ -___________________________________________________________________________________________________________ coverage: platform linux, python 3.13.2-final-0 ____________________________________________________________________________________________________________ - -Name Stmts Miss Branch BrPart Cover --------------------------------------------------------------------------- -sigstore/__init__.py 1 0 0 0 100% -sigstore/__main__.py 3 3 2 0 0% -sigstore/_internal/__init__.py 3 0 0 0 100% -sigstore/_internal/fulcio/__init__.py 2 0 0 0 100% -sigstore/_internal/fulcio/client.py 84 21 10 2 69% -sigstore/_internal/merkle.py 42 2 10 2 92% -sigstore/_internal/oidc/__init__.py 0 0 0 0 100% -sigstore/_internal/oidc/oauth.py 100 25 8 1 70% -sigstore/_internal/rekor/__init__.py 8 0 0 0 100% -sigstore/_internal/rekor/checkpoint.py 86 12 22 9 81% -sigstore/_internal/rekor/client.py 106 25 12 3 73% -sigstore/_internal/sct.py 86 16 22 11 75% -sigstore/_internal/timestamp.py 42 0 0 0 100% -sigstore/_internal/trust.py 264 16 62 8 92% -sigstore/_internal/tuf.py 80 7 18 1 92% -sigstore/_store/__init__.py 0 0 0 0 100% -sigstore/_utils.py 111 6 30 2 94% -sigstore/dsse/__init__.py 113 20 18 3 76% -sigstore/dsse/_predicate.py 79 1 2 1 98% -sigstore/errors.py 33 11 2 0 63% -sigstore/hashes.py 21 2 4 2 84% -sigstore/models.py 227 12 52 10 91% -sigstore/oidc.py 132 27 30 3 77% -sigstore/sign.py 93 4 12 4 92% -sigstore/verify/__init__.py 3 0 0 0 100% -sigstore/verify/policy.py 138 5 16 3 95% -sigstore/verify/verifier.py 165 15 44 7 89% --------------------------------------------------------------------------- -TOTAL 2022 230 376 72 86% -======================================================================================================================= short test summary info ======================================================================================================================== -SKIPPED [10] test/conftest.py:115: skipping test that requires a Timestamp Authority -====================================================================================================== 203 passed, 10 skipped, 2 xfailed, 351 warnings in 26.98s ======================================================================================================= -Name Stmts Miss Branch BrPart Cover Missing ------------------------------------------------------------------------------------- -sigstore/__init__.py 1 0 0 0 100% -sigstore/__main__.py 3 3 2 0 0% 19-22 -sigstore/_internal/__init__.py 3 0 0 0 100% -sigstore/_internal/fulcio/__init__.py 2 0 0 0 100% -sigstore/_internal/fulcio/client.py 84 21 10 2 69% 113-115, 122-123, 128, 144-158, 195 -sigstore/_internal/merkle.py 42 2 10 2 92% 107, 127 -sigstore/_internal/oidc/__init__.py 0 0 0 0 100% -sigstore/_internal/oidc/oauth.py 100 25 8 1 70% 134, 137-166, 202, 234, 239, 243 -sigstore/_internal/rekor/__init__.py 8 0 0 0 100% -sigstore/_internal/rekor/checkpoint.py 86 12 22 9 81% 77, 81, 99, 131, 140, 144, 153, 176, 184-185, 215, 229 -sigstore/_internal/rekor/client.py 106 25 12 3 73% 56, 74-83, 101-106, 131, 136, 142-143, 160-161, 196-199, 210->208, 256 -sigstore/_internal/sct.py 86 16 22 11 75% 57-58, 61, 73, 82, 108, 147, 162-163, 168, 179-181, 202->222, 211, 216, 225 -sigstore/_internal/timestamp.py 42 0 0 0 100% -sigstore/_internal/trust.py 264 16 62 8 92% 154, 181-191, 256, 316, 334, 347-348, 356, 366, 441, 465, 518, 571, 631 -sigstore/_internal/tuf.py 80 7 18 1 92% 123-124, 135, 140-144, 163-167 -sigstore/_store/__init__.py 0 0 0 0 100% -sigstore/_utils.py 111 6 30 2 94% 42, 110-111, 114, 138-139 -sigstore/dsse/__init__.py 113 20 18 3 76% 94-98, 110-120, 180-181, 239, 292, 298-299 -sigstore/dsse/_predicate.py 79 1 2 1 98% 171 -sigstore/errors.py 33 11 2 0 63% 31, 36-49, 93-98, 110, 118 -sigstore/hashes.py 21 2 4 2 84% 49, 57 -sigstore/models.py 227 12 52 10 91% 188, 196, 309, 412, 477, 502, 509-510, 547, 549, 554, 634 -sigstore/oidc.py 132 27 30 3 77% 128-129, 213, 256-257, 269-270, 297, 307-315, 339-340, 349-354, 365, 369-397, 411-412 -sigstore/sign.py 93 4 12 4 92% 103->exit, 113-114, 130, 136 -sigstore/verify/__init__.py 3 0 0 0 100% -sigstore/verify/policy.py 138 5 16 3 95% 126-127, 136, 347, 454, 461->465 -sigstore/verify/verifier.py 165 15 44 7 89% 261-262, 336-337, 343, 347, 370, 404, 425-426, 433, 435, 448, 485-486 ------------------------------------------------------------------------------------- -TOTAL 2022 230 376 72 86% diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index a2eb764ee..550802961 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -171,14 +171,11 @@ def test_sign_dsse(preprod): @pytest.mark.timestamp_authority class TestSignWithTSA: @pytest.fixture - def sig_ctx(self, asset, tsa_url) -> SigningContext: - trust_config = ClientTrustConfig.from_json( - asset("tsa/trust_config.json").read_text() - ) - - trust_config._inner.signing_config.tsa_urls[0].url = tsa_url - - return SigningContext.from_trust_config(trust_config) + def sign_ctx_and_identity(self, preprod, tsa_url): + sign_ctx_func, _, identity = preprod + sign_ctx = sign_ctx_func() + sign_ctx._tsa_clients[0].url = tsa_url + return sign_ctx, identity @pytest.fixture def identity(self, preprod): @@ -192,7 +189,8 @@ def hashed(self) -> Hashed: digest=hashlib.sha256(input_).digest(), algorithm=HashAlgorithm.SHA2_256 ) - def test_sign_artifact(self, sig_ctx, identity, hashed): + def test_sign_artifact(self, sign_ctx_and_identity, hashed): + sig_ctx, identity = sign_ctx_and_identity with sig_ctx.signer(identity) as signer: bundle = signer.sign_artifact(hashed) @@ -201,7 +199,8 @@ def test_sign_artifact(self, sig_ctx, identity, hashed): bundle.verification_material.timestamp_verification_data.rfc3161_timestamps ) - def test_sign_dsse(self, sig_ctx, identity): + def test_sign_dsse(self, sign_ctx_and_identity): + sig_ctx, identity = sign_ctx_and_identity stmt = ( StatementBuilder() .subjects( @@ -228,8 +227,9 @@ def test_sign_dsse(self, sig_ctx, identity): bundle.verification_material.timestamp_verification_data.rfc3161_timestamps ) - def test_with_timestamp_error(self, sig_ctx, identity, hashed, caplog): + def test_with_timestamp_error(self, sign_ctx_and_identity, hashed, caplog): # Simulate here an TSA that returns an invalid Timestamp + sig_ctx, identity = sign_ctx_and_identity sig_ctx._tsa_clients.append(TimestampAuthorityClient("invalid-url")) with caplog.at_level(logging.WARNING, logger="sigstore.sign"): From d5876f08c429f071b42fcbe170f90653d77cab72 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 16:47:43 +0000 Subject: [PATCH 13/20] lint Signed-off-by: Ramon Petgrave --- test/unit/test_sign.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index 550802961..f9a880e15 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -21,7 +21,6 @@ import sigstore.oidc from sigstore._internal.timestamp import TimestampAuthorityClient -from sigstore._internal.trust import ClientTrustConfig from sigstore.dsse import StatementBuilder, Subject from sigstore.errors import VerificationError from sigstore.hashes import Hashed From 7b1d39e20b73ae5ddd4d574e717b0ff683f13e84 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 18:58:48 +0000 Subject: [PATCH 14/20] rename fixcture Signed-off-by: Ramon Petgrave --- test/unit/internal/rekor/test_client_v2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/internal/rekor/test_client_v2.py b/test/unit/internal/rekor/test_client_v2.py index e8058223a..40328350d 100644 --- a/test/unit/internal/rekor/test_client_v2.py +++ b/test/unit/internal/rekor/test_client_v2.py @@ -28,10 +28,10 @@ @pytest.mark.staging @pytest.mark.ambient_oidc -def test_rekor_v2_create_entry_dsse(staging): +def test_rekor_v2_create_entry_dsse(preprod): # This is not a real unit test: it requires not only staging rekor but also TUF # fulcio and oidc -- maybe useful only until we have real integration tests in place - sign_ctx_cls, _, identity = staging + sign_ctx_cls, _, identity = preprod # Hack to run Signer.sign() with staging rekor v2 sign_ctx = sign_ctx_cls() @@ -64,10 +64,10 @@ def test_rekor_v2_create_entry_dsse(staging): @pytest.mark.staging @pytest.mark.ambient_oidc -def test_rekor_v2_create_entry_hashed_rekord(staging): +def test_rekor_v2_create_entry_hashed_rekord(preprod): # This is not a real unit test: it requires not only staging rekor but also TUF # fulcio and oidc -- maybe useful only until we have real integration tests in place - sign_ctx_cls, _, identity = staging + sign_ctx_cls, _, identity = preprod # Hack to run Signer.sign() with staging rekor v2 sign_ctx = sign_ctx_cls() From 4d6232941dbb370f5f2bfd9e887b2922c64403b7 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 19:13:53 +0000 Subject: [PATCH 15/20] xfail on local when trying to fetch logs Signed-off-by: Ramon Petgrave --- test/unit/test_sign.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index f9a880e15..9724a3754 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -30,7 +30,9 @@ from .conftest import LOCAL -@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) +@pytest.mark.parametrize( + "env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)] +) @pytest.mark.ambient_oidc def test_sign_rekor_entry_consistent(sign_ctx_and_ident_for_env): ctx_cls, identity = sign_ctx_and_ident_for_env @@ -91,7 +93,9 @@ def test_sct_verify_keyring_error(sign_ctx_and_ident_for_env, monkeypatch): signer.sign_artifact(payload) -@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) +@pytest.mark.parametrize( + "env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)] +) @pytest.mark.ambient_oidc def test_identity_proof_claim_lookup(sign_ctx_and_ident_for_env, monkeypatch): ctx_cls, identity = sign_ctx_and_ident_for_env From 65bcb10e86983fb53cb9b509850749a5825a21ff Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 20:54:14 +0000 Subject: [PATCH 16/20] cleanup Signed-off-by: Ramon Petgrave --- test/unit/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/conftest.py b/test/unit/conftest.py index c1c5f71b3..8f103deea 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -218,7 +218,6 @@ def ctx_cls(): return SigningContext.from_trust_config(ClientTrustConfig.production()) elif env == "local": - print("HAS", _has_setup_sigstore_env()) if not _has_setup_sigstore_env(): pytest.skip( "skipping test that use the local environment due to unset `TEST_SETUP_SIGSTORE_ENV` env variable" From fed8f7078509feadeab55dc684ce0ca27053be1e Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 20:55:26 +0000 Subject: [PATCH 17/20] -vvv Signed-off-by: Ramon Petgrave --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85e4b83f7..6e7af60bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: unshare --map-root-user --net make test T="test/unit" TEST_ARGS="--skip-online -vv --showlocals" - name: test - run: make test TEST_ARGS="-vv --showlocals" + run: make test TEST_ARGS="-vvv --showlocals" # TODO: Refactor this or remove it entirely once there's # a suitable staging TSA instance. From 4d5f19ef8c4f206728f4d5cd0a34ba00e40db232 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 21:03:39 +0000 Subject: [PATCH 18/20] additional xfail Signed-off-by: Ramon Petgrave --- test/unit/test_sign.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index 9724a3754..0427a3a8c 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -54,7 +54,7 @@ def test_sign_rekor_entry_consistent(sign_ctx_and_ident_for_env): assert expected_entry.log_index == actual_entry.log_index -@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) +@pytest.mark.parametrize("env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)]) @pytest.mark.ambient_oidc def test_sct_verify_keyring_lookup_error(sign_ctx_and_ident_for_env, monkeypatch): ctx, identity = sign_ctx_and_ident_for_env @@ -73,7 +73,7 @@ def test_sct_verify_keyring_lookup_error(sign_ctx_and_ident_for_env, monkeypatch signer.sign_artifact(payload) -@pytest.mark.parametrize("env", ["staging", "production", LOCAL]) +@pytest.mark.parametrize("env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)]) @pytest.mark.ambient_oidc def test_sct_verify_keyring_error(sign_ctx_and_ident_for_env, monkeypatch): ctx, identity = sign_ctx_and_ident_for_env From cac6e00f3d7676e58a8f71bd076fc7e3564b91fa Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 21:06:29 +0000 Subject: [PATCH 19/20] no LOCAL for sign_ctx_and_ident_for_env Signed-off-by: Ramon Petgrave --- test/unit/conftest.py | 11 ----------- test/unit/test_sign.py | 14 ++++---------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/test/unit/conftest.py b/test/unit/conftest.py index 8f103deea..24f8ae182 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -217,17 +217,6 @@ def ctx_cls(): def ctx_cls(): return SigningContext.from_trust_config(ClientTrustConfig.production()) - elif env == "local": - if not _has_setup_sigstore_env(): - pytest.skip( - "skipping test that use the local environment due to unset `TEST_SETUP_SIGSTORE_ENV` env variable" - ) - - def ctx_cls(): - return SigningContext.from_trust_config( - ClientTrustConfig.from_json(Path(os.getenv("TRUST_CONFIG")).read_text()) - ) - else: raise ValueError(f"Unknown env {env}") diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index 0427a3a8c..ad19b82e1 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -27,12 +27,8 @@ from sigstore.sign import SigningContext from sigstore.verify.policy import UnsafeNoOp -from .conftest import LOCAL - -@pytest.mark.parametrize( - "env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)] -) +@pytest.mark.parametrize("env", ["staging", "production"]) @pytest.mark.ambient_oidc def test_sign_rekor_entry_consistent(sign_ctx_and_ident_for_env): ctx_cls, identity = sign_ctx_and_ident_for_env @@ -54,7 +50,7 @@ def test_sign_rekor_entry_consistent(sign_ctx_and_ident_for_env): assert expected_entry.log_index == actual_entry.log_index -@pytest.mark.parametrize("env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)]) +@pytest.mark.parametrize("env", ["staging", "production"]) @pytest.mark.ambient_oidc def test_sct_verify_keyring_lookup_error(sign_ctx_and_ident_for_env, monkeypatch): ctx, identity = sign_ctx_and_ident_for_env @@ -73,7 +69,7 @@ def test_sct_verify_keyring_lookup_error(sign_ctx_and_ident_for_env, monkeypatch signer.sign_artifact(payload) -@pytest.mark.parametrize("env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)]) +@pytest.mark.parametrize("env", ["staging", "production"]) @pytest.mark.ambient_oidc def test_sct_verify_keyring_error(sign_ctx_and_ident_for_env, monkeypatch): ctx, identity = sign_ctx_and_ident_for_env @@ -93,9 +89,7 @@ def test_sct_verify_keyring_error(sign_ctx_and_ident_for_env, monkeypatch): signer.sign_artifact(payload) -@pytest.mark.parametrize( - "env", ["staging", "production", pytest.param(LOCAL, marks=pytest.mark.xfail)] -) +@pytest.mark.parametrize("env", ["staging", "production"]) @pytest.mark.ambient_oidc def test_identity_proof_claim_lookup(sign_ctx_and_ident_for_env, monkeypatch): ctx_cls, identity = sign_ctx_and_ident_for_env From c1ea8aadf53e565922e32336e70790a1c3352d38 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 13 Jun 2025 21:14:31 +0000 Subject: [PATCH 20/20] revert -vvv Signed-off-by: Ramon Petgrave --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e7af60bf..85e4b83f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: unshare --map-root-user --net make test T="test/unit" TEST_ARGS="--skip-online -vv --showlocals" - name: test - run: make test TEST_ARGS="-vvv --showlocals" + run: make test TEST_ARGS="-vv --showlocals" # TODO: Refactor this or remove it entirely once there's # a suitable staging TSA instance.