-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(e2e): add CLI test for pkg update (#405)
Reviewed-by: Cezar Craciunoiu <[email protected]> Reviewed-by: Alexander Jung <[email protected]> Approved-by: Alexander Jung <[email protected]>
- Loading branch information
Showing
10 changed files
with
570 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
// Copyright (c) 2023, Unikraft GmbH and The KraftKit Authors. | ||
// Licensed under the BSD-3-Clause License (the "License"). | ||
// You may not use this file except in compliance with the License. | ||
|
||
package cli_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo/v2" //nolint:stylecheck | ||
. "github.com/onsi/gomega" //nolint:stylecheck | ||
|
||
"sigs.k8s.io/kustomize/kyaml/yaml" | ||
|
||
fcmd "kraftkit.sh/test/e2e/framework/cmd" | ||
fcfg "kraftkit.sh/test/e2e/framework/config" | ||
. "kraftkit.sh/test/e2e/framework/matchers" //nolint:stylecheck | ||
) | ||
|
||
var _ = Describe("kraft pkg", func() { | ||
var cmd *fcmd.Cmd | ||
|
||
var stdout *fcmd.IOStream | ||
var stderr *fcmd.IOStream | ||
|
||
var cfg *fcfg.Config | ||
|
||
BeforeEach(func() { | ||
stdout = fcmd.NewIOStream() | ||
stderr = fcmd.NewIOStream() | ||
|
||
cfg = fcfg.NewTempConfig() | ||
|
||
cmd = fcmd.NewKraft(stdout, stderr, cfg.Path()) | ||
cmd.Args = append(cmd.Args, "pkg") | ||
}) | ||
|
||
_ = Describe("update", func() { | ||
var manifestsPath string | ||
|
||
BeforeEach(func() { | ||
cmd.Args = append(cmd.Args, "update") | ||
|
||
manifestsPath = yaml.GetValue(cfg.Read("paths", "manifests")) | ||
Expect(manifestsPath).To(SatisfyAny( | ||
Not(BeAnExistingFile()), | ||
BeAnEmptyDirectory(), | ||
), "manifests directory should either be empty or not yet created") | ||
}) | ||
|
||
Context("implicitly using the default manager type (manifest)", func() { | ||
When("invoked without flags or positional arguments", func() { | ||
It("should retrieve the list of components, libraries and packages", func() { | ||
err := cmd.Run() | ||
Expect(err).ToNot(HaveOccurred()) | ||
|
||
Expect(stderr.String()).To(BeEmpty()) | ||
// The command sends ANSI escape sequences while updating, such as `\e[2K` (erase entire line). | ||
// References: | ||
// https://www.regular-expressions.info/nonprint.html | ||
// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 | ||
Expect(stdout.String()).To(MatchRegexp(`\x1b\[2K\[\+\] Updating\.\.\. \[\d+\.\d+s\]\r\n`), "Quoted output: %q", stdout) | ||
|
||
Expect(manifestsPath).To(ContainFiles("index.yaml", "unikraft.yaml")) | ||
Expect(manifestsPath).To(ContainDirectories("libs")) | ||
}) | ||
}) | ||
|
||
When("invoked with the --help flag", func() { | ||
BeforeEach(func() { | ||
cmd.Args = append(cmd.Args, "--help") | ||
}) | ||
|
||
It("should print the command's help", func() { | ||
err := cmd.Run() | ||
Expect(err).ToNot(HaveOccurred()) | ||
|
||
Expect(stderr.String()).To(BeEmpty()) | ||
Expect(stdout).To(MatchRegexp(`^Retrieve new lists of Unikraft components, libraries and packages.\n`)) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
// Copyright (c) 2023, Unikraft GmbH and The KraftKit Authors. | ||
// Licensed under the BSD-3-Clause License (the "License"). | ||
// You may not use this file except in compliance with the License. | ||
|
||
package matchers | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/onsi/gomega/format" | ||
"github.com/onsi/gomega/types" | ||
) | ||
|
||
// beAnEmptyDirectoryMatcher asserts that an existing directory is empty. | ||
type beAnEmptyDirectoryMatcher struct { | ||
err error | ||
} | ||
|
||
var _ types.GomegaMatcher = (*beAnEmptyDirectoryMatcher)(nil) | ||
|
||
func (matcher *beAnEmptyDirectoryMatcher) Match(actual any) (success bool, err error) { | ||
actualDirName, ok := actual.(string) | ||
if !ok { | ||
return false, fmt.Errorf("BeAnEmptyDirectory matcher expects a directory path") | ||
} | ||
|
||
dirEntries, err := os.ReadDir(actualDirName) | ||
if err != nil { | ||
matcher.err = fmt.Errorf("reading directory entries: %w", err) | ||
return false, nil | ||
} | ||
|
||
n := len(dirEntries) | ||
hasEntries := n > 0 | ||
|
||
if hasEntries { | ||
matcher.err = fmt.Errorf("directory contains %d entries", n) | ||
} | ||
|
||
return !hasEntries, nil | ||
} | ||
|
||
func (matcher *beAnEmptyDirectoryMatcher) FailureMessage(actual any) string { | ||
return format.Message(actual, fmt.Sprintf("to be an empty directory: %s", matcher.err)) | ||
} | ||
|
||
func (*beAnEmptyDirectoryMatcher) NegatedFailureMessage(actual any) string { | ||
return format.Message(actual, "not be an empty directory") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
// Copyright (c) 2023, Unikraft GmbH and The KraftKit Authors. | ||
// Licensed under the BSD-3-Clause License (the "License"). | ||
// You may not use this file except in compliance with the License. | ||
|
||
package matchers_test | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"kraftkit.sh/test/e2e/framework/matchers" | ||
) | ||
|
||
func TestBeAnEmptyDirectoryMatcher(t *testing.T) { | ||
testCases := []struct { | ||
desc string | ||
files []fileEntry | ||
success bool | ||
}{ | ||
{ | ||
desc: "Directory is empty", | ||
files: []fileEntry{}, | ||
success: true, | ||
}, { | ||
desc: "Directory contains a file", | ||
files: []fileEntry{regular("f.txt")}, | ||
success: false, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
d := newDirectory(t, tc.files...) | ||
|
||
m := matchers.BeAnEmptyDirectory() | ||
success, err := m.Match(d) | ||
if err != nil { | ||
t.Fatal("Failed to run matcher:", err) | ||
} | ||
|
||
if tc.success && !success { | ||
t.Error("Expected the matcher to succeed. Failure was:", m.FailureMessage(d)) | ||
} else if !tc.success && success { | ||
t.Error("Expected the matcher to fail") | ||
} | ||
}) | ||
} | ||
|
||
t.Run("Directory does not exist", func(t *testing.T) { | ||
d := newDirectory(t) | ||
if err := os.RemoveAll(d); err != nil { | ||
t.Fatal("Failed to remove temporary directory:", err) | ||
} | ||
|
||
m := matchers.BeAnEmptyDirectory() | ||
success, err := m.Match(d) | ||
if err != nil { | ||
t.Fatal("Failed to run matcher:", err) | ||
} | ||
|
||
if success { | ||
t.Error("Expected the matcher to fail") | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
// Copyright (c) 2023, Unikraft GmbH and The KraftKit Authors. | ||
// Licensed under the BSD-3-Clause License (the "License"). | ||
// You may not use this file except in compliance with the License. | ||
|
||
package matchers | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/onsi/gomega/format" | ||
"github.com/onsi/gomega/types" | ||
) | ||
|
||
// containDirectoriesMatcher asserts that a directory contains sub-directories | ||
// with provided names. | ||
type containDirectoriesMatcher struct { | ||
dirNames []string | ||
err error | ||
} | ||
|
||
var _ types.GomegaMatcher = (*containDirectoriesMatcher)(nil) | ||
|
||
func (matcher *containDirectoriesMatcher) Match(actual any) (success bool, err error) { | ||
actualDirName, ok := actual.(string) | ||
if !ok { | ||
return false, fmt.Errorf("ContainFiles matcher expects a directory path") | ||
} | ||
|
||
dirEntries, err := os.ReadDir(actualDirName) | ||
if err != nil { | ||
matcher.err = fmt.Errorf("reading directory entries: %w", err) | ||
return false, nil | ||
} | ||
|
||
if n, nExpect := len(dirEntries), len(matcher.dirNames); n < nExpect { | ||
matcher.err = fmt.Errorf("directory contains less entries (%d) than provided sub-directories names (%d)", n, nExpect) | ||
return false, nil | ||
} | ||
|
||
for _, fn := range matcher.dirNames { | ||
fi, err := os.Stat(filepath.Join(actualDirName, fn)) | ||
if err != nil { | ||
matcher.err = fmt.Errorf("reading file info: %w", err) | ||
return false, nil | ||
} | ||
|
||
if !fi.IsDir() { | ||
matcher.err = fmt.Errorf("file %q is not a directory (type: %s)", fi.Name(), fi.Mode().Type()) | ||
return false, nil | ||
} | ||
} | ||
|
||
return true, nil | ||
} | ||
|
||
func (matcher *containDirectoriesMatcher) FailureMessage(actual any) string { | ||
return format.Message(actual, fmt.Sprintf("to contain the directories with the provided names: %s", matcher.err)) | ||
} | ||
|
||
func (*containDirectoriesMatcher) NegatedFailureMessage(actual any) string { | ||
return format.Message(actual, "not contain the directories with the provided names") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
// Copyright (c) 2023, Unikraft GmbH and The KraftKit Authors. | ||
// Licensed under the BSD-3-Clause License (the "License"). | ||
// You may not use this file except in compliance with the License. | ||
|
||
package matchers_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"kraftkit.sh/test/e2e/framework/matchers" | ||
) | ||
|
||
func TestContainDirectoriesMatcher(t *testing.T) { | ||
const d1 = "d1" | ||
const d2 = "d2" | ||
|
||
testCases := []struct { | ||
desc string | ||
files []fileEntry | ||
success bool | ||
}{ | ||
{ | ||
desc: "All directories exist", | ||
files: []fileEntry{dir(d1), dir(d2), dir("other")}, | ||
success: true, | ||
}, { | ||
desc: "One directory is missing", | ||
files: []fileEntry{dir(d1), dir("other1"), dir("other2")}, | ||
success: false, | ||
}, { | ||
desc: "All directories are missing", | ||
files: []fileEntry{dir("other1"), dir("other2")}, | ||
success: false, | ||
}, { | ||
desc: "One file is regular", | ||
files: []fileEntry{dir(d1), regular(d2)}, | ||
success: false, | ||
}, { | ||
desc: "One file is a symbolic link", | ||
files: []fileEntry{dir(d1), symlink(d2)}, | ||
success: false, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
d := newDirectory(t, tc.files...) | ||
|
||
m := matchers.ContainDirectories(d1, d2) | ||
success, err := m.Match(d) | ||
if err != nil { | ||
t.Fatal("Failed to run matcher:", err) | ||
} | ||
|
||
if tc.success && !success { | ||
t.Error("Expected the matcher to succeed. Failure was:", m.FailureMessage(d)) | ||
} else if !tc.success && success { | ||
t.Error("Expected the matcher to fail") | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.