github.com/coreos/mantle@v0.13.0/harness/suite_test.go (about)

     1  // Copyright 2017 CoreOS, Inc.
     2  // Copyright 2016 The Go Authors.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package harness
    17  
    18  import (
    19  	"testing"
    20  )
    21  
    22  func TestSuiteParallelism(t *testing.T) {
    23  	const (
    24  		add1 = 0
    25  		done = 1
    26  	)
    27  	// Apply a series of calls to the Suite, checking state after each.
    28  	type call struct {
    29  		typ int // add1 or done
    30  		// result from applying the call
    31  		running int
    32  		waiting int
    33  		started bool
    34  	}
    35  	testCases := []struct {
    36  		max int
    37  		run []call
    38  	}{{
    39  		max: 1,
    40  		run: []call{
    41  			{typ: add1, running: 1, waiting: 0, started: true},
    42  			{typ: done, running: 0, waiting: 0, started: false},
    43  		},
    44  	}, {
    45  		max: 1,
    46  		run: []call{
    47  			{typ: add1, running: 1, waiting: 0, started: true},
    48  			{typ: add1, running: 1, waiting: 1, started: false},
    49  			{typ: done, running: 1, waiting: 0, started: true},
    50  			{typ: done, running: 0, waiting: 0, started: false},
    51  			{typ: add1, running: 1, waiting: 0, started: true},
    52  		},
    53  	}, {
    54  		max: 3,
    55  		run: []call{
    56  			{typ: add1, running: 1, waiting: 0, started: true},
    57  			{typ: add1, running: 2, waiting: 0, started: true},
    58  			{typ: add1, running: 3, waiting: 0, started: true},
    59  			{typ: add1, running: 3, waiting: 1, started: false},
    60  			{typ: add1, running: 3, waiting: 2, started: false},
    61  			{typ: add1, running: 3, waiting: 3, started: false},
    62  			{typ: done, running: 3, waiting: 2, started: true},
    63  			{typ: add1, running: 3, waiting: 3, started: false},
    64  			{typ: done, running: 3, waiting: 2, started: true},
    65  			{typ: done, running: 3, waiting: 1, started: true},
    66  			{typ: done, running: 3, waiting: 0, started: true},
    67  			{typ: done, running: 2, waiting: 0, started: false},
    68  			{typ: done, running: 1, waiting: 0, started: false},
    69  			{typ: done, running: 0, waiting: 0, started: false},
    70  		},
    71  	}}
    72  	for i, tc := range testCases {
    73  		suite := NewSuite(Options{Parallel: tc.max}, nil)
    74  		for j, call := range tc.run {
    75  			doCall := func(f func()) chan bool {
    76  				done := make(chan bool)
    77  				go func() {
    78  					f()
    79  					done <- true
    80  				}()
    81  				return done
    82  			}
    83  			started := false
    84  			switch call.typ {
    85  			case add1:
    86  				signal := doCall(suite.waitParallel)
    87  				select {
    88  				case <-signal:
    89  					started = true
    90  				case suite.startParallel <- true:
    91  					<-signal
    92  				}
    93  			case done:
    94  				signal := doCall(suite.release)
    95  				select {
    96  				case <-signal:
    97  				case <-suite.startParallel:
    98  					started = true
    99  					<-signal
   100  				}
   101  			}
   102  			if started != call.started {
   103  				t.Errorf("%d:%d:started: got %v; want %v", i, j, started, call.started)
   104  			}
   105  			if suite.running != call.running {
   106  				t.Errorf("%d:%d:running: got %v; want %v", i, j, suite.running, call.running)
   107  			}
   108  			if suite.waiting != call.waiting {
   109  				t.Errorf("%d:%d:waiting: got %v; want %v", i, j, suite.waiting, call.waiting)
   110  			}
   111  		}
   112  	}
   113  }