def send_request(url, data): """Get a clusterfuzz url that requires authentication. Attempts to authenticate and is guaranteed to either return a valid, authorized response or throw an exception.""" header = common.get_stored_auth_header() or get_verification_header() response = None for _ in range(2): response = common.post(url=url, headers={ 'Authorization': header, 'User-Agent': 'clusterfuzz-tools' }, allow_redirects=True, data=data) if response.status_code == 401: # The access token expired. header = get_verification_header() else: # Other errors or success break if response.status_code != 200: raise common.ClusterfuzzAuthError(response.text) common.store_auth_header(response.headers[CLUSTERFUZZ_AUTH_HEADER]) return response
def send_request(url, data): """Get a clusterfuzz url that requires authentication. Attempts to authenticate and is guaranteed to either return a valid, authorized response or throw an exception.""" header = common.get_stored_auth_header() or get_verification_header() response = None for _ in range(RETRY_COUNT): response = common.post( url=url, headers={ 'Authorization': header, 'User-Agent': 'clusterfuzz-tools' }, data=data, allow_redirects=True) # The access token expired. if response.status_code == 401: header = get_verification_header() # Internal server error (e.g. due to deployment) elif response.status_code == 500: time.sleep(common.RETRY_SLEEP_TIME) continue else: # Other errors or success break if response.status_code != 200: raise error.ClusterFuzzError( response.status_code, response.text, str(response.headers.get(CLUSTERFUZZ_AUTH_IDENTITY, ''))) common.store_auth_header(response.headers[CLUSTERFUZZ_AUTH_HEADER]) return response
def test_exception(self): """Test retrying.""" self.http.post.side_effect = ([exceptions.ConnectionError()] * (common.RETRY_COUNT + 1)) with self.assertRaises(exceptions.ConnectionError): common.post(url='a', headers={'c': 'd'}, data={'e': 'f'}, random='thing') self.assertTrue(os.path.exists(common.CLUSTERFUZZ_TESTCASES_DIR)) self.assertEqual(common.RETRY_COUNT + 1, self.mock.CachedSession.call_count) self.assertEqual(common.RETRY_COUNT + 1, self.http.mount.call_count) self.assert_exact_calls(self.http.post, [ mock.call( url='a', headers={'c': 'd'}, data={'e': 'f'}, random='thing') ] * (common.RETRY_COUNT + 1))
def get_crash_signature(job_type, raw_stacktrace): """Get crash signature from raw_stacktrace by asking ClusterFuzz.""" response = common.post(url='https://clusterfuzz.com/parse_stacktrace', data=json.dumps({ 'job': job_type, 'stacktrace': raw_stacktrace })) response = json.loads(response.text) crash_state_lines = tuple( [x for x in response['crash_state'].split('\n') if x]) crash_type = response['crash_type'].replace('\n', ' ') return common.CrashSignature(crash_type, crash_state_lines)
def get_stacktrace_info(self, trace): """Post a stacktrace, return (crash_state, crash_type).""" response = common.post( url=('https://clusterfuzz.com/v2/parse_stacktrace'), data=json.dumps({ 'job': self.job_type, 'stacktrace': trace })) response = json.loads(response.text) crash_state_lines = tuple( [x for x in response['crash_state'].split('\n') if x]) crash_type = response['crash_type'].replace('\n', ' ') return common.CrashSignature(crash_type, crash_state_lines)
def test_post(self): """Test post.""" self.http.post.return_value = 'returned' self.assertEqual( 'returned', common.post(url='a', headers={'c': 'd'}, data={'e': 'f'}, random='thing')) self.assertTrue(os.path.exists(common.CLUSTERFUZZ_TESTCASES_DIR)) self.assertEqual(1, self.mock.CachedSession.call_count) self.assertEqual(1, self.http.mount.call_count) self.http.post.assert_called_once_with(url='a', headers={'c': 'd'}, data={'e': 'f'}, random='thing')