Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1219)

Side by Side Diff: src/pkg/exp/cookiejar/jar_test.go

Issue 6996044: code review 6996044: exp/cookiejar: dumbify the storage interface, add a bas... (Closed)
Patch Set: diff -r 5acb449b2a67 https://go.googlecode.com/hg/ Created 11 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2012 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 package cookiejar
6
7 import (
8 "bytes"
9 "fmt"
10 "net/http"
11 "net/url"
12 "reflect"
13 "sort"
14 "strings"
15 "sync"
16 "testing"
17 "time"
18 )
19
20 // memStorage is an in-memory storage used for testing.
21 type memStorage struct {
22 lock sync.Mutex
23 m map[string]string
24 }
25
26 func (m *memStorage) Get(key string) (value []byte, err error) {
27 m.lock.Lock()
28 defer m.lock.Unlock()
29
30 if m.m == nil {
31 m.m = make(map[string]string)
32 }
33 return []byte(m.m[key]), nil
34 }
35
36 func (m *memStorage) Set(key string, value []byte) error {
37 m.lock.Lock()
38 defer m.lock.Unlock()
39
40 if m.m == nil {
41 m.m = make(map[string]string)
42 }
43 if len(value) != 0 {
44 m.m[key] = string(value)
45 } else {
46 delete(m.m, key)
47 }
48 return nil
49 }
50
51 func (m *memStorage) Keys() ([]string, error) {
52 m.lock.Lock()
53 defer m.lock.Unlock()
54
55 keys := make([]string, 0, len(m.m))
56 for k := range m.m {
57 keys = append(keys, k)
58 }
59 return keys, nil
60 }
61
62 // fakePSL is a public suffix list used for testing.
63 type fakePSL struct{}
64
65 func (fakePSL) PublicSuffix(domain string) string {
66 if domain == "" {
67 return ""
68 }
69 knownPublicSuffixes := [...]string{
70 ".com",
71 ".co.uk",
72 ".uk",
73 // TODO: double-check this. http://publicsuffix.org/ currently l ists
74 // pvt.k12.wy.us, but Simone Carletti at submissions@publicsuffi x.org
75 // says that that's wrong; pvt.k12.wy.us is not in effective_tld _names.dat.
76 ".pvt.k12.wy.us",
77 ".us",
78 }
79 for _, s := range knownPublicSuffixes {
80 if domain == s[1:] || strings.HasSuffix(domain, s) {
81 return s[1:]
82 }
83 }
84 panic("unreachable")
85 }
86
87 func (fakePSL) String() string {
88 return "fakePSL"
89 }
90
91 func TestEffectiveTLDPlus1(t *testing.T) {
92 psl := PublicSuffixList(fakePSL{})
93 testCases := []struct {
94 domain, want string
95 }{
96 {"", "error"},
97
98 {"com", "error"},
99 {"example.com", "example.com"},
100 {"www.example.com", "example.com"},
101 {"www.xxx.example.com", "example.com"},
102 {"www.xxx.yyy.example.com", "example.com"},
103
104 {"uk", "error"},
105 {"co.uk", "error"},
106 {"example.co.uk", "example.co.uk"},
107 {"www.example.co.uk", "example.co.uk"},
108 {"www.xxx.example.co.uk", "example.co.uk"},
109 {"www.xxx.yyy.example.co.uk", "example.co.uk"},
110
111 {"us", "error"},
112 {"wy.us", "wy.us"},
113 {"k12.wy.us", "wy.us"},
114 {"pvt.k12.wy.us", "error"},
115 {"example.pvt.k12.wy.us", "example.pvt.k12.wy.us"},
116 }
117 for _, tc := range testCases {
118 got, err := effectiveTLDPlus1(tc.domain, psl)
119 if tc.want == "error" {
120 if err == nil {
121 t.Errorf("%q: got nil error, want non-nil", tc.d omain)
122 }
123 continue
124 }
125 if err != nil {
126 t.Errorf("%q: %v", tc.domain, err)
127 continue
128 }
129 if got != tc.want {
130 t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want)
131 continue
132 }
133 }
134 }
135
136 func urlMustParse(rawurl string) *url.URL {
137 u, err := url.Parse(rawurl)
138 if err != nil {
139 panic(err)
140 }
141 return u
142 }
143
144 var (
145 urlAt = urlMustParse("http://at.com/index.html")
146 urlOg = urlMustParse("http://og.com/index.html")
147
148 time0 = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
149 time1 = time0.AddDate(1, 0, 0)
150 time2 = time0.AddDate(2, 0, 0)
151 time3 = time0.AddDate(3, 0, 0)
152 time4 = time0.AddDate(4, 0, 0)
153 time9 = time0.AddDate(9, 0, 0)
154 )
155
156 type byName []*http.Cookie
157
158 func (b byName) Len() int { return len(b) }
159 func (b byName) Less(i, j int) bool { return b[i].Name < b[j].Name }
160 func (b byName) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
161
162 func str(cookies []*http.Cookie) string {
163 b := &bytes.Buffer{}
164 b.WriteString("{\n")
165 for _, c := range cookies {
166 fmt.Fprintf(b, "\t%v,\n", c)
167 }
168 b.WriteString("}")
169 return b.String()
170 }
171
172 func TestBasics(t *testing.T) {
volker.dobler 2012/12/22 00:27:10 This type of test is hard to understand, and e.g.
173 jar, err := New(nil)
174 if err != nil {
175 t.Fatalf("New: %v", err)
176 }
177
178 cBatA2 := &http.Cookie{
179 Name: "b",
180 Value: "bat-a",
181 Path: "/",
182 Domain: "at.com",
183 Expires: time2,
184 }
185 cCatA4 := &http.Cookie{
186 Name: "c",
187 Value: "cat-a",
188 Path: "/",
189 Domain: "at.com",
190 Expires: time4,
191 }
192 cCatB4 := &http.Cookie{
193 Name: "c",
194 Value: "cat-b",
195 Path: "/",
196 Domain: "at.com",
197 Expires: time4,
198 }
199 cCatC0 := &http.Cookie{
200 Name: "c",
201 Value: "cat-c",
202 Path: "/",
203 Domain: "at.com",
204 Expires: time0,
205 }
206 cDogA4 := &http.Cookie{
207 Name: "d",
208 Value: "dog-a",
209 Path: "/",
210 Domain: "og.com",
211 Expires: time4,
212 }
213 cHatB9 := &http.Cookie{
214 Name: "h",
215 Value: "hat-b",
216 Path: "/",
217 Domain: "at.com",
218 Expires: time9,
219 }
220
221 // Add some cookies for at.com.
222 jar.SetCookies(urlAt, []*http.Cookie{cBatA2, cCatA4})
223 got, err := jar.Cookies2(urlAt, time1, nil)
224 if err != nil {
225 t.Fatalf("Cookies2: %v", err)
226 }
227 sort.Sort(byName(got))
228 want := []*http.Cookie{cBatA2, cCatA4}
229 if !reflect.DeepEqual(got, want) {
230 t.Fatalf("cookies for %s:\ngot %v\nwant %v", urlAt, str(got), s tr(want))
231 }
232
233 // Add some cookies for og.com.
234 jar.SetCookies(urlOg, []*http.Cookie{cDogA4})
235 got, err = jar.Cookies2(urlOg, time1, nil)
236 if err != nil {
237 t.Fatalf("Cookies2: %v", err)
238 }
239 sort.Sort(byName(got))
240 want = []*http.Cookie{cDogA4}
241 if !reflect.DeepEqual(got, want) {
242 t.Fatalf("cookies for %s:\ngot %v\nwant %v", urlOg, str(got), s tr(want))
243 }
244
245 // Add two more cookies, overriding a previous one.
246 jar.SetCookies(urlAt, []*http.Cookie{cCatB4, cHatB9})
247 got, err = jar.Cookies2(urlAt, time1, nil)
248 if err != nil {
249 t.Fatalf("Cookies2: %v", err)
250 }
251 sort.Sort(byName(got))
252 want = []*http.Cookie{cBatA2, cCatB4, cHatB9}
253 if !reflect.DeepEqual(got, want) {
254 t.Fatalf("cookies for %s:\ngot %v\nwant %v", urlAt, str(got), s tr(want))
255 }
256
257 // Implicitly delete an expired cookie.
258 got, err = jar.Cookies2(urlAt, time3, nil)
259 if err != nil {
260 t.Fatalf("Cookies2: %v", err)
261 }
262 sort.Sort(byName(got))
263 want = []*http.Cookie{cCatB4, cHatB9}
264 if !reflect.DeepEqual(got, want) {
265 t.Fatalf("cookies for %s:\ngot %v\nwant %v", urlAt, str(got), s tr(want))
266 }
267
268 // Explicitly delete a cookie by setting its expiry to some point in the past.
269 jar.SetCookies(urlAt, []*http.Cookie{cCatC0})
270 got, err = jar.Cookies2(urlAt, time3, nil)
271 if err != nil {
272 t.Fatalf("Cookies2: %v", err)
273 }
274 sort.Sort(byName(got))
275 want = []*http.Cookie{cHatB9}
276 if !reflect.DeepEqual(got, want) {
277 t.Fatalf("cookies for %s:\ngot %v\nwant %v", urlAt, str(got), s tr(want))
278 }
279 }
280
281 func TestStorage(t *testing.T) {
282 mem := &memStorage{}
283
284 cHog := &http.Cookie{
285 Name: "h",
286 Value: "hog",
287 Path: "/",
288 Domain: "og.com",
289 Expires: time9,
290 }
291 cLog := &http.Cookie{
292 Name: "l",
293 Value: "log",
294 Path: "/",
295 Domain: "og.com",
296 Expires: time9,
297 }
298 cMat := &http.Cookie{
299 Name: "m",
300 Value: "mat",
301 Path: "/",
302 Domain: "at.com",
303 Expires: time9,
304 }
305
306 // Save some cookies with one jar, backed by a memStorage.
307 jar0, err := New(&Options{Storage: mem})
308 if err != nil {
309 t.Fatalf("New: %v", err)
310 }
311 jar0.SetCookies(urlAt, []*http.Cookie{cMat})
312 jar0.SetCookies(urlOg, []*http.Cookie{cHog, cLog})
313
314 // Load those cookies with another jar, backed by the same storage.
315 jar1, err := New(&Options{Storage: mem})
316 if err != nil {
317 t.Fatalf("New: %v", err)
318 }
319 got, err := jar1.Cookies2(urlOg, time1, nil)
320 if err != nil {
321 t.Fatalf("Cookies2: %v", err)
322 }
323 sort.Sort(byName(got))
324 want := []*http.Cookie{cHog, cLog}
325 if !reflect.DeepEqual(got, want) {
326 t.Fatalf("cookies for %s:\ngot %v\nwant %v", urlAt, str(got), s tr(want))
327 }
328 }
329
330 // TODO: test creation times.
331 // TODO: test last access times.
332 // TODO: test max-age.
333 // TODO: test sub-domains and non-/ paths.
334 // TODO: test Secure, HttpOnly, Persistent, HostOnly cookie bits.
335 // TODO: test SkipHttpOnly, ReadOnly Cookie2Options.
336 // TODO: test non-canonical hosts: EXAMPLE.COM, IP addresses, IDNA?
volker.dobler 2012/12/22 00:27:10 One more: TODO: test re-keying on changed public s
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b