func newTestSystem(t *testing.T, numClients int, params *Params) *testSystem { ts := new(testSystem) ts.t = t ts.params = params ts.numClients = numClients ts.exitChan = make(chan struct{}) // Try to create server for different port numbers. const numTries = 5 var port int var err error for i := 0; i < numTries && ts.server == nil; i++ { port = 3000 + rand.Intn(50000) ts.server, err = NewServer(port, params) if err != nil { t.Logf("Failed to start server on port %d: %s", port, err) } } if err != nil { t.Fatalf("Failed to start server.") } t.Logf("Started server on port %d.", port) // Create the clients. ts.clients = make([]Client, numClients) for i := range ts.clients { hostport := lspnet.JoinHostPort("localhost", strconv.Itoa(port)) ts.clients[i], err = NewClient(hostport, params) if err != nil { t.Fatalf("Client failed to connect to server on port %d: %s.", port, err) } } t.Logf("Started %d clients.", numClients) return ts }
func newWindowTestSystem(t *testing.T, mode windowTestMode, numClients, numMsgs int, params *Params) *windowTestSystem { ts := new(windowTestSystem) ts.t = t ts.exitChan = make(chan struct{}) ts.clientMap = make(map[int]Client) ts.serverReadMsgs = make(map[int][]string) ts.clientReadMsgs = make(map[int][]string) ts.params = params ts.numClients = numClients ts.numMsgs = numMsgs ts.mode = mode ts.serverSendMsgs = ts.makeRandMsgs(numMsgs) ts.clientSendMsgs = ts.makeRandMsgs(numMsgs) ts.serverDoneChan = make(chan bool, numClients+1) ts.clientDoneChan = make(chan bool, numClients+1) // Start up the server. const numTries = 5 var err error var port int for i := 0; i < numTries && ts.server == nil; i++ { port = 3000 + rand.Intn(50000) ts.server, err = NewServer(port, ts.params) if err != nil { t.Logf("Failed to start server on port %d: %s", port, err) } } if err != nil { t.Fatalf("Failed to start server.") } t.Logf("Started server on port %d.", port) // Start up the clients. hostport := lspnet.JoinHostPort("localhost", strconv.Itoa(port)) for i := 0; i < ts.numClients; i++ { cli, err := NewClient(hostport, ts.params) if err != nil { ts.t.Fatalf("Failed to create client: %s", err) } connID := cli.ConnID() ts.clientMap[connID] = cli ts.serverReadMsgs[connID] = nil ts.clientReadMsgs[connID] = nil } return ts }
func main() { flag.Parse() if !*showLogs { log.SetOutput(ioutil.Discard) } lspnet.SetClientReadDropPercent(*readDrop) lspnet.SetClientWriteDropPercent(*writeDrop) params := &lsp.Params{ EpochLimit: *epochLimit, EpochMillis: *epochMillis, WindowSize: *windowSize, } hostport := lspnet.JoinHostPort(*host, strconv.Itoa(*port)) fmt.Printf("Connecting to server at '%s'...\n", hostport) cli, err := lsp.NewClient(hostport, params) if err != nil { fmt.Printf("Failed to connect to server at %s: %s\n", hostport, err) return } runClient(cli) }
// Create and runs a client. Runs in a background goroutine. Called once per client at // the very beginning of a test. func (ts *syncTestSystem) runClient(clienti int) { t := ts.t hostport := lspnet.JoinHostPort("localhost", strconv.Itoa(ts.port)) cli, err := NewClient(hostport, ts.params) if err != nil { t.Errorf("Couldn't create client %d to server at %s", clienti, hostport) ts.errChan <- fmt.Errorf("couldn't create client %d to server at %s", clienti, hostport) return } ts.clients[clienti] = cli id := cli.ConnID() ts.mapLock.Lock() ts.clientMap[id] = clienti ts.mapLock.Unlock() t.Logf("Client %d created with id %d to server at %s", clienti, id, hostport) ts.clientToMasterChan <- struct{}{} // Write if ts.mode != doServerToClient { t.Logf("Client %d (id %d) waiting to write\n", clienti, id) <-ts.masterToClientChan t.Logf("Client %d (id %d) writing messages\n", clienti, id) for nsent := 0; nsent < ts.numMsgs; nsent++ { v := ts.data[clienti][nsent] b, _ := json.Marshal(v) if err := cli.Write(b); err != nil { t.Errorf("Client failed to write: %s", err) ts.errChan <- fmt.Errorf("client %d (id %d) could not send value %v", clienti, id, v) return } } t.Logf("Client %d (id %d) wrote all %v messages to server\n", clienti, id, ts.numMsgs) ts.clientToMasterChan <- struct{}{} } // Read if ts.mode != doClientToServer { t.Logf("Client %d (id %d) waiting to read", clienti, id) <-ts.masterToClientChan t.Logf("Client %d (id %d) reading messages", clienti, id) // Receive messages from server for nrcvd := 0; nrcvd < ts.numMsgs; nrcvd++ { b, err := cli.Read() if err != nil { t.Errorf("Client failed to read: %s", err) ts.errChan <- fmt.Errorf("client %d (id %d) failed to read value #%d", clienti, id, nrcvd) return } var v int json.Unmarshal(b, &v) ev := ts.data[clienti][nrcvd] if v != ev { t.Errorf("Client %d (id %d) received element #%v, value %v. Expected %v\n", clienti, id, nrcvd, v, ev) ts.errChan <- fmt.Errorf("client %d (id %d) received element #%v, value %v; expected %v", clienti, id, nrcvd, v, ev) return } t.Logf("Client %d (id %d) received element #%v, value %v. Correct!", clienti, id, nrcvd, v) } t.Logf("Client %d (id %d) read all %v messages from servers\n", clienti, id, ts.numMsgs) ts.clientToMasterChan <- struct{}{} } t.Logf("Client %d (id %d) waiting to close...", clienti, id) <-ts.masterToClientChan t.Logf("Client %d (id %d) closing...", clienti, id) cli.Close() t.Logf("Client %d (id %d) done.", clienti, id) ts.clientToMasterChan <- struct{}{} }
func (ts *closeTestSystem) createClient(index int) error { cli, err := NewClient(lspnet.JoinHostPort("localhost", strconv.Itoa(ts.port)), ts.params) ts.clients[index] = cli return err }