1010"""
1111from __future__ import print_function
1212
13+ # Python3 imports are commented out, six is used to offer py2+py3 compatibility
1314import argparse
14- import BaseHTTPServer
15- import ConfigParser
15+ # from configparser import ConfigParser
16+ # from http.server import BaseHTTPRequestHandler, HTTPServer
1617import json
1718import os
1819import random
2627import time
2728import traceback
2829import 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
3036
3137from lxml import html
3238
3541from trac .util .translation import _
3642
3743import requests
44+ import six
3845
3946
4047GIT = 'test-git-foo'
@@ -83,6 +90,9 @@ def git_check_output(*args, **kwargs):
8390 as a string.
8491 """
8592 repo = kwargs .pop ('repo' , None )
93+ kwargs .setdefault ('text' , True )
94+ if six .PY2 :
95+ del kwargs ['text' ]
8696
8797 if repo is None :
8898 cmdargs = ["git" ] + list (args )
@@ -136,9 +146,12 @@ def createTracEnvironment(cls, **kwargs):
136146 subprocess .check_output ([TRAC_ADMIN_BIN , d (ENV ), 'permission' ,
137147 'add' , 'anonymous' , 'TRAC_ADMIN' ])
138148
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 )
142155
143156 conf .add_section ('components' )
144157 conf .set ('components' , 'trac.versioncontrol.web_ui.browser.BrowserModule' , 'disabled' )
@@ -210,7 +223,7 @@ def createTracEnvironment(cls, **kwargs):
210223 conf .set ('trac' , 'permission_policies' ,
211224 'GitHubPolicy, %s' % old_permission_policies )
212225
213- with open (d (CONF ), 'wb ' ) as fp :
226+ with open (d (CONF ), 'w ' ) as fp :
214227 conf .write (fp )
215228
216229 with open (d (HTDIGEST ), 'w' ) as fp :
@@ -269,7 +282,7 @@ def makeGitCommit(repo, path, content, message='edit', branch=None):
269282
270283 if branch != GIT_DEFAULT_BRANCH :
271284 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 :
273286 fp .write (content )
274287 git_check_output ('add' , path , repo = repo )
275288 git_check_output ('commit' , '-m' , message , repo = repo )
@@ -406,11 +419,11 @@ def testLogin(self):
406419 response = requests .get (u ('github/login' ), allow_redirects = False )
407420 self .assertEqual (response .status_code , 302 )
408421
409- redirect_url = urlparse . urlparse (response .headers ['Location' ])
422+ redirect_url = urlparse (response .headers ['Location' ])
410423 self .assertEqual (redirect_url .scheme , 'https' )
411424 self .assertEqual (redirect_url .netloc , 'github.com' )
412425 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 )
414427 state = params ['state' ][0 ] # this is a random value
415428 self .assertEqual (params , {
416429 'client_id' : ['01234567890123456789' ],
@@ -490,7 +503,7 @@ def setUpClass(cls):
490503 cls .trac_env_broken = trac_env_broken
491504 cls .trac_env_broken_api = trac_env_broken_api
492505
493- with open (d (SECRET ), 'wb ' ) as fp :
506+ with open (d (SECRET ), 'w ' ) as fp :
494507 fp .write ('98765432109876543210' )
495508
496509
@@ -505,11 +518,11 @@ def testLoginWithReqEmail(self):
505518 response = requests .get (u ('github/login' ), allow_redirects = False )
506519 self .assertEqual (response .status_code , 302 )
507520
508- redirect_url = urlparse . urlparse (response .headers ['Location' ])
521+ redirect_url = urlparse (response .headers ['Location' ])
509522 self .assertEqual (redirect_url .scheme , 'https' )
510523 self .assertEqual (redirect_url .netloc , 'github.com' )
511524 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 )
513526 state = params ['state' ][0 ] # this is a random value
514527 self .assertEqual (params , {
515528 'client_id' : ['01234567890123456789' ],
@@ -527,11 +540,11 @@ def loginAndVerifyClientId(self, expected_client_id):
527540 response = requests .get (u ('github/login' ), allow_redirects = False )
528541 self .assertEqual (response .status_code , 302 )
529542
530- redirect_url = urlparse . urlparse (response .headers ['Location' ])
543+ redirect_url = urlparse (response .headers ['Location' ])
531544 self .assertEqual (redirect_url .scheme , 'https' )
532545 self .assertEqual (redirect_url .netloc , 'github.com' )
533546 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 )
535548 state = params ['state' ][0 ] # this is a random value
536549 self .assertEqual (params , {
537550 'client_id' : [expected_client_id ],
@@ -636,8 +649,8 @@ def attemptValidOauth(self, testenv, callback, **kwargs):
636649 self .assertEqual (response .status_code , 302 )
637650
638651 # 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 )
641654 state = params ['state' ][0 ] # this is a random value
642655 response = session .get (
643656 u ('github/oauth' ),
@@ -1095,13 +1108,13 @@ class GitHubPostCommitHookWithUpdateHookTests(TracGitHubTests):
10951108
10961109 @classmethod
10971110 def createUpdateHook (cls ):
1098- with open (d (UPDATEHOOK ), 'wb ' ) as fp :
1111+ with open (d (UPDATEHOOK ), 'w ' ) as fp :
10991112 # simple shell script to echo back all input
11001113 fp .write ("""#!/bin/sh\n exec cat""" )
11011114 os .fchmod (fp .fileno (), 0o755 )
11021115
11031116 def createFailingUpdateHook (cls ):
1104- with open (d (UPDATEHOOK ), 'wb ' ) as fp :
1117+ with open (d (UPDATEHOOK ), 'w ' ) as fp :
11051118 fp .write ("""#!/bin/sh\n exit 1""" )
11061119 os .fchmod (fp .fileno (), 0o755 )
11071120
@@ -1160,7 +1173,7 @@ class GitHubPostCommitHookWithCacheTests(GitHubPostCommitHookTests):
11601173 cached_git = True
11611174
11621175
1163- class GitHubAPIMock (BaseHTTPServer . BaseHTTPRequestHandler ):
1176+ class GitHubAPIMock (BaseHTTPRequestHandler ):
11641177 def log_message (self , format , * args ):
11651178 # Visibly differentiate GitHub API mock logging from tracd logs
11661179 sys .stderr .write ("%s [%s] %s\n " %
@@ -1221,7 +1234,7 @@ def do_GET(self):
12211234 self .send_header ("Content-Type" , contenttype )
12221235 self .end_headers ()
12231236
1224- self .wfile .write (json .dumps (answer ))
1237+ self .wfile .write (json .dumps (answer , ensure_ascii = True ). encode ( 'ascii' ))
12251238
12261239 def do_POST (self ):
12271240 md = self .server .mockdata
@@ -1239,9 +1252,9 @@ def do_POST(self):
12391252 chunk = self .rfile .read (chunk_size )
12401253 if not chunk :
12411254 break
1242- L .append (chunk )
1255+ L .append (chunk . decode ( 'ascii' ) )
12431256 size_remaining -= len (L [- 1 ])
1244- args = urlparse . parse_qs ('' .join (L ))
1257+ args = parse_qs ('' .join (L ))
12451258
12461259 retcode = 404
12471260 answer = {}
@@ -1255,7 +1268,7 @@ def do_POST(self):
12551268 self .send_response (retcode )
12561269 self .send_header ("Content-Type" , contenttype )
12571270 self .end_headers ()
1258- self .wfile .write (json .dumps (answer ))
1271+ self .wfile .write (json .dumps (answer , ensure_ascii = True ). encode ( 'ascii' ))
12591272
12601273
12611274class TracContext (object ):
@@ -1836,7 +1849,7 @@ def test_014_hook_membership_event_add_team(self):
18361849 self .assertGreater (len (data ), 0 , "No groups returned after update" )
18371850 self .assertIn (users [0 ]["login" ], data ,
18381851 "User %s expected after update, but not present" % users [0 ]["login" ])
1839- self . assertItemsEqual (
1852+ six . assertCountEqual ( self ,
18401853 data [users [0 ]["login" ]],
18411854 (u"github-%s-justice-league" % self .organization , u"github-%s" % self .organization ),
18421855 "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):
19011914 self .assertGreater (len (data ), 0 , "No groups returned after update" )
19021915 self .assertIn (users [1 ]["login" ], data ,
19031916 "User %s expected after update, but not present" % users [1 ]["login" ])
1904- self . assertItemsEqual (
1917+ six . assertCountEqual ( self ,
19051918 data [users [1 ]["login" ]],
19061919 (u"github-%s-justice-league" % self .organization , u"github-%s" % self .organization ),
19071920 "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,
21132126 JSON-encoded and returned for requests to the paths.
21142127 :param postcallback: A callback function called for the next POST requests.
21152128 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
21172130 callback should return a tuple `(retcode, answer)`
21182131 where `retcode` is the HTTP return code and `answer`
21192132 will be JSON-encoded and sent to the client. Note that
@@ -2148,7 +2161,7 @@ def apiMockServer(port, mockdata):
21482161 be JSON-encoded and returned. Use `updateMockData()` to
21492162 update the contents of the mockdata dict.
21502163 """
2151- httpd = BaseHTTPServer . HTTPServer (('127.0.0.1' , port ), GitHubAPIMock )
2164+ httpd = HTTPServer (('127.0.0.1' , port ), GitHubAPIMock )
21522165 # Make mockdata available to server
21532166 httpd .mockdata = mockdata
21542167 httpd .serve_forever ()
0 commit comments