Skip to content

Testing Strategy

This document covers the testing philosophy, categories, and execution for QPKI development.

Integration Testing, Not Primitive Testing

Section titled “Integration Testing, Not Primitive Testing”

We do NOT duplicate tests that underlying cryptographic libraries already perform. For PQC (ML-DSA, SLH-DSA, ML-KEM), we use cloudflare/circl which includes NIST ACVP test vectors and comprehensive fuzzing.

What we test:

  • Key generation produces valid keys (integration)
  • Sign/Verify round-trip works (integration)
  • Key serialization to PEM/DER (PKI-specific)
  • Certificate integration (PKI-specific)
  • Cross-validation with OpenSSL/BouncyCastle

What we don’t test:

  • ACVP test vectors (circl does this)
  • Edge cases in primitive operations (circl does this)

Every certificate type is verified by at least 2 independent implementations:

  • QPKI itself
  • OpenSSL 3.6+ (with native PQC support)
  • BouncyCastle 1.83+ (Java)
CategoryLocationCI JobPurpose
Unit*_test.gotestIndividual function correctness
Integrationinternal/ca/*_test.gotestFull CA workflows
CLIcmd/qpki/*_test.gotestCommand-line interface
Fuzzing*_fuzz_test.gofuzzASN.1 parser robustness
Cross-OpenSSLtest/crossval/openssl/crosstest-opensslOpenSSL interoperability
Cross-BCtest/crossval/bouncycastle/crosstest-bcBouncyCastle interoperability
ProtocolCI workflow stepsocsp-test, tsa-test, cms-testRFC protocol compliance
HSMCI workflow stepshsm-testPKCS#11 integration
E2EExternal lab repolab-testsReal-world scenarios
MetricThresholdEnforcement
Minimum coverage60%CI blocks merge
Target for new code70%Code review
Patch coverage70%Codecov check
Terminal window
# Standard unit tests
make test
make test-race
make coverage
make fuzz
make fuzz-quick
make fuzz-all
make crosstest
make crosstest-openssl
make crosstest-bc
┌─ Workflow
│ └─ pki-test
├─ Protocols
│ ├─ ocsp-test
│ ├─ tsa-test
│ └─ cms-test
test ───┬──> build (+ smoke) ───────────┼─ Interoperability
│ │ ├─ crosstest-openssl
lint ───┘ │ └─ crosstest-bc
├─ Integration
│ └─ hsm-test
└─ E2E Scenarios
├─ cryptoagility-test
└─ lab-tests

All jobs after build run in parallel.

JobDescription
pki-testPKI operations (key, CSR, CA, cert, CRL, credential)
ocsp-testOCSP sign/verify
tsa-testTSA sign/verify
cms-testCMS sign/encrypt
crosstest-opensslInteroperability with OpenSSL 3.6
crosstest-bcInteroperability with BouncyCastle 1.83
hsm-testHSM operations with SoftHSM2
cryptoagility-testAlgorithm transitions (EC → Catalyst → ML-DSA)
lab-testsEnd-to-end demos from pki-lab repo

See TESTS-INTEROP.md for the detailed test matrix and cross-validation coverage.

Go Test Function Prefixes:

PrefixTypeBoxLocationExample
TestU_UnitWhiteinternal/**/*_test.goTestU_ParseCertificate_ValidPEM
TestF_FunctionalGreycmd/**/*_test.goTestF_CA_Initialize_ECDSA
TestA_AcceptanceBlacktest/acceptance/TestA_CA_Init_WithProfile
TestC_Cross-valBlacktest/crossval/TestC_OpenSSL_VerifyCert_MLDSA
FuzzFuzzing-*_fuzz_test.goFuzzCMSParser

TC-ID Format (ISO 29119):

TC-<TYPE>-<DOMAIN>-<SEQ>
TYPE: U, F, A, C, Z
DOMAIN: KEY, CA, CERT, CRL, OCSP, TSA, CMS, HSM
SEQ: 001-999

Example: TC-F-CA-001TestF_CA_Initialize_ECDSA

  • Unit tests (TestU_*): Same package as code, *_test.go
  • Functional tests (TestF_*): cmd/qpki/*_test.go
  • Acceptance tests (TestA_*): test/acceptance/ with //go:build acceptance
  • Cross-validation (TestC_*): test/crossval/ with //go:build crossval
  • Use table-driven tests for multiple scenarios

Fuzzing tests ensure parsers don’t panic on malformed input:

PackageFocus
cmsASN.1 parsing (SignedData, EnvelopedData)
tsaASN.1 parsing (Request, Response)
ocspASN.1 parsing (Request, Response)
caComposite signatures, public key parsing
cryptoAlgorithm parsing, key/signature handling
profileProfile YAML parsing
credentialCredential JSON parsing
x509utilCSR parsing, hybrid extensions