blob: 5242d35f93e6c183f9005a6ab158a54a5c18c905 [file] [log] [blame]
Xinan Lin3ba18a02019-08-13 15:44:55 -07001# Copyright 2019 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Module for buildbucket unittests."""
6
7import mock
8import os
9import unittest
10
11import build_lib
12import buildbucket
13import task_executor
14
15from chromite.api.gen.test_platform import request_pb2
16from google.appengine.ext import testbed
17from google.protobuf import json_format
18
19
20ADDR = u'http://localhost:1'
21
22
Prathmesh Prabhu91ef1622019-08-30 14:07:42 -070023def _get_default_suite_params():
Xinan Lin3ba18a02019-08-13 15:44:55 -070024 return {
25 'suite': 'fake_suite',
26 'board': 'fake_board',
27 'model': 'fake_model',
28 build_lib.BuildVersionKey.CROS_VERSION: 'fake_cros_build',
29 build_lib.BuildVersionKey.FW_RW_VERSION: 'fake_firmware_rw_build',
30 build_lib.BuildVersionKey.FW_RO_VERSION: 'fake_firmware_ro_build',
31 build_lib.BuildVersionKey.ANDROID_BUILD_VERSION: 'fake_android_build',
32 build_lib.BuildVersionKey.TESTBED_BUILD_VERSION: 'fake_testbed_build',
33 'num': 1,
34 'pool': 'DUT_POOL_SUITES',
35 'priority': 10,
Xinan Lin6e097382019-08-27 18:43:35 -070036 'timeout': 12,
37 'timeout_mins': 4320,
38 'max_runtime_mins': 4320,
Xinan Lin3ba18a02019-08-13 15:44:55 -070039 'no_wait_for_results': True,
40 'test_source_build': 'fake_test_source_build',
41 'job_retry': False,
42 'no_delay': False,
43 'force': False,
44 'run_prod_code': True,
45 'is_skylab': False,
46 }
47
48
49class FakeTestPlatformClient(object):
50
51 def __init__(self, test):
52 self._test = test
53 self.called_with_requests = []
54
55 def ScheduleBuild(self, req, credentials=None):
56 self.called_with_requests.append(req)
57 # No test_platform_response proto. Simply return '200, ok'.
58 return '200 ok'
59
60
61class TestPlatformClientTestCase(unittest.TestCase):
62
63 def setUp(self):
64 super(TestPlatformClientTestCase, self).setUp()
65 self.fake_client = FakeTestPlatformClient(self)
66 patcher = mock.patch('buildbucket._get_client',
67 return_value=self._get_client(ADDR))
68 patcher.start()
69 self.client = buildbucket.TestPlatformClient(ADDR,
70 'foo-proj',
71 'foo-bucket',
72 'foo-builder')
73 self.addCleanup(patcher.stop)
74 self.testbed = testbed.Testbed()
75 self.testbed.activate()
76 self.addCleanup(self.testbed.deactivate)
77 self.testbed.init_taskqueue_stub(
78 root_path=os.path.join(os.path.dirname(__file__)))
79 self.taskqueue_stub = self.testbed.get_stub(
80 testbed.TASKQUEUE_SERVICE_NAME)
81
Xinan Lin3ba18a02019-08-13 15:44:55 -070082 def testFormTestPlatformRequestSuccessfully(self):
Prathmesh Prabhu91ef1622019-08-30 14:07:42 -070083 tp = _get_default_suite_params()
Prathmesh Prabhu6f8d2f92019-08-30 14:05:35 -070084 self.client.run(**self._marshal_to_tq_params(tp))
Prathmesh Prabhu9a8060a2019-08-30 14:13:23 -070085 self._assert_bb_client_called()
Prathmesh Prabhu6348ea82019-08-30 14:15:21 -070086 req = self._extract_request_from_bb_client()
Xinan Lin3ba18a02019-08-13 15:44:55 -070087 self.assertEqual(req.params.scheduling.managed_pool,
88 request_pb2.Request.Params.Scheduling.MANAGED_POOL_SUITES)
Xinan Lin6e097382019-08-27 18:43:35 -070089 self.assertEqual(req.params.time.maximum_duration.seconds, 165600)
Xinan Lin3ba18a02019-08-13 15:44:55 -070090 self.assertEqual(req.params.metadata.test_metadata_url,
Xinan Lin6e097382019-08-27 18:43:35 -070091 'gs://chromeos-image-archive/' + tp['test_source_build'])
Xinan Lin3ba18a02019-08-13 15:44:55 -070092 self.assertEqual(req.test_plan.suite[0].name, tp['suite'])
93
Alex Zamorzaevc1935602019-08-28 14:37:35 -070094 def testNonStandardPoolName(self):
Prathmesh Prabhu91ef1622019-08-30 14:07:42 -070095 tp = _get_default_suite_params()
Alex Zamorzaevc1935602019-08-28 14:37:35 -070096 tp['pool'] = 'cts'
Prathmesh Prabhu6f8d2f92019-08-30 14:05:35 -070097 self.client.run(**self._marshal_to_tq_params(tp))
Prathmesh Prabhu9a8060a2019-08-30 14:13:23 -070098 self._assert_bb_client_called()
Prathmesh Prabhu6348ea82019-08-30 14:15:21 -070099 req = self._extract_request_from_bb_client()
Alex Zamorzaevc1935602019-08-28 14:37:35 -0700100 self.assertEqual(req.params.scheduling.managed_pool,
101 request_pb2.Request.Params.Scheduling.MANAGED_POOL_CTS)
102
Xinan Lin3ba18a02019-08-13 15:44:55 -0700103 def testShouldGoUnmanagedPool(self):
Prathmesh Prabhu91ef1622019-08-30 14:07:42 -0700104 tp = _get_default_suite_params()
Xinan Lin3ba18a02019-08-13 15:44:55 -0700105 tp['pool'] = 'wifi'
Prathmesh Prabhu6f8d2f92019-08-30 14:05:35 -0700106 self.client.run(**self._marshal_to_tq_params(tp))
Prathmesh Prabhu9a8060a2019-08-30 14:13:23 -0700107 self._assert_bb_client_called()
Prathmesh Prabhu6348ea82019-08-30 14:15:21 -0700108 req = self._extract_request_from_bb_client()
Xinan Lin3ba18a02019-08-13 15:44:55 -0700109 self.assertEqual(req.params.scheduling.unmanaged_pool, tp['pool'])
110
111 def testShouldSchedulewithQuotaAccount(self):
Prathmesh Prabhu91ef1622019-08-30 14:07:42 -0700112 tp = _get_default_suite_params()
Xinan Lin3ba18a02019-08-13 15:44:55 -0700113 tp['override_qs_account'] = 'dummy@foo.com'
Prathmesh Prabhu6f8d2f92019-08-30 14:05:35 -0700114 self.client.run(**self._marshal_to_tq_params(tp))
Prathmesh Prabhu9a8060a2019-08-30 14:13:23 -0700115 self._assert_bb_client_called()
Prathmesh Prabhu6348ea82019-08-30 14:15:21 -0700116 req = self._extract_request_from_bb_client()
Xinan Lin3ba18a02019-08-13 15:44:55 -0700117 self.assertEqual(req.params.scheduling.quota_account,
118 tp['override_qs_account'])
119
120 def testNoFinalBuild(self):
Prathmesh Prabhu91ef1622019-08-30 14:07:42 -0700121 tp = _get_default_suite_params()
Xinan Lin3ba18a02019-08-13 15:44:55 -0700122 tp[build_lib.BuildVersionKey.CROS_VERSION] = None
123 tp[build_lib.BuildVersionKey.ANDROID_BUILD_VERSION] = None
124 tp[build_lib.BuildVersionKey.TESTBED_BUILD_VERSION] = None
Prathmesh Prabhu6f8d2f92019-08-30 14:05:35 -0700125 params = self._marshal_to_tq_params(tp)
Xinan Lin3ba18a02019-08-13 15:44:55 -0700126 self.assertRaises(buildbucket.BuildbucketRunError,
127 self.client.run, **params)
Prathmesh Prabhu9a8060a2019-08-30 14:13:23 -0700128 self._assert_bb_client_not_called()
Xinan Lin3ba18a02019-08-13 15:44:55 -0700129
Prathmesh Prabhu6f8d2f92019-08-30 14:05:35 -0700130 def _marshal_to_tq_params(self, suite_params):
131 """Marshal given suite parameters to a format returned from taskqueue.
132
133 buildbucket.TestPlatformClient.run() expects arguments pulled from a
134 taskqueue. This helper function marshals suite parameters into the format
135 they would be in when pulled from a taskqueue.
136 """
137 task_executor.push(task_executor.SUITES_QUEUE, **suite_params)
138 tasks = self.taskqueue_stub.get_filtered_tasks()
139 return tasks[0].extract_params()
Xinan Lin3ba18a02019-08-13 15:44:55 -0700140
Prathmesh Prabhu73801e12019-08-30 14:09:31 -0700141 def _get_client(self, addr):
142 self.assertEqual(ADDR, addr)
143 return self.fake_client
144
Prathmesh Prabhu9a8060a2019-08-30 14:13:23 -0700145 def _assert_bb_client_called(self):
146 self.assertEqual(len(self.fake_client.called_with_requests), 1)
147
148 def _assert_bb_client_not_called(self):
149 self.assertEqual(len(self.fake_client.called_with_requests), 0)
150
Prathmesh Prabhu6348ea82019-08-30 14:15:21 -0700151 def _extract_request_from_bb_client(self):
152 return _struct_pb2_to_request_pb2(
153 self.fake_client.called_with_requests[0].properties['request'])
154
Prathmesh Prabhu9a8060a2019-08-30 14:13:23 -0700155
Xinan Lin3ba18a02019-08-13 15:44:55 -0700156def _struct_pb2_to_request_pb2(struct_pb2):
157 """Transform google struct proto to test_platform_request.
158
159 Args:
160 struct_pb2: A struct_pb2 instance.
161
162 Returns:
163 A request_pb2 instance.
164 """
165 json = json_format.MessageToJson(struct_pb2)
166 return json_format.Parse(json, request_pb2.Request())