master
go 55 lines 1.67 KB
Raw
1 package migrations
2
3 // NOTE: These concurrent migration tests require the local Kubo binary (built with 'make build') to be in PATH.
4 //
5 // To run these tests successfully:
6 // export PATH="$(pwd)/cmd/ipfs:$PATH"
7 // go test ./test/cli/migrations/
8
9 import (
10 "context"
11 "testing"
12 "time"
13
14 "github.com/stretchr/testify/require"
15 )
16
17 const daemonStartupWait = 2 * time.Second
18
19 // TestConcurrentMigrations tests concurrent daemon --migrate attempts
20 func TestConcurrentMigrations(t *testing.T) {
21 t.Parallel()
22
23 t.Run("concurrent daemon migrations prevented by lock", testConcurrentDaemonMigrations)
24 }
25
26 func testConcurrentDaemonMigrations(t *testing.T) {
27 node := setupStaticV16Repo(t)
28
29 // Start first daemon --migrate in background (holds repo.lock)
30 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
31 defer cancel()
32
33 firstDaemon := setupDaemonCmd(ctx, node, "daemon", "--migrate")
34 require.NoError(t, firstDaemon.Start())
35 defer func() {
36 // Shutdown first daemon
37 shutdownCmd := setupDaemonCmd(context.Background(), node, "shutdown")
38 _ = shutdownCmd.Run()
39 _ = firstDaemon.Wait()
40 }()
41
42 // Wait for first daemon to start and acquire lock
43 time.Sleep(daemonStartupWait)
44
45 // Attempt second daemon --migrate (should fail due to lock)
46 secondDaemon := setupDaemonCmd(context.Background(), node, "daemon", "--migrate")
47 output, err := secondDaemon.CombinedOutput()
48 t.Logf("Second daemon output: %s", output)
49
50 // Should fail with lock error
51 require.Error(t, err, "second daemon should fail when first daemon holds lock")
52 require.Contains(t, string(output), "lock", "error should mention lock")
53
54 assertNoTempFiles(t, node.Dir, "no temp files should be created when lock fails")
55 }