diff --git a/commands_test.go b/commands_test.go index 841079a..acfdedd 100644 --- a/commands_test.go +++ b/commands_test.go @@ -9,6 +9,9 @@ import ( "context" "errors" "net" + "os" + "path/filepath" + "strconv" "testing" "time" @@ -237,6 +240,29 @@ func TestFormatChainSyncDaemonStopping_Good(t *testing.T) { assert.Equal(t, "Stopping background chain sync (PID 42).", formatChainSyncDaemonStopping(42)) } +func TestFormatChainSyncDaemonAlreadyRunning_Good(t *testing.T) { + assert.Equal(t, `background chain sync is already running for data dir "/tmp/chain" (PID 42). Stop it with core-chain chain sync --stop --data-dir "/tmp/chain".`, formatChainSyncDaemonAlreadyRunning("/tmp/chain", 42)) +} + +func TestFormatChainSyncDaemonNotRunning_Good(t *testing.T) { + assert.Equal(t, `No background chain sync is running for data dir "/tmp/chain".`, formatChainSyncDaemonNotRunning("/tmp/chain")) +} + +func TestRunChainSyncDaemon_Bad_RejectsExistingDaemonForDataDir(t *testing.T) { + dataDir := t.TempDir() + pidFile := filepath.Join(dataDir, "sync.pid") + pid := os.Getpid() + require.NoError(t, os.WriteFile(pidFile, []byte(strconv.Itoa(pid)), 0o644)) + + err := runChainSyncDaemon(dataDir, "127.0.0.1:36942", false) + require.EqualError(t, err, `blockchain: background chain sync is already running for data dir "`+dataDir+`" (PID `+strconv.Itoa(pid)+`). Stop it with core-chain chain sync --stop --data-dir "`+dataDir+`".`) +} + +func TestStopChainSyncDaemon_Good_NoRunningDaemonForDataDir(t *testing.T) { + err := stopChainSyncDaemon(t.TempDir()) + require.NoError(t, err) +} + func TestRunChainSyncOnce_Bad_RespectsCancelledContext(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() diff --git a/sync_command.go b/sync_command.go index be23f71..eb13bef 100644 --- a/sync_command.go +++ b/sync_command.go @@ -102,6 +102,9 @@ func runChainSyncDaemon(dataDir, seed string, testnet bool) error { } pidFile := filepath.Join(dataDir, "sync.pid") + if pid, running := process.ReadPID(pidFile); running { + return fmt.Errorf("blockchain: %s", formatChainSyncDaemonAlreadyRunning(dataDir, pid)) + } syncDaemon := process.NewDaemon(process.DaemonOptions{ PIDFile: pidFile, @@ -153,7 +156,8 @@ func stopChainSyncDaemon(dataDir string) error { pidFile := filepath.Join(dataDir, "sync.pid") pid, running := process.ReadPID(pidFile) if pid == 0 || !running { - return coreerr.E("stopChainSyncDaemon", "no running background sync process found", nil) + log.Print(formatChainSyncDaemonNotRunning(dataDir)) + return nil } processHandle, err := os.FindProcess(pid) @@ -188,3 +192,11 @@ func formatChainSyncStopCommand(dataDir string) string { func formatChainSyncDaemonStopping(pid int) string { return fmt.Sprintf("Stopping background chain sync (PID %d).", pid) } + +func formatChainSyncDaemonAlreadyRunning(dataDir string, pid int) string { + return fmt.Sprintf("background chain sync is already running for data dir %q (PID %d). Stop it with %s.", dataDir, pid, formatChainSyncStopCommand(dataDir)) +} + +func formatChainSyncDaemonNotRunning(dataDir string) string { + return fmt.Sprintf("No background chain sync is running for data dir %q.", dataDir) +}