github.com/kekek/gb@v0.4.5-0.20170222120241-d4ba64b0b297/executor_test.go (about)

     1  package gb
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"go/build"
     7  	"io"
     8  	"path/filepath"
     9  	"reflect"
    10  	"testing"
    11  )
    12  
    13  func TestExecuteBuildAction(t *testing.T) {
    14  	tests := []struct {
    15  		pkg string
    16  		err error
    17  	}{{
    18  		pkg: "a",
    19  		err: nil,
    20  	}, {
    21  		pkg: "b", // actually command
    22  		err: nil,
    23  	}, {
    24  		pkg: "c",
    25  		err: nil,
    26  	}, {
    27  		pkg: "d.v1",
    28  		err: nil,
    29  	}, {
    30  		pkg: "x",
    31  		err: errors.New("import cycle detected: x -> y -> x"),
    32  	}, {
    33  		pkg: "h", // imports "blank", which is blank, see issue #131
    34  		err: &build.NoGoError{Dir: filepath.Join(getwd(t), "testdata", "src", "blank")},
    35  	}}
    36  
    37  	for _, tt := range tests {
    38  		ctx := testContext(t)
    39  		defer ctx.Destroy()
    40  		pkg, err := ctx.ResolvePackage(tt.pkg)
    41  		if !reflect.DeepEqual(err, tt.err) {
    42  			t.Errorf("ctx.ResolvePackage(%v): want %v, got %v", tt.pkg, tt.err, err)
    43  			continue
    44  		}
    45  		if err != nil {
    46  			continue
    47  		}
    48  		action, err := BuildPackages(pkg)
    49  		if err != nil {
    50  			t.Errorf("BuildAction(%v): %v", tt.pkg, err)
    51  			continue
    52  		}
    53  		if err := Execute(action); !reflect.DeepEqual(err, tt.err) {
    54  			t.Errorf("Execute(%v): want: %v, got %v", action.Name, tt.err, err)
    55  		}
    56  	}
    57  }
    58  
    59  func niltask() error { return nil }
    60  
    61  var executorTests = []struct {
    62  	action *Action // root action
    63  	err    error   // expected error
    64  }{{
    65  	action: &Action{
    66  		Name: "no error",
    67  		Run:  niltask,
    68  	},
    69  }, {
    70  	action: &Action{
    71  		Name: "root error",
    72  		Run:  func() error { return io.EOF },
    73  	},
    74  	err: io.EOF,
    75  }, {
    76  	action: &Action{
    77  		Name: "child, child, error",
    78  		Run:  func() error { return fmt.Errorf("I should not have been called") },
    79  		Deps: []*Action{{
    80  			Name: "child, error",
    81  			Run:  niltask,
    82  			Deps: []*Action{{
    83  				Name: "error",
    84  				Run:  func() error { return io.EOF },
    85  			}},
    86  		}},
    87  	},
    88  	err: io.EOF,
    89  }, {
    90  	action: &Action{
    91  		Name: "once only",
    92  		Run: func() error {
    93  			if c1 != 1 || c2 != 1 || c3 != 1 {
    94  				return fmt.Errorf("unexpected count, c1: %v, c2: %v, c3: %v", c1, c2, c3)
    95  			}
    96  			return nil
    97  		},
    98  		Deps: []*Action{createDag()},
    99  	},
   100  }, {
   101  	action: &Action{
   102  		Name: "failure count",
   103  		Run:  func() error { return fmt.Errorf("I should not have been called") },
   104  		Deps: []*Action{createFailDag()},
   105  	},
   106  	err: fmt.Errorf("task3 called 1 time"),
   107  }}
   108  
   109  func createDag() *Action {
   110  	task1 := func() error { c1++; return nil }
   111  	task2 := func() error { c2++; return nil }
   112  	task3 := func() error { c3++; return nil }
   113  
   114  	action1 := Action{Name: "c1", Run: task1}
   115  	action2 := Action{Name: "c2", Run: task2}
   116  	action3 := Action{Name: "c3", Run: task3}
   117  
   118  	action1.Deps = append(action1.Deps, &action2, &action3)
   119  	action2.Deps = append(action2.Deps, &action3)
   120  	return &action1
   121  }
   122  
   123  func createFailDag() *Action {
   124  	task1 := func() error { c1++; return nil }
   125  	task2 := func() error { c2++; return fmt.Errorf("task2 called %v time", c2) }
   126  	task3 := func() error { c3++; return fmt.Errorf("task3 called %v time", c3) }
   127  
   128  	action1 := Action{Name: "c1", Run: task1}
   129  	action2 := Action{Name: "c2", Run: task2}
   130  	action3 := Action{Name: "c3", Run: task3}
   131  
   132  	action1.Deps = append(action1.Deps, &action2, &action3)
   133  	action2.Deps = append(action2.Deps, &action3)
   134  	return &action1
   135  }
   136  
   137  var c1, c2, c3 int
   138  
   139  func executeReset() {
   140  	c1 = 0
   141  	c2 = 0
   142  	c3 = 0
   143  	// reset executor test variables
   144  }
   145  
   146  func TestExecute(t *testing.T) {
   147  	for _, tt := range executorTests {
   148  		executeReset()
   149  		got := Execute(tt.action)
   150  		if !reflect.DeepEqual(got, tt.err) {
   151  			t.Errorf("Execute: %v: want err: %v, got err %v", tt.action.Name, tt.err, got)
   152  		}
   153  	}
   154  }
   155  
   156  func testExecuteConcurrentN(t *testing.T, n int) {
   157  	for _, tt := range executorTests {
   158  		executeReset()
   159  		got := ExecuteConcurrent(tt.action, n, nil) // no interrupt ch
   160  		if !reflect.DeepEqual(got, tt.err) {
   161  			t.Errorf("ExecuteConcurrent(%v): %v: want err: %v, got err %v", n, tt.action.Name, tt.err, got)
   162  		}
   163  	}
   164  }
   165  
   166  func TestExecuteConcurrent1(t *testing.T) { testExecuteConcurrentN(t, 1) }
   167  func TestExecuteConcurrent2(t *testing.T) { testExecuteConcurrentN(t, 2) }
   168  func TestExecuteConcurrent4(t *testing.T) { testExecuteConcurrentN(t, 4) }
   169  func TestExecuteConcurrent7(t *testing.T) { testExecuteConcurrentN(t, 7) }