mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-01-19 06:14:33 +01:00
Pulling image is the most time-consuming step in the container lifecycle. This PR introduse nydus to kata container, it can lazily pull image when container start. So it can speed up kata container create and start. Fixes #2724 Signed-off-by: luodaowen.backend <luodaowen.backend@bytedance.com>
242 lines
5.7 KiB
Go
242 lines
5.7 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package virtcontainers
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestNydusdStart(t *testing.T) {
|
|
assert := assert.New(t)
|
|
// nolint: govet
|
|
type fields struct {
|
|
pid int
|
|
path string
|
|
sockPath string
|
|
apiSockPath string
|
|
sourcePath string
|
|
debug bool
|
|
extraArgs []string
|
|
startFn func(cmd *exec.Cmd) error
|
|
setupShareDirFn func() error
|
|
}
|
|
|
|
sourcePath, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(sourcePath)
|
|
|
|
socketDir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(socketDir)
|
|
|
|
sockPath := filepath.Join(socketDir, "vhost-user.sock")
|
|
apiSockPath := filepath.Join(socketDir, "api.sock")
|
|
|
|
validConfig := fields{
|
|
path: "/usr/bin/nydusd",
|
|
sockPath: sockPath,
|
|
apiSockPath: apiSockPath,
|
|
sourcePath: sourcePath,
|
|
startFn: func(cmd *exec.Cmd) error {
|
|
cmd.Process = &os.Process{}
|
|
return nil
|
|
},
|
|
setupShareDirFn: func() error { return nil },
|
|
}
|
|
SourcePathNoExist := validConfig
|
|
SourcePathNoExist.sourcePath = "/tmp/path/to/nydusd/sourcepath"
|
|
|
|
// nolint: govet
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantErr bool
|
|
}{
|
|
{"empty config", fields{}, true},
|
|
{"directory source path not exist", SourcePathNoExist, true},
|
|
{"valid config", validConfig, false},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
nd := &nydusd{
|
|
path: tt.fields.path,
|
|
sockPath: tt.fields.sockPath,
|
|
apiSockPath: tt.fields.apiSockPath,
|
|
sourcePath: tt.fields.sourcePath,
|
|
extraArgs: tt.fields.extraArgs,
|
|
debug: tt.fields.debug,
|
|
pid: tt.fields.pid,
|
|
startFn: tt.fields.startFn,
|
|
setupShareDirFn: tt.fields.setupShareDirFn,
|
|
}
|
|
ctx := context.Background()
|
|
_, err := nd.Start(ctx, nil)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("nydusd.Start() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
func TestNydusdArgs(t *testing.T) {
|
|
assert := assert.New(t)
|
|
nd := &nydusd{
|
|
path: "/usr/bin/nydusd",
|
|
sockPath: "/var/lib/vhost-user.sock",
|
|
apiSockPath: "/var/lib/api.sock",
|
|
debug: true,
|
|
}
|
|
expected := "--log-level debug --apisock /var/lib/api.sock --sock /var/lib/vhost-user.sock"
|
|
args, err := nd.args()
|
|
assert.NoError(err)
|
|
assert.Equal(expected, strings.Join(args, " "))
|
|
|
|
nd.debug = false
|
|
expected = "--log-level info --apisock /var/lib/api.sock --sock /var/lib/vhost-user.sock"
|
|
args, err = nd.args()
|
|
assert.NoError(err)
|
|
assert.Equal(expected, strings.Join(args, " "))
|
|
}
|
|
|
|
func TestNydusdValid(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sourcePath, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(sourcePath)
|
|
|
|
socketDir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(socketDir)
|
|
|
|
sockPath := filepath.Join(socketDir, "vhost-user.sock")
|
|
apiSockPath := filepath.Join(socketDir, "api.sock")
|
|
|
|
newNydsudFunc := func() *nydusd {
|
|
return &nydusd{
|
|
path: "/usr/bin/nydusd",
|
|
sourcePath: sourcePath,
|
|
sockPath: sockPath,
|
|
apiSockPath: apiSockPath,
|
|
}
|
|
}
|
|
nd := newNydsudFunc()
|
|
err = nd.valid()
|
|
assert.NoError(err)
|
|
|
|
nd = newNydsudFunc()
|
|
nd.path = ""
|
|
err = nd.valid()
|
|
assert.Equal(errNydusdDaemonPathInvalid, err)
|
|
|
|
nd = newNydsudFunc()
|
|
nd.sockPath = ""
|
|
err = nd.valid()
|
|
assert.Equal(errNydusdSockPathInvalid, err)
|
|
|
|
nd = newNydsudFunc()
|
|
nd.apiSockPath = ""
|
|
err = nd.valid()
|
|
assert.Equal(errNydusdAPISockPathInvalid, err)
|
|
|
|
nd = newNydsudFunc()
|
|
nd.sourcePath = ""
|
|
err = nd.valid()
|
|
assert.Equal(errNydusdSourcePathInvalid, err)
|
|
}
|
|
|
|
func TestParseExtraOption(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
option string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "valid option",
|
|
option: "extraoption=" + base64.StdEncoding.EncodeToString([]byte("{\"source\":\"/path/to/bootstrap\",\"config\":\"config content\",\"snapshotdir\":\"/path/to/snapshotdir\"}")),
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "no extra option",
|
|
option: base64.StdEncoding.EncodeToString([]byte("{\"source\":/path/to/bootstrap,\"config\":config content,\"snapshotdir\":/path/to/snapshotdir}")),
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no source",
|
|
option: "extraoption=" + base64.StdEncoding.EncodeToString([]byte("{\"config\":config content,\"snapshotdir\":/path/to/snapshotdir}")),
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no config",
|
|
option: "extraoption=" + base64.StdEncoding.EncodeToString([]byte("{\"source\":/path/to/bootstrap,\"snapshotdir\":/path/to/snapshotdir}")),
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "no snapshotdir",
|
|
option: "extraoption=" + base64.StdEncoding.EncodeToString([]byte("{\"source\":/path/to/bootstrap,\"config\":config content}")),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
_, err := parseExtraOption([]string{tt.option})
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("parseExtraOption error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCheckRafsMountPointValid(t *testing.T) {
|
|
tests := []struct {
|
|
mountPoint string
|
|
valid bool
|
|
}{
|
|
{
|
|
mountPoint: "/rafs/xxxxaaa/lowerdir",
|
|
valid: true,
|
|
},
|
|
{
|
|
mountPoint: "/",
|
|
valid: false,
|
|
},
|
|
{
|
|
mountPoint: "/rafs",
|
|
valid: false,
|
|
},
|
|
{
|
|
mountPoint: "/xxxx",
|
|
valid: false,
|
|
},
|
|
{
|
|
mountPoint: "/rafs/aaaaa/xxxx",
|
|
valid: false,
|
|
},
|
|
{
|
|
mountPoint: "/rafs//lowerdir",
|
|
valid: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
res := checkRafsMountPointValid(tt.mountPoint)
|
|
if res != tt.valid {
|
|
t.Errorf("test %v get %v, but want %v", tt, res, tt.valid)
|
|
}
|
|
}
|
|
}
|