# -*- encoding: UTF8 -*- # Test harness for SwarmReviewTemplate.py from __future__ import print_function import sys import unittest import os from p4testutils import TestCase, P4Server, localDirectory, create_file, append_to_file parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parent_dir) from SwarmReviewTemplate import SwarmReviewTemplate os.environ["LOGS"] = "." LOGGER_NAME = "TestSwarmReviewTemplate" LOG_FILE = "log-SwarmReviewTemplate.log" python3 = sys.version_info[0] >= 3 if python3: from unittest.mock import patch, Mock else: from mock import patch, Mock class TestSwarmReviewTemplate(TestCase): def __init__(self, methodName='runTest'): super(TestSwarmReviewTemplate, self).__init__(LOGGER_NAME, LOG_FILE, methodName=methodName) def setUp(self): pass def tearDown(self): pass def testHasRequiredReviewers(self): """Make sure can parse json appropriately""" trig = SwarmReviewTemplate('1234') review = {u'updated': 1524722029, u'description': u'VWMEB-1864/HeKa: some desc', u'author': u'uid04885', u'commits': [], u'created': 1524722029, u'deployDetails': [], u'state': u'needsReview', u'comments': [0, 0], u'testDetails': [], u'testStatus': None, u'commitStatus': [], u'participants': {u'uid03351': [], u'uid04885': [], u'uidl9595': [], u'uid94250': {u'required': True}}} self.assertTrue(trig.has_required_reviewers(review)) review = {u'updated': 1524722029, u'description': u'VWMEB-1864/HeKa: some desc', u'author': u'uid04885', u'commits': [], u'created': 1524722029, u'deployDetails': [], u'state': u'needsReview', u'comments': [0, 0], u'testDetails': [], u'testStatus': None, u'commitStatus': [], u'participants': {u'uid03351': [], u'uid04885': [], u'uidl9595': [], u'uid94250': []}} self.assertFalse(trig.has_required_reviewers(review)) @patch('SwarmReviewTemplate.requests') def testSwarmReviewTemplate(self, requests_mock): """trigger fires and sends expected info to Swarm""" self.server = P4Server() config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "~test_config.yaml") p4 = self.server.p4 p4.logger = self.logger orig_user = p4.user inside = localDirectory(self.server.client_root, "inside") outside = localDirectory(self.server.client_root, "outside") inside_file1 = os.path.join(inside, "inside_file1") outside_file1 = os.path.join(outside, "outside_file1") create_file(inside_file1, 'Test content') create_file(outside_file1, 'Test content') with open(config_path, "w") as f: f.write(""" api: "api/v6" user: swarmtest swarm_user: swarm ticket: A123453 review_description: - "Please review me!" - "Don't forget to check YYYY" projects: - name: ProjectA post_submit_create_review: n pre_submit_require_review: y depot_paths: - //depot/inside/... """) get_call_count = 0 patch_call_count = 0 # Create a change and shelve for review # Then as user swarm we create a review shelved change - duplicating swarm actions # Then run trigger and see that it performs correct API calls to Swarm p4.run('add', outside_file1) chg = p4.fetch_change() chg['Description'] = "test change" p4.save_change(chg) p4.run_shelve('-c', '1') p4.run_revert('//...') p4.user = 'swarm' p4.run('add', outside_file1) chg = p4.fetch_change() chg['Description'] = "test change" p4.save_change(chg) p4.run_shelve('-c', '2') p4.run_revert('//...') trig_args = ["-p", p4.port, "-u", p4.user, "-c", config_path, "-L", "p4triggers.log", "--test-mode", "1"] # For non Swarm user change should be ignored trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) # Hasn't been called self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) # For swarm user but outside any project change is ignored trig_args[-1] = "2" trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) # Hasn't been called self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) #---------------------------------------- # For a path config file defines as inside, Swarm should be called p4.user = orig_user p4.run('add', inside_file1) chg = p4.fetch_change() chg['Description'] = "test change2" p4.save_change(chg) p4.run_shelve('-c', '3') p4.run_revert('//...') p4.user = 'swarm' p4.run('add', inside_file1) chg = p4.fetch_change() chg['Description'] = "test change2" p4.save_change(chg) p4.run_shelve('-c', '4') p4.run_revert('//...') trig_args[-1] = "4" mock_get_response = Mock() mock_get_response.json.return_value = {"lastSeen": 843, "reviews": [{"author": "perforce", "changes": [3], "comments": [0, 0], "commits": [], "description": "my change\n", "groups": ["longlived"], "id": 4, "participants": {"perforce": [], "super": []}, "pending": False, "projects": [], "state": "needsReview", "stateLabel": "Needs Review", "testDetails": [], "testStatus": None, "type": "default", "updateDate": "2017-11-09T15:16:55+00:00", "updated": 1510240615}], "totalCount": 1} # Assign our mock response as the result of our patched function requests_mock.get.return_value = mock_get_response trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) get_call_count += 1 # Expect an update patch_call_count += 1 self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) args, kwargs = requests_mock.patch.call_args_list[patch_call_count - 1] self.assertEqual(('http://swarm.dev/api/v6/reviews/4',), args) self.assertDictEqual({'auth': ('swarmtest', 'A123453'), 'data': [('description', "Please review me!\nDon't forget to check YYYY")]}, kwargs) #---------------------------------------- # Check formatting with a job associated with open(config_path, "w") as f: f.write(""" api: "api/v6" user: swarmtest swarm_user: swarm ticket: A123453 review_description: - "$jobDescription" - "$changeDescription" - "Please review me!" - "Don't forget to check YYYY" projects: - name: ProjectA post_submit_create_review: n pre_submit_require_review: y depot_paths: - //depot/inside/... """) job = p4.fetch_job() job['Description'] = 'test job' p4.save_job(job) p4.run('fix', '-c', '4', 'job000001') trig_args[-1] = "4" trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) get_call_count += 1 # Expect an update patch_call_count += 1 self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) args, kwargs = requests_mock.patch.call_args_list[patch_call_count - 1] self.assertEqual(('http://swarm.dev/api/v6/reviews/4',), args) self.assertDictEqual({'auth': ('swarmtest', 'A123453'), 'data': [('description', "test job\ntest change2\nPlease review me!\nDon't forget to check YYYY")]}, kwargs) #---------------------------------------- # Check formatting when 'swarm_review_template' only is set to 'y' with open(config_path, "w") as f: f.write(""" api: "api/v6" user: swarmtest swarm_user: swarm ticket: A123453 review_description: - "$jobDescription" - "$changeDescription" - "Please review me!" - "Don't forget to check YYYY" projects: - name: ProjectA post_submit_create_review: n pre_submit_require_review: n swarm_review_template: y depot_paths: - //depot/inside/... """) trig_args[-1] = "4" trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) get_call_count += 1 # Expect an update patch_call_count += 1 self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) args, kwargs = requests_mock.patch.call_args_list[patch_call_count - 1] self.assertEqual(('http://swarm.dev/api/v6/reviews/4',), args) self.assertDictEqual({'auth': ('swarmtest', 'A123453'), 'data': [('description', "test job\ntest change2\nPlease review me!\nDon't forget to check YYYY")]}, kwargs) # -------------------------------------- # Handle no reviews found mock_get_response = Mock() mock_get_response.json.return_value = {"lastSeen": None, "reviews": [], "totalCount": 0} requests_mock.get.return_value = mock_get_response trig_args[-1] = "4" trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) get_call_count += 1 self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) args, kwargs = requests_mock.patch.call_args_list[patch_call_count - 1] self.assertEqual(('http://swarm.dev/api/v6/reviews/4',), args) # --------------- # Handle required reviewers being reset mock_get_response.json.return_value = {"lastSeen": 843, "reviews": [{"author": "perforce", "changes": [3], "comments": [0, 0], "commits": [], "description": "my change\n", "groups": ["longlived"], "id": 4, "participants": {"perforce": {'required': True}, "super": []}, "pending": False, "projects": [], "state": "needsReview", "stateLabel": "Needs Review", "testDetails": [], "testStatus": None, "type": "default", "updateDate": "2017-11-09T15:16:55+00:00", "updated": 1510240615}], "totalCount": 1} trig_args[-1] = "4" trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) get_call_count += 1 # Expect an update patch_call_count += 2 self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) args, kwargs = requests_mock.patch.call_args_list[patch_call_count - 1] self.assertEqual(('http://swarm.dev/api/v6/reviews/4',), args) self.assertDictEqual({'auth': ('swarmtest', 'A123453'), 'data': [('description', "test job\ntest change2\nPlease review me!\nDon't forget to check YYYY")]}, kwargs) args, kwargs = requests_mock.patch.call_args_list[patch_call_count - 2] self.assertEqual(('http://swarm.dev/api/v6/reviews/4',), args) self.assertDictEqual({'auth': ('swarmtest', 'A123453'), 'json': {'requiredReviewers': []}}, kwargs) # --------------- # Handle multiple changes being specified, with the first change no longer present p4.run_shelve("-d", "-c", "2", "//...") p4.run_change("-d", "2") mock_get_response.json.return_value = {"lastSeen": 843, "reviews": [{"author": "perforce", "changes": [2, 3], "comments": [0, 0], "commits": [], "description": "my change\n", "groups": ["longlived"], "id": 4, "participants": {"perforce": {'required': True}, "super": []}, "pending": False, "projects": [], "state": "needsReview", "stateLabel": "Needs Review", "testDetails": [], "testStatus": None, "type": "default", "updateDate": "2017-11-09T15:16:55+00:00", "updated": 1510240615}], "totalCount": 1} trig_args[-1] = "4" trig = SwarmReviewTemplate(*trig_args) result = trig.run() self.assertEqual(0, result) get_call_count += 1 # Expect an update patch_call_count += 1 self.assertEqual(get_call_count, requests_mock.get.call_count) self.assertEqual(patch_call_count, requests_mock.patch.call_count) args, kwargs = requests_mock.patch.call_args_list[patch_call_count - 1] self.assertEqual(('http://swarm.dev/api/v6/reviews/4',), args) self.assertDictEqual({'auth': ('swarmtest', 'A123453'), 'json': {'requiredReviewers': []}}, kwargs) if __name__ == '__main__': unittest.main()