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