| index ef8cbc533..e320147b8 100644 |
| --- a/internal/appconfig/syncexec_test.go |
| +++ b/internal/appconfig/syncexec_test.go |
| @@ -2735,3 +2735,86 @@ func TestSyncExecWithRouteFilter(t *testing.T) { |
| t.Fatalf("bounced %v, want only shop.example.com", bounced) |
| } |
| } |
| + |
| +// TestConfigEnvPathNestedWorker pins sidecar isolation D8's config rule: a |
| +// native worker row has no socket in either layout, so its rendered bundle |
| +// lands in its instance directory when its database path alone is the |
| +// nested default, flat when it is the flat default, and flat (never |
| +// nested) for a sidecar row carrying a socket, which is not a shape the |
| +// platform produced and which Classify calls foreign. |
| +func TestConfigEnvPathNestedWorker(t *testing.T) { |
| + dd := t.TempDir() |
| + host := "bot.shop.abc123" + provision.SidecarSuffix |
| + nested := filepath.Join(provision.InstanceDir(dd, host), host+".config.env") |
| + flat := filepath.Join(dd, host+".config.env") |
| + for _, c := range []struct { |
| + name string |
| + rt registry.Route |
| + want string |
| + }{ |
| + {"nested worker", registry.Route{Host: host, Kind: "sidecar", DBPath: provision.NestedDBPath(dd, host)}, nested}, |
| + {"flat worker", registry.Route{Host: host, Kind: "sidecar", DBPath: provision.DefaultDBPath(dd, host)}, flat}, |
| + {"worker with no database path", registry.Route{Host: host, Kind: "sidecar"}, flat}, |
| + {"sidecar row carrying a socket at the nested database", registry.Route{Host: host, Kind: "sidecar", DBPath: provision.NestedDBPath(dd, host), Socket: provision.NestedSocket(host)}, flat}, |
| + {"instance row at the nested database alone is not nested", registry.Route{Host: host, Kind: "instance", DBPath: provision.NestedDBPath(dd, host)}, flat}, |
| + } { |
| + if got := ConfigEnvPath(dd, c.rt); got != c.want { |
| + t.Errorf("%s: ConfigEnvPath = %q, want %q", c.name, got, c.want) |
| + } |
| + } |
| +} |
| + |
| +// TestSyncExecNestedWorkerBundleAndFencedSkip is D8's config rule through |
| +// SyncExec itself: a nested worker row's bundle is written inside its |
| +// instance directory and nowhere flat, and the fenced skip (the layout |
| +// pass's journal predicate) covers a worker host exactly as it covers an |
| +// instance host, writing nothing at either path for it. |
| +func TestSyncExecNestedWorkerBundleAndFencedSkip(t *testing.T) { |
| + ctx, s, reg, dd, priv, _ := execKit(t) |
| + pk, err := ParsePrivateKey(priv, "test") |
| + if err != nil { |
| + t.Fatalf("ParsePrivateKey: %v", err) |
| + } |
| + if err := SetEnv(ctx, s, "bab", "eleven", map[string]string{"LOG_LEVEL": "debug"}); err != nil { |
| + t.Fatalf("SetEnv: %v", err) |
| + } |
| + worker := "bot.eleven.abc123" + provision.SidecarSuffix |
| + fenced := "cron.eleven.abc123" + provision.SidecarSuffix |
| + for _, h := range []string{worker, fenced} { |
| + if err := os.MkdirAll(provision.InstanceDir(dd, h), 0o755); err != nil { |
| + t.Fatalf("mkdir instance dir: %v", err) |
| + } |
| + if err := reg.Upsert(registry.Route{Host: h, Kind: "sidecar", App: "eleven", Account: "bab", |
| + Status: "ready", Args: `["work"]`, DBPath: provision.NestedDBPath(dd, h)}); err != nil { |
| + t.Fatalf("Upsert: %v", err) |
| + } |
| + } |
| + var bounced []string |
| + bounce := func(h string) error { bounced = append(bounced, h); return nil } |
| + skip := func(h string) bool { return h == fenced } |
| + if err := SyncExec(ctx, reg, s, pk, dd, bounce, "", nil, SkipFenced(skip)); err != nil { |
| + t.Fatalf("SyncExec: %v", err) |
| + } |
| + nestedPath := filepath.Join(provision.InstanceDir(dd, worker), worker+".config.env") |
| + got, err := os.ReadFile(nestedPath) |
| + if err != nil || string(got) != "LOG_LEVEL=debug\n" { |
| + t.Fatalf("nested worker bundle = %q, %v", got, err) |
| + } |
| + if _, err := os.Stat(filepath.Join(dd, worker+".config.env")); !os.IsNotExist(err) { |
| + t.Fatalf("a nested worker's config also landed at the flat path, stat err = %v", err) |
| + } |
| + for _, path := range []string{ |
| + filepath.Join(provision.InstanceDir(dd, fenced), fenced+".config.env"), |
| + filepath.Join(dd, fenced+".config.env"), |
| + } { |
| + if _, err := os.Lstat(path); !os.IsNotExist(err) { |
| + t.Errorf("a fenced worker's bundle was written at %s (err %v)", path, err) |
| + } |
| + } |
| + // A sidecar is never bounced by this pass (inScope's doc: nothing dials |
| + // a worker back up; carlos restart pairs the stop with a wake), nested |
| + // or flat. |
| + if len(bounced) != 0 { |
| + t.Fatalf("bounced = %v, want nothing bounced for worker rows", bounced) |
| + } |
| +} |