test_blockimgdiff.py revision cb73aed1f00ebafe2b9319ec20e41734da9d6b88
1334822842353669df47cec08500d4497b4b353eaTao Bao# 2334822842353669df47cec08500d4497b4b353eaTao Bao# Copyright (C) 2016 The Android Open Source Project 3334822842353669df47cec08500d4497b4b353eaTao Bao# 4334822842353669df47cec08500d4497b4b353eaTao Bao# Licensed under the Apache License, Version 2.0 (the "License"); 5334822842353669df47cec08500d4497b4b353eaTao Bao# you may not use this file except in compliance with the License. 6334822842353669df47cec08500d4497b4b353eaTao Bao# You may obtain a copy of the License at 7334822842353669df47cec08500d4497b4b353eaTao Bao# 8334822842353669df47cec08500d4497b4b353eaTao Bao# http://www.apache.org/licenses/LICENSE-2.0 9334822842353669df47cec08500d4497b4b353eaTao Bao# 10334822842353669df47cec08500d4497b4b353eaTao Bao# Unless required by applicable law or agreed to in writing, software 11334822842353669df47cec08500d4497b4b353eaTao Bao# distributed under the License is distributed on an "AS IS" BASIS, 12334822842353669df47cec08500d4497b4b353eaTao Bao# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13334822842353669df47cec08500d4497b4b353eaTao Bao# See the License for the specific language governing permissions and 14334822842353669df47cec08500d4497b4b353eaTao Bao# limitations under the License. 15334822842353669df47cec08500d4497b4b353eaTao Bao# 16334822842353669df47cec08500d4497b4b353eaTao Bao 17334822842353669df47cec08500d4497b4b353eaTao Baofrom __future__ import print_function 18334822842353669df47cec08500d4497b4b353eaTao Bao 19334822842353669df47cec08500d4497b4b353eaTao Baoimport unittest 20334822842353669df47cec08500d4497b4b353eaTao Bao 21186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Baoimport common 22186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Baofrom blockimgdiff import BlockImageDiff, EmptyImage, HeapItem, Transfer 23334822842353669df47cec08500d4497b4b353eaTao Baofrom rangelib import RangeSet 24334822842353669df47cec08500d4497b4b353eaTao Bao 25186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 26186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Baoclass HealpItemTest(unittest.TestCase): 27186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 28186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao class Item(object): 29186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao def __init__(self, score): 30186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.score = score 31186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 32186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao def test_init(self): 33186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao item1 = HeapItem(self.Item(15)) 34186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao item2 = HeapItem(self.Item(20)) 35186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao item3 = HeapItem(self.Item(15)) 36186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertTrue(item1) 37186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertTrue(item2) 38186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertTrue(item3) 39186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 40186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertNotEqual(item1, item2) 41186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertEqual(item1, item3) 42186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao # HeapItem uses negated scores. 43186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertGreater(item1, item2) 44186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertLessEqual(item1, item3) 45186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertTrue(item1 <= item3) 46186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertFalse(item2 >= item1) 47186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 48186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao def test_clear(self): 49186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao item = HeapItem(self.Item(15)) 50186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertTrue(item) 51186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 52186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao item.clear() 53186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao self.assertFalse(item) 54186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 55186ec99eb9a5580bbd6404ba61b5210f524d65aaTao Bao 56334822842353669df47cec08500d4497b4b353eaTao Baoclass BlockImageDiffTest(unittest.TestCase): 57334822842353669df47cec08500d4497b4b353eaTao Bao 58334822842353669df47cec08500d4497b4b353eaTao Bao def test_GenerateDigraphOrder(self): 59334822842353669df47cec08500d4497b4b353eaTao Bao """Make sure GenerateDigraph preserves the order. 60334822842353669df47cec08500d4497b4b353eaTao Bao 61334822842353669df47cec08500d4497b4b353eaTao Bao t0: <0-5> => <...> 62334822842353669df47cec08500d4497b4b353eaTao Bao t1: <0-7> => <...> 63334822842353669df47cec08500d4497b4b353eaTao Bao t2: <0-4> => <...> 64334822842353669df47cec08500d4497b4b353eaTao Bao t3: <...> => <0-10> 65334822842353669df47cec08500d4497b4b353eaTao Bao 66334822842353669df47cec08500d4497b4b353eaTao Bao t0, t1 and t2 must go before t3, i.e. t3.goes_after = 67334822842353669df47cec08500d4497b4b353eaTao Bao { t0:..., t1:..., t2:... }. But the order of t0-t2 must be preserved. 68334822842353669df47cec08500d4497b4b353eaTao Bao """ 69334822842353669df47cec08500d4497b4b353eaTao Bao 70334822842353669df47cec08500d4497b4b353eaTao Bao src = EmptyImage() 71334822842353669df47cec08500d4497b4b353eaTao Bao tgt = EmptyImage() 72334822842353669df47cec08500d4497b4b353eaTao Bao block_image_diff = BlockImageDiff(tgt, src) 73334822842353669df47cec08500d4497b4b353eaTao Bao 74334822842353669df47cec08500d4497b4b353eaTao Bao transfers = block_image_diff.transfers 75a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu t0 = Transfer("t1", "t1", RangeSet("10-15"), RangeSet("0-5"), "t1hash", 76a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t1hash", "move", transfers) 77a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu t1 = Transfer("t2", "t2", RangeSet("20-25"), RangeSet("0-7"), "t2hash", 78a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t2hash", "move", transfers) 79a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu t2 = Transfer("t3", "t3", RangeSet("30-35"), RangeSet("0-4"), "t3hash", 80a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t3hash", "move", transfers) 81a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu t3 = Transfer("t4", "t4", RangeSet("0-10"), RangeSet("40-50"), "t4hash", 82a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t4hash", "move", transfers) 83334822842353669df47cec08500d4497b4b353eaTao Bao 84334822842353669df47cec08500d4497b4b353eaTao Bao block_image_diff.GenerateDigraph() 85334822842353669df47cec08500d4497b4b353eaTao Bao t3_goes_after_copy = t3.goes_after.copy() 86334822842353669df47cec08500d4497b4b353eaTao Bao 87334822842353669df47cec08500d4497b4b353eaTao Bao # Elements in the set must be in the transfer evaluation order. 88334822842353669df47cec08500d4497b4b353eaTao Bao elements = list(t3_goes_after_copy) 89334822842353669df47cec08500d4497b4b353eaTao Bao self.assertEqual(t0, elements[0]) 90334822842353669df47cec08500d4497b4b353eaTao Bao self.assertEqual(t1, elements[1]) 91334822842353669df47cec08500d4497b4b353eaTao Bao self.assertEqual(t2, elements[2]) 92334822842353669df47cec08500d4497b4b353eaTao Bao 93334822842353669df47cec08500d4497b4b353eaTao Bao # Now switch the order of t0, t1 and t2. 94334822842353669df47cec08500d4497b4b353eaTao Bao transfers[0], transfers[1], transfers[2] = ( 95334822842353669df47cec08500d4497b4b353eaTao Bao transfers[2], transfers[0], transfers[1]) 96334822842353669df47cec08500d4497b4b353eaTao Bao t3.goes_after.clear() 97334822842353669df47cec08500d4497b4b353eaTao Bao t3.goes_before.clear() 98334822842353669df47cec08500d4497b4b353eaTao Bao block_image_diff.GenerateDigraph() 99334822842353669df47cec08500d4497b4b353eaTao Bao 100334822842353669df47cec08500d4497b4b353eaTao Bao # The goes_after must be different from last run. 101334822842353669df47cec08500d4497b4b353eaTao Bao self.assertNotEqual(t3_goes_after_copy, t3.goes_after) 102334822842353669df47cec08500d4497b4b353eaTao Bao 103334822842353669df47cec08500d4497b4b353eaTao Bao # Assert that each element must agree with the transfer order. 104334822842353669df47cec08500d4497b4b353eaTao Bao elements = list(t3.goes_after) 105334822842353669df47cec08500d4497b4b353eaTao Bao self.assertEqual(t2, elements[0]) 106334822842353669df47cec08500d4497b4b353eaTao Bao self.assertEqual(t0, elements[1]) 107334822842353669df47cec08500d4497b4b353eaTao Bao self.assertEqual(t1, elements[2]) 108304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 109304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao def test_ReviseStashSize(self): 110304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao """ReviseStashSize should convert transfers to 'new' commands as needed. 111304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 112304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t1: diff <20-29> => <11-15> 113304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t2: diff <11-15> => <20-29> 114304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao """ 115304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 116304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao src = EmptyImage() 117304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao tgt = EmptyImage() 118304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao block_image_diff = BlockImageDiff(tgt, src, version=3) 119304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 120304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao transfers = block_image_diff.transfers 121a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu Transfer("t1", "t1", RangeSet("11-15"), RangeSet("20-29"), "t1hash", 122a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t1hash", "diff", transfers) 123a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu Transfer("t2", "t2", RangeSet("20-29"), RangeSet("11-15"), "t2hash", 124a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t2hash", "diff", transfers) 125304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 126304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao block_image_diff.GenerateDigraph() 127304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao block_image_diff.FindVertexSequence() 128304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao block_image_diff.ReverseBackwardEdges() 129304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 130304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao # Sufficient cache to stash 5 blocks (size * 0.8 >= 5). 131304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao common.OPTIONS.cache_size = 7 * 4096 132304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao self.assertEqual(0, block_image_diff.ReviseStashSize()) 133304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 134304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao # Insufficient cache to stash 5 blocks (size * 0.8 < 5). 135304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao common.OPTIONS.cache_size = 6 * 4096 136304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao self.assertEqual(10, block_image_diff.ReviseStashSize()) 137304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 138304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao def test_ReviseStashSize_bug_33687949(self): 139304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao """ReviseStashSize() should "free" the used stash _after_ the command. 140304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 141304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t1: diff <1-5> => <11-15> 142304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t2: diff <11-15> => <21-25> 143304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t3: diff <11-15 30-39> => <1-5 30-39> 144304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 145304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao For transfer t3, the used stash "11-15" should not be freed until the 146304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao command finishes. Assume the allowed cache size is 12-block, it should 147304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao convert the command to 'new' due to insufficient cache (12 < 5 + 10). 148304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao """ 149304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 150304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao src = EmptyImage() 151304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao tgt = EmptyImage() 152304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao block_image_diff = BlockImageDiff(tgt, src, version=3) 153304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 154304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao transfers = block_image_diff.transfers 155a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu t1 = Transfer("t1", "t1", RangeSet("11-15"), RangeSet("1-5"), "t1hash", 156a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t1hash", "diff", transfers) 157a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu t2 = Transfer("t2", "t2", RangeSet("21-25"), RangeSet("11-15"), "t2hash", 158a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t2hash", "diff", transfers) 159304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t3 = Transfer("t3", "t3", RangeSet("1-5 30-39"), RangeSet("11-15 30-39"), 160a011dec9b28c03e3f8283de0a0e503f57f73973aTianjie Xu "t3hash", "t3hash", "diff", transfers) 161304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 162304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao block_image_diff.GenerateDigraph() 163304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 164304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao # Instead of calling FindVertexSequence() and ReverseBackwardEdges(), we 165304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao # just set up the stash_before and use_stash manually. Otherwise it will 166304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao # reorder the transfer, which makes testing ReviseStashSize() harder. 167304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t1.stash_before.append((0, RangeSet("11-15"))) 168304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t2.use_stash.append((0, RangeSet("11-15"))) 169304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t1.stash_before.append((1, RangeSet("11-15"))) 170304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao t3.use_stash.append((1, RangeSet("11-15"))) 171304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao 172304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao # Insufficient cache to stash 15 blocks (size * 0.8 < 15). 173304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao common.OPTIONS.cache_size = 15 * 4096 174304ee27e889d0b16c66a9b5d2faed379f8cad627Tao Bao self.assertEqual(15, block_image_diff.ReviseStashSize()) 175cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao 176cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao def test_FileTypeSupportedByImgdiff(self): 177cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertTrue( 178cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao BlockImageDiff.FileTypeSupportedByImgdiff( 179cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/priv-app/Settings/Settings.apk")) 180cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertTrue( 181cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao BlockImageDiff.FileTypeSupportedByImgdiff( 182cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/framework/am.jar")) 183cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertTrue( 184cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao BlockImageDiff.FileTypeSupportedByImgdiff( 185cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/etc/security/otacerts.zip")) 186cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao 187cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertFalse( 188cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao BlockImageDiff.FileTypeSupportedByImgdiff( 189cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/framework/arm/boot.oat")) 190cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertFalse( 191cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao BlockImageDiff.FileTypeSupportedByImgdiff( 192cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/priv-app/notanapk")) 193cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao 194cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao def test_CanUseImgdiff(self): 195cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff = BlockImageDiff(EmptyImage(), EmptyImage()) 196cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertTrue( 197cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff.CanUseImgdiff( 198cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/app/app1.apk", RangeSet("10-15"), RangeSet("0-5"))) 199cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao 200cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao def test_CanUseImgdiff_ineligible(self): 201cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao # Disabled by caller. 202cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff = BlockImageDiff(EmptyImage(), EmptyImage(), 203cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao disable_imgdiff=True) 204cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertFalse( 205cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff.CanUseImgdiff( 206cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/app/app1.apk", RangeSet("10-15"), RangeSet("0-5"))) 207cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao 208cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao # Unsupported file type. 209cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff = BlockImageDiff(EmptyImage(), EmptyImage()) 210cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertFalse( 211cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff.CanUseImgdiff( 212cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/bin/gzip", RangeSet("10-15"), RangeSet("0-5"))) 213cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao 214cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao # At least one of the ranges is in non-monotonic order. 215cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertFalse( 216cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff.CanUseImgdiff( 217cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/system/app/app2.apk", RangeSet("10-15"), 218cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao RangeSet("15-20 30 10-14"))) 219cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao 220cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao # At least one of the ranges has been modified. 221cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao src_ranges = RangeSet("0-5") 222cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao src_ranges.extra['trimmed'] = True 223cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao self.assertFalse( 224cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao block_image_diff.CanUseImgdiff( 225cb73aed1f00ebafe2b9319ec20e41734da9d6b88Tao Bao "/vendor/app/app3.apk", RangeSet("10-15"), src_ranges)) 226