Skip to content

Commit

Permalink
Add integrations tests
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim An <[email protected]>
  • Loading branch information
anmaxvl committed Nov 23, 2020
1 parent 95c0d84 commit 9e2a1e2
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 18 deletions.
4 changes: 1 addition & 3 deletions internal/cmd/io_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ UpstreamIO, er
return nil, err
}

var (
sout, serr, w io.ReadWriteCloser
)
var sout, serr, w io.ReadWriteCloser

bio := &binaryIO{}

Expand Down
16 changes: 16 additions & 0 deletions test/cri-containerd/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,19 @@ func removeContainer(t *testing.T, client runtime.RuntimeServiceClient, ctx cont
t.Fatalf("failed StopContainer request for container: %s, with: %v", containerID, err)
}
}

func getCreateContainerRequest(podID string, name string, image string, command []string, podConfig *runtime.PodSandboxConfig) *runtime.CreateContainerRequest {
return &runtime.CreateContainerRequest{
Config: &runtime.ContainerConfig{
Metadata: &runtime.ContainerMetadata{
Name: name,
},
Image: &runtime.ImageSpec{
Image: image,
},
Command: command,
},
PodSandboxId: podID,
SandboxConfig: podConfig,
}
}
50 changes: 50 additions & 0 deletions test/cri-containerd/helpers/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"context"
"fmt"
"io"
"os"
"sync"

"github.com/Microsoft/go-winio"
)

func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

soutPipe := os.Getenv("CONTAINER_STDOUT")
waitPipe := os.Getenv("CONTAINER_WAIT")

sout, err := winio.DialPipeContext(ctx, soutPipe)
if err != nil {
fmt.Fprintf(os.Stderr, "couldn't open pipe. %s", err)
os.Exit(1)
}
defer sout.Close()

wait, err := winio.DialPipeContext(ctx, waitPipe)
if err != nil {
fmt.Fprintf(os.Stderr, "couldn't open pipe. %s", err)
os.Exit(1)
}

destPath := os.Args[1]
dest, err := os.Create(destPath)
if err != nil {
fmt.Fprintf(os.Stderr, "couldn't open destination file: %s", err)
}
defer dest.Close()

wait.Close()

var wg sync.WaitGroup

wg.Add(1)
go func() {
defer wg.Done()
io.Copy(dest, sout)
}()
wg.Wait()
}
138 changes: 138 additions & 0 deletions test/cri-containerd/logging_binary_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// +build functional

package cri_containerd

import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"time"

runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)

// This test requires compiling a helper logging binary which can be found
// at test/cri-containerd/helpers/log.go. Copy log.exe to ContainerPlat install
// directory or set "TEST_BINARY_ROOT" environment variable, which this test
// will use to construct logPath for CreateContainerRequest and as the location
// of stdout artifacts created by the binary
func Test_Run_Container_With_Binary_Logger(t *testing.T) {
client := newTestRuntimeClient(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

logBinaryRoot := os.Getenv("TEST_BINARY_ROOT")
if logBinaryRoot == "" {
logBinaryRoot = "/ContainerPlat"
}

binaryPath := fmt.Sprintf("binary://%s/log.exe", logBinaryRoot)

type config struct {
TestConfig
expectedContent string
}

tests := []config{
{
TestConfig: TestConfig{
name: "WCOW_Process",
containerName: t.Name() + "-Container-WCOW_Process",
requiredFeatures: []string{featureWCOWProcess},
runtimeHandler: wcowProcessRuntimeHandler,
sandboxImage: imageWindowsNanoserver,
containerImage: imageWindowsNanoserver,
cmd: []string{"ping", "-t", "127.0.0.1"},
},
expectedContent: "Pinging 127.0.0.1 with 32 bytes of data",
},
{
TestConfig: TestConfig{
name: "WCOW_Hypervisor",
containerName: t.Name() + "-Container-WCOW_Hypervisor",
requiredFeatures: []string{featureWCOWHypervisor},
runtimeHandler: wcowHypervisorRuntimeHandler,
sandboxImage: imageWindowsNanoserver,
containerImage: imageWindowsNanoserver,
cmd: []string{"ping", "-t", "127.0.0.1"},
},
expectedContent: "Pinging 127.0.0.1 with 32 bytes of data",
},
{
TestConfig: TestConfig{
name: "LCOW",
containerName: t.Name() + "-Container-LCOW",
requiredFeatures: []string{featureLCOW},
runtimeHandler: lcowRuntimeHandler,
sandboxImage: imageLcowK8sPause,
containerImage: imageLcowAlpine,
cmd: []string{"ash", "-c", "while true; do echo 'Hello, World!'; sleep 1; done"},
},
expectedContent: "Hello, World!",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
requireFeatures(t, test.requiredFeatures...)

requiredImages := []string{test.sandboxImage, test.containerImage}
if test.runtimeHandler == lcowRuntimeHandler {
pullRequiredLcowImages(t, requiredImages)
} else {
pullRequiredImages(t, requiredImages)
}

podReq := getRunPodSandboxRequest(t, test.runtimeHandler)
podID := runPodSandbox(t, client, ctx, &podReq)
defer removePodSandbox(t, client, ctx, podID)

logFileName := fmt.Sprintf("%s/stdout-%s.txt", logBinaryRoot, test.name)
conReq := getCreateContainerRequest(podID, test.containerName, test.containerImage, test.cmd, podReq.Config)
conReq.Config.LogPath = binaryPath + fmt.Sprintf("?%s", logFileName)

createAndRunContainer(t, client, ctx, conReq)

_, err := os.Stat(logFileName)

if os.IsNotExist(err) {
t.Fatalf("log file was not created: %s", logFileName)
}
defer os.Remove(logFileName)

ok, err := assertFileContent(logFileName, test.expectedContent)

if err != nil {
t.Fatalf("failed to read log file: %s", err)
}

if !ok {
t.Fatalf("file content validation failed: %s", test.expectedContent)
}
})
}
}

func createAndRunContainer(t *testing.T, client runtime.RuntimeServiceClient, ctx context.Context, conReq *runtime.CreateContainerRequest) {
containerID := createContainer(t, client, ctx, conReq)
defer removeContainer(t, client, ctx, containerID)

startContainer(t, client, ctx, containerID)
defer stopContainer(t, client, ctx, containerID)

// Let stdio kick in
time.Sleep(time.Second * 1)
}

func assertFileContent(path string, content string) (bool, error) {
fileContent, err := ioutil.ReadFile(path)

if err != nil {
return false, err
}

return strings.Contains(string(fileContent), content), nil
}
18 changes: 3 additions & 15 deletions test/cri-containerd/runpodsandbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1353,21 +1353,9 @@ func createSandboxContainerAndExecForCustomScratch(t *testing.T, annotations map
func createContainerInSandbox(t *testing.T, client runtime.RuntimeServiceClient, ctx context.Context, podId, containerName, imageName string, command []string,
annotations map[string]string, mounts []*runtime.Mount, podConfig *runtime.PodSandboxConfig) string {

cRequest := &runtime.CreateContainerRequest{
Config: &runtime.ContainerConfig{
Metadata: &runtime.ContainerMetadata{
Name: containerName,
},
Image: &runtime.ImageSpec{
Image: imageName,
},
Command: command,
Annotations: annotations,
Mounts: mounts,
},
PodSandboxId: podId,
SandboxConfig: podConfig,
}
cRequest := getCreateContainerRequest(podId, containerName, imageName, command, podConfig)
cRequest.Config.Annotations = annotations
cRequest.Config.Mounts = mounts

containerID := createContainer(t, client, ctx, cRequest)

Expand Down

0 comments on commit 9e2a1e2

Please sign in to comment.