10
10
"""
11
11
from __future__ import print_function
12
12
13
+ # Python3 imports are commented out, six is used to offer py2+py3 compatibility
13
14
import argparse
14
- import BaseHTTPServer
15
- import ConfigParser
15
+ # from configparser import ConfigParser
16
+ # from http.server import BaseHTTPRequestHandler, HTTPServer
16
17
import json
17
18
import os
18
19
import random
26
27
import time
27
28
import traceback
28
29
import unittest
29
- import urlparse
30
+ # from urllib.parse import parse_qs, urlparse
31
+
32
+
33
+ from six .moves .BaseHTTPServer import BaseHTTPRequestHandler , HTTPServer
34
+ from six .moves .configparser import ConfigParser
35
+ from six .moves .urllib .parse import parse_qs , urlparse
30
36
31
37
from lxml import html
32
38
35
41
from trac .util .translation import _
36
42
37
43
import requests
44
+ import six
38
45
39
46
40
47
GIT = 'test-git-foo'
@@ -83,6 +90,9 @@ def git_check_output(*args, **kwargs):
83
90
as a string.
84
91
"""
85
92
repo = kwargs .pop ('repo' , None )
93
+ kwargs .setdefault ('text' , True )
94
+ if six .PY2 :
95
+ del kwargs ['text' ]
86
96
87
97
if repo is None :
88
98
cmdargs = ["git" ] + list (args )
@@ -136,9 +146,12 @@ def createTracEnvironment(cls, **kwargs):
136
146
subprocess .check_output ([TRAC_ADMIN_BIN , d (ENV ), 'permission' ,
137
147
'add' , 'anonymous' , 'TRAC_ADMIN' ])
138
148
139
- conf = ConfigParser .ConfigParser ()
140
- with open (d (CONF ), 'rb' ) as fp :
141
- conf .readfp (fp )
149
+ conf = ConfigParser ()
150
+ with open (d (CONF ), 'r' ) as fp :
151
+ if six .PY2 :
152
+ conf .readfp (fp )
153
+ else :
154
+ conf .read_file (fp )
142
155
143
156
conf .add_section ('components' )
144
157
conf .set ('components' , 'trac.versioncontrol.web_ui.browser.BrowserModule' , 'disabled' )
@@ -210,7 +223,7 @@ def createTracEnvironment(cls, **kwargs):
210
223
conf .set ('trac' , 'permission_policies' ,
211
224
'GitHubPolicy, %s' % old_permission_policies )
212
225
213
- with open (d (CONF ), 'wb ' ) as fp :
226
+ with open (d (CONF ), 'w ' ) as fp :
214
227
conf .write (fp )
215
228
216
229
with open (d (HTDIGEST ), 'w' ) as fp :
@@ -269,7 +282,7 @@ def makeGitCommit(repo, path, content, message='edit', branch=None):
269
282
270
283
if branch != GIT_DEFAULT_BRANCH :
271
284
git_check_output ('checkout' , branch , repo = repo )
272
- with open (d (repo , path ), 'wb ' ) as fp :
285
+ with open (d (repo , path ), 'w ' ) as fp :
273
286
fp .write (content )
274
287
git_check_output ('add' , path , repo = repo )
275
288
git_check_output ('commit' , '-m' , message , repo = repo )
@@ -406,11 +419,11 @@ def testLogin(self):
406
419
response = requests .get (u ('github/login' ), allow_redirects = False )
407
420
self .assertEqual (response .status_code , 302 )
408
421
409
- redirect_url = urlparse . urlparse (response .headers ['Location' ])
422
+ redirect_url = urlparse (response .headers ['Location' ])
410
423
self .assertEqual (redirect_url .scheme , 'https' )
411
424
self .assertEqual (redirect_url .netloc , 'github.com' )
412
425
self .assertEqual (redirect_url .path , '/login/oauth/authorize' )
413
- params = urlparse . parse_qs (redirect_url .query , keep_blank_values = True )
426
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
414
427
state = params ['state' ][0 ] # this is a random value
415
428
self .assertEqual (params , {
416
429
'client_id' : ['01234567890123456789' ],
@@ -490,7 +503,7 @@ def setUpClass(cls):
490
503
cls .trac_env_broken = trac_env_broken
491
504
cls .trac_env_broken_api = trac_env_broken_api
492
505
493
- with open (d (SECRET ), 'wb ' ) as fp :
506
+ with open (d (SECRET ), 'w ' ) as fp :
494
507
fp .write ('98765432109876543210' )
495
508
496
509
@@ -505,11 +518,11 @@ def testLoginWithReqEmail(self):
505
518
response = requests .get (u ('github/login' ), allow_redirects = False )
506
519
self .assertEqual (response .status_code , 302 )
507
520
508
- redirect_url = urlparse . urlparse (response .headers ['Location' ])
521
+ redirect_url = urlparse (response .headers ['Location' ])
509
522
self .assertEqual (redirect_url .scheme , 'https' )
510
523
self .assertEqual (redirect_url .netloc , 'github.com' )
511
524
self .assertEqual (redirect_url .path , '/login/oauth/authorize' )
512
- params = urlparse . parse_qs (redirect_url .query , keep_blank_values = True )
525
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
513
526
state = params ['state' ][0 ] # this is a random value
514
527
self .assertEqual (params , {
515
528
'client_id' : ['01234567890123456789' ],
@@ -527,11 +540,11 @@ def loginAndVerifyClientId(self, expected_client_id):
527
540
response = requests .get (u ('github/login' ), allow_redirects = False )
528
541
self .assertEqual (response .status_code , 302 )
529
542
530
- redirect_url = urlparse . urlparse (response .headers ['Location' ])
543
+ redirect_url = urlparse (response .headers ['Location' ])
531
544
self .assertEqual (redirect_url .scheme , 'https' )
532
545
self .assertEqual (redirect_url .netloc , 'github.com' )
533
546
self .assertEqual (redirect_url .path , '/login/oauth/authorize' )
534
- params = urlparse . parse_qs (redirect_url .query , keep_blank_values = True )
547
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
535
548
state = params ['state' ][0 ] # this is a random value
536
549
self .assertEqual (params , {
537
550
'client_id' : [expected_client_id ],
@@ -636,8 +649,8 @@ def attemptValidOauth(self, testenv, callback, **kwargs):
636
649
self .assertEqual (response .status_code , 302 )
637
650
638
651
# 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 )
652
+ redirect_url = urlparse (response .headers ['Location' ])
653
+ params = parse_qs (redirect_url .query , keep_blank_values = True )
641
654
state = params ['state' ][0 ] # this is a random value
642
655
response = session .get (
643
656
u ('github/oauth' ),
@@ -1095,13 +1108,13 @@ class GitHubPostCommitHookWithUpdateHookTests(TracGitHubTests):
1095
1108
1096
1109
@classmethod
1097
1110
def createUpdateHook (cls ):
1098
- with open (d (UPDATEHOOK ), 'wb ' ) as fp :
1111
+ with open (d (UPDATEHOOK ), 'w ' ) as fp :
1099
1112
# simple shell script to echo back all input
1100
1113
fp .write ("""#!/bin/sh\n exec cat""" )
1101
1114
os .fchmod (fp .fileno (), 0o755 )
1102
1115
1103
1116
def createFailingUpdateHook (cls ):
1104
- with open (d (UPDATEHOOK ), 'wb ' ) as fp :
1117
+ with open (d (UPDATEHOOK ), 'w ' ) as fp :
1105
1118
fp .write ("""#!/bin/sh\n exit 1""" )
1106
1119
os .fchmod (fp .fileno (), 0o755 )
1107
1120
@@ -1160,7 +1173,7 @@ class GitHubPostCommitHookWithCacheTests(GitHubPostCommitHookTests):
1160
1173
cached_git = True
1161
1174
1162
1175
1163
- class GitHubAPIMock (BaseHTTPServer . BaseHTTPRequestHandler ):
1176
+ class GitHubAPIMock (BaseHTTPRequestHandler ):
1164
1177
def log_message (self , format , * args ):
1165
1178
# Visibly differentiate GitHub API mock logging from tracd logs
1166
1179
sys .stderr .write ("%s [%s] %s\n " %
@@ -1221,7 +1234,7 @@ def do_GET(self):
1221
1234
self .send_header ("Content-Type" , contenttype )
1222
1235
self .end_headers ()
1223
1236
1224
- self .wfile .write (json .dumps (answer ))
1237
+ self .wfile .write (json .dumps (answer , ensure_ascii = True ). encode ( 'ascii' ))
1225
1238
1226
1239
def do_POST (self ):
1227
1240
md = self .server .mockdata
@@ -1239,9 +1252,9 @@ def do_POST(self):
1239
1252
chunk = self .rfile .read (chunk_size )
1240
1253
if not chunk :
1241
1254
break
1242
- L .append (chunk )
1255
+ L .append (chunk . decode ( 'ascii' ) )
1243
1256
size_remaining -= len (L [- 1 ])
1244
- args = urlparse . parse_qs ('' .join (L ))
1257
+ args = parse_qs ('' .join (L ))
1245
1258
1246
1259
retcode = 404
1247
1260
answer = {}
@@ -1255,7 +1268,7 @@ def do_POST(self):
1255
1268
self .send_response (retcode )
1256
1269
self .send_header ("Content-Type" , contenttype )
1257
1270
self .end_headers ()
1258
- self .wfile .write (json .dumps (answer ))
1271
+ self .wfile .write (json .dumps (answer , ensure_ascii = True ). encode ( 'ascii' ))
1259
1272
1260
1273
1261
1274
class TracContext (object ):
@@ -1836,7 +1849,7 @@ def test_014_hook_membership_event_add_team(self):
1836
1849
self .assertGreater (len (data ), 0 , "No groups returned after update" )
1837
1850
self .assertIn (users [0 ]["login" ], data ,
1838
1851
"User %s expected after update, but not present" % users [0 ]["login" ])
1839
- self . assertItemsEqual (
1852
+ six . assertCountEqual ( self ,
1840
1853
data [users [0 ]["login" ]],
1841
1854
(u"github-%s-justice-league" % self .organization , u"github-%s" % self .organization ),
1842
1855
"User %s does not have expected groups after update" % users [0 ]["login" ])
@@ -1901,7 +1914,7 @@ def test_015_hook_membership_event_add_member(self):
1901
1914
self .assertGreater (len (data ), 0 , "No groups returned after update" )
1902
1915
self .assertIn (users [1 ]["login" ], data ,
1903
1916
"User %s expected after update, but not present" % users [1 ]["login" ])
1904
- self . assertItemsEqual (
1917
+ six . assertCountEqual ( self ,
1905
1918
data [users [1 ]["login" ]],
1906
1919
(u"github-%s-justice-league" % self .organization , u"github-%s" % self .organization ),
1907
1920
"User %s does not have expected groups after update" % users [1 ]["login" ])
@@ -2113,7 +2126,7 @@ def updateMockData(md, retcode=None, contenttype=None, answers=None,
2113
2126
JSON-encoded and returned for requests to the paths.
2114
2127
:param postcallback: A callback function called for the next POST requests.
2115
2128
Arguments are the requested path and a dict of POST
2116
- data as returned by `urlparse. parse_qs()`. The
2129
+ data as returned by `parse_qs()`. The
2117
2130
callback should return a tuple `(retcode, answer)`
2118
2131
where `retcode` is the HTTP return code and `answer`
2119
2132
will be JSON-encoded and sent to the client. Note that
@@ -2148,7 +2161,7 @@ def apiMockServer(port, mockdata):
2148
2161
be JSON-encoded and returned. Use `updateMockData()` to
2149
2162
update the contents of the mockdata dict.
2150
2163
"""
2151
- httpd = BaseHTTPServer . HTTPServer (('127.0.0.1' , port ), GitHubAPIMock )
2164
+ httpd = HTTPServer (('127.0.0.1' , port ), GitHubAPIMock )
2152
2165
# Make mockdata available to server
2153
2166
httpd .mockdata = mockdata
2154
2167
httpd .serve_forever ()
0 commit comments