bldr/resource/attach-mux-data_test.go
Rama master · réplica de lectura del repositorio original.
package resource
import (
"io"
"testing"
"github.com/pkg/errors"
)
func TestAttachMuxDataRwc_Read_BasicData(t *testing.T) {
// Prepare a mux reader that returns the complete payload.
data := []byte("hello world")
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return nil },
func() ([]byte, error) { return data, nil },
)
// Read the payload into a destination larger than the data.
buf := make([]byte, 64)
n, err := rwc.Read(buf)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Assert that the read returned every payload byte.
if n != len(data) {
t.Fatalf("read %d bytes, want %d", n, len(data))
}
// Assert that the destination contains the expected payload.
if string(buf[:n]) != "hello world" {
t.Fatalf("got %q, want %q", string(buf[:n]), "hello world")
}
}
func TestAttachMuxDataRwc_Read_BuffersPartialReads(t *testing.T) {
// Guard the receiver callback against extra reads.
called := false
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return nil },
func() ([]byte, error) {
if called {
t.Fatal("recvMuxData called more than once")
}
called = true
return []byte("abcdef"), nil
},
)
// Read the first chunk from the mux reader.
buf := make([]byte, 3)
n, err := rwc.Read(buf)
if err != nil {
t.Fatalf("unexpected error on first read: %v", err)
}
// Assert that the first read returned the first three bytes.
if n != 3 || string(buf[:n]) != "abc" {
t.Fatalf("first read: got %q, want %q", string(buf[:n]), "abc")
}
// Read the buffered remainder without calling the receiver again.
n, err = rwc.Read(buf)
if err != nil {
t.Fatalf("unexpected error on second read: %v", err)
}
// Assert that the second read returned the remaining bytes.
if n != 3 || string(buf[:n]) != "def" {
t.Fatalf("second read: got %q, want %q", string(buf[:n]), "def")
}
}
func TestAttachMuxDataRwc_Read_SkipsEmptyData(t *testing.T) {
// Return empty payloads before the non-empty mux data.
calls := 0
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return nil },
func() ([]byte, error) {
calls++
switch calls {
case 1:
return nil, nil
case 2:
return []byte{}, nil
case 3:
return []byte("data"), nil
default:
t.Fatal("too many recv calls")
return nil, nil
}
},
)
// Read through the empty responses to the first data chunk.
buf := make([]byte, 64)
n, err := rwc.Read(buf)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Assert that the reader skipped both empty responses.
if calls != 3 {
t.Fatalf("expected 3 recv calls, got %d", calls)
}
// Assert that the reader returned the non-empty payload.
if string(buf[:n]) != "data" {
t.Fatalf("got %q, want %q", string(buf[:n]), "data")
}
}
func TestAttachMuxDataRwc_Read_ReturnsRecvError(t *testing.T) {
// Configure the receiver callback to return a sentinel error.
recvErr := errors.New("recv failed")
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return nil },
func() ([]byte, error) { return nil, recvErr },
)
// Read once and capture the receiver error.
buf := make([]byte, 64)
_, err := rwc.Read(buf)
// Assert that Read returns the receiver error unchanged.
if err != recvErr {
t.Fatalf("got error %v, want %v", err, recvErr)
}
}
func TestAttachMuxDataRwc_Write_SendsData(t *testing.T) {
// Capture the bytes that the mux writer sends.
var sent []byte
rwc := NewAttachMuxDataRwc(
func(d []byte) error {
sent = d
return nil
},
func() ([]byte, error) { return nil, nil },
)
// Write a payload and check the number of bytes reported.
input := []byte("payload")
n, err := rwc.Write(input)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Assert that Write reports the full input length.
if n != len(input) {
t.Fatalf("wrote %d bytes, want %d", n, len(input))
}
// Assert that the mux writer received the payload.
if string(sent) != "payload" {
t.Fatalf("sent %q, want %q", string(sent), "payload")
}
}
func TestAttachMuxDataRwc_Write_ReturnsLength(t *testing.T) {
// Construct a mux writer whose send callback succeeds.
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return nil },
func() ([]byte, error) { return nil, nil },
)
// Write data and verify the reported byte count.
data := []byte("twelve bytes")
n, err := rwc.Write(data)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Assert that Write reports the full data length.
if n != len(data) {
t.Fatalf("got %d, want %d", n, len(data))
}
}
func TestAttachMuxDataRwc_Write_PropagatesError(t *testing.T) {
// Configure the sender callback to return a sentinel error.
sendErr := errors.New("send failed")
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return sendErr },
func() ([]byte, error) { return nil, nil },
)
// Write through the callback that returns the sentinel error.
_, err := rwc.Write([]byte("data"))
// Assert that Write returns the sender error unchanged.
if err != sendErr {
t.Fatalf("got error %v, want %v", err, sendErr)
}
}
func TestAttachMuxDataRwc_Write_ClonesData(t *testing.T) {
// Capture the bytes retained by the mux writer.
var sent []byte
rwc := NewAttachMuxDataRwc(
func(d []byte) error {
sent = d
return nil
},
func() ([]byte, error) { return nil, nil },
)
// Write the original payload before changing its backing bytes.
input := []byte("original")
_, err := rwc.Write(input)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Mutate the original buffer after Write.
input[0] = 'X'
// The sent data should still have the original value.
if sent[0] != 'o' {
t.Fatalf("sent data was mutated: got %q, want first byte 'o'", string(sent))
}
}
func TestAttachMuxDataRwc_Close_ReturnsNil(t *testing.T) {
// Construct a mux stream with successful no-op callbacks.
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return nil },
func() ([]byte, error) { return nil, nil },
)
// Close the stream and check its result.
if err := rwc.Close(); err != nil {
t.Fatalf("expected nil, got %v", err)
}
}
func TestAttachMuxDataRwc_ImplementsReadWriteCloser(t *testing.T) {
// Construct a mux stream for the interface assertion.
rwc := NewAttachMuxDataRwc(
func(d []byte) error { return nil },
func() ([]byte, error) { return nil, nil },
)
// Verify the mux stream satisfies io.ReadWriteCloser.
var _ io.ReadWriteCloser = rwc
}