From 4ccad563d2a3559f0557bfb177bcf45144219bdf Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 23 Oct 2012 04:31:11 +0000 Subject: libgo: Update to current sources. From-SVN: r192704 --- libgo/go/net/http/fs_test.go | 192 +++++++++++++++++++++++++++++++------------ 1 file changed, 141 insertions(+), 51 deletions(-) (limited to 'libgo/go/net/http/fs_test.go') diff --git a/libgo/go/net/http/fs_test.go b/libgo/go/net/http/fs_test.go index 17329fbd59a..09d5cfaf2d4 100644 --- a/libgo/go/net/http/fs_test.go +++ b/libgo/go/net/http/fs_test.go @@ -81,6 +81,7 @@ func TestServeFile(t *testing.T) { } // Range tests +Cases: for _, rt := range ServeFileRangeTests { if rt.r != "" { req.Header.Set("Range", rt.r) @@ -109,7 +110,7 @@ func TestServeFile(t *testing.T) { t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody) } if strings.HasPrefix(ct, "multipart/byteranges") { - t.Errorf("range=%q content-type = %q; unexpected multipart/byteranges", rt.r) + t.Errorf("range=%q content-type = %q; unexpected multipart/byteranges", rt.r, ct) } } if len(rt.ranges) > 1 { @@ -119,37 +120,41 @@ func TestServeFile(t *testing.T) { continue } if typ != "multipart/byteranges" { - t.Errorf("range=%q content-type = %q; want multipart/byteranges", rt.r) + t.Errorf("range=%q content-type = %q; want multipart/byteranges", rt.r, typ) continue } if params["boundary"] == "" { t.Errorf("range=%q content-type = %q; lacks boundary", rt.r, ct) + continue } if g, w := resp.ContentLength, int64(len(body)); g != w { t.Errorf("range=%q Content-Length = %d; want %d", rt.r, g, w) + continue } mr := multipart.NewReader(bytes.NewReader(body), params["boundary"]) for ri, rng := range rt.ranges { part, err := mr.NextPart() if err != nil { - t.Fatalf("range=%q, reading part index %d: %v", rt.r, ri, err) + t.Errorf("range=%q, reading part index %d: %v", rt.r, ri, err) + continue Cases + } + wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen) + if g, w := part.Header.Get("Content-Range"), wantContentRange; g != w { + t.Errorf("range=%q: part Content-Range = %q; want %q", rt.r, g, w) } body, err := ioutil.ReadAll(part) if err != nil { - t.Fatalf("range=%q, reading part index %d body: %v", rt.r, ri, err) + t.Errorf("range=%q, reading part index %d body: %v", rt.r, ri, err) + continue Cases } - wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen) wantBody := file[rng.start:rng.end] if !bytes.Equal(body, wantBody) { t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody) } - if g, w := part.Header.Get("Content-Range"), wantContentRange; g != w { - t.Errorf("range=%q: part Content-Range = %q; want %q", rt.r, g, w) - } } _, err = mr.NextPart() if err != io.EOF { - t.Errorf("range=%q; expected final error io.EOF; got %v", err) + t.Errorf("range=%q; expected final error io.EOF; got %v", rt.r, err) } } } @@ -335,11 +340,6 @@ func TestServeFileMimeType(t *testing.T) { } func TestServeFileFromCWD(t *testing.T) { - if runtime.GOOS == "windows" { - // TODO(brainman): find out why this test is broken - t.Logf("Temporarily skipping test on Windows; see http://golang.org/issue/3917") - return - } ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { ServeFile(w, r, "fs_test.go") })) @@ -348,6 +348,7 @@ func TestServeFileFromCWD(t *testing.T) { if err != nil { t.Fatal(err) } + r.Body.Close() if r.StatusCode != 200 { t.Fatalf("expected 200 OK, got %s", r.Status) } @@ -522,51 +523,140 @@ func TestDirectoryIfNotModified(t *testing.T) { res.Body.Close() } -func TestServeContent(t *testing.T) { - type req struct { - name string - modtime time.Time - content io.ReadSeeker +func mustStat(t *testing.T, fileName string) os.FileInfo { + fi, err := os.Stat(fileName) + if err != nil { + t.Fatal(err) } - ch := make(chan req, 1) + return fi +} + +func TestServeContent(t *testing.T) { + type serveParam struct { + name string + modtime time.Time + content io.ReadSeeker + contentType string + etag string + } + servec := make(chan serveParam, 1) ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - p := <-ch + p := <-servec + if p.etag != "" { + w.Header().Set("ETag", p.etag) + } + if p.contentType != "" { + w.Header().Set("Content-Type", p.contentType) + } ServeContent(w, r, p.name, p.modtime, p.content) })) defer ts.Close() - css, err := os.Open("testdata/style.css") - if err != nil { - t.Fatal(err) - } - defer css.Close() - - ch <- req{"style.css", time.Time{}, css} - res, err := Get(ts.URL) - if err != nil { - t.Fatal(err) - } - if g, e := res.Header.Get("Content-Type"), "text/css; charset=utf-8"; g != e { - t.Errorf("style.css: content type = %q, want %q", g, e) - } - if g := res.Header.Get("Last-Modified"); g != "" { - t.Errorf("want empty Last-Modified; got %q", g) + type testCase struct { + file string + modtime time.Time + serveETag string // optional + serveContentType string // optional + reqHeader map[string]string + wantLastMod string + wantContentType string + wantStatus int + } + htmlModTime := mustStat(t, "testdata/index.html").ModTime() + tests := map[string]testCase{ + "no_last_modified": { + file: "testdata/style.css", + wantContentType: "text/css; charset=utf-8", + wantStatus: 200, + }, + "with_last_modified": { + file: "testdata/index.html", + wantContentType: "text/html; charset=utf-8", + modtime: htmlModTime, + wantLastMod: htmlModTime.UTC().Format(TimeFormat), + wantStatus: 200, + }, + "not_modified_modtime": { + file: "testdata/style.css", + modtime: htmlModTime, + reqHeader: map[string]string{ + "If-Modified-Since": htmlModTime.UTC().Format(TimeFormat), + }, + wantStatus: 304, + }, + "not_modified_modtime_with_contenttype": { + file: "testdata/style.css", + serveContentType: "text/css", // explicit content type + modtime: htmlModTime, + reqHeader: map[string]string{ + "If-Modified-Since": htmlModTime.UTC().Format(TimeFormat), + }, + wantStatus: 304, + }, + "not_modified_etag": { + file: "testdata/style.css", + serveETag: `"foo"`, + reqHeader: map[string]string{ + "If-None-Match": `"foo"`, + }, + wantStatus: 304, + }, + "range_good": { + file: "testdata/style.css", + serveETag: `"A"`, + reqHeader: map[string]string{ + "Range": "bytes=0-4", + }, + wantStatus: StatusPartialContent, + wantContentType: "text/css; charset=utf-8", + }, + // An If-Range resource for entity "A", but entity "B" is now current. + // The Range request should be ignored. + "range_no_match": { + file: "testdata/style.css", + serveETag: `"A"`, + reqHeader: map[string]string{ + "Range": "bytes=0-4", + "If-Range": `"B"`, + }, + wantStatus: 200, + wantContentType: "text/css; charset=utf-8", + }, } + for testName, tt := range tests { + f, err := os.Open(tt.file) + if err != nil { + t.Fatalf("test %q: %v", testName, err) + } + defer f.Close() - fi, err := css.Stat() - if err != nil { - t.Fatal(err) - } - ch <- req{"style.html", fi.ModTime(), css} - res, err = Get(ts.URL) - if err != nil { - t.Fatal(err) - } - if g, e := res.Header.Get("Content-Type"), "text/html; charset=utf-8"; g != e { - t.Errorf("style.html: content type = %q, want %q", g, e) - } - if g := res.Header.Get("Last-Modified"); g == "" { - t.Errorf("want non-empty last-modified") + servec <- serveParam{ + name: filepath.Base(tt.file), + content: f, + modtime: tt.modtime, + etag: tt.serveETag, + contentType: tt.serveContentType, + } + req, err := NewRequest("GET", ts.URL, nil) + if err != nil { + t.Fatal(err) + } + for k, v := range tt.reqHeader { + req.Header.Set(k, v) + } + res, err := DefaultClient.Do(req) + if err != nil { + t.Fatal(err) + } + if res.StatusCode != tt.wantStatus { + t.Errorf("test %q: status = %d; want %d", testName, res.StatusCode, tt.wantStatus) + } + if g, e := res.Header.Get("Content-Type"), tt.wantContentType; g != e { + t.Errorf("test %q: content-type = %q, want %q", testName, g, e) + } + if g, e := res.Header.Get("Last-Modified"), tt.wantLastMod; g != e { + t.Errorf("test %q: last-modified = %q, want %q", testName, g, e) + } } } -- cgit v1.2.1