Skip to content

Commit

Permalink
add tests for container connections
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-rock committed Feb 23, 2024
1 parent a0f63d9 commit fb90c12
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 185 deletions.
4 changes: 2 additions & 2 deletions providers/os/connection/container/image_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ func NewContainerRegistryImage(id uint32, conf *inventory.Config, asset *invento
if err != nil {
return nil, err
}
if asset.Connections[0].Options == nil {
asset.Connections[0].Options = map[string]string{}
if conf.Options == nil {
conf.Options = map[string]string{}
}

conn, err := NewContainerImageConnection(id, conf, asset, img)
Expand Down
342 changes: 173 additions & 169 deletions providers/os/connection/container/image_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,197 @@ import (
)

const (
alpineImage = "alpine:3.9"
alpineImage = "alpine:3.15"
alpineContainerPath = "./alpine-container.tar"

centosImage = "centos:7"
centosContainerPath = "./centos-container.tar"
)

func TestTarCommand(t *testing.T) {
err := cacheAlpine()
require.NoError(t, err, "should create tar without error")
func cacheImageToTar(source string, filename string) error {
// check if the cache is already there
_, err := os.Stat(filename)
if err == nil {
return nil
}

c, err := container.NewContainerFromTar(0, &inventory.Config{
Type: "tar",
Options: map[string]string{
tar.OPTION_FILE: alpineContainerPath,
},
}, &inventory.Asset{})
assert.Equal(t, nil, err, "should create tar without error")
tag, err := name.NewTag(source, name.WeakValidation)
if err != nil {
return err
}

cmd, err := c.RunCommand("ls /")
assert.Nil(t, err)
if assert.NotNil(t, cmd) {
assert.Equal(t, nil, err, "should execute without error")
assert.Equal(t, -1, cmd.ExitStatus, "command should not be executed")
stdoutContent, _ := io.ReadAll(cmd.Stdout)
assert.Equal(t, "", string(stdoutContent), "output should be correct")
stderrContent, _ := io.ReadAll(cmd.Stdout)
assert.Equal(t, "", string(stderrContent), "output should be correct")
auth, err := authn.DefaultKeychain.Resolve(tag.Registry)
if err != nil {
return err
}

img, err := remote.Image(tag, remote.WithAuth(auth), remote.WithTransport(http.DefaultTransport))
if err != nil {
return err
}

return tarball.WriteToFile(filename, tag, img)
}

func cacheAlpine() error {
return cacheImageToTar(alpineImage, alpineContainerPath)
}

func cacheCentos() error {
return cacheImageToTar(centosImage, centosContainerPath)
}

type dockerConnTest struct {
name string
conn *tar.TarConnection
testfile string
}

func TestPlatformIdentifier(t *testing.T) {
func TestImageConnections(t *testing.T) {
testConnections := []dockerConnTest{}

// create a connection to ta downloaded alpine image
err := cacheAlpine()
require.NoError(t, err, "should create tar without error")

conn, err := container.NewContainerFromTar(0, &inventory.Config{
alpineConn, err := container.NewContainerFromTar(0, &inventory.Config{
Type: "tar",
Options: map[string]string{
tar.OPTION_FILE: alpineContainerPath,
},
}, &inventory.Asset{})
require.NoError(t, err)
platformId, err := conn.Identifier()
require.NoError(t, err)
assert.True(t, len(platformId) > 0)
testConnections = append(testConnections, dockerConnTest{
name: "alpine",
conn: alpineConn,
testfile: "/etc/alpine-release",
})

// create a connection to ta downloaded centos image
err = cacheCentos()
require.NoError(t, err, "should create tar without error")
centosConn, err := container.NewContainerFromTar(0, &inventory.Config{
Type: "tar",
Options: map[string]string{
tar.OPTION_FILE: centosContainerPath,
},
}, &inventory.Asset{})
testConnections = append(testConnections, dockerConnTest{
name: "centos",
conn: centosConn,
testfile: "/etc/centos-release",
})

// create a connection to a remote alpine image
alpineRemoteConn, err := container.NewContainerRegistryImage(0, &inventory.Config{
Type: "docker-image",
Host: alpineImage,
}, &inventory.Asset{})
require.NoError(t, err, "should create remote connection without error")
testConnections = append(testConnections, dockerConnTest{
name: "alpine",
conn: alpineRemoteConn,
testfile: "/etc/alpine-release",
})

for _, test := range testConnections {
t.Run("Test Connection for "+test.name, func(t *testing.T) {
conn := test.conn
require.NotNil(t, conn)
t.Run("Test Run Command", func(t *testing.T) {
cmd, err := conn.RunCommand("ls /")
assert.Nil(t, err, "should execute without error")
assert.Equal(t, -1, cmd.ExitStatus, "command should not be executed")
stdoutContent, _ := io.ReadAll(cmd.Stdout)
assert.Equal(t, "", string(stdoutContent), "output should be correct")
stderrContent, _ := io.ReadAll(cmd.Stdout)
assert.Equal(t, "", string(stderrContent), "output should be correct")
})

t.Run("Test Platform Identifier", func(t *testing.T) {
platformId, err := conn.Identifier()
require.NoError(t, err)
assert.True(t, len(platformId) > 0)
})

t.Run("Test File Stat", func(t *testing.T) {
f, err := conn.FileSystem().Open(test.testfile)
assert.Nil(t, err)
assert.Equal(t, nil, err, "should execute without error")

p := f.Name()
assert.Equal(t, test.testfile, p, "path should be correct")

stat, err := f.Stat()
assert.True(t, stat.Size() >= 6, "should read file size")
assert.Equal(t, nil, err, "should execute without error")

content, err := io.ReadAll(f)
assert.Equal(t, nil, err, "should execute without error")
assert.True(t, len(content) >= 6, "should read the full content")
})

t.Run("Test File Permissions", func(t *testing.T) {
path := test.testfile
details, err := conn.FileInfo(path)
require.NoError(t, err)
assert.Equal(t, int64(0), details.Uid)
assert.Equal(t, int64(0), details.Gid)
assert.True(t, details.Size >= 0)
assert.Equal(t, false, details.Mode.IsDir())
assert.Equal(t, true, details.Mode.IsRegular())
assert.Equal(t, "-rw-r--r--", details.Mode.String())
assert.True(t, details.Mode.UserReadable())
assert.True(t, details.Mode.UserWriteable())
assert.False(t, details.Mode.UserExecutable())
assert.True(t, details.Mode.GroupReadable())
assert.False(t, details.Mode.GroupWriteable())
assert.False(t, details.Mode.GroupExecutable())
assert.True(t, details.Mode.OtherReadable())
assert.False(t, details.Mode.OtherWriteable())
assert.False(t, details.Mode.OtherExecutable())
assert.False(t, details.Mode.Suid())
assert.False(t, details.Mode.Sgid())
assert.False(t, details.Mode.Sticky())

path = "/etc"
details, err = conn.FileInfo(path)
require.NoError(t, err)
assert.Equal(t, int64(0), details.Uid)
assert.Equal(t, int64(0), details.Gid)
assert.True(t, details.Size >= 0)
assert.True(t, details.Mode.IsDir())
assert.False(t, details.Mode.IsRegular())
assert.Equal(t, "drwxr-xr-x", details.Mode.String())
assert.True(t, details.Mode.UserReadable())
assert.True(t, details.Mode.UserWriteable())
assert.True(t, details.Mode.UserExecutable())
assert.True(t, details.Mode.GroupReadable())
assert.False(t, details.Mode.GroupWriteable())
assert.True(t, details.Mode.GroupExecutable())
assert.True(t, details.Mode.OtherReadable())
assert.False(t, details.Mode.OtherWriteable())
assert.True(t, details.Mode.OtherExecutable())
assert.False(t, details.Mode.Suid())
assert.False(t, details.Mode.Sgid())
assert.False(t, details.Mode.Sticky())
})

t.Run("Test Files Find", func(t *testing.T) {
fs := conn.FileSystem()
fSearch := fs.(*tar.FS)

if test.testfile == "/etc/alpine-release" {
infos, err := fSearch.Find("/", regexp.MustCompile(`alpine-release`), "file")
require.NoError(t, err)
assert.Equal(t, 1, len(infos))
} else if test.testfile == "/etc/centos-release" {
infos, err := fSearch.Find("/", regexp.MustCompile(`centos-release`), "file")
require.NoError(t, err)
assert.Equal(t, 6, len(infos))
}
})
})
}

}

func TestTarSymlinkFile(t *testing.T) {
Expand Down Expand Up @@ -131,145 +277,3 @@ func TestTarRelativeSymlinkFileCentos(t *testing.T) {
assert.Equal(t, 37, len(content), "should read the full content")
}
}

func TestTarFile(t *testing.T) {
err := cacheAlpine()
require.NoError(t, err, "should create tar without error")

c, err := container.NewContainerFromTar(0, &inventory.Config{
Type: "tar",
Options: map[string]string{
tar.OPTION_FILE: alpineContainerPath,
},
}, &inventory.Asset{})
assert.Equal(t, nil, err, "should create tar without error")

f, err := c.FileSystem().Open("/etc/alpine-release")
assert.Nil(t, err)
if assert.NotNil(t, f) {
assert.Equal(t, nil, err, "should execute without error")

p := f.Name()
assert.Equal(t, "/etc/alpine-release", p, "path should be correct")

stat, err := f.Stat()
assert.Equal(t, int64(6), stat.Size(), "should read file size")
assert.Equal(t, nil, err, "should execute without error")

content, err := io.ReadAll(f)
assert.Equal(t, nil, err, "should execute without error")
assert.Equal(t, 6, len(content), "should read the full content")
}
}

func TestFilePermissions(t *testing.T) {
err := cacheAlpine()
require.NoError(t, err, "should create tar without error")

c, err := container.NewContainerFromTar(0, &inventory.Config{
Type: "tar",
Options: map[string]string{
tar.OPTION_FILE: alpineContainerPath,
},
}, &inventory.Asset{})
require.NoError(t, err)

path := "/etc/alpine-release"
details, err := c.FileInfo(path)
require.NoError(t, err)
assert.Equal(t, int64(0), details.Uid)
assert.Equal(t, int64(0), details.Gid)
assert.True(t, details.Size >= 0)
assert.Equal(t, false, details.Mode.IsDir())
assert.Equal(t, true, details.Mode.IsRegular())
assert.Equal(t, "-rw-r--r--", details.Mode.String())
assert.True(t, details.Mode.UserReadable())
assert.True(t, details.Mode.UserWriteable())
assert.False(t, details.Mode.UserExecutable())
assert.True(t, details.Mode.GroupReadable())
assert.False(t, details.Mode.GroupWriteable())
assert.False(t, details.Mode.GroupExecutable())
assert.True(t, details.Mode.OtherReadable())
assert.False(t, details.Mode.OtherWriteable())
assert.False(t, details.Mode.OtherExecutable())
assert.False(t, details.Mode.Suid())
assert.False(t, details.Mode.Sgid())
assert.False(t, details.Mode.Sticky())

path = "/etc"
details, err = c.FileInfo(path)
require.NoError(t, err)
assert.Equal(t, int64(0), details.Uid)
assert.Equal(t, int64(0), details.Gid)
assert.True(t, details.Size >= 0)
assert.True(t, details.Mode.IsDir())
assert.False(t, details.Mode.IsRegular())
assert.Equal(t, "drwxr-xr-x", details.Mode.String())
assert.True(t, details.Mode.UserReadable())
assert.True(t, details.Mode.UserWriteable())
assert.True(t, details.Mode.UserExecutable())
assert.True(t, details.Mode.GroupReadable())
assert.False(t, details.Mode.GroupWriteable())
assert.True(t, details.Mode.GroupExecutable())
assert.True(t, details.Mode.OtherReadable())
assert.False(t, details.Mode.OtherWriteable())
assert.True(t, details.Mode.OtherExecutable())
assert.False(t, details.Mode.Suid())
assert.False(t, details.Mode.Sgid())
assert.False(t, details.Mode.Sticky())
}

func TestTarFileFind(t *testing.T) {
err := cacheAlpine()
require.NoError(t, err, "should create tar without error")

c, err := container.NewContainerFromTar(0, &inventory.Config{
Type: "tar",
Options: map[string]string{
tar.OPTION_FILE: alpineContainerPath,
},
}, &inventory.Asset{})
assert.Equal(t, nil, err, "should create tar without error")

fs := c.FileSystem()

fSearch := fs.(*tar.FS)

infos, err := fSearch.Find("/", regexp.MustCompile(`alpine-release`), "file")
require.NoError(t, err)

assert.Equal(t, 1, len(infos))
}

func cacheAlpine() error {
return cacheImageToTar(alpineImage, alpineContainerPath)
}

func cacheCentos() error {
return cacheImageToTar(centosImage, centosContainerPath)
}

func cacheImageToTar(source string, filename string) error {
// check if the cache is already there
_, err := os.Stat(filename)
if err == nil {
return nil
}

tag, err := name.NewTag(source, name.WeakValidation)
if err != nil {
return err
}

auth, err := authn.DefaultKeychain.Resolve(tag.Registry)
if err != nil {
return err
}

img, err := remote.Image(tag, remote.WithAuth(auth), remote.WithTransport(http.DefaultTransport))
if err != nil {
return err
}

return tarball.WriteToFile(filename, tag, img)
}
Loading

0 comments on commit fb90c12

Please sign in to comment.