github.com/containers/podman/v4@v4.9.4/libpod/common_test.go (about)

     1  //go:build !remote
     2  // +build !remote
     3  
     4  package libpod
     5  
     6  import (
     7  	"net"
     8  	"reflect"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/containers/common/libnetwork/types"
    14  	"github.com/containers/common/pkg/config"
    15  	"github.com/containers/podman/v4/libpod/define"
    16  	"github.com/containers/podman/v4/libpod/lock"
    17  	"github.com/opencontainers/runtime-tools/generate"
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func getTestContainer(id, name string, manager lock.Manager) (*Container, error) {
    23  	ctr := &Container{
    24  		config: &ContainerConfig{
    25  			ID:   id,
    26  			Name: name,
    27  			ContainerRootFSConfig: ContainerRootFSConfig{
    28  				RootfsImageID:   id,
    29  				RootfsImageName: "testimg",
    30  				StaticDir:       "/does/not/exist/",
    31  				Mounts:          []string{"/does/not/exist"},
    32  			},
    33  			ContainerMiscConfig: ContainerMiscConfig{
    34  				LogPath:     "/does/not/exist/",
    35  				Stdin:       true,
    36  				Labels:      map[string]string{"a": "b", "c": "d"},
    37  				StopSignal:  0,
    38  				StopTimeout: 0,
    39  				CreatedTime: time.Now(),
    40  			},
    41  			ContainerSecurityConfig: ContainerSecurityConfig{
    42  				Privileged: true,
    43  			},
    44  			ContainerNetworkConfig: ContainerNetworkConfig{
    45  				DNSServer: []net.IP{net.ParseIP("192.168.1.1"), net.ParseIP("192.168.2.2")},
    46  				DNSSearch: []string{"example.com", "example.example.com"},
    47  				PortMappings: []types.PortMapping{
    48  					{
    49  						HostPort:      80,
    50  						ContainerPort: 90,
    51  						Protocol:      "tcp",
    52  						HostIP:        "192.168.3.3",
    53  						Range:         1,
    54  					},
    55  					{
    56  						HostPort:      100,
    57  						ContainerPort: 110,
    58  						Protocol:      "udp",
    59  						HostIP:        "192.168.4.4",
    60  						Range:         1,
    61  					},
    62  				},
    63  			},
    64  		},
    65  		state: &ContainerState{
    66  			State:      define.ContainerStateRunning,
    67  			ConfigPath: "/does/not/exist/specs/" + id,
    68  			RunDir:     "/does/not/exist/tmp/",
    69  			Mounted:    true,
    70  			Mountpoint: "/does/not/exist/tmp/" + id,
    71  			PID:        1234,
    72  			ExecSessions: map[string]*ExecSession{
    73  				"abcd": {
    74  					Id:  "1",
    75  					PID: 9876,
    76  				},
    77  				"ef01": {
    78  					Id:  "5",
    79  					PID: 46765,
    80  				},
    81  			},
    82  			BindMounts: map[string]string{
    83  				"/1/2/3":          "/4/5/6",
    84  				"/test/file.test": "/test2/file2.test",
    85  			},
    86  		},
    87  		runtime: &Runtime{
    88  			config: &config.Config{
    89  				Engine: config.EngineConfig{
    90  					VolumePath: "/does/not/exist/tmp/volumes",
    91  				},
    92  			},
    93  		},
    94  		valid: true,
    95  	}
    96  
    97  	g, err := generate.New("linux")
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	ctr.config.Spec = g.Config
   102  
   103  	ctr.config.Labels["test"] = "testing"
   104  
   105  	// Allocate a containerLock for the container
   106  	containerLock, err := manager.AllocateLock()
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	ctr.lock = containerLock
   111  	ctr.config.LockID = containerLock.ID()
   112  
   113  	return ctr, nil
   114  }
   115  
   116  func getTestPod(id, name string, manager lock.Manager) (*Pod, error) {
   117  	pod := &Pod{
   118  		config: &PodConfig{
   119  			ID:           id,
   120  			Name:         name,
   121  			Labels:       map[string]string{"a": "b", "c": "d"},
   122  			CgroupParent: "/hello/world/cgroup/parent",
   123  		},
   124  		state: &podState{
   125  			CgroupPath: "/path/to/cgroups/hello/",
   126  		},
   127  		valid: true,
   128  	}
   129  
   130  	// Allocate a podLock for the pod
   131  	podLock, err := manager.AllocateLock()
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  	pod.lock = podLock
   136  	pod.config.LockID = podLock.ID()
   137  
   138  	return pod, nil
   139  }
   140  
   141  func getTestCtrN(n string, manager lock.Manager) (*Container, error) {
   142  	return getTestContainer(strings.Repeat(n, 32), "test"+n, manager)
   143  }
   144  
   145  func getTestCtr1(manager lock.Manager) (*Container, error) {
   146  	return getTestCtrN("1", manager)
   147  }
   148  
   149  func getTestCtr2(manager lock.Manager) (*Container, error) {
   150  	return getTestCtrN("2", manager)
   151  }
   152  
   153  func getTestPodN(n string, manager lock.Manager) (*Pod, error) {
   154  	return getTestPod(strings.Repeat(n, 32), "test"+n, manager)
   155  }
   156  
   157  func getTestPod1(manager lock.Manager) (*Pod, error) {
   158  	return getTestPodN("1", manager)
   159  }
   160  
   161  func getTestPod2(manager lock.Manager) (*Pod, error) {
   162  	return getTestPodN("2", manager)
   163  }
   164  
   165  // This horrible hack tests if containers are equal in a way that should handle
   166  // empty arrays being dropped to nil pointers in the spec JSON
   167  // For some operations (container retrieval from the database) state is allowed
   168  // to be empty. This is controlled by the allowedEmpty bool.
   169  func testContainersEqual(t *testing.T, a, b *Container, allowedEmpty bool) {
   170  	if a == nil && b == nil {
   171  		return
   172  	}
   173  	require.NotNil(t, a)
   174  	require.NotNil(t, b)
   175  
   176  	require.NotNil(t, a.config)
   177  	require.NotNil(t, b.config)
   178  	require.NotNil(t, a.state)
   179  	require.NotNil(t, b.state)
   180  
   181  	aConfig := new(ContainerConfig)
   182  	bConfig := new(ContainerConfig)
   183  	aState := new(ContainerState)
   184  	bState := new(ContainerState)
   185  
   186  	blankState := new(ContainerState)
   187  
   188  	assert.Equal(t, a.valid, b.valid)
   189  
   190  	assert.Equal(t, a.lock.ID(), b.lock.ID())
   191  
   192  	aConfigJSON, err := json.Marshal(a.config)
   193  	assert.NoError(t, err)
   194  	err = json.Unmarshal(aConfigJSON, aConfig)
   195  	assert.NoError(t, err)
   196  
   197  	bConfigJSON, err := json.Marshal(b.config)
   198  	assert.NoError(t, err)
   199  	err = json.Unmarshal(bConfigJSON, bConfig)
   200  	assert.NoError(t, err)
   201  
   202  	assert.EqualValues(t, aConfig, bConfig)
   203  
   204  	aStateJSON, err := json.Marshal(a.state)
   205  	assert.NoError(t, err)
   206  	err = json.Unmarshal(aStateJSON, aState)
   207  	assert.NoError(t, err)
   208  
   209  	bStateJSON, err := json.Marshal(b.state)
   210  	assert.NoError(t, err)
   211  	err = json.Unmarshal(bStateJSON, bState)
   212  	assert.NoError(t, err)
   213  
   214  	if allowedEmpty {
   215  		assert.True(t, reflect.DeepEqual(aState, bState) || reflect.DeepEqual(aState, blankState))
   216  	} else {
   217  		assert.EqualValues(t, aState, bState)
   218  	}
   219  }
   220  
   221  // Test if pods are equal.
   222  // For some operations (pod retrieval from the database) state is allowed to be
   223  // empty. This is controlled by the allowedEmpty bool.
   224  func testPodsEqual(t *testing.T, a, b *Pod, allowedEmpty bool) {
   225  	if a == nil && b == nil {
   226  		return
   227  	}
   228  
   229  	blankState := new(podState)
   230  
   231  	require.NotNil(t, a)
   232  	require.NotNil(t, b)
   233  
   234  	require.NotNil(t, a.config)
   235  	require.NotNil(t, b.config)
   236  	require.NotNil(t, a.state)
   237  	require.NotNil(t, b.state)
   238  
   239  	assert.Equal(t, a.valid, b.valid)
   240  
   241  	assert.Equal(t, a.lock.ID(), b.lock.ID())
   242  
   243  	assert.EqualValues(t, a.config, b.config)
   244  
   245  	if allowedEmpty {
   246  		assert.True(t, reflect.DeepEqual(a.state, b.state) || reflect.DeepEqual(a.state, blankState))
   247  	} else {
   248  		assert.EqualValues(t, a.state, b.state)
   249  	}
   250  }