fix: add RunDaemon test, remove dead daemonWatcherBatchDelay constant
All checks were successful
check / check (pull_request) Successful in 3m7s
All checks were successful
check / check (pull_request) Successful in 3m7s
- Add TestRunDaemon_CancelledContext: exercises RunDaemon with a daemon-friendly config, cancels via context, verifies clean return and startup output - Remove unused daemonWatcherBatchDelay constant (batch-settle logic was never implemented; the watcher loop records changes immediately) - Update TestDaemonConstants to remove reference to deleted constant
This commit is contained in:
@@ -19,11 +19,6 @@ import (
|
|||||||
// regardless of config, to prevent runaway backup loops.
|
// regardless of config, to prevent runaway backup loops.
|
||||||
const daemonMinBackupInterval = 1 * time.Minute
|
const daemonMinBackupInterval = 1 * time.Minute
|
||||||
|
|
||||||
// daemonWatcherBatchDelay is the time to wait after the last filesystem event
|
|
||||||
// before considering the batch of changes "settled." This prevents triggering
|
|
||||||
// a backup for every individual file write during a burst of activity.
|
|
||||||
const daemonWatcherBatchDelay = 5 * time.Second
|
|
||||||
|
|
||||||
// daemonShutdownTimeout is the maximum time to wait for an in-progress backup
|
// daemonShutdownTimeout is the maximum time to wait for an in-progress backup
|
||||||
// to complete during graceful shutdown before force-exiting.
|
// to complete during graceful shutdown before force-exiting.
|
||||||
const daemonShutdownTimeout = 5 * time.Minute
|
const daemonShutdownTimeout = 5 * time.Minute
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package vaultik
|
package vaultik
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.eeqj.de/sneak/vaultik/internal/config"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@@ -136,6 +141,56 @@ func TestSnapshotsAffectedByChanges(t *testing.T) {
|
|||||||
func TestDaemonConstants(t *testing.T) {
|
func TestDaemonConstants(t *testing.T) {
|
||||||
// Verify daemon constants are reasonable values.
|
// Verify daemon constants are reasonable values.
|
||||||
assert.GreaterOrEqual(t, daemonMinBackupInterval, 1*time.Minute)
|
assert.GreaterOrEqual(t, daemonMinBackupInterval, 1*time.Minute)
|
||||||
assert.GreaterOrEqual(t, daemonWatcherBatchDelay, 1*time.Second)
|
|
||||||
assert.GreaterOrEqual(t, daemonShutdownTimeout, 1*time.Minute)
|
assert.GreaterOrEqual(t, daemonShutdownTimeout, 1*time.Minute)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunDaemon_CancelledContext(t *testing.T) {
|
||||||
|
// Create a temporary directory to use as a snapshot path.
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
|
// Write a file so the watched path is non-empty.
|
||||||
|
err := os.WriteFile(filepath.Join(tmpDir, "testfile.txt"), []byte("hello"), 0o644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Build a minimal Vaultik with daemon-friendly config.
|
||||||
|
// RunDaemon will fail on the initial backup (no storage configured),
|
||||||
|
// but it should continue running. We cancel the context to verify
|
||||||
|
// graceful shutdown.
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
stdout := &bytes.Buffer{}
|
||||||
|
stderr := &bytes.Buffer{}
|
||||||
|
|
||||||
|
v := &Vaultik{
|
||||||
|
Config: &config.Config{
|
||||||
|
BackupInterval: 1 * time.Hour,
|
||||||
|
FullScanInterval: 24 * time.Hour,
|
||||||
|
MinTimeBetweenRun: 1 * time.Minute,
|
||||||
|
Snapshots: map[string]config.SnapshotConfig{
|
||||||
|
"test": {
|
||||||
|
Paths: []string{tmpDir},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ctx: ctx,
|
||||||
|
cancel: cancel,
|
||||||
|
Stdout: stdout,
|
||||||
|
Stderr: stderr,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel the context shortly after RunDaemon starts so the daemon
|
||||||
|
// loop exits via its ctx.Done() path.
|
||||||
|
go func() {
|
||||||
|
// Wait for the initial backup to fail (it will, since there's no
|
||||||
|
// storage backend), then cancel.
|
||||||
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
cancel()
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = v.RunDaemon(&SnapshotCreateOptions{})
|
||||||
|
// RunDaemon should return nil on context cancellation (graceful shutdown).
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify daemon printed startup messages.
|
||||||
|
output := stdout.String()
|
||||||
|
assert.Contains(t, output, "Daemon mode started")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user