Skip to content

Conversation

@pimpin
Copy link
Member

@pimpin pimpin commented Oct 31, 2025

Context

This PR addresses the tombstone purge issue discussed in Couchbase support ticket #70596.

Final Test Results ✅

After extensive testing, we have successfully validated the tombstone purge behavior with the following confirmed findings:

✅ Tombstone Purge Works Correctly

Test configuration:

  • Metadata purge interval: 0.04 days (1 hour)
  • Configured at bucket creation via REST API
  • Wait time: 65 minutes + compaction

Result: Tombstone completely purged from CBS (xattr _sync absent)

  • Document can be re-created with same ID
  • Re-created document has flags=0 (treated as new)
  • Test report: test_results/test_run_2025-11-01_06-54-46_a427ac3/

⚠️ Critical Finding: Configuration Timing Matters

When Configured Tombstone Purge Result
At bucket creation ✅ Purged after 1h + compaction
After tombstone exists ❌ Persists despite 1h + compaction

Conclusion: The metadata purge interval must be configured before tombstones are created. Retroactive configuration does not purge existing tombstones.

❌ Reset Checkpoint Limitation Discovered

Testing revealed that reset checkpoint alone does NOT re-push unmodified documents:

  • Reset checkpoint clears sync history
  • But CBLite only pushes documents that changed since last successful sync
  • Unmodified documents are not re-pushed even with reset

SGW logs evidence: Type:proposeChanges #Changes: 0 after reset

Implication for BC-994: Documents must be modified locally before reset checkpoint to trigger re-push.

What's in this PR

1. Automated Test Infrastructure

Complete test automation infrastructure with:

  • Git validation: Ensures clean state before running
  • Docker management: Automatic rebuild for reproducible environment
  • Timezone sync: Validates container/host timezone alignment
  • Structured reporting: Generates comprehensive reports in test_results/

Each test run produces:

  • Executive summary (README.md)
  • Full _sync xattr states at each checkpoint
  • Complete console output
  • CBS and SGW container logs
  • GitHub commit links

2. CBS/SGW Helper Functions

CBS operations (utils/cbs_admin.rs):

  • get_metadata_purge_interval(): Query current purge interval configuration
  • set_metadata_purge_interval(): Configure via REST API with validation
  • get_sync_xattr(): Extract _sync xattr for tombstone detection
  • check_doc_in_cbs(): Verify document state (live/tombstone/purged)
  • compact_cbs_bucket(): Trigger manual compaction

SGW operations (utils/sgw_admin.rs):

  • add_or_update_user(), get_session(): User management
  • get_doc_rev(): Get document revision (including deleted)
  • delete_doc_from_central(): Delete document from central only
  • check_doc_exists_in_central(): Verify document existence in SGW
  • purge_doc_from_sgw(): Purge tombstone from SGW
  • compact_sgw_database(): Trigger SGW compaction

Infrastructure (utils/):

  • git_checker.rs: Git status validation and commit info extraction
  • docker_manager.rs: Docker lifecycle management
  • test_reporter.rs: Structured report generation

3. Test Examples

tombstone_purge_test.rs (~70 minutes)

Complete automated test validating tombstone purge after 1-hour interval.

Features:

  • Automatic Docker environment rebuild
  • Git validation
  • Structured reporting with full state capture
  • Validates Thomas's recommendations

Run: cargo run --features=enterprise --example tombstone_purge_test

tombstone_quick_check.rs (~30 seconds)

Rapid validation of tombstone detection via _sync xattr queries.

Run: cargo run --features=enterprise --example tombstone_quick_check

check_cbs_config.rs (instant)

Utility to verify CBS bucket metadata purge interval configuration.

Run: cargo run --features=enterprise --example check_cbs_config

ticket_70596.rs

Antoine's original test for auto-purge when documents move to inaccessible channels.

Run: cargo run --features=enterprise --example ticket_70596

4. Docker Configuration Improvements

Metadata purge interval (configure-server.sh):

  • Uses REST API instead of CLI for per-bucket configuration
  • Configured to 0.04 days (1 hour) at bucket creation
  • Required parameters: autoCompactionDefined=true, purgeInterval, parallelDBAndViewCompaction

Sync function (sync-function.js):

  • Includes BC-994 soft_delete logic for testing
  • Detects resurrection: !oldDoc && updatedAt > 1 hour
  • Routes to soft_deleted channel + sets TTL

Timezone sync (docker-compose.yml):

  • Passes TZ environment variable to containers
  • Ensures time-based logic consistency

Critical Discoveries

Discovery #1: _sync xattr Structure (flags field)

Tombstone detection requires checking _sync.flags:

Live document:

{
  "cas": "...",
  "channels": { "channel1": null },
  "sequence": 7,
  "value_crc32c": "0x548d82c8"
}

Tombstone:

{
  "flags": 1,                    // PRIMARY INDICATOR
  "tombstoned_at": 1761980103,   
  "channels": { "channel1": { "del": true } },
  "value_crc32c": "0x00000000"
}

Purged:

  • _sync xattr completely absent
  • Only document ID in query results

NB : to get sync meta data, you must query them explicitly (otherwise they are filtered out from meta() :

SELECT META().id, META().xattrs._sync as sync_metadata 
FROM `billeo-cb-bucket`
USE KEYS ["b596f899-f2d0-49e7-a8a8-a67955329802","880e8265-9504-4c16-b57f-e821b3f4f1e7"
]

Discovery #2: Metadata Purge Interval Configuration

CLI method (cluster-wide, insufficient):

couchbase-cli setting-compaction --bucket my-bucket --metadata-purge-interval 0.04

Result: autoCompactionSettings: false at bucket level

REST API method (per-bucket, correct):

curl -X POST http://localhost:8091/pools/default/buckets/my-bucket \
  -d "autoCompactionDefined=true" \
  -d "purgeInterval=0.04" \
  -d "parallelDBAndViewCompaction=false"

Result: purgeInterval: 0.04 at bucket root level

Discovery #3: CBS API Validation Bug

The REST API accepts purge interval values below 0.04 days with 200 OK instead of rejecting them:

  • Documentation minimum: 0.04 days (1 hour)
  • API accepts: 0.0007 days (1 minute) without error
  • Configuration is silently ignored

Recommendation: API should validate like Web UI does.

Discovery #4: Tombstone Purge Timing

Purge interval must be configured before tombstones are created:

  • Purge eligibility based on tombstoned_at + purge_interval
  • Retroactive configuration does not apply to existing tombstones
  • Re-created documents always get flags=0 regardless

Discovery #5: Reset Checkpoint Does Not Re-Push Unmodified Documents

Testing BC-994 scenario revealed:

  • Reset checkpoint clears replication history
  • But CBLite only pushes modified documents
  • Unmodified documents are not re-evaluated/re-pushed

SGW logs evidence:

Type:proposeChanges #Changes: 0

Implication: For BC-994, documents must be modified locally before reset to trigger push.

Testing

Prerequisites

Set timezone for time-based logic:

export TZ="Europe/Paris"  # Or your local timezone

Quick Validation

Verify tombstone detection (~30 seconds):

cargo run --features=enterprise --example tombstone_quick_check

Verify CBS configuration:

cargo run --features=enterprise --example check_cbs_config

Full Test

Complete tombstone purge test with automation (~70 minutes):

cargo run --features=enterprise --example tombstone_purge_test

What it does automatically:

  • ✅ Validates git status
  • ✅ Rebuilds Docker environment (down -v && up)
  • ✅ Verifies timezone synchronization
  • ✅ Verifies CBS purge interval configuration
  • ✅ Runs test with state capture at each checkpoint
  • ✅ Generates structured report in test_results/
  • ✅ Captures CBS and SGW logs

Test Report

Report location: test_results/test_run_<timestamp>_<commit_sha>/

Contents:

  • README.md: Executive summary
  • metadata.json: Test metadata and GitHub link
  • tombstone_states.json: _sync xattr at each checkpoint
  • test_output.log: Complete console output
  • cbs_logs.log, sgw_logs.log: Container logs

Related

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

pimpin and others added 26 commits October 31, 2025 10:28
Add set_metadata_purge_interval() function to configure Couchbase Server
metadata purge interval via the REST API.

Features:
- Validates that the interval respects CBS minimum of 0.04 days (1 hour)
- Displays warning if below minimum but proceeds for testing purposes
- Shows configured interval in days and minutes for clarity

This helper is needed to test tombstone purge behavior following
Couchbase support recommendations (ticket 70596).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add two test examples to validate CBS tombstone purge behavior
following Couchbase support recommendations (ticket 70596).

Tests:
- tombstone_purge_test_short.rs: Quick validation (~10 min) with 5-min interval
- tombstone_purge_test.rs: Full test (~65 min) with 1-hour CBS minimum interval

Test scenario:
1. Create document in accessible channel and replicate
2. Delete document (creating tombstone)
3. Purge tombstone from Sync Gateway
4. Configure CBS metadata purge interval
5. Wait for purge interval + margin
6. Compact CBS and SGW
7. Verify tombstone no longer exists in CBS
8. Re-create document with same ID
9. Verify it's treated as new (flags=0) not deleted (flags=1)

The tests validate whether tombstones can be completely purged from
CBS and SGW such that re-creating a document with the same ID is
treated as a brand new document.

Documentation updated to describe the new examples and test scenarios.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The previous implementation returned 404 when trying to get the revision
of a deleted document (tombstone) because deleted documents are not
returned by default via the SGW admin API.

Changes:
- Add ?deleted=true parameter to the API call to include tombstones
- Display whether the retrieved document is deleted
- Improve error logging with HTTP status codes

This fix allows the tombstone purge tests to properly retrieve the
tombstone revision for purging from Sync Gateway.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The previous implementation had a malformed URL that concatenated
port numbers incorrectly (http://localhost:8091:8093), causing a
"builder error" when trying to query CBS.

Changes:
- Fix URL to use port 8093 directly for Query service
- Parse JSON response to clearly show if document exists or was purged
- Display tombstone state with formatted output
- Better error handling and status reporting

This fix enables the tombstone purge tests to verify whether documents
have been successfully purged from Couchbase Server after compaction.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Clarify that STEP 3 (purging tombstone from SGW) may fail with 404
when get_doc_rev cannot retrieve the tombstone. This is expected if:
- The tombstone only exists in CBS, not in SGW's cache
- SGW auto-purged it very quickly

This failure is not blocking for the test objective, which is to
verify that re-creating a document with the same ID after purge
is treated as new (flags=0) rather than as deleted (flags=1).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The previous implementation used META().deleted which does not exist
in Couchbase N1QL. Tombstones cannot be queried directly via standard
N1QL queries.

With enable_shared_bucket_access: true, Sync Gateway stores metadata
in extended attributes (XATTRs). The _sync xattr contains the deleted
status and other sync metadata.

Changes:
- Query META().xattrs._sync.deleted instead of non-existent META().deleted
- Use USE KEYS syntax for direct document lookup
- Parse and display tombstone status clearly (TOMBSTONE vs LIVE document)
- Improve output messages to distinguish between purged vs existing docs

This fix enables the tests to properly detect tombstones in CBS and
verify whether they persist or get purged after compaction.

References:
- Sync Gateway docs on shared bucket access and tombstones
- Couchbase N1QL docs on XATTRs querying

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The previous Docker configuration did not explicitly set the metadata
purge interval, relying on CBS default (3 days). This made tombstone
purge testing impractical.

Changes:
- Add configureBucketCompaction() function to set metadata purge interval
- Set to 0.04 days (1 hour) - the CBS minimum per documentation
- Execute during initial cluster setup after bucket creation
- Add explicit logging for this configuration step

This configuration is critical for testing tombstone behavior with
Sync Gateway, as it controls when tombstones are permanently removed
from CBS after deletion.

With the default 3-day interval, testing would require waiting days
to observe purge behavior. The 1-hour minimum allows practical testing
while respecting CBS constraints.

References:
- Couchbase docs: metadata purge interval minimum is 0.04 days (1 hour)
- Thomas's recommendation in ticket 70596

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The Sync Gateway _sync xattr uses `_deleted` (with underscore) not
`deleted` as the field name to indicate tombstone status.

Changes:
- Query `_sync._deleted` instead of `_sync.deleted`
- Add WARNING comment that querying _sync directly is unsupported in production
- Reference Sync Gateway documentation on shared bucket access

This fix enables proper detection of tombstones vs live documents
in CBS when using shared bucket access mode.

According to Sync Gateway docs, the _sync structure is internal and
can change between versions. Direct N1QL queries on _sync should only
be used for testing/debugging, not in production applications.

References:
- https://docs.couchbase.com/sync-gateway/current/shared-bucket-access.html
- Sync Gateway GitHub issues discussing _sync structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add a fast-running test (~30 seconds) to validate tombstone detection
in CBS without waiting for purge intervals.

Test scenario:
1. Create document → verify LIVE in CBS
2. Delete document → verify TOMBSTONE in CBS
3. Re-create document → verify LIVE in CBS
4. Check replication flags throughout

This example is useful for:
- Quickly validating _sync xattr query corrections
- Debugging tombstone visibility issues
- Understanding tombstone lifecycle without long waits
- Verifying that re-created documents are treated as new (flags=0)

Runtime: ~30 seconds vs 6+ minutes for other tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The _sync xattr does not have a _deleted field at the root level.
Based on actual _sync structure analysis, tombstone status is
indicated by:

Primary indicator:
- flags == 1: Document is a tombstone

Secondary indicators:
- tombstoned_at: Timestamp when document became tombstone (only present for tombstones)
- channels.*.del == true: Per-channel deletion marker
- history.deleted: Array of deleted revision indices

Changes:
- Check _sync.flags == 1 to detect tombstones
- Also check for tombstoned_at field as confirmation
- Display flags value and tombstoned_at in output
- Add #[allow(deprecated)] to test examples to suppress warnings for deprecated Database methods

This fix enables proper tombstone detection in CBS when using
shared bucket access mode.

Real _sync structure discovered via N1QL query:
- Live document: flags absent or 0, no tombstoned_at
- Tombstone: flags == 1, tombstoned_at present, channels.*.del == true

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add #[allow(dead_code)] and #[allow(deprecated)] attributes to
suppress compiler warnings for utility functions and deprecated
Database methods used in test examples.

Changes:
- Add #[allow(dead_code)] to utils modules (cbs_admin, constants, sgw_admin)
- Add #[allow(deprecated)] to create_doc helper function
- Utility functions are used across different test examples, so dead_code
  warnings in one example are expected

This keeps test output clean and focused on actual test results.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add #[allow(deprecated)] to create_doc() and get_doc() helper
functions in tombstone purge tests to suppress warnings about
deprecated Database methods.

These are test utilities that will be updated to use the new
collection-based API in a future refactoring, but for now we
suppress warnings to keep test output clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The previous implementation used couchbase-cli setting-compaction which
only sets cluster-wide defaults, not per-bucket settings. This resulted
in autoCompactionSettings: false at bucket level.

Changes:
- Use REST API POST to /pools/default/buckets/{bucket} instead of CLI
- Add required parameters:
  - autoCompactionDefined=true (enables per-bucket override)
  - purgeInterval=0.04 (1 hour minimum)
  - parallelDBAndViewCompaction=false (required parameter)
- Add get_metadata_purge_interval() to verify configuration
- Add check_cbs_config example to inspect current settings
- Improve get function to search purgeInterval in multiple locations

Per-bucket configuration overrides cluster-wide defaults and allows
independent purge interval settings for testing.

Verified: purgeInterval now appears at bucket root level and is set
to 0.04 days (1 hour).

References:
- https://docs.couchbase.com/server/current/rest-api/rest-autocompact-per-bucket.html
- Couchbase docs on cluster-wide vs per-bucket auto-compaction

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
The previous implementation used metadataPurgeInterval parameter which
does not work for per-bucket configuration. The REST API requires
specific parameters to enable and configure per-bucket auto-compaction.

Changes:
- Use autoCompactionDefined=true to enable per-bucket override
- Use purgeInterval instead of metadataPurgeInterval
- Add parallelDBAndViewCompaction=false (required by API)
- Add verification call to confirm configuration was applied

This aligns the Rust function with the corrected bash script in
configure-server.sh to ensure consistent bucket configuration.

Without these parameters, the bucket retains cluster-wide defaults
and per-bucket purge interval is not applied.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add comprehensive test infrastructure to automate environment setup,
test execution, and result reporting for Couchbase support ticket #70596.

New modules:
- git_checker.rs: Validates git status and extracts commit info
- docker_manager.rs: Manages Docker lifecycle (down/rebuild/up/health check)
- test_reporter.rs: Generates structured test reports with checkpoints

Features:
- Automatic Docker environment rebuild before each test
- Git validation (fails if uncommitted changes)
- Structured report generation in test_results/ directory
- Captures tombstone state at each checkpoint via _sync xattr
- Extracts CBS and SGW logs for analysis
- Generates README with executive summary and GitHub links

Report structure:
- README.md: Test summary with checkpoints and findings
- metadata.json: Commit SHA, timestamp, environment info
- tombstone_states.json: Full _sync xattr at each step
- test_output.log: Complete console output
- cbs_logs.log / sgw_logs.log: Container logs

Helper improvements:
- get_sync_xattr(): Extract _sync xattr without printing
- get_metadata_purge_interval(): Enhanced to search multiple locations

Dependencies added:
- chrono: Timestamp formatting for reports
- serde: Serialization for report generation

This infrastructure enables reproducible testing with complete
documentation for Couchbase support analysis.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Update tombstone_purge_test.rs to use the new automated test
infrastructure with Docker management and structured reporting.

Changes to tombstone_purge_test.rs:
- Add git status validation before test
- Automatically rebuild Docker environment with correct config
- Integrate TestReporter for structured output
- Add checkpoints at each major step with _sync xattr capture
- Generate comprehensive report in test_results/ directory
- Note: Purge interval no longer set during test (STEP 4)
  It's now configured at bucket creation via Docker setup

New example:
- test_with_reporting.rs: Minimal example demonstrating the
  reporting infrastructure without long waits

README updates:
- Document automated test infrastructure features
- Add check_cbs_config and tombstone_quick_check examples
- Explain test report structure and contents
- Update tombstone_purge_test description with automation details

The test now ensures clean, reproducible runs with complete
documentation for Couchbase support analysis.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Rename Database variable from 'db' to 'db_cblite' throughout all
test examples to clearly distinguish the local Couchbase Lite
database from central (Couchbase Server/Sync Gateway).

This improves code readability and prepares for tests that will
interact with both local database and central server explicitly.

Files updated:
- tombstone_purge_test.rs
- tombstone_purge_test_short.rs
- tombstone_quick_check.rs
- test_with_reporting.rs
- ticket_70596.rs

No functional changes, purely a variable rename for clarity.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Implement sync function logic to detect and handle documents that
resurrect after their tombstones have expired (BC-994 scenario).

Logic:
- If document arrives without oldDoc (!oldDoc) AND has updatedAt field
- Check if updatedAt is older than 1 hour (test value, production uses 60 days)
- If YES: Route to "soft_deleted" channel + set TTL to 5 minutes
- This triggers auto-purge in cblite (document removed from accessible channels)
- TTL ensures cleanup from central after 5 minutes

Test parameters (adapted for rapid testing):
- Cutoff: 1 hour (vs 60 days in production)
- TTL: 5 minutes (vs 6 months in production)

This tests the complete flow:
1. Document older than cutoff resurre cts from cblite
2. Sync function routes to soft_deleted
3. Auto-purge removes from cblite (not in user channels)
4. TTL purges from central after expiry

Reference: billeo-engine PR #7672

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add two new helper functions to interact with documents in central
(Sync Gateway / Couchbase Server):

1. delete_doc_from_central(doc_id):
   - Deletes document from central via SGW admin API
   - Gets current revision, then sends DELETE request
   - Returns bool indicating success/failure
   - Used to simulate central-only deletion (doc remains in cblite)

2. check_doc_exists_in_central(doc_id):
   - Checks if document exists in central via SGW admin API
   - Returns true if document exists and is LIVE
   - Returns false if document is deleted, 404, or error
   - Useful for verifying document state after TTL expiry

These functions enable testing the scenario where:
- Document is deleted in central only (not in cblite)
- Tombstone expires in central
- Cblite re-pushes the document (resurrection)
- Sync function handles resurrection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Create comprehensive test to validate the complete soft_delete flow
when documents resurrect after central tombstone expiry.

Test scenario (~75 minutes):
1. Create doc with updatedAt=NOW, replicate to central, STOP replication
2. Delete doc from CENTRAL only (doc remains in cblite)
3. Wait 65 minutes (doc's updatedAt becomes > 1 hour old)
4. Compact CBS + SGW to purge central tombstone
5. Restart replication with RESET CHECKPOINT
   - Cblite pushes doc1 back to central (resurrection)
   - Sync function detects updatedAt > 1h cutoff
   - Routes to "soft_deleted" channel + sets 5-min TTL
6. Verify auto-purge in cblite (doc removed, user has no access to soft_deleted)
7. Wait 6 minutes for TTL expiry
8. Compact CBS + SGW
9. Verify doc purged from central (TTL expired)

Features:
- Uses automated test infrastructure (Docker management, reporting)
- Creates doc with updatedAt field for sync function logic
- Tests complete BC-994 flow from resurrection to final purge
- Non-blocking checks (logs warnings instead of panics)
- Captures full state at each checkpoint

This validates the billeo-engine PR #7672 soft_delete logic adapted
for testing with 1-hour cutoff and 5-minute TTL.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add comprehensive documentation for the new tombstone_resurrection_test
example that validates the BC-994 soft_delete scenario.

Documentation includes:
- Runtime and features
- What it tests (6 key validations)
- Complete test scenario (9 steps)
- Sync function logic being tested
- Report location

This test validates the complete flow from document resurrection
after tombstone expiry to final purge via TTL, testing the logic
from billeo-engine PR #7672 adapted for rapid testing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Ensure tombstone_resurrection_test starts with a clean local database
by deleting any existing database from previous runs.

This prevents interference from previous test data and ensures
reproducible results.

Changes:
- Check if database exists before opening
- Delete existing database if found
- Log cleanup action for transparency

This is critical for the resurrection test scenario where we need
to control exactly when the document is created with its updatedAt
timestamp.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Ensure Docker containers (CBS and SGW) use the same timezone as the
local environment to prevent time-based logic issues in tests.

Changes:
- Pass TZ environment variable to both CBS and SGW containers
- Add verify_timezone_sync() to check and log timezone configuration
- Display local and container timezones during setup
- Non-blocking check (warns if mismatch, doesn't fail)

This is critical for tests using time-based logic like:
- Sync function Date.now() comparisons
- updatedAt field age calculations
- TTL expiry timing

Usage:
  export TZ="Europe/Paris"  # or your local timezone
  cargo run --features=enterprise --example tombstone_resurrection_test

If TZ is not set, defaults to UTC.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Multiple fixes to improve test clarity and fix document resurrection:

1. Fix STEP numbering consistency:
   - STEP 1-6: Setup and tombstone purge (unchanged)
   - STEP 7: NEW - Touch document to force push
   - STEP 8-14: Renumbered for consistency (was 7-13)
   - Comments now match log output

2. Add document modification before reset checkpoint:
   - Touch doc1 by adding _resurrection_test field
   - Forces CBL to detect change and push during reset
   - Fixes issue where doc wasn't pushed after reset

3. Improve logging and output capture:
   - Use reporter.log() for all test output
   - Remove println!() from create_doc helper
   - Add detailed logging for each verification
   - Log replication events explicitly after reset

4. Increase wait time after reset:
   - 10s → 30s to allow replication to complete
   - Log number of replication events captured
   - Warn if no events (indicates push didn't happen)

These fixes address:
- Logs were incomplete (println!() not captured)
- STEP numbers didn't match (comments vs logs)
- Document wasn't pushed after reset (no change detected)
- Hard to diagnose issues without replication event tracking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…ckpoint

Remove STEP 7 (document modification) from the resurrection test to
validate the BC-994 scenario as it should occur in production:
document resurrection WITHOUT any local modification.

Changes:
- Removed document touch/modification before reset checkpoint
- Renumbered STEP 8-14 to STEP 7-13 for consistency
- Updated README to clarify no modification occurs
- Document should resurrect naturally when reset checkpoint is used

Scenario:
- Document exists in cblite (unchanged since creation)
- Document was deleted from central, tombstone purged
- Reset checkpoint causes cblite to re-evaluate all docs
- Document is pushed to central WITHOUT oldDoc
- Sync function detects: !oldDoc && updatedAt > 1h → soft_delete

This validates whether reset checkpoint alone is sufficient to
trigger document resurrection, which is the actual BC-994 scenario.

If the document is not pushed without modification, this will reveal
a limitation of the reset checkpoint mechanism that needs to be
addressed differently.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Remove redundant and non-functional test examples:
- tombstone_purge_test_short.rs: Redundant with tombstone_quick_check
- tombstone_resurrection_test.rs: Non-functional - reset checkpoint does not re-push unmodified documents
- test_with_reporting.rs: Demo only, not a real test

Keep essential examples:
- ticket_70596.rs: Original auto-purge test
- check_cbs_config.rs: Configuration verification utility
- tombstone_quick_check.rs: Rapid validation (~30s)
- tombstone_purge_test.rs: Complete automated test with reporting

All utility infrastructure (utils/) remains unchanged.

README updates:
- Document key findings from extensive testing
- Tombstone purge timing requirements
- Reset checkpoint limitation for BC-994 scenario
- Simplified examples section

Key findings documented:
✅ Tombstone purge works when configured at bucket creation
❌ Retroactive configuration does not purge existing tombstones
❌ Reset checkpoint alone does not re-push unmodified documents

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@pimpin pimpin marked this pull request as ready for review November 5, 2025 11:18
@pimpin pimpin requested a review from a team as a code owner November 5, 2025 11:18
@pimpin pimpin requested a review from Nao-ris November 5, 2025 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants