Test Report — 18.0.1.0.0
What is tested in Automatic Database Backup, and how to run the suite.
Result: 57 automated tests, 0 failures, 0 errors. Exit code 0.
Every figure here comes from an actual run, and the backups in it are real: the suite dumps this database to disk, reads the archives back, and deletes them again. Nothing is mocked away.
Environment
| Odoo | 18.0 (community, source checkout) |
| Python | 3.12.3 |
| PostgreSQL | 16.15 |
| OS | Ubuntu 24.04.1 LTS |
| Database | created fresh for the run |
| Command | odoo-bin -d <db> -i technovision_database_backup --test-enable --test-tags /technovision_database_backup --stop-after-init |
Result
Tests started : 57
Failures : 0
Errors : 0
Odoo exit code: 0The run emits two ERROR lines from PostgreSQL — a rejected port and a rejected retention value — produced deliberately by test_bad_port_refused and test_negative_retention_refused, which assert that the database constraints hold when the ORM is bypassed.
Coverage by area
| Suite | Tests | Covers |
|---|---|---|
| TestDestination | 15 | Field validation, defaults, filename construction, SFTP requirements, the connection test, and archive verification against missing, empty and corrupt files |
| TestBackupRun | 13 | Real zip and dump backups, the cron, failure handling, partial-file cleanup, name collisions, history |
| TestRetention | 12 | What is swept, what is kept, boundary days, foreign files, SFTP, failed runs, history pruning |
| TestSecurity | 9 | Group gates on destinations, history and manual runs; the SFTP password field |
| TestAlerts | 8 | Who is emailed on failure, who is not emailed on success, and what the alert says |
| Total | 57 |
What the tests actually prove
The backups are real. test_zip_backup_is_written_and_readable takes an actual backup of the test database, opens the archive, and asserts it contains a database dump. test_dump_backup_is_written does the same for the plain SQL format. A test that asserts a function was called proves nothing about whether the file on disk could ever be restored.
A failed backup cannot destroy a good one. The name carries the time only to the second, so two runs in the same second used to land on the same file: the second truncated the first, and when the second then failed its own cleanup deleted what was left. test_two_runs_do_not_collide and test_no_partial_file_is_left_behind assert the fix — a clashing name gains a _2 suffix, and the write itself is exclusive, so the cleanup path can only ever remove a file this run created. Both tests were written before the fix and failed against the original code.
Retention is timid. test_other_peoples_files_are_never_touched puts five plausible-looking foreign files in the folder and asserts all five survive. test_the_boundary_day_is_kept asserts the file exactly on the retention boundary stays. test_a_failed_run_does_not_apply_retention asserts that a failed backup never triggers a sweep — deleting yesterday's good backup because today's failed is the worst possible moment to be tidy. test_retention_is_skipped_for_sftp asserts the module never deletes anything on a remote server.
A broken destination does not stop the rest. test_one_broken_destination_does_not_stop_the_others asserts the cron completes every other destination after one raises, and test_failure_is_recorded_not_raised asserts the failure is recorded rather than thrown at the scheduler. The manual button behaves the opposite way on purpose: test_manual_run_raises_so_the_user_sees_it.
A corrupt archive is caught at the time. Three tests drive _verify_archive against a missing file, an empty file and a file that is not an archive, and assert each is rejected. A backup nobody has ever opened is a hope, not a backup.
Nobody is emailed about a success. test_success_emails_nobody asserts a successful backup sends nothing at all, and test_the_alert_says_what_went_wrong asserts the failure email carries the server's own message rather than "the backup failed". test_the_backup_cron_ships_disabled asserts the module takes no backups until an administrator asks it to.
Known gaps in coverage
Stated rather than glossed over:
- SFTP is not exercised against a real server. Field validation, the requirement checks and the local half of the upload path are covered; the paramiko transfer itself is not, because a test suite cannot assume an SSH server. It was verified manually against a real host.
- Restores are not automated. The suite proves the archive is well-formed and contains a dump. It does not restore it into a running database — see RESTORING.md, which asks you to do exactly that once a quarter.
- Scale. The test database is small. Backup duration on a large database is dominated by pg_dump and the filesystem, not by this module.
- Odoo 19. Not tested; this release targets 18.0 only.
Reproducing
createdb -O odoo adb_test
odoo-bin -c odoo.conf -d adb_test \
-i technovision_database_backup --test-enable \
--test-tags /technovision_database_backup --stop-after-init
echo "exit code: $?"A clean run prints no FAIL: or ERROR: Test lines and exits 0.