Logging_.py
1 ############################ Copyrights and license ############################ 2 # # 3 # Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> # 4 # Copyright 2012 Zearin <zearin@gonk.net> # 5 # Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> # 6 # Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> # 7 # Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> # 8 # Copyright 2017 Hugo <hugovk@users.noreply.github.com> # 9 # Copyright 2018 R1kk3r <R1kk3r@users.noreply.github.com> # 10 # Copyright 2018 sfdye <tsfdye@gmail.com> # 11 # # 12 # This file is part of PyGithub. # 13 # http://pygithub.readthedocs.io/ # 14 # # 15 # PyGithub is free software: you can redistribute it and/or modify it under # 16 # the terms of the GNU Lesser General Public License as published by the Free # 17 # Software Foundation, either version 3 of the License, or (at your option) # 18 # any later version. # 19 # # 20 # PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # 21 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # 22 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # 23 # details. # 24 # # 25 # You should have received a copy of the GNU Lesser General Public License # 26 # along with PyGithub. If not, see <http://www.gnu.org/licenses/>. # 27 # # 28 ################################################################################ 29 30 import github 31 32 from . import Framework 33 34 35 class Logging(Framework.BasicTestCase): 36 class MockLogger: 37 def __init__(self): 38 self.verb = None 39 self.url = None 40 self.requestHeaders = None 41 self.input = None 42 self.status = None 43 self.responseHeaders = None 44 self.output = None 45 46 def isEnabledFor(self, kind): 47 return True 48 49 def debug( 50 self, 51 format_string, 52 verb, 53 scheme, 54 hostname, 55 fragment, 56 requestHeaders, 57 input_, 58 status, 59 responseHeaders, 60 output, 61 ): 62 self.verb = verb 63 self.url = f"{scheme}://{hostname}{fragment}" 64 self.requestHeaders = requestHeaders 65 self.input = input_ 66 self.status = status 67 self.responseHeaders = responseHeaders 68 self.output = output 69 70 def setUp(self): 71 super().setUp() 72 self.logger = self.MockLogger() 73 github.Requester.Requester.injectLogger(self.logger) 74 75 def tearDown(self): 76 github.Requester.Requester.resetLogger() 77 super().tearDown() 78 79 def assertLogging(self, verb, url, requestHeaders, responseHeaders, output): 80 self.assertEqual(self.logger.verb, verb) 81 self.assertEqual(self.logger.url, url) 82 self.assertEqual(self.logger.requestHeaders, requestHeaders) 83 self.assertIsNone(self.logger.input) 84 self.assertEqual(self.logger.status, 200) 85 self.assertEqual(self.logger.responseHeaders, responseHeaders) 86 self.assertEqual(self.logger.output, output) 87 88 def testLoggingWithBasicAuthentication(self): 89 self.assertEqual(github.Github(auth=self.login).get_user().name, "Vincent Jacques") 90 url = "https://api.github.com/user" 91 requestHeaders = { 92 "Authorization": "Basic (login and password removed)", 93 "User-Agent": "PyGithub/Python", 94 } 95 responseHeaders = { 96 "status": "200 OK", 97 "content-length": "806", 98 "x-github-media-type": "github.beta; format=json", 99 "x-content-type-options": "nosniff", 100 "x-ratelimit-limit": "5000", 101 "vary": "Accept, Authorization, Cookie", 102 "x-ratelimit-remaining": "4993", 103 "server": "nginx", 104 "last-modified": "Fri, 14 Sep 2012 18:47:46 GMT", 105 "connection": "keep-alive", 106 "etag": '"434dfe5d3f50558fe3cea087cb95c401"', 107 "cache-control": "private, s-maxage=60, max-age=60", 108 "date": "Mon, 17 Sep 2012 17:12:32 GMT", 109 "content-type": "application/json; charset=utf-8", 110 "DEBUG_FRAME": 0, 111 } 112 output = '{"owned_private_repos":3,"disk_usage":18612,"following":28,"type":"User","public_repos":13,"location":"Paris, France","company":"Criteo","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","plan":{"space":614400,"private_repos":5,"name":"micro","collaborators":1},"blog":"http://vincent-jacques.net","login":"jacquev6","public_gists":3,"html_url":"https://github.com/jacquev6","hireable":false,"created_at":"2010-07-09T06:10:06Z","private_gists":5,"followers":13,"name":"Vincent Jacques","email":"vincent@vincent-jacques.net","bio":"","total_private_repos":3,"collaborators":0,"gravatar_id":"b68de5ae38616c296fa345d2b9df2225","id":327146,"url":"https://api.github.com/users/jacquev6"}' 113 self.assertLogging("GET", url, requestHeaders, responseHeaders, output) 114 115 def testLoggingWithOAuthAuthentication(self): 116 self.assertEqual(github.Github(auth=self.oauth_token).get_user().name, "Vincent Jacques") 117 url = "https://api.github.com/user" 118 requestHeaders = { 119 "Authorization": "token (oauth token removed)", 120 "User-Agent": "PyGithub/Python", 121 } 122 responseHeaders = { 123 "status": "200 OK", 124 "x-ratelimit-remaining": "4993", 125 "x-github-media-type": "github.beta; format=json", 126 "x-content-type-options": "nosniff", 127 "vary": "Accept, Authorization, Cookie", 128 "content-length": "628", 129 "server": "nginx", 130 "last-modified": "Tue, 25 Sep 2012 07:42:42 GMT", 131 "connection": "keep-alive", 132 "x-ratelimit-limit": "5000", 133 "etag": '"c23ad6b5815fc3d6ec6341c4a47afe85"', 134 "cache-control": "private, max-age=60, s-maxage=60", 135 "date": "Tue, 25 Sep 2012 20:36:54 GMT", 136 "x-oauth-scopes": "", 137 "content-type": "application/json; charset=utf-8", 138 "x-accepted-oauth-scopes": "user", 139 "DEBUG_FRAME": 0, 140 } 141 output = '{"type":"User","bio":"","html_url":"https://github.com/jacquev6","login":"jacquev6","followers":14,"company":"Criteo","blog":"http://vincent-jacques.net","public_repos":13,"created_at":"2010-07-09T06:10:06Z","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","email":"vincent@vincent-jacques.net","following":29,"name":"Vincent Jacques","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","hireable":false,"id":327146,"public_gists":3,"location":"Paris, France","url":"https://api.github.com/users/jacquev6"}' 142 self.assertLogging("GET", url, requestHeaders, responseHeaders, output) 143 144 def testLoggingWithoutAuthentication(self): 145 self.assertEqual(github.Github().get_user("jacquev6").name, "Vincent Jacques") 146 url = "https://api.github.com/users/jacquev6" 147 requestHeaders = {"User-Agent": "PyGithub/Python"} 148 responseHeaders = { 149 "status": "200 OK", 150 "content-length": "628", 151 "x-github-media-type": "github.beta; format=json", 152 "x-content-type-options": "nosniff", 153 "x-ratelimit-limit": "5000", 154 "vary": "Accept", 155 "x-ratelimit-remaining": "4989", 156 "server": "nginx", 157 "last-modified": "Tue, 25 Sep 2012 07:42:42 GMT", 158 "connection": "keep-alive", 159 "etag": '"9bd085221a16b6d2ea95e72634c3c1ac"', 160 "cache-control": "public, max-age=60, s-maxage=60", 161 "date": "Tue, 25 Sep 2012 20:38:56 GMT", 162 "content-type": "application/json; charset=utf-8", 163 "DEBUG_FRAME": 0, 164 } 165 output = '{"type":"User","html_url":"https://github.com/jacquev6","login":"jacquev6","followers":14,"company":"Criteo","created_at":"2010-07-09T06:10:06Z","email":"vincent@vincent-jacques.net","hireable":false,"avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","public_gists":3,"bio":"","following":29,"name":"Vincent Jacques","blog":"http://vincent-jacques.net","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","id":327146,"public_repos":13,"location":"Paris, France","url":"https://api.github.com/users/jacquev6"}' 166 self.assertLogging("GET", url, requestHeaders, responseHeaders, output) 167 168 def testLoggingWithBaseUrl(self): 169 # ReplayData forged, not recorded 170 self.assertEqual( 171 github.Github(base_url="http://my.enterprise.com/my/prefix").get_user("jacquev6").name, 172 "Vincent Jacques", 173 ) 174 url = "http://my.enterprise.com/my/prefix/users/jacquev6" 175 requestHeaders = {"User-Agent": "PyGithub/Python"} 176 responseHeaders = { 177 "status": "200 OK", 178 "content-length": "628", 179 "x-github-media-type": "github.beta; format=json", 180 "x-content-type-options": "nosniff", 181 "x-ratelimit-limit": "5000", 182 "vary": "Accept", 183 "x-ratelimit-remaining": "4989", 184 "server": "nginx", 185 "last-modified": "Tue, 25 Sep 2012 07:42:42 GMT", 186 "connection": "keep-alive", 187 "etag": '"9bd085221a16b6d2ea95e72634c3c1ac"', 188 "cache-control": "public, max-age=60, s-maxage=60", 189 "date": "Tue, 25 Sep 2012 20:38:56 GMT", 190 "content-type": "application/json; charset=utf-8", 191 "DEBUG_FRAME": 0, 192 } 193 output = '{"type":"User","html_url":"https://github.com/jacquev6","login":"jacquev6","followers":14,"company":"Criteo","created_at":"2010-07-09T06:10:06Z","email":"vincent@vincent-jacques.net","hireable":false,"avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","public_gists":3,"bio":"","following":29,"name":"Vincent Jacques","blog":"http://vincent-jacques.net","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","id":327146,"public_repos":13,"location":"Paris, France","url":"https://api.github.com/users/jacquev6"}' 194 self.assertLogging("GET", url, requestHeaders, responseHeaders, output) 195 196 def testLoggingDoesNotModifyRequestHeaders(self): 197 # Recorded replay data already sanitizes Authorization headers, so we 198 # need to go under the covers 199 requestHeaders = {"Authorization": "thisisnotatoken"} 200 responseHeaders = {"status": "200 OK"} 201 github.Github()._Github__requester._Requester__log( 202 "GET", 203 "http://example.com", 204 requestHeaders, 205 None, 206 200, 207 responseHeaders, 208 None, 209 ) 210 self.assertEqual(requestHeaders["Authorization"], "thisisnotatoken")