Example #1
0
 def test_forked_paths(self):
     # We have a fork in the road.  There is a full update, but two deltas
     # with different versions point to the same base.  This will give us
     # two upgrade paths, both of which include the full.
     index = get_index('candidates.index_07.json')
     candidates = get_candidates(index, 1200)
     self.assertEqual(len(candidates), 2)
     # We can sort the paths by length.
     paths = sorted(candidates, key=len)
     # The shortest path gets us to 1302 in two steps.
     self.assertEqual(len(paths[0]), 2)
     self.assertEqual([image.version for image in paths[0]], [1300, 1302])
     descriptions = []
     for image in paths[0]:
         # There's only one description per image so order doesn't matter.
         descriptions.extend(image.descriptions.values())
     self.assertEqual(descriptions, ['Full 1', 'Delta 2'])
     # The longer path gets us to 1302 in three steps.
     self.assertEqual(len(paths[1]), 3)
     self.assertEqual([image.version for image in paths[1]],
                      [1300, 1301, 1302])
     descriptions = []
     for image in paths[1]:
         # There's only one description per image so order doesn't matter.
         descriptions.extend(image.descriptions.values())
     self.assertEqual(descriptions, ['Full 1', 'Delta 1', 'Delta 3'])
Example #2
0
 def test_candidates(self):
     # Path B will win; it has one full and two deltas.
     index = get_index('candidates.index_13.json')
     candidates = get_candidates(index, 0)
     self.assertEqual(len(candidates), 3)
     path0 = candidates[0]
     self.assertEqual(descriptions(path0),
                      ['Full A', 'Delta A.1', 'Delta A.2'])
     path1 = candidates[1]
     self.assertEqual(descriptions(path1),
                      ['Full B', 'Delta B.1', 'Delta B.2'])
     path2 = candidates[2]
     self.assertEqual(descriptions(path2), ['Full C', 'Delta C.1'])
     # The version numbers use the new regime.
     self.assertEqual(path0[0].version, 300)
     self.assertEqual(path0[1].base, 300)
     self.assertEqual(path0[1].version, 301)
     self.assertEqual(path0[2].base, 301)
     self.assertEqual(path0[2].version, 304)
     winner = WeightedScorer().choose(candidates, 'devel')
     self.assertEqual(descriptions(winner),
                      ['Full B', 'Delta B.1', 'Delta B.2'])
     self.assertEqual(winner[0].version, 200)
     self.assertEqual(winner[1].base, 200)
     self.assertEqual(winner[1].version, 201)
     self.assertEqual(winner[2].base, 201)
     self.assertEqual(winner[2].version, 304)
Example #3
0
 def test_filter_for_deltas(self):
     # Filter the candidates, where the only available path is a delta path.
     index = get_index('candidates.index_11.json')
     candidates = get_candidates(index, 100)
     self.assertEqual(len(candidates), 1)
     filtered = delta_filter(candidates)
     self.assertEqual(len(filtered), 1)
     self.assertEqual(candidates, filtered)
Example #4
0
 def test_filter_for_deltas_none_available(self):
     # Run a filter over the candidates, such that the only ones left are
     # those that start with and contain only deltas.  Since none of the
     # paths do so, tere are no candidates left.
     index = get_index('candidates.index_08.json')
     candidates = get_candidates(index, 600)
     filtered = delta_filter(candidates)
     self.assertEqual(len(filtered), 0)
Example #5
0
 def test_filter_for_fulls_with_just_delta_candidates(self):
     # A candidate path that contains only deltas will have no filtered
     # paths if all the images are delta updates.
     index = get_index('candidates.index_11.json')
     candidates = get_candidates(index, 100)
     self.assertEqual(len(candidates), 1)
     filtered = full_filter(candidates)
     self.assertEqual(len(filtered), 0)
Example #6
0
 def test_filter_for_multiple_deltas(self):
     # The candidate path has multiple deltas.  All are preserved.
     index = get_index('candidates.index_12.json')
     candidates = get_candidates(index, 100)
     filtered = delta_filter(candidates)
     self.assertEqual(len(filtered), 1)
     path = filtered[0]
     self.assertEqual(len(path), 3)
     self.assertEqual(descriptions(path), ['Delta A', 'Delta B', 'Delta C'])
Example #7
0
 def test_image_20130500_minversion(self):
     # Some full images have a minimum version older than which they refuse
     # to upgrade from.
     index = get_index('index.index_05.json')
     image = index.images[5]
     self.assertEqual(image.type, 'full')
     self.assertEqual(image.version, 20130500)
     self.assertTrue(image.bootme)
     self.assertEqual(image.minversion, 20130100)
Example #8
0
 def test_tied_candidates(self):
     # LP: #1206866 - TypeError when two candidate paths scored equal.
     #
     # index_04.json was captured from real data causing the traceback.
     index = get_index('scores.index_04.json')
     candidates = get_candidates(index, 1)
     path = self.scorer.choose(candidates, 'devel')
     self.assertEqual(len(path), 1)
     self.assertEqual(path[0].version, 1800)
Example #9
0
 def test_outside_phase_gets_update(self):
     # When the final image on an update path has a phase percentage lower
     # than the device percentage, the scorer falls back to the next
     # candidate path.
     index = get_index('scores.index_05.json')
     candidates = get_candidates(index, 100)
     with patch('systemimage.scores.phased_percentage', return_value=66):
         winner = self.scorer.choose(candidates, 'devel')
     self.assertEqual(descriptions(winner),
                      ['Full A', 'Delta A.1', 'Delta A.2'])
Example #10
0
 def test_equal_phase_gets_update(self):
     # When the final image on an update path has a phase percentage exactly
     # equal to the device percentage, the candidate path is okay.  In this
     # case, the `Full B` has phase of 50%.
     index = get_index('scores.index_05.json')
     candidates = get_candidates(index, 100)
     with patch('systemimage.scores.phased_percentage', return_value=50):
         winner = self.scorer.choose(candidates, 'devel')
     self.assertEqual(descriptions(winner),
                      ['Full B', 'Delta B.1', 'Delta B.2'])
Example #11
0
 def test_pulled_update(self):
     # When the final image on an update path has a phase percentage of
     # zero, then regardless of the device's percentage, the candidate path
     # is not okay.  In this case, the `Full B` has phase of 0%.
     index = get_index('scores.index_01.json')
     candidates = get_candidates(index, 100)
     with patch('systemimage.scores.phased_percentage', return_value=0):
         winner = self.scorer.choose(candidates, 'devel')
     self.assertEqual(descriptions(winner),
                      ['Full A', 'Delta A.1', 'Delta A.2'])
Example #12
0
 def test_one_path_with_full_and_deltas(self):
     # There's one path to upgrade from our version to the final version.
     # This one starts at a full and includes several deltas.
     index = get_index('candidates.index_06.json')
     candidates = get_candidates(index, 1000)
     self.assertEqual(len(candidates), 1)
     path = candidates[0]
     self.assertEqual(len(path), 3)
     self.assertEqual([image.version for image in path], [1300, 1301, 1302])
     self.assertEqual(descriptions(path), ['Full 1', 'Delta 1', 'Delta 2'])
Example #13
0
 def test_one_delta_based_on_us(self):
     # There is one delta in the test data that is based on us.
     index = get_index('candidates.index_04.json')
     candidates = get_candidates(index, 500)
     self.assertEqual(len(candidates), 1)
     path = candidates[0]
     # The path has exactly one image.
     self.assertEqual(len(path), 1)
     image = path[0]
     self.assertEqual(list(image.descriptions.values()), ['Delta 2'])
Example #14
0
 def test_pulled_update_insanely_positive_randint(self):
     # When the final image on an update path has a phase percentage of
     # zero, then regardless of the device's percentage (even if randint
     # returned some insane value), the candidate path is not okay.  In this
     # case, the `Full B` has phase of 0%.
     index = get_index('scores.index_01.json')
     candidates = get_candidates(index, 100)
     with patch('systemimage.scores.phased_percentage', return_value=1000):
         winner = self.scorer.choose(candidates, 'devel')
     self.assertEqual(len(winner), 0)
Example #15
0
 def test_one_path_with_deltas(self):
     # Similar to above, except that because we're upgrading from the
     # version of the full, the path is only two images long, i.e. the
     # deltas.
     index = get_index('candidates.index_06.json')
     candidates = get_candidates(index, 1300)
     self.assertEqual(len(candidates), 1)
     path = candidates[0]
     self.assertEqual(len(path), 2)
     self.assertEqual([image.version for image in path], [1301, 1302])
     self.assertEqual(descriptions(path), ['Delta 1', 'Delta 2'])
Example #16
0
 def test_inside_phase_gets_update(self):
     # When the final image on an update path has a phase percentage higher
     # than the device percentage, the candidate path is okay.  In this
     # case, the `Full B` has phase of 50%.
     index = get_index('scores.index_05.json')
     candidates = get_candidates(index, 100)
     with patch('systemimage.scores.phased_percentage', return_value=22):
         winner = self.scorer.choose(candidates, 'devel')
         descriptions = []
         for image in winner:
             descriptions.extend(image.descriptions.values())
     self.assertEqual(descriptions, ['Full B', 'Delta B.1', 'Delta B.2'])
Example #17
0
 def test_one_path(self):
     index = get_index('scores.index_02.json')
     candidates = get_candidates(index, 600)
     # There's only one path.
     scores = self.scorer.score(candidates)
     # The score is 200 for the two extra bootme flags.
     self.assertEqual(scores, [200])
     # And we upgrade to the only path available.
     winner = self.scorer.choose(candidates, 'devel')
     # There are two images in the winning path.
     self.assertEqual(len(winner), 2)
     self.assertEqual([image.version for image in winner], [1300, 1301])
Example #18
0
 def test_one_higher_full(self):
     # Our device is between the minversions of the two available fulls, so
     # the older one can be upgraded too.
     index = get_index('candidates.index_02.json')
     candidates = get_candidates(index, 800)
     # There is exactly one upgrade path.
     self.assertEqual(len(candidates), 1)
     path = candidates[0]
     # The path has exactly one image.
     self.assertEqual(len(path), 1)
     image = path[0]
     self.assertEqual(list(image.descriptions.values()),
                      ['New full build 1'])
Example #19
0
 def test_two_deltas_based_on_us(self):
     # There are two deltas that are based on us, so both are candidates.
     # They get us to different final versions.
     index = get_index('candidates.index_05.json')
     candidates = get_candidates(index, 1100)
     self.assertEqual(len(candidates), 2)
     # Both candidate paths have exactly one image in them.  We can't sort
     # these paths, so just test them both.
     path0, path1 = candidates
     self.assertEqual(len(path0), 1)
     self.assertEqual(len(path1), 1)
     # One path gets us to version 1300 and the other 1400.
     images = sorted([path0[0], path1[0]], key=attrgetter('version'))
     self.assertEqual(descriptions(images), ['Delta 2', 'Delta 1'])
Example #20
0
 def test_no_version_detail(self):
     # The index.json file has three paths for updates, but only one is
     # selected.  The winning path lands on an image without a
     # version_detail key.
     index = get_index('scores.index_07.json')
     candidates = get_candidates(index, 600)
     scores = self.scorer.score(candidates)
     self.assertEqual(scores, [300, 200, 9401])
     winner = self.scorer.choose(candidates, 'devel')
     self.assertEqual(len(winner), 3)
     self.assertEqual([image.version for image in winner],
                      [1200, 1201, 1304])
     self.assertEqual(descriptions(winner),
                      ['Full B', 'Delta B.1', 'Delta B.2'])
     self.assertEqual(winner[-1].version_detail, '')
Example #21
0
 def test_filter_for_fulls(self):
     # Run a filter over the candidates, such that the only ones left are
     # those that contain only full upgrades.  This can truncate any paths
     # that start with some fulls and then contain some deltas.
     index = get_index('candidates.index_08.json')
     candidates = get_candidates(index, 600)
     filtered = full_filter(candidates)
     # Since all images start with a full update, we're still left with
     # three candidates.
     self.assertEqual(len(filtered), 3)
     self.assertEqual([image.type for image in filtered[0]], ['full'])
     self.assertEqual([image.type for image in filtered[1]], ['full'])
     self.assertEqual([image.type for image in filtered[2]], ['full'])
     self.assertEqual(descriptions(filtered[0]), ['Full A'])
     self.assertEqual(descriptions(filtered[1]), ['Full B'])
     self.assertEqual(descriptions(filtered[2]), ['Full C'])
Example #22
0
 def test_fulls_with_no_minversion(self):
     # Like the previous test, there are two full upgrades, but because
     # neither of them have minversions, both are candidates.
     index = get_index('candidates.index_03.json')
     candidates = get_candidates(index, 400)
     self.assertEqual(len(candidates), 2)
     # Both candidate paths have exactly one image in them.  We can't sort
     # these paths, so just test them both.
     path0, path1 = candidates
     self.assertEqual(len(path0), 1)
     self.assertEqual(len(path1), 1)
     # One path gets us to version 1300 and the other 1400.
     images = sorted([path0[0], path1[0]], key=attrgetter('version'))
     self.assertEqual(list(images[0].descriptions.values()),
                      ['New full build 1'])
     self.assertEqual(list(images[1].descriptions.values()),
                      ['New full build 2'])
Example #23
0
 def test_get_downloads(self):
     # Path B will win; it has one full and two deltas, none of which have
     # a bootme flag.  Download all their files.
     index = get_index('candidates.index_08.json')
     candidates = get_candidates(index, 600)
     winner = WeightedScorer().choose(candidates, 'devel')
     descriptions = []
     for image in winner:
         # There's only one description per image so order doesn't matter.
         descriptions.extend(image.descriptions.values())
     self.assertEqual(descriptions, ['Full B', 'Delta B.1', 'Delta B.2'])
     downloads = list(iter_path(winner))
     paths = set(filerec.path for (n, filerec) in downloads)
     self.assertEqual(
         paths,
         set([
             '/3/4/5.txt',
             '/4/5/6.txt',
             '/5/6/7.txt',
             '/6/7/8.txt',
             '/7/8/9.txt',
             '/8/9/a.txt',
             '/9/a/b.txt',
             '/e/d/c.txt',
             '/f/e/d.txt',
         ]))
     signatures = set(filerec.signature for (n, filerec) in downloads)
     self.assertEqual(
         signatures,
         set([
             '/3/4/5.txt.asc',
             '/4/5/6.txt.asc',
             '/5/6/7.txt.asc',
             '/6/7/8.txt.asc',
             '/7/8/9.txt.asc',
             '/8/9/a.txt.asc',
             '/9/a/b.txt.asc',
             '/e/d/c.txt.asc',
             '/f/e/d.txt.asc',
         ]))
Example #24
0
 def test_image_20130300_full(self):
     index = get_index('index.index_05.json')
     image = index.images[0]
     self.assertEqual(image.descriptions,
                      {'description': 'Some kind of daily build'})
     self.assertEqual(image.type, 'full')
     self.assertEqual(image.version, 20130300)
     self.assertTrue(image.bootme)
     self.assertEqual(len(image.files), 3)
     # The first file is the device dependent image.  The second is the
     # device independent file, and the third is the version zip.
     dev, ind, ver = image.files
     self.assertEqual(dev.path, '/sprint/nexus7/nexus7-20130300.full.zip')
     self.assertEqual(dev.signature,
                      '/sprint/nexus7/nexus7-20130300.full.zip.asc')
     self.assertEqual(dev.checksum, 'abcdef0')
     self.assertEqual(dev.order, 0)
     self.assertEqual(dev.size, 0)
     # Let's not check the whole file, just a few useful bits.
     self.assertEqual(ind.checksum, 'abcdef1')
     self.assertEqual(ind.order, 0)
     self.assertEqual(ver.checksum, 'abcdef2')
     self.assertEqual(ver.order, 1)
Example #25
0
 def test_get_downloads_with_bootme(self):
     # Path B will win; it has one full and two deltas.  The first delta
     # has a bootme flag so the second delta's files are not downloaded.
     index = get_index('candidates.index_09.json')
     candidates = get_candidates(index, 600)
     winner = WeightedScorer().choose(candidates, 'devel')
     descriptions = []
     for image in winner:
         # There's only one description per image so order doesn't matter.
         descriptions.extend(image.descriptions.values())
     self.assertEqual(descriptions, ['Full B', 'Delta B.1', 'Delta B.2'])
     downloads = iter_path(winner)
     paths = set(filerec.path for (n, filerec) in downloads)
     self.assertEqual(
         paths,
         set([
             '/3/4/5.txt',
             '/4/5/6.txt',
             '/5/6/7.txt',
             '/6/7/8.txt',
             '/7/8/9.txt',
             '/8/9/a.txt',
         ]))
Example #26
0
 def test_three_paths(self):
     # - Path A requires three extra reboots, is the smallest total
     #   download and leaves you at the highest available version.
     #   Score: 300
     #
     # - Path B requires one extra reboot, but is 100MiB bigger and leaves
     #   you at the highest available version.  Score: 200
     #
     # - Path C requires no extra reboots, but is 400MiB bigger and leaves
     #   you at 1303 instead of the highest 1304.  For that reason, it gets
     #   a huge score making it impossible to win.
     #
     # Path B wins.
     index = get_index('scores.index_03.json')
     candidates = get_candidates(index, 600)
     # There are three paths.  The scores are as above.
     scores = self.scorer.score(candidates)
     self.assertEqual(scores, [300, 200, 9401])
     winner = self.scorer.choose(candidates, 'devel')
     self.assertEqual(len(winner), 3)
     self.assertEqual([image.version for image in winner],
                      [1200, 1201, 1304])
     self.assertEqual(descriptions(winner),
                      ['Full B', 'Delta B.1', 'Delta B.2'])
Example #27
0
 def test_image_descriptions(self):
     # Image descriptions can come in a variety of locales.
     index = get_index('index.index_01.json')
     self.assertEqual(index.images[0].descriptions,
                      {'description': 'Full A'})
     self.assertEqual(index.images[3].descriptions, {
         'description': 'Full B',
         'description-en': 'The full B',
     })
     self.assertEqual(
         index.images[4].descriptions, {
             'description': 'Delta B.1',
             'description-en_US': 'This is the delta B.1',
             'description-xx': 'XX This is the delta B.1',
             'description-yy': 'YY This is the delta B.1',
             'description-yy_ZZ': 'YY-ZZ This is the delta B.1',
         })
     # The second delta.
     self.assertEqual(
         index.images[5].descriptions, {
             'description': 'Delta B.2',
             'description-xx': 'Oh delta, my delta',
             'description-xx_CC': 'This hyar is the delta B.2',
         })
Example #28
0
 def test_no_deltas_based_on_us(self):
     # There are deltas in the test data, but no fulls.  None of the deltas
     # have a base equal to our build number.
     index = get_index('candidates.index_04.json')
     candidates = get_candidates(index, 100)
     self.assertEqual(candidates, [])
Example #29
0
 def test_only_higher_fulls(self):
     # All the full images have a minversion greater than our version, so
     # we cannot upgrade to any of them.
     index = get_index('candidates.index_02.json')
     candidates = get_candidates(index, 100)
     self.assertEqual(candidates, [])
Example #30
0
 def test_no_images(self):
     # If there are no images defined, there are no candidates.
     index = get_index('candidates.index_01.json')
     candidates = get_candidates(index, 1400)
     self.assertEqual(candidates, [])