github.com/gsquire/gb@v0.4.4-0.20161112235727-3982dc872064/executor_test.go (about)

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