瀏覽代碼

http2: fix flake in TestServer_Push_StateTransitions

I believe there were two bugs, both fixed by this CL.

* Previously, we checked stateHalfClosedRemote before waiting for the
  PUSH_PROMISE. However, the pushed stream is not created until the promise
  is written, so the stream may not have started yet, which means we'd see
  stateIdle instead of stateHalfClosedRemote.

* The push reponse handler cannot write the response until after we
  check the pushed stream state. Otherwise, the response might finish
  just before we check the stream state and we'll see stateClosed instead
  of stateHalfClosedRemote.

Test passes with -count 1000.

Fixes golang/go#18559

Change-Id: I61f62635957e061fba905a41dcb15cd4e563031a
Reviewed-on: https://go-review.googlesource.com/34984
TryBot-Result: Gobot Gobot <gobot@golang.org>
Run-TryBot: Tom Bergan <tombergan@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Tom Bergan 9 年之前
父節點
當前提交
4aaac4bb36
共有 1 個文件被更改,包括 6 次插入1 次删除
  1. 6 1
      http2/server_push_test.go

+ 6 - 1
http2/server_push_test.go

@@ -431,7 +431,9 @@ func TestServer_Push_StateTransitions(t *testing.T) {
 	const body = "foo"
 
 	startedPromise := make(chan bool)
+	gotPromise := make(chan bool)
 	finishedPush := make(chan bool)
+
 	st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
 		switch r.URL.RequestURI() {
 		case "/":
@@ -442,6 +444,8 @@ func TestServer_Push_StateTransitions(t *testing.T) {
 			// Don't finish this request until the push finishes so we don't
 			// nondeterministically interleave output frames with the push.
 			<-finishedPush
+		case "/pushed":
+			<-gotPromise
 		}
 		w.Header().Set("Content-Type", "text/html")
 		w.Header().Set("Content-Length", strconv.Itoa(len(body)))
@@ -459,10 +463,11 @@ func TestServer_Push_StateTransitions(t *testing.T) {
 	}
 	getSlash(st)
 	<-startedPromise
+	st.wantPushPromise()
 	if got, want := st.streamState(2), stateHalfClosedRemote; got != want {
 		t.Fatalf("streamState(2)=%v, want %v", got, want)
 	}
-	st.wantPushPromise()
+	close(gotPromise)
 	st.wantHeaders()
 	if df := st.wantData(); !df.StreamEnded() {
 		t.Fatal("expected END_STREAM flag on DATA")