def test_simple(self): _bot_event('first1', 'first', {'git': 1}, None) _bot_event('first2', 'first', {'build': 100000, 'git': 1000}, None) self.assertEqual(2, named_caches.cron_update_named_caches()) self.assertEqual(2, named_caches.NamedCache.query().count()) oses = ['Linux'] hints = named_caches.get_hints('first', oses, ['git', 'build', 'new']) self.assertEqual([1000, 100000, -1], hints)
def test_fuzzy_other_os(self): # Use the hint from 'Mac' (the larger one) even if requesting for Linux. _bot_event('first1', 'first', {'build': 50000}, ['Android']) _bot_event('first2', 'first', {'build': 100000}, ['Mac']) self.assertEqual(2, named_caches.cron_update_named_caches()) self.assertEqual(2, named_caches.NamedCache.query().count()) oses = ['Linux'] hints = named_caches.get_hints('first', oses, ['build']) self.assertEqual([100000], hints)
def test_p95(self): # Create 45 bots with cache 'foo' size between 1 and 45. for i in range(45): _bot_event('second%d' % i, 'second', {'foo': i + 1}, None) self.assertEqual(2, named_caches.cron_update_named_caches()) self.assertEqual(1, named_caches.NamedCache.query().count()) oses = ['Linux'] hints = named_caches.get_hints('second', oses, ['foo']) # Roughly p95. self.assertEqual([43], hints)
def _cmd_run(self, request, secret_bytes, run_result, bot_id, oses, bot_group_cfg): logging.info('Run: %s', request.task_id) props = request.task_slice(run_result.current_task_slice).properties caches = [c.to_dict() for c in props.caches] names = [c.name for c in props.caches] pool = props.dimensions['pool'][0] # Warning: this is doing a DB GET on the cold path, which will increase the # reap failure. for i, hint in enumerate(named_caches.get_hints(pool, oses, names)): caches[i]['hint'] = str(hint) out = { 'cmd': 'run', 'manifest': { 'bot_id': bot_id, 'bot_authenticated_as': auth.get_peer_identity().to_bytes(), 'caches': caches, 'cipd_input': { 'client_package': props.cipd_input.client_package.to_dict(), 'packages': [p.to_dict() for p in props.cipd_input.packages], 'server': props.cipd_input.server, } if props.cipd_input else None, 'command': props.command, 'containment': props.containment.to_dict() if props.containment else {}, 'dimensions': props.dimensions, 'env': props.env, 'env_prefixes': props.env_prefixes, 'extra_args': props.extra_args, 'grace_period': props.grace_period_secs, 'hard_timeout': props.execution_timeout_secs, 'host': utils.get_versioned_hosturl(), 'io_timeout': props.io_timeout_secs, 'secret_bytes': (secret_bytes.secret_bytes.encode('base64') if secret_bytes else None), 'isolated': { 'input': props.inputs_ref.isolated, 'namespace': props.inputs_ref.namespace, 'server': props.inputs_ref.isolatedserver, } if props.inputs_ref else None, 'outputs': props.outputs, 'relative_cwd': props.relative_cwd, 'service_accounts': { 'system': { # 'none', 'bot' or email. Bot interprets 'none' and 'bot' locally. # When it sees something else, it uses /oauth_token API endpoint to # grab tokens through server. 'service_account': bot_group_cfg.system_service_account or 'none', }, 'task': { # Same here. 'service_account': request.service_account, }, }, 'task_id': task_pack.pack_run_result_key(run_result.key), }, } self.send_response(utils.to_json_encodable(out))