@@ -19,7 +19,6 @@ package container
1919import (
2020 "encoding/json"
2121 "errors"
22- "fmt"
2322 "strings"
2423 "testing"
2524 "time"
@@ -32,11 +31,16 @@ import (
3231 "github.com/containerd/nerdctl/mod/tigron/tig"
3332
3433 "github.com/containerd/nerdctl/v2/pkg/healthcheck"
34+ "github.com/containerd/nerdctl/v2/pkg/rootlessutil"
3535 "github.com/containerd/nerdctl/v2/pkg/testutil"
3636 "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest"
3737)
3838
3939func TestContainerHealthCheckBasic (t * testing.T ) {
40+ if rootlessutil .IsRootless () {
41+ t .Skip ("healthcheck tests are skipped in rootless environment" )
42+ }
43+
4044 testCase := nerdtest .Setup ()
4145
4246 // Docker CLI does not provide a standalone healthcheck command.
@@ -134,6 +138,10 @@ func TestContainerHealthCheckBasic(t *testing.T) {
134138}
135139
136140func TestContainerHealthCheckAdvance (t * testing.T ) {
141+ if rootlessutil .IsRootless () {
142+ t .Skip ("healthcheck tests are skipped in rootless environment" )
143+ }
144+
137145 testCase := nerdtest .Setup ()
138146
139147 // Docker CLI does not provide a standalone healthcheck command.
@@ -391,43 +399,6 @@ func TestContainerHealthCheckAdvance(t *testing.T) {
391399 }
392400 },
393401 },
394- {
395- Description : "Healthcheck emits large output repeatedly" ,
396- Setup : func (data test.Data , helpers test.Helpers ) {
397- helpers .Ensure ("run" , "-d" , "--name" , data .Identifier (),
398- "--health-cmd" , "yes X | head -c 60000" ,
399- "--health-interval" , "1s" , "--health-timeout" , "2s" ,
400- testutil .CommonImage , "sleep" , nerdtest .Infinity )
401- nerdtest .EnsureContainerStarted (helpers , data .Identifier ())
402- },
403- Cleanup : func (data test.Data , helpers test.Helpers ) {
404- helpers .Anyhow ("rm" , "-f" , data .Identifier ())
405- },
406- Command : func (data test.Data , helpers test.Helpers ) test.TestableCommand {
407- for i := 0 ; i < 3 ; i ++ {
408- helpers .Ensure ("container" , "healthcheck" , data .Identifier ())
409- time .Sleep (2 * time .Second )
410- }
411- return helpers .Command ("inspect" , data .Identifier ())
412- },
413- Expected : func (data test.Data , helpers test.Helpers ) * test.Expected {
414- return & test.Expected {
415- ExitCode : 0 ,
416- Output : expect .All (func (_ string , t tig.T ) {
417- inspect := nerdtest .InspectContainer (helpers , data .Identifier ())
418- h := inspect .State .Health
419- debug , _ := json .MarshalIndent (h , "" , " " )
420- t .Log (string (debug ))
421- assert .Assert (t , h != nil , "expected health state" )
422- assert .Equal (t , h .Status , healthcheck .Healthy )
423- assert .Assert (t , len (h .Log ) >= 3 , "expected at least 3 health log entries" )
424- for _ , log := range h .Log {
425- assert .Assert (t , len (log .Output ) >= 1024 , fmt .Sprintf ("each output should be >= 1024 bytes, was: %s" , log .Output ))
426- }
427- }),
428- }
429- },
430- },
431402 {
432403 Description : "Health log in inspect keeps only the latest 5 entries" ,
433404 Setup : func (data test.Data , helpers test.Helpers ) {
@@ -603,121 +574,121 @@ func TestContainerHealthCheckAdvance(t *testing.T) {
603574 testCase .Run (t )
604575}
605576
606- func TestHealthCheck_SystemdIntegration_Basic (t * testing.T ) {
607- testCase := nerdtest .Setup ()
608- testCase .Require = require .Not (nerdtest .Docker )
577+ // func TestHealthCheck_SystemdIntegration_Basic(t *testing.T) {
578+ // testCase := nerdtest.Setup()
579+ // testCase.Require = require.Not(nerdtest.Docker)
609580
610- testCase .SubTests = []* test.Case {
611- //{
612- // Description: "Basic healthy container with systemd-triggered healthcheck",
613- // Setup: func(data test.Data, helpers test.Helpers) {
614- // helpers.Ensure("run", "-d", "--name", data.Identifier(),
615- // "--health-cmd", "echo healthy",
616- // "--health-interval", "2s",
617- // testutil.CommonImage, "sleep", "30")
618- // // Wait for a couple of healthchecks to execute
619- // time.Sleep(5 * time.Second)
620- // },
621- // Cleanup: func(data test.Data, helpers test.Helpers) {
622- // helpers.Anyhow("rm", "-f", data.Identifier())
623- // },
624- // Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
625- // return &test.Expected{
626- // ExitCode: 0,
627- // Output: expect.All(func(stdout, _ string, t *testing.T) {
628- // inspect := nerdtest.InspectContainer(helpers, data.Identifier())
629- // h := inspect.State.Health
630- // assert.Assert(t, h != nil, "expected health state to be present")
631- // assert.Equal(t, h.Status, "healthy")
632- // assert.Assert(t, len(h.Log) > 0, "expected at least one health check log entry")
633- // }),
634- // }
635- // },
636- //},
637- //{
638- // Description: "Kill stops healthcheck execution",
639- // Setup: func(data test.Data, helpers test.Helpers) {
640- // helpers.Ensure("run", "-d", "--name", data.Identifier(),
641- // "--health-cmd", "echo healthy",
642- // "--health-interval", "1s",
643- // testutil.CommonImage, "sleep", "30")
644- // time.Sleep(5 * time.Second) // Wait for at least one health check to execute
645- // helpers.Ensure("kill", data.Identifier()) // Kill the container
646- // time.Sleep(3 * time.Second) // Wait to allow any potential extra healthchecks (shouldn't happen)
647- // },
648- // Cleanup: func(data test.Data, helpers test.Helpers) {
649- // helpers.Anyhow("rm", "-f", data.Identifier())
650- // },
651- // Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
652- // return &test.Expected{
653- // ExitCode: 0,
654- // Output: expect.All(func(stdout, _ string, t *testing.T) {
655- // inspect := nerdtest.InspectContainer(helpers, data.Identifier())
656- // h := inspect.State.Health
657- // assert.Assert(t, h != nil, "expected health state to be present")
658- // assert.Assert(t, len(h.Log) > 0, "expected at least one health check log entry")
659- //
660- // // Get container FinishedAt timestamp
661- // containerEnd, err := time.Parse(time.RFC3339Nano, inspect.State.FinishedAt)
662- // assert.NilError(t, err, "parsing container FinishedAt")
663- //
664- // // Assert all healthcheck log start times are before container finished
665- // for _, entry := range h.Log {
666- // assert.NilError(t, err, "parsing healthcheck Start time")
667- // assert.Assert(t, entry.Start.Before(containerEnd), "healthcheck ran after container was killed")
668- // }
669- // }),
670- // }
671- // },
672- //},
581+ // testCase.SubTests = []*test.Case{
582+ // //{
583+ // // Description: "Basic healthy container with systemd-triggered healthcheck",
584+ // // Setup: func(data test.Data, helpers test.Helpers) {
585+ // // helpers.Ensure("run", "-d", "--name", data.Identifier(),
586+ // // "--health-cmd", "echo healthy",
587+ // // "--health-interval", "2s",
588+ // // testutil.CommonImage, "sleep", "30")
589+ // // // Wait for a couple of healthchecks to execute
590+ // // time.Sleep(5 * time.Second)
591+ // // },
592+ // // Cleanup: func(data test.Data, helpers test.Helpers) {
593+ // // helpers.Anyhow("rm", "-f", data.Identifier())
594+ // // },
595+ // // Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
596+ // // return &test.Expected{
597+ // // ExitCode: 0,
598+ // // Output: expect.All(func(stdout, _ string, t *testing.T) {
599+ // // inspect := nerdtest.InspectContainer(helpers, data.Identifier())
600+ // // h := inspect.State.Health
601+ // // assert.Assert(t, h != nil, "expected health state to be present")
602+ // // assert.Equal(t, h.Status, "healthy")
603+ // // assert.Assert(t, len(h.Log) > 0, "expected at least one health check log entry")
604+ // // }),
605+ // // }
606+ // // },
607+ // //},
608+ // //{
609+ // // Description: "Kill stops healthcheck execution",
610+ // // Setup: func(data test.Data, helpers test.Helpers) {
611+ // // helpers.Ensure("run", "-d", "--name", data.Identifier(),
612+ // // "--health-cmd", "echo healthy",
613+ // // "--health-interval", "1s",
614+ // // testutil.CommonImage, "sleep", "30")
615+ // // time.Sleep(5 * time.Second) // Wait for at least one health check to execute
616+ // // helpers.Ensure("kill", data.Identifier()) // Kill the container
617+ // // time.Sleep(3 * time.Second) // Wait to allow any potential extra healthchecks (shouldn't happen)
618+ // // },
619+ // // Cleanup: func(data test.Data, helpers test.Helpers) {
620+ // // helpers.Anyhow("rm", "-f", data.Identifier())
621+ // // },
622+ // // Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
623+ // // return &test.Expected{
624+ // // ExitCode: 0,
625+ // // Output: expect.All(func(stdout, _ string, t *testing.T) {
626+ // // inspect := nerdtest.InspectContainer(helpers, data.Identifier())
627+ // // h := inspect.State.Health
628+ // // assert.Assert(t, h != nil, "expected health state to be present")
629+ // // assert.Assert(t, len(h.Log) > 0, "expected at least one health check log entry")
630+ // //
631+ // // // Get container FinishedAt timestamp
632+ // // containerEnd, err := time.Parse(time.RFC3339Nano, inspect.State.FinishedAt)
633+ // // assert.NilError(t, err, "parsing container FinishedAt")
634+ // //
635+ // // // Assert all healthcheck log start times are before container finished
636+ // // for _, entry := range h.Log {
637+ // // assert.NilError(t, err, "parsing healthcheck Start time")
638+ // // assert.Assert(t, entry.Start.Before(containerEnd), "healthcheck ran after container was killed")
639+ // // }
640+ // // }),
641+ // // }
642+ // // },
643+ // //},
673644
674- // {
675- // Description: "Pause/unpause halts and resumes healthcheck execution",
676- // Setup: func(data test.Data, helpers test.Helpers) {
677- // data.Labels().Set("cID", data.Identifier())
678- // helpers.Ensure("run", "-d", "--name", data.Identifier(),
679- // "--health-cmd", "echo healthy",
680- // "--health-interval", "1s",
681- // testutil.CommonImage, "sleep", "30")
682- // time.Sleep(4 * time.Second)
645+ // // {
646+ // // Description: "Pause/unpause halts and resumes healthcheck execution",
647+ // // Setup: func(data test.Data, helpers test.Helpers) {
648+ // // data.Labels().Set("cID", data.Identifier())
649+ // // helpers.Ensure("run", "-d", "--name", data.Identifier(),
650+ // // "--health-cmd", "echo healthy",
651+ // // "--health-interval", "1s",
652+ // // testutil.CommonImage, "sleep", "30")
653+ // // time.Sleep(4 * time.Second)
683654
684- // // Inspect using raw command
685- // helpers.Command("container", "inspect", data.Labels().Get("cID")).
686- // Run(&test.Expected{
687- // ExitCode: expect.ExitCodeNoCheck,
688- // Output: func(stdout string, _ string, t *testing.T) {
689- // var dc []dockercompat.Container
690- // err := json.Unmarshal([]byte(stdout), &dc)
691- // assert.NilError(t, err)
692- // assert.Equal(t, len(dc), 1)
693- // h := dc[0].State.Health
694- // assert.Assert(t, h != nil, "expected health state to be present")
695- // data.Labels().Set("healthStatus", h.Status)
696- // data.Labels().Set("logCount", strconv.Itoa(len(h.Log)))
697- // fmt.Printf("📋 Setup Inspect: Status=%s, LogCount=%s\n", h.Status, strconv.Itoa(len(h.Log)))
698- // },
699- // })
700- // },
701- // Cleanup: func(data test.Data, helpers test.Helpers) {
702- // helpers.Anyhow("rm", "-f", data.Identifier())
703- // },
704- // Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
705- // return &test.Expected{
706- // ExitCode: 0,
707- // Output: expect.All(func(stdout, _ string, t *testing.T) {
708- // before := data.Labels().Get("logCountBeforePause")
709- // after := data.Labels().Get("logCountAfterUnpause")
655+ // // // Inspect using raw command
656+ // // helpers.Command("container", "inspect", data.Labels().Get("cID")).
657+ // // Run(&test.Expected{
658+ // // ExitCode: expect.ExitCodeNoCheck,
659+ // // Output: func(stdout string, _ string, t *testing.T) {
660+ // // var dc []dockercompat.Container
661+ // // err := json.Unmarshal([]byte(stdout), &dc)
662+ // // assert.NilError(t, err)
663+ // // assert.Equal(t, len(dc), 1)
664+ // // h := dc[0].State.Health
665+ // // assert.Assert(t, h != nil, "expected health state to be present")
666+ // // data.Labels().Set("healthStatus", h.Status)
667+ // // data.Labels().Set("logCount", strconv.Itoa(len(h.Log)))
668+ // // fmt.Printf("📋 Setup Inspect: Status=%s, LogCount=%s\n", h.Status, strconv.Itoa(len(h.Log)))
669+ // // },
670+ // // })
671+ // // },
672+ // // Cleanup: func(data test.Data, helpers test.Helpers) {
673+ // // helpers.Anyhow("rm", "-f", data.Identifier())
674+ // // },
675+ // // Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
676+ // // return &test.Expected{
677+ // // ExitCode: 0,
678+ // // Output: expect.All(func(stdout, _ string, t *testing.T) {
679+ // // before := data.Labels().Get("logCountBeforePause")
680+ // // after := data.Labels().Get("logCountAfterUnpause")
710681
711- // beforeCount, _ := strconv.Atoi(before)
712- // afterCount, _ := strconv.Atoi(after)
682+ // // beforeCount, _ := strconv.Atoi(before)
683+ // // afterCount, _ := strconv.Atoi(after)
713684
714- // assert.Assert(t, afterCount > beforeCount,
715- // "expected more healthchecks after unpause (got %d → %d)", beforeCount, afterCount)
716- // }),
717- // }
718- // },
719- // },
720- }
685+ // // assert.Assert(t, afterCount > beforeCount,
686+ // // "expected more healthchecks after unpause (got %d → %d)", beforeCount, afterCount)
687+ // // }),
688+ // // }
689+ // // },
690+ // // },
691+ // }
721692
722- testCase .Run (t )
723- }
693+ // testCase.Run(t)
694+ // }
0 commit comments