// 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)
		}
	}
}
Beispiel #2
0
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)
}