github.com/comcast/canticle@v0.0.0-20161108184242-c53cface56e8/canticles/depwalker_test.go (about)

     1  package canticles
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path"
     7  	"testing"
     8  )
     9  
    10  type TestDepRead struct {
    11  	Deps []string
    12  	Err  error
    13  }
    14  
    15  type TestDepReader struct {
    16  	PackageDeps map[string]TestDepRead
    17  }
    18  
    19  func (tdr *TestDepReader) ReadDependencies(p string) ([]string, error) {
    20  	r := tdr.PackageDeps[p]
    21  	return r.Deps, r.Err
    22  }
    23  
    24  type TestWalker struct {
    25  	calls     []string
    26  	responses []error
    27  }
    28  
    29  func (tw *TestWalker) HandlePackage(pkg string) error {
    30  	tw.calls = append(tw.calls, pkg)
    31  	if len(tw.responses) > 0 {
    32  		resp := tw.responses[0]
    33  		tw.responses = tw.responses[1:]
    34  		return resp
    35  	}
    36  	return nil
    37  }
    38  
    39  var NormalReader = &TestDepReader{
    40  	map[string]TestDepRead{
    41  		"testpkg": TestDepRead{[]string{"dep1", "dep2"}, nil},
    42  		"dep1":    TestDepRead{[]string{"dep2"}, nil},
    43  		"dep2":    TestDepRead{},
    44  	},
    45  }
    46  
    47  var NormalReaderResult = []string{"testpkg", "dep1", "dep2"}
    48  
    49  var HandlerErrorResult = []string{"testpkg"}
    50  
    51  var HandlerSkipResult = []string{"testpkg"}
    52  
    53  var CycledReader = &TestDepReader{
    54  	map[string]TestDepRead{
    55  		"testpkg": TestDepRead{[]string{"dep1", "dep2"}, nil},
    56  		"dep1":    TestDepRead{[]string{"dep2"}, nil},
    57  		"dep2":    TestDepRead{[]string{"dep1"}, nil},
    58  	},
    59  }
    60  
    61  var CycleReaderResult = []string{"testpkg", "dep1", "dep2"}
    62  
    63  var ChildErrorReader = &TestDepReader{
    64  	map[string]TestDepRead{
    65  		"testpkg": TestDepRead{[]string{"dep1", "dep2"}, nil},
    66  		"dep1":    TestDepRead{[]string{"dep3"}, nil},
    67  		"dep2":    TestDepRead{},
    68  		"dep3":    TestDepRead{[]string{}, errTest},
    69  	},
    70  }
    71  
    72  var ChildErrorReaderResult = []string{"testpkg", "dep1", "dep2"}
    73  
    74  func CheckResult(t *testing.T, logPrefix string, expected, got []string) {
    75  	for i, v := range expected {
    76  		if v != got[i] {
    77  			t.Errorf("%s expected dep: %+v != got %+v", logPrefix, v, got[i])
    78  		}
    79  	}
    80  }
    81  
    82  func TestTraverseDependencies(t *testing.T) {
    83  	tw := &TestWalker{}
    84  	// Run a test with a reader with normal deps
    85  	dw := NewDependencyWalker(NormalReader.ReadDependencies, tw.HandlePackage)
    86  	err := dw.TraverseDependencies("testpkg")
    87  	if err != nil {
    88  		t.Errorf("Error loading valid pkg %s", err.Error())
    89  	}
    90  	CheckResult(t, "NormalReader", NormalReaderResult, tw.calls)
    91  
    92  	// Run a test with an error from our handler
    93  	tw = &TestWalker{responses: []error{nil, errTest}}
    94  	dw = NewDependencyWalker(NormalReader.ReadDependencies, tw.HandlePackage)
    95  	err = dw.TraverseDependencies("testpkg")
    96  	if err == nil {
    97  		t.Errorf("Error not returned from hanlder")
    98  	}
    99  	CheckResult(t, "HandlerError", HandlerErrorResult, tw.calls)
   100  
   101  	// Run a test with a skip error from our handler
   102  	tw = &TestWalker{responses: []error{nil, ErrorSkip}}
   103  	dw = NewDependencyWalker(NormalReader.ReadDependencies, tw.HandlePackage)
   104  	err = dw.TraverseDependencies("testpkg")
   105  	if err != nil {
   106  		t.Errorf("Error returned when skip form hanlder %s", err.Error())
   107  	}
   108  	CheckResult(t, "HandlerSkip", HandlerSkipResult, tw.calls)
   109  
   110  	// Run a test with a reader with cycled deps, make sure we don't infinite loop
   111  	tw = &TestWalker{}
   112  	dw = NewDependencyWalker(CycledReader.ReadDependencies, tw.HandlePackage)
   113  	err = dw.TraverseDependencies("testpkg")
   114  	if err != nil {
   115  		t.Errorf("Error loading valid pkg %s", err.Error())
   116  	}
   117  	CheckResult(t, "CycledReader", CycleReaderResult, tw.calls)
   118  
   119  	// Run a test with a non loadable package
   120  	tw = &TestWalker{}
   121  	dw = NewDependencyWalker(ChildErrorReader.ReadDependencies, tw.HandlePackage)
   122  	err = dw.TraverseDependencies("testpkg")
   123  	if err == nil {
   124  		t.Errorf("Error loading invvalid pkg %s", err.Error())
   125  	}
   126  	CheckResult(t, "ChildErrorReader", ChildErrorReaderResult, tw.calls)
   127  }
   128  
   129  type TestVCSResolve struct {
   130  	V   VCS
   131  	Err error
   132  }
   133  
   134  type TestResolver struct {
   135  	ResolvePaths map[string]*TestVCSResolve
   136  }
   137  
   138  func (tr *TestResolver) ResolveRepo(importPath string, dep *CanticleDependency) (VCS, error) {
   139  	r := tr.ResolvePaths[importPath]
   140  	return r.V, r.Err
   141  }
   142  
   143  type TestDependencyRead struct {
   144  	Deps Dependencies
   145  	Err  error
   146  }
   147  
   148  type TestDependencyReader struct {
   149  	PackageDeps map[string]TestDependencyRead
   150  }
   151  
   152  func (tdr *TestDependencyReader) ReadDependencies(p string) (Dependencies, error) {
   153  	r := tdr.PackageDeps[p]
   154  	return r.Deps, r.Err
   155  }
   156  
   157  func TestDependencyLoader(t *testing.T) {
   158  	// Create our
   159  	testHome, err := ioutil.TempDir("", "cant-test")
   160  	if err != nil {
   161  		t.Fatalf("Error creating tempdir: %s", err.Error())
   162  	}
   163  	defer os.RemoveAll(testHome)
   164  	if err := os.MkdirAll(path.Join(testHome, "src", "pkg1", "child"), 0755); err != nil {
   165  		t.Fatal(err)
   166  	}
   167  	pkg1dep := map[string]*Dependency{
   168  		"pkg1/child": NewDependency("pkg1/child"),
   169  	}
   170  	pkg1childdep := map[string]*Dependency{
   171  		"pkg2/child": NewDependency("pkg2/child"),
   172  	}
   173  	deps := &TestDependencyReader{
   174  		map[string]TestDependencyRead{
   175  			testHome + "/src/" + "pkg1":       TestDependencyRead{pkg1dep, nil},
   176  			testHome + "/src/" + "pkg1/child": TestDependencyRead{pkg1childdep, nil},
   177  			testHome + "/src/" + "pkg2":       TestDependencyRead{NewDependencies(), nil},
   178  			testHome + "/src/" + "pkg2/child": TestDependencyRead{NewDependencies(), nil},
   179  		},
   180  	}
   181  
   182  	cdeps := []*CanticleDependency{
   183  		&CanticleDependency{Root: "pkg1"},
   184  		&CanticleDependency{Root: "pkg2"},
   185  	}
   186  	pkg1vcs := &TestVCS{}
   187  	pkg2vcs := &TestVCS{}
   188  	tr := &TestResolver{map[string]*TestVCSResolve{
   189  		"pkg1":       &TestVCSResolve{pkg1vcs, nil},
   190  		"pkg1/child": &TestVCSResolve{pkg1vcs, nil},
   191  		"pkg2":       &TestVCSResolve{pkg2vcs, nil},
   192  		"pkg2/child": &TestVCSResolve{pkg2vcs, nil},
   193  	}}
   194  	dl := NewDependencyLoader(tr, deps.ReadDependencies, cdeps, testHome)
   195  	if err := dl.FetchUpdatePackage("pkg1"); err != nil {
   196  		t.Errorf("Error fetching pkg1: %s", err.Error())
   197  	}
   198  	pkgImports, err := dl.PackageImports("pkg1")
   199  	if err != nil {
   200  		t.Errorf("Error getting imports for pkg1: %s", err.Error())
   201  	}
   202  	if pkgImports[0] != "pkg1/child" {
   203  		t.Errorf("Expected pkg1 to have imports pkg1/child got: %s", pkgImports[0])
   204  	}
   205  	if pkg1vcs.Created != 0 {
   206  		t.Errorf("Expected pkg1vcs to have no creates: %d", pkg1vcs.Created)
   207  	}
   208  	if err := dl.FetchUpdatePackage("pkg1/child"); err != nil {
   209  		t.Errorf("Error fetching pkg1: %s", err.Error())
   210  	}
   211  	pkgImports, err = dl.PackageImports("pkg1/child")
   212  	if err != nil {
   213  		t.Errorf("Error getting imports for pkg1: %s", err.Error())
   214  	}
   215  	if pkgImports[0] != "pkg2/child" {
   216  		t.Errorf("Expected pkg1 to have imports pkg2/child got: %s", pkgImports[0])
   217  	}
   218  	if pkg1vcs.Created != 0 {
   219  		t.Errorf("Expected pkg1vcs to have no creates: %d", pkg1vcs.Created)
   220  	}
   221  
   222  	if err := dl.FetchUpdatePackage("pkg2/child"); err != nil {
   223  		t.Errorf("Error fetching pkg2: %s", err.Error())
   224  	}
   225  	pkgImports, err = dl.PackageImports("pkg2/child")
   226  	if err != nil {
   227  		t.Errorf("Error getting imports for pkg2: %s", err.Error())
   228  	}
   229  	if len(pkgImports) != 0 {
   230  		t.Errorf("Expected pkg2 to have no imports pkg2/child got: %d", len(pkgImports))
   231  	}
   232  	if pkg2vcs.Created != 1 {
   233  		t.Errorf("Expected pkg2vcs to have 1 create: %d", pkg2vcs.Created)
   234  	}
   235  
   236  }