Skip to content

Commit

Permalink
containerz tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alshabib committed Sep 30, 2024
1 parent 3f72a23 commit f407f27
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 31 deletions.
16 changes: 16 additions & 0 deletions feature/container/containerz/tests/container_lifecycle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ Now export the container to a tarball.

```shell
$ docker save -o /tmp/cntrsrv.tar cntrsrv:latest
$ docker tag cntrsrv:latest cntrsrv:upgrade
$ docker save -o /tmp/cntrsrv-upgrade.tar cntrsrv:upgrade
$ docker rmi cntrsrv:latest
```

Expand Down Expand Up @@ -98,6 +100,16 @@ Using the container started as part of CNTR-1.2, validate that the container can
be stopped, and is subsequently no longer listed in the `gnoi.Containerz.List`
API.

## CNTR-1.5: Create a volume on the DUT.

Validate the the DUT is capable of creating a volume, reading it back
and removing it.

## CNTR-1.6: Upgrade a container on the DUT.

Using the same container started as part of CNTR-1.1, validate that the container
can upgraded.

## OpenConfig Path and RPC Coverage

The below yaml defines the RPCs intended to be covered by this test.
Expand All @@ -110,4 +122,8 @@ rpcs:
containerz.Containerz.StopContainer:
containerz.Containerz.Log:
containerz.Containerz.ListContainer:
containerz.Containerz.CreateVolume:
containerz.Containerz.RemoveVolume:
containerz.Containerz.ListVolume:
containerz.Containerz.UpgradeContainer:
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,42 @@ import (
"context"
"crypto/tls"
"flag"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/openconfig/containerz/client"
cpb "github.com/openconfig/featureprofiles/internal/cntrsrv/proto/cntr"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"testing"
"time"
)

var (
containerTar = flag.String("container_tar", "/tmp/cntrsrv.tar", "The container tarball to deploy.")
containerzAddr = flag.String("containerz_addr", "localhost:19999", "containerz server address")
containerTar = flag.String("container_tar", "/tmp/cntrsrv.tar", "The container tarball to deploy.")
containerUpgradeTar = flag.String("container_upgrade_tar", "/tmp/cntrsrv-upgrade.tar", "The container tarball to upgrade to.")
containerzAddr = flag.String("containerz_addr", "localhost:19999", "containerz server address")
)

// TestDeployAndStartContainer implements CNTR-1.1 validating that it is
// possible deploy and start a container via containerz.
func TestDeployAndStartContainer(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
const (
instanceName = "test-instance"
)

func containerzClient(ctx context.Context, t *testing.T) *client.Client {
client.Dial = func(ctx context.Context, target string, opts ...grpc.DialOption) (conn *grpc.ClientConn, err error) {
return grpc.DialContext(ctx, target, grpc.WithTransportCredentials(insecure.NewCredentials()))
}
cli, err := client.NewClient(ctx, *containerzAddr)
if err != nil {
t.Fatalf("unable to dial containerz: %v", err)
}

return cli
}

func startContainer(ctx context.Context, t *testing.T) *client.Client {
cli := containerzClient(ctx, t)

progCh, err := cli.PushImage(ctx, "cntrsrv", "latest", *containerTar)
if err != nil {
t.Fatalf("unable to push image: %v", err)
Expand All @@ -45,18 +56,35 @@ func TestDeployAndStartContainer(t *testing.T) {
}
}

ret, err := cli.StartContainer(ctx, "cntrsrv", "latest", "./cntrsrv", "test-instance", client.WithPorts([]string{"60061:60061"}))
ret, err := cli.StartContainer(ctx, "cntrsrv", "latest", "./cntrsrv", instanceName, client.WithPorts([]string{"60061:60061"}))
if err != nil {
t.Fatalf("unable to start container: %v", err)
}

// wait for cntr container to come up.
time.Sleep(5 * time.Second)
t.Logf("Started %s", ret)

return cli
}

func stopContainer(ctx context.Context, t *testing.T, cli *client.Client) {
if err := cli.StopContainer(ctx, instanceName, true); err != nil {
t.Logf("container already stopping: %v", err)
}
}

// TestDeployAndStartContainer implements CNTR-1.1 validating that it is
// possible deploy and start a container via containerz.
func TestDeployAndStartContainer(t *testing.T) {
ctx := context.Background()
cli := startContainer(ctx, t)
defer stopContainer(ctx, t, cli)

tlsc := credentials.NewTLS(&tls.Config{
InsecureSkipVerify: true, // NOLINT
})
conntectionState := connectivity.Ready
conn, err := grpc.NewClient("localhost:60061", grpc.WithTransportCredentials(tlsc))
conn.WaitForStateChange(ctx, conntectionState)
if err != nil {
t.Fatalf("Failed to dial cntrsrv, %v", err)
}
Expand All @@ -65,5 +93,155 @@ func TestDeployAndStartContainer(t *testing.T) {
if _, err = cntrCli.Ping(ctx, &cpb.PingRequest{}); err != nil {
t.Errorf("unable to reach cntrsrv: %v", err)
}
}

// TestRetrieveLogs implements CNTR-1.2 validating that logs can be retrieved from a
// running container.
func TestRetrieveLogs(t *testing.T) {
ctx := context.Background()
cli := startContainer(ctx, t)
defer stopContainer(ctx, t, cli)

logCh, err := cli.Logs(ctx, instanceName, false)
if err != nil {
t.Errorf("unable to obtain logs for %s: %v", instanceName, err)
}

var logs []string
for msg := range logCh {
logs = append(logs, msg.Msg)
if msg.Error != nil {
t.Errorf("logs returned an error: %v", err)
}
}

if len(logs) == 0 {
t.Errorf("no logs were returned")
}
}

// TestListContainers implements CNTR-1.3 validating listing running containers.
func TestListContainers(t *testing.T) {
ctx := context.Background()
cli := startContainer(ctx, t)
defer stopContainer(ctx, t, cli)

listCh, err := cli.ListContainer(ctx, true, 0, nil)
if err != nil {
t.Errorf("unable to list containers: %v", err)
}

wantCntrs := []string{"cntrsrv:latest"}
var gotCntrs []string

for cnt := range listCh {
gotCntrs = append(gotCntrs, cnt.ImageName)
}

if diff := cmp.Diff(wantCntrs, gotCntrs, cmpopts.SortSlices(func(l, r string) bool { return l < r })); diff != "" {
t.Errorf("ListContainer() returned diff (-want, +got):\n%s", diff)
}
}

// TestStopContainer implements CNTR-1.4 validating that stopping a container works as expected.
func TestStopContainer(t *testing.T) {
ctx := context.Background()
cli := startContainer(ctx, t)
stopContainer(ctx, t, cli)

// wait for container to stop
time.Sleep(2 * time.Second)

listCh, err := cli.ListContainer(ctx, true, 0, nil)
if err != nil {
t.Errorf("unable to list containers: %v", err)
}

for cntr := range listCh {
t.Errorf("StopContainer did not stop the container: %v", cntr)
}
}

func TestVolumes(t *testing.T) {
ctx := context.Background()
cli := containerzClient(ctx, t)

wantVolume := "my-vol"
gotVolume, err := cli.CreateVolume(ctx, "my-vol", "local", nil, nil)
if err != nil {
t.Errorf("unable to create volume: %v", err)
}
defer cli.RemoveVolume(ctx, "my-vol", true)

if wantVolume != gotVolume {
t.Errorf("incorrect volume name: want %s, got %s", wantVolume, gotVolume)
}

t.Logf("created volume %s", gotVolume)

volCh, err := cli.ListVolume(ctx, nil)
if err != nil {
t.Errorf("unable to list volumes: %v", err)
}

wantVolumes := []*client.VolumeInfo{
{
Name: "my-vol",
Driver: "local",
Options: map[string]string{"device": "", "o": "", "type": "none"},
},
}
var gotVolumes []*client.VolumeInfo
for vol := range volCh {
gotVolumes = append(gotVolumes, vol)
}

if diff := cmp.Diff(wantVolumes, gotVolumes, cmpopts.IgnoreFields(client.VolumeInfo{}, "CreationTime")); diff != "" {
t.Errorf("Volumes returned diff (-want, +got):\n%s", diff)
}
}

func TestUpgrade(t *testing.T) {
ctx := context.Background()
cli := startContainer(ctx, t)
defer stopContainer(ctx, t, cli)

progCh, err := cli.PushImage(ctx, "cntrsrv", "upgrade", *containerUpgradeTar)
if err != nil {
t.Fatalf("unable to push image: %v", err)
}

for prog := range progCh {
switch {
case prog.Error != nil:
t.Fatalf("failed to push image: %v", err)
case prog.Finished:
t.Logf("Pushed %s/%s\n", prog.Image, prog.Tag)
default:
t.Logf(" %d bytes pushed", prog.BytesReceived)
}
}

_, err = cli.UpdateContainer(ctx, "cntrsrv", "upgrade", "./cntrsrv", instanceName, false, client.WithPorts([]string{"60061:60061"}))
if err != nil {
t.Errorf("unable to upgrade container: %v", err)
}

time.Sleep(3 * time.Second)

listCh, err := cli.ListContainer(ctx, true, 0, nil)
if err != nil {
t.Errorf("unable to list containers: %v", err)
}

wantCntrs := []string{"cntrsrv:upgrade"}
var gotCntrs []string

for cnt := range listCh {
gotCntrs = append(gotCntrs, cnt.ImageName)
}

if diff := cmp.Diff(wantCntrs, gotCntrs, cmpopts.SortSlices(func(l, r string) bool { return l < r })); diff != "" {
t.Errorf("ListContainer() returned diff (-want, +got):\n%s", diff)
}
}
38 changes: 20 additions & 18 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ require (
github.com/cisco-open/go-p4 v0.1.2
github.com/go-git/go-billy/v5 v5.5.0
github.com/go-git/go-git/v5 v5.11.0
github.com/golang/glog v1.2.1
github.com/golang/glog v1.2.2
github.com/google/go-cmp v0.6.0
github.com/google/go-github/v50 v50.1.0
github.com/google/gopacket v1.1.19
github.com/google/uuid v1.6.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/kr/pretty v0.3.1
github.com/open-traffic-generator/snappi/gosnappi v1.3.0
github.com/openconfig/containerz v0.0.0-20240620162940-e0bf23af17d6
github.com/open-traffic-generator/snappi/gosnappi v1.13.0
github.com/openconfig/containerz v0.0.0-20240926173756-5ea817752106
github.com/openconfig/entity-naming v0.0.0-20230912181021-7ac806551a31
github.com/openconfig/gnmi v0.11.0
github.com/openconfig/gnoi v0.4.1
github.com/openconfig/gnoi v0.5.0
github.com/openconfig/gnoigo v0.0.0-20240320202954-ebd033e3542c
github.com/openconfig/gnsi v1.6.0
github.com/openconfig/gocloser v0.0.0-20220310182203-c6c950ed3b0b
Expand All @@ -45,24 +45,24 @@ require (
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8
golang.org/x/text v0.18.0
google.golang.org/api v0.171.0
google.golang.org/grpc v1.66.2
google.golang.org/grpc v1.67.0
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/klog/v2 v2.120.1
)

require (
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/semver/v3 v3.3.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
golang.org/x/oauth2 v0.21.0
golang.org/x/oauth2 v0.22.0
)

require (
bitbucket.org/creachadair/stringset v0.0.14 // indirect
cel.dev/expr v0.15.0 // indirect
cel.dev/expr v0.16.0 // indirect
cloud.google.com/go v0.112.1 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/compute/metadata v0.5.0 // indirect
cloud.google.com/go/iam v1.1.6 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
Expand All @@ -72,21 +72,21 @@ require (
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect
github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
github.com/creack/pty v1.1.18 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/drivenets/cdnos-controller v1.7.4 // indirect
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
github.com/envoyproxy/go-control-plane v0.13.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
Expand All @@ -100,6 +100,7 @@ require (
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down Expand Up @@ -146,10 +147,10 @@ require (
github.com/xanzy/ssh-agent v0.3.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.18.0 // indirect
Expand All @@ -160,8 +161,9 @@ require (
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
Expand Down
Loading

0 comments on commit f407f27

Please sign in to comment.