github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/utils/parallel/parallel_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package parallel_test 5 6 import ( 7 "sort" 8 "sync" 9 stdtesting "testing" 10 "time" 11 12 gc "launchpad.net/gocheck" 13 14 "launchpad.net/juju-core/utils/parallel" 15 ) 16 17 func Test(t *stdtesting.T) { 18 gc.TestingT(t) 19 } 20 21 type parallelSuite struct{} 22 23 var _ = gc.Suite(¶llelSuite{}) 24 25 func (*parallelSuite) TestParallelMaxPar(c *gc.C) { 26 const ( 27 totalDo = 10 28 maxConcurrentRunnersPar = 3 29 ) 30 var mu sync.Mutex 31 maxConcurrentRunners := 0 32 nbRunners := 0 33 nbRuns := 0 34 parallelRunner := parallel.NewRun(maxConcurrentRunnersPar) 35 for i := 0; i < totalDo; i++ { 36 parallelRunner.Do(func() error { 37 mu.Lock() 38 nbRuns++ 39 nbRunners++ 40 if nbRunners > maxConcurrentRunners { 41 maxConcurrentRunners = nbRunners 42 } 43 mu.Unlock() 44 time.Sleep(time.Second / 10) 45 mu.Lock() 46 nbRunners-- 47 mu.Unlock() 48 return nil 49 }) 50 } 51 err := parallelRunner.Wait() 52 if nbRunners != 0 { 53 c.Errorf("%d functions still running", nbRunners) 54 } 55 if nbRuns != totalDo { 56 c.Errorf("all functions not executed; want %d got %d", totalDo, nbRuns) 57 } 58 c.Check(err, gc.IsNil) 59 if maxConcurrentRunners != maxConcurrentRunnersPar { 60 c.Errorf("wrong number of do's ran at once; want %d got %d", maxConcurrentRunnersPar, maxConcurrentRunners) 61 } 62 } 63 64 type intError int 65 66 func (intError) Error() string { 67 return "error" 68 } 69 70 func (*parallelSuite) TestParallelError(c *gc.C) { 71 const ( 72 totalDo = 10 73 errDo = 5 74 ) 75 parallelRun := parallel.NewRun(6) 76 for i := 0; i < totalDo; i++ { 77 i := i 78 if i >= errDo { 79 parallelRun.Do(func() error { 80 return intError(i) 81 }) 82 } else { 83 parallelRun.Do(func() error { 84 return nil 85 }) 86 } 87 } 88 err := parallelRun.Wait() 89 c.Check(err, gc.NotNil) 90 errs := err.(parallel.Errors) 91 c.Check(len(errs), gc.Equals, totalDo-errDo) 92 ints := make([]int, len(errs)) 93 for i, err := range errs { 94 ints[i] = int(err.(intError)) 95 } 96 sort.Ints(ints) 97 for i, n := range ints { 98 c.Check(n, gc.Equals, i+errDo) 99 } 100 } 101 102 func (*parallelSuite) TestZeroWorkerPanics(c *gc.C) { 103 defer func() { 104 r := recover() 105 c.Check(r, gc.Matches, "parameter maxParallel must be >= 1") 106 }() 107 parallel.NewRun(0) 108 }