Skip to content
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

test: change e2e tests to use new log format #3318

Merged
merged 16 commits into from
Dec 13, 2024
39 changes: 18 additions & 21 deletions src/test/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"bufio"
"errors"
"fmt"
"log/slog"
"os"
"regexp"
"runtime"
Expand All @@ -19,6 +20,7 @@ import (
"github.com/defenseunicorns/pkg/helpers/v2"
_ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory" // used for docker test registry
"github.com/stretchr/testify/require"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/pkg/utils/exec"
)

Expand All @@ -30,7 +32,19 @@ type ZarfE2ETest struct {
ApplianceModeKeep bool
}

var logRegex = regexp.MustCompile(`Saving log file to (?P<logFile>.*?\.log)`)
// GetLogger returns the default log configuration for the tests.
func GetLogger(t *testing.T) *slog.Logger {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

t.Helper()
cfg := logger.Config{
Level: logger.Info,
Format: logger.FormatConsole,
Destination: logger.DestinationDefault, // Stderr
Color: false,
}
l, err := logger.New(cfg)
require.NoError(t, err)
return l
}

// GetCLIName looks at the OS and CPU architecture to determine which Zarf binary needs to be run.
func GetCLIName() string {
Expand Down Expand Up @@ -60,6 +74,9 @@ func (e2e *ZarfE2ETest) Zarf(t *testing.T, args ...string) (_ string, _ string,

// ZarfInDir executes a Zarf command in specific directory.
func (e2e *ZarfE2ETest) ZarfInDir(t *testing.T, dir string, args ...string) (_ string, _ string, err error) {
if !slices.Contains(args, "tools") {
args = append(args, "--log-format=console", "--no-color")
}
if !slices.Contains(args, "--tmpdir") && !slices.Contains(args, "tools") {
tmpdir, err := os.MkdirTemp("", "zarf-")
if err != nil {
Expand Down Expand Up @@ -119,16 +136,6 @@ func (e2e *ZarfE2ETest) GetMismatchedArch() string {
}
}

// GetLogFileContents gets the log file contents from a given run's std error.
func (e2e *ZarfE2ETest) GetLogFileContents(t *testing.T, stdErr string) string {
get, err := helpers.MatchRegex(logRegex, stdErr)
require.NoError(t, err)
logFile := get("logFile")
logContents, err := os.ReadFile(logFile)
require.NoError(t, err)
return string(logContents)
}

// GetZarfVersion returns the current build/zarf version
func (e2e *ZarfE2ETest) GetZarfVersion(t *testing.T) string {
// Get the version of the CLI
Expand All @@ -137,16 +144,6 @@ func (e2e *ZarfE2ETest) GetZarfVersion(t *testing.T) string {
return strings.Trim(stdOut, "\n")
}

// StripMessageFormatting strips any ANSI color codes and extra spaces from a given string
func (e2e *ZarfE2ETest) StripMessageFormatting(input string) string {
// Regex to strip any color codes from the output - https://regex101.com/r/YFyIwC/2
ansiRegex := regexp.MustCompile(`\x1b\[(.*?)m`)
unAnsiInput := ansiRegex.ReplaceAllString(input, "")
// Regex to strip any more than two spaces or newline - https://regex101.com/r/wqQmys/1
multiSpaceRegex := regexp.MustCompile(`\s{2,}|\n`)
return multiSpaceRegex.ReplaceAllString(unAnsiInput, " ")
}

// NormalizeYAMLFilenames normalizes YAML filenames / paths across Operating Systems (i.e Windows vs Linux)
func (e2e *ZarfE2ETest) NormalizeYAMLFilenames(input string) string {
if runtime.GOOS != "windows" {
Expand Down
5 changes: 2 additions & 3 deletions src/test/e2e/00_use_cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestUseCLI(t *testing.T) {
// Test that excluding all components with a leading dash results in a warning
_, stdErr, err := e2e.Zarf(t, "package", "deploy", path, "--components=-deselect-me", "--confirm")
require.NoError(t, err)
require.Contains(t, stdErr, "No components were selected for deployment")
require.Contains(t, stdErr, "no components were selected for deployment")

// Test that excluding still works even if a wildcard is given
_, stdErr, err = e2e.Zarf(t, "package", "deploy", path, "--components=*,-deselect-me", "--confirm")
Expand All @@ -112,7 +112,7 @@ func TestUseCLI(t *testing.T) {
// Test that changing the log level actually applies the requested level
_, stdErr, err := e2e.Zarf(t, "internal", "crc32", "zarf", "--log-level=debug")
require.NoError(t, err)
expectedOutString := "Log level set to debug"
expectedOutString := "cfg.level=debug"
require.Contains(t, stdErr, expectedOutString, "The log level should be changed to 'debug'")
})

Expand Down Expand Up @@ -192,7 +192,6 @@ func TestUseCLI(t *testing.T) {
})
stdOut, stdErr, err := e2e.Zarf(t, "tools", "gen-pki", "github.com", "--sub-alt-name", "google.com")
require.NoError(t, err, stdOut, stdErr)
require.Contains(t, stdErr, "Successfully created a chain of trust for github.com")

require.FileExists(t, tlsCA)

Expand Down
4 changes: 2 additions & 2 deletions src/test/e2e/02_component_actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func TestComponentActions(t *testing.T) {
// Try creating the package to test the onCreate actions.
stdOut, stdErr, err := e2e.Zarf(t, "package", "create", "examples/component-actions", "--confirm")
require.NoError(t, err, stdOut, stdErr)
require.Contains(t, stdErr, "Completed \"Create a test file\"")
require.Contains(t, stdErr, "Completed \"touch test-create-after.txt\"")
require.Contains(t, stdErr, "action succeeded cmd=Create a test file")
require.Contains(t, stdErr, "action succeeded cmd=touch test-create-after.txt")
require.Contains(t, stdErr, "multiline!")
require.Contains(t, stdErr, "updates!")
require.Contains(t, stdErr, "realtime!")
Expand Down
2 changes: 1 addition & 1 deletion src/test/e2e/08_create_differential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestCreateDifferential(t *testing.T) {
// Build the differential package without changing the version
_, stdErr, err = e2e.Zarf(t, "package", "create", packagePath, "--set=PACKAGE_VERSION=v0.25.0", differentialFlag, "--confirm")
require.Error(t, err, "zarf package create should have errored when a differential package was being created without updating the package version number")
require.Contains(t, e2e.StripMessageFormatting(stdErr), lang.PkgCreateErrDifferentialSameVersion)
require.Contains(t, stdErr, lang.PkgCreateErrDifferentialSameVersion)

// Build the differential package
stdOut, stdErr, err = e2e.Zarf(t, "package", "create", packagePath, "--set=PACKAGE_VERSION=v0.26.0", differentialFlag, "--confirm")
Expand Down
2 changes: 1 addition & 1 deletion src/test/e2e/09_component_compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,5 @@ func TestComposabilityBadLocalOS(t *testing.T) {
composeTestBadLocalOS := filepath.Join("src", "test", "packages", "09-composable-packages", "bad-local-os")
_, stdErr, err := e2e.Zarf(t, "package", "create", composeTestBadLocalOS, "-o", "build", "--no-color", "--confirm")
require.Error(t, err)
require.Contains(t, e2e.StripMessageFormatting(stdErr), "\"only.localOS\" \"linux\" cannot be redefined as \"windows\" during compose")
require.Contains(t, stdErr, "\"only.localOS\" \"linux\" cannot be redefined as \"windows\" during compose")
}
16 changes: 9 additions & 7 deletions src/test/e2e/12_lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"testing"

"github.com/stretchr/testify/require"
"github.com/zarf-dev/zarf/src/config/lang"
)

// TODO (@AustinAbro321) - remove this test in favor of unit testing lint.Validate
func TestLint(t *testing.T) {
t.Log("E2E: Lint")

Expand All @@ -31,12 +33,12 @@ func TestLint(t *testing.T) {
configPath := filepath.Join(testPackagePath, "zarf-config.toml")
osSetErr := os.Setenv("ZARF_CONFIG", configPath)
require.NoError(t, osSetErr, "Unable to set ZARF_CONFIG")
stdOut, stdErr, err := e2e.Zarf(t, "dev", "lint", testPackagePath, "-f", "good-flavor")
stdout, stderr, err := e2e.Zarf(t, "dev", "lint", testPackagePath, "-f", "good-flavor")
osUnsetErr := os.Unsetenv("ZARF_CONFIG")
require.NoError(t, osUnsetErr, "Unable to cleanup ZARF_CONFIG")
require.Error(t, err, "Require an exit code since there was warnings / errors")
strippedStdOut := e2e.StripMessageFormatting(stdOut)
strippedStdErr := e2e.StripMessageFormatting(stdErr)
multiSpaceRegex := regexp.MustCompile(`\s{2,}|\n`)
strippedStdOut := multiSpaceRegex.ReplaceAllString(stdout, " ")

key := "WHATEVER_IMAGE"
require.Contains(t, strippedStdOut, lang.UnsetVarLintWarning)
Expand All @@ -52,11 +54,11 @@ func TestLint(t *testing.T) {
require.Contains(t, strippedStdOut, ".components.[0].images.[0] | Image not pinned with digest - ghcr.io/zarf-dev/doom-game:0.0.1")

// Check flavors
require.NotContains(t, strippedStdOut, "image-in-bad-flavor-component:unpinned")
require.Contains(t, strippedStdOut, "image-in-good-flavor-component:unpinned")
require.NotContains(t, stdout, "image-in-bad-flavor-component:unpinned")
require.Contains(t, stdout, "image-in-good-flavor-component:unpinned")

// Check reported filepaths
require.Contains(t, strippedStdErr, "Linting package \"dos-games\" at oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0")
require.Contains(t, strippedStdErr, fmt.Sprintf("Linting package \"lint\" at %s", testPackagePath))
require.Contains(t, stderr, "linting package name=dos-games path=oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0")
require.Contains(t, stderr, fmt.Sprintf("linting package name=lint path=%s", testPackagePath))
})
}
12 changes: 6 additions & 6 deletions src/test/e2e/14_oci_compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import (
"github.com/stretchr/testify/suite"
"github.com/zarf-dev/zarf/src/api/v1alpha1"
"github.com/zarf-dev/zarf/src/pkg/layout"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/pkg/transform"
"github.com/zarf-dev/zarf/src/pkg/utils"
"github.com/zarf-dev/zarf/src/pkg/zoci"
"github.com/zarf-dev/zarf/src/test"
"github.com/zarf-dev/zarf/src/test/testutil"
corev1 "k8s.io/api/core/v1"
"oras.land/oras-go/v2/registry"
Expand Down Expand Up @@ -65,18 +67,15 @@ func (suite *PublishCopySkeletonSuite) Test_0_Publish_Skeletons() {
ref := suite.Reference.String()

helmCharts := filepath.Join("examples", "helm-charts")
_, stdErr, err := e2e.Zarf(suite.T(), "package", "publish", helmCharts, "oci://"+ref, "--plain-http")
_, _, err := e2e.Zarf(suite.T(), "package", "publish", helmCharts, "oci://"+ref, "--plain-http")
suite.NoError(err)
suite.Contains(stdErr, "Published "+ref)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to fewer suite.Contains


composable := filepath.Join("src", "test", "packages", "09-composable-packages")
_, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", composable, "oci://"+ref, "--plain-http")
_, _, err = e2e.Zarf(suite.T(), "package", "publish", composable, "oci://"+ref, "--plain-http")
suite.NoError(err)
suite.Contains(stdErr, "Published "+ref)

_, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", importEverything, "oci://"+ref, "--plain-http")
_, _, err = e2e.Zarf(suite.T(), "package", "publish", importEverything, "oci://"+ref, "--plain-http")
suite.NoError(err)
suite.Contains(stdErr, "Published "+ref)

_, _, err = e2e.Zarf(suite.T(), "package", "inspect", "oci://"+ref+"/import-everything:0.0.1", "--plain-http", "-a", "skeleton")
suite.NoError(err)
Expand Down Expand Up @@ -190,6 +189,7 @@ func (suite *PublishCopySkeletonSuite) Test_3_Copy() {
dstRegistry := testutil.SetupInMemoryRegistry(testutil.TestContext(t), t, 31890)
dstRef := strings.Replace(ref, suite.Reference.Registry, dstRegistry, 1)
ctx := testutil.TestContext(t)
ctx = logger.WithContext(ctx, test.GetLogger(t))

src, err := zoci.NewRemote(ctx, ref, oci.PlatformForArch(e2e.Arch), oci.WithPlainHTTP(true))
suite.NoError(err)
Expand Down
26 changes: 2 additions & 24 deletions src/test/e2e/20_zarf_init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestZarfInit(t *testing.T) {
// We need to use the --architecture flag here to force zarf to find the package.
_, stdErr, err = e2e.Zarf(t, "init", "--architecture", mismatchedArch, "--components=k3s", "--confirm")
require.Error(t, err, stdErr)
require.Contains(t, e2e.StripMessageFormatting(stdErr), expectedErrorMessage)
require.Contains(t, stdErr, expectedErrorMessage)
}

if !e2e.ApplianceMode {
Expand All @@ -64,12 +64,8 @@ func TestZarfInit(t *testing.T) {
}

// run `zarf init`
_, initStdErr, err := e2e.Zarf(t, "init", "--components="+initComponents, "--nodeport", "31337", "-l", "trace", "--confirm")
_, _, err = e2e.Zarf(t, "init", "--components="+initComponents, "--nodeport", "31337", "--confirm")
require.NoError(t, err)
require.Contains(t, initStdErr, "an inventory of all software contained in this package")
require.NotContains(t, initStdErr, "This package does NOT contain an SBOM. If you require an SBOM, please contact the creator of this package to request a version that includes an SBOM.")

logText := e2e.GetLogFileContents(t, e2e.StripMessageFormatting(initStdErr))

// Verify that any state secrets were not included in the log
state := types.ZarfState{}
Expand All @@ -79,7 +75,6 @@ func TestZarfInit(t *testing.T) {
require.NoError(t, err)
err = json.Unmarshal(stateJSON, &state)
require.NoError(t, err)
checkLogForSensitiveState(t, logText, state)

if e2e.ApplianceMode {
// make sure that we upgraded `k3s` correctly and are running the correct version - this should match that found in `packages/distros/k3s`
Expand Down Expand Up @@ -108,23 +103,6 @@ func TestZarfInit(t *testing.T) {
_, _, _ = e2e.Kubectl(t, "scale", "deploy", "-n", "zarf", "agent-hook", "--replicas=1") //nolint:errcheck
}

func checkLogForSensitiveState(t *testing.T, logText string, zarfState types.ZarfState) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have unit test coverage for zarfState redactions?

t.Helper()

require.NotContains(t, logText, zarfState.AgentTLS.CA)
require.NotContains(t, logText, string(zarfState.AgentTLS.CA))
require.NotContains(t, logText, zarfState.AgentTLS.Cert)
require.NotContains(t, logText, string(zarfState.AgentTLS.Cert))
require.NotContains(t, logText, zarfState.AgentTLS.Key)
require.NotContains(t, logText, string(zarfState.AgentTLS.Key))
require.NotContains(t, logText, zarfState.ArtifactServer.PushToken)
require.NotContains(t, logText, zarfState.GitServer.PullPassword)
require.NotContains(t, logText, zarfState.GitServer.PushPassword)
require.NotContains(t, logText, zarfState.RegistryInfo.PullPassword)
require.NotContains(t, logText, zarfState.RegistryInfo.PushPassword)
require.NotContains(t, logText, zarfState.RegistryInfo.Secret)
}

func verifyZarfNamespaceLabels(t *testing.T) {
t.Helper()

Expand Down
12 changes: 7 additions & 5 deletions src/test/e2e/21_connect_creds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (

"github.com/stretchr/testify/require"
"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/test"
)

type RegistryResponse struct {
Expand All @@ -23,7 +25,7 @@ type RegistryResponse struct {

func TestConnectAndCreds(t *testing.T) {
t.Log("E2E: Connect")
ctx := context.Background()
ctx := logger.WithContext(context.Background(), test.GetLogger(t))

prevAgentSecretData, _, err := e2e.Kubectl(t, "get", "secret", "agent-hook-tls", "-n", "zarf", "-o", "jsonpath={.data}")
require.NoError(t, err)
Expand All @@ -36,7 +38,7 @@ func TestConnectAndCreds(t *testing.T) {

connectToZarfServices(ctx, t)

stdOut, stdErr, err := e2e.Zarf(t, "tools", "update-creds", "--confirm")
stdOut, stdErr, err := e2e.Zarf(t, "tools", "update-creds", "--confirm", "--log-format=console", "--no-color")
require.NoError(t, err, stdOut, stdErr)

newAgentSecretData, _, err := e2e.Kubectl(t, "get", "secret", "agent-hook-tls", "-n", "zarf", "-o", "jsonpath={.data}")
Expand Down Expand Up @@ -104,13 +106,13 @@ func connectToZarfServices(ctx context.Context, t *testing.T) {
require.Contains(t, stdOut, "library/registry")

// Get the git credentials
stdOut, stdErr, err = e2e.Zarf(t, "tools", "get-creds", "git")
stdOut, stdErr, err = e2e.Zarf(t, "tools", "get-creds", "git", "--log-format=console", "--no-color")
require.NoError(t, err, stdOut, stdErr)
gitPushPassword := strings.TrimSpace(stdOut)
stdOut, stdErr, err = e2e.Zarf(t, "tools", "get-creds", "git-readonly")
stdOut, stdErr, err = e2e.Zarf(t, "tools", "get-creds", "git-readonly", "--log-format=console", "--no-color")
require.NoError(t, err, stdOut, stdErr)
gitPullPassword := strings.TrimSpace(stdOut)
stdOut, stdErr, err = e2e.Zarf(t, "tools", "get-creds", "artifact")
stdOut, stdErr, err = e2e.Zarf(t, "tools", "get-creds", "artifact", "--log-format=console", "--no-color")
require.NoError(t, err, stdOut, stdErr)
gitArtifactToken := strings.TrimSpace(stdOut)

Expand Down
7 changes: 5 additions & 2 deletions src/test/e2e/22_git_and_gitops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/zarf-dev/zarf/src/internal/gitea"
"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/test"
"github.com/zarf-dev/zarf/src/types"
)

Expand All @@ -35,7 +37,8 @@ func TestGit(t *testing.T) {

c, err := cluster.NewCluster()
require.NoError(t, err)
ctx := context.Background()
ctx := logger.WithContext(context.Background(), test.GetLogger(t))

tunnelGit, err := c.Connect(ctx, cluster.ZarfGit)
require.NoError(t, err)
defer tunnelGit.Close()
Expand Down Expand Up @@ -132,7 +135,7 @@ func testGitServerTagAndHash(ctx context.Context, t *testing.T, gitURL string) {
}

func waitFluxPodInfoDeployment(t *testing.T) {
ctx := context.Background()
ctx := logger.WithContext(context.Background(), test.GetLogger(t))
cluster, err := cluster.NewClusterWithWait(ctx)
require.NoError(t, err)
zarfState, err := cluster.LoadZarfState(ctx)
Expand Down
17 changes: 6 additions & 11 deletions src/test/e2e/23_data_injection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,25 @@ import (
"net/http"
"path/filepath"
"testing"
"time"

"github.com/stretchr/testify/require"
"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/utils/exec"
"github.com/zarf-dev/zarf/src/pkg/logger"
"github.com/zarf-dev/zarf/src/test"
)

func TestDataInjection(t *testing.T) {
t.Log("E2E: Data injection")

ctx := context.Background()

ctx := logger.WithContext(context.Background(), test.GetLogger(t))
path := fmt.Sprintf("build/zarf-package-kiwix-%s-3.5.0.tar", e2e.Arch)

tmpdir := t.TempDir()
sbomPath := filepath.Join(tmpdir, ".sbom-location")

// Repeat the injection action 3 times to ensure the data injection is idempotent and doesn't fail to perform an upgrade
for i := 0; i < 3; i++ {
runDataInjection(ctx, t, path)
runDataInjection(t, path)
}

// Verify the file and injection marker were created
Expand Down Expand Up @@ -65,12 +64,8 @@ func TestDataInjection(t *testing.T) {
require.FileExists(t, filepath.Join(sbomPath, "kiwix", "zarf-component-kiwix-serve.json"), "The data-injection component should have an SBOM json")
}

func runDataInjection(ctx context.Context, t *testing.T, path string) {
// Limit this deploy to 5 minutes
ctx, cancel := context.WithTimeout(ctx, 5*time.Minute)
defer cancel()

func runDataInjection(t *testing.T, path string) {
// Deploy the data injection example
stdOut, stdErr, err := exec.CmdWithContext(ctx, exec.PrintCfg(), e2e.ZarfBinPath, "package", "deploy", path, "-l", "trace", "--confirm")
stdOut, stdErr, err := e2e.Zarf(t, "package", "deploy", path, "--confirm", "--timeout", "5m")
require.NoError(t, err, stdOut, stdErr)
}
Loading
Loading