// Alternates between turning network writes on and off in a loop. // Runs in a background goroutine and is started once at the very beginning of a test. func (ts *syncTestSystem) runNetwork() { t := ts.t // Network initially on t.Log("Setting global write drop percent to 0%") lspnet.SetWriteDropPercent(0) for { select { case <-ts.exitChan: t.Log("Received exit signal in runNetwork. Shutting down...") return default: t.Log("Waiting for master...") <-ts.masterToNetworkChan t.Log("Setting global write drop percent to 100%") lspnet.SetWriteDropPercent(100) ts.networkToMasterChan <- struct{}{} t.Log("Waiting for master...") <-ts.masterToNetworkChan t.Log("Setting global write drop percent to 0%") lspnet.SetWriteDropPercent(0) ts.networkToMasterChan <- struct{}{} t.Logf("Sleeping for %d ms", 2*ts.params.EpochMillis) time.Sleep(time.Duration(2*ts.params.EpochMillis) * time.Millisecond) } } }
func (ts *testSystem) runTest(timeout int) { lspnet.SetWriteDropPercent(ts.dropPercent) defer lspnet.ResetDropPercent() fmt.Printf("=== %s (%d clients, %d msgs/client, %d%% drop rate, %d window size)\n", ts.desc, ts.numClients, ts.numMsgs, ts.dropPercent, ts.params.WindowSize) clientDoneChan := make(chan bool, ts.numClients) go ts.runServer() for i := range ts.clients { go ts.runClient(i, clientDoneChan) } timeoutChan := time.After(time.Duration(timeout) * time.Millisecond) for _ = range ts.clients { select { case <-timeoutChan: close(ts.exitChan) ts.t.Fatalf("Test timed out after %.2f secs", float64(timeout)/1000.0) case ok := <-clientDoneChan: if !ok { // May or may not close the server goroutine. There's no guarantee // since we do not explicitly test the students' Close implementations // in these basic tests. close(ts.exitChan) ts.t.Fatal("Client failed due to an error.") } } } close(ts.exitChan) }