Commit Graph

67 Commits

Author SHA1 Message Date
52b4fef814 Add error recovery tests for backup failures
Adds 7 new tests in TestErrorRecovery class covering:
- Hardlink failure cleanup (incomplete backup removal)
- Rsync failure cleanup
- Detection of incomplete backups without marker files
- Lock handling after backup failures
- Permission error handling during cleanup

Tests verify that failed backups are properly cleaned up and don't interfere
with subsequent backup operations or lock management.
2026-02-04 22:21:02 -08:00
84c8425422 Add tests for external rsync and hardlink tools
Tests --external-rsync and --external-hardlink flags with conditional
execution based on tool availability. Verifies external tools correctly
sync files and preserve hardlinks for unchanged files.
2026-02-04 22:14:04 -08:00
e9a65a9b88 Add tests for rsync edge cases
Covers real-world scenarios: broken symlinks, unicode/spaces in filenames,
empty files, and deeply nested paths. All edge cases handled correctly.
2026-02-04 22:00:55 -08:00
95614b6eec Add metadata preservation tests for copy_direntry
Verify that timestamps, permissions, and ownership are correctly
preserved when copying files, directories, and symlinks. Tests account
for filesystem behavior where reading a file updates its atime by
capturing source timestamps before the copy operation.
2026-02-04 21:56:25 -08:00
3214b48ae8 Add tests for ISO week calendar boundary edge cases
Tests cover week 53 year transitions, same week numbers across years,
and late December dates in week 1 of next year. Discovered bug #33
where weekly retention compares only week number without ISO year,
causing backups 1 year apart to be incorrectly deduplicated.
2026-02-04 21:49:23 -08:00
f0894584d4 Add tests for force lock behavior with signal handling
Tests verify --force flag properly handles running processes:
- SIGTERM success (process terminates gracefully)
- SIGKILL escalation (process survives SIGTERM)
- Kill failure handling (permission errors)
2026-02-04 21:03:46 -08:00
06583f7e1a Add test for combined retention policy interaction
Add test_combined_retention_policies to verify all 5 retention policies
(keep_all, keep_daily, keep_weekly, keep_monthly, keep_yearly) work
correctly together. Test validates precedence rules where later retention
tiers can override earlier ones (e.g., monthly overrides weekly, yearly
overrides monthly) and documents threshold inclusive behavior.

Test uses 36 backups spanning 2017-2021 with expected 21 backups kept
based on policy interaction.
2026-02-04 20:58:06 -08:00
fb9dcbd392 Refactor: split rsync tests into separate module
Move all rsync-related tests (44 tests) from test_fs.py to new
test_rsync.py module for better organization:
- TestRsync (14 tests)
- TestRsyncBasic (5 tests)
- TestParseRsyncOutput (17 tests)
- TestRsyncExt (8 tests)

Extract shared helper functions to conftest.py to eliminate duplication:
- create_file(), create_dir(), relpath()
- check_identical_file()
- common_fs_dirs fixture

This improves test organization and maintainability by grouping related
tests and removing code duplication between test modules.
2026-02-04 20:23:51 -08:00
dc9bc2e5e4 Add comprehensive CLI tests
Implements 26 tests across 6 test classes covering all CLI functionality:
- Argument parsing and flag handling
- Platform validation (Linux/macOS only)
- External tool availability checks (rsync, cp, gcp)
- Directory validation
- Lock acquisition and release
- Backup execution flow

Brings CLI module from zero coverage to complete test coverage.
Total test count: 99 → 127 tests (all passing).
2026-02-04 19:40:59 -08:00
fe48010fc9 Add comprehensive tests for rsync output parsing
Implements TestParseRsyncOutput class with 17 tests covering all code
paths in _parse_rsync_output() function. Tests cover deletions, file/
directory/symlink creation, rewrites, metadata updates (permissions,
ownership, timestamps), and error handling for invalid input.
2026-02-04 19:36:24 -08:00
ee1df4cb21 Update tests 2026-02-04 19:31:29 -08:00
5dc9235992 Fix potential NameError in copy_file exception handler
Initialize file descriptors to None before opening to prevent
UnboundLocalError in the finally block if file opening fails.

Changes:
- Initialize fin = None and fout = None at function start
- Check if descriptors are not None before closing
- Remove UnboundLocalError from exception handling (no longer needed)

This improves code quality by eliminating the need to catch an error
that indicates a logic bug. The existing tests verify correct behavior.

Fixes #6
2026-02-03 22:20:52 -08:00
Claude
7c59bbc90b Fix high-priority bugs and add comprehensive test coverage
This commit addresses 8 high-priority issues identified in code analysis.

Fixes #3
Fixes #4
Fixes #5
Fixes #7
Fixes #10
Fixes #19
Fixes #20
Fixes #21

## Critical Bug Fixes

1. **Race condition in lock file creation (#3)**
   - Changed to atomic file creation using os.O_CREAT | os.O_EXCL
   - Prevents two processes from both acquiring the lock
   - Location: curateipsum/backup.py:110-115

2. **Invalid lock file error handling (#4)**
   - Added try/except for corrupted/empty lock files
   - Gracefully removes corrupted locks and retries
   - Location: curateipsum/backup.py:121-133

3. **SIGKILL vs SIGTERM issue (#5)**
   - Now sends SIGTERM first for graceful shutdown
   - Waits 5 seconds before escalating to SIGKILL
   - Allows previous process to clean up resources
   - Location: curateipsum/backup.py:146-156

4. **Wrong stat object for permissions (#7)**
   - Fixed bug where dst_stat was used instead of src_stat
   - Permissions are now correctly updated during rsync
   - Location: curateipsum/fs.py:371

5. **os.chown() fails for non-root users (#10)**
   - Wrapped all os.chown() calls in try/except blocks
   - Logs debug message instead of crashing
   - Allows backups to succeed for non-root users
   - Locations: curateipsum/fs.py:217-221, 228-231, 383-387, 469-472

## Comprehensive Test Coverage

6. **Lock file tests (#19)**
   - Added TestBackupLock class with 7 test cases
   - Tests: creation, concurrent prevention, stale locks, corruption
   - Location: tests/test_backups.py:228-330

7. **Filesystem operation tests (#20)**
   - Added tests/test_fs_extended.py with 6 test classes
   - Tests: copy_file, copy_direntry, rsync, hardlink_dir, scantree, rm_direntry
   - 20+ test cases covering normal and edge cases
   - Location: tests/test_fs_extended.py

8. **Integration tests (#21)**
   - Added tests/test_integration.py with 2 test classes
   - Tests full backup workflow end-to-end
   - Tests: incremental backups, hardlinks, delta dirs, cleanup, recovery
   - 14 test cases covering complete backup lifecycle
   - Location: tests/test_integration.py

## Test Results
All 68 tests pass successfully:
- 11 original backup cleanup tests
- 7 new lock file tests
- 16 original fs tests
- 20 new fs extended tests
- 14 new integration tests

## Impact
These fixes address critical bugs that could cause:
- Data corruption from concurrent backups
- Incomplete cleanup from forced process termination
- Permission sync failures
- Tool unusability for non-root users

The comprehensive test coverage ensures these bugs are caught early
and provides confidence for future refactoring.
2026-02-03 22:09:28 -08:00
32ce113608 Migrate to pyproject.toml with setuptools_scm
Replace custom version management with setuptools_scm to eliminate
source file modifications during installation. Version is now derived
from git tags at build time without writing to tracked files.

Changes:
- Add pyproject.toml with full project metadata
- Simplify setup.py to minimal backwards-compatible shim
- Remove curateipsum/_version.py from version control
- Add _version.py to .gitignore (auto-generated at build time)
- Use PEP 440 compliant version strings

Fixes #18
2026-02-03 21:27:49 -08:00
6fd6051642 Merge pull request #4 from snegov/claude/fix-github-actions-python-versions-011CUyaqGCtZoDZVxANHBu2n
Fix GitHub Actions Python version testing
2025-11-09 20:55:42 -08:00
Claude
22933d7520 Fix GitHub Actions workflow to support Python 3.6-3.14
Use Docker containers with official Python images to run tests across
all Python versions from 3.6 to 3.14. This approach:

- Eliminates "workers not found" errors from deprecated Ubuntu runners
- Provides reliable support for older Python versions (3.6, 3.7)
- Simplifies workflow configuration significantly
- Uses official python:X.Y Docker images maintained by Python team
- Sets fail-fast: false to test all versions independently
2025-11-10 04:50:39 +00:00
Claude
6839d21a77 Add comprehensive README documentation
- Project overview and features
- Installation and usage instructions
- Detailed explanation of how hardlink-based backups work
- Command-line options and examples
- Backup structure and retention policy details
- Development and testing information
2025-11-09 20:23:56 -08:00
6d6038b027 Remove backup markers from previous backups 0.0.3 2023-05-07 22:00:05 -07:00
5746a9bc82 Update github actions 2023-05-07 15:33:45 -07:00
45c2480778 Fix spent time calculation 2023-05-06 23:20:21 -07:00
62fcfe5881 Add running backup lock and marker of finished backup 2023-05-06 23:06:15 -07:00
775234a433 Fix incorrect logging 2022-08-28 19:42:00 +04:00
ae95856a58 Fix symlinks issue in nest_hardlink function 2021-11-16 00:00:19 +03:00
2631b78d4d Handle socket files 0.0.2 2021-11-15 23:12:51 +03:00
04692be42d Minor fix in printing version info 2021-11-15 10:28:48 +03:00
e7774a5e5a Create run_tests.yml 2021-11-15 10:28:10 +03:00
9cf99f78b4 Add version support 0.0.1 2021-11-15 01:09:11 +03:00
a927f3e2d3 Minor fixes 2021-11-13 07:57:11 +03:00
84546243cb Add setup.py 2021-11-13 07:39:23 +03:00
990faf9a43 Add license 2021-11-12 20:50:32 +03:00
0c30501b9c Update debug logging 2021-11-12 11:33:53 +03:00
1cc5271c29 Add lock for backups directory 2021-11-12 11:30:11 +03:00
c64955362a Add backups cleanup 2021-11-12 10:38:28 +03:00
d521ef3c89 Do not create backup if no changes were found 2021-11-09 22:51:49 +03:00
dae1398f49 Do not create _delta dir on first run 2021-11-09 22:50:38 +03:00
7395268e97 Add processing of changed files 2021-11-09 00:43:18 +03:00
1ed1032f42 Add nested dir hardlink test 2021-11-02 23:45:11 +03:00
2dec011ca9 Fix setting symlink attributes in linux 2021-11-02 22:35:23 +03:00
7daa8d74b3 Add --external-hardlink parameter 2021-10-24 21:39:36 +03:00
f01d24f1bd Fix copying symlinks in Linux 2021-10-23 21:07:14 +03:00
1b6badf375 Check for rsync before using --external-rsync option 2021-10-23 00:36:39 +03:00
da228dfb99 Code style 2021-10-23 00:22:04 +03:00
05ecd09f57 Rename copy_file function 2021-10-22 17:30:45 +03:00
14552db4c8 Add --external-rsync option 2021-08-13 17:06:56 +03:00
eaf2b3c0ea Fix setting directories' mtime in rsync 2021-06-22 07:36:50 +03:00
036d241585 Fix setting directory mtime in hardlink_dir 2021-06-22 06:56:26 +03:00
5e042a73c1 Refactoring 2021-06-21 10:25:13 +03:00
874f2de9ff Enable rsync in initiate_backup 2021-06-21 10:24:53 +03:00
3620c5c137 Add spent time info 2021-06-21 10:22:37 +03:00
bddf311d99 Remove created backup if fail 2021-06-21 10:21:14 +03:00