-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of remaining containerz tests. #3477
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
``` | ||
|
||
|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding something that defines what "upgraded" means? |
||
|
||
## OpenConfig Path and RPC Coverage | ||
|
||
The below yaml defines the RPCs intended to be covered by this test. | ||
|
@@ -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 | ||||
---|---|---|---|---|---|---|
|
@@ -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) | ||||||
|
@@ -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) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I presume there's nothing fancier we can do to determine whether this container is alive? Is this the one that implements |
||||||
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) | ||||||
} | ||||||
|
@@ -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 { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I presume that the container here is specified to create some logs so there's no chance that this is a flake? |
||||||
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) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a comment here? I think it'd be worth just noting that the test here ensures that a volume can be created and removed from an API perspective -- it doesn't check that it's possible to actually use that volume. |
||||||
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"})) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
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) | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.