Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This code is a duplicate of ../chunked_test.go with these edits: | 5 // This code is a duplicate of ../chunked_test.go with these edits: |
6 // s/newChunked/NewChunked/g | 6 // s/newChunked/NewChunked/g |
7 // s/package http/package httputil/ | 7 // s/package http/package httputil/ |
8 // Please make any changes in both files. | 8 // Please make any changes in both files. |
9 | 9 |
10 package httputil | 10 package httputil |
11 | 11 |
12 import ( | 12 import ( |
13 "bytes" | 13 "bytes" |
14 "fmt" | 14 "fmt" |
15 "io" | 15 "io" |
16 "io/ioutil" | 16 "io/ioutil" |
17 "runtime" | |
18 "testing" | 17 "testing" |
19 ) | 18 ) |
20 | 19 |
21 func TestChunk(t *testing.T) { | 20 func TestChunk(t *testing.T) { |
22 var b bytes.Buffer | 21 var b bytes.Buffer |
23 | 22 |
24 w := NewChunkedWriter(&b) | 23 w := NewChunkedWriter(&b) |
25 const chunk1 = "hello, " | 24 const chunk1 = "hello, " |
26 const chunk2 = "world! 0123456789abcdef" | 25 const chunk2 = "world! 0123456789abcdef" |
27 w.Write([]byte(chunk1)) | 26 w.Write([]byte(chunk1)) |
28 w.Write([]byte(chunk2)) | 27 w.Write([]byte(chunk2)) |
29 w.Close() | 28 w.Close() |
30 | 29 |
31 if g, e := b.String(), "7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\ n0\r\n"; g != e { | 30 if g, e := b.String(), "7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\ n0\r\n"; g != e { |
32 t.Fatalf("chunk writer wrote %q; want %q", g, e) | 31 t.Fatalf("chunk writer wrote %q; want %q", g, e) |
33 } | 32 } |
34 | 33 |
35 r := NewChunkedReader(&b) | 34 r := NewChunkedReader(&b) |
36 data, err := ioutil.ReadAll(r) | 35 data, err := ioutil.ReadAll(r) |
37 if err != nil { | 36 if err != nil { |
38 t.Logf(`data: "%s"`, data) | 37 t.Logf(`data: "%s"`, data) |
39 t.Fatalf("ReadAll from reader: %v", err) | 38 t.Fatalf("ReadAll from reader: %v", err) |
40 } | 39 } |
41 if g, e := string(data), chunk1+chunk2; g != e { | 40 if g, e := string(data), chunk1+chunk2; g != e { |
42 t.Errorf("chunk reader read %q; want %q", g, e) | 41 t.Errorf("chunk reader read %q; want %q", g, e) |
43 } | 42 } |
44 } | 43 } |
45 | 44 |
46 func TestChunkReaderAllocs(t *testing.T) { | 45 func TestChunkReaderAllocs(t *testing.T) { |
47 » // temporarily set GOMAXPROCS to 1 as we are testing memory allocations | 46 » const N = 100 |
48 » defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) | 47 |
49 var buf bytes.Buffer | 48 var buf bytes.Buffer |
50 w := NewChunkedWriter(&buf) | 49 w := NewChunkedWriter(&buf) |
51 a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("ccccccccccc ccccccccccccc") | 50 a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("ccccccccccc ccccccccccccc") |
51 testing.AllocsPerRun(N, func() { | |
52 w.Write(a) | |
53 w.Write(b) | |
54 w.Write(c) | |
55 }) | |
56 w.Close() | |
57 | |
58 r := NewChunkedReader(&buf) | |
59 readBuf := make([]byte, len(a)+len(b)+len(c)) | |
60 | |
61 allocs := testing.AllocsPerRun(N, func() { | |
rsc
2013/01/30 17:55:41
This is not obviously clearer. Please revert.
kevlar
2013/01/31 06:14:02
Done.
| |
62 n, err := io.ReadFull(r, readBuf) | |
63 if n != len(readBuf) { | |
64 t.Errorf("read %d bytes; want %d", n, len(readBuf)-1) | |
65 } | |
66 if err != nil { | |
67 t.Errorf("read error = %v", err) | |
68 } | |
69 }) | |
70 if _, err := r.Read(readBuf); err != io.EOF { | |
71 t.Errorf("final read error was %v, want io.EOF", err) | |
72 } | |
73 | |
74 if allocs > 0 { | |
75 t.Errorf("%v mallocs; want zero", allocs) | |
76 } | |
77 } | |
78 | |
79 func TestChunkReaderUnexpectedEOF(t *testing.T) { | |
80 var buf bytes.Buffer | |
81 w := NewChunkedWriter(&buf) | |
82 a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("ccccccccccc ccccccccccccc") | |
52 w.Write(a) | 83 w.Write(a) |
53 w.Write(b) | 84 w.Write(b) |
54 w.Write(c) | 85 w.Write(c) |
55 w.Close() | 86 w.Close() |
56 | 87 |
57 r := NewChunkedReader(&buf) | 88 r := NewChunkedReader(&buf) |
58 readBuf := make([]byte, len(a)+len(b)+len(c)+1) | 89 readBuf := make([]byte, len(a)+len(b)+len(c)+1) |
59 | 90 |
60 var ms runtime.MemStats | |
61 runtime.ReadMemStats(&ms) | |
62 m0 := ms.Mallocs | |
63 | |
64 n, err := io.ReadFull(r, readBuf) | 91 n, err := io.ReadFull(r, readBuf) |
65 | |
66 runtime.ReadMemStats(&ms) | |
67 mallocs := ms.Mallocs - m0 | |
68 if mallocs > 1 { | |
69 t.Errorf("%d mallocs; want <= 1", mallocs) | |
70 } | |
71 | |
72 if n != len(readBuf)-1 { | 92 if n != len(readBuf)-1 { |
73 t.Errorf("read %d bytes; want %d", n, len(readBuf)-1) | 93 t.Errorf("read %d bytes; want %d", n, len(readBuf)-1) |
74 } | 94 } |
75 if err != io.ErrUnexpectedEOF { | 95 if err != io.ErrUnexpectedEOF { |
76 t.Errorf("read error = %v; want ErrUnexpectedEOF", err) | 96 t.Errorf("read error = %v; want ErrUnexpectedEOF", err) |
77 } | 97 } |
78 } | 98 } |
79 | 99 |
80 func TestParseHexUint(t *testing.T) { | 100 func TestParseHexUint(t *testing.T) { |
81 for i := uint64(0); i <= 1234; i++ { | 101 for i := uint64(0); i <= 1234; i++ { |
82 line := []byte(fmt.Sprintf("%x", i)) | 102 line := []byte(fmt.Sprintf("%x", i)) |
83 got, err := parseHexUint(line) | 103 got, err := parseHexUint(line) |
84 if err != nil { | 104 if err != nil { |
85 t.Fatalf("on %d: %v", i, err) | 105 t.Fatalf("on %d: %v", i, err) |
86 } | 106 } |
87 if got != i { | 107 if got != i { |
88 t.Errorf("for input %q = %d; want %d", line, got, i) | 108 t.Errorf("for input %q = %d; want %d", line, got, i) |
89 } | 109 } |
90 } | 110 } |
91 _, err := parseHexUint([]byte("bogus")) | 111 _, err := parseHexUint([]byte("bogus")) |
92 if err == nil { | 112 if err == nil { |
93 t.Error("expected error on bogus input") | 113 t.Error("expected error on bogus input") |
94 } | 114 } |
95 } | 115 } |
OLD | NEW |