k8s.io/test-infra@v0.0.0-20240520184403-27c6b4c223d8/experiment/bumpmonitoring/main_test.go (about) 1 /* 2 Copyright 2021 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "os" 21 "path" 22 "testing" 23 24 "github.com/google/go-cmp/cmp" 25 "github.com/google/go-cmp/cmp/cmpopts" 26 ) 27 28 func TestFindConfigToUpdate(t *testing.T) { 29 tests := []struct { 30 name string 31 desc string 32 srcNodes []node 33 dstNodes []node 34 want []string 35 wantErr bool 36 }{ 37 { 38 name: "base", 39 dstNodes: []node{ 40 {Path: "mixins/grafana_dashboards/a.jsonnet"}, 41 {Path: "mixins/prometheus/a.libsonnet"}, 42 }, 43 want: []string{ 44 "mixins/grafana_dashboards/a.jsonnet", 45 "mixins/prometheus/a.libsonnet", 46 }, 47 wantErr: false, 48 }, 49 { 50 name: "multiple-files", 51 dstNodes: []node{ 52 {Path: "mixins/grafana_dashboards/a.jsonnet"}, 53 {Path: "mixins/grafana_dashboards/b.jsonnet"}, 54 }, 55 want: []string{ 56 "mixins/grafana_dashboards/a.jsonnet", 57 "mixins/grafana_dashboards/b.jsonnet", 58 }, 59 wantErr: false, 60 }, 61 { 62 name: "wrong-extension", 63 dstNodes: []node{ 64 {Path: "mixins/grafana_dashboards/a.somethingelse"}, 65 }, 66 wantErr: false, 67 }, 68 { 69 name: "excluded-file", 70 dstNodes: []node{ 71 {Path: "mixins/grafana_dashboards/prometheus.libsonnet"}, 72 }, 73 wantErr: false, 74 }, 75 { 76 name: "empty", 77 }, 78 { 79 name: "empty dir", 80 dstNodes: []node{ 81 {Path: "mixins/grafana_dashboards", IsDir: true}, 82 }, 83 wantErr: false, 84 }, 85 } 86 87 for _, tc := range tests { 88 t.Run(tc.name, func(t *testing.T) { 89 tmpDir := t.TempDir() 90 srcRootDir, dstRootDir := seedTempDir(t, tmpDir, tc.srcNodes, tc.dstNodes) 91 c := client{ 92 srcPath: srcRootDir, 93 dstPath: dstRootDir, 94 } 95 if wantErr, gotErr := tc.wantErr, c.findConfigToUpdate(); (wantErr && (gotErr == nil)) || (!wantErr && (gotErr != nil)) { 96 t.Fatalf("Error mismatch. want: %v, got: %v", wantErr, gotErr) 97 } 98 if diff := cmp.Diff(tc.want, c.paths, cmpopts.SortSlices(func(a, b string) bool { 99 return a < b 100 })); diff != "" { 101 t.Fatalf("Config files mismatch. want(-), got(+):\n%s", diff) 102 } 103 }) 104 } 105 } 106 107 func TestCopyFiles(t *testing.T) { 108 tests := []struct { 109 name string 110 desc string 111 srcNodes []node 112 dstNodes []node 113 paths []string 114 want []node 115 wantErr bool 116 }{ 117 { 118 name: "base", 119 srcNodes: []node{ 120 {Path: "mixins/grafana_dashboards/a.jsonnet", Content: "123"}, 121 {Path: "mixins/prometheus/a.libsonnet", Content: "123"}, 122 }, 123 dstNodes: []node{ 124 {Path: "mixins/grafana_dashboards/a.jsonnet", Content: "456"}, 125 {Path: "mixins/prometheus/a.libsonnet", Content: "456"}, 126 }, 127 paths: []string{ 128 "mixins/grafana_dashboards/a.jsonnet", 129 "mixins/prometheus/a.libsonnet", 130 }, 131 want: []node{ 132 {Path: "mixins/grafana_dashboards/a.jsonnet", Content: "123"}, 133 {Path: "mixins/prometheus/a.libsonnet", Content: "123"}, 134 }, 135 wantErr: false, 136 }, 137 { 138 name: "not exist upstream", 139 srcNodes: []node{ 140 {Path: "mixins/grafana_dashboards/b.jsonnet"}, 141 }, 142 dstNodes: []node{ 143 {Path: "mixins/grafana_dashboards/a.jsonnet"}, 144 }, 145 paths: []string{ 146 "mixins/grafana_dashboards/a.jsonnet", 147 }, 148 want: []node{ 149 {Path: "mixins/grafana_dashboards/a.jsonnet"}, 150 }, 151 wantErr: true, 152 }, 153 } 154 155 for _, tc := range tests { 156 t.Run(tc.name, func(t *testing.T) { 157 tmpDir := t.TempDir() 158 srcRootDir, dstRootDir := seedTempDir(t, tmpDir, tc.srcNodes, tc.dstNodes) 159 c := client{ 160 srcPath: srcRootDir, 161 dstPath: dstRootDir, 162 paths: tc.paths, 163 } 164 if wantErr, gotErr := tc.wantErr, c.copyFiles(); (wantErr && (gotErr == nil)) || (!wantErr && (gotErr != nil)) { 165 t.Fatalf("Error mismatch. want: %v, got: %v", wantErr, gotErr) 166 } 167 var got []node 168 for _, p := range tc.paths { 169 got = append(got, pathToNode(t, dstRootDir, p)) 170 } 171 if diff := cmp.Diff(tc.want, got, cmpopts.SortSlices(func(a, b string) bool { 172 return a < b 173 })); diff != "" { 174 t.Fatalf("Config files mismatch. want(-), got(+):\n%s", diff) 175 } 176 }) 177 } 178 } 179 180 type node struct { 181 Path string 182 Content string 183 IsDir bool 184 } 185 186 func pathToNode(t *testing.T, root, p string) node { 187 n := node{Path: p} 188 189 p = path.Join(root, p) 190 info, err := os.Lstat(p) 191 if err != nil { 192 t.Fatalf("Failed stats %q: %v", p, err) 193 } 194 if info.IsDir() { 195 n.IsDir = true 196 } else { 197 bs, err := os.ReadFile(p) 198 if err != nil { 199 t.Fatalf("Failed to read %q: %v", p, err) 200 } 201 n.Content = string(bs) 202 } 203 204 return n 205 } 206 207 func seedTempDir(t *testing.T, root string, srcNodes, dstNodes []node) (string, string) { 208 srcRootDir := path.Join(root, "src") 209 dstRootDir := path.Join(root, "dst") 210 211 create := func(t *testing.T, root string, ns []node) { 212 for _, n := range ns { 213 p := path.Join(root, n.Path) 214 if n.IsDir { 215 if err := os.MkdirAll(p, 0755); err != nil { 216 t.Fatalf("Failed creating dir %q: %v", p, err) 217 } 218 } else { 219 dir := path.Dir(p) 220 if err := os.MkdirAll(dir, 0755); err != nil { 221 t.Fatalf("Failed creating dir %q: %v", dir, err) 222 } 223 if err := os.WriteFile(p, []byte(n.Content), 0777); err != nil { 224 t.Fatalf("Failed creating file %q: %v", p, err) 225 } 226 } 227 } 228 } 229 230 create(t, srcRootDir, srcNodes) 231 create(t, dstRootDir, dstNodes) 232 233 return srcRootDir, dstRootDir 234 }