paygen: Re-enable generation of NMO update test payloads.
This CL adds more cataloging of NMO/previous builds during
the build discovery phase of paygen.
This information is used to better control which test payloads
we generate.
This CL removes any usage of '_previous_versions' in paygen and allows
for all discovered 'previous' builds to have update test payloads
generated.
BUG=chromium:541417
TEST=Unittests.
Reviewed-on: https://chromium-review.googlesource.com/305332
Commit-Ready: Matthew Sartori <msartori@chromium.org>
Tested-by: Matthew Sartori <msartori@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
(cherry picked from commit 3ecd1eb51da8cf67bc987b90b1d8df0f8f40334f)
Change-Id: Ie927de458dde6cebda6eb03051d2f85b4e8d2286
Reviewed-on: https://chromium-review.googlesource.com/309569
Reviewed-by: Josafat Garcia <josafat@chromium.org>
Tested-by: Matthew Sartori <msartori@chromium.org>
diff --git a/lib/paygen/paygen_build_lib.py b/lib/paygen/paygen_build_lib.py
index 290ef7a..b9d383e 100644
--- a/lib/paygen/paygen_build_lib.py
+++ b/lib/paygen/paygen_build_lib.py
@@ -306,6 +306,25 @@
return [p for p in self.payloads
if set(p['labels']).issuperset(labels)]
+ def GetOnly(self, labels):
+ """Retrieve all payloads with label sets that are equal to |labels|.
+
+ Args:
+ labels: A list of strings.
+
+ Returns:
+ A list of gspath.Payload objects with label sets equal to |labels|.
+
+ Raises:
+ ValueError if |labels| is not a list.
+ """
+ if not isinstance(labels, list):
+ raise ValueError('PayloadManager.GetOnly expects a list of labels.'
+ ' Given %s' % type(labels))
+
+ labels = set(labels)
+ return [p for p in self.payloads if set(p['labels']) == labels]
+
class _PaygenBuild(object):
"""This class is responsible for generating the payloads for a given build.
@@ -395,7 +414,6 @@
self._skip_nontest_payloads = skip_nontest_payloads
self._control_dir = control_dir
self._output_dir = output_dir
- self._previous_version = None
self._run_parallel = run_parallel
self._run_on_builder = run_on_builder
self._archive_board = None
@@ -872,13 +890,19 @@
_LogList('Images found', images)
- # Discover active FSI builds. We need these for generating deltas.
+ # Discover and filter active FSI builds.
fsi_builds = self._DiscoverFsiBuildsForDeltas()
if fsi_builds:
_LogList('Active FSI builds considered', fsi_builds)
else:
logging.info('No active FSI builds found')
+ for fsi in fsi_builds:
+ fsi_images += self._DiscoverImages(fsi)
+ fsi_images += self._DiscoverTestImageArchives(fsi)
+
+ fsi_images = _FilterForBasic(fsi_images) + _FilterForTest(fsi_images)
+
# Discover previous, non-FSI, builds that we also must generate deltas for.
previous_builds = [b for b in self._DiscoverNmoBuild()
if b not in fsi_builds]
@@ -887,13 +911,6 @@
else:
logging.info('No other previous builds found')
- # Discover and filter FSI images.
- for fsi in fsi_builds:
- fsi_images += self._DiscoverImages(fsi)
- fsi_images += self._DiscoverTestImageArchives(fsi)
-
- fsi_images = _FilterForBasic(fsi_images) + _FilterForTest(fsi_images)
-
# Discover and filter previous images.
for p in previous_builds:
try:
@@ -904,14 +921,6 @@
# TODO(mtennant): Remove this when bug is fixed properly.
logging.warning('Previous build image is missing, skipping: %s', e)
- # We also clear the previous version field so that subsequent code does
- # not attempt to generate a full update test from the N-1 version;
- # since this version has missing images, no payloads were generated for
- # it and test generation is bound to fail.
- # TODO(garnold) This should be reversed together with the rest of this
- # block.
- self._previous_version = None
-
# In this case, we should also skip test image discovery; since no
# signed deltas will be generated from this build, we don't need to
# generate test deltas from it.
@@ -921,13 +930,21 @@
previous_images = (
_FilterForBasic(previous_images) + _FilterForTest(previous_images))
- # Discover full payloads for all non-test images in the current build.
+ # Discover and catalogue full, non-test payloads.
skip_full = self._skip_full_payloads or self._skip_nontest_payloads
+
+ # Full payloads for the current build.
payload_manager.Add(
['full'],
self._DiscoverRequiredFullPayloads(_FilterForImages(images)),
skip=skip_full)
+ # Full payloads for previous builds.
+ payload_manager.Add(
+ ['full', 'previous'],
+ self._DiscoverRequiredFullPayloads(_FilterForImages(previous_images)),
+ skip=skip_full)
+
# Discover delta payloads.
skip_deltas = self._skip_delta_payloads or self._skip_nontest_payloads
@@ -983,6 +1000,12 @@
self._DiscoverRequiredFullPayloads(_FilterForTest(images)),
skip=skip_test_full)
+ # Full previous payloads.
+ payload_manager.Add(
+ ['test', 'full', 'previous'],
+ self._DiscoverRequiredFullPayloads(_FilterForTest(previous_images)),
+ skip=skip_test_full)
+
# Deltas for current -> NPO (test payloads).
payload_manager.Add(
['test', 'delta', 'npo'],
@@ -1311,59 +1334,55 @@
"""
payload_tests = []
- for p in payload_manager.Get([]):
- # We are only testing test payloads.
- if not 'test' in p.labels:
- continue
+ # Pre-fetch lab stable FSIs.
+ lab_stable_fsi_deltas = self._DiscoverAllFsiBuildsForDeltaTesting()
+ lab_stable_fsi_full = self._DiscoverAllFsiBuildsForFullTesting()
- # Distinguish between delta and full payloads.
- if not 'delta' in p.labels:
- # Create a full update test from NMO, if we are newer.
- if not self._previous_version:
- logging.warning('No previous build, not testing full update %s from '
- 'NMO', p)
- elif gspaths.VersionGreater(
- self._previous_version, p.tgt_image.version):
+ def IsFsiLabStable(fsi_image):
+ for build in lab_stable_fsi_deltas:
+ if all([fsi_image.board == build.board,
+ fsi_image.channel == build.channel,
+ fsi_image.version == build.version,
+ fsi_image.bucket == build.bucket]):
+ return True
+ return False
+
+ # Create full update tests that involve the current build.
+ for p in payload_manager.GetOnly(['test', 'full']):
+
+ # Update tests from previous to current, if we are newer.
+ for p_prev in payload_manager.GetOnly(['test', 'full', 'previous']):
+ if gspaths.VersionGreater(p_prev.tgt_image.version,
+ p.tgt_image.version):
logging.warning(
'NMO (%s) is newer than target (%s), skipping NMO full '
- 'update test.', self._previous_version, p)
- else:
- payload_tests.append(self.PayloadTest(
- p, src_channel=self._build.channel,
- src_version=self._previous_version))
+ 'update test.', p_prev, p)
+ continue
- # Create a full update test from the current version to itself.
payload_tests.append(self.PayloadTest(
p,
- src_channel=self._build.channel,
- src_version=self._build.version))
+ src_channel=p_prev.tgt_image.channel,
+ src_version=p_prev.tgt_image.version))
- # Create a full update test from oldest viable FSI.
- payload_tests += self._CreateFsiPayloadTests(
- p, self._DiscoverAllFsiBuildsForFullTesting())
- else:
- # Create a delta update test.
+ # Update test from current version to itself.
+ payload_tests.append(self.PayloadTest(
+ p,
+ src_channel=self._build.channel,
+ src_version=self._build.version))
- # FSI deltas are included only if they are lab stable.
- if 'fsi' in p.labels:
- fsi_image = p.src_image
- is_lab_stable = False
+ # Update test from the oldest viable FSI.
+ payload_tests += self._CreateFsiPayloadTests(p, lab_stable_fsi_full)
- for build in self._DiscoverAllFsiBuildsForDeltaTesting():
- if all([fsi_image.board == build.board,
- fsi_image.channel == build.channel,
- fsi_image.version == build.version,
- fsi_image.bucket == build.bucket]):
- is_lab_stable = True
- break
+ # Create delta payload tests.
+ for p in payload_manager.Get(['test', 'delta']):
+ # FSI deltas are included only if they are known to be lab stable.
+ if 'fsi' in p.labels and not IsFsiLabStable(p.src_image):
+ logging.warning(
+ 'FSI delta payload (%s) is not lab stable, skipping '
+ 'delta update test', p)
+ continue
- if not is_lab_stable:
- logging.warning(
- 'FSI delta payload (%s) is not lab stable, skipping '
- 'delta update test', p)
- continue
-
- payload_tests.append(self.PayloadTest(p))
+ payload_tests.append(self.PayloadTest(p))
return payload_tests
diff --git a/lib/paygen/paygen_build_lib_unittest.py b/lib/paygen/paygen_build_lib_unittest.py
index 85c8e16..f828e14 100644
--- a/lib/paygen/paygen_build_lib_unittest.py
+++ b/lib/paygen/paygen_build_lib_unittest.py
@@ -74,6 +74,18 @@
self.assertEquals([p1, p2], pm.Get(['test']))
self.assertEquals([], pm.Get(['foo', 'bar']))
+ def testGetOnly(self):
+ """Test retrieving payloads from the manager."""
+ pm = paygen_build_lib.PayloadManager()
+
+ p1 = gspaths.Payload(tgt_image='bar', labels=['bar', 'test'])
+ p2 = gspaths.Payload(tgt_image='bar', labels=['bar', 'test', 'test2'])
+
+ pm.payloads = [p1, p2]
+
+ self.assertEquals([p1, p2], pm.Get(['bar', 'test']))
+ self.assertEquals([p1], pm.GetOnly(['bar', 'test']))
+
class BasePaygenBuildLibTest(cros_test_lib.MoxTempDirTestCase):
"""Base class for testing PaygenBuildLib class."""
@@ -690,6 +702,8 @@
# Run the test verification.
self.mox.ReplayAll()
+ self.maxDiff = None
+
payload_manager = paygen._DiscoverRequiredPayloads()
expected = [gspaths.Payload(tgt_image=self.basic_image, uri=output_uri,
@@ -700,6 +714,11 @@
labels=['full']),
gspaths.Payload(tgt_image=self.premp_npo_image, uri=output_uri,
labels=['full']),
+
+ gspaths.Payload(tgt_image=nmo_images[0], uri=output_uri,
+ labels=['full', 'previous']),
+ gspaths.Payload(tgt_image=nmo_images[1], uri=output_uri,
+ labels=['full', 'previous']),
# NPO Deltas
gspaths.Payload(tgt_image=self.npo_image,
src_image=self.basic_image,
@@ -740,6 +759,9 @@
gspaths.Payload(tgt_image=self.test_image,
uri=output_uri,
labels=['test', 'full']),
+ gspaths.Payload(tgt_image=nmo_test_image,
+ uri=output_uri,
+ labels=['test', 'full', 'previous']),
# Test NPO delta.
gspaths.Payload(tgt_image=self.test_image,
@@ -1353,6 +1375,7 @@
def setupCreatePayloadTests(self):
paygen = self._GetPaygenBuildInstance()
+ self.mox.StubOutWithMock(paygen, '_DiscoverAllFsiBuildsForDeltaTesting')
self.mox.StubOutWithMock(paygen, '_DiscoverAllFsiBuildsForFullTesting')
self.mox.StubOutWithMock(paygen, '_FindFullTestPayloads')
@@ -1366,6 +1389,9 @@
paygen = self.setupCreatePayloadTests()
+ paygen._DiscoverAllFsiBuildsForDeltaTesting().AndReturn([])
+ paygen._DiscoverAllFsiBuildsForFullTesting().AndReturn([])
+
# Run the test verification.
self.mox.ReplayAll()
@@ -1380,12 +1406,13 @@
]
payload_manager = paygen_build_lib.PayloadManager()
- payload_manager.Add(['test'], [payloads[0]])
+ payload_manager.Add(['test', 'full'], [payloads[0]])
payload_manager.Add(['test', 'delta'], [payloads[1]])
paygen = self.setupCreatePayloadTests()
# We search for FSIs once for each full payload.
+ paygen._DiscoverAllFsiBuildsForDeltaTesting().AndReturn(['0.9.9', '1.0.0'])
paygen._DiscoverAllFsiBuildsForFullTesting().AndReturn(['0.9.9', '1.0.0'])
paygen._FindFullTestPayloads('stable-channel', '0.9.9').AndReturn(False)
paygen._FindFullTestPayloads('stable-channel', '1.0.0').AndReturn(True)
@@ -1396,7 +1423,7 @@
self.maxDiff = None
labelled_payloads = [
- gspaths.Payload(tgt_image=self.test_image, labels=['test']),
+ gspaths.Payload(tgt_image=self.test_image, labels=['test', 'full']),
gspaths.Payload(tgt_image=self.prev_image, src_image=self.test_image,
labels=['test', 'delta'])
]
@@ -1422,9 +1449,8 @@
paygen = self.setupCreatePayloadTests()
- self.mox.StubOutWithMock(paygen, '_DiscoverAllFsiBuildsForDeltaTesting')
-
paygen._DiscoverAllFsiBuildsForDeltaTesting().AndReturn([self.foo_build])
+ paygen._DiscoverAllFsiBuildsForFullTesting().AndReturn([])
self.mox.ReplayAll()
@@ -1445,12 +1471,11 @@
paygen = self.setupCreatePayloadTests()
- self.mox.StubOutWithMock(paygen, '_DiscoverAllFsiBuildsForDeltaTesting')
-
paygen._DiscoverAllFsiBuildsForDeltaTesting().AndReturn(
[gspaths.Build(bucket='crt', channel='not-foo-channel',
board='foo-board', version='1.2.3')]
)
+ paygen._DiscoverAllFsiBuildsForFullTesting().AndReturn([])
self.mox.ReplayAll()
@@ -1955,7 +1980,6 @@
version='1.1.0')
nmo_images = self._GetBuildImages(nmo_build)
- nmo_test_image = self._GetBuildTestImage(nmo_build)
fsi1_images = self._GetBuildImages(fsi1_build)
fsi1_test_image = self._GetBuildTestImage(fsi1_build)
fsi2_images = self._GetBuildImages(fsi2_build)
@@ -1964,13 +1988,13 @@
paygen._DiscoverImages(paygen._build).AndReturn(self.images)
paygen._DiscoverTestImageArchives(paygen._build).AndReturn([])
paygen._DiscoverFsiBuildsForDeltas().AndReturn([fsi1_build, fsi2_build])
- paygen._DiscoverNmoBuild().AndReturn([nmo_build])
paygen._DiscoverImages(fsi1_build).AndReturn(fsi1_images)
paygen._DiscoverTestImageArchives(fsi1_build).AndReturn([fsi1_test_image])
paygen._DiscoverImages(fsi2_build).AndReturn(fsi2_images)
paygen._DiscoverTestImageArchives(fsi2_build).AndReturn([fsi2_test_image])
+ paygen._DiscoverNmoBuild().AndReturn([nmo_build])
paygen._DiscoverImages(nmo_build).AndReturn(nmo_images)
- paygen._DiscoverTestImageArchives(nmo_build).AndReturn([nmo_test_image])
+ paygen._DiscoverTestImageArchives(nmo_build).AndReturn([])
# Simplify the output URIs, so it's easy to check them below.
paygen_payload_lib.DefaultPayloadUri(
@@ -1979,6 +2003,8 @@
# Run the test verification.
self.mox.ReplayAll()
+ self.maxDiff = None
+
payload_manager = paygen._DiscoverRequiredPayloads()
expected = [
@@ -1990,6 +2016,11 @@
labels=['full']),
gspaths.Payload(tgt_image=self.premp_npo_image, uri=output_uri,
labels=['full']),
+
+ gspaths.Payload(tgt_image=nmo_images[0], uri=output_uri,
+ labels=['full', 'previous']),
+ gspaths.Payload(tgt_image=nmo_images[1], uri=output_uri,
+ labels=['full', 'previous']),
# No NPO Deltas because the basic images have different image types.
# NMO deltas.