package notify import ( "bytes" "errors" "io" "strings" "testing" ) func TestNewTransferSourceFromReaderSequentialRead(t *testing.T) { source, err := NewTransferSourceFromReader(strings.NewReader("abcdef"), 6) if err != nil { t.Fatalf("NewTransferSourceFromReader failed: %v", err) } buf := make([]byte, 2) n, err := source.ReadAt(buf, 2) if err != nil { t.Fatalf("ReadAt resume offset failed: %v", err) } if got := string(buf[:n]); got != "cd" { t.Fatalf("ReadAt got %q, want %q", got, "cd") } n, err = source.ReadAt(buf, 4) if n != 2 { t.Fatalf("ReadAt n = %d, want 2", n) } if err != nil && !errors.Is(err, io.EOF) { t.Fatalf("ReadAt err = %v, want nil/EOF", err) } if got := string(buf[:n]); got != "ef" { t.Fatalf("ReadAt tail got %q, want %q", got, "ef") } if _, err := source.ReadAt(buf, 1); !errors.Is(err, errTransferSequentialSourceOrderedRead) { t.Fatalf("backward ReadAt err = %v, want %v", err, errTransferSequentialSourceOrderedRead) } } func TestNewTransferSinkFromWriterSequentialWrite(t *testing.T) { var dst bytes.Buffer sink, err := NewTransferSinkFromWriter(&dst) if err != nil { t.Fatalf("NewTransferSinkFromWriter failed: %v", err) } n, err := sink.WriteAt([]byte("ab"), 0) if err != nil { t.Fatalf("first WriteAt failed: %v", err) } if n != 2 { t.Fatalf("first WriteAt n = %d, want 2", n) } n, err = sink.WriteAt([]byte("cd"), 2) if err != nil { t.Fatalf("second WriteAt failed: %v", err) } if n != 2 { t.Fatalf("second WriteAt n = %d, want 2", n) } if got := dst.String(); got != "abcd" { t.Fatalf("writer got %q, want %q", got, "abcd") } offsetProvider, ok := sink.(interface{ NextOffset() int64 }) if !ok { t.Fatal("sink does not expose NextOffset") } if got := offsetProvider.NextOffset(); got != 4 { t.Fatalf("NextOffset = %d, want 4", got) } if _, err := sink.WriteAt([]byte("x"), 1); !errors.Is(err, errTransferSequentialSinkOrderedWrite) { t.Fatalf("out-of-order WriteAt err = %v, want %v", err, errTransferSequentialSinkOrderedWrite) } } func TestNewTransferReaderFromSource(t *testing.T) { reader, err := NewTransferReaderFromSource(newTransferBytesSource([]byte("abcdef")), 2) if err != nil { t.Fatalf("NewTransferReaderFromSource failed: %v", err) } data, err := io.ReadAll(reader) if err != nil { t.Fatalf("ReadAll failed: %v", err) } if got := string(data); got != "cdef" { t.Fatalf("ReadAll got %q, want %q", got, "cdef") } } func TestNewTransferWriterFromSink(t *testing.T) { sink := &transferMemorySink{} writer, err := NewTransferWriterFromSink(sink, 0) if err != nil { t.Fatalf("NewTransferWriterFromSink failed: %v", err) } n, err := writer.Write([]byte("abcdef")) if err != nil { t.Fatalf("Write failed: %v", err) } if n != 6 { t.Fatalf("Write n = %d, want 6", n) } if got := string(sink.Bytes()); got != "abcdef" { t.Fatalf("sink bytes = %q, want %q", got, "abcdef") } } func TestNormalizeTransferSendOptionsRejectsSequentialSourceUnsupportedModes(t *testing.T) { source, err := NewTransferSourceFromReader(strings.NewReader("abcdef"), 6) if err != nil { t.Fatalf("NewTransferSourceFromReader failed: %v", err) } _, err = normalizeTransferSendOptions(TransferSendOptions{ Descriptor: TransferDescriptor{ ID: "seq-parallel", Size: 6, }, Source: source, Parallelism: 2, }) if !errors.Is(err, errTransferSequentialSourceParallelism) { t.Fatalf("normalize parallel err = %v, want %v", err, errTransferSequentialSourceParallelism) } source, err = NewTransferSourceFromReader(strings.NewReader("abcdef"), 6) if err != nil { t.Fatalf("NewTransferSourceFromReader failed: %v", err) } _, err = normalizeTransferSendOptions(TransferSendOptions{ Descriptor: TransferDescriptor{ ID: "seq-checksum", Size: 6, }, Source: source, VerifyChecksum: true, }) if !errors.Is(err, errTransferSequentialSourceImplicitChecksum) { t.Fatalf("normalize checksum err = %v, want %v", err, errTransferSequentialSourceImplicitChecksum) } }