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  }