github.com/btwiuse/jiri@v0.0.0-20191125065820-53353bcfef54/cmd/jiri/override_test.go (about)

     1  // Copyright 2018 The Fuchsia 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 main
     6  
     7  import (
     8  	"fmt"
     9  	"io/ioutil"
    10  	"os"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/btwiuse/jiri/jiritest/xtest"
    15  	"github.com/btwiuse/jiri/project"
    16  )
    17  
    18  type overrideTestCase struct {
    19  	Args           []string
    20  	Filename       string
    21  	OutputFileName string
    22  	Exist, Want    string
    23  	Stdout, Stderr string
    24  	SetFlags       func()
    25  	runOnce        bool
    26  }
    27  
    28  func setDefaultOverrideFlags() {
    29  	overrideFlags.importManifest = ""
    30  	overrideFlags.path = ""
    31  	overrideFlags.revision = ""
    32  	overrideFlags.gerritHost = ""
    33  	overrideFlags.delete = false
    34  	overrideFlags.list = false
    35  	overrideFlags.JSONOutput = ""
    36  }
    37  
    38  func TestOverride(t *testing.T) {
    39  	tests := []overrideTestCase{
    40  		{
    41  			Stderr: `wrong number of arguments`,
    42  		},
    43  		{
    44  			Args:   []string{"a"},
    45  			Stderr: `wrong number of arguments`,
    46  		},
    47  		{
    48  			Args:   []string{"a", "b", "c"},
    49  			Stderr: `wrong number of arguments`,
    50  		},
    51  		// Remote imports, default append behavior
    52  		{
    53  			Args: []string{"foo", "https://github.com/new.git"},
    54  			Want: `<manifest>
    55    <imports>
    56      <import manifest="manifest" name="foo" remote="https://github.com/new.git"/>
    57    </imports>
    58    <overrides>
    59      <project name="foo" remote="https://github.com/new.git"/>
    60    </overrides>
    61  </manifest>
    62  `,
    63  		},
    64  		{
    65  			SetFlags: func() {
    66  				overrideFlags.path = "bar"
    67  			},
    68  			Args: []string{"foo", "https://github.com/new.git"},
    69  			Want: `<manifest>
    70    <imports>
    71      <import manifest="manifest" name="foo" remote="https://github.com/new.git"/>
    72    </imports>
    73    <overrides>
    74      <project name="foo" path="bar" remote="https://github.com/new.git"/>
    75    </overrides>
    76  </manifest>
    77  `,
    78  		},
    79  		{
    80  			SetFlags: func() {
    81  				overrideFlags.revision = "bar"
    82  			},
    83  			Args: []string{"foo", "https://github.com/new.git"},
    84  			Want: `<manifest>
    85    <imports>
    86      <import manifest="manifest" name="foo" remote="https://github.com/new.git"/>
    87    </imports>
    88    <overrides>
    89      <project name="foo" remote="https://github.com/new.git" revision="bar"/>
    90    </overrides>
    91  </manifest>
    92  `,
    93  		},
    94  		{
    95  			SetFlags: func() {
    96  				overrideFlags.list = true
    97  				overrideFlags.JSONOutput = "file"
    98  			},
    99  			Exist: `<manifest>
   100    <imports>
   101      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   102    </imports>
   103    <overrides>
   104      <project name="foo" remote="https://github.com/new.git"/>
   105    </overrides>
   106  </manifest>
   107  `,
   108  			OutputFileName: `file`,
   109  			Want: `[
   110    {
   111      "name": "foo",
   112      "remote": "https://github.com/new.git",
   113      "revision": "HEAD"
   114    }
   115  ]
   116  `,
   117  		},
   118  		{
   119  			SetFlags: func() {
   120  				overrideFlags.list = true
   121  			},
   122  			Exist: `<manifest>
   123    <imports>
   124      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   125    </imports>
   126    <overrides>
   127      <project name="foo" remote="https://github.com/new.git"/>
   128    </overrides>
   129  </manifest>
   130  `,
   131  			Stdout: `* override foo
   132    Name:        foo
   133    Remote:      https://github.com/new.git
   134  `,
   135  		},
   136  		{
   137  			Args: []string{"bar", "https://github.com/bar.git"},
   138  			Exist: `<manifest>
   139    <imports>
   140      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   141    </imports>
   142    <overrides>
   143      <project name="foo" remote="https://github.com/foo.git"/>
   144    </overrides>
   145  </manifest>
   146  `,
   147  			Want: `<manifest>
   148    <imports>
   149      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   150    </imports>
   151    <overrides>
   152      <project name="foo" remote="https://github.com/foo.git"/>
   153      <project name="bar" remote="https://github.com/bar.git"/>
   154    </overrides>
   155  </manifest>
   156  `,
   157  		},
   158  		// test delete flag
   159  		{
   160  			SetFlags: func() {
   161  				overrideFlags.delete = true
   162  			},
   163  			Stderr:  `wrong number of arguments`,
   164  			runOnce: true,
   165  		},
   166  		{
   167  			SetFlags: func() {
   168  				overrideFlags.delete = true
   169  			},
   170  			Args:    []string{"a", "b", "c"},
   171  			Stderr:  `wrong number of arguments`,
   172  			runOnce: true,
   173  		},
   174  		{
   175  			SetFlags: func() {
   176  				overrideFlags.delete = true
   177  				overrideFlags.list = true
   178  			},
   179  			Args:    []string{"a", "b"},
   180  			Stderr:  `cannot use -delete and -list together`,
   181  			runOnce: true,
   182  		},
   183  		{
   184  			SetFlags: func() {
   185  				overrideFlags.delete = true
   186  			},
   187  			Args:    []string{"foo"},
   188  			runOnce: true,
   189  			Exist: `<manifest>
   190    <imports>
   191      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   192    </imports>
   193    <overrides>
   194      <project name="foo" remote="https://github.com/foo.git"/>
   195      <project name="bar" remote="https://github.com/bar.git"/>
   196    </overrides>
   197  </manifest>
   198  `,
   199  			Want: `<manifest>
   200    <imports>
   201      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   202    </imports>
   203    <overrides>
   204      <project name="bar" remote="https://github.com/bar.git"/>
   205    </overrides>
   206  </manifest>
   207  `,
   208  		},
   209  		{
   210  			SetFlags: func() {
   211  				overrideFlags.delete = true
   212  			},
   213  			Args:    []string{"foo"},
   214  			runOnce: true,
   215  			Exist: `<manifest>
   216    <imports>
   217      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   218    </imports>
   219    <overrides>
   220      <project name="foo" remote="https://github.com/foo.git"/>
   221      <project name="foo" remote="https://github.com/bar.git"/>
   222    </overrides>
   223  </manifest>
   224  `,
   225  			Stderr: `more than one override matches`,
   226  		},
   227  		{
   228  			SetFlags: func() {
   229  				overrideFlags.delete = true
   230  			},
   231  			Args:    []string{"foo", "https://github.com/bar.git"},
   232  			runOnce: true,
   233  			Exist: `<manifest>
   234    <imports>
   235      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   236    </imports>
   237    <overrides>
   238      <project name="foo" remote="https://github.com/foo.git"/>
   239      <project name="foo" remote="https://github.com/bar.git"/>
   240    </overrides>
   241  </manifest>
   242  `,
   243  			Want: `<manifest>
   244    <imports>
   245      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   246    </imports>
   247    <overrides>
   248      <project name="foo" remote="https://github.com/foo.git"/>
   249    </overrides>
   250  </manifest>
   251  `,
   252  		},
   253  		{
   254  			SetFlags: func() {
   255  				overrideFlags.importManifest = "manifest"
   256  				overrideFlags.revision = "eabeadae97b1e7f97ba93206066411adfe93a509"
   257  			},
   258  			Args:    []string{"orig", "https://github.com/orig.git"},
   259  			runOnce: true,
   260  			Exist: `<manifest>
   261    <imports>
   262      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   263    </imports>
   264  </manifest>
   265  `,
   266  			Want: `<manifest>
   267    <imports>
   268      <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/>
   269    </imports>
   270    <overrides>
   271      <import manifest="manifest" name="orig" remote="https://github.com/orig.git" revision="eabeadae97b1e7f97ba93206066411adfe93a509"/>
   272    </overrides>
   273  </manifest>
   274  `,
   275  		},
   276  	}
   277  
   278  	// Temporary directory in which our jiri binary will live.
   279  	binDir, err := ioutil.TempDir("", "")
   280  	if err != nil {
   281  		t.Fatal(err)
   282  	}
   283  	defer os.RemoveAll(binDir)
   284  
   285  	for _, test := range tests {
   286  		if err := testOverride(t, test); err != nil {
   287  			t.Errorf("%v: %v", test.Args, err)
   288  		}
   289  	}
   290  }
   291  
   292  func testOverride(t *testing.T, test overrideTestCase) error {
   293  	jirix, cleanup := xtest.NewX(t)
   294  	defer cleanup()
   295  	// Temporary directory in which to run `jiri import`.
   296  	tmpDir, err := ioutil.TempDir("", "")
   297  	if err != nil {
   298  		return err
   299  	}
   300  	defer os.RemoveAll(tmpDir)
   301  
   302  	// Create a .jiri_manifest file which imports the manifest created above.
   303  	manifest := project.Manifest{
   304  		Imports: []project.Import{
   305  			project.Import{
   306  				Manifest: "manifest",
   307  				Name:     "foo",
   308  				Remote:   "https://github.com/new.git",
   309  			},
   310  		},
   311  	}
   312  	if err := manifest.ToFile(jirix, jirix.JiriManifestFile()); err != nil {
   313  		t.Fatal(err)
   314  	}
   315  
   316  	// Return to the current working directory when done.
   317  	cwd, err := os.Getwd()
   318  	if err != nil {
   319  		return err
   320  	}
   321  	defer os.Chdir(cwd)
   322  
   323  	// cd into a root directory in which to do the actual import.
   324  	jiriRoot := jirix.Root
   325  	if err := os.Chdir(jiriRoot); err != nil {
   326  		return err
   327  	}
   328  
   329  	// Allow optional non-default filenames.
   330  	filename := test.Filename
   331  	if filename == "" {
   332  		filename = ".jiri_manifest"
   333  	}
   334  
   335  	// Set up an existing file if it was specified.
   336  	if test.Exist != "" {
   337  		if err := ioutil.WriteFile(filename, []byte(test.Exist), 0644); err != nil {
   338  			return err
   339  		}
   340  	}
   341  
   342  	run := func() error {
   343  		// Run override and check the results.
   344  		overrideCmd := func() {
   345  			setDefaultOverrideFlags()
   346  			if test.SetFlags != nil {
   347  				test.SetFlags()
   348  			}
   349  			err = runOverride(jirix, test.Args)
   350  		}
   351  		stdout, _, runErr := runfunc(overrideCmd)
   352  		if runErr != nil {
   353  			return err
   354  		}
   355  		stderr := ""
   356  		if err != nil {
   357  			stderr = err.Error()
   358  		}
   359  		if got, want := stdout, test.Stdout; !strings.Contains(got, want) || (got != "" && want == "") {
   360  			return fmt.Errorf("stdout got %q, want substr %q", got, want)
   361  		}
   362  		if got, want := stderr, test.Stderr; !strings.Contains(got, want) || (got != "" && want == "") {
   363  			return fmt.Errorf("stderr got %q, want substr %q", got, want)
   364  		}
   365  		return nil
   366  	}
   367  	if err := run(); err != nil {
   368  		return err
   369  	}
   370  
   371  	// check that it is idempotent
   372  	if !test.runOnce {
   373  		if err := run(); err != nil {
   374  			return err
   375  		}
   376  	}
   377  	f := test.OutputFileName
   378  	if f == "" {
   379  		f = filename
   380  	}
   381  
   382  	// Make sure the right file is generated.
   383  	if test.Want != "" {
   384  		data, err := ioutil.ReadFile(f)
   385  		if err != nil {
   386  			return err
   387  		}
   388  		if got, want := string(data), test.Want; got != want {
   389  			return fmt.Errorf("GOT\n%s\nWANT\n%s", got, want)
   390  		}
   391  	}
   392  	return nil
   393  }