diff --git a/tests/log_parser/test_utils.py b/tests/log_parser/test_utils.py index b59ccb5202b..a573144985d 100644 --- a/tests/log_parser/test_utils.py +++ b/tests/log_parser/test_utils.py @@ -3,8 +3,8 @@ # file, you can obtain one at http://mozilla.org/MPL/2.0/. import pytest -from treeherder.log_parser.utils import (get_error_search_term, - get_crash_signature) +from treeherder.model.bug_suggestions import (get_error_search_term, + get_crash_signature) PIPE_DELIMITED_LINE_TEST_CASES = ( diff --git a/tests/sample_data/artifacts/text_log_summary.json b/tests/sample_data/artifacts/text_log_summary.json new file mode 100644 index 00000000000..0a419e9d498 --- /dev/null +++ b/tests/sample_data/artifacts/text_log_summary.json @@ -0,0 +1,262 @@ +{ + "blob": { + "header": { + "slave": "t-snow-r4-0001", + "buildid": "20150415030206", + "builder": "mozilla-central_snowleopard_test-mochitest-2", + "results": "warnings (1)", + "starttime": "1429100703.17", + "builduid": "8ad46455f18545abbdff94ba9dce402e", + "revision": "a6f7a33731bc3fe22073129bba83fc7480e387e2" + }, + "step_data": { + "all_errors": [ + { + "line": "05:35:49 INFO - 2018 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Should be able to get objectStore - expected PASS", + "linenumber": 8151 + }, + { + "line": "05:35:49 INFO - 2019 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Should be able to get index - expected PASS", + "linenumber": 8152 + }, + { + "line": "05:35:49 INFO - 2023 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Ordering is correct. - expected PASS", + "linenumber": 8156 + }, + { + "line": "05:35:49 INFO - 2024 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Worker: uncaught exception [http://mochi.test:8888/tests/dom/indexedDB/test/unit/test_transaction_lifetimes.js:45]: ': InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable' - expected PASS", + "linenumber": 8157 + } + ], + "steps": [ + { + "errors": [ ], + "name": "set props: master", + "started": "2015-04-15 05:25:03.168328", + "started_linenumber": 8, + "finished_linenumber": 10, + "finished": "2015-04-15 05:25:03.168795", + "error_count": 0, + "duration": 0, + "order": 0, + "result": "success" + }, + { + "errors": [ ], + "name": "set props: basedir", + "started": "2015-04-15 05:25:03.169099", + "started_linenumber": 12, + "finished_linenumber": 40, + "finished": "2015-04-15 05:25:03.597219", + "error_count": 0, + "duration": 0, + "order": 1, + "result": "success" + }, + { + "errors": [ ], + "name": "downloading to buildprops.json", + "started": "2015-04-15 05:25:03.597542", + "started_linenumber": 42, + "finished_linenumber": 43, + "finished": "2015-04-15 05:25:03.726142", + "error_count": 0, + "duration": 0, + "order": 2, + "result": "success" + }, + { + "errors": [ ], + "name": "'rm -rf ...'", + "started": "2015-04-15 05:25:03.726523", + "started_linenumber": 45, + "finished_linenumber": 71, + "finished": "2015-04-15 05:25:03.777120", + "error_count": 0, + "duration": 0, + "order": 3, + "result": "success" + }, + { + "errors": [ ], + "name": "set props: script_repo_url", + "started": "2015-04-15 05:25:03.777445", + "started_linenumber": 73, + "finished_linenumber": 75, + "finished": "2015-04-15 05:25:03.777817", + "error_count": 0, + "duration": 0, + "order": 4, + "result": "success" + }, + { + "errors": [ ], + "name": "'bash -c ...'", + "started": "2015-04-15 05:25:03.778747", + "started_linenumber": 77, + "finished_linenumber": 114, + "finished": "2015-04-15 05:25:03.945448", + "error_count": 0, + "duration": 0, + "order": 5, + "result": "success" + }, + { + "errors": [ ], + "name": "set props: script_repo_revision script_repo_url", + "started": "2015-04-15 05:25:03.945809", + "started_linenumber": 116, + "finished_linenumber": 146, + "finished": "2015-04-15 05:25:04.682022", + "error_count": 0, + "duration": 1, + "order": 6, + "result": "success" + }, + { + "errors": [ ], + "name": "'rm -rf ...'", + "started": "2015-04-15 05:25:04.682572", + "started_linenumber": 148, + "finished_linenumber": 174, + "finished": "2015-04-15 05:25:05.278125", + "error_count": 0, + "duration": 1, + "order": 7, + "result": "success" + }, + { + "errors": [ ], + "name": "'hg clone ...'", + "started": "2015-04-15 05:25:05.278437", + "started_linenumber": 176, + "finished_linenumber": 210, + "finished": "2015-04-15 05:25:11.964370", + "error_count": 0, + "duration": 7, + "order": 8, + "result": "success" + }, + { + "errors": [ ], + "name": "'hg update ...'", + "started": "2015-04-15 05:25:11.964712", + "started_linenumber": 212, + "finished_linenumber": 239, + "finished": "2015-04-15 05:25:12.506740", + "error_count": 0, + "duration": 1, + "order": 9, + "result": "success" + }, + { + "errors": [ ], + "name": "set props: script_repo_revision", + "started": "2015-04-15 05:25:12.507514", + "started_linenumber": 241, + "finished_linenumber": 269, + "finished": "2015-04-15 05:25:12.700263", + "error_count": 0, + "duration": 0, + "order": 10, + "result": "success" + }, + { + "errors": [ ], + "name": "downloading to oauth.txt", + "started": "2015-04-15 05:25:12.700568", + "started_linenumber": 271, + "finished_linenumber": 272, + "finished": "2015-04-15 05:25:12.730239", + "error_count": 0, + "duration": 0, + "order": 11, + "result": "success" + }, + { + "errors": [ ], + "name": "tinderboxprint_script_revlink", + "started": "2015-04-15 05:25:12.730485", + "started_linenumber": 274, + "finished_linenumber": 276, + "finished": "2015-04-15 05:25:12.730832", + "error_count": 0, + "duration": 0, + "order": 12, + "result": "success" + }, + { + "errors": [ + { + "line": "05:35:49 INFO - 2018 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Should be able to get objectStore - expected PASS", + "linenumber": 8151 + }, + { + "line": "05:35:49 INFO - 2019 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Should be able to get index - expected PASS", + "linenumber": 8152 + }, + { + "line": "05:35:49 INFO - 2023 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Ordering is correct. - expected PASS", + "linenumber": 8156 + }, + { + "line": "05:35:49 INFO - 2024 INFO TEST-UNEXPECTED-FAIL | dom/indexedDB/test/test_transaction_lifetimes.html | Worker: uncaught exception [http://mochi.test:8888/tests/dom/indexedDB/test/unit/test_transaction_lifetimes.js:45]: ': InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable' - expected PASS", + "linenumber": 8157 + } + ], + "name": "'/tools/buildbot/bin/python scripts/scripts/desktop_unittest.py ...' warnings", + "started": "2015-04-15 05:25:12.731202", + "started_linenumber": 278, + "finished_linenumber": 9248, + "finished": "2015-04-15 05:36:51.808779", + "error_count": 4, + "duration": 699, + "order": 13, + "result": "testfailed" + }, + { + "errors": [ ], + "name": "set props: build_url blobber_files", + "started": "2015-04-15 05:36:51.812718", + "started_linenumber": 9250, + "finished_linenumber": 9280, + "finished": "2015-04-15 05:36:51.871786", + "error_count": 0, + "duration": 0, + "order": 14, + "result": "success" + }, + { + "errors": [ ], + "name": "'rm -f ...'", + "started": "2015-04-15 05:36:51.872124", + "started_linenumber": 9282, + "finished_linenumber": 9308, + "finished": "2015-04-15 05:36:51.927004", + "error_count": 0, + "duration": 0, + "order": 15, + "result": "success" + }, + { + "errors": [ ], + "name": "reboot skipped", + "started": "2015-04-15 05:36:51.927332", + "started_linenumber": 9310, + "finished_linenumber": 9311, + "finished": "2015-04-15 05:36:51.927750", + "error_count": 0, + "duration": 0, + "order": 16, + "result": "skipped" + } + ], + "errors_truncated": false + }, + "logurl": "http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2015/04/2015-04-15-03-02-06-mozilla-central/mozilla-central_snowleopard_test-mochitest-2-bm107-tests1-macosx-build128.txt.gz" + }, + "type": "json", + "id": 8217463, + "name": "text_log_summary", + "job_id": 1330578 +} \ No newline at end of file diff --git a/tests/sampledata.py b/tests/sampledata.py index 424c71e9ce5..5d00d39b23b 100644 --- a/tests/sampledata.py +++ b/tests/sampledata.py @@ -57,6 +57,10 @@ def __init__(self): os.path.dirname(__file__))) as f: self.job_artifact = f.readlines() + with open("{0}/sample_data/artifacts/text_log_summary.json".format( + os.path.dirname(__file__))) as f: + self.text_log_summary = json.load(f) + self.job_data = [] self.resultset_data = [] diff --git a/tests/webapp/api/test_artifact_api.py b/tests/webapp/api/test_artifact_api.py index 175dca6053a..cdff4e579b6 100644 --- a/tests/webapp/api/test_artifact_api.py +++ b/tests/webapp/api/test_artifact_api.py @@ -2,10 +2,17 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, you can obtain one at http://mozilla.org/MPL/2.0/. +import json import pytest + from django.core.urlresolvers import reverse + +import thclient + +from treeherder.etl.oauth_utils import OAuthCredentials from treeherder.model.derived import ArtifactsModel + xfail = pytest.mark.xfail @@ -13,7 +20,7 @@ def test_artifact_detail(webapp, test_project, eleven_jobs_processed, sample_artifacts, jm): """ - test retrieving a single job from the jobs-detail + test retrieving a single artifact from the artifact-detail endpoint. """ job = jm.get_job_list(0, 1)[0] @@ -68,3 +75,59 @@ def test_artifact_detail_bad_project(webapp, jm): assert resp.json == {"detail": "No project with name foo"} jm.disconnect() + + +def test_artifact_create_text_log_summary(webapp, eleven_jobs_processed, + mock_send_request, monkeypatch, + sample_data, jm): + """ + test creating a text_log_summary artifact which auto-generates bug suggestions + """ + bs_obj = ["foo", "bar"] + + from treeherder.model import bug_suggestions + + def _get_bug_suggestions(params): + return bs_obj + + monkeypatch.setattr(bug_suggestions, "get_bug_suggestions", _get_bug_suggestions) + + credentials = OAuthCredentials.get_credentials(jm.project) + + job = jm.get_job_list(0, 1)[0] + tls = sample_data.text_log_summary + + tac = thclient.TreeherderArtifactCollection() + ta = thclient.TreeherderArtifact({ + 'type': 'json', + 'name': 'text_log_summary', + 'blob': json.dumps(tls['blob']), + 'job_guid': job['job_guid'] + }) + tac.add(ta) + + req = thclient.TreeherderRequest( + protocol='http', + host='localhost', + project=jm.project, + oauth_key=credentials['consumer_key'], + oauth_secret=credentials['consumer_secret'] + ) + + # Post the request to treeherder + resp = req.post(tac) + assert resp.status_int == 200 + assert resp.body == '{"message": "Artifacts stored successfully"}' + + with ArtifactsModel(jm.project) as artifacts_model: + artifacts = artifacts_model.get_job_artifact_list(0, 10, conditions={ + 'job_id': {('=', job["id"])} + }) + + artifact_names = {x['name'] for x in artifacts} + act_bs_obj = [x['blob'] for x in artifacts if x['name'] == 'Bug suggestions'][0] + + assert set(artifact_names) == {'Bug suggestions', 'text_log_summary'} + assert bs_obj == act_bs_obj + + jm.disconnect()