Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(747)

Side by Side Diff: appengine/monorail/framework/test/framework_helpers_test.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """Unit tests for the framework_helpers module."""
7
8 import unittest
9
10 import mox
11 import time
12
13 from framework import framework_helpers
14 from framework import framework_views
15 from proto import project_pb2
16 from services import service_manager
17 from testing import fake
18 from testing import testing_helpers
19
20
21 class HelperFunctionsTest(unittest.TestCase):
22
23 def setUp(self):
24 self.mox = mox.Mox()
25 self.time = self.mox.CreateMock(framework_helpers.time)
26 framework_helpers.time = self.time # Point to a mocked out time module.
27
28 def tearDown(self):
29 framework_helpers.time = time # Point back to the time module.
30 self.mox.UnsetStubs()
31 self.mox.ResetAll()
32
33 def testRetryDecorator_ExceedFailures(self):
34 class Tracker(object):
35 func_called = 0
36 tracker = Tracker()
37
38 # Use a function that always fails.
39 @framework_helpers.retry(2, delay=1, backoff=2)
40 def testFunc(tracker):
41 tracker.func_called += 1
42 raise Exception('Failed')
43
44 self.time.sleep(1).AndReturn(None)
45 self.time.sleep(2).AndReturn(None)
46 self.mox.ReplayAll()
47 with self.assertRaises(Exception):
48 testFunc(tracker)
49 self.mox.VerifyAll()
50 self.assertEquals(3, tracker.func_called)
51
52 def testRetryDecorator_EventuallySucceed(self):
53 class Tracker(object):
54 func_called = 0
55 tracker = Tracker()
56
57 # Use a function that succeeds on the 2nd attempt.
58 @framework_helpers.retry(2, delay=1, backoff=2)
59 def testFunc(tracker):
60 tracker.func_called += 1
61 if tracker.func_called < 2:
62 raise Exception('Failed')
63
64 self.time.sleep(1).AndReturn(None)
65 self.mox.ReplayAll()
66 testFunc(tracker)
67 self.mox.VerifyAll()
68 self.assertEquals(2, tracker.func_called)
69
70 def testGetRoleName(self):
71 proj = project_pb2.Project()
72 proj.owner_ids.append(111L)
73 proj.committer_ids.append(222L)
74 proj.contributor_ids.append(333L)
75
76 self.assertEquals(None, framework_helpers.GetRoleName(set(), proj))
77
78 self.assertEquals(
79 'Owner', framework_helpers.GetRoleName({111L}, proj))
80 self.assertEquals(
81 'Committer', framework_helpers.GetRoleName({222L}, proj))
82 self.assertEquals(
83 'Contributor', framework_helpers.GetRoleName({333L}, proj))
84
85 self.assertEquals(
86 'Owner',
87 framework_helpers.GetRoleName({111L, 222L, 999L}, proj))
88 self.assertEquals(
89 'Committer',
90 framework_helpers.GetRoleName({222L, 333L, 999L}, proj))
91 self.assertEquals(
92 'Contributor',
93 framework_helpers.GetRoleName({333L, 999L}, proj))
94
95
96 class UrlFormattingTest(unittest.TestCase):
97 """Tests for URL formatting."""
98
99 def setUp(self):
100 self.services = service_manager.Services(user=fake.UserService())
101
102 def testFormatMovedProjectURL(self):
103 """Project foo has been moved to bar. User is visiting /p/foo/..."""
104 mr = testing_helpers.MakeMonorailRequest()
105 mr.current_page_url = '/p/foo/'
106 self.assertEqual(
107 '/p/bar/',
108 framework_helpers.FormatMovedProjectURL(mr, 'bar'))
109
110 mr.current_page_url = '/p/foo/issues/list'
111 self.assertEqual(
112 '/p/bar/issues/list',
113 framework_helpers.FormatMovedProjectURL(mr, 'bar'))
114
115 mr.current_page_url = '/p/foo/issues/detail?id=123'
116 self.assertEqual(
117 '/p/bar/issues/detail?id=123',
118 framework_helpers.FormatMovedProjectURL(mr, 'bar'))
119
120 mr.current_page_url = '/p/foo/issues/detail?id=123#c7'
121 self.assertEqual(
122 '/p/bar/issues/detail?id=123#c7',
123 framework_helpers.FormatMovedProjectURL(mr, 'bar'))
124
125 def testFormatURL(self):
126 mr = testing_helpers.MakeMonorailRequest()
127 path = '/dude/wheres/my/car'
128 url = framework_helpers.FormatURL(mr, path)
129 self.assertEqual(path, url)
130
131 def testFormatURLWithRecognizedParams(self):
132 params = {}
133 query = []
134 for name in framework_helpers.RECOGNIZED_PARAMS:
135 params[name] = name
136 query.append('%s=%s' % (name, name))
137 path = '/dude/wheres/my/car'
138 expected = '%s?%s' % (path, '&'.join(query))
139 mr = testing_helpers.MakeMonorailRequest(path=expected)
140 url = framework_helpers.FormatURL(mr, path) # No added params.
141 self.assertEqual(expected, url)
142
143 def testFormatURLWithKeywordArgs(self):
144 params = {}
145 query_pairs = []
146 for name in framework_helpers.RECOGNIZED_PARAMS:
147 params[name] = name
148 if name is not 'can' and name is not 'start':
149 query_pairs.append('%s=%s' % (name, name))
150 path = '/dude/wheres/my/car'
151 mr = testing_helpers.MakeMonorailRequest(
152 path='%s?%s' % (path, '&'.join(query_pairs)))
153 query_pairs.append('can=yep')
154 query_pairs.append('start=486')
155 query_string = '&'.join(query_pairs)
156 expected = '%s?%s' % (path, query_string)
157 url = framework_helpers.FormatURL(mr, path, can='yep', start=486)
158 self.assertEqual(expected, url)
159
160 def testFormatURLWithKeywordArgsAndID(self):
161 params = {}
162 query_pairs = []
163 query_pairs.append('id=200') # id should be the first parameter.
164 for name in framework_helpers.RECOGNIZED_PARAMS:
165 params[name] = name
166 if name is not 'can' and name is not 'start':
167 query_pairs.append('%s=%s' % (name, name))
168 path = '/dude/wheres/my/car'
169 mr = testing_helpers.MakeMonorailRequest(
170 path='%s?%s' % (path, '&'.join(query_pairs)))
171 query_pairs.append('can=yep')
172 query_pairs.append('start=486')
173 query_string = '&'.join(query_pairs)
174 expected = '%s?%s' % (path, query_string)
175 url = framework_helpers.FormatURL(mr, path, can='yep', start=486, id=200)
176 self.assertEqual(expected, url)
177
178 def testFormatURLWithStrangeParams(self):
179 mr = testing_helpers.MakeMonorailRequest(path='/foo?start=0')
180 url = framework_helpers.FormatURL(
181 mr, '/foo', r=0, path='/foo/bar', sketchy='/foo/ bar baz ')
182 self.assertEqual(
183 '/foo?start=0&path=/foo/bar&r=0&sketchy=/foo/%20bar%20baz%20',
184 url)
185
186 def testFormatAbsoluteURL(self):
187 _request, mr = testing_helpers.GetRequestObjects(
188 path='/p/proj/some-path',
189 headers={'Host': 'www.test.com'})
190 self.assertEqual(
191 'http://www.test.com/p/proj/some/path',
192 framework_helpers.FormatAbsoluteURL(mr, '/some/path'))
193
194 def testFormatAbsoluteURL_CommonRequestParams(self):
195 _request, mr = testing_helpers.GetRequestObjects(
196 path='/p/proj/some-path?foo=bar&can=1',
197 headers={'Host': 'www.test.com'})
198 self.assertEqual(
199 'http://www.test.com/p/proj/some/path?can=1',
200 framework_helpers.FormatAbsoluteURL(mr, '/some/path'))
201 self.assertEqual(
202 'http://www.test.com/p/proj/some/path',
203 framework_helpers.FormatAbsoluteURL(
204 mr, '/some/path', copy_params=False))
205
206 def testFormatAbsoluteURL_NoProject(self):
207 path = '/some/path'
208 _request, mr = testing_helpers.GetRequestObjects(
209 headers={'Host': 'www.test.com'}, path=path)
210 url = framework_helpers.FormatAbsoluteURL(mr, path, include_project=False)
211 self.assertEqual(url, 'http://www.test.com/some/path')
212
213
214 class WordWrapSuperLongLinesTest(unittest.TestCase):
215
216 def testEmptyLogMessage(self):
217 msg = ''
218 wrapped_msg = framework_helpers.WordWrapSuperLongLines(msg)
219 self.assertEqual(wrapped_msg, '')
220
221 def testShortLines(self):
222 msg = 'one\ntwo\nthree\n'
223 wrapped_msg = framework_helpers.WordWrapSuperLongLines(msg)
224 expected = 'one\ntwo\nthree\n'
225 self.assertEqual(wrapped_msg, expected)
226
227 def testOneLongLine(self):
228 msg = ('This is a super long line that just goes on and on '
229 'and it seems like it will never stop because it is '
230 'super long and it was entered by a user who had no '
231 'familiarity with the return key.')
232 wrapped_msg = framework_helpers.WordWrapSuperLongLines(msg)
233 expected = ('This is a super long line that just goes on and on and it '
234 'seems like it will never stop because it\n'
235 'is super long and it was entered by a user who had no '
236 'familiarity with the return key.')
237 self.assertEqual(wrapped_msg, expected)
238
239 msg2 = ('This is a super long line that just goes on and on '
240 'and it seems like it will never stop because it is '
241 'super long and it was entered by a user who had no '
242 'familiarity with the return key. '
243 'This is a super long line that just goes on and on '
244 'and it seems like it will never stop because it is '
245 'super long and it was entered by a user who had no '
246 'familiarity with the return key.')
247 wrapped_msg2 = framework_helpers.WordWrapSuperLongLines(msg2)
248 expected2 = ('This is a super long line that just goes on and on and it '
249 'seems like it will never stop because it\n'
250 'is super long and it was entered by a user who had no '
251 'familiarity with the return key. This is a\n'
252 'super long line that just goes on and on and it seems like '
253 'it will never stop because it is super\n'
254 'long and it was entered by a user who had no familiarity '
255 'with the return key.')
256 self.assertEqual(wrapped_msg2, expected2)
257
258 def testMixOfShortAndLong(self):
259 msg = ('[Author: mpcomplete]\n'
260 '\n'
261 # Description on one long line
262 'Fix a memory leak in JsArray and JsObject for the IE and NPAPI '
263 'ports. Each time you call GetElement* or GetProperty* to '
264 'retrieve string or object token, the token would be leaked. '
265 'I added a JsScopedToken to ensure that the right thing is '
266 'done when the object leaves scope, depending on the platform.\n'
267 '\n'
268 'R=zork\n'
269 'CC=google-gears-eng@googlegroups.com\n'
270 'DELTA=108 (52 added, 36 deleted, 20 changed)\n'
271 'OCL=5932446\n'
272 'SCL=5933728\n')
273 wrapped_msg = framework_helpers.WordWrapSuperLongLines(msg)
274 expected = (
275 '[Author: mpcomplete]\n'
276 '\n'
277 'Fix a memory leak in JsArray and JsObject for the IE and NPAPI '
278 'ports. Each time you call\n'
279 'GetElement* or GetProperty* to retrieve string or object token, the '
280 'token would be leaked. I added\n'
281 'a JsScopedToken to ensure that the right thing is done when the '
282 'object leaves scope, depending on\n'
283 'the platform.\n'
284 '\n'
285 'R=zork\n'
286 'CC=google-gears-eng@googlegroups.com\n'
287 'DELTA=108 (52 added, 36 deleted, 20 changed)\n'
288 'OCL=5932446\n'
289 'SCL=5933728\n')
290 self.assertEqual(wrapped_msg, expected)
291
292
293 class ComputeListDeltasTest(unittest.TestCase):
294
295 def DoOne(self, old=None, new=None, added=None, removed=None):
296 """Run one call to the target method and check expected results."""
297 actual_added, actual_removed = framework_helpers.ComputeListDeltas(
298 old, new)
299 self.assertItemsEqual(added, actual_added)
300 self.assertItemsEqual(removed, actual_removed)
301
302 def testEmptyLists(self):
303 self.DoOne(old=[], new=[], added=[], removed=[])
304 self.DoOne(old=[1, 2], new=[], added=[], removed=[1, 2])
305 self.DoOne(old=[], new=[1, 2], added=[1, 2], removed=[])
306
307 def testUnchanged(self):
308 self.DoOne(old=[1], new=[1], added=[], removed=[])
309 self.DoOne(old=[1, 2], new=[1, 2], added=[], removed=[])
310 self.DoOne(old=[1, 2], new=[2, 1], added=[], removed=[])
311
312 def testCompleteChange(self):
313 self.DoOne(old=[1, 2], new=[3, 4], added=[3, 4], removed=[1, 2])
314
315 def testGeneralChange(self):
316 self.DoOne(old=[1, 2], new=[2], added=[], removed=[1])
317 self.DoOne(old=[1], new=[1, 2], added=[2], removed=[])
318 self.DoOne(old=[1, 2], new=[2, 3], added=[3], removed=[1])
319
320
321 class UserSettingsTest(unittest.TestCase):
322
323 def testGatherUnifiedSettingsPageData(self):
324 email_options = []
325
326 class UserSettingsStub(framework_helpers.UserSettings):
327
328 # pylint: disable=unused-argument
329 @classmethod
330 def _GetEmailOptions(cls, user_view, conn_pool):
331 return email_options
332
333 mr = testing_helpers.MakeMonorailRequest()
334 mr.auth.user_view = framework_views.UserView(100, 'user@invalid', True)
335 mr.auth.user_view.profile_url = '/u/profile/url'
336 page_data = UserSettingsStub.GatherUnifiedSettingsPageData(
337 mr.auth.user_id, mr.auth.user_view, mr.auth.user_pb)
338
339 expected_keys = [
340 'api_request_reset',
341 'api_request_lifetime_limit',
342 'api_request_hard_limit',
343 'api_request_soft_limit',
344 'settings_user',
345 'settings_user_pb',
346 'settings_user_is_banned',
347 'settings_user_ignore_action_limits',
348 'self',
349 'project_creation_reset',
350 'issue_comment_reset',
351 'issue_attachment_reset',
352 'issue_bulk_edit_reset',
353 'project_creation_lifetime_limit',
354 'project_creation_soft_limit',
355 'project_creation_hard_limit',
356 'issue_comment_lifetime_limit',
357 'issue_comment_soft_limit',
358 'issue_comment_hard_limit',
359 'issue_attachment_lifetime_limit',
360 'issue_attachment_soft_limit',
361 'issue_attachment_hard_limit',
362 'issue_bulk_edit_lifetime_limit',
363 'issue_bulk_edit_hard_limit',
364 'issue_bulk_edit_soft_limit',
365 'profile_url_fragment',
366 'preview_on_hover',
367 ]
368 self.assertItemsEqual(expected_keys, page_data.keys())
369
370 self.assertEqual('profile/url', page_data['profile_url_fragment'])
371 # TODO(jrobbins): Test action limit support
372
373 # TODO(jrobbins): Test ProcessForm.
374
375
376 class MurmurHash3Test(unittest.TestCase):
377
378 def testMurmurHash(self):
379 test_data = [
380 ('', 0),
381 ('agable@chromium.org', 4092810879),
382 (u'jrobbins@chromium.org', 904770043),
383 ('seanmccullough%google.com@gtempaccount.com', 1301269279),
384 ('rmistry+monorail@chromium.org', 4186878788),
385 ('jparent+foo@', 2923900874),
386 ('@example.com', 3043483168),
387 ]
388 hashes = [framework_helpers.MurmurHash3_x86_32(x)
389 for (x, _) in test_data]
390 self.assertListEqual(hashes, [e for (_, e) in test_data])
391
392 def testMurmurHashWithSeed(self):
393 test_data = [
394 ('', 1113155926, 2270882445),
395 ('agable@chromium.org', 772936925, 3995066671),
396 (u'jrobbins@chromium.org', 1519359761, 1273489513),
397 ('seanmccullough%google.com@gtempaccount.com', 49913829, 1202521153),
398 ('rmistry+monorail@chromium.org', 314860298, 3636123309),
399 ('jparent+foo@', 195791379, 332453977),
400 ('@example.com', 521490555, 257496459),
401 ]
402 hashes = [framework_helpers.MurmurHash3_x86_32(x, s)
403 for (x, s, _) in test_data]
404 self.assertListEqual(hashes, [e for (_, _, e) in test_data])
405
406
407 class MakeRandomKeyTest(unittest.TestCase):
408
409 def testMakeRandomKey_Normal(self):
410 key1 = framework_helpers.MakeRandomKey()
411 key2 = framework_helpers.MakeRandomKey()
412 self.assertEqual(128, len(key1))
413 self.assertEqual(128, len(key2))
414 self.assertNotEqual(key1, key2)
415
416 def testMakeRandomKey_Length(self):
417 key = framework_helpers.MakeRandomKey()
418 self.assertEqual(128, len(key))
419 key16 = framework_helpers.MakeRandomKey(length=16)
420 self.assertEqual(16, len(key16))
421
422 def testMakeRandomKey_Chars(self):
423 key = framework_helpers.MakeRandomKey(chars='a', length=4)
424 self.assertEqual('aaaa', key)
425
426
427 class IsServiceAccountTest(unittest.TestCase):
428
429 def testIsServiceAccount(self):
430 appspot = 'abc@appspot.gserviceaccount.com'
431 developer = '@developer.gserviceaccount.com'
432 bugdroid = 'bugdroid1@chromium.org'
433 user = 'test@example.com'
434
435 self.assertTrue(framework_helpers.IsServiceAccount(appspot))
436 self.assertTrue(framework_helpers.IsServiceAccount(developer))
437 self.assertTrue(framework_helpers.IsServiceAccount(bugdroid))
438 self.assertFalse(framework_helpers.IsServiceAccount(user))
439
440
441 if __name__ == '__main__':
442 unittest.main()
OLDNEW
« no previous file with comments | « appengine/monorail/framework/test/framework_bizobj_test.py ('k') | appengine/monorail/framework/test/framework_views_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698