11
11
from __future__ import print_function
12
12
13
13
import argparse
14
- import BaseHTTPServer
15
- import ConfigParser
16
14
import json
17
15
import os
18
16
import random
26
24
import time
27
25
import traceback
28
26
import unittest
29
- import urlparse
27
+
28
+
29
+ from six .moves .BaseHTTPServer import BaseHTTPRequestHandler , HTTPServer
30
+ from six .moves .configparser import ConfigParser
31
+ from six .moves .urllib .parse import parse_qs , urlparse
30
32
31
33
from lxml import html
32
34
35
37
from trac .util .translation import _
36
38
37
39
import requests
40
+ import six
38
41
39
42
40
43
GIT = 'test-git-foo'
@@ -83,6 +86,9 @@ def git_check_output(*args, **kwargs):
83
86
as a string.
84
87
"""
85
88
repo = kwargs .pop ('repo' , None )
89
+ kwargs .setdefault ('text' , True )
90
+ if six .PY2 :
91
+ del kwargs ['text' ]
86
92
87
93
if repo is None :
88
94
cmdargs = ["git" ] + list (args )
@@ -136,9 +142,12 @@ def createTracEnvironment(cls, **kwargs):
136
142
subprocess .check_output ([TRAC_ADMIN_BIN , d (ENV ), 'permission' ,
137
143
'add' , 'anonymous' , 'TRAC_ADMIN' ])
138
144
139
- conf = ConfigParser .ConfigParser ()
140
- with open (d (CONF ), 'rb' ) as fp :
141
- conf .readfp (fp )
145
+ conf = ConfigParser ()
146
+ with open (d (CONF ), 'r' ) as fp :
147
+ if six .PY2 :
148
+ conf .readfp (fp )
149
+ else :
150
+ conf .read_file (fp )
142
151
143
152
conf .add_section ('components' )
144
153
conf .set ('components' , 'trac.versioncontrol.web_ui.browser.BrowserModule' , 'disabled' )
@@ -210,7 +219,7 @@ def createTracEnvironment(cls, **kwargs):
210
219
conf .set ('trac' , 'permission_policies' ,
211
220
'GitHubPolicy, %s' % old_permission_policies )
212
221
213
- with open (d (CONF ), 'wb ' ) as fp :
222
+ with open (d (CONF ), 'w ' ) as fp :
214
223
conf .write (fp )
215
224
216
225
with open (d (HTDIGEST ), 'w' ) as fp :
@@ -269,7 +278,7 @@ def makeGitCommit(repo, path, content, message='edit', branch=None):
269
278
270
279
if branch != GIT_DEFAULT_BRANCH :
271
280
git_check_output ('checkout' , branch , repo = repo )
272
- with open (d (repo , path ), 'wb ' ) as fp :
281
+ with open (d (repo , path ), 'w ' ) as fp :
273
282
fp .write (content )
274
283
git_check_output ('add' , path , repo = repo )
275
284
git_check_output ('commit' , '-m' , message , repo = repo )
@@ -406,11 +415,11 @@ def testLogin(self):
406
415
response = requests .get (u ('github/login' ), allow_redirects = False )
407
416
self .assertEqual (response .status_code , 302 )
408
417
409
- redirect_url = urlparse . urlparse (response .headers ['Location' ])
418
+ redirect_url = urlparse (response .headers ['Location' ])
410
419
self .assertEqual (redirect_url .scheme , 'https' )
411
420
self .assertEqual (redirect_url .netloc , 'github.com' )
412
421
self .assertEqual (redirect_url .path , '/login/oauth/authorize' )
413
- params = urlparse . parse_qs (redirect_url .query , keep_blank_values = True )
422
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
414
423
state = params ['state' ][0 ] # this is a random value
415
424
self .assertEqual (params , {
416
425
'client_id' : ['01234567890123456789' ],
@@ -490,7 +499,7 @@ def setUpClass(cls):
490
499
cls .trac_env_broken = trac_env_broken
491
500
cls .trac_env_broken_api = trac_env_broken_api
492
501
493
- with open (d (SECRET ), 'wb ' ) as fp :
502
+ with open (d (SECRET ), 'w ' ) as fp :
494
503
fp .write ('98765432109876543210' )
495
504
496
505
@@ -505,11 +514,11 @@ def testLoginWithReqEmail(self):
505
514
response = requests .get (u ('github/login' ), allow_redirects = False )
506
515
self .assertEqual (response .status_code , 302 )
507
516
508
- redirect_url = urlparse . urlparse (response .headers ['Location' ])
517
+ redirect_url = urlparse (response .headers ['Location' ])
509
518
self .assertEqual (redirect_url .scheme , 'https' )
510
519
self .assertEqual (redirect_url .netloc , 'github.com' )
511
520
self .assertEqual (redirect_url .path , '/login/oauth/authorize' )
512
- params = urlparse . parse_qs (redirect_url .query , keep_blank_values = True )
521
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
513
522
state = params ['state' ][0 ] # this is a random value
514
523
self .assertEqual (params , {
515
524
'client_id' : ['01234567890123456789' ],
@@ -527,11 +536,11 @@ def loginAndVerifyClientId(self, expected_client_id):
527
536
response = requests .get (u ('github/login' ), allow_redirects = False )
528
537
self .assertEqual (response .status_code , 302 )
529
538
530
- redirect_url = urlparse . urlparse (response .headers ['Location' ])
539
+ redirect_url = urlparse (response .headers ['Location' ])
531
540
self .assertEqual (redirect_url .scheme , 'https' )
532
541
self .assertEqual (redirect_url .netloc , 'github.com' )
533
542
self .assertEqual (redirect_url .path , '/login/oauth/authorize' )
534
- params = urlparse . parse_qs (redirect_url .query , keep_blank_values = True )
543
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
535
544
state = params ['state' ][0 ] # this is a random value
536
545
self .assertEqual (params , {
537
546
'client_id' : [expected_client_id ],
@@ -636,8 +645,8 @@ def attemptValidOauth(self, testenv, callback, **kwargs):
636
645
self .assertEqual (response .status_code , 302 )
637
646
638
647
# Extract the state from the redirect
639
- redirect_url = urlparse . urlparse (response .headers ['Location' ])
640
- params = urlparse . parse_qs (redirect_url .query , keep_blank_values = True )
648
+ redirect_url = urlparse (response .headers ['Location' ])
649
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
641
650
state = params ['state' ][0 ] # this is a random value
642
651
response = session .get (
643
652
u ('github/oauth' ),
@@ -938,7 +947,7 @@ def testAlternativeRepository(self):
938
947
def testCommit (self ):
939
948
self .makeGitCommit (GIT , 'foo' , 'foo content\n ' )
940
949
output = self .openGitHubHook ()
941
- self . assertRegexpMatches ( output , r"Running hook on \(default\)\n"
950
+ six . assertRegex ( self , output , r"Running hook on \(default\)\n"
942
951
r"\* Updating clone\n"
943
952
r"\* Synchronizing with clone\n"
944
953
r"\* Adding commit [0-9a-f]{40}\n" )
@@ -947,7 +956,7 @@ def testMultipleCommits(self):
947
956
self .makeGitCommit (GIT , 'bar' , 'bar content\n ' )
948
957
self .makeGitCommit (GIT , 'bar' , 'more bar content\n ' )
949
958
output = self .openGitHubHook (2 )
950
- self . assertRegexpMatches ( output , r"Running hook on \(default\)\n"
959
+ six . assertRegex ( self , output , r"Running hook on \(default\)\n"
951
960
r"\* Updating clone\n"
952
961
r"\* Synchronizing with clone\n"
953
962
r"\* Adding commits [0-9a-f]{40}, [0-9a-f]{40}\n" )
@@ -958,7 +967,7 @@ def testCommitOnBranch(self):
958
967
self .makeGitBranch (ALTGIT , 'unstable/1.0' )
959
968
self .makeGitCommit (ALTGIT , 'unstable' , 'unstable branch\n ' , branch = 'unstable/1.0' )
960
969
output = self .openGitHubHook (2 , 'alt' )
961
- self . assertRegexpMatches ( output , r"Running hook on alt\n"
970
+ six . assertRegex ( self , output , r"Running hook on alt\n"
962
971
r"\* Updating clone\n"
963
972
r"\* Synchronizing with clone\n"
964
973
r"\* Adding commit [0-9a-f]{40}\n"
@@ -969,7 +978,7 @@ def testUnknownCommit(self):
969
978
random_id = '' .join (random .choice ('0123456789abcdef' ) for _ in range (40 ))
970
979
payload = {'commits' : [{'id' : random_id , 'message' : '' , 'distinct' : True }]}
971
980
response = requests .post (u ('github' ), json = payload , headers = HEADERS )
972
- self . assertRegexpMatches ( response .text , r"Running hook on \(default\)\n"
981
+ six . assertRegex ( self , response .text , r"Running hook on \(default\)\n"
973
982
r"\* Updating clone\n"
974
983
r"\* Synchronizing with clone\n"
975
984
r"\* Unknown commit [0-9a-f]{40}\n" )
@@ -1095,13 +1104,13 @@ class GitHubPostCommitHookWithUpdateHookTests(TracGitHubTests):
1095
1104
1096
1105
@classmethod
1097
1106
def createUpdateHook (cls ):
1098
- with open (d (UPDATEHOOK ), 'wb ' ) as fp :
1107
+ with open (d (UPDATEHOOK ), 'w ' ) as fp :
1099
1108
# simple shell script to echo back all input
1100
1109
fp .write ("""#!/bin/sh\n exec cat""" )
1101
1110
os .fchmod (fp .fileno (), 0o755 )
1102
1111
1103
1112
def createFailingUpdateHook (cls ):
1104
- with open (d (UPDATEHOOK ), 'wb ' ) as fp :
1113
+ with open (d (UPDATEHOOK ), 'w ' ) as fp :
1105
1114
fp .write ("""#!/bin/sh\n exit 1""" )
1106
1115
os .fchmod (fp .fileno (), 0o755 )
1107
1116
@@ -1128,7 +1137,7 @@ def testUpdateHook(self):
1128
1137
self .makeGitCommit (GIT , 'foo' , 'foo content\n ' )
1129
1138
payload = self .makeGitHubHookPayload ()
1130
1139
output = self .openGitHubHook (payload = payload )
1131
- self . assertRegexpMatches ( output , r"Running hook on \(default\)\n"
1140
+ six . assertRegex ( self , output , r"Running hook on \(default\)\n"
1132
1141
r"\* Updating clone\n"
1133
1142
r"\* Synchronizing with clone\n"
1134
1143
r"\* Adding commit [0-9a-f]{40}\n"
@@ -1139,14 +1148,14 @@ def testUpdateHookExecFailure(self):
1139
1148
os .chmod (d (UPDATEHOOK ), 0o644 )
1140
1149
self .makeGitCommit (GIT , 'bar' , 'bar content\n ' )
1141
1150
payload = self .makeGitHubHookPayload ()
1142
- with self . assertRaisesRegexp ( requests .HTTPError , r'^500 Server Error: Internal Server Error' ):
1151
+ with six . assertRaisesRegex ( self , requests .HTTPError , r'^500 Server Error: Internal Server Error' ):
1143
1152
output = self .openGitHubHook (payload = payload )
1144
1153
1145
1154
def testUpdateHookFailure (self ):
1146
1155
self .createFailingUpdateHook ()
1147
1156
self .makeGitCommit (GIT , 'baz' , 'baz content\n ' )
1148
1157
payload = self .makeGitHubHookPayload ()
1149
- with self . assertRaisesRegexp ( requests .HTTPError , r'^500 Server Error: Internal Server Error' ):
1158
+ with six . assertRaisesRegex ( self , requests .HTTPError , r'^500 Server Error: Internal Server Error' ):
1150
1159
output = self .openGitHubHook (payload = payload )
1151
1160
1152
1161
@@ -1160,7 +1169,7 @@ class GitHubPostCommitHookWithCacheTests(GitHubPostCommitHookTests):
1160
1169
cached_git = True
1161
1170
1162
1171
1163
- class GitHubAPIMock (BaseHTTPServer . BaseHTTPRequestHandler ):
1172
+ class GitHubAPIMock (BaseHTTPRequestHandler ):
1164
1173
def log_message (self , format , * args ):
1165
1174
# Visibly differentiate GitHub API mock logging from tracd logs
1166
1175
sys .stderr .write ("%s [%s] %s\n " %
@@ -1221,7 +1230,7 @@ def do_GET(self):
1221
1230
self .send_header ("Content-Type" , contenttype )
1222
1231
self .end_headers ()
1223
1232
1224
- self .wfile .write (json .dumps (answer ))
1233
+ self .wfile .write (json .dumps (answer , ensure_ascii = True ). encode ( 'ascii' ))
1225
1234
1226
1235
def do_POST (self ):
1227
1236
md = self .server .mockdata
@@ -1239,9 +1248,9 @@ def do_POST(self):
1239
1248
chunk = self .rfile .read (chunk_size )
1240
1249
if not chunk :
1241
1250
break
1242
- L .append (chunk )
1251
+ L .append (chunk . decode ( 'ascii' ) )
1243
1252
size_remaining -= len (L [- 1 ])
1244
- args = urlparse . parse_qs ('' .join (L ))
1253
+ args = parse_qs ('' .join (L ))
1245
1254
1246
1255
retcode = 404
1247
1256
answer = {}
@@ -1255,7 +1264,7 @@ def do_POST(self):
1255
1264
self .send_response (retcode )
1256
1265
self .send_header ("Content-Type" , contenttype )
1257
1266
self .end_headers ()
1258
- self .wfile .write (json .dumps (answer ))
1267
+ self .wfile .write (json .dumps (answer , ensure_ascii = True ). encode ( 'ascii' ))
1259
1268
1260
1269
1261
1270
class TracContext (object ):
@@ -1836,7 +1845,7 @@ def test_014_hook_membership_event_add_team(self):
1836
1845
self .assertGreater (len (data ), 0 , "No groups returned after update" )
1837
1846
self .assertIn (users [0 ]["login" ], data ,
1838
1847
"User %s expected after update, but not present" % users [0 ]["login" ])
1839
- self . assertItemsEqual (
1848
+ six . assertCountEqual ( self ,
1840
1849
data [users [0 ]["login" ]],
1841
1850
(u"github-%s-justice-league" % self .organization , u"github-%s" % self .organization ),
1842
1851
"User %s does not have expected groups after update" % users [0 ]["login" ])
@@ -1901,7 +1910,7 @@ def test_015_hook_membership_event_add_member(self):
1901
1910
self .assertGreater (len (data ), 0 , "No groups returned after update" )
1902
1911
self .assertIn (users [1 ]["login" ], data ,
1903
1912
"User %s expected after update, but not present" % users [1 ]["login" ])
1904
- self . assertItemsEqual (
1913
+ six . assertCountEqual ( self ,
1905
1914
data [users [1 ]["login" ]],
1906
1915
(u"github-%s-justice-league" % self .organization , u"github-%s" % self .organization ),
1907
1916
"User %s does not have expected groups after update" % users [1 ]["login" ])
@@ -2113,7 +2122,7 @@ def updateMockData(md, retcode=None, contenttype=None, answers=None,
2113
2122
JSON-encoded and returned for requests to the paths.
2114
2123
:param postcallback: A callback function called for the next POST requests.
2115
2124
Arguments are the requested path and a dict of POST
2116
- data as returned by `urlparse. parse_qs()`. The
2125
+ data as returned by `parse_qs()`. The
2117
2126
callback should return a tuple `(retcode, answer)`
2118
2127
where `retcode` is the HTTP return code and `answer`
2119
2128
will be JSON-encoded and sent to the client. Note that
@@ -2148,7 +2157,7 @@ def apiMockServer(port, mockdata):
2148
2157
be JSON-encoded and returned. Use `updateMockData()` to
2149
2158
update the contents of the mockdata dict.
2150
2159
"""
2151
- httpd = BaseHTTPServer . HTTPServer (('127.0.0.1' , port ), GitHubAPIMock )
2160
+ httpd = HTTPServer (('127.0.0.1' , port ), GitHubAPIMock )
2152
2161
# Make mockdata available to server
2153
2162
httpd .mockdata = mockdata
2154
2163
httpd .serve_forever ()
0 commit comments