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  }