2024-03-20 19:23:31 +00:00
|
|
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
2024-03-25 01:36:21 +00:00
|
|
|
|
2024-03-20 19:23:31 +00:00
|
|
|
package resource
|
|
|
|
|
|
|
|
import (
|
2024-03-25 20:31:06 +00:00
|
|
|
"context"
|
|
|
|
"decl/tests/mocks"
|
2024-11-10 18:24:06 +00:00
|
|
|
_ "encoding/json"
|
|
|
|
_ "fmt"
|
2024-03-25 20:31:06 +00:00
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/container"
|
|
|
|
"github.com/docker/docker/api/types/network"
|
|
|
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
|
|
"github.com/stretchr/testify/assert"
|
2024-11-10 18:24:06 +00:00
|
|
|
"io"
|
|
|
|
_ "net/http"
|
|
|
|
_ "net/http/httptest"
|
|
|
|
_ "net/url"
|
|
|
|
_ "os"
|
|
|
|
"strings"
|
2024-03-25 20:31:06 +00:00
|
|
|
"testing"
|
2024-11-10 18:24:06 +00:00
|
|
|
"bytes"
|
2024-03-20 19:23:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestNewContainerResource(t *testing.T) {
|
2024-03-25 20:31:06 +00:00
|
|
|
c := NewContainer(&mocks.MockContainerClient{})
|
|
|
|
assert.NotEqual(t, nil, c)
|
2024-03-20 19:23:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestReadContainer(t *testing.T) {
|
2024-03-25 20:31:06 +00:00
|
|
|
ctx := context.Background()
|
|
|
|
decl := `
|
2024-03-20 19:23:31 +00:00
|
|
|
name: "testcontainer"
|
|
|
|
image: "alpine"
|
|
|
|
state: present
|
|
|
|
`
|
2024-03-25 20:31:06 +00:00
|
|
|
m := &mocks.MockContainerClient{
|
2024-04-03 22:58:29 +00:00
|
|
|
InjectContainerList: func(ctx context.Context, options container.ListOptions) ([]types.Container, error) {
|
2024-03-25 20:31:06 +00:00
|
|
|
return []types.Container{
|
|
|
|
{ID: "123456789abc"},
|
|
|
|
{ID: "123456789def"},
|
|
|
|
}, nil
|
|
|
|
},
|
|
|
|
InjectContainerInspect: func(ctx context.Context, containerID string) (types.ContainerJSON, error) {
|
|
|
|
return types.ContainerJSON{
|
|
|
|
ContainerJSONBase: &types.ContainerJSONBase{
|
|
|
|
ID: "123456789abc",
|
|
|
|
Name: "test",
|
|
|
|
Image: "alpine",
|
|
|
|
}}, nil
|
|
|
|
},
|
2024-05-24 05:11:51 +00:00
|
|
|
InjectContainerWait: func(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
|
|
|
|
var res container.WaitResponse
|
|
|
|
resChan := make(chan container.WaitResponse)
|
|
|
|
errChan := make(chan error, 1)
|
|
|
|
go func() { resChan <- res }()
|
|
|
|
return resChan, errChan
|
|
|
|
},
|
2024-11-10 18:24:06 +00:00
|
|
|
InjectContainerLogs: func(ctx context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) {
|
|
|
|
return io.NopCloser(strings.NewReader("done.")), nil
|
|
|
|
},
|
2024-03-25 20:31:06 +00:00
|
|
|
}
|
2024-03-20 19:23:31 +00:00
|
|
|
|
2024-03-25 20:31:06 +00:00
|
|
|
c := NewContainer(m)
|
|
|
|
assert.NotEqual(t, nil, c)
|
2024-03-20 19:23:31 +00:00
|
|
|
|
2024-03-25 20:31:06 +00:00
|
|
|
e := c.LoadDecl(decl)
|
|
|
|
assert.Equal(t, nil, e)
|
|
|
|
assert.Equal(t, "testcontainer", c.Name)
|
2024-03-20 19:23:31 +00:00
|
|
|
|
2024-03-25 20:31:06 +00:00
|
|
|
resourceYaml, readContainerErr := c.Read(ctx)
|
|
|
|
assert.Equal(t, nil, readContainerErr)
|
|
|
|
assert.Greater(t, len(resourceYaml), 0)
|
2024-03-20 19:23:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestCreateContainer(t *testing.T) {
|
2024-03-25 20:31:06 +00:00
|
|
|
m := &mocks.MockContainerClient{
|
|
|
|
InjectContainerCreate: func(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {
|
|
|
|
return container.CreateResponse{ID: "abcdef012", Warnings: []string{}}, nil
|
|
|
|
},
|
2024-05-24 05:11:51 +00:00
|
|
|
InjectContainerStop: func(context.Context, string, container.StopOptions) error {
|
|
|
|
return nil
|
|
|
|
},
|
2024-03-25 20:31:06 +00:00
|
|
|
InjectContainerRemove: func(context.Context, string, container.RemoveOptions) error {
|
|
|
|
return nil
|
|
|
|
},
|
2024-05-24 05:11:51 +00:00
|
|
|
InjectContainerWait: func(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
|
|
|
|
var res container.WaitResponse
|
|
|
|
resChan := make(chan container.WaitResponse)
|
|
|
|
errChan := make(chan error, 1)
|
|
|
|
go func() { resChan <- res }()
|
|
|
|
return resChan, errChan
|
|
|
|
},
|
2024-11-10 18:24:06 +00:00
|
|
|
InjectContainerLogs: func(ctx context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) {
|
|
|
|
return io.NopCloser(strings.NewReader("done.")), nil
|
|
|
|
},
|
2024-03-25 20:31:06 +00:00
|
|
|
}
|
2024-03-20 19:23:31 +00:00
|
|
|
|
2024-03-25 20:31:06 +00:00
|
|
|
decl := `
|
2024-03-20 19:23:31 +00:00
|
|
|
name: "testcontainer"
|
|
|
|
image: "alpine"
|
|
|
|
state: present
|
|
|
|
`
|
2024-03-25 20:31:06 +00:00
|
|
|
c := NewContainer(m)
|
|
|
|
e := c.LoadDecl(decl)
|
|
|
|
assert.Equal(t, nil, e)
|
|
|
|
assert.Equal(t, "testcontainer", c.Name)
|
2024-03-20 19:23:31 +00:00
|
|
|
|
2024-03-25 20:31:06 +00:00
|
|
|
applyErr := c.Apply()
|
|
|
|
assert.Equal(t, nil, applyErr)
|
2024-03-20 19:23:31 +00:00
|
|
|
|
2024-03-25 20:31:06 +00:00
|
|
|
c.State = "absent"
|
2024-03-20 19:23:31 +00:00
|
|
|
|
2024-03-25 20:31:06 +00:00
|
|
|
applyDeleteErr := c.Apply()
|
|
|
|
assert.Equal(t, nil, applyDeleteErr)
|
2024-03-20 19:23:31 +00:00
|
|
|
}
|
2024-11-10 18:24:06 +00:00
|
|
|
|
|
|
|
// Detect the ContainerLog header for each entry
|
|
|
|
func TestContainerLogOutput(t *testing.T) {
|
|
|
|
logHeader := []byte{0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x05}
|
|
|
|
logHeader = append(logHeader, []byte(string("done."))...)
|
|
|
|
logs := bytes.NewReader(logHeader)
|
|
|
|
|
|
|
|
m := &mocks.MockContainerClient{
|
|
|
|
InjectContainerCreate: func(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {
|
|
|
|
return container.CreateResponse{ID: "abcdef012", Warnings: []string{}}, nil
|
|
|
|
},
|
|
|
|
InjectContainerStop: func(context.Context, string, container.StopOptions) error {
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
InjectContainerRemove: func(context.Context, string, container.RemoveOptions) error {
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
InjectContainerWait: func(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {
|
|
|
|
var res container.WaitResponse
|
|
|
|
resChan := make(chan container.WaitResponse)
|
|
|
|
errChan := make(chan error, 1)
|
|
|
|
go func() { resChan <- res }()
|
|
|
|
return resChan, errChan
|
|
|
|
},
|
|
|
|
InjectContainerLogs: func(ctx context.Context, containerID string, options container.LogsOptions) (io.ReadCloser, error) {
|
|
|
|
return io.NopCloser(logs), nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
c := NewContainer(m)
|
|
|
|
c.ReadFromContainer(context.Background())
|
|
|
|
assert.Equal(t, "done.", c.Stdout)
|
|
|
|
|
|
|
|
}
|