test(gopher): add resume coverage for typeInformation
This commit is contained in:
@@ -494,3 +494,103 @@ func TestGopherResumeIgnoredWhenWriterSet(t *testing.T) {
|
|||||||
t.Error("Output file should not be created when Writer is set")
|
t.Error("Output file should not be created when Writer is set")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestGopherResumeInformation verifies that resume machinery works for the
|
||||||
|
// informational (type i) response path, which is also routed through
|
||||||
|
// downloadText. Informational lines are passed through verbatim (no
|
||||||
|
// metadata strip), so the resume offset matches the raw line length
|
||||||
|
// including trailing CR/LF.
|
||||||
|
func TestGopherResumeInformation(t *testing.T) {
|
||||||
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer listener.Close()
|
||||||
|
port := listener.Addr().(*net.TCPAddr).Port
|
||||||
|
|
||||||
|
cancelReady := make(chan struct{})
|
||||||
|
connReady := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
conn, lerr := listener.Accept()
|
||||||
|
if lerr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r := bufio.NewReader(conn)
|
||||||
|
r.ReadString('\n')
|
||||||
|
if i == 0 {
|
||||||
|
// First half: send two info lines, then wait
|
||||||
|
// for the client to cancel before closing.
|
||||||
|
conn.Write([]byte("iFirst line.\r\n"))
|
||||||
|
conn.Write([]byte("iSecond line.\r\n"))
|
||||||
|
<-cancelReady
|
||||||
|
conn.Close()
|
||||||
|
connReady <- struct{}{}
|
||||||
|
} else {
|
||||||
|
// Second half: full body.
|
||||||
|
conn.Write([]byte("iFirst line.\r\n"))
|
||||||
|
conn.Write([]byte("iSecond line.\r\n"))
|
||||||
|
conn.Write([]byte(".\r\n"))
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
tmp := t.TempDir()
|
||||||
|
outPath := tmp + "/info.txt"
|
||||||
|
|
||||||
|
proto := NewProtocol()
|
||||||
|
u, _ := url.Parse("gopher://127.0.0.1:" + strconv.Itoa(port) + "/info")
|
||||||
|
|
||||||
|
progress := make(chan int64, 1)
|
||||||
|
ctx1, cancel1 := context.WithCancel(context.Background())
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
_, dlErr := proto.Download(ctx1, &core.DownloadRequest{
|
||||||
|
URL: u,
|
||||||
|
Output: outPath,
|
||||||
|
ProgressCallback: func(current, total int64, speed float64) {
|
||||||
|
select {
|
||||||
|
case progress <- current:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
errCh <- dlErr
|
||||||
|
}()
|
||||||
|
<-progress
|
||||||
|
cancel1()
|
||||||
|
cancelReady <- struct{}{}
|
||||||
|
<-connReady
|
||||||
|
if dlErr := <-errCh; dlErr == nil {
|
||||||
|
t.Fatal("expected error from cancelled context")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resume should append the missing bytes. For informational lines
|
||||||
|
// we do not strip metadata, so the output preserves the server CR/LF.
|
||||||
|
result, resErr := proto.Download(context.Background(), &core.DownloadRequest{
|
||||||
|
URL: u,
|
||||||
|
Output: outPath,
|
||||||
|
Resume: true,
|
||||||
|
})
|
||||||
|
if resErr != nil {
|
||||||
|
t.Fatalf("resume download failed: %v", resErr)
|
||||||
|
}
|
||||||
|
if !result.Resumed {
|
||||||
|
t.Error("expected Resumed=true")
|
||||||
|
}
|
||||||
|
if result.ContentType != "text/plain" {
|
||||||
|
t.Errorf("ContentType = %q, want text/plain", result.ContentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, _ := os.ReadFile(outPath)
|
||||||
|
// Informational lines are passed through verbatim: the 'i' item-type
|
||||||
|
// prefix and CR/LF framing from the server survive into the output.
|
||||||
|
want := "iFirst line.\r\niSecond line.\r\n"
|
||||||
|
if string(data) != want {
|
||||||
|
t.Errorf("content = %q, want %q", string(data), want)
|
||||||
|
}
|
||||||
|
if output.FileExists(outPath + output.ResumeMetaFileSuffix) {
|
||||||
|
t.Error("expected .goget.meta to be deleted after successful resume")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user