Skip to content

chore: implement a snapshot testing utility #5266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft

Conversation

dougch
Copy link
Contributor

@dougch dougch commented Apr 22, 2025

Release Summary:

Resolved issues:

#5097

Description of changes:

We'd like a tool like insta, but for our C project. Because pytest can output junit, I'm attempting to use that as a data-source to track test invocation.

Example use from my testing:

cd tests/integrationv2
junit-snapshot init
junit-snapshot capture  ../../build/junit/integrationv2_happy_path.xml --name "baseline" --description "initial baseline snapshot"

List output, note that numbers captured for each test end state; the test names are present in the snapshot file:

$ junit-snapshot list
Available snapshots:
1: 20250422_210032 - 2025-04-22 21:00:32 (Tests: 8840, Passed: 8840, Failed: 0, Errors: 0, Skipped: 0)
2: 20250422_210701 - 2025-04-22 21:07:01 (Tests: 576, Passed: 576, Failed: 0, Errors: 0, Skipped: 0)

I then changed the CIPHERS in the ocsp test from ALL_CIPHERS to TLS13_CIPHERS, reran the ocsp test and compared the resulting xml file against the named snapshot

$ junit-snapshot compare ../../build/junit/integrationv2_ocsp.xml 20250422_210701
Comparing "../../build/junit/integrationv2_ocsp.xml" against baseline snapshot: 20250422_210701

Test Suite: pytest
  ✓ test_s2n_client_ocsp_response[OCSP_RSA-TLS1.3-X25519-S2N-OpenSSL-TLS_AES_128_GCM_SHA256]

...SNIP...

  - test_s2n_server_ocsp_response[OCSP_RSA-TLS1.1-P-256-S2N-GnuTLS-DHE-RSA-AES128-SHA] (missing test from suite pytest)
  - test_s2n_server_ocsp_response[OCSP_ECDSA_256-TLS1.1-P-256-S2N-GnuTLS-ECDHE-ECDSA-AES128-SHA] (missing test from suite pytest)

Comparison Summary:
  Total tests: 375
  Matching tests: 375
  Different tests: 0
  New tests: 0
  Missing tests: 201

Differences found!

So it correctly identified that 201 tests were missed because of the change in ciphers.

Call-outs:

There are bugs. I don't love the name.

Testing:

How is this change tested (unit tests, fuzz tests, etc.)? What manual testing was performed? Are there any testing steps to be verified by the reviewer?
How can you convince your reviewers that this PR is safe and effective?
Is this a refactor change? If so, how have you proved that the intended behavior hasn't changed?

Remember:

  • Any change to the library source code should at least include unit tests.
  • Any change to the core stuffer or blob methods should include CBMC proofs.
  • Any change to the CI or tests should:
    1. prove that the test succeeds for good input
    2. prove that the test fails for bad input (eg, a test for memory leaks fails when a memory leak is committed)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

dougch added 17 commits April 22, 2025 13:21
- Add #[allow(dead_code)] attributes to unused functions and variants
- Fix unused variable warning by prefixing with underscore
- Make TestSuites fields optional with default values
- Fix Option<e> typo to Option<Error> in model.rs
- Add test for parsing integrationv2_sni_match.xml
- Mark tests with missing files as ignored
- Add test_parse_integration_files.rs to verify parsing of all integration XML files
- Add test_snapshot_integration.rs to test snapshot creation and storage
- Add test_cli_integration.rs to test CLI functionality
- Update main.rs to support --dir parameter in capture and list commands

This ensures the junit-snapshot tool can successfully parse and use all the
integration test XML files.
- Add all integration test XML files as test inputs
- Move snapshot_testing_utility_design_doc.md from docs/ to tools/
- These XML files are used by the new test suite to verify parsing
  and snapshot functionality
Add a comprehensive guide for new developers on how to use the
junit-snapshot tool, including:
- Initial setup and building
- Creating and managing snapshots
- Comparing test results against snapshots
- Updating snapshots as tests evolve
- Best practices and workflow examples

This guide will help onboard new developers and provide a reference
for working with the snapshot testing utility.
Replace symlink and PATH instructions with cargo install instructions,
which is the recommended way to install Rust binaries. This provides
a cleaner installation process that leverages Cargo's built-in
package management capabilities.
- Add integrationv2_happy_path.xml (1.2MB) as a test input file
- Modify parser to use buffered reading for large XML files
- This change enables the previously ignored tests that depend on this file
- The buffered approach is more memory efficient for large files
- Remove ignore annotations from tests that use integrationv2_happy_path.xml
- Now that the large test file is available and the parser is improved,
  these tests can run successfully
- This completes the test coverage for the snapshot functionality
This commit addresses two issues in the junit-snapshot tool:
1. Fix type error in model.rs where 'error: Option<e>' was incorrectly defined
2. Improve XML parsing to handle large files by:
   - Using BufReader with streaming parser instead of loading entire file
   - Calculating total test counts from individual test suites when not set in root
   - Properly handling memory-efficient deserialization

These changes allow the parser to successfully process large XML files like
integrationv2_happy_path.xml without memory issues while maintaining
accurate test statistics.
Remove unused Read import and add #[allow(dead_code)] attribute to
parse_junit_xml function to eliminate compiler warnings.
This commit adds a new 'compare' command to the JUnit snapshot utility that:
- Compares a new JUnit file against a baseline snapshot
- Detects matching, different, new, and missing tests
- Shows detailed information about test status changes
- Uses colored output to highlight differences
- Supports a diff-only flag to show only differences
- Supports a fail-on-diff flag for CI integration

Also adds comprehensive tests for the compare command and updates documentation.
@github-actions github-actions bot added the s2n-core team label Apr 22, 2025
@@ -32,7 +32,13 @@
# We're not including openssl1.1.1 in our package list to avoid confusing cmake.
# It will be in the PATH of our devShell for use in tests.
pythonEnv
pkgs.valgrind
# Pin to a specific version of valgrind that's maintained
(pkgs.valgrind.overrideAttrs (oldAttrs: {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this belongs elsewhere- I'll pull this out when we get further along.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant