Skip to content

Commit 72d5d6f

Browse files
committed
Use oauth endpoints for external testcase uploader
1 parent 96e334f commit 72d5d6f

File tree

2 files changed

+66
-37
lines changed

2 files changed

+66
-37
lines changed

src/clusterfuzz/_internal/config/local_config.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
MONITORING_REGIONS_PATH = 'monitoring.regions'
3535
PROJECT_PATH = 'project'
3636
SWARMING_PATH = 'swarming.swarming'
37-
EXTERNAL_TESTCASE_UPLOADER_PATH = 'external_testcase_reader.config'
37+
EXTERNAL_TESTCASE_UPLOADER_PATH = 'k8s.external_testcase_reader'
3838

3939

4040
def _load_yaml_file(yaml_file_path):
@@ -262,7 +262,7 @@ def __init__(self):
262262
super().__init__(SWARMING_PATH)
263263

264264

265-
class ExternalTestcaseReaderConfig(Config):
265+
class ExternalTestcaseReaderConfigr(Config):
266266
"""External testcase reader config."""
267267

268268
def __init__(self):

src/clusterfuzz/_internal/cron/external_testcase_reader.py

+64-35
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,27 @@
1919
from google.cloud import storage
2020
import requests
2121

22-
from appengine.libs import form
23-
from appengine.libs import gcs
24-
from appengine.libs import helpers
2522
from clusterfuzz._internal.config import local_config
2623
from clusterfuzz._internal.issue_management.google_issue_tracker import \
2724
issue_tracker
25+
from clusterfuzz._internal.metrics import logs
2826

2927
ACCEPTED_FILETYPES = [
3028
'text/javascript', 'application/pdf', 'text/html', 'application/zip'
3129
]
3230
ISSUETRACKER_ACCEPTED_STATE = 'ACCEPTED'
3331
ISSUETRACKER_WONTFIX_STATE = 'NOT_REPRODUCIBLE'
32+
_CLUSTERFUZZ_GET_URL = (
33+
'https://clusterfuzz.corp.google.com/upload-testcase/get-url-oauth')
34+
_UPLOAD_URL_PROPERTY = 'uploadUrl'
35+
_TESTCASE_ID_PROPERTY = 'id'
36+
37+
38+
class ExternalTestcaseReaderException(Exception):
39+
"""Error when uploading an externally submitted testcase.."""
40+
41+
def __init__(self, message):
42+
super().__init__(message)
3443

3544

3645
def get_vrp_uploaders(config):
@@ -42,19 +51,18 @@ def get_vrp_uploaders(config):
4251
return members
4352

4453

45-
def close_issue_if_invalid(upload_request, attachment_info, description,
46-
vrp_uploaders):
54+
def close_issue_if_invalid(issue, attachment_info, description, vrp_uploaders):
4755
"""Closes any invalid upload requests with a helpful message."""
4856
comment_message = (
4957
'Hello, this issue is automatically closed. Please file a new bug after'
5058
' fixing the following issues:\n\n')
5159
invalid = False
5260

5361
# TODO(pgrace) Remove after testing.
54-
if upload_request.id == 373893311:
62+
if issue.id == 373893311:
5563
return False
5664

57-
if not upload_request.reporter in vrp_uploaders:
65+
if not issue.reporter in vrp_uploaders:
5866
comment_message += (
5967
'You are not authorized to submit testcases to Clusterfuzz.'
6068
' If you believe you should be, please reach out to'
@@ -90,8 +98,8 @@ def close_issue_if_invalid(upload_request, attachment_info, description,
9098
comment_message += (
9199
'\nPlease see the new bug template for more information on how to use'
92100
' Clusterfuzz direct uploads.')
93-
upload_request.status = ISSUETRACKER_WONTFIX_STATE
94-
upload_request.save(new_comment=comment_message, notify=True)
101+
issue.status = ISSUETRACKER_WONTFIX_STATE
102+
issue.save(new_comment=comment_message, notify=True)
95103

96104
return invalid
97105

@@ -116,71 +124,91 @@ def filed_n_days_ago(issue_created_time_string, config):
116124

117125
def submit_testcase(issue_id, file, filename, filetype, cmds):
118126
"""Uploads the given testcase file to Clusterfuzz."""
127+
target = None
119128
if filetype == 'text/javascript':
120129
job = 'linux_asan_d8_dbg'
121130
elif filetype == 'application/pdf':
122131
job = 'libfuzzer_pdfium_asan'
132+
# Only libfuzzer_pdfium_asan needs a fuzzer target specified
133+
target = 'pdfium_xfa_fuzzer'
123134
elif filetype == 'text/html':
124135
job = 'linux_asan_chrome_mp'
125136
elif filetype == 'application/zip':
126137
job = 'linux_asan_chrome_mp'
127138
else:
128139
raise TypeError
129-
upload_info = gcs.prepare_blob_upload()._asdict()
140+
141+
get_url_response = requests.post(_CLUSTERFUZZ_GET_URL, timeout=10)
142+
print(get_url_response.content)
143+
if _UPLOAD_URL_PROPERTY not in get_url_response:
144+
logs.error('Unexpected response (missing uploadUrl): %s' % get_url_response)
145+
raise ExternalTestcaseReaderException(
146+
'Unexpected response (missing uploadUrl): %s' % get_url_response)
147+
upload_url = get_url_response[_UPLOAD_URL_PROPERTY]
130148

131149
data = {
132-
# Content provided by uploader.
133-
'issue': issue_id,
150+
'platform': 'Linux',
134151
'job': job,
135-
'file': file,
152+
'issue': issue_id,
136153
'cmd': cmds,
154+
'file': file,
137155
'x-goog-meta-filename': filename,
138-
139-
# Content generated internally.
140-
'platform': 'Linux',
141-
'csrf_token': form.generate_csrf_token(),
142-
'upload_key': upload_info['key'],
143-
# TODO(pgrace) Replace with upload_info['bucket'] once testing complete.
144-
'bucket': 'clusterfuzz-test-bucket',
145-
'key': upload_info['key'],
146-
'GoogleAccessId': upload_info['google_access_id'],
147-
'policy': upload_info['policy'],
148-
'signature': upload_info['signature'],
149156
}
150157

151-
return requests.post(
152-
'https://clusterfuzz.com/upload-testcase/upload', data=data, timeout=10)
158+
if target:
159+
data['target'] = target
160+
161+
upload_response = requests.post(upload_url, data=data, timeout=10)
162+
is_error_code = upload_response.status_code != 200
163+
is_missing_testcase_id = _TESTCASE_ID_PROPERTY not in upload_response
164+
if is_error_code or is_missing_testcase_id:
165+
reason = 'missing testcase id' if is_missing_testcase_id else 'failure code'
166+
msg = 'Unexpected response (%s): %s' % (reason, upload_response)
167+
logs.error(msg)
168+
raise ExternalTestcaseReaderException(msg)
169+
170+
return upload_response
153171

154172

155173
def handle_testcases(tracker, config):
156174
"""Fetches and submits testcases from bugs or closes unnecessary bugs."""
157175

176+
177+
print("START ISSUES")
158178
# Handle bugs that were already submitted and still open.
159179
older_issues = tracker.find_issues_with_filters(
160180
keywords=[],
161181
query_filters=['componentid:1600865', 'status:accepted'],
162182
only_open=True)
183+
print("START ISSUE111S")
163184
for issue in older_issues:
185+
print("START ISSUE 222S")
164186
# Close out older bugs that may have failed to reproduce.
165187
if close_issue_if_not_reproducible(issue, config):
166-
helpers.log('Closing issue {issue_id} as it failed to reproduce',
167-
issue.id)
188+
print("START ISSeeeUES")
189+
logs.info('Closing issue %s as it failed to reproduce' & issue.id)
168190

191+
print("START ISSUESqqq")
169192
# Handle new bugs that may need to be submitted.
170193
issues = tracker.find_issues_with_filters(
171194
keywords=[],
172195
query_filters=['componentid:1600865', 'status:new'],
173196
only_open=True)
174-
if len(issues) == 0:
197+
print("GOT TJE SSUES ISSUES")
198+
issues_list = list(issues)
199+
if len(issues_list) == 0: # issues is a generator
200+
print("NO ISSUES")
175201
return
176202

177203
vrp_uploaders = get_vrp_uploaders(config)
204+
print(vrp_uploaders)
178205

179206
# Rudimentary rate limiting -
180207
# Process only a certain number of bugs per reporter for each job run.
181208
reporters_map = {}
182209

183-
for issue in issues:
210+
for issue in issues_list:
211+
print("WE HAVE AN ISSUE JUKKK")
184212
attachment_metadata = tracker.get_attachment_metadata(issue.id)
185213
commandline_flags = tracker.get_description(issue.id)
186214
if reporters_map.get(issue.reporter,
@@ -189,7 +217,7 @@ def handle_testcases(tracker, config):
189217
reporters_map[issue.reporter] = reporters_map.get(issue.reporter, 1) + 1
190218
if close_issue_if_invalid(issue, attachment_metadata, commandline_flags,
191219
vrp_uploaders):
192-
helpers.log('Closing issue {issue_id} as it is invalid', issue.id)
220+
logs.info('Closing issue %s as it is invalid' % issue.id)
193221
continue
194222

195223
# Submit valid testcases.
@@ -202,13 +230,14 @@ def handle_testcases(tracker, config):
202230
issue.status = ISSUETRACKER_ACCEPTED_STATE
203231
issue.assignee = '[email protected]'
204232
issue.save(new_comment=comment_message, notify=True)
205-
helpers.log('Submitted testcase file for issue {issue_id}', issue.id)
206-
233+
logs.info('Submitted testcase file for issue %s' % issue.id)
207234

235+
_ISSUE_TRACKER_URL = 'https://issues.chromium.org/issues'
208236
def main():
209237
tracker = issue_tracker.IssueTracker('chromium', None,
210-
{'default_component_id': 1363614})
211-
handle_testcases(tracker, local_config.ExternalTestcaseReaderConfig())
238+
{'default_component_id': 1363614,
239+
'url': _ISSUE_TRACKER_URL})
240+
handle_testcases(tracker, local_config.ExternalTestcaseReaderConfigr())
212241

213242

214243
if __name__ == '__main__':

0 commit comments

Comments
 (0)