Skip to content

Commit 9e42f8d

Browse files
authored
Merge pull request #5177 from annasong20/test-accumulate-remote-file
Test accumulateResources errors for remote files
2 parents 336bc14 + 168e31b commit 9e42f8d

File tree

4 files changed

+153
-34
lines changed

4 files changed

+153
-34
lines changed

api/krusty/accumulation_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
package krusty_test
55

66
import (
7+
"fmt"
78
"path/filepath"
9+
"regexp"
810
"strings"
911
"testing"
1012

13+
"github.com/stretchr/testify/require"
1114
. "sigs.k8s.io/kustomize/api/internal/target"
1215
"sigs.k8s.io/kustomize/api/konfig"
16+
"sigs.k8s.io/kustomize/api/krusty"
1317
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
1418
)
1519

@@ -160,3 +164,72 @@ spec:
160164
secretName: cert-tls
161165
`)
162166
}
167+
168+
func TestAccumulateResourcesErrors(t *testing.T) {
169+
type testcase struct {
170+
name string
171+
resource string
172+
// regex error message that is output when kustomize tries to
173+
// accumulate resource as file and dir, respectively
174+
errFile, errDir string
175+
}
176+
buildError := func(tc testcase) string {
177+
const (
178+
prefix = "accumulating resources"
179+
filePrefixf = "accumulating resources from '%s'"
180+
fileWrapperIfDirf = "accumulation err='%s'"
181+
separator = ": "
182+
)
183+
parts := []string{
184+
prefix,
185+
strings.Join([]string{
186+
fmt.Sprintf(filePrefixf, regexp.QuoteMeta(tc.resource)),
187+
tc.errFile,
188+
}, separator),
189+
}
190+
if tc.errDir != "" {
191+
parts[1] = fmt.Sprintf(fileWrapperIfDirf, parts[1])
192+
parts = append(parts, tc.errDir)
193+
}
194+
return strings.Join(parts, separator)
195+
}
196+
for _, test := range []testcase{
197+
{
198+
name: "remote file not considered repo",
199+
// This url is too short to be considered a remote repo.
200+
resource: "https://raw.githubusercontent.com/kustomize",
201+
// It is acceptable that the error for a remote file-like reference
202+
// (that is not long enough to be considered a repo) does not
203+
// indicate said reference is not a local directory.
204+
// Though it is possible for the remote file-like reference to be
205+
// a local directory, it is very unlikely.
206+
errFile: `HTTP Error: status code 400 \(Bad Request\)\z`,
207+
},
208+
{
209+
name: "remote file qualifies as repo",
210+
resource: "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/kustomize/v5.0.0/examples/helloWorld/configMap",
211+
// TODO(4788): This error message is technically wrong. Just
212+
// because we fail to GET a reference does not mean the reference is
213+
// not a remote file. We should return the GET status code instead.
214+
errFile: "URL is a git repository",
215+
errDir: `failed to run \S+/git fetch --depth=1 .+`,
216+
},
217+
} {
218+
t.Run(test.name, func(t *testing.T) {
219+
// should use real file system to indicate that we are creating
220+
// new temporary directories on disk when we attempt to fetch repos
221+
fSys, tmpDir := kusttest_test.CreateKustDir(t, fmt.Sprintf(`
222+
resources:
223+
- %s
224+
`, test.resource))
225+
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
226+
_, err := b.Run(fSys, tmpDir.String())
227+
require.Regexp(t, buildError(test), err.Error())
228+
})
229+
}
230+
// TODO(annasong): add tests that check accumulateResources errors for
231+
// - local files
232+
// - repos
233+
// - local directories
234+
// - files that yield malformed yaml errors
235+
}

api/krusty/remoteloader_test.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"io"
1111
"os"
1212
"os/exec"
13-
"path/filepath"
1413
"strings"
1514
"testing"
1615

@@ -19,7 +18,7 @@ import (
1918
"sigs.k8s.io/kustomize/api/krusty"
2019
"sigs.k8s.io/kustomize/api/loader"
2120
"sigs.k8s.io/kustomize/api/resmap"
22-
"sigs.k8s.io/kustomize/kyaml/filesys"
21+
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
2322
"sigs.k8s.io/kustomize/kyaml/yaml"
2423
)
2524

@@ -264,7 +263,7 @@ resources:
264263
}
265264

266265
kust := strings.ReplaceAll(test.kustomization, "$ROOT", repos.root)
267-
fSys, tmpDir := createKustDir(t, kust)
266+
fSys, tmpDir := kusttest_test.CreateKustDir(t, kust)
268267

269268
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
270269
m, err := b.Run(
@@ -368,7 +367,7 @@ resources:
368367
if test.beforeTest != nil {
369368
test.beforeTest(t)
370369
}
371-
fSys, tmpDir := createKustDir(t, test.kustomization)
370+
fSys, tmpDir := kusttest_test.CreateKustDir(t, test.kustomization)
372371

373372
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
374373
m, err := b.Run(
@@ -424,16 +423,6 @@ func configureGitSSHCommand(t *testing.T) {
424423
})
425424
}
426425

427-
func createKustDir(t *testing.T, content string) (filesys.FileSystem, filesys.ConfirmedDir) {
428-
t.Helper()
429-
430-
fSys := filesys.MakeFsOnDisk()
431-
tmpDir, err := filesys.NewTmpConfirmedDir()
432-
require.NoError(t, err)
433-
require.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(content)))
434-
return fSys, tmpDir
435-
}
436-
437426
func checkYaml(t *testing.T, actual resmap.ResMap, expected string) {
438427
t.Helper()
439428

api/loader/fileloader_test.go

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,31 @@ func TestLoaderBadRelative(t *testing.T) {
196196
require.Error(err)
197197
}
198198

199-
func TestLoaderMisc(t *testing.T) {
200-
l := makeLoader()
201-
_, err := l.New("")
199+
func TestNewEmptyLoader(t *testing.T) {
200+
_, err := makeLoader().New("")
202201
require.Error(t, err)
202+
}
203203

204-
_, err = l.New("https://google.com/project")
205-
require.Error(t, err)
204+
func TestNewLoaderHTTP(t *testing.T) {
205+
t.Run("doesn't exist", func(t *testing.T) {
206+
_, err := makeLoader().New("https://google.com/project")
207+
require.Error(t, err)
208+
})
209+
// Though it is unlikely and we do not weigh this use case in our designs,
210+
// it is possible for a reference that is considered a remote file to
211+
// actually be a directory
212+
t.Run("exists", func(t *testing.T) {
213+
const remoteFileLikeRoot = "https://domain"
214+
require.True(t, IsRemoteFile(remoteFileLikeRoot))
215+
fSys, dir := setupOnDisk(t)
216+
require.NoError(t, fSys.MkdirAll(dir.Join("https:/domain")))
217+
ldr, err := newLoaderOrDie(RestrictionRootOnly,
218+
fSys,
219+
dir.String(),
220+
).New(remoteFileLikeRoot)
221+
require.NoError(t, err)
222+
require.Empty(t, ldr.Repo())
223+
})
206224
}
207225

208226
const (
@@ -212,17 +230,17 @@ const (
212230

213231
// Create a structure like this
214232
//
215-
// /tmp/kustomize-test-random
216-
// ├── base
217-
// │ ├── okayData
218-
// │ ├── symLinkToOkayData -> okayData
219-
// │ └── symLinkToExteriorData -> ../exteriorData
220-
// └── exteriorData
221-
//
233+
// /tmp/kustomize-test-random
234+
// ├── base
235+
// │ ├── okayData
236+
// │ ├── symLinkToOkayData -> okayData
237+
// │ └── symLinkToExteriorData -> ../exteriorData
238+
// └── exteriorData
222239
func commonSetupForLoaderRestrictionTest(t *testing.T) (string, filesys.FileSystem) {
223240
t.Helper()
224-
dir := t.TempDir()
225-
fSys := filesys.MakeFsOnDisk()
241+
fSys, tmpDir := setupOnDisk(t)
242+
dir := tmpDir.String()
243+
226244
fSys.Mkdir(filepath.Join(dir, "base"))
227245

228246
fSys.WriteFile(
@@ -446,12 +464,8 @@ func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
446464
}
447465

448466
func TestLoaderDisallowsRemoteBaseExitRepo(t *testing.T) {
449-
fSys := filesys.MakeFsOnDisk()
450-
dir, err := filesys.NewTmpConfirmedDir()
451-
require.NoError(t, err)
452-
t.Cleanup(func() {
453-
_ = fSys.RemoveAll(dir.String())
454-
})
467+
fSys, dir := setupOnDisk(t)
468+
455469
repo := dir.Join("repo")
456470
require.NoError(t, fSys.Mkdir(repo))
457471

@@ -618,3 +632,17 @@ func TestLoaderHTTP(t *testing.T) {
618632
require.Error(err)
619633
}
620634
}
635+
636+
// setupOnDisk sets up a file system on disk and directory that is cleaned after
637+
// test completion.
638+
func setupOnDisk(t *testing.T) (filesys.FileSystem, filesys.ConfirmedDir) {
639+
t.Helper()
640+
641+
fSys := filesys.MakeFsOnDisk()
642+
dir, err := filesys.NewTmpConfirmedDir()
643+
require.NoError(t, err)
644+
t.Cleanup(func() {
645+
_ = fSys.RemoveAll(dir.String())
646+
})
647+
return fSys, dir
648+
}

api/testutils/kusttest/ondisk.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2023 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package kusttest_test
5+
6+
import (
7+
"path/filepath"
8+
"testing"
9+
10+
"github.com/stretchr/testify/require"
11+
"sigs.k8s.io/kustomize/kyaml/filesys"
12+
)
13+
14+
// CreateKustDir creates a file system on disk and a new directory
15+
// that holds a kustomization file with content. The directory is removed on
16+
// test completion.
17+
func CreateKustDir(t *testing.T, content string) (filesys.FileSystem, filesys.ConfirmedDir) {
18+
t.Helper()
19+
20+
fSys := filesys.MakeFsOnDisk()
21+
tmpDir, err := filesys.NewTmpConfirmedDir()
22+
require.NoError(t, err)
23+
require.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(content)))
24+
25+
t.Cleanup(func() {
26+
require.NoError(t, fSys.RemoveAll(tmpDir.String()))
27+
})
28+
return fSys, tmpDir
29+
}

0 commit comments

Comments
 (0)