h2spec/spec/verifier.go

237 строки
4.2 KiB
Go
Исходник Обычный вид История

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) {
case ConnectionClosedEvent:
2016-11-05 17:47:07 +03:00
passed = true
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) {
case ConnectionClosedEvent:
2016-10-02 16:41:58 +03:00
passed = true
case GoAwayFrameEvent:
2016-11-05 17:47:07 +03:00
passed = VerifyErrorCode(codes, event.ErrCode)
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) {
case ConnectionClosedEvent:
2016-10-02 16:41:58 +03:00
passed = true
case GoAwayFrameEvent:
2016-11-05 17:47:07 +03:00
passed = VerifyErrorCode(codes, event.ErrCode)
case RSTStreamFrameEvent:
2016-11-05 17:47:07 +03:00
passed = VerifyErrorCode(codes, event.ErrCode)
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) {
case DataFrameEvent:
2016-11-05 17:47:07 +03:00
if event.StreamEnded() {
2016-10-02 16:41:58 +03:00
passed = true
}
case HeadersFrameEvent:
2016-11-05 17:47:07 +03:00
if event.StreamEnded() {
2016-10-02 16:41:58 +03:00
passed = true
}
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) {
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
}