github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/test/e2e/00_use_cli_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2021-Present The Jackal Authors
     3  
     4  // Package test provides e2e tests for Jackal.
     5  package test
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"path/filepath"
    11  	"runtime"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/defenseunicorns/pkg/helpers"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestUseCLI(t *testing.T) {
    20  	t.Log("E2E: Use CLI")
    21  
    22  	t.Run("jackal prepare sha256sum <local>", func(t *testing.T) {
    23  		t.Parallel()
    24  
    25  		// Test `jackal prepare sha256sum` for a local asset
    26  		expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n"
    27  		shasumTestFilePath := "shasum-test-file"
    28  
    29  		e2e.CleanFiles(shasumTestFilePath)
    30  		t.Cleanup(func() {
    31  			e2e.CleanFiles(shasumTestFilePath)
    32  		})
    33  
    34  		err := os.WriteFile(shasumTestFilePath, []byte("random test data 🦄\n"), helpers.ReadWriteUser)
    35  		require.NoError(t, err)
    36  
    37  		stdOut, stdErr, err := e2e.Jackal("prepare", "sha256sum", shasumTestFilePath)
    38  		require.NoError(t, err, stdOut, stdErr)
    39  		require.Equal(t, expectedShasum, stdOut, "The expected SHASUM should equal the actual SHASUM")
    40  	})
    41  
    42  	t.Run("jackal prepare sha256sum <remote>", func(t *testing.T) {
    43  		t.Parallel()
    44  		// Test `jackal prepare sha256sum` for a remote asset
    45  		expectedShasum := "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n"
    46  
    47  		stdOut, stdErr, err := e2e.Jackal("prepare", "sha256sum", "https://jackal-public.s3-us-gov-west-1.amazonaws.com/pipelines/jackal-prepare-shasum-remote-test-file.txt")
    48  		require.NoError(t, err, stdOut, stdErr)
    49  		require.Contains(t, stdOut, expectedShasum, "The expected SHASUM should equal the actual SHASUM")
    50  	})
    51  
    52  	t.Run("jackal version", func(t *testing.T) {
    53  		t.Parallel()
    54  		// Test `jackal version`
    55  		version, _, err := e2e.Jackal("version")
    56  		require.NoError(t, err)
    57  		require.NotEqual(t, len(version), 0, "Jackal version should not be an empty string")
    58  		version = strings.Trim(version, "\n")
    59  
    60  		// test `jackal version --output=json`
    61  		stdOut, _, err := e2e.Jackal("version", "--output=json")
    62  		require.NoError(t, err)
    63  		jsonVersion := fmt.Sprintf(",\"version\":\"%s\"}", version)
    64  		require.Contains(t, stdOut, jsonVersion, "Jackal version should be the same in all formats")
    65  
    66  		// test `jackal version --output=yaml`
    67  		stdOut, _, err = e2e.Jackal("version", "--output=yaml")
    68  		require.NoError(t, err)
    69  		yamlVersion := fmt.Sprintf("version: %s", version)
    70  		require.Contains(t, stdOut, yamlVersion, "Jackal version should be the same in all formats")
    71  	})
    72  
    73  	t.Run("jackal deploy should fail when given a bad component input", func(t *testing.T) {
    74  		t.Parallel()
    75  		// Test for expected failure when given a bad component input
    76  		path := fmt.Sprintf("build/jackal-package-component-actions-%s.tar.zst", e2e.Arch)
    77  		_, _, err := e2e.Jackal("package", "deploy", path, "--components=on-create,foo,logging", "--confirm")
    78  		require.Error(t, err)
    79  	})
    80  
    81  	t.Run("jackal deploy should return a warning when no components are deployed", func(t *testing.T) {
    82  		t.Parallel()
    83  		_, _, err := e2e.Jackal("package", "create", "src/test/packages/00-no-components", "-o=build", "--confirm")
    84  		require.NoError(t, err)
    85  		path := fmt.Sprintf("build/jackal-package-no-components-%s.tar.zst", e2e.Arch)
    86  
    87  		// Test that excluding all components with a leading dash results in a warning
    88  		_, stdErr, err := e2e.Jackal("package", "deploy", path, "--components=-deselect-me", "--confirm")
    89  		require.NoError(t, err)
    90  		require.Contains(t, stdErr, "No components were selected for deployment")
    91  
    92  		// Test that excluding still works even if a wildcard is given
    93  		_, stdErr, err = e2e.Jackal("package", "deploy", path, "--components=*,-deselect-me", "--confirm")
    94  		require.NoError(t, err)
    95  		require.NotContains(t, stdErr, "DESELECT-ME COMPONENT")
    96  	})
    97  
    98  	t.Run("changing log level", func(t *testing.T) {
    99  		t.Parallel()
   100  		// Test that changing the log level actually applies the requested level
   101  		_, stdErr, _ := e2e.Jackal("internal", "crc32", "jackal", "--log-level=debug")
   102  		expectedOutString := "Log level set to debug"
   103  		require.Contains(t, stdErr, expectedOutString, "The log level should be changed to 'debug'")
   104  	})
   105  
   106  	t.Run("bad jackal package deploy w/o --insecure or --shasum", func(t *testing.T) {
   107  		t.Parallel()
   108  		// Test that `jackal package deploy` gives an error if deploying a remote package without the --insecure or --shasum flags
   109  		stdOut, stdErr, err := e2e.Jackal("package", "deploy", "https://jackal-examples.s3.amazonaws.com/jackal-package-appliance-demo-doom-20210125.tar.zst", "--confirm")
   110  		require.Error(t, err, stdOut, stdErr)
   111  	})
   112  
   113  	t.Run("jackal package to test bad remote images", func(t *testing.T) {
   114  		_, stdErr, err := e2e.Jackal("package", "create", "src/test/packages/00-remote-pull-fail", "--confirm")
   115  		// expecting jackal to have an error and output to stderr
   116  		require.Error(t, err)
   117  		// Make sure we print the get request error (only look for GET since the actual error changes based on login status)
   118  		require.Contains(t, stdErr, "failed to find the manifest on a remote: GET")
   119  		// And the docker error
   120  		require.Contains(t, stdErr, "response from daemon: No such image")
   121  	})
   122  
   123  	t.Run("jackal package to test archive path", func(t *testing.T) {
   124  		t.Parallel()
   125  		stdOut, stdErr, err := e2e.Jackal("package", "create", "packages/distros/eks", "--confirm")
   126  		require.NoError(t, err, stdOut, stdErr)
   127  
   128  		path := fmt.Sprintf("jackal-package-distro-eks-%s-0.0.3.tar.zst", e2e.Arch)
   129  		stdOut, stdErr, err = e2e.Jackal("package", "deploy", path, "--confirm")
   130  		require.NoError(t, err, stdOut, stdErr)
   131  
   132  		require.FileExists(t, "binaries/eksctl_Darwin_x86_64")
   133  		require.FileExists(t, "binaries/eksctl_Darwin_arm64")
   134  		require.FileExists(t, "binaries/eksctl_Linux_x86_64")
   135  
   136  		e2e.CleanFiles("binaries/eksctl_Darwin_x86_64", "binaries/eksctl_Darwin_arm64", "binaries/eksctl_Linux_x86_64", path, "eks.yaml")
   137  	})
   138  
   139  	t.Run("jackal package create with tmpdir and cache", func(t *testing.T) {
   140  		t.Parallel()
   141  		tmpdir := t.TempDir()
   142  		cacheDir := filepath.Join(t.TempDir(), ".cache-location")
   143  		stdOut, stdErr, err := e2e.Jackal("package", "create", "examples/dos-games", "--jackal-cache", cacheDir, "--tmpdir", tmpdir, "--log-level=debug", "-o=build", "--confirm")
   144  		require.Contains(t, stdErr, tmpdir, "The other tmp path should show as being created")
   145  		require.NoError(t, err, stdOut, stdErr)
   146  
   147  		files, err := os.ReadDir(filepath.Join(cacheDir, "images"))
   148  		require.NoError(t, err, "Encountered an unexpected error when reading image cache path")
   149  		require.Greater(t, len(files), 1)
   150  	})
   151  
   152  	t.Run("jackal package inspect with tmpdir", func(t *testing.T) {
   153  		t.Parallel()
   154  		path := fmt.Sprintf("build/jackal-package-component-actions-%s.tar.zst", e2e.Arch)
   155  		tmpdir := t.TempDir()
   156  		stdOut, stdErr, err := e2e.Jackal("package", "inspect", path, "--tmpdir", tmpdir, "--log-level=debug")
   157  		require.Contains(t, stdErr, tmpdir, "The other tmp path should show as being created")
   158  		require.NoError(t, err, stdOut, stdErr)
   159  	})
   160  
   161  	t.Run("jackal package deploy with tmpdir", func(t *testing.T) {
   162  		t.Parallel()
   163  		tmpdir := t.TempDir()
   164  		// run `jackal package deploy` with a specified tmp location
   165  		var (
   166  			firstFile  = "first-choice-file.txt"
   167  			secondFile = "second-choice-file.txt"
   168  		)
   169  		t.Cleanup(func() {
   170  			e2e.CleanFiles(firstFile, secondFile)
   171  		})
   172  		path := fmt.Sprintf("build/jackal-package-component-choice-%s.tar.zst", e2e.Arch)
   173  		stdOut, stdErr, err := e2e.Jackal("package", "deploy", path, "--tmpdir", tmpdir, "--log-level=debug", "--confirm")
   174  		require.Contains(t, stdErr, tmpdir, "The other tmp path should show as being created")
   175  		require.NoError(t, err, stdOut, stdErr)
   176  	})
   177  
   178  	t.Run("remove cache", func(t *testing.T) {
   179  		t.Parallel()
   180  		tmpdir := t.TempDir()
   181  		// Test removal of cache
   182  		cachePath := filepath.Join(tmpdir, ".cache-location")
   183  		stdOut, stdErr, err := e2e.Jackal("tools", "clear-cache", "--jackal-cache", cachePath)
   184  		require.NoError(t, err, stdOut, stdErr)
   185  		// Check that ReadDir returns no such file or directory for the cachePath
   186  		_, err = os.ReadDir(cachePath)
   187  		if runtime.GOOS == "windows" {
   188  			msg := fmt.Sprintf("open %s: The system cannot find the file specified.", cachePath)
   189  			require.EqualError(t, err, msg, "Did not receive expected error when reading a directory that should not exist")
   190  		} else {
   191  			msg := fmt.Sprintf("open %s: no such file or directory", cachePath)
   192  			require.EqualError(t, err, msg, "Did not receive expected error when reading a directory that should not exist")
   193  		}
   194  	})
   195  
   196  	t.Run("gen pki", func(t *testing.T) {
   197  		t.Parallel()
   198  		// Test generation of PKI
   199  		tlsCA := "tls.ca"
   200  		tlsCert := "tls.crt"
   201  		tlsKey := "tls.key"
   202  		t.Cleanup(func() {
   203  			e2e.CleanFiles(tlsCA, tlsCert, tlsKey)
   204  		})
   205  		stdOut, stdErr, err := e2e.Jackal("tools", "gen-pki", "github.com", "--sub-alt-name", "google.com")
   206  		require.NoError(t, err, stdOut, stdErr)
   207  		require.Contains(t, stdErr, "Successfully created a chain of trust for github.com")
   208  
   209  		require.FileExists(t, tlsCA)
   210  
   211  		require.FileExists(t, tlsCert)
   212  
   213  		require.FileExists(t, tlsKey)
   214  	})
   215  
   216  	t.Run("jackal tools yq should function appropriately across different uses", func(t *testing.T) {
   217  		t.Parallel()
   218  
   219  		file := "src/test/packages/00-yq-checks/file1.yaml"
   220  		otherFile := "src/test/packages/00-yq-checks/file2.yaml"
   221  
   222  		// Test that yq can eval properly
   223  		_, stdErr, err := e2e.Jackal("tools", "yq", "eval", "-i", `.items[1].name = "renamed-item"`, file)
   224  		require.NoError(t, err, stdErr)
   225  		stdOut, stdErr, err := e2e.Jackal("tools", "yq", ".items[1].name", file)
   226  		require.Contains(t, stdOut, "renamed-item")
   227  
   228  		// Test that yq ea can be used properly
   229  		_, stdErr, err = e2e.Jackal("tools", "yq", "eval-all", "-i", `. as $doc ireduce ({}; .items += $doc.items)`, file, otherFile)
   230  		require.NoError(t, err, stdErr)
   231  		stdOut, stdErr, err = e2e.Jackal("tools", "yq", "e", ".items | length", file)
   232  		require.Equal(t, "4\n", stdOut)
   233  
   234  	})
   235  }