Some checks failed
Go / build (.exe, 386, windows, windows-386) (push) Has been cancelled
Go / build (.exe, amd64, windows, windows-amd64) (push) Has been cancelled
Go / build (.exe, arm64, windows, windows-arm64) (push) Has been cancelled
Go / build (386, freebsd, freebsd-386) (push) Has been cancelled
Go / build (386, linux, linux-386) (push) Has been cancelled
Go / build (386, netbsd, netbsd-386) (push) Has been cancelled
Go / build (386, openbsd, openbsd-386) (push) Has been cancelled
Go / build (386, plan9, plan9-386) (push) Has been cancelled
Go / build (amd64, darwin, darwin-amd64) (push) Has been cancelled
Go / build (amd64, dragonfly, dragonfly-amd64) (push) Has been cancelled
Go / build (amd64, freebsd, freebsd-amd64) (push) Has been cancelled
Go / build (amd64, illumos, illumos-amd64) (push) Has been cancelled
Go / build (amd64, linux, linux-amd64) (push) Has been cancelled
Go / build (amd64, netbsd, netbsd-amd64) (push) Has been cancelled
Go / build (amd64, openbsd, openbsd-amd64) (push) Has been cancelled
Go / build (amd64, plan9, plan9-amd64) (push) Has been cancelled
Go / build (amd64, solaris, solaris-amd64) (push) Has been cancelled
Go / build (arm, 6, linux, linux-armv6) (push) Has been cancelled
Go / build (arm, 7, linux, linux-armv7) (push) Has been cancelled
Go / build (arm, freebsd, freebsd-arm) (push) Has been cancelled
Go / build (arm, netbsd, netbsd-arm) (push) Has been cancelled
Go / build (arm, openbsd, openbsd-arm) (push) Has been cancelled
Go / build (arm, plan9, plan9-arm) (push) Has been cancelled
Go / build (arm64, darwin, darwin-arm64) (push) Has been cancelled
Go / build (arm64, freebsd, freebsd-arm64) (push) Has been cancelled
Go / build (arm64, linux, linux-arm64) (push) Has been cancelled
Go / build (arm64, netbsd, netbsd-arm64) (push) Has been cancelled
Go / build (arm64, openbsd, openbsd-arm64) (push) Has been cancelled
Go / build (loong64, linux, linux-loong64) (push) Has been cancelled
Go / build (mips, linux, linux-mips) (push) Has been cancelled
Go / build (mips64, linux, linux-mips64) (push) Has been cancelled
Go / build (mips64le, linux, linux-mips64le) (push) Has been cancelled
Go / build (mipsle, linux, linux-mipsle) (push) Has been cancelled
Go / build (ppc64, aix, aix-ppc64) (push) Has been cancelled
Go / build (ppc64, linux, linux-ppc64) (push) Has been cancelled
Go / build (ppc64, openbsd, openbsd-ppc64) (push) Has been cancelled
Go / build (ppc64le, linux, linux-ppc64le) (push) Has been cancelled
Go / build (riscv64, freebsd, freebsd-riscv64) (push) Has been cancelled
Go / build (riscv64, linux, linux-riscv64) (push) Has been cancelled
Go / build (riscv64, openbsd, openbsd-riscv64) (push) Has been cancelled
Go / build (s390x, linux, linux-s390x) (push) Has been cancelled
Docker Image / docker (push) Has been cancelled
Go / merge-artifacts (push) Has been cancelled
210 lines
4.5 KiB
Go
210 lines
4.5 KiB
Go
// cmd/gateway/relay_test.go 包含用于约束 relay 行为的测试。
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestWriteAll(t *testing.T) {
|
|
t.Run("partial writes", func(t *testing.T) {
|
|
writer := &partialGatewayWriter{chunkSize: 2}
|
|
if err := writeAll(writer, []byte("abcdef")); err != nil {
|
|
t.Fatalf("writeAll() error = %v", err)
|
|
}
|
|
if got := writer.buf.String(); got != "abcdef" {
|
|
t.Fatalf("written data = %q, want abcdef", got)
|
|
}
|
|
})
|
|
|
|
t.Run("short write", func(t *testing.T) {
|
|
if err := writeAll(shortGatewayWriter{}, []byte("abcdef")); !errors.Is(err, io.ErrShortWrite) {
|
|
t.Fatalf("writeAll() error = %v, want %v", err, io.ErrShortWrite)
|
|
}
|
|
})
|
|
|
|
t.Run("writer error", func(t *testing.T) {
|
|
wantErr := errors.New("write failed")
|
|
writer := &partialGatewayWriter{chunkSize: 2, err: wantErr}
|
|
if err := writeAll(writer, []byte("abcdef")); !errors.Is(err, wantErr) {
|
|
t.Fatalf("writeAll() error = %v, want %v", err, wantErr)
|
|
}
|
|
if got := writer.buf.String(); got != "ab" {
|
|
t.Fatalf("written data = %q, want ab", got)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCopyForwardCopiesData(t *testing.T) {
|
|
var dst bytes.Buffer
|
|
n, err := copyForward(&dst, strings.NewReader("payload"))
|
|
if err != nil {
|
|
t.Fatalf("copyForward() error = %v", err)
|
|
}
|
|
if n != int64(len("payload")) {
|
|
t.Fatalf("copyForward() n = %d, want %d", n, len("payload"))
|
|
}
|
|
if got := dst.String(); got != "payload" {
|
|
t.Fatalf("copyForward() data = %q, want payload", got)
|
|
}
|
|
}
|
|
|
|
func TestCopyForwardWithPlainReaderWriter(t *testing.T) {
|
|
dst := &plainGatewayWriter{}
|
|
n, err := copyForward(dst, &plainGatewayReader{data: []byte("plain")})
|
|
if err != nil {
|
|
t.Fatalf("copyForward() error = %v", err)
|
|
}
|
|
if n != int64(len("plain")) {
|
|
t.Fatalf("copyForward() n = %d, want %d", n, len("plain"))
|
|
}
|
|
if got := dst.buf.String(); got != "plain" {
|
|
t.Fatalf("copyForward() data = %q, want plain", got)
|
|
}
|
|
}
|
|
|
|
func TestProxyCopyClosesSides(t *testing.T) {
|
|
src := &closingGatewayReader{}
|
|
dst := &closingGatewayWriter{}
|
|
|
|
proxyCopy(dst, src)
|
|
|
|
if !src.closeReadCalled {
|
|
t.Fatal("CloseRead was not called")
|
|
}
|
|
if !dst.closeWriteCalled {
|
|
t.Fatal("CloseWrite was not called")
|
|
}
|
|
}
|
|
|
|
func TestProxyCopyRecoversAndClosesSides(t *testing.T) {
|
|
src := &panicGatewayReader{}
|
|
dst := &closingGatewayWriter{}
|
|
|
|
proxyCopy(dst, src)
|
|
|
|
if !src.closeReadCalled {
|
|
t.Fatal("CloseRead was not called after panic")
|
|
}
|
|
if !dst.closeWriteCalled {
|
|
t.Fatal("CloseWrite was not called after panic")
|
|
}
|
|
}
|
|
|
|
func TestCloseWriteFallsBackToClose(t *testing.T) {
|
|
closer := &gatewayCloser{}
|
|
closeWrite(closer)
|
|
if !closer.closed {
|
|
t.Fatal("Close was not called")
|
|
}
|
|
}
|
|
|
|
func TestGetAndPutProxyBuffer(t *testing.T) {
|
|
buf := getProxyBuffer()
|
|
if len(buf) != proxyBufferSize {
|
|
t.Fatalf("buffer len = %d, want %d", len(buf), proxyBufferSize)
|
|
}
|
|
if cap(buf) != proxyBufferSize {
|
|
t.Fatalf("buffer cap = %d, want %d", cap(buf), proxyBufferSize)
|
|
}
|
|
|
|
putProxyBuffer(buf[:1])
|
|
putProxyBuffer(make([]byte, 1))
|
|
}
|
|
|
|
type partialGatewayWriter struct {
|
|
chunkSize int
|
|
err error
|
|
buf bytes.Buffer
|
|
}
|
|
|
|
func (w *partialGatewayWriter) Write(p []byte) (int, error) {
|
|
if len(p) > w.chunkSize {
|
|
p = p[:w.chunkSize]
|
|
}
|
|
n, _ := w.buf.Write(p)
|
|
if w.err != nil {
|
|
return n, w.err
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
type shortGatewayWriter struct{}
|
|
|
|
func (shortGatewayWriter) Write([]byte) (int, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
type plainGatewayReader struct {
|
|
data []byte
|
|
}
|
|
|
|
func (r *plainGatewayReader) Read(p []byte) (int, error) {
|
|
if len(r.data) == 0 {
|
|
return 0, io.EOF
|
|
}
|
|
n := copy(p, r.data)
|
|
r.data = r.data[n:]
|
|
return n, nil
|
|
}
|
|
|
|
type plainGatewayWriter struct {
|
|
buf bytes.Buffer
|
|
}
|
|
|
|
func (w *plainGatewayWriter) Write(p []byte) (int, error) {
|
|
return w.buf.Write(p)
|
|
}
|
|
|
|
type closingGatewayReader struct {
|
|
closeReadCalled bool
|
|
}
|
|
|
|
func (r *closingGatewayReader) Read([]byte) (int, error) {
|
|
return 0, io.EOF
|
|
}
|
|
|
|
func (r *closingGatewayReader) CloseRead() error {
|
|
r.closeReadCalled = true
|
|
return nil
|
|
}
|
|
|
|
type panicGatewayReader struct {
|
|
closeReadCalled bool
|
|
}
|
|
|
|
func (r *panicGatewayReader) Read([]byte) (int, error) {
|
|
panic("read panic")
|
|
}
|
|
|
|
func (r *panicGatewayReader) CloseRead() error {
|
|
r.closeReadCalled = true
|
|
return nil
|
|
}
|
|
|
|
type closingGatewayWriter struct {
|
|
closeWriteCalled bool
|
|
}
|
|
|
|
func (w *closingGatewayWriter) Write(p []byte) (int, error) {
|
|
return len(p), nil
|
|
}
|
|
|
|
func (w *closingGatewayWriter) CloseWrite() error {
|
|
w.closeWriteCalled = true
|
|
return nil
|
|
}
|
|
|
|
type gatewayCloser struct {
|
|
closed bool
|
|
}
|
|
|
|
func (c *gatewayCloser) Close() error {
|
|
c.closed = true
|
|
return nil
|
|
}
|