github.com/golang/dep@v0.5.4/gps/version_queue_test.go (about)

     1  // Copyright 2017 The Go 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 gps
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // just need a listVersions method
    14  type fakeBridge struct {
    15  	*bridge
    16  	vl []Version
    17  }
    18  
    19  var fakevl = []Version{
    20  	NewVersion("v2.0.0").Pair("200rev"),
    21  	NewVersion("v1.1.1").Pair("111rev"),
    22  	NewVersion("v1.1.0").Pair("110rev"),
    23  	NewVersion("v1.0.0").Pair("100rev"),
    24  	NewBranch("master").Pair("masterrev"),
    25  }
    26  
    27  func init() {
    28  	SortForUpgrade(fakevl)
    29  }
    30  
    31  func (fb *fakeBridge) listVersions(id ProjectIdentifier) ([]Version, error) {
    32  	// it's a fixture, we only ever do the one, regardless of id
    33  	return fb.vl, nil
    34  }
    35  
    36  type fakeFailBridge struct {
    37  	*bridge
    38  }
    39  
    40  var errVQ = errors.New("vqerr")
    41  
    42  func (fb *fakeFailBridge) listVersions(id ProjectIdentifier) ([]Version, error) {
    43  	return nil, errVQ
    44  }
    45  
    46  func TestVersionQueueSetup(t *testing.T) {
    47  	id := ProjectIdentifier{ProjectRoot: ProjectRoot("foo")}.normalize()
    48  
    49  	// shouldn't even need to embed a real bridge
    50  	fb := &fakeBridge{vl: fakevl}
    51  	ffb := &fakeFailBridge{}
    52  
    53  	_, err := newVersionQueue(id, nil, nil, ffb)
    54  	if err == nil {
    55  		t.Error("Expected err when providing no prefv or lockv, and injected bridge returns err from ListVersions()")
    56  	}
    57  
    58  	vq, err := newVersionQueue(id, nil, nil, fb)
    59  	if err != nil {
    60  		t.Errorf("Unexpected err on vq create: %s", err)
    61  	} else {
    62  		if len(vq.pi) != 5 {
    63  			t.Errorf("Should have five versions from listVersions() when providing no prefv or lockv; got %v:\n\t%s", len(vq.pi), vq.String())
    64  		}
    65  		if !vq.allLoaded {
    66  			t.Errorf("allLoaded flag should be set, but wasn't")
    67  		}
    68  
    69  		if vq.prefv != nil || vq.lockv != nil {
    70  			t.Error("lockv and prefv should be nil")
    71  		}
    72  		if vq.current() != fakevl[0] {
    73  			t.Errorf("current should be head of fakevl (%s), got %s", fakevl[0], vq.current())
    74  		}
    75  	}
    76  
    77  	lockv := fakevl[0]
    78  	prefv := fakevl[1]
    79  	vq, err = newVersionQueue(id, lockv, nil, fb)
    80  	if err != nil {
    81  		t.Errorf("Unexpected err on vq create: %s", err)
    82  	} else {
    83  		if len(vq.pi) != 1 {
    84  			t.Errorf("Should have one version when providing only a lockv; got %v:\n\t%s", len(vq.pi), vq.String())
    85  		}
    86  		if vq.allLoaded {
    87  			t.Errorf("allLoaded flag should not be set")
    88  		}
    89  		if vq.lockv != lockv {
    90  			t.Errorf("lockv should be %s, was %s", lockv, vq.lockv)
    91  		}
    92  		if vq.current() != lockv {
    93  			t.Errorf("current should be lockv (%s), got %s", lockv, vq.current())
    94  		}
    95  	}
    96  
    97  	vq, err = newVersionQueue(id, nil, prefv, fb)
    98  	if err != nil {
    99  		t.Errorf("Unexpected err on vq create: %s", err)
   100  	} else {
   101  		if len(vq.pi) != 1 {
   102  			t.Errorf("Should have one version when providing only a prefv; got %v:\n\t%s", len(vq.pi), vq.String())
   103  		}
   104  		if vq.allLoaded {
   105  			t.Errorf("allLoaded flag should not be set")
   106  		}
   107  		if vq.prefv != prefv {
   108  			t.Errorf("prefv should be %s, was %s", prefv, vq.prefv)
   109  		}
   110  		if vq.current() != prefv {
   111  			t.Errorf("current should be prefv (%s), got %s", prefv, vq.current())
   112  		}
   113  	}
   114  
   115  	vq, err = newVersionQueue(id, lockv, prefv, fb)
   116  	if err != nil {
   117  		t.Errorf("Unexpected err on vq create: %s", err)
   118  	} else {
   119  		if len(vq.pi) != 2 {
   120  			t.Errorf("Should have two versions when providing both a prefv and lockv; got %v:\n\t%s", len(vq.pi), vq.String())
   121  		}
   122  		if vq.allLoaded {
   123  			t.Errorf("allLoaded flag should not be set")
   124  		}
   125  		if vq.prefv != prefv {
   126  			t.Errorf("prefv should be %s, was %s", prefv, vq.prefv)
   127  		}
   128  		if vq.lockv != lockv {
   129  			t.Errorf("lockv should be %s, was %s", lockv, vq.lockv)
   130  		}
   131  		if vq.current() != lockv {
   132  			t.Errorf("current should be lockv (%s), got %s", lockv, vq.current())
   133  		}
   134  	}
   135  }
   136  
   137  func TestVersionQueueAdvance(t *testing.T) {
   138  	fb := &fakeBridge{vl: fakevl}
   139  	id := ProjectIdentifier{ProjectRoot: ProjectRoot("foo")}.normalize()
   140  
   141  	// First with no prefv or lockv
   142  	vq, err := newVersionQueue(id, nil, nil, fb)
   143  	if err != nil {
   144  		t.Fatalf("Unexpected err on vq create: %s", err)
   145  	}
   146  
   147  	for k, v := range fakevl[1:] {
   148  		err = vq.advance(errors.Errorf("advancment fail for %s", fakevl[k]))
   149  		if err != nil {
   150  			t.Errorf("error on advancing vq from %s to %s", fakevl[k], v)
   151  			break
   152  		}
   153  
   154  		if vq.current() != v {
   155  			t.Errorf("on advance() %v, current should be %s, got %s", k, v, vq.current())
   156  		}
   157  	}
   158  
   159  	if vq.isExhausted() {
   160  		t.Error("should not be exhausted until advancing 'past' the end")
   161  	}
   162  	if err = vq.advance(errors.Errorf("final advance failure")); err != nil {
   163  		t.Errorf("should not error on advance, even past end, but got %s", err)
   164  	}
   165  
   166  	if !vq.isExhausted() {
   167  		t.Error("advanced past end, should now report exhaustion")
   168  	}
   169  	if vq.current() != nil {
   170  		t.Error("advanced past end, current should return nil")
   171  	}
   172  
   173  	// now, do one with both a prefv and lockv
   174  	lockv := fakevl[2]
   175  	prefv := fakevl[0]
   176  	vq, err = newVersionQueue(id, lockv, prefv, fb)
   177  	if err != nil {
   178  		t.Errorf("error creating version queue: %v", err)
   179  	}
   180  	if vq.String() != "[v1.1.0, v2.0.0]" {
   181  		t.Error("stringifying vq did not have expected outcome, got", vq.String())
   182  	}
   183  	if vq.isExhausted() {
   184  		t.Error("can't be exhausted, we aren't even 'allLoaded' yet")
   185  	}
   186  
   187  	err = vq.advance(errors.Errorf("dequeue lockv"))
   188  	if err != nil {
   189  		t.Error("unexpected error when advancing past lockv", err)
   190  	} else {
   191  		if vq.current() != prefv {
   192  			t.Errorf("current should be prefv (%s) after first advance, got %s", prefv, vq.current())
   193  		}
   194  		if len(vq.pi) != 1 {
   195  			t.Errorf("should have just prefv elem left in vq, but there are %v:\n\t%s", len(vq.pi), vq.String())
   196  		}
   197  	}
   198  
   199  	err = vq.advance(errors.Errorf("dequeue prefv"))
   200  	if err != nil {
   201  		t.Error("unexpected error when advancing past prefv", err)
   202  	} else {
   203  		if !vq.allLoaded {
   204  			t.Error("allLoaded should now be true")
   205  		}
   206  		if len(vq.pi) != 3 {
   207  			t.Errorf("should have three remaining versions after removing prefv and lockv, but there are %v:\n\t%s", len(vq.pi), vq.String())
   208  		}
   209  		if vq.current() != fakevl[1] {
   210  			t.Errorf("current should be first elem of fakevl (%s) after advancing into all, got %s", fakevl[1], vq.current())
   211  		}
   212  	}
   213  
   214  	// make sure the queue ordering is still right even with a double-delete
   215  	vq.advance(nil)
   216  	if vq.current() != fakevl[3] {
   217  		t.Errorf("second elem after ListVersions() should be idx 3 of fakevl (%s), got %s", fakevl[3], vq.current())
   218  	}
   219  	vq.advance(nil)
   220  	if vq.current() != fakevl[4] {
   221  		t.Errorf("third elem after ListVersions() should be idx 4 of fakevl (%s), got %s", fakevl[4], vq.current())
   222  	}
   223  	vq.advance(nil)
   224  	if vq.current() != nil || !vq.isExhausted() {
   225  		t.Error("should be out of versions in the queue")
   226  	}
   227  
   228  	// Make sure we handle things correctly when listVersions adds nothing new
   229  	fb = &fakeBridge{vl: []Version{lockv, prefv}}
   230  	vq, err = newVersionQueue(id, lockv, prefv, fb)
   231  	if err != nil {
   232  		t.Errorf("error creating version queue: %v", err)
   233  	}
   234  	vq.advance(nil)
   235  	vq.advance(nil)
   236  	if vq.current() != nil || !vq.isExhausted() {
   237  		t.Errorf("should have no versions left, as ListVersions() added nothing new, but still have %s", vq.String())
   238  	}
   239  	err = vq.advance(nil)
   240  	if err != nil {
   241  		t.Errorf("should be fine to advance on empty queue, per docs, but got err %s", err)
   242  	}
   243  
   244  	// Also handle it well when advancing calls ListVersions() and it gets an
   245  	// error
   246  	vq, err = newVersionQueue(id, lockv, nil, &fakeFailBridge{})
   247  	if err != nil {
   248  		t.Errorf("should not err on creation when preseeded with lockv, but got err %s", err)
   249  	}
   250  	err = vq.advance(nil)
   251  	if err == nil {
   252  		t.Error("advancing should trigger call to erroring bridge, but no err")
   253  	}
   254  	err = vq.advance(nil)
   255  	if err == nil {
   256  		t.Error("err should be stored for reuse on any subsequent calls")
   257  	}
   258  
   259  }