From 4108c97ffe41ef81d5cce5a0e67ee0b8678b3e77 Mon Sep 17 00:00:00 2001 From: Dimitar Dimitrov Date: Mon, 6 Feb 2023 13:09:59 +0200 Subject: [PATCH] Provide integration test for the CLI sysinfo, logs and update commands (#125) [#119] Provide integration test for the CLI sysinfo, logs and update commands - added integration tests for sysinfo, update and logs CLI commands - implemented custom result function for logs command - fixed stop_invalid_id test Signed-off-by: Dimitar Dimitrov --- integration/framework/cli/cmd_base.go | 3 +- integration/framework/cli/cmd_base_api.go | 5 ++ .../framework/cli/cmd_base_custom_result.go | 39 +++++++++ integration/testdata/logs-help.golden | 19 +++++ integration/testdata/logs-test.yaml | 84 +++++++++++++++++++ integration/testdata/stop-test.yaml | 2 +- integration/testdata/sysinfo-help.golden | 15 ++++ integration/testdata/sysinfo-test.yaml | 17 ++++ integration/testdata/update-help.golden | 33 ++++++++ integration/testdata/update-test.yaml | 76 +++++++++++++++++ 10 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 integration/testdata/logs-help.golden create mode 100644 integration/testdata/logs-test.yaml create mode 100644 integration/testdata/sysinfo-help.golden create mode 100644 integration/testdata/sysinfo-test.yaml create mode 100644 integration/testdata/update-help.golden create mode 100644 integration/testdata/update-test.yaml diff --git a/integration/framework/cli/cmd_base.go b/integration/framework/cli/cmd_base.go index b6291c2..1985ae4 100644 --- a/integration/framework/cli/cmd_base.go +++ b/integration/framework/cli/cmd_base.go @@ -31,7 +31,8 @@ import ( const TestData = "testdata" var customResultDefaultFns = map[string]func(result icmd.Result, args ...string) assert.BoolOrComparison{ - "REGEX": regex, + "REGEX": regex, + "LOGS_JSON": logs, } // TestCaseCMD represents a command and expected result diff --git a/integration/framework/cli/cmd_base_api.go b/integration/framework/cli/cmd_base_api.go index 97dbbb9..ab8cc6a 100644 --- a/integration/framework/cli/cmd_base_api.go +++ b/integration/framework/cli/cmd_base_api.go @@ -49,6 +49,11 @@ type Expected struct { // customResult: // name: REGEX // args: ["([A-Za-z0-9]+(-[A-Za-z0-9]+)+)"] +// - LOGS_JSON - this function will validate that the stdout outputs consist of valid JSON entries and compare their count to args[0] if provided. +// example: +// customResult: +// name: LOGS_JSON +// args: ["5"] type CustomResult struct { Type string `yaml:"type"` Args []string `yaml:"args"` diff --git a/integration/framework/cli/cmd_base_custom_result.go b/integration/framework/cli/cmd_base_custom_result.go index 26ab939..e19a1e4 100644 --- a/integration/framework/cli/cmd_base_custom_result.go +++ b/integration/framework/cli/cmd_base_custom_result.go @@ -13,10 +13,14 @@ package framework import ( + "encoding/json" "errors" "fmt" "regexp" + "strconv" + "strings" + "github.com/eclipse-kanto/container-management/containerm/log" "gotest.tools/v3/assert" "gotest.tools/v3/icmd" ) @@ -41,3 +45,38 @@ func checkRegex(r *regexp.Regexp, s string) assert.BoolOrComparison { } return true } + +func logs(result icmd.Result, args ...string) assert.BoolOrComparison { + var ( + expectedLogEntries int + err error + ) + if len(args) > 0 { + expectedLogEntries, err = strconv.Atoi(args[0]) + if err != nil { + return err + } + } + + var logEntriesCount int + if result.Stdout() != "" { + lines := strings.Split(result.Stdout(), "\n") + for _, l := range lines { + if len(l) == 0 { + continue + } + var x map[string]interface{} + if err := json.Unmarshal([]byte(l), &x); err != nil { + return err + } + logEntriesCount++ + } + } + + if len(args) > 0 { + if logEntriesCount != expectedLogEntries { + return log.NewErrorf("unexpected number of log entries: %d", logEntriesCount) + } + } + return true +} diff --git a/integration/testdata/logs-help.golden b/integration/testdata/logs-help.golden new file mode 100644 index 0000000..b048f94 --- /dev/null +++ b/integration/testdata/logs-help.golden @@ -0,0 +1,19 @@ +Print the logs for a container. + +Usage: + kanto-cm logs + +Examples: +logs +logs --name +logs -n + +Flags: + -h, --help help for logs + -n, --name string Print the logs of a container with a specific name. + -t, --tail int32 Lines of recent log file to display. Setting it to -1 will return all logs. (default 100) + +Global Flags: + --debug Switch commands log level to DEBUG mode + --host string Specify the address path to the Eclipse Kanto container management (default "/run/container-management/container-management.sock") + --timeout int Specify the connection timeout in seconds to the Eclipse Kanto container management (default 30) diff --git a/integration/testdata/logs-test.yaml b/integration/testdata/logs-test.yaml new file mode 100644 index 0000000..a24e46c --- /dev/null +++ b/integration/testdata/logs-test.yaml @@ -0,0 +1,84 @@ +name: logs_help +command: + binary: kanto-cm + args: ["logs", "-h"] +expected: + exitCode: 0 +goldenFile: "logs-help.golden" +--- +name: logs_no_args +command: + binary: kanto-cm + args: ["logs"] +expected: + exitCode: 1 + err: "Error: You must provide either an ID or a name for the container via --name (-n)" +--- +name: logs_invalid_id +command: + binary: kanto-cm + args: ["logs", "invalid"] +expected: + exitCode: 1 + err: "Error: The requested container with ID = invalid was not found." +--- +name: logs_invalid_name +command: + binary: kanto-cm + args: ["logs", "-n", "invalid"] +expected: + exitCode: 1 + err: "Error: The requested container with name = invalid was not found. Try using an ID instead." +--- +name: logs_of_container_with_state_created +setupCmd: + - binary: kanto-cm + args: ["create", "--host", "$KANTO_HOST", "-n", "test-it", "docker.io/library/influxdb:1.8.4"] +command: + binary: kanto-cm + args: ["logs", "-n", "test-it"] +expected: + exitCode: 1 + err: "Error: rpc error: code = Unknown desc = there are no logs for container with status \"Created\"" +onExit: + - binary: "kanto-cm" + args: ["remove","--host", "$KANTO_HOST", "-n", "test-it", "-f"] +--- +name: logs_of_container_with_state_running +setupCmd: + - binary: kanto-cm + args: ["create", "--host", "$KANTO_HOST", "-n", "test-it", "docker.io/library/influxdb:1.8.4"] + - binary: kanto-cm + args: ["start", "-n", "test-it"] + - binary: sleep + args: ["2"] +command: + binary: kanto-cm + args: ["logs", "-n", "test-it", "-t", "5"] +expected: + exitCode: 0 +customResult: + type: LOGS_JSON + args: ["5"] +onExit: + - binary: "kanto-cm" + args: ["remove","--host", "$KANTO_HOST", "-n", "test-it", "-f"] +--- +name: logs_of_container_with_state_stopped +setupCmd: + - binary: kanto-cm + args: ["create", "--host", "$KANTO_HOST", "-n", "test-it", "docker.io/library/influxdb:1.8.4"] + - binary: kanto-cm + args: ["start", "-n", "test-it"] + - binary: kanto-cm + args: ["stop", "-n", "test-it"] +command: + binary: kanto-cm + args: ["logs", "-n", "test-it"] +expected: + exitCode: 0 +customResult: + type: LOGS_JSON +onExit: + - binary: "kanto-cm" + args: ["remove","--host", "$KANTO_HOST", "-n", "test-it", "-f"] \ No newline at end of file diff --git a/integration/testdata/stop-test.yaml b/integration/testdata/stop-test.yaml index 115d2d0..d99e2ce 100644 --- a/integration/testdata/stop-test.yaml +++ b/integration/testdata/stop-test.yaml @@ -17,7 +17,7 @@ expected: name: stop_invalid_id command: binary: kanto-cm - args: ["start", "invalid"] + args: ["stop", "invalid"] expected: exitCode: 1 err: "Error: The requested container with ID = invalid was not found." diff --git a/integration/testdata/sysinfo-help.golden b/integration/testdata/sysinfo-help.golden new file mode 100644 index 0000000..09c2498 --- /dev/null +++ b/integration/testdata/sysinfo-help.golden @@ -0,0 +1,15 @@ +Show information about the container management runtime and its environment. + +Usage: + kanto-cm sysinfo + +Examples: +sysinfo + +Flags: + -h, --help help for sysinfo + +Global Flags: + --debug Switch commands log level to DEBUG mode + --host string Specify the address path to the Eclipse Kanto container management (default "/run/container-management/container-management.sock") + --timeout int Specify the connection timeout in seconds to the Eclipse Kanto container management (default 30) diff --git a/integration/testdata/sysinfo-test.yaml b/integration/testdata/sysinfo-test.yaml new file mode 100644 index 0000000..4a1e7d1 --- /dev/null +++ b/integration/testdata/sysinfo-test.yaml @@ -0,0 +1,17 @@ +name: sysinfo_help +command: + binary: kanto-cm + args: ["sysinfo", "-h"] +expected: + exitCode: 0 +goldenFile: "sysinfo-help.golden" +--- +name: sysinfo +command: + binary: kanto-cm + args: ["sysinfo"] +expected: + exitCode: 0 +customResult: + type: REGEX + args: ["Engine v[^ ]*, API v[^ ]*, \\(build [^ ]* [^ ]*\\) [\\r?\\n]CLI v[^ ]*, API v[^ ]*, \\(build [^ ]* [^ ]*\\) [\\r?\\n]"] \ No newline at end of file diff --git a/integration/testdata/update-help.golden b/integration/testdata/update-help.golden new file mode 100644 index 0000000..814f15c --- /dev/null +++ b/integration/testdata/update-help.golden @@ -0,0 +1,33 @@ +Update a container without recreating it. The provided configurations will be merged with the current one. + +Usage: + kanto-cm update + +Examples: +update +update -n + + +Flags: + -h, --help help for update + -m, --memory string Updates the max amount of memory the container can use in the form of 200m, 1.2g. + Use -1, to remove the memory usage limit. + --memory-reservation string Updates the soft memory limitation in the form of 200m, 1.2g. + Use -1, to remove the reservation memory limit. + --memory-swap string Updates the total amount of memory + swap that the container can use in the form of 200m, 1.2g. + Use -1, to remove the swap memory limit. + -n, --name string Updates the container with a specific name. + --rp string Updates the restart policy for the container. The policy will be applied when the container exits. Supported restart policies are - no, always, unless-stopped, on-failure. + no - no attempts to restart the container for any reason will be made + always - an attempt to restart the container will be made each time the container exits regardless of the exit code + unless-stopped - restart attempts will be made only if the container has not been stopped by the user + on-failure - restart attempts will be made if the container exits with an exit code != 0; + the additional flags (--rp-cnt and --rp-to) apply only for this policy; if max retry count is not provided - the system will retry until it succeeds endlessly + + --rp-cnt int Updates the number of retries that will be made to restart the container on exit if the policy is on-failure (default -2147483648) + --rp-to int Updates the time out period in seconds for each retry that will be made to restart the container on exit if the policy is set to on-failure (default -9223372036854775808) + +Global Flags: + --debug Switch commands log level to DEBUG mode + --host string Specify the address path to the Eclipse Kanto container management (default "/run/container-management/container-management.sock") + --timeout int Specify the connection timeout in seconds to the Eclipse Kanto container management (default 30) diff --git a/integration/testdata/update-test.yaml b/integration/testdata/update-test.yaml new file mode 100644 index 0000000..5e00b62 --- /dev/null +++ b/integration/testdata/update-test.yaml @@ -0,0 +1,76 @@ +name: update_help +command: + binary: kanto-cm + args: ["update", "-h"] +expected: + exitCode: 0 +goldenFile: "update-help.golden" +--- +name: update_no_args +command: + binary: kanto-cm + args: ["update"] +expected: + exitCode: 1 + err: "Error: You must provide either an ID or a name for the container via --name (-n)" +--- +name: update_invalid_id +command: + binary: kanto-cm + args: ["update", "invalid"] +expected: + exitCode: 1 + err: "Error: The requested container with ID = invalid was not found." +--- +name: update_invalid_name +command: + binary: kanto-cm + args: ["update", "-n", "invalid"] +expected: + exitCode: 1 + err: "Error: The requested container with name = invalid was not found. Try using an ID instead." +--- +name: update_container_with_state_running +setupCmd: + - binary: kanto-cm + args: ["create", "--host", "$KANTO_HOST", "-n", "test-it", "docker.io/library/influxdb:1.8.4"] + - binary: kanto-cm + args: ["start", "-n", "test-it"] +command: + binary: kanto-cm + args: ["update", "-n", "test-it", "--rp", "no"] +expected: + exitCode: 0 +onExit: + - binary: "kanto-cm" + args: ["remove","--host", "$KANTO_HOST", "-n", "test-it", "-f"] +--- +name: update_container_with_state_created +setupCmd: + - binary: kanto-cm + args: ["create", "--host", "$KANTO_HOST", "-n", "test-it", "docker.io/library/influxdb:1.8.4"] +command: + binary: kanto-cm + args: ["update", "-n", "test-it", "--rp", "no"] +expected: + exitCode: 0 +onExit: + - binary: "kanto-cm" + args: ["remove","--host", "$KANTO_HOST", "-n", "test-it", "-f"] +--- +name: update_container_with_state_stopped +setupCmd: + - binary: kanto-cm + args: ["create", "--host", "$KANTO_HOST", "-n", "test-it", "docker.io/library/influxdb:1.8.4"] + - binary: kanto-cm + args: [ "start", "-n", "test-it" ] + - binary: kanto-cm + args: [ "stop", "-n", "test-it" ] +command: + binary: kanto-cm + args: ["update", "-n", "test-it", "--rp", "no"] +expected: + exitCode: 0 +onExit: + - binary: "kanto-cm" + args: ["remove","--host", "$KANTO_HOST", "-n", "test-it", "-f"] \ No newline at end of file