Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3173)

Unified Diff: appengine/swarming/local_smoke_test.py

Issue 2911193003: Expose named caches as dimensions. (Closed)
Patch Set: Fixed smoke test Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | appengine/swarming/swarming_bot/api/os_utilities.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/swarming/local_smoke_test.py
diff --git a/appengine/swarming/local_smoke_test.py b/appengine/swarming/local_smoke_test.py
index 9d61a16dfa32faaaa2ff99a5ae57243fc2c31904..7d17f50abea607b7790d9e2790a012b2c40b3b66 100755
--- a/appengine/swarming/local_smoke_test.py
+++ b/appengine/swarming/local_smoke_test.py
@@ -19,6 +19,7 @@ import socket
import sys
import tempfile
import textwrap
+import time
import unittest
import urllib
@@ -208,6 +209,14 @@ class SwarmingClient(object):
file_path.rmtree(self._tmpdir)
self._tmpdir = None
+ def query_bot(self):
+ """Returns the bot's properties."""
+ data = json.loads(self._capture('query', ['bots/list', '--limit', '10']))
+ if not data.get('items'):
+ return None
+ assert len(data['items']) == 1
+ return data['items'][0]
+
def dump_log(self):
print >> sys.stderr, '-' * 60
print >> sys.stderr, 'Client calls'
@@ -241,6 +250,13 @@ class SwarmingClient(object):
p.communicate()
return p.returncode
+ def _capture(self, command, args):
+ cmd = [
+ sys.executable, 'swarming.py', command, '-S', self._swarming_server,
+ ] + args
+ p = subprocess42.Popen(cmd, stdout=subprocess42.PIPE, cwd=CLIENT_DIR)
+ return p.communicate()[0]
+
def gen_expected(**kwargs):
expected = {
@@ -280,20 +296,41 @@ def gen_expected(**kwargs):
class Test(unittest.TestCase):
maxDiff = None
client = None
- dimensions = None
servers = None
bot = None
- @classmethod
- def setUpClass(cls):
- cls.dimensions = os_utilities.get_dimensions()
-
def setUp(self):
super(Test, self).setUp()
- # Reset the bot's cache at the start of each task, so that the cache reuse
- # data becomes deterministic.
- # Main caveat is 'isolated_upload' as the isolate server is not cleared.
- self.bot.wipe_cache()
+ self.dimensions = os_utilities.get_dimensions()
+ # Reset the bot's isolated cache at the start of each task, so that the
+ # cache reuse data becomes deterministic. Only restart the bot when it had a
+ # named cache because it takes multiple seconds to to restart the bot. :(
+ #
+ # TODO(maruel): 'isolated_upload' is not deterministic because the isolate
+ # server not cleared.
+ old = self.client.query_bot()
+ started_ts = json.loads(old['state'])['started_ts'] if old else None
+ logging.info('setUp: started_ts was %s', started_ts)
+ had_cache = any(
+ u'caches' == i['key'] for i in old['dimensions']) if old else False
+ self.bot.wipe_cache(had_cache)
+ # The bot restarts due to wipe_cache() so wait for the bot to come back
+ # online. It may takes a few loop.
+ while True:
+ state = self.client.query_bot()
+ if not state:
+ time.sleep(0.1)
+ continue
+ if not had_cache:
+ break
+ new_started_ts = json.loads(state['state'])['started_ts']
+ logging.info('setUp: new_started_ts is %s', new_started_ts)
+ # This assumes that starting the bot and running the previous test case
+ # took more than 1s.
+ if not started_ts or new_started_ts != started_ts:
+ dimensions = {i['key']: i['value'] for i in state['dimensions']}
+ self.assertNotIn(u'caches', dimensions)
+ break
def gen_expected(self, **kwargs):
return gen_expected(bot_dimensions=self.dimensions, **kwargs)
@@ -636,6 +673,10 @@ class Test(unittest.TestCase):
def test_local_cache(self):
# First task creates the cache, second copy the content to the output
# directory. Each time it's the exact same script.
+ dimensions = {
+ i['key']: i['value'] for i in self.client.query_bot()['dimensions']}
+ self.assertEqual(set(self.dimensions), set(dimensions))
+ self.assertNotIn(u'cache', set(dimensions))
script = '\n'.join((
'import os, shutil, sys',
'p = "p/b/a.txt"',
@@ -692,12 +733,23 @@ class Test(unittest.TestCase):
},
},
)
+ # The previous task caused the bot to have a named cache.
+ expected_summary['bot_dimensions'] = (
+ expected_summary['bot_dimensions'].copy())
+ expected_summary['bot_dimensions'][u'caches'] = [u'fuu']
self._run_isolated(
script, 'cache_second',
['--named-cache', 'fuu', 'p/b', '--', '${ISOLATED_OUTDIR}/yo'],
expected_summary,
{'0/yo': 'Yo!'})
+ # Check that the bot now has a cache dimension by independently querying.
+ expected = set(self.dimensions)
+ expected.add(u'caches')
+ dimensions = {
+ i['key']: i['value'] for i in self.client.query_bot()['dimensions']}
+ self.assertEqual(expected, set(dimensions))
+
def _run_isolated(self, hello_world, name, args, expected_summary,
expected_files, deduped=False, isolated_content=None):
"""Runs hello_world.py as an isolated file."""
@@ -817,6 +869,8 @@ def main():
verbose = '-v' in sys.argv
leak = bool('--leak' in sys.argv)
if leak:
+ # Note that --leak will not guarantee that 'c' and 'isolated_cache' are
+ # kept. Only the last test case will leak these two directories.
sys.argv.remove('--leak')
if verbose:
logging.basicConfig(level=logging.INFO)
« no previous file with comments | « no previous file | appengine/swarming/swarming_bot/api/os_utilities.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698