// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package testing func TestTestContext(t *T) { const ( add1 = 0 done = 1 ) // After each of the calls are applied to the context, the type call struct { typ int // run or done // result from applying the call running int waiting int started bool } testCases := []struct { max int run []call }{{ max: 1, run: []call{ {typ: add1, running: 1, waiting: 0, started: true}, {typ: done, running: 0, waiting: 0, started: false}, }, }, { max: 1, run: []call{ {typ: add1, running: 1, waiting: 0, started: true}, {typ: add1, running: 1, waiting: 1, started: false}, {typ: done, running: 1, waiting: 0, started: true}, {typ: done, running: 0, waiting: 0, started: false}, {typ: add1, running: 1, waiting: 0, started: true}, }, }, { max: 3, run: []call{ {typ: add1, running: 1, waiting: 0, started: true}, {typ: add1, running: 2, waiting: 0, started: true}, {typ: add1, running: 3, waiting: 0, started: true}, {typ: add1, running: 3, waiting: 1, started: false}, {typ: add1, running: 3, waiting: 2, started: false}, {typ: add1, running: 3, waiting: 3, started: false}, {typ: done, running: 3, waiting: 2, started: true}, {typ: add1, running: 3, waiting: 3, started: false}, {typ: done, running: 3, waiting: 2, started: true}, {typ: done, running: 3, waiting: 1, started: true}, {typ: done, running: 3, waiting: 0, started: true}, {typ: done, running: 2, waiting: 0, started: false}, {typ: done, running: 1, waiting: 0, started: false}, {typ: done, running: 0, waiting: 0, started: false}, }, }} for i, tc := range testCases { ctx := &testContext{ startParallel: make(chan bool), maxParallel: tc.max, } for j, call := range tc.run { doCall := func(f func()) chan bool { done := make(chan bool) go func() { f() done <- true }() return done } started := false switch call.typ { case add1: signal := doCall(ctx.waitParallel) select { case <-signal: started = true case ctx.startParallel <- true: <-signal } case done: signal := doCall(ctx.release) select { case <-signal: case <-ctx.startParallel: started = true <-signal } } if started != call.started { t.Errorf("%d:%d:started: got %v; want %v", i, j, started, call.started) } if ctx.running != call.running { t.Errorf("%d:%d:running: got %v; want %v", i, j, ctx.running, call.running) } if ctx.numWaiting != call.waiting { t.Errorf("%d:%d:waiting: got %v; want %v", i, j, ctx.numWaiting, call.waiting) } } } }