From 86b62b86d8b2b30648e5bcb1f4a4448eb99ce6ef Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Wed, 18 Jan 2023 07:36:00 +0000 Subject: [PATCH] Extend checkpoint e2e test to check for results When the e2e_node/checkpoint_container.go test was introduced no CRI implementation supported the new CheckpointContainer RPC yet. With the release of CRI-O 1.25 the CheckpointContainer is implemented and the test has been extended to see if the content of the checkpoint is as expected. The test is skipped if the ContainerCheckpoint feature gate is disabled or if the CRI implementation does not support the CheckpointContainer RPC. Signed-off-by: Adrian Reber --- test/e2e_node/checkpoint_container.go | 55 +++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/test/e2e_node/checkpoint_container.go b/test/e2e_node/checkpoint_container.go index a409a0c4ca9..a86c02ad52a 100644 --- a/test/e2e_node/checkpoint_container.go +++ b/test/e2e_node/checkpoint_container.go @@ -17,9 +17,13 @@ limitations under the License. package e2enode import ( + "archive/tar" "context" + "encoding/json" "fmt" + "io" "net/http" + "os" "strings" "time" @@ -41,6 +45,10 @@ const ( proxyTimeout = 2 * time.Minute ) +type checkpointResult struct { + Items []string `json:"items"` +} + // proxyPostRequest performs a post on a node proxy endpoint given the nodename and rest client. func proxyPostRequest(ctx context.Context, c clientset.Interface, node, endpoint string, port int) (restclient.Result, error) { // proxy tends to hang in some cases when Node is not ready. Add an artificial timeout for this call. #22165 @@ -150,10 +158,51 @@ var _ = SIGDescribe("Checkpoint Container [NodeFeature:CheckpointContainer]", fu } framework.ExpectNoError(err) - // TODO: once a container engine implements the Checkpoint CRI API this needs - // to be extended to handle it. - // + // Checkpointing actually worked. Verify that the checkpoint exists and that // it is a checkpoint. + + raw, err := result.Raw() + framework.ExpectNoError(err) + answer := checkpointResult{} + err = json.Unmarshal(raw, &answer) + framework.ExpectNoError(err) + + for _, item := range answer.Items { + // Check that the file exists + _, err := os.Stat(item) + framework.ExpectNoError(err) + // Check the content of the tar file + // At least looking for the following files + // * spec.dump + // * config.dump + // * checkpoint/inventory.img + // If these files exist in the checkpoint archive it is + // probably a complete checkpoint. + checkForFiles := map[string]bool{ + "spec.dump": false, + "config.dump": false, + "checkpoint/inventory.img": false, + } + fileReader, err := os.Open(item) + framework.ExpectNoError(err) + tr := tar.NewReader(fileReader) + for { + hdr, err := tr.Next() + if err == io.EOF { + // End of archive + break + } + framework.ExpectNoError(err) + if _, key := checkForFiles[hdr.Name]; key { + checkForFiles[hdr.Name] = true + } + } + for fileName := range checkForFiles { + framework.ExpectEqual(checkForFiles[fileName], true) + } + // cleanup checkpoint archive + os.RemoveAll(item) + } }) })