@@ -58,7 +58,8 @@ func TestRuntime_CLIsInstalled(t *testing.T) {
5858 Image : testImage ,
5959 Env : map [string ]string {"CLAUDE_MODEL" : "test" },
6060 Labels : map [string ]string {"mecha.test" : "true" },
61- User : func () string { u , _ := worker .CurrentUser (); return u }(),
61+ // Don't set User — let the container use its Dockerfile USER (worker).
62+ // Host UID override is only needed for workspace bind mounts.
6263 }
6364
6465 id , err := cli .Create (ctx , cfg )
@@ -117,7 +118,8 @@ func TestRuntime_SettingsFile(t *testing.T) {
117118 Image : testImage ,
118119 Env : map [string ]string {"CLAUDE_MODEL" : "test" },
119120 Labels : map [string ]string {"mecha.test" : "true" },
120- User : func () string { u , _ := worker .CurrentUser (); return u }(),
121+ // Don't set User — let the container use its Dockerfile USER (worker).
122+ // Host UID override is only needed for workspace bind mounts.
121123 }
122124
123125 id , err := cli .Create (ctx , cfg )
@@ -167,7 +169,8 @@ func TestRuntime_CodexMCPNoAuth(t *testing.T) {
167169 "CODEX_MCP" : "true" ,
168170 },
169171 Labels : map [string ]string {"mecha.test" : "true" },
170- User : func () string { u , _ := worker .CurrentUser (); return u }(),
172+ // Don't set User — let the container use its Dockerfile USER (worker).
173+ // Host UID override is only needed for workspace bind mounts.
171174 }
172175
173176 id , err := cli .Create (ctx , cfg )
@@ -223,7 +226,8 @@ func TestRuntime_CodexMCPWithAPIKey(t *testing.T) {
223226 "CODEX_API_KEY" : "sk-test-fake-key" ,
224227 },
225228 Labels : map [string ]string {"mecha.test" : "true" },
226- User : func () string { u , _ := worker .CurrentUser (); return u }(),
229+ // Don't set User — let the container use its Dockerfile USER (worker).
230+ // Host UID override is only needed for workspace bind mounts.
227231 }
228232
229233 id , err := cli .Create (ctx , cfg )
@@ -264,7 +268,8 @@ func TestRuntime_NoCodexMCPByDefault(t *testing.T) {
264268 Image : testImage ,
265269 Env : map [string ]string {"CLAUDE_MODEL" : "test" },
266270 Labels : map [string ]string {"mecha.test" : "true" },
267- User : func () string { u , _ := worker .CurrentUser (); return u }(),
271+ // Don't set User — let the container use its Dockerfile USER (worker).
272+ // Host UID override is only needed for workspace bind mounts.
268273 }
269274
270275 id , err := cli .Create (ctx , cfg )
@@ -309,7 +314,8 @@ func TestRuntime_PluginEnvVars(t *testing.T) {
309314 "CLAUDE_PLUGINS" : "nonexistent-plugin" ,
310315 },
311316 Labels : map [string ]string {"mecha.test" : "true" },
312- User : func () string { u , _ := worker .CurrentUser (); return u }(),
317+ // Don't set User — let the container use its Dockerfile USER (worker).
318+ // Host UID override is only needed for workspace bind mounts.
313319 }
314320
315321 id , err := cli .Create (ctx , cfg )
@@ -322,11 +328,15 @@ func TestRuntime_PluginEnvVars(t *testing.T) {
322328 }
323329 defer cli .Stop (ctx , id , 10 * time .Second )
324330
325- // Wait a bit for entrypoint to try installing plugins
326- time .Sleep (30 * time .Second )
331+ endpoint , _ := cli .Endpoint (ctx , id )
332+ // Wait for container to become healthy (CLIs installed) or exit
333+ // Plugin install happens after CLI install, so we need the full boot
334+ waitForHealth (endpoint , 90 * time .Second )
335+ // Give plugin install step a few extra seconds
336+ time .Sleep (10 * time .Second )
327337
328338 logs := containerLogs (id )
329- if ! strings .Contains (logs , "installing: nonexistent-plugin" ) {
339+ if ! strings .Contains (logs , "installing: nonexistent-plugin" ) && ! strings . Contains ( logs , "installing plugins" ) {
330340 t .Errorf ("expected plugin install attempt in logs:\n %s" , logs )
331341 }
332342}
@@ -344,44 +354,57 @@ func TestRuntime_DualCredentialMount(t *testing.T) {
344354 }
345355 }
346356
347- reg := tempRegistry (t )
348- yml := `name: cred-mount-test
349- docker:
350- image: mecha-worker:latest
351- credentials: [claude, codex]
352- lifecycle: persistent
353- timeout: 5m
354- `
355- yamlPath := filepath .Join (t .TempDir (), "cred-mount-test.yml" )
356- writeFile (yamlPath , yml )
357+ // Use Docker SDK directly — the CLI's health timeout is too short for runtime install.
358+ dc := & worker.DockerConfig {
359+ Image : testImage ,
360+ Credentials : []string {"claude" , "codex" },
361+ }
362+ mounts , err := worker .BuildContainerMounts (dc )
363+ if err != nil {
364+ t .Fatal (err )
365+ }
366+
367+ cli , err := worker .NewDockerClient ("" )
368+ if err != nil {
369+ t .Fatal (err )
370+ }
371+ defer cli .Close ()
357372
358- out , _ , code := runMecha (t , reg , "worker" , "add" , yamlPath )
359- if code != 0 {
360- t .Fatalf ("add failed: %s" , out )
373+ ctx := context .Background ()
374+ cfg := worker.ContainerCfg {
375+ Name : "mecha-test-cred-mount" ,
376+ Image : testImage ,
377+ Env : map [string ]string {"CLAUDE_MODEL" : "test" },
378+ Labels : map [string ]string {"mecha.test" : "true" },
379+ Mounts : mounts ,
380+ // Don't set User — let the container use its Dockerfile USER (worker).
361381 }
362382
363- out , stderr , code := runMecha (t , reg , "worker" , "start" , "cred-mount-test" )
364- if code != 0 {
365- t .Fatalf ("start failed (code %d): stdout=%s stderr=%s" , code , out , stderr )
383+ id , err := cli .Create (ctx , cfg )
384+ if err != nil {
385+ t .Fatalf ("create: %v" , err )
386+ }
387+ defer cli .Remove (ctx , id )
388+ if err := cli .Start (ctx , id ); err != nil {
389+ t .Fatalf ("start: %v" , err )
366390 }
367- defer runMecha (t , reg , "worker" , "stop" , "cred-mount-test" )
368- defer runMecha (t , reg , "worker" , "remove" , "cred-mount-test" )
391+ defer cli .Stop (ctx , id , 10 * time .Second )
369392
370393 // Verify mounts by inspecting the container
371394 inspectOut , err := exec .Command ("docker" , "inspect" ,
372- "-f" , "{{range .Mounts}}{{.Destination}} {{.RW}}\n {{end}}" ,
373- "mecha-worker-cred-mount-test" ).CombinedOutput ()
395+ "-f" , "{{range .Mounts}}{{.Destination}} {{.RW}}\n {{end}}" , id ).CombinedOutput ()
374396 if err != nil {
375397 t .Fatalf ("inspect: %v\n %s" , err , inspectOut )
376398 }
377399
378- mounts := string (inspectOut )
379- if ! strings .Contains (mounts , "/home/worker/.claude false" ) {
380- t .Errorf (".claude mount missing or not read-only:\n %s" , mounts )
400+ mountStr := string (inspectOut )
401+ if ! strings .Contains (mountStr , "/home/worker/.claude false" ) {
402+ t .Errorf (".claude mount missing or not read-only:\n %s" , mountStr )
381403 }
382- if ! strings .Contains (mounts , "/home/worker/.codex false" ) {
383- t .Errorf (".codex mount missing or not read-only:\n %s" , mounts )
404+ if ! strings .Contains (mountStr , "/home/worker/.codex false" ) {
405+ t .Errorf (".codex mount missing or not read-only:\n %s" , mountStr )
384406 }
407+ t .Logf ("mounts verified:\n %s" , mountStr )
385408}
386409
387410// --- Test 6: Health During Install Phase ---
@@ -402,7 +425,8 @@ func TestRuntime_HealthDuringInstall(t *testing.T) {
402425 Image : testImage ,
403426 Env : map [string ]string {"CLAUDE_MODEL" : "test" },
404427 Labels : map [string ]string {"mecha.test" : "true" },
405- User : func () string { u , _ := worker .CurrentUser (); return u }(),
428+ // Don't set User — let the container use its Dockerfile USER (worker).
429+ // Host UID override is only needed for workspace bind mounts.
406430 }
407431
408432 id , err := cli .Create (ctx , cfg )
0 commit comments