Example #1
0
// Test state transitions from new->active->-idle->closed using an actual
// network connection and make sure the waitgroup count is correct at the end.
func TestStateTransitionActiveIdleClosed(t *testing.T) {
	var (
		listener net.Listener
		exitchan chan error
	)

	keyFile, err1 := test_helpers.NewTempFile(test_helpers.Key)
	certFile, err2 := test_helpers.NewTempFile(test_helpers.Cert)
	defer keyFile.Unlink()
	defer certFile.Unlink()

	if err1 != nil || err2 != nil {
		t.Fatal("Failed to create temporary files", err1, err2)
	}

	for _, withTLS := range []bool{false, true} {
		server := newServer()
		wg := test_helpers.NewWaitGroup()
		statechanged := make(chan http.ConnState)
		server.wg = wg
		if withTLS {
			listener, exitchan = startTLSServer(t, server, certFile.Name(), keyFile.Name(), statechanged)
		} else {
			listener, exitchan = startServer(t, server, statechanged)
		}

		client := newClient(listener.Addr(), withTLS)
		client.Run()

		// wait for client to connect, but don't let it send the request
		if err := <-client.connected; err != nil {
			t.Fatal("Client failed to connect to server", err)
		}

		client.sendrequest <- true
		waitForState(t, statechanged, http.StateActive, "Client failed to reach active state")

		rr := <-client.response
		if rr.err != nil {
			t.Fatalf("tls=%t unexpected error from client %s", withTLS, rr.err)
		}

		waitForState(t, statechanged, http.StateIdle, "Client failed to reach idle state")

		// client is now in an idle state
		close(client.sendrequest)
		<-client.closed
		waitForState(t, statechanged, http.StateClosed, "Client failed to reach closed state")

		server.Close()
		waiting := <-wg.WaitCalled
		if waiting != 0 {
			t.Errorf("Waitcount should be zero, got %d", waiting)
		}

		if err := <-exitchan; err != nil {
			t.Error("Unexpected error during shutdown", err)
		}
	}
}
Example #2
0
// Use the top level functions to instantiate servers and make sure
// they all shutdown when Close() is called
func TestGlobalShutdown(t *testing.T) {
	laserr := make(chan error)
	lastlserr := make(chan error)
	serveerr := make(chan error)

	go func() {
		laserr <- ListenAndServe("127.0.0.1:0", nullHandler)
	}()

	go func() {
		keyFile, _ := test_helpers.NewTempFile(test_helpers.Key)
		certFile, _ := test_helpers.NewTempFile(test_helpers.Cert)
		defer keyFile.Unlink()
		defer certFile.Unlink()
		lastlserr <- ListenAndServeTLS("127.0.0.1:0", certFile.Name(), keyFile.Name(), nullHandler)
	}()

	go func() {
		l := test_helpers.NewListener()
		serveerr <- Serve(l, nullHandler)
	}()

	// wait for registration
	expected := 3
	var sl int
	for sl < expected {
		m.Lock()
		sl = len(servers)
		m.Unlock()
		time.Sleep(time.Millisecond)
	}

	Close()

	for i := 0; i < expected; i++ {
		select {
		case err := <-laserr:
			if err != nil {
				t.Error("ListenAndServe returned error", err)
			}
			laserr = nil

		case err := <-lastlserr:
			if err != nil {
				t.Error("ListenAndServeTLS returned error", err)
			}
			lastlserr = nil

		case err := <-serveerr:
			if err != nil {
				t.Error("Serve returned error", err)
			}
			serveerr = nil
		case <-time.After(time.Second):
			t.Fatal("Timed out waiting for servers to exit")
		}
	}

}