mirror of
https://github.com/containers/podman.git
synced 2025-05-17 06:59:07 +08:00

Moving from Go module v4 to v5 prepares us for public releases. Move done using gomove [1] as with the v3 and v4 moves. [1] https://github.com/KSubedi/gomove Signed-off-by: Matt Heon <mheon@redhat.com>
250 lines
6.0 KiB
Go
250 lines
6.0 KiB
Go
//go:build !remote
|
|
|
|
package libpod
|
|
|
|
import (
|
|
"net"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/containers/common/libnetwork/types"
|
|
"github.com/containers/common/pkg/config"
|
|
"github.com/containers/podman/v5/libpod/define"
|
|
"github.com/containers/podman/v5/libpod/lock"
|
|
"github.com/opencontainers/runtime-tools/generate"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func getTestContainer(id, name string, manager lock.Manager) (*Container, error) {
|
|
ctr := &Container{
|
|
config: &ContainerConfig{
|
|
ID: id,
|
|
Name: name,
|
|
ContainerRootFSConfig: ContainerRootFSConfig{
|
|
RootfsImageID: id,
|
|
RootfsImageName: "testimg",
|
|
StaticDir: "/does/not/exist/",
|
|
Mounts: []string{"/does/not/exist"},
|
|
},
|
|
ContainerMiscConfig: ContainerMiscConfig{
|
|
LogPath: "/does/not/exist/",
|
|
Stdin: true,
|
|
Labels: map[string]string{"a": "b", "c": "d"},
|
|
StopSignal: 0,
|
|
StopTimeout: 0,
|
|
CreatedTime: time.Now(),
|
|
},
|
|
ContainerSecurityConfig: ContainerSecurityConfig{
|
|
Privileged: true,
|
|
},
|
|
ContainerNetworkConfig: ContainerNetworkConfig{
|
|
DNSServer: []net.IP{net.ParseIP("192.168.1.1"), net.ParseIP("192.168.2.2")},
|
|
DNSSearch: []string{"example.com", "example.example.com"},
|
|
PortMappings: []types.PortMapping{
|
|
{
|
|
HostPort: 80,
|
|
ContainerPort: 90,
|
|
Protocol: "tcp",
|
|
HostIP: "192.168.3.3",
|
|
Range: 1,
|
|
},
|
|
{
|
|
HostPort: 100,
|
|
ContainerPort: 110,
|
|
Protocol: "udp",
|
|
HostIP: "192.168.4.4",
|
|
Range: 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
state: &ContainerState{
|
|
State: define.ContainerStateRunning,
|
|
ConfigPath: "/does/not/exist/specs/" + id,
|
|
RunDir: "/does/not/exist/tmp/",
|
|
Mounted: true,
|
|
Mountpoint: "/does/not/exist/tmp/" + id,
|
|
PID: 1234,
|
|
ExecSessions: map[string]*ExecSession{
|
|
"abcd": {
|
|
Id: "1",
|
|
PID: 9876,
|
|
},
|
|
"ef01": {
|
|
Id: "5",
|
|
PID: 46765,
|
|
},
|
|
},
|
|
BindMounts: map[string]string{
|
|
"/1/2/3": "/4/5/6",
|
|
"/test/file.test": "/test2/file2.test",
|
|
},
|
|
},
|
|
runtime: &Runtime{
|
|
config: &config.Config{
|
|
Engine: config.EngineConfig{
|
|
VolumePath: "/does/not/exist/tmp/volumes",
|
|
},
|
|
},
|
|
},
|
|
valid: true,
|
|
}
|
|
|
|
g, err := generate.New("linux")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ctr.config.Spec = g.Config
|
|
|
|
ctr.config.Labels["test"] = "testing"
|
|
|
|
// Allocate a containerLock for the container
|
|
containerLock, err := manager.AllocateLock()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ctr.lock = containerLock
|
|
ctr.config.LockID = containerLock.ID()
|
|
|
|
return ctr, nil
|
|
}
|
|
|
|
func getTestPod(id, name string, manager lock.Manager) (*Pod, error) {
|
|
pod := &Pod{
|
|
config: &PodConfig{
|
|
ID: id,
|
|
Name: name,
|
|
Labels: map[string]string{"a": "b", "c": "d"},
|
|
CgroupParent: "/hello/world/cgroup/parent",
|
|
},
|
|
state: &podState{
|
|
CgroupPath: "/path/to/cgroups/hello/",
|
|
},
|
|
valid: true,
|
|
}
|
|
|
|
// Allocate a podLock for the pod
|
|
podLock, err := manager.AllocateLock()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
pod.lock = podLock
|
|
pod.config.LockID = podLock.ID()
|
|
|
|
return pod, nil
|
|
}
|
|
|
|
func getTestCtrN(n string, manager lock.Manager) (*Container, error) {
|
|
return getTestContainer(strings.Repeat(n, 32), "test"+n, manager)
|
|
}
|
|
|
|
func getTestCtr1(manager lock.Manager) (*Container, error) {
|
|
return getTestCtrN("1", manager)
|
|
}
|
|
|
|
func getTestCtr2(manager lock.Manager) (*Container, error) {
|
|
return getTestCtrN("2", manager)
|
|
}
|
|
|
|
func getTestPodN(n string, manager lock.Manager) (*Pod, error) {
|
|
return getTestPod(strings.Repeat(n, 32), "test"+n, manager)
|
|
}
|
|
|
|
func getTestPod1(manager lock.Manager) (*Pod, error) {
|
|
return getTestPodN("1", manager)
|
|
}
|
|
|
|
func getTestPod2(manager lock.Manager) (*Pod, error) {
|
|
return getTestPodN("2", manager)
|
|
}
|
|
|
|
// This horrible hack tests if containers are equal in a way that should handle
|
|
// empty arrays being dropped to nil pointers in the spec JSON
|
|
// For some operations (container retrieval from the database) state is allowed
|
|
// to be empty. This is controlled by the allowedEmpty bool.
|
|
func testContainersEqual(t *testing.T, a, b *Container, allowedEmpty bool) {
|
|
if a == nil && b == nil {
|
|
return
|
|
}
|
|
require.NotNil(t, a)
|
|
require.NotNil(t, b)
|
|
|
|
require.NotNil(t, a.config)
|
|
require.NotNil(t, b.config)
|
|
require.NotNil(t, a.state)
|
|
require.NotNil(t, b.state)
|
|
|
|
aConfig := new(ContainerConfig)
|
|
bConfig := new(ContainerConfig)
|
|
aState := new(ContainerState)
|
|
bState := new(ContainerState)
|
|
|
|
blankState := new(ContainerState)
|
|
|
|
assert.Equal(t, a.valid, b.valid)
|
|
|
|
assert.Equal(t, a.lock.ID(), b.lock.ID())
|
|
|
|
aConfigJSON, err := json.Marshal(a.config)
|
|
assert.NoError(t, err)
|
|
err = json.Unmarshal(aConfigJSON, aConfig)
|
|
assert.NoError(t, err)
|
|
|
|
bConfigJSON, err := json.Marshal(b.config)
|
|
assert.NoError(t, err)
|
|
err = json.Unmarshal(bConfigJSON, bConfig)
|
|
assert.NoError(t, err)
|
|
|
|
assert.EqualValues(t, aConfig, bConfig)
|
|
|
|
aStateJSON, err := json.Marshal(a.state)
|
|
assert.NoError(t, err)
|
|
err = json.Unmarshal(aStateJSON, aState)
|
|
assert.NoError(t, err)
|
|
|
|
bStateJSON, err := json.Marshal(b.state)
|
|
assert.NoError(t, err)
|
|
err = json.Unmarshal(bStateJSON, bState)
|
|
assert.NoError(t, err)
|
|
|
|
if allowedEmpty {
|
|
assert.True(t, reflect.DeepEqual(aState, bState) || reflect.DeepEqual(aState, blankState))
|
|
} else {
|
|
assert.EqualValues(t, aState, bState)
|
|
}
|
|
}
|
|
|
|
// Test if pods are equal.
|
|
// For some operations (pod retrieval from the database) state is allowed to be
|
|
// empty. This is controlled by the allowedEmpty bool.
|
|
func testPodsEqual(t *testing.T, a, b *Pod, allowedEmpty bool) {
|
|
if a == nil && b == nil {
|
|
return
|
|
}
|
|
|
|
blankState := new(podState)
|
|
|
|
require.NotNil(t, a)
|
|
require.NotNil(t, b)
|
|
|
|
require.NotNil(t, a.config)
|
|
require.NotNil(t, b.config)
|
|
require.NotNil(t, a.state)
|
|
require.NotNil(t, b.state)
|
|
|
|
assert.Equal(t, a.valid, b.valid)
|
|
|
|
assert.Equal(t, a.lock.ID(), b.lock.ID())
|
|
|
|
assert.EqualValues(t, a.config, b.config)
|
|
|
|
if allowedEmpty {
|
|
assert.True(t, reflect.DeepEqual(a.state, b.state) || reflect.DeepEqual(a.state, blankState))
|
|
} else {
|
|
assert.EqualValues(t, a.state, b.state)
|
|
}
|
|
}
|