v.io/jiri@v0.0.0-20160715023856-abfb8b131290/profiles/manifest_test.go (about) 1 // Copyright 2015 The Vanadium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package profiles_test 6 7 import ( 8 "bufio" 9 "bytes" 10 "io/ioutil" 11 "os" 12 "path/filepath" 13 "reflect" 14 "regexp" 15 "strings" 16 "testing" 17 18 "v.io/jiri/jiritest" 19 "v.io/jiri/profiles" 20 ) 21 22 func addProfileAndTargets(t *testing.T, pdb *profiles.DB, name string) { 23 t1, _ := profiles.NewTarget("cpu1-os1@1", "A=B,C=D") 24 t2, _ := profiles.NewTarget("cpu2-os2@bar", "A=B,C=D") 25 pdb.InstallProfile("test", name, "") 26 if err := pdb.AddProfileTarget("test", name, t1); err != nil { 27 t.Fatal(err) 28 } 29 t2.InstallationDir = "bar" 30 if err := pdb.AddProfileTarget("test", name, t2); err != nil { 31 t.Fatal(err) 32 } 33 } 34 35 func tmpFile() string { 36 dirname, err := ioutil.TempDir("", "pdb") 37 if err != nil { 38 panic(err) 39 } 40 return filepath.Join(dirname, "manifest") 41 } 42 43 func removeDate(s string) string { 44 var result bytes.Buffer 45 scanner := bufio.NewScanner(bytes.NewBufferString(s)) 46 re := regexp.MustCompile("(.*) date=\".*\"") 47 for scanner.Scan() { 48 result.WriteString(re.ReplaceAllString(scanner.Text(), "$1")) 49 result.WriteString("\n") 50 } 51 return strings.TrimSpace(result.String()) 52 } 53 54 func TestWrite(t *testing.T) { 55 pdb := profiles.NewDB() 56 jirix, cleanup := jiritest.NewX(t) 57 defer cleanup() 58 filename := tmpFile() 59 defer os.RemoveAll(filepath.Dir(filename)) 60 61 // test for no version being set. 62 t1, _ := profiles.NewTarget("cpu1-os1", "A=B,C=D") 63 pdb.InstallProfile("test", "b", "") 64 if err := pdb.AddProfileTarget("test", "b", t1); err != nil { 65 t.Fatal(err) 66 } 67 if err := pdb.Write(jirix, "test", filename); err == nil || !strings.HasPrefix(err.Error(), "missing version for profile") { 68 t.Fatalf("was expecing a missing version error, but got %v", err) 69 } 70 pdb.RemoveProfileTarget("test", "b", t1) 71 72 addProfileAndTargets(t, pdb, "b") 73 addProfileAndTargets(t, pdb, "a") 74 if err := pdb.Write(jirix, "test", filename); err != nil { 75 t.Fatal(err) 76 } 77 78 g, _ := ioutil.ReadFile(filename) 79 w, _ := ioutil.ReadFile("./testdata/m1.xml") 80 if got, want := removeDate(strings.TrimSpace(string(g))), strings.TrimSpace(string(w)); got != want { 81 t.Fatalf("got %v, want %v", got, want) 82 } 83 } 84 85 func exists(t *testing.T, filename string) bool { 86 fi, err := os.Stat(filename) 87 if err != nil { 88 if !os.IsNotExist(err) { 89 t.Fatal(err) 90 } 91 return false 92 } 93 return fi.Size() > 0 94 } 95 96 func TestWriteAndRename(t *testing.T) { 97 pdb := profiles.NewDB() 98 jirix, cleanup := jiritest.NewX(t) 99 defer cleanup() 100 filename := tmpFile() 101 defer os.RemoveAll(filepath.Dir(filename)) 102 103 addProfileAndTargets(t, pdb, "b") 104 105 if exists(t, filename) { 106 t.Fatalf("%q exists", filename) 107 } 108 if exists(t, filename+".prev") { 109 t.Fatalf("%q exists", filename+".prev") 110 } 111 if err := pdb.Write(jirix, "test", filename); err != nil { 112 t.Fatal(err) 113 } 114 115 if !exists(t, filename) { 116 t.Fatalf("%q exists", filename) 117 } 118 if exists(t, filename+".prev") { 119 t.Fatalf("%q exists", filename+".prev") 120 } 121 122 if err := pdb.Write(jirix, "test", filename); err != nil { 123 t.Fatal(err) 124 } 125 126 if !exists(t, filename) { 127 t.Fatalf("%q does not exist", filename) 128 } 129 if !exists(t, filename+".prev") { 130 t.Fatalf("%q does not exist", filename+".prev") 131 } 132 } 133 134 func TestWriteDir(t *testing.T) { 135 pdb := profiles.NewDB() 136 jirix, cleanup := jiritest.NewX(t) 137 defer cleanup() 138 dir, err := ioutil.TempDir("", "pdb-") 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 t1, _ := profiles.NewTarget("cpu1-os1@1", "A=B,C=D") 144 pdb.InstallProfile("i1", "b", "") 145 if err := pdb.AddProfileTarget("i1", "b", t1); err != nil { 146 t.Fatal(err) 147 } 148 149 t2, _ := profiles.NewTarget("cpu1-os1@2", "A=B,C=D") 150 pdb.InstallProfile("i2", "b", "") 151 if err := pdb.AddProfileTarget("i2", "b", t2); err != nil { 152 t.Fatal(err) 153 } 154 155 // Write out i1 installer's data 156 if err := pdb.Write(jirix, "i1", dir); err != nil { 157 t.Fatal(err) 158 } 159 if f := filepath.Join(dir, "i1"); !exists(t, f) { 160 t.Errorf("%s doesn't exist", f) 161 } 162 if f := filepath.Join(dir, "i2"); exists(t, f) { 163 t.Errorf("%s exists", f) 164 } 165 166 // Write out i2 installer's data 167 if err := pdb.Write(jirix, "i2", dir); err != nil { 168 t.Fatal(err) 169 } 170 if f := filepath.Join(dir, "i1"); !exists(t, f) { 171 t.Errorf("%s doesn't exist", f) 172 } 173 if f := filepath.Join(dir, "i2"); !exists(t, f) { 174 t.Errorf("%s doesn't exist", f) 175 } 176 } 177 178 func TestRead(t *testing.T) { 179 pdb := profiles.NewDB() 180 jirix, cleanup := jiritest.NewX(t) 181 defer cleanup() 182 if err := pdb.Read(jirix, "./testdata/m1.xml"); err != nil { 183 t.Fatal(err) 184 } 185 names := pdb.Names() 186 if got, want := names, []string{"test:a", "test:b"}; !reflect.DeepEqual(got, want) { 187 t.Fatalf("got %v, want %v", got, want) 188 } 189 p := pdb.LookupProfile("test", "a") 190 if got, want := p.Targets()[0].OS(), "os1"; got != want { 191 t.Errorf("got %v, want %v", got, want) 192 } 193 if got, want := p.Targets()[1].Version(), "bar"; got != want { 194 t.Errorf("got %v, want %v", got, want) 195 } 196 } 197 198 func TestReadDir(t *testing.T) { 199 pdb := profiles.NewDB() 200 jirix, cleanup := jiritest.NewX(t) 201 defer cleanup() 202 if err := pdb.Read(jirix, "./testdata/old_version"); err == nil || !strings.Contains(err.Error(), "files must be at version") { 203 t.Fatalf("missing or wrong error: %v", err) 204 } 205 if err := pdb.Read(jirix, "./testdata/mismatched_versions"); err == nil || !strings.Contains(err.Error(), "files must have the same version") { 206 t.Fatalf("missing or wrong error: %v", err) 207 } 208 if err := pdb.Read(jirix, "./testdata/db_dir"); err != nil { 209 t.Fatal(err) 210 } 211 names := pdb.Names() 212 if got, want := names, []string{"m1:a", "m1:b", "m2:a", "m2:b"}; !reflect.DeepEqual(got, want) { 213 t.Fatalf("got %v, want %v", got, want) 214 } 215 profile := pdb.LookupProfile("m2", "a") 216 if got, want := profile.Root(), "root"; got != want { 217 t.Errorf("got %v, want %v", got, want) 218 } 219 profile = pdb.LookupProfile("m1", "b") 220 if got, want := profile.Root(), "r1"; got != want { 221 t.Errorf("got %v, want %v", got, want) 222 } 223 } 224 225 func TestReadDirWithPrevFiles(t *testing.T) { 226 pdb := profiles.NewDB() 227 jirix, cleanup := jiritest.NewX(t) 228 defer cleanup() 229 if err := pdb.Read(jirix, "./testdata/db_dir_with_prev"); err != nil { 230 t.Fatal(err) 231 } 232 names := pdb.Names() 233 if got, want := names, []string{"m1:a", "m2:b"}; !reflect.DeepEqual(got, want) { 234 t.Fatalf("got %v, want %v", got, want) 235 } 236 profile := pdb.LookupProfile("m1", "a") 237 if got, want := profile.Root(), "root"; got != want { 238 t.Errorf("got %v, want %v", got, want) 239 } 240 profile = pdb.LookupProfile("m2", "b") 241 if got, want := profile.Root(), "r2"; got != want { 242 t.Errorf("got %v, want %v", got, want) 243 } 244 } 245 246 func TestInstallProfile(t *testing.T) { 247 pdb := profiles.NewDB() 248 pdb.InstallProfile("test", "a", "root1") 249 pdb.InstallProfile("test", "a", "root2") 250 profile := pdb.LookupProfile("test", "a") 251 if got, want := profile.Root(), "root1"; got != want { 252 t.Errorf("got %v, want %v", got, want) 253 } 254 } 255 256 func TestReadingV0(t *testing.T) { 257 pdb := profiles.NewDB() 258 jirix, cleanup := jiritest.NewX(t) 259 defer cleanup() 260 261 if err := pdb.Read(jirix, "./testdata/legacy.xml"); err != nil { 262 t.Fatal(err) 263 } 264 265 if got, want := pdb.SchemaVersion(), profiles.Original; got != want { 266 t.Errorf("got %v, want %v", got, want) 267 } 268 269 oprofiles := pdb.Profiles() 270 if got, want := len(oprofiles), 5; got != want { 271 t.Errorf("got %v, want %v", got, want) 272 } 273 filename := tmpFile() 274 defer os.RemoveAll(filepath.Dir(filename)) 275 276 var t1 profiles.Target 277 t1.Set("cpu-os@1") 278 pdb.InstallProfile("", "__first", "") 279 if err := pdb.AddProfileTarget("", "__first", t1); err != nil { 280 t.Fatal(err) 281 } 282 283 if err := pdb.Write(jirix, "", filename); err != nil { 284 t.Fatal(err) 285 } 286 287 if err := pdb.Read(jirix, filename); err != nil { 288 t.Fatal(err) 289 } 290 291 if got, want := pdb.SchemaVersion(), profiles.V5; got != want { 292 t.Errorf("got %v, want %v", got, want) 293 } 294 nprofiles := pdb.Profiles() 295 if got, want := len(nprofiles), 6; got != want { 296 t.Fatalf("got %v, want %v", got, want) 297 } 298 299 if got, want := nprofiles[0].Name(), "__first"; got != want { 300 t.Errorf("got %v, want %v", got, want) 301 } 302 303 for i, v := range nprofiles[1:] { 304 if got, want := v.Name(), oprofiles[i].Name(); got != want { 305 t.Errorf("got %v, want %v", got, want) 306 } 307 } 308 } 309 310 func TestReadingV3AndV4(t *testing.T) { 311 fake, cleanup := jiritest.NewFakeJiriRoot(t) 312 defer cleanup() 313 for i, c := range []struct { 314 filename, prefix, variable string 315 version profiles.Version 316 }{ 317 {"v3.xml", "", "", profiles.V3}, 318 {"v4.xml", fake.X.Root, "${JIRI_ROOT}", profiles.V4}, 319 } { 320 pdb := profiles.NewDB() 321 err := pdb.Read(fake.X, filepath.Join("testdata", c.filename)) 322 if err != nil { 323 t.Fatal(err) 324 } 325 if got, want := pdb.SchemaVersion(), c.version; got != want { 326 t.Errorf("%d: got %v, want %v", i, got, want) 327 } 328 target, err := profiles.NewTarget("cpu1-os1@1", "") 329 if err != nil { 330 t.Fatal(err) 331 } 332 p := pdb.LookupProfile("", "a") 333 // We need to expand the variable here for a V4 profile if we want 334 // to get the full absolute path. 335 if got, want := p.Root(), c.variable+"/an/absolute/root"; got != want { 336 t.Errorf("%d: got %v, want %v", i, got, want) 337 } 338 lt := pdb.LookupProfileTarget("", "a", target) 339 if got, want := lt.InstallationDir, c.variable+"/an/absolute/dir"; got != want { 340 t.Errorf("%d: got %v, want %v", i, got, want) 341 } 342 } 343 } 344 345 func TestQualifiedNames(t *testing.T) { 346 for i, c := range []struct{ i, p, e string }{ 347 {"a", "b", "a:b"}, 348 {"a", ":b", "a:b"}, 349 {"a", "", "a:"}, 350 {"", "b", "b"}, 351 {"", "", ""}, 352 } { 353 if got, want := profiles.QualifiedProfileName(c.i, c.p), c.e; got != want { 354 t.Errorf("%d: got %v, want %v", i, got, want) 355 } 356 } 357 for i, c := range []struct{ q, i, p string }{ 358 {"aa:bb", "aa", "bb"}, 359 {":bb", "", "bb"}, 360 {"bb", "", "bb"}, 361 {"", "", ""}, 362 {":bb", "", "bb"}, 363 } { 364 gi, gp := profiles.SplitProfileName(c.q) 365 if got, want := gi, c.i; got != want { 366 t.Errorf("%d: got %v, want %v", i, got, want) 367 } 368 if got, want := gp, c.p; got != want { 369 t.Errorf("%d: got %v, want %v", i, got, want) 370 } 371 } 372 373 if got, want := profiles.QualifiedProfileName("new", "old:bar"), "new:bar"; got != want { 374 t.Errorf("got %v, want %v", got, want) 375 } 376 377 }