github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/libcontainer/factory_linux_test.go (about) 1 package libcontainer 2 3 import ( 4 "errors" 5 "os" 6 "path/filepath" 7 "reflect" 8 "testing" 9 10 "github.com/opencontainers/runc/libcontainer/configs" 11 "github.com/opencontainers/runc/libcontainer/utils" 12 "github.com/opencontainers/runtime-spec/specs-go" 13 ) 14 15 func TestFactoryLoadNotExists(t *testing.T) { 16 stateDir := t.TempDir() 17 _, err := Load(stateDir, "nocontainer") 18 if err == nil { 19 t.Fatal("expected nil error loading non-existing container") 20 } 21 if !errors.Is(err, ErrNotExist) { 22 t.Fatalf("expected ErrNotExist, got %v", err) 23 } 24 } 25 26 func TestFactoryLoadContainer(t *testing.T) { 27 root := t.TempDir() 28 // setup default container config and state for mocking 29 var ( 30 id = "1" 31 expectedHooks = configs.Hooks{ 32 configs.Prestart: configs.HookList{ 33 configs.CommandHook{Command: configs.Command{Path: "prestart-hook"}}, 34 }, 35 configs.Poststart: configs.HookList{ 36 configs.CommandHook{Command: configs.Command{Path: "poststart-hook"}}, 37 }, 38 configs.Poststop: configs.HookList{ 39 unserializableHook{}, 40 configs.CommandHook{Command: configs.Command{Path: "poststop-hook"}}, 41 }, 42 } 43 expectedConfig = &configs.Config{ 44 Rootfs: "/mycontainer/root", 45 Hooks: expectedHooks, 46 Cgroups: &configs.Cgroup{ 47 Resources: &configs.Resources{}, 48 }, 49 } 50 expectedState = &State{ 51 BaseState: BaseState{ 52 InitProcessPid: 1024, 53 Config: *expectedConfig, 54 }, 55 } 56 ) 57 if err := os.Mkdir(filepath.Join(root, id), 0o700); err != nil { 58 t.Fatal(err) 59 } 60 if err := marshal(filepath.Join(root, id, stateFilename), expectedState); err != nil { 61 t.Fatal(err) 62 } 63 container, err := Load(root, id) 64 if err != nil { 65 t.Fatal(err) 66 } 67 if container.ID() != id { 68 t.Fatalf("expected container id %q but received %q", id, container.ID()) 69 } 70 config := container.Config() 71 if config.Rootfs != expectedConfig.Rootfs { 72 t.Fatalf("expected rootfs %q but received %q", expectedConfig.Rootfs, config.Rootfs) 73 } 74 expectedHooks[configs.Poststop] = expectedHooks[configs.Poststop][1:] // expect unserializable hook to be skipped 75 if !reflect.DeepEqual(config.Hooks, expectedHooks) { 76 t.Fatalf("expects hooks %q but received %q", expectedHooks, config.Hooks) 77 } 78 if container.initProcess.pid() != expectedState.InitProcessPid { 79 t.Fatalf("expected init pid %d but received %d", expectedState.InitProcessPid, container.initProcess.pid()) 80 } 81 } 82 83 func marshal(path string, v interface{}) error { 84 f, err := os.Create(path) 85 if err != nil { 86 return err 87 } 88 defer f.Close() //nolint: errcheck 89 return utils.WriteJSON(f, v) 90 } 91 92 type unserializableHook struct{} 93 94 func (unserializableHook) Run(*specs.State) error { 95 return nil 96 }