github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/internal/testutil/setup_manager.go (about) 1 // Copyright 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package testutil 16 17 import ( 18 "os" 19 "path" 20 "path/filepath" 21 "testing" 22 23 "github.com/GoogleContainerTools/kpt/internal/gitutil" 24 "github.com/GoogleContainerTools/kpt/internal/printer/fake" 25 "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" 26 "github.com/GoogleContainerTools/kpt/internal/util/get" 27 kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" 28 "github.com/stretchr/testify/assert" 29 "sigs.k8s.io/kustomize/kyaml/yaml" 30 ) 31 32 const ( 33 Upstream = "upstream" 34 Local = "local" 35 ) 36 37 type TestSetupManager struct { 38 T *testing.T 39 40 // GetRef is the git ref to fetch 41 GetRef string 42 43 // GetSubDirectory is the repo subdirectory containing the package 44 GetSubDirectory string 45 46 // ReposChanges are content for any repos. 47 ReposChanges map[string][]Content 48 49 LocalChanges []Content 50 51 Repos map[string]*TestGitRepo 52 53 LocalWorkspace *TestWorkspace 54 55 cleanTestRepos func() 56 cacheDir string 57 targetDir string 58 } 59 60 type Content struct { 61 CreateBranch bool 62 Branch string 63 Data string 64 Pkg *pkgbuilder.RootPkg 65 Tag string 66 Message string 67 68 // UpdateFunc is invoked after the repo has been updated with the new 69 // content, but before it is committed. This allows for making changes 70 // that isn't supported by the pkgbuilder (like creating symlinks). 71 UpdateFunc func(path string) error 72 } 73 74 // Init initializes test data 75 // - Setup a new upstream repo in a tmp directory 76 // - Set the initial upstream content to Dataset1 77 // - Setup a new cache location for git repos and update the environment variable 78 // - Setup fetch the upstream package to a local package 79 // - Verify the local package contains the upstream content 80 func (g *TestSetupManager) Init() bool { 81 // Default optional values 82 if g.GetRef == "" { 83 g.GetRef = "master" 84 } 85 if g.GetSubDirectory == "" { 86 g.GetSubDirectory = "/" 87 } 88 89 // Configure the cache location for cloning repos 90 cacheDir, err := os.MkdirTemp("", "kpt-test-cache-repos-") 91 if !assert.NoError(g.T, err) { 92 return false 93 } 94 g.cacheDir = cacheDir 95 os.Setenv(gitutil.RepoCacheDirEnv, g.cacheDir) 96 97 g.Repos, g.LocalWorkspace, g.cleanTestRepos = SetupReposAndWorkspace(g.T, g.ReposChanges) 98 if g.GetSubDirectory == "/" { 99 g.targetDir = filepath.Base(g.Repos[Upstream].RepoName) 100 } else { 101 g.targetDir = filepath.Base(g.GetSubDirectory) 102 } 103 g.LocalWorkspace.PackageDir = g.targetDir 104 105 // Get the content from the upstream repo into the local workspace. 106 if !assert.NoError(g.T, get.Command{ 107 Destination: filepath.Join(g.LocalWorkspace.WorkspaceDirectory, g.targetDir), 108 Git: &kptfilev1.Git{ 109 Repo: g.Repos[Upstream].RepoDirectory, 110 Ref: g.GetRef, 111 Directory: g.GetSubDirectory, 112 }}.Run(fake.CtxWithDefaultPrinter())) { 113 return false 114 } 115 localGit, err := gitutil.NewLocalGitRunner(g.LocalWorkspace.WorkspaceDirectory) 116 if !assert.NoError(g.T, err) { 117 return false 118 } 119 _, err = localGit.Run(fake.CtxWithDefaultPrinter(), "add", ".") 120 if !assert.NoError(g.T, err) { 121 return false 122 } 123 _, err = localGit.Run(fake.CtxWithDefaultPrinter(), "commit", "-m", "add files") 124 if !assert.NoError(g.T, err) { 125 return false 126 } 127 128 // Modify other repos after initial fetch. 129 if err := UpdateRepos(g.T, g.Repos, g.ReposChanges); err != nil { 130 return false 131 } 132 133 // Modify local workspace after initial fetch. 134 if err := UpdateGitDir(g.T, Local, g.LocalWorkspace, g.LocalChanges, g.Repos); err != nil { 135 return false 136 } 137 138 return true 139 } 140 141 type GitDirectory interface { 142 CheckoutBranch(branch string, create bool) error 143 ReplaceData(data string) error 144 Commit(message string) (string, error) 145 Tag(tagName string) error 146 CustomUpdate(updateFunc func(string) error) error 147 } 148 149 func UpdateGitDir(t *testing.T, name string, gitDir GitDirectory, changes []Content, repos map[string]*TestGitRepo) error { 150 for _, content := range changes { 151 if content.Message == "" { 152 content.Message = "initializing data" 153 } 154 if len(content.Branch) > 0 { 155 err := gitDir.CheckoutBranch(content.Branch, content.CreateBranch) 156 if !assert.NoError(t, err) { 157 return err 158 } 159 } 160 161 var pkgData string 162 if content.Pkg != nil { 163 pkgData = content.Pkg.ExpandPkg(t, ToReposInfo(repos)) 164 } else { 165 pkgData = content.Data 166 } 167 168 err := gitDir.ReplaceData(pkgData) 169 if !assert.NoError(t, err) { 170 return err 171 } 172 173 if content.UpdateFunc != nil { 174 err = gitDir.CustomUpdate(content.UpdateFunc) 175 if !assert.NoError(t, err) { 176 return err 177 } 178 } 179 180 sha, err := gitDir.Commit(content.Message) 181 if !assert.NoError(t, err) { 182 return err 183 } 184 185 // Update the list of commit shas for the repo. 186 if r, found := repos[name]; found { 187 r.Commits = append(r.Commits, sha) 188 } 189 190 if len(content.Tag) > 0 { 191 err = gitDir.Tag(content.Tag) 192 if !assert.NoError(t, err) { 193 return err 194 } 195 } 196 } 197 return nil 198 } 199 200 // GetSubPkg gets a subpkg specified by repo/upstreamDir to destination in the local workspace 201 func (g *TestSetupManager) GetSubPkg(dest, repo, upstreamDir string) { 202 assert.NoError(g.T, get.Command{ 203 Destination: path.Join(g.LocalWorkspace.FullPackagePath(), dest), 204 Git: &kptfilev1.Git{ 205 Repo: g.Repos[repo].RepoDirectory, 206 Ref: g.GetRef, 207 Directory: path.Join(g.GetSubDirectory, upstreamDir), 208 }}.Run(fake.CtxWithDefaultPrinter())) 209 210 localGit, err := gitutil.NewLocalGitRunner(g.LocalWorkspace.WorkspaceDirectory) 211 assert.NoError(g.T, err) 212 _, err = localGit.Run(fake.CtxWithDefaultPrinter(), "add", ".") 213 assert.NoError(g.T, err) 214 _, err = localGit.Run(fake.CtxWithDefaultPrinter(), "commit", "-m", "add files") 215 assert.NoError(g.T, err) 216 } 217 218 func (g *TestSetupManager) AssertKptfile(name, commit, ref string, strategy kptfilev1.UpdateStrategyType) bool { 219 expectedKptfile := kptfilev1.KptFile{ 220 ResourceMeta: yaml.ResourceMeta{ 221 ObjectMeta: yaml.ObjectMeta{ 222 NameMeta: yaml.NameMeta{ 223 Name: name, 224 }, 225 }, 226 TypeMeta: yaml.TypeMeta{ 227 APIVersion: kptfilev1.TypeMeta.APIVersion, 228 Kind: kptfilev1.TypeMeta.Kind}, 229 }, 230 Upstream: &kptfilev1.Upstream{ 231 Type: "git", 232 Git: &kptfilev1.Git{ 233 Directory: g.GetSubDirectory, 234 Repo: g.Repos[Upstream].RepoDirectory, 235 Ref: ref, 236 }, 237 UpdateStrategy: strategy, 238 }, 239 UpstreamLock: &kptfilev1.UpstreamLock{ 240 Type: "git", 241 Git: &kptfilev1.GitLock{ 242 Directory: g.GetSubDirectory, 243 Repo: g.Repos[Upstream].RepoDirectory, 244 Ref: ref, 245 Commit: commit, 246 }, 247 }, 248 } 249 250 return g.Repos[Upstream].AssertKptfile( 251 g.T, filepath.Join(g.LocalWorkspace.WorkspaceDirectory, g.targetDir), expectedKptfile) 252 } 253 254 func (g *TestSetupManager) AssertLocalDataEquals(path string, addMergeCommentToSource bool) bool { 255 var sourceDir string 256 if filepath.IsAbs(path) { 257 sourceDir = path 258 } else { 259 sourceDir = filepath.Join(g.Repos[Upstream].DatasetDirectory, path) 260 } 261 destDir := filepath.Join(g.LocalWorkspace.WorkspaceDirectory, g.targetDir) 262 return g.Repos[Upstream].AssertEqual(g.T, sourceDir, destDir, addMergeCommentToSource) 263 } 264 265 func (g *TestSetupManager) Clean() { 266 g.cleanTestRepos() 267 os.RemoveAll(g.cacheDir) 268 }