diff --git a/internal/protocol/gemini/gemini_test.go b/internal/protocol/gemini/gemini_test.go index 43362e0..ff2287c 100644 --- a/internal/protocol/gemini/gemini_test.go +++ b/internal/protocol/gemini/gemini_test.go @@ -218,18 +218,29 @@ func TestGeminiResumeSaveMetadata(t *testing.T) { u, _ := url.Parse("gemini://127.0.0.1:" + strconv.Itoa(port) + "/") ctx, cancel := context.WithCancel(context.Background()) + // progress is signalled every time the download loop calls + // req.ProgressCallback — which happens *after* a successful + // writer.Write. Reading from it is therefore a deterministic + // barrier waiting for the first byte to land on disk. + progress := make(chan int64, 1) errCh := make(chan error, 1) go func() { _, err := proto.Download(ctx, &core.DownloadRequest{ URL: u, Output: outPath, + ProgressCallback: func(current, total int64, speed float64) { + select { + case progress <- current: + default: + } + }, }) errCh <- err }() - // Cancel mid-download — the slow server keeps the connection open - // long enough for the cancellation to fire between reads. - time.Sleep(150 * time.Millisecond) + // Wait until the first byte has been written to disk, then cancel. + // No fixed sleep — this is robust against slow CI schedulers. + <-progress cancel() err = <-errCh @@ -307,17 +318,26 @@ func TestGeminiResumeDownload(t *testing.T) { u, _ := url.Parse("gemini://127.0.0.1:" + strconv.Itoa(port) + "/data") // First attempt: the server sends 500 bytes and blocks. We cancel - // the context, then the server closes the connection. + // the context, then the server closes the connection. progress + // signals after the first writer.Write so waiting on it replaces + // the previous fixed sleep with a deterministic barrier. ctx1, cancel1 := context.WithCancel(context.Background()) + progress := make(chan int64, 1) 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 }() - time.Sleep(100 * time.Millisecond) + <-progress cancel1() cancelReady <- struct{}{} // let server close connection <-connReady