appconfig: pin that SyncExec leaves a stamped route's old file alone
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 file changed,
+45
−0
internal/appconfig/syncexec_test.go+45 −0
diff --git a/internal/appconfig/syncexec_test.go b/internal/appconfig/syncexec_test.go| index 1fe50a6e9..8cb0860b5 100644 |
| --- a/internal/appconfig/syncexec_test.go |
| +++ b/internal/appconfig/syncexec_test.go |
| @@ -1942,3 +1942,48 @@ func TestSyncExecHoldsConfigWhenHostNamesADifferentAccount(t *testing.T) { |
| t.Fatalf("agreeing host's stale file survived, stat err = %v", err) |
| } |
| } |
| + |
| +func TestSyncExecLeavesAStampedRoutesOldFileAlone(t *testing.T) { |
| + ctx, s, reg, dataDir, priv, _ := execKit(t) |
| + privKey, err := ParsePrivateKey(priv, "test") |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + if err := SetEnv(ctx, s, "bab", "relay", map[string]string{"TOKEN": "old"}); err != nil { |
| + t.Fatal(err) |
| + } |
| + if err := SetExecDelivery(ctx, s, "bab", "relay", ExecDeliveryFile); err != nil { |
| + t.Fatal(err) |
| + } |
| + rt := registry.Route{Host: "relay.example.com", Kind: "instance", App: "relay", Account: "bab", |
| + Status: "ready", Addr: "127.0.0.1:8451"} |
| + if err := reg.Upsert(rt); err != nil { |
| + t.Fatal(err) |
| + } |
| + if err := SyncExec(ctx, reg, s, privKey, dataDir, nil, ""); err != nil { |
| + t.Fatal(err) |
| + } |
| + path := filepath.Join(dataDir, "relay.example.com.config.env") |
| + before, err := os.ReadFile(path) |
| + if err != nil { |
| + t.Fatalf("the opted-in addr route must have a file before the stamp: %v", err) |
| + } |
| + // Stamp it and change the bundle: the exec side must neither refresh |
| + // nor remove the file (spec §3.3, the ruling at syncexec.go:428). |
| + if err := reg.SetUnit("relay.example.com", "relay.service"); err != nil { |
| + t.Fatal(err) |
| + } |
| + if err := SetEnv(ctx, s, "bab", "relay", map[string]string{"TOKEN": "new"}); err != nil { |
| + t.Fatal(err) |
| + } |
| + if err := SyncExec(ctx, reg, s, privKey, dataDir, nil, ""); err != nil { |
| + t.Fatal(err) |
| + } |
| + after, err := os.ReadFile(path) |
| + if err != nil { |
| + t.Fatalf("file removed for a stamped route: %v", err) |
| + } |
| + if string(after) != string(before) { |
| + t.Fatalf("file refreshed for a stamped route: %q -> %q", before, after) |
| + } |
| +} |