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 }