Merge upstream libjuju
[osm/N2VC.git] / modules / libjuju / tests / unit / test_gocookies.py
1 """
2 Tests for the gocookies code.
3 """
4 import os
5 import shutil
6 import tempfile
7 import unittest
8 import urllib.request
9
10 import pyrfc3339
11 from juju.client.gocookies import GoCookieJar
12
13 # cookie_content holds the JSON contents of a Go-produced
14 # cookie file (reformatted so it's not all on one line but
15 # otherwise unchanged).
16 cookie_content = """
17 [
18 {
19 "CanonicalHost": "bar.com",
20 "Creation": "2017-11-17T08:53:55.088820092Z",
21 "Domain": "bar.com",
22 "Expires": "2345-11-15T18:16:08Z",
23 "HostOnly": true,
24 "HttpOnly": false,
25 "LastAccess": "2017-11-17T08:53:55.088822562Z",
26 "Name": "bar",
27 "Path": "/",
28 "Persistent": true,
29 "Secure": false,
30 "Updated": "2017-11-17T08:53:55.088822562Z",
31 "Value": "bar-value"
32 },
33 {
34 "CanonicalHost": "x.foo.com",
35 "Creation": "2017-11-17T08:53:55.088814857Z",
36 "Domain": "x.foo.com",
37 "Expires": "2345-11-15T18:16:05Z",
38 "HostOnly": true,
39 "HttpOnly": false,
40 "LastAccess": "2017-11-17T08:53:55.088884015Z",
41 "Name": "foo",
42 "Path": "/path",
43 "Persistent": true,
44 "Secure": false,
45 "Updated": "2017-11-17T08:53:55.088814857Z",
46 "Value": "foo-path-value"
47 },
48 {
49 "CanonicalHost": "x.foo.com",
50 "Creation": "2017-11-17T08:53:55.088814857Z",
51 "Domain": "foo.com",
52 "Expires": "2345-11-15T18:16:06Z",
53 "HostOnly": false,
54 "HttpOnly": false,
55 "LastAccess": "2017-11-17T08:53:55.088919437Z",
56 "Name": "foo4",
57 "Path": "/path",
58 "Persistent": true,
59 "Secure": false,
60 "Updated": "2017-11-17T08:53:55.088814857Z",
61 "Value": "foo4-value"
62 },
63 {
64 "CanonicalHost": "x.foo.com",
65 "Creation": "2017-11-17T08:53:55.088790709Z",
66 "Domain": "x.foo.com",
67 "Expires": "2345-11-15T18:16:01Z",
68 "HostOnly": true,
69 "HttpOnly": false,
70 "LastAccess": "2017-11-17T08:53:55.088884015Z",
71 "Name": "foo",
72 "Path": "/",
73 "Persistent": true,
74 "Secure": false,
75 "Updated": "2017-11-17T08:53:55.088790709Z",
76 "Value": "foo-value"
77 },
78 {
79 "CanonicalHost": "x.foo.com",
80 "Creation": "2017-11-17T08:53:55.088790709Z",
81 "Domain": "foo.com",
82 "Expires": "2345-11-15T18:16:02Z",
83 "HostOnly": false,
84 "HttpOnly": false,
85 "LastAccess": "2017-11-17T08:53:55.088919437Z",
86 "Name": "foo1",
87 "Path": "/",
88 "Persistent": true,
89 "Secure": false,
90 "Updated": "2017-11-17T08:53:55.088790709Z",
91 "Value": "foo1-value"
92 },
93 {
94 "CanonicalHost": "x.foo.com",
95 "Creation": "2017-11-17T08:53:55.088790709Z",
96 "Domain": "x.foo.com",
97 "Expires": "2345-11-15T18:16:03Z",
98 "HostOnly": true,
99 "HttpOnly": false,
100 "LastAccess": "2017-11-17T08:53:55.088850252Z",
101 "Name": "foo2",
102 "Path": "/",
103 "Persistent": true,
104 "Secure": true,
105 "Updated": "2017-11-17T08:53:55.088790709Z",
106 "Value": "foo2-value"
107 },
108 {
109 "CanonicalHost": "x.foo.com",
110 "Creation": "2017-11-17T08:53:55.088790709Z",
111 "Domain": "foo.com",
112 "Expires": "2345-11-15T18:16:04Z",
113 "HostOnly": false,
114 "HttpOnly": false,
115 "LastAccess": "2017-11-17T08:53:55.088919437Z",
116 "Name": "foo3",
117 "Path": "/",
118 "Persistent": true,
119 "Secure": false,
120 "Updated": "2017-11-17T08:53:55.088790709Z",
121 "Value": "foo3-value"
122 }
123 ]
124 """
125
126 # cookie_content_queries holds a set of queries
127 # that were automatically generated by running
128 # the queries on the above cookie_content data
129 # and printing the results.
130 cookie_content_queries = [
131 ('http://x.foo.com', [
132 ('foo', 'foo-value'),
133 ('foo1', 'foo1-value'),
134 ('foo3', 'foo3-value'),
135 ]),
136 ('https://x.foo.com', [
137 ('foo', 'foo-value'),
138 ('foo1', 'foo1-value'),
139 ('foo2', 'foo2-value'),
140 ('foo3', 'foo3-value'),
141 ]),
142 ('http://arble.foo.com', [
143 ('foo1', 'foo1-value'),
144 ('foo3', 'foo3-value'),
145 ]),
146 ('http://arble.com', [
147 ]),
148 ('http://x.foo.com/path/x', [
149 ('foo', 'foo-path-value'),
150 ('foo4', 'foo4-value'),
151 ('foo', 'foo-value'),
152 ('foo1', 'foo1-value'),
153 ('foo3', 'foo3-value'),
154 ]),
155 ('http://arble.foo.com/path/x', [
156 ('foo4', 'foo4-value'),
157 ('foo1', 'foo1-value'),
158 ('foo3', 'foo3-value'),
159 ]),
160 ('http://foo.com/path/x', [
161 ('foo4', 'foo4-value'),
162 ('foo1', 'foo1-value'),
163 ('foo3', 'foo3-value'),
164 ]),
165 ]
166
167
168 class TestGoCookieJar(unittest.TestCase):
169 def setUp(self):
170 self.dir = tempfile.mkdtemp()
171
172 def tearDown(self):
173 shutil.rmtree(self.dir)
174
175 def test_readcookies(self):
176 jar = self.load_jar(cookie_content)
177 self.assert_jar_queries(jar, cookie_content_queries)
178
179 def test_roundtrip(self):
180 jar = self.load_jar(cookie_content)
181 filename2 = os.path.join(self.dir, 'cookies2')
182 jar.save(filename=filename2)
183 jar = GoCookieJar()
184 jar.load(filename=filename2)
185 self.assert_jar_queries(jar, cookie_content_queries)
186
187 def test_expiry_time(self):
188 content = '''[
189 {
190 "CanonicalHost": "bar.com",
191 "Creation": "2017-11-17T08:53:55.088820092Z",
192 "Domain": "bar.com",
193 "Expires": "2345-11-15T18:16:08Z",
194 "HostOnly": true,
195 "HttpOnly": false,
196 "LastAccess": "2017-11-17T08:53:55.088822562Z",
197 "Name": "bar",
198 "Path": "/",
199 "Persistent": true,
200 "Secure": false,
201 "Updated": "2017-11-17T08:53:55.088822562Z",
202 "Value": "bar-value"
203 }
204 ]'''
205 jar = self.load_jar(content)
206 got_expires = tuple(jar)[0].expires
207 want_expires = int(pyrfc3339.parse('2345-11-15T18:16:08Z').timestamp())
208 self.assertEqual(got_expires, want_expires)
209
210 def load_jar(self, content):
211 filename = os.path.join(self.dir, 'cookies')
212 with open(filename, 'x') as f:
213 f.write(content)
214 jar = GoCookieJar()
215 jar.load(filename=filename)
216 return jar
217
218 def assert_jar_queries(self, jar, queries):
219 '''Assert that all the given queries (see cookie_content_queries)
220 are satisfied when run on the given cookie jar.
221 :param jar CookieJar: the cookie jar to query
222 :param queries: the queries to run.
223 '''
224 for url, want_cookies in queries:
225 req = urllib.request.Request(url)
226 jar.add_cookie_header(req)
227 # We can't use SimpleCookie to find out what cookies
228 # have been presented, because SimpleCookie
229 # only allows one cookie with a given name,
230 # so we naively parse the cookies ourselves, which
231 # is OK because we know we don't have to deal
232 # with any complex cases.
233
234 cookie_header = req.get_header('Cookie')
235 got_cookies = []
236 if cookie_header is not None:
237 got_cookies = [
238 tuple(part.split('='))
239 for part in cookie_header.split('; ')
240 ]
241 got_cookies.sort()
242 want_cookies = list(want_cookies)
243 want_cookies.sort()
244 self.assertEqual(got_cookies, want_cookies, msg='query {}; got {}; want {}'.format(url, got_cookies, want_cookies))