Skip to content

Commit 3df8952

Browse files
authored
GenerateManifests test (#18)
* GenerateManifests test Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
1 parent 546c07d commit 3df8952

File tree

6 files changed

+140
-31
lines changed

6 files changed

+140
-31
lines changed

reposerver/repository/repository.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ var ErrExceededMaxCombinedManifestFileSize = errors.New("exceeded max combined m
8383
type Service struct {
8484
gitCredsStore git.CredsStore
8585
rootDir string
86-
gitRepoPaths *io.TempPaths
87-
chartPaths *io.TempPaths
86+
gitRepoPaths io.TempPaths
87+
chartPaths io.TempPaths
8888
gitRepoInitializer func(rootPath string) goio.Closer
8989
repoLock *repositoryLock
9090
cache *reposervercache.Cache
@@ -118,6 +118,8 @@ func NewService(metricsServer *metrics.MetricsServer, cache *reposervercache.Cac
118118
parallelismLimitSemaphore = semaphore.NewWeighted(initConstants.ParallelismLimit)
119119
}
120120
repoLock := NewRepositoryLock()
121+
gitRandomizedPaths := io.NewRandomizedTempPaths(rootDir)
122+
helmRandomizedPaths := io.NewRandomizedTempPaths(rootDir)
121123
return &Service{
122124
parallelismLimitSemaphore: parallelismLimitSemaphore,
123125
repoLock: repoLock,
@@ -131,8 +133,8 @@ func NewService(metricsServer *metrics.MetricsServer, cache *reposervercache.Cac
131133
initConstants: initConstants,
132134
now: time.Now,
133135
gitCredsStore: gitCredsStore,
134-
gitRepoPaths: io.NewTempPaths(rootDir),
135-
chartPaths: io.NewTempPaths(rootDir),
136+
gitRepoPaths: gitRandomizedPaths,
137+
chartPaths: helmRandomizedPaths,
136138
gitRepoInitializer: directoryPermissionInitializer,
137139
rootDir: rootDir,
138140
}
@@ -946,7 +948,7 @@ func populateRequestRepos(appPath string, q *apiclient.ManifestRequest) error {
946948
return nil
947949
}
948950

949-
func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths *io.TempPaths) ([]*unstructured.Unstructured, error) {
951+
func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths io.TempPaths) ([]*unstructured.Unstructured, error) {
950952
concurrencyAllowed := isConcurrencyAllowed(appPath)
951953
if !concurrencyAllowed {
952954
manifestGenerateLock.Lock(appPath)
@@ -1084,7 +1086,7 @@ func getResolvedValueFiles(
10841086
allowedValueFilesSchemas []string,
10851087
rawValueFiles []string,
10861088
refSources map[string]*v1alpha1.RefTarget,
1087-
gitRepoPaths *io.TempPaths,
1089+
gitRepoPaths io.TempPaths,
10881090
ignoreMissingValueFiles bool,
10891091
) ([]pathutil.ResolvedFilePath, error) {
10901092
var resolvedValueFiles []pathutil.ResolvedFilePath
@@ -1128,7 +1130,7 @@ func getResolvedRefValueFile(
11281130
env *v1alpha1.Env,
11291131
allowedValueFilesSchemas []string,
11301132
refSourceRepo string,
1131-
gitRepoPaths *io.TempPaths,
1133+
gitRepoPaths io.TempPaths,
11321134
) (pathutil.ResolvedFilePath, error) {
11331135
pathStrings := strings.Split(rawValueFile, "/")
11341136
repoPath := gitRepoPaths.GetPathIfExists(git.NormalizeGitURL(refSourceRepo))
@@ -1197,7 +1199,7 @@ func WithCMPTarExcludedGlobs(excludedGlobs []string) GenerateManifestOpt {
11971199
}
11981200

11991201
// GenerateManifests generates manifests from a path. Overrides are applied as a side effect on the given ApplicationSource.
1200-
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, gitRepoPaths *io.TempPaths, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) {
1202+
func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, gitRepoPaths io.TempPaths, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) {
12011203
opt := newGenerateManifestOpt(opts...)
12021204
var targetObjs []*unstructured.Unstructured
12031205
var dest *v1alpha1.ApplicationDestination
@@ -1923,7 +1925,7 @@ func (s *Service) createGetAppDetailsCacheHandler(res *apiclient.RepoAppDetailsR
19231925
}
19241926
}
19251927

1926-
func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery, gitRepoPaths *io.TempPaths) error {
1928+
func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery, gitRepoPaths io.TempPaths) error {
19271929
var selectedValueFiles []string
19281930

19291931
if q.Source.Helm != nil {

reposerver/repository/repository_test.go

+43-7
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,28 @@ import (
3535
fileutil "github.com/argoproj/argo-cd/v2/test/fixture/path"
3636
"github.com/argoproj/argo-cd/v2/util/argo"
3737
cacheutil "github.com/argoproj/argo-cd/v2/util/cache"
38+
dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks"
3839
"github.com/argoproj/argo-cd/v2/util/git"
3940
gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks"
4041
"github.com/argoproj/argo-cd/v2/util/helm"
4142
helmmocks "github.com/argoproj/argo-cd/v2/util/helm/mocks"
4243
"github.com/argoproj/argo-cd/v2/util/io"
44+
iomocks "github.com/argoproj/argo-cd/v2/util/io/mocks"
4345
)
4446

4547
const testSignature = `gpg: Signature made Wed Feb 26 23:22:34 2020 CET
4648
gpg: using RSA key 4AEE18F83AFDEB23
4749
gpg: Good signature from "GitHub (web-flow commit signing) <noreply@github.com>" [ultimate]
4850
`
4951

50-
type clientFunc func(*gitmocks.Client, *helmmocks.Client)
52+
type clientFunc func(*gitmocks.Client, *helmmocks.Client, *iomocks.TempPaths)
5153

5254
func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) {
5355
root, err := filepath.Abs(root)
5456
if err != nil {
5557
panic(err)
5658
}
57-
return newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client) {
59+
return newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) {
5860
gitClient.On("Init").Return(nil)
5961
gitClient.On("Fetch", mock.Anything).Return(nil)
6062
gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil)
@@ -79,13 +81,17 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client)
7981
helmClient.On("CleanChartCache", chart, version).Return(nil)
8082
helmClient.On("CleanChartCache", oobChart, version).Return(nil)
8183
helmClient.On("DependencyBuild").Return(nil)
84+
85+
paths.On("GetPath", mock.Anything).Return(root, nil)
86+
paths.On("GetPathIfExists", mock.Anything).Return(root, nil)
8287
}, root)
8388
}
8489

8590
func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) {
8691
helmClient := &helmmocks.Client{}
8792
gitClient := &gitmocks.Client{}
88-
cf(gitClient, helmClient)
93+
paths := &iomocks.TempPaths{}
94+
cf(gitClient, helmClient, paths)
8995
service := NewService(metrics.NewMetricsServer(), cache.NewCache(
9096
cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Minute)),
9197
1*time.Minute,
@@ -101,6 +107,7 @@ func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client)
101107
service.gitRepoInitializer = func(rootPath string) goio.Closer {
102108
return io.NopCloser
103109
}
110+
service.gitRepoPaths = paths
104111
return service, gitClient
105112
}
106113

@@ -122,7 +129,7 @@ func newServiceWithCommitSHA(root, revision string) *Service {
122129
revisionErr = errors.New("not a commit SHA")
123130
}
124131

125-
service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client) {
132+
service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) {
126133
gitClient.On("Init").Return(nil)
127134
gitClient.On("Fetch", mock.Anything).Return(nil)
128135
gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil)
@@ -286,6 +293,35 @@ func TestHelmManifestFromChartRepo(t *testing.T) {
286293
}, response)
287294
}
288295

296+
func TestHelmChartReferencingExternalValues(t *testing.T) {
297+
service := newService(".")
298+
spec := argoappv1.ApplicationSpec{
299+
Sources: []argoappv1.ApplicationSource{
300+
{RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{
301+
ValueFiles: []string{"$ref/testdata/my-chart/my-chart-values.yaml"},
302+
}},
303+
{Ref: "ref", RepoURL: "https://git.example.com/test/repo"},
304+
},
305+
}
306+
repoDB := &dbmocks.ArgoDB{}
307+
repoDB.On("GetRepository", context.Background(), "https://git.example.com/test/repo").Return(&argoappv1.Repository{
308+
Repo: "https://git.example.com/test/repo",
309+
}, nil)
310+
refSources, err := argo.GetRefSources(context.Background(), spec, repoDB)
311+
require.NoError(t, err)
312+
request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true}
313+
response, err := service.GenerateManifest(context.Background(), request)
314+
assert.NoError(t, err)
315+
assert.NotNil(t, response)
316+
assert.Equal(t, &apiclient.ManifestResponse{
317+
Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"},
318+
Namespace: "",
319+
Server: "",
320+
Revision: "1.1.0",
321+
SourceType: "Helm",
322+
}, response)
323+
}
324+
289325
func TestGenerateManifestsUseExactRevision(t *testing.T) {
290326
service, gitClient := newServiceWithMocks(".", false)
291327

@@ -2496,7 +2532,7 @@ func Test_findHelmValueFilesInPath(t *testing.T) {
24962532
}
24972533

24982534
func Test_populateHelmAppDetails(t *testing.T) {
2499-
var emptyTempPaths = io.NewTempPaths(t.TempDir())
2535+
var emptyTempPaths = io.NewRandomizedTempPaths(t.TempDir())
25002536
res := apiclient.RepoAppDetailsResponse{}
25012537
q := apiclient.RepoServerAppDetailsQuery{
25022538
Repo: &argoappv1.Repository{},
@@ -2513,7 +2549,7 @@ func Test_populateHelmAppDetails(t *testing.T) {
25132549
}
25142550

25152551
func Test_populateHelmAppDetails_values_symlinks(t *testing.T) {
2516-
var emptyTempPaths = io.NewTempPaths(t.TempDir())
2552+
var emptyTempPaths = io.NewRandomizedTempPaths(t.TempDir())
25172553
t.Run("inbound", func(t *testing.T) {
25182554
res := apiclient.RepoAppDetailsResponse{}
25192555
q := apiclient.RepoServerAppDetailsQuery{Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{}}
@@ -2550,7 +2586,7 @@ func TestOCIDependencies(t *testing.T) {
25502586

25512587
func Test_getResolvedValueFiles(t *testing.T) {
25522588
tempDir := t.TempDir()
2553-
paths := io.NewTempPaths(tempDir)
2589+
paths := io.NewRandomizedTempPaths(tempDir)
25542590
paths.Add(git.NormalizeGitURL("https://github.com/org/repo1"), path.Join(tempDir, "repo1"))
25552591

25562592
testCases := []struct {

util/helm/client.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func WithIndexCache(indexCache indexCache) ClientOpts {
6565
}
6666
}
6767

68-
func WithChartPaths(chartPaths *argoio.TempPaths) ClientOpts {
68+
func WithChartPaths(chartPaths argoio.TempPaths) ClientOpts {
6969
return func(c *nativeHelmChart) {
7070
c.chartCachePaths = chartPaths
7171
}
@@ -82,7 +82,7 @@ func NewClientWithLock(repoURL string, creds Creds, repoLock sync.KeyLock, enabl
8282
repoLock: repoLock,
8383
enableOci: enableOci,
8484
proxy: proxy,
85-
chartCachePaths: argoio.NewTempPaths(os.TempDir()),
85+
chartCachePaths: argoio.NewRandomizedTempPaths(os.TempDir()),
8686
}
8787
for i := range opts {
8888
opts[i](c)
@@ -93,7 +93,7 @@ func NewClientWithLock(repoURL string, creds Creds, repoLock sync.KeyLock, enabl
9393
var _ Client = &nativeHelmChart{}
9494

9595
type nativeHelmChart struct {
96-
chartCachePaths *argoio.TempPaths
96+
chartCachePaths argoio.TempPaths
9797
repoURL string
9898
creds Creds
9999
repoLock sync.KeyLock

util/io/mocks/TempPaths.go

+65
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

util/io/paths.go

+13-7
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,34 @@ import (
77
"github.com/google/uuid"
88
)
99

10-
// TempPaths allows generating and memoizing random paths, each path being mapped to a specific key.
11-
type TempPaths struct {
10+
type TempPaths interface {
11+
Add(key string, value string)
12+
GetPath(key string) (string, error)
13+
GetPathIfExists(key string) string
14+
}
15+
16+
// RandomizedTempPaths allows generating and memoizing random paths, each path being mapped to a specific key.
17+
type RandomizedTempPaths struct {
1218
root string
1319
paths map[string]string
1420
lock sync.Mutex
1521
}
1622

17-
func NewTempPaths(root string) *TempPaths {
18-
return &TempPaths{
23+
func NewRandomizedTempPaths(root string) *RandomizedTempPaths {
24+
return &RandomizedTempPaths{
1925
root: root,
2026
paths: map[string]string{},
2127
}
2228
}
2329

24-
func (p *TempPaths) Add(key string, value string) {
30+
func (p *RandomizedTempPaths) Add(key string, value string) {
2531
p.lock.Lock()
2632
defer p.lock.Unlock()
2733
p.paths[key] = value
2834
}
2935

3036
// GetPath generates a path for the given key or returns previously generated one.
31-
func (p *TempPaths) GetPath(key string) (string, error) {
37+
func (p *RandomizedTempPaths) GetPath(key string) (string, error) {
3238
p.lock.Lock()
3339
defer p.lock.Unlock()
3440
if val, ok := p.paths[key]; ok {
@@ -44,7 +50,7 @@ func (p *TempPaths) GetPath(key string) (string, error) {
4450
}
4551

4652
// GetPathIfExists gets a path for the given key if it exists. Otherwise, returns an empty string.
47-
func (p *TempPaths) GetPathIfExists(key string) string {
53+
func (p *RandomizedTempPaths) GetPathIfExists(key string) string {
4854
p.lock.Lock()
4955
defer p.lock.Unlock()
5056
if val, ok := p.paths[key]; ok {

util/io/paths_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
func TestGetPath_SameURLs(t *testing.T) {
12-
paths := NewTempPaths(os.TempDir())
12+
paths := NewRandomizedTempPaths(os.TempDir())
1313
res1, err := paths.GetPath("https://localhost/test.txt")
1414
require.NoError(t, err)
1515
res2, err := paths.GetPath("https://localhost/test.txt")
@@ -18,7 +18,7 @@ func TestGetPath_SameURLs(t *testing.T) {
1818
}
1919

2020
func TestGetPath_DifferentURLs(t *testing.T) {
21-
paths := NewTempPaths(os.TempDir())
21+
paths := NewRandomizedTempPaths(os.TempDir())
2222
res1, err := paths.GetPath("https://localhost/test1.txt")
2323
require.NoError(t, err)
2424
res2, err := paths.GetPath("https://localhost/test2.txt")
@@ -27,17 +27,17 @@ func TestGetPath_DifferentURLs(t *testing.T) {
2727
}
2828

2929
func TestGetPath_SameURLsDifferentInstances(t *testing.T) {
30-
paths1 := NewTempPaths(os.TempDir())
30+
paths1 := NewRandomizedTempPaths(os.TempDir())
3131
res1, err := paths1.GetPath("https://localhost/test.txt")
3232
require.NoError(t, err)
33-
paths2 := NewTempPaths(os.TempDir())
33+
paths2 := NewRandomizedTempPaths(os.TempDir())
3434
res2, err := paths2.GetPath("https://localhost/test.txt")
3535
require.NoError(t, err)
3636
assert.NotEqual(t, res1, res2)
3737
}
3838

3939
func TestGetPathIfExists(t *testing.T) {
40-
paths := NewTempPaths(os.TempDir())
40+
paths := NewRandomizedTempPaths(os.TempDir())
4141
t.Run("does not exist", func(t *testing.T) {
4242
path := paths.GetPathIfExists("https://localhost/test.txt")
4343
assert.Empty(t, path)

0 commit comments

Comments
 (0)