Files
Jeff Bailey 3dfb724997 Add test documentation and expand CLI test coverage (#46)
* Add test documentation and expand CLI test coverage

Document testing philosophy and expand test suite with better CLI-focused
tests and improved error verification.

Changes:
- Add tests/README.md documenting testing philosophy separating application
  (CLI interface) from library (archive format) testing concerns
- Update README.md with Testing section linking to test documentation
- Add 23 new CLI-focused tests covering:
  * Basic CLI: conflicting operations, missing operation specification
  * Create operations: directory archiving, verbose output, empty archive
    handling, nonexistent file errors
  * Extract operations: verbose output, directory structure preservation
  * Round-trip tests: single/multiple files, directories, empty files,
    special characters in filenames
  * Error handling: permission denied, corrupted archives, dash-prefixed
    filenames with -- separator
  * Verbose output: format verification for create/extract operations
  * CLI parsing: mixed short/long options, option order variations,
    default overwrite behavior
  * Edge cases: filenames with spaces, large file counts (100 files)
- Improve all 8 existing tests with better error verification:
  * Add exit code checks and stderr pattern matching
  * Add no_stderr() assertions for successful operations
  * Add sanity checks for archive file sizes
  * Add TODO comments noting exit code mismatches (usage errors currently
    return 1 instead of documented 64)
- Reorganize tests with clear section headers:
  1. Basic CLI Tests
  2. Create Operation Tests
  3. Extract Operation Tests
  4. Round-trip Tests
  5. Error Handling and Exit Code Tests
  6. Verbose Output Format Tests
  7. CLI Argument Handling Tests
  8. Edge Case Tests

All 31 tests pass. Test suite now has clear documentation explaining what
should be tested at the application level vs library level.

* Align exit codes with GNU tar and modernize tests

- Refactor `uumain` to manually handle `clap` errors, ensuring exit code 64 for command-line syntax errors and exit code 2 for semantic/fatal errors.
- Add mutual exclusion between `--create` and `--extract` operations.
- Update `README.md` and `tests/README.md` with corrected exit code documentation and clarified testing philosophy.
- Modernize `tests/by-util/test_tar.rs`:
    - Define `TAR_BLOCK_SIZE` constant (512 bytes).
    - Use `uutests` convenience methods (`at.touch()`, `at.rmdir()`, etc.).
    - Improve `test_verbose` to use `PathBuf`.
    - Replace `.no_stderr()` with `.no_output()`.
    - Implement a root-user check in `test_create_permission_denied`.
    - Remove redundant or outdated roundtrip and verbose format tests.

* Add missing [test] annotation.

---------

Co-authored-by: Sylvestre Ledru <sylvestre.ledru@gmail.com>
2026-03-08 21:36:45 +01:00

2.5 KiB

Testing the tar Application

This directory contains tests for the tar command-line utility.

Philosophy

The tar utility is built on top of the tar-rs library, which is an external crate we depend on. Because of this, we split our testing into two distinct areas:

  1. The External Library (tar-rs): This is an independent library that handles the nitty-gritty details of the tar format. If you want to verify that permissions are preserved correctly, that long paths are handled according to the UStar spec, or that unicode filenames are encoded properly, those tests belong in the tar-rs crate itself.

  2. The Application (tar): This is where we test the user interface. These tests ensure that the command-line arguments are parsed correctly, that the program exits with the right status codes, and that basic operations like creating and extracting archives actually work from a user's perspective.

Writing Tests for the Application

When writing tests here, focus on the user experience.

  • Do check that flags like -c, -x, -v, and -f do what they say.

  • Do check that invalid combinations of flags produce a helpful error message and exit code 2.

  • Do check that serious errors (like file not found) return exit code 2.

  • Do perform "smoke tests" — create an archive and make sure the file appears; extract an archive and make sure the files come out.

  • Don't inspect the internal bytes of the archive to verify header fields. Trust that tar-rs handles that.

  • Don't write complex tests for edge cases in file system permissions or encoding, unless they are specifically related to a CLI flag.

Example

If you are testing that tar -cf archive.tar file.txt works:

  • Good: Run the command, assert it succeeds (exit code 0), and assert that archive.tar exists on disk.
  • Bad: Run the command, open archive.tar with a library, parse the headers, and assert that the checksum is correct.

Running Tests

You can run these tests just like any other Rust project:

cargo test --all

To run a specific test:

cargo test test_name

Exit Codes

We follow GNU tar conventions for exit codes:

  • 0: Success.
  • 1: Some files differ (used in compare mode, not yet implemented).
  • 2: Fatal error (file not found, permission denied, conflicting options like -c -x, invalid option values).
  • 64: Command line usage error (unknown option, missing required argument, wrong number of values for an option).