v.io/jiri@v0.0.0-20160715023856-abfb8b131290/jiritest/fake.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 jiritest
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"path/filepath"
    11  	"testing"
    12  
    13  	"v.io/jiri"
    14  	"v.io/jiri/gitutil"
    15  	"v.io/jiri/project"
    16  )
    17  
    18  // FakeJiriRoot sets up a fake JIRI_ROOT under a tmp directory.
    19  type FakeJiriRoot struct {
    20  	X        *jiri.X
    21  	Projects map[string]string
    22  	remote   string
    23  }
    24  
    25  const (
    26  	defaultDataDir      = "data"
    27  	manifestFileName    = "public"
    28  	manifestProjectName = "manifest"
    29  	manifestProjectPath = "manifest"
    30  )
    31  
    32  // NewFakeJiriRoot returns a new FakeJiriRoot and a cleanup closure.  The
    33  // closure must be run to cleanup temporary directories and restore the original
    34  // environment; typically it is run as a defer function.
    35  func NewFakeJiriRoot(t *testing.T) (*FakeJiriRoot, func()) {
    36  	jirix, cleanup := NewX(t)
    37  	fake := &FakeJiriRoot{
    38  		X:        jirix,
    39  		Projects: map[string]string{},
    40  	}
    41  
    42  	s := jirix.NewSeq()
    43  	// Create fake remote manifest and tools projects.
    44  	remoteDir, err := s.TempDir("", "")
    45  	if err != nil {
    46  		t.Fatalf("TempDir() failed: %v", err)
    47  	}
    48  	fake.remote = remoteDir
    49  	if err := fake.CreateRemoteProject(manifestProjectPath); err != nil {
    50  		t.Fatal(err)
    51  	}
    52  	// Create a fake manifest.
    53  	manifestDir := filepath.Join(remoteDir, manifestProjectPath)
    54  	if err := s.MkdirAll(manifestDir, os.FileMode(0700)).Done(); err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	if err := fake.WriteRemoteManifest(&project.Manifest{}); err != nil {
    58  		t.Fatal(err)
    59  	}
    60  	// Add the "manifest" project to the manifest.
    61  	if err := fake.AddProject(project.Project{
    62  		Name:   manifestProjectName,
    63  		Path:   manifestProjectPath,
    64  		Remote: fake.Projects[manifestProjectName],
    65  	}); err != nil {
    66  		t.Fatal(err)
    67  	}
    68  	// Create a .jiri_manifest file which imports the manifest created above.
    69  	if err := fake.WriteJiriManifest(&project.Manifest{
    70  		Imports: []project.Import{
    71  			project.Import{
    72  				Manifest: manifestFileName,
    73  				Name:     manifestProjectName,
    74  				Remote:   filepath.Join(fake.remote, manifestProjectPath),
    75  			},
    76  		},
    77  	}); err != nil {
    78  		t.Fatal(err)
    79  	}
    80  
    81  	// Update the contents of the fake JIRI_ROOT instance based on
    82  	// the information recorded in the remote manifest.
    83  	if err := fake.UpdateUniverse(false); err != nil {
    84  		t.Fatal(err)
    85  	}
    86  
    87  	// Create the profiles database directory.
    88  	profilesDB := filepath.Join(jirix.Root, ".jiri_root", "profile_db")
    89  	if err := s.MkdirAll(profilesDB, os.FileMode(0700)).Done(); err != nil {
    90  		t.Fatal(err)
    91  	}
    92  
    93  	return fake, func() {
    94  		cleanup()
    95  		if err := fake.X.NewSeq().RemoveAll(fake.remote).Done(); err != nil {
    96  			t.Fatalf("RemoveAll(%q) failed: %v", fake.remote, err)
    97  		}
    98  	}
    99  }
   100  
   101  // AddProject adds the given project to a remote manifest.
   102  func (fake FakeJiriRoot) AddProject(project project.Project) error {
   103  	manifest, err := fake.ReadRemoteManifest()
   104  	if err != nil {
   105  		return err
   106  	}
   107  	manifest.Projects = append(manifest.Projects, project)
   108  	if err := fake.WriteRemoteManifest(manifest); err != nil {
   109  		return err
   110  	}
   111  	return nil
   112  }
   113  
   114  // AddTool adds the given tool to a remote manifest.
   115  func (fake FakeJiriRoot) AddTool(tool project.Tool) error {
   116  	manifest, err := fake.ReadRemoteManifest()
   117  	if err != nil {
   118  		return err
   119  	}
   120  	manifest.Tools = append(manifest.Tools, tool)
   121  	if err := fake.WriteRemoteManifest(manifest); err != nil {
   122  		return err
   123  	}
   124  	return nil
   125  }
   126  
   127  // DisableRemoteManifestPush disables pushes to the remote manifest
   128  // repository.
   129  func (fake FakeJiriRoot) DisableRemoteManifestPush() error {
   130  	dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProjectPath))
   131  	if err := gitutil.New(fake.X.NewSeq(), dir).CheckoutBranch("master"); err != nil {
   132  		return err
   133  	}
   134  	return nil
   135  }
   136  
   137  // EnableRemoteManifestPush enables pushes to the remote manifest
   138  // repository.
   139  func (fake FakeJiriRoot) EnableRemoteManifestPush() error {
   140  	dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProjectPath))
   141  	if !gitutil.New(fake.X.NewSeq(), dir).BranchExists("non-master") {
   142  		if err := gitutil.New(fake.X.NewSeq(), dir).CreateBranch("non-master"); err != nil {
   143  			return err
   144  		}
   145  	}
   146  	if err := gitutil.New(fake.X.NewSeq(), dir).CheckoutBranch("non-master"); err != nil {
   147  		return err
   148  	}
   149  	return nil
   150  }
   151  
   152  // CreateRemoteProject creates a new remote project.
   153  func (fake FakeJiriRoot) CreateRemoteProject(name string) error {
   154  	projectDir := filepath.Join(fake.remote, name)
   155  	if err := fake.X.NewSeq().MkdirAll(projectDir, os.FileMode(0700)).Done(); err != nil {
   156  		return err
   157  	}
   158  	if err := gitutil.New(fake.X.NewSeq()).Init(projectDir); err != nil {
   159  		return err
   160  	}
   161  	if err := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(projectDir)).CommitWithMessage("initial commit"); err != nil {
   162  		return err
   163  	}
   164  	fake.Projects[name] = projectDir
   165  	return nil
   166  }
   167  
   168  // ReadRemoteManifest read a manifest from the remote manifest project.
   169  func (fake FakeJiriRoot) ReadRemoteManifest() (*project.Manifest, error) {
   170  	path := filepath.Join(fake.remote, manifestProjectPath, manifestFileName)
   171  	return project.ManifestFromFile(fake.X, path)
   172  }
   173  
   174  // UpdateUniverse synchronizes the content of the Vanadium fake based
   175  // on the content of the remote manifest.
   176  func (fake FakeJiriRoot) UpdateUniverse(gc bool) error {
   177  	oldRoot := os.Getenv(jiri.RootEnv)
   178  	if err := os.Setenv(jiri.RootEnv, fake.X.Root); err != nil {
   179  		return fmt.Errorf("Setenv() failed: %v", err)
   180  	}
   181  	defer os.Setenv(jiri.RootEnv, oldRoot)
   182  	if err := project.UpdateUniverse(fake.X, gc); err != nil {
   183  		return err
   184  	}
   185  	return nil
   186  }
   187  
   188  // ReadJiriManifest reads the .jiri_manifest manifest.
   189  func (fake FakeJiriRoot) ReadJiriManifest() (*project.Manifest, error) {
   190  	return project.ManifestFromFile(fake.X, fake.X.JiriManifestFile())
   191  }
   192  
   193  // WriteJiriManifest writes the given manifest to the .jiri_manifest file.
   194  func (fake FakeJiriRoot) WriteJiriManifest(manifest *project.Manifest) error {
   195  	return manifest.ToFile(fake.X, fake.X.JiriManifestFile())
   196  }
   197  
   198  // WriteRemoteManifest writes the given manifest to the remote
   199  // manifest project.
   200  func (fake FakeJiriRoot) WriteRemoteManifest(manifest *project.Manifest) error {
   201  	dir := filepath.Join(fake.remote, manifestProjectPath)
   202  	path := filepath.Join(dir, manifestFileName)
   203  	return fake.writeManifest(manifest, dir, path)
   204  }
   205  
   206  func (fake FakeJiriRoot) writeManifest(manifest *project.Manifest, dir, path string) error {
   207  	git := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(dir))
   208  	if err := manifest.ToFile(fake.X, path); err != nil {
   209  		return err
   210  	}
   211  	if err := git.Add(path); err != nil {
   212  		return err
   213  	}
   214  	if err := git.Commit(); err != nil {
   215  		return err
   216  	}
   217  	return nil
   218  }