2016-10-02 16:41:58 +03:00
|
|
|
package spec
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"golang.org/x/net/http2"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
ExpectedConnectionClosed = "Connection closed"
|
|
|
|
ExpectedStreamClosed = "Stream closed"
|
|
|
|
ExpectedGoAwayFrame = "GOAWAY Frame (Error Code: %s)"
|
|
|
|
ExpectedRSTStreamFrame = "RST_STREAM Frame (Error Code: %s)"
|
|
|
|
)
|
|
|
|
|
2016-12-24 16:10:42 +03:00
|
|
|
// VerifyConnectionClose verifies whether the connection was closed.
|
2016-10-02 16:41:58 +03:00
|
|
|
func VerifyConnectionClose(conn *Conn) error {
|
|
|
|
var actual Event
|
|
|
|
|
|
|
|
passed := false
|
|
|
|
for !conn.Closed {
|
2016-11-05 17:47:07 +03:00
|
|
|
event := conn.WaitEvent()
|
|
|
|
|
|
|
|
switch ev := event.(type) {
|
2016-12-31 17:41:23 +03:00
|
|
|
case ConnectionClosedEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
passed = true
|
2016-12-31 17:41:23 +03:00
|
|
|
case TimeoutEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
if actual == nil {
|
|
|
|
actual = ev
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
actual = ev
|
|
|
|
}
|
|
|
|
|
2016-10-02 16:41:58 +03:00
|
|
|
if passed {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !passed {
|
|
|
|
return &TestError{
|
|
|
|
Expected: []string{ExpectedConnectionClosed},
|
|
|
|
Actual: actual.String(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-12-24 16:10:42 +03:00
|
|
|
// VerifyConnectionError verifies whether a connection error of HTTP/2
|
|
|
|
// has occurred.
|
2016-10-02 16:41:58 +03:00
|
|
|
func VerifyConnectionError(conn *Conn, codes ...http2.ErrCode) error {
|
|
|
|
var actual Event
|
|
|
|
|
|
|
|
passed := false
|
|
|
|
for !conn.Closed {
|
2016-11-05 17:47:07 +03:00
|
|
|
ev := conn.WaitEvent()
|
2016-10-02 16:41:58 +03:00
|
|
|
|
2016-11-05 17:47:07 +03:00
|
|
|
switch event := ev.(type) {
|
2016-12-31 17:41:23 +03:00
|
|
|
case ConnectionClosedEvent:
|
2016-10-02 16:41:58 +03:00
|
|
|
passed = true
|
2016-12-31 17:41:23 +03:00
|
|
|
case GoAwayFrameEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
passed = VerifyErrorCode(codes, event.ErrCode)
|
2016-12-31 17:41:23 +03:00
|
|
|
case TimeoutEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
if actual == nil {
|
|
|
|
actual = event
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
actual = event
|
2016-10-02 16:41:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if passed {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !passed {
|
|
|
|
expected := []string{}
|
|
|
|
for _, code := range codes {
|
|
|
|
expected = append(expected, fmt.Sprintf(ExpectedGoAwayFrame, code))
|
|
|
|
}
|
|
|
|
expected = append(expected, ExpectedConnectionClosed)
|
|
|
|
|
|
|
|
return &TestError{
|
|
|
|
Expected: expected,
|
|
|
|
Actual: actual.String(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-12-24 16:10:42 +03:00
|
|
|
// VerifyStreamError verifies whether a stream error of HTTP/2
|
|
|
|
// has occurred.
|
2016-10-02 16:41:58 +03:00
|
|
|
func VerifyStreamError(conn *Conn, codes ...http2.ErrCode) error {
|
|
|
|
var actual Event
|
|
|
|
|
|
|
|
passed := false
|
|
|
|
for !conn.Closed {
|
2016-11-05 17:47:07 +03:00
|
|
|
ev := conn.WaitEvent()
|
2016-10-02 16:41:58 +03:00
|
|
|
|
2016-11-05 17:47:07 +03:00
|
|
|
switch event := ev.(type) {
|
2016-12-31 17:41:23 +03:00
|
|
|
case ConnectionClosedEvent:
|
2016-10-02 16:41:58 +03:00
|
|
|
passed = true
|
2016-12-31 17:41:23 +03:00
|
|
|
case GoAwayFrameEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
passed = VerifyErrorCode(codes, event.ErrCode)
|
2016-12-31 17:41:23 +03:00
|
|
|
case RSTStreamFrameEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
passed = VerifyErrorCode(codes, event.ErrCode)
|
2016-12-31 17:41:23 +03:00
|
|
|
case TimeoutEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
if actual == nil {
|
|
|
|
actual = event
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
actual = event
|
2016-10-02 16:41:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if passed {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !passed {
|
|
|
|
expected := []string{}
|
|
|
|
for _, code := range codes {
|
|
|
|
expected = append(expected, fmt.Sprintf(ExpectedGoAwayFrame, code))
|
|
|
|
expected = append(expected, fmt.Sprintf(ExpectedRSTStreamFrame, code))
|
|
|
|
}
|
|
|
|
expected = append(expected, ExpectedConnectionClosed)
|
|
|
|
|
|
|
|
return &TestError{
|
|
|
|
Expected: expected,
|
|
|
|
Actual: actual.String(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-12-24 16:10:42 +03:00
|
|
|
// VerifyStreamClose verifies whether a stream close of HTTP/2
|
|
|
|
// has occurred.
|
2016-10-02 16:41:58 +03:00
|
|
|
func VerifyStreamClose(conn *Conn) error {
|
|
|
|
var actual Event
|
|
|
|
|
|
|
|
passed := false
|
|
|
|
for !conn.Closed {
|
2016-11-05 17:47:07 +03:00
|
|
|
ev := conn.WaitEvent()
|
2016-10-02 16:41:58 +03:00
|
|
|
|
2016-11-05 17:47:07 +03:00
|
|
|
switch event := ev.(type) {
|
2016-12-31 17:41:23 +03:00
|
|
|
case DataFrameEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
if event.StreamEnded() {
|
2016-10-02 16:41:58 +03:00
|
|
|
passed = true
|
|
|
|
}
|
2016-12-31 17:41:23 +03:00
|
|
|
case HeadersFrameEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
if event.StreamEnded() {
|
2016-10-02 16:41:58 +03:00
|
|
|
passed = true
|
|
|
|
}
|
2016-12-31 17:41:23 +03:00
|
|
|
case TimeoutEvent:
|
2016-11-05 17:47:07 +03:00
|
|
|
if actual == nil {
|
|
|
|
actual = event
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
actual = event
|
2016-10-02 16:41:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if passed {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !passed {
|
|
|
|
return &TestError{
|
|
|
|
Expected: []string{ExpectedStreamClosed},
|
|
|
|
Actual: actual.String(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-12-24 17:23:17 +03:00
|
|
|
// VerifyFrameType verifies whether a frame with specified type
|
|
|
|
// has received.
|
|
|
|
func VerifyFrameType(conn *Conn, frameTypes ...http2.FrameType) error {
|
|
|
|
var actual Event
|
|
|
|
|
|
|
|
passed := false
|
|
|
|
for !conn.Closed {
|
|
|
|
ev := conn.WaitEvent()
|
|
|
|
|
|
|
|
switch event := ev.(type) {
|
2016-12-31 17:41:23 +03:00
|
|
|
case TimeoutEvent:
|
2016-12-24 17:23:17 +03:00
|
|
|
if actual == nil {
|
|
|
|
actual = event
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
actual = ev
|
|
|
|
|
|
|
|
ef, ok := event.(EventFrame)
|
|
|
|
if ok {
|
|
|
|
for _, ft := range frameTypes {
|
|
|
|
if ef.Header().Type == ft {
|
|
|
|
passed = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if passed {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !passed {
|
|
|
|
expected := []string{}
|
|
|
|
for _, ft := range frameTypes {
|
|
|
|
expected = append(expected, fmt.Sprintf("%s frame", ft))
|
|
|
|
}
|
|
|
|
|
|
|
|
return &TestError{
|
|
|
|
Expected: expected,
|
|
|
|
Actual: actual.String(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-12-24 16:10:42 +03:00
|
|
|
// VerifyErrorCode verifies whether the specified error code is
|
|
|
|
// the expected error code.
|
2016-10-02 16:41:58 +03:00
|
|
|
func VerifyErrorCode(codes []http2.ErrCode, code http2.ErrCode) bool {
|
|
|
|
for _, c := range codes {
|
|
|
|
if c == code {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|