1f583a7d7c5255ec0e2321db60b7690c25e58c290Gilad Arnold#!/usr/bin/python2 25502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# 35502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 45502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# Use of this source code is governed by a BSD-style license that can be 55502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# found in the LICENSE file. 65502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 75502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold"""Unit testing checker.py.""" 85502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9f583a7d7c5255ec0e2321db60b7690c25e58c290Gilad Arnoldfrom __future__ import print_function 10f583a7d7c5255ec0e2321db60b7690c25e58c290Gilad Arnold 115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport array 125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport collections 135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport cStringIO 145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport hashlib 155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport itertools 165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport os 175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport unittest 185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 19cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold# pylint cannot find mox. 205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# pylint: disable=F0401 215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport mox 225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport checker 245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport common 25cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnoldimport payload as update_payload # Avoid name conflicts later. 265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport test_utils 275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldimport update_metadata_pb2 285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnolddef _OpTypeByName(op_name): 315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op_name_to_type = { 325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'REPLACE': common.OpType.REPLACE, 335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'REPLACE_BZ': common.OpType.REPLACE_BZ, 345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'MOVE': common.OpType.MOVE, 355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'BSDIFF': common.OpType.BSDIFF, 36f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 'SOURCE_COPY': common.OpType.SOURCE_COPY, 37f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 'SOURCE_BSDIFF': common.OpType.SOURCE_BSDIFF, 382846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo 'ZERO': common.OpType.ZERO, 392846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo 'DISCARD': common.OpType.DISCARD, 402846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo 'REPLACE_XZ': common.OpType.REPLACE_XZ, 41c2538fab9a7fc01c0216520874d711c8a9fbd9d3Sen Jiang 'IMGDIFF': common.OpType.IMGDIFF, 425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold } 435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return op_name_to_type[op_name] 445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 46eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnolddef _GetPayloadChecker(payload_gen_write_to_file_func, payload_gen_dargs=None, 47eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold checker_init_dargs=None): 485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Returns a payload checker from a given payload generator.""" 49eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold if payload_gen_dargs is None: 50eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold payload_gen_dargs = {} 51eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold if checker_init_dargs is None: 52eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold checker_init_dargs = {} 53eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_file = cStringIO.StringIO() 55eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold payload_gen_write_to_file_func(payload_file, **payload_gen_dargs) 565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_file.seek(0) 575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload = update_payload.Payload(payload_file) 585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload.Init() 59eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold return checker.PayloadChecker(payload, **checker_init_dargs) 605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnolddef _GetPayloadCheckerWithData(payload_gen): 635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Returns a payload checker from a given payload generator.""" 645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_file = cStringIO.StringIO() 655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.WriteToFile(payload_file) 665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_file.seek(0) 675502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload = update_payload.Payload(payload_file) 685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload.Init() 695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return checker.PayloadChecker(payload) 705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 715502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 72cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold# This class doesn't need an __init__(). 735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# pylint: disable=W0232 74cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold# Unit testing is all about running protected methods. 755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# pylint: disable=W0212 76cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold# Don't bark about missing members of classes you cannot import. 775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# pylint: disable=E1101 785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldclass PayloadCheckerTest(mox.MoxTestBase): 795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests the PayloadChecker class. 805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold In addition to ordinary testFoo() methods, which are automatically invoked by 825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold the unittest framework, in this class we make use of DoBarTest() calls that 835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold implement parametric tests of certain features. In order to invoke each test, 845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold which embodies a unique combination of parameter values, as a complete unit 855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold test, we perform explicit enumeration of the parameter space and create 865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold individual invocation contexts for each, which are then bound as 875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold testBar__param1=val1__param2=val2(). The enumeration of parameter spaces for 885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold all such tests is done in AddAllParametricTests(). 895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def MockPayload(self): 92f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood """Create a mock payload object, complete with a mock manifest.""" 935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload = self.mox.CreateMock(update_payload.Payload) 945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload.is_init = True 955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload.manifest = self.mox.CreateMock( 965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_metadata_pb2.DeltaArchiveManifest) 975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return payload 985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold @staticmethod 1005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def NewExtent(start_block, num_blocks): 1015502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Returns an Extent message. 1025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Each of the provided fields is set iff it is >= 0; otherwise, it's left at 1045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold its default state. 1055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 107cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold start_block: The starting block of the extent. 108cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold num_blocks: The number of blocks in the extent. 109f583a7d7c5255ec0e2321db60b7690c25e58c290Gilad Arnold 1105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Returns: 1115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold An Extent message. 1125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 1135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold ex = update_metadata_pb2.Extent() 1145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if start_block >= 0: 1155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold ex.start_block = start_block 1165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if num_blocks >= 0: 1175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold ex.num_blocks = num_blocks 1185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return ex 1195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold @staticmethod 1215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def NewExtentList(*args): 1225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Returns an list of extents. 1235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 125cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold *args: (start_block, num_blocks) pairs defining the extents. 126f583a7d7c5255ec0e2321db60b7690c25e58c290Gilad Arnold 1275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Returns: 1285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold A list of Extent objects. 1295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 1305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold ex_list = [] 1315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold for start_block, num_blocks in args: 1325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold ex_list.append(PayloadCheckerTest.NewExtent(start_block, num_blocks)) 1335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return ex_list 1345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold @staticmethod 1365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def AddToMessage(repeated_field, field_vals): 1375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold for field_val in field_vals: 1385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold new_field = repeated_field.add() 1395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold new_field.CopyFrom(field_val) 1405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def SetupAddElemTest(self, is_present, is_submsg, convert=str, 1425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold linebreak=False, indent=0): 1435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Setup for testing of _CheckElem() and its derivatives. 1445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 146cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_present: Whether or not the element is found in the message. 147cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_submsg: Whether the element is a sub-message itself. 148cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold convert: A representation conversion function. 149cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold linebreak: Whether or not a linebreak is to be used in the report. 150cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold indent: Indentation used for the report. 151f583a7d7c5255ec0e2321db60b7690c25e58c290Gilad Arnold 1525502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Returns: 153cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold msg: A mock message object. 154cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold report: A mock report object. 155cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold subreport: A mock sub-report object. 156cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold name: An element name to check. 157cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold val: Expected element value. 1585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 1595502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold name = 'foo' 1605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold val = 'fake submsg' if is_submsg else 'fake field' 1615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold subreport = 'fake subreport' 1625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create a mock message. 1642846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo msg = self.mox.CreateMock(update_metadata_pb2._message.Message) 1655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold msg.HasField(name).AndReturn(is_present) 1665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold setattr(msg, name, val) 1675502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create a mock report. 1695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold report = self.mox.CreateMock(checker._PayloadReport) 1705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if is_present: 1715502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if is_submsg: 1725502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold report.AddSubReport(name).AndReturn(subreport) 1735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 1745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold report.AddField(name, convert(val), linebreak=linebreak, indent=indent) 1755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.mox.ReplayAll() 1775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return (msg, report, subreport, name, val) 1785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def DoAddElemTest(self, is_present, is_mandatory, is_submsg, convert, 1805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold linebreak, indent): 1815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Parametric testing of _CheckElem(). 1825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 184cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_present: Whether or not the element is found in the message. 185cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_mandatory: Whether or not it's a mandatory element. 186cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_submsg: Whether the element is a sub-message itself. 187cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold convert: A representation conversion function. 188cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold linebreak: Whether or not a linebreak is to be used in the report. 189cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold indent: Indentation used for the report. 1905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 1915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold msg, report, subreport, name, val = self.SetupAddElemTest( 1925502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold is_present, is_submsg, convert, linebreak, indent) 1935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 194cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args = (msg, name, report, is_mandatory, is_submsg) 195cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold kwargs = {'convert': convert, 'linebreak': linebreak, 'indent': indent} 1965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if is_mandatory and not is_present: 1975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 198cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold checker.PayloadChecker._CheckElem, *args, **kwargs) 1995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 200cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold ret_val, ret_subreport = checker.PayloadChecker._CheckElem(*args, 201cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold **kwargs) 202cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEquals(val if is_present else None, ret_val) 203cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEquals(subreport if is_present and is_submsg else None, 204cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold ret_subreport) 2055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def DoAddFieldTest(self, is_mandatory, is_present, convert, linebreak, 2075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold indent): 2085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Parametric testing of _Check{Mandatory,Optional}Field(). 2095502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 211cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_mandatory: Whether we're testing a mandatory call. 212cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_present: Whether or not the element is found in the message. 213cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold convert: A representation conversion function. 214cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold linebreak: Whether or not a linebreak is to be used in the report. 215cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold indent: Indentation used for the report. 2165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 2175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold msg, report, _, name, val = self.SetupAddElemTest( 2185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold is_present, False, convert, linebreak, indent) 2195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Prepare for invocation of the tested method. 221cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args = [msg, name, report] 222cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold kwargs = {'convert': convert, 'linebreak': linebreak, 'indent': indent} 2235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if is_mandatory: 224cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args.append('bar') 2255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold tested_func = checker.PayloadChecker._CheckMandatoryField 2265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 2275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold tested_func = checker.PayloadChecker._CheckOptionalField 2285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Test the method call. 2305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if is_mandatory and not is_present: 231cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertRaises(update_payload.PayloadError, tested_func, *args, 232cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold **kwargs) 2335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 234cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold ret_val = tested_func(*args, **kwargs) 235cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEquals(val if is_present else None, ret_val) 2365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def DoAddSubMsgTest(self, is_mandatory, is_present): 2385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Parametrized testing of _Check{Mandatory,Optional}SubMsg(). 2395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 241cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_mandatory: Whether we're testing a mandatory call. 242cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_present: Whether or not the element is found in the message. 2435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 2445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold msg, report, subreport, name, val = self.SetupAddElemTest(is_present, True) 2455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2465502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Prepare for invocation of the tested method. 247cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args = [msg, name, report] 2485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if is_mandatory: 249cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args.append('bar') 2505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold tested_func = checker.PayloadChecker._CheckMandatorySubMsg 2515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 2525502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold tested_func = checker.PayloadChecker._CheckOptionalSubMsg 2535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Test the method call. 2555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if is_mandatory and not is_present: 256cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertRaises(update_payload.PayloadError, tested_func, *args) 2575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 258cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold ret_val, ret_subreport = tested_func(*args) 259cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEquals(val if is_present else None, ret_val) 260cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEquals(subreport if is_present else None, ret_subreport) 2615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckPresentIff(self): 2635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckPresentIff().""" 2645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone(checker.PayloadChecker._CheckPresentIff( 2655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold None, None, 'foo', 'bar', 'baz')) 2665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone(checker.PayloadChecker._CheckPresentIff( 2675502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'a', 'b', 'foo', 'bar', 'baz')) 2685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 2695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckPresentIff, 2705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'a', None, 'foo', 'bar', 'baz') 2715502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 2725502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckPresentIff, 2735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold None, 'b', 'foo', 'bar', 'baz') 2745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def DoCheckSha256SignatureTest(self, expect_pass, expect_subprocess_call, 2765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sig_data, sig_asn1_header, 2775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold returned_signed_hash, expected_signed_hash): 2785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Parametric testing of _CheckSha256SignatureTest(). 2795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 2805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 281cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold expect_pass: Whether or not it should pass. 282cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold expect_subprocess_call: Whether to expect the openssl call to happen. 283cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold sig_data: The signature raw data. 284cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold sig_asn1_header: The ASN1 header. 285cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold returned_signed_hash: The signed hash data retuned by openssl. 286cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold expected_signed_hash: The signed hash data to compare against. 2875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 288cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold try: 289cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold # Stub out the subprocess invocation. 290cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.mox.StubOutWithMock(checker.PayloadChecker, '_Run') 291cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold if expect_subprocess_call: 292cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold checker.PayloadChecker._Run( 293cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold mox.IsA(list), send_data=sig_data).AndReturn( 294cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold (sig_asn1_header + returned_signed_hash, None)) 295cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold 296cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.mox.ReplayAll() 297cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold if expect_pass: 298cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertIsNone(checker.PayloadChecker._CheckSha256Signature( 299cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold sig_data, 'foo', expected_signed_hash, 'bar')) 300cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold else: 301cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertRaises(update_payload.PayloadError, 302cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold checker.PayloadChecker._CheckSha256Signature, 303cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold sig_data, 'foo', expected_signed_hash, 'bar') 304cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold finally: 305cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.mox.UnsetStubs() 3065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckSha256Signature_Pass(self): 3085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckSha256Signature(); pass case.""" 3095502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sig_data = 'fake-signature'.ljust(256) 3105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold signed_hash = hashlib.sha256('fake-data').digest() 3115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.DoCheckSha256SignatureTest(True, True, sig_data, 3125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold common.SIG_ASN1_HEADER, signed_hash, 3135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold signed_hash) 3145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckSha256Signature_FailBadSignature(self): 3165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckSha256Signature(); fails due to malformed signature.""" 317cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold sig_data = 'fake-signature' # Malformed (not 256 bytes in length). 3185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold signed_hash = hashlib.sha256('fake-data').digest() 3195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.DoCheckSha256SignatureTest(False, False, sig_data, 3205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold common.SIG_ASN1_HEADER, signed_hash, 3215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold signed_hash) 3225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckSha256Signature_FailBadOutputLength(self): 3245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckSha256Signature(); fails due to unexpected output length.""" 3255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sig_data = 'fake-signature'.ljust(256) 326cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold signed_hash = 'fake-hash' # Malformed (not 32 bytes in length). 3275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.DoCheckSha256SignatureTest(False, True, sig_data, 3285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold common.SIG_ASN1_HEADER, signed_hash, 3295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold signed_hash) 3305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckSha256Signature_FailBadAsnHeader(self): 3325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckSha256Signature(); fails due to bad ASN1 header.""" 3335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sig_data = 'fake-signature'.ljust(256) 3345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold signed_hash = hashlib.sha256('fake-data').digest() 3355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold bad_asn1_header = 'bad-asn-header'.ljust(len(common.SIG_ASN1_HEADER)) 3365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.DoCheckSha256SignatureTest(False, True, sig_data, bad_asn1_header, 3375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold signed_hash, signed_hash) 3385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckSha256Signature_FailBadHash(self): 3405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckSha256Signature(); fails due to bad hash returned.""" 3415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sig_data = 'fake-signature'.ljust(256) 3425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold expected_signed_hash = hashlib.sha256('fake-data').digest() 3435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold returned_signed_hash = hashlib.sha256('bad-fake-data').digest() 3445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.DoCheckSha256SignatureTest(False, True, sig_data, 3455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold common.SIG_ASN1_HEADER, 3465502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold expected_signed_hash, returned_signed_hash) 3475502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckBlocksFitLength_Pass(self): 3495502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckBlocksFitLength(); pass case.""" 3505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone(checker.PayloadChecker._CheckBlocksFitLength( 3515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 64, 4, 16, 'foo')) 3525502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone(checker.PayloadChecker._CheckBlocksFitLength( 3535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 60, 4, 16, 'foo')) 3545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone(checker.PayloadChecker._CheckBlocksFitLength( 3555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 49, 4, 16, 'foo')) 3565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone(checker.PayloadChecker._CheckBlocksFitLength( 3575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 48, 3, 16, 'foo')) 3585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3595502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckBlocksFitLength_TooManyBlocks(self): 3605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckBlocksFitLength(); fails due to excess blocks.""" 3615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 64, 5, 16, 'foo') 3645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 60, 5, 16, 'foo') 3675502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 49, 5, 16, 'foo') 3705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3715502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3725502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 48, 4, 16, 'foo') 3735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckBlocksFitLength_TooFewBlocks(self): 3755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckBlocksFitLength(); fails due to insufficient blocks.""" 3765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 64, 3, 16, 'foo') 3795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 60, 3, 16, 'foo') 3825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 49, 3, 16, 'foo') 3855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 3865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold checker.PayloadChecker._CheckBlocksFitLength, 3875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 48, 2, 16, 'foo') 3885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def DoCheckManifestTest(self, fail_mismatched_block_size, fail_bad_sigs, 3905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_oki_ori, fail_bad_oki, fail_bad_ori, 3915bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold fail_bad_nki, fail_bad_nri, fail_old_kernel_fs_size, 3925bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold fail_old_rootfs_fs_size, fail_new_kernel_fs_size, 3935bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold fail_new_rootfs_fs_size): 3945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Parametric testing of _CheckManifest(). 3955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 3965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 397cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_mismatched_block_size: Simulate a missing block_size field. 398cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_bad_sigs: Make signatures descriptor inconsistent. 399cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_mismatched_oki_ori: Make old rootfs/kernel info partially present. 400cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_bad_oki: Tamper with old kernel info. 401cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_bad_ori: Tamper with old rootfs info. 402cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_bad_nki: Tamper with new kernel info. 403cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_bad_nri: Tamper with new rootfs info. 404cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_old_kernel_fs_size: Make old kernel fs size too big. 405cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_old_rootfs_fs_size: Make old rootfs fs size too big. 406cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_new_kernel_fs_size: Make new kernel fs size too big. 407cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_new_rootfs_fs_size: Make new rootfs fs size too big. 4085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 4095502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Generate a test payload. For this test, we only care about the manifest 4105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # and don't need any data blobs, hence we can use a plain paylaod generator 4115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # (which also gives us more control on things that can be screwed up). 4125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen = test_utils.PayloadGenerator() 4135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Tamper with block size, if required. 4155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_mismatched_block_size: 41618f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold payload_gen.SetBlockSize(test_utils.KiB(1)) 4175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 41818f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold payload_gen.SetBlockSize(test_utils.KiB(4)) 4195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add some operations. 4215bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold payload_gen.AddOperation(False, common.OpType.MOVE, 4225bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold src_extents=[(0, 16), (16, 497)], 4235bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold dst_extents=[(16, 496), (0, 16)]) 4245bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold payload_gen.AddOperation(True, common.OpType.MOVE, 4255bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold src_extents=[(0, 8), (8, 8)], 4265bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold dst_extents=[(8, 8), (0, 8)]) 4275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Set an invalid signatures block (offset but no size), if required. 4295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_bad_sigs: 4305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetSignatures(32, None) 4315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 432382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold # Set partition / filesystem sizes. 43318f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold rootfs_part_size = test_utils.MiB(8) 43418f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold kernel_part_size = test_utils.KiB(512) 435382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold old_rootfs_fs_size = new_rootfs_fs_size = rootfs_part_size 436382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold old_kernel_fs_size = new_kernel_fs_size = kernel_part_size 437382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold if fail_old_kernel_fs_size: 438382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold old_kernel_fs_size += 100 439382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold if fail_old_rootfs_fs_size: 440382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold old_rootfs_fs_size += 100 441382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold if fail_new_kernel_fs_size: 442382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold new_kernel_fs_size += 100 443382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold if fail_new_rootfs_fs_size: 444382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold new_rootfs_fs_size += 100 445382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold 4465502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add old kernel/rootfs partition info, as required. 447382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold if fail_mismatched_oki_ori or fail_old_kernel_fs_size or fail_bad_oki: 4485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold oki_hash = (None if fail_bad_oki 4495502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else hashlib.sha256('fake-oki-content').digest()) 450382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold payload_gen.SetPartInfo(True, False, old_kernel_fs_size, oki_hash) 451382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold if not fail_mismatched_oki_ori and (fail_old_rootfs_fs_size or 452382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold fail_bad_ori): 453382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold ori_hash = (None if fail_bad_ori 454382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold else hashlib.sha256('fake-ori-content').digest()) 455382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold payload_gen.SetPartInfo(False, False, old_rootfs_fs_size, ori_hash) 4565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add new kernel/rootfs partition info. 4585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetPartInfo( 459382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold True, True, new_kernel_fs_size, 4605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold None if fail_bad_nki else hashlib.sha256('fake-nki-content').digest()) 4615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetPartInfo( 462382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold False, True, new_rootfs_fs_size, 4635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold None if fail_bad_nri else hashlib.sha256('fake-nri-content').digest()) 4645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4650d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold # Set the minor version. 4660d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_gen.SetMinorVersion(0) 4670d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold 4685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create the test object. 4695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = _GetPayloadChecker(payload_gen.WriteToFile) 4705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold report = checker._PayloadReport() 4715502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4725502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold should_fail = (fail_mismatched_block_size or fail_bad_sigs or 4735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_oki_ori or fail_bad_oki or fail_bad_ori or 4745bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold fail_bad_nki or fail_bad_nri or fail_old_kernel_fs_size or 4755bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold fail_old_rootfs_fs_size or fail_new_kernel_fs_size or 4765bc7fbea01f944192f146b97cd83050858cddcc5Gilad Arnold fail_new_rootfs_fs_size) 4775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if should_fail: 4785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 479382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold payload_checker._CheckManifest, report, 480382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold rootfs_part_size, kernel_part_size) 4815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 482382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold self.assertIsNone(payload_checker._CheckManifest(report, 483382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold rootfs_part_size, 484382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold kernel_part_size)) 4855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckLength(self): 4875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckLength().""" 4885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 4895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold block_size = payload_checker.block_size 4905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 4915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Passes. 4925502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone(payload_checker._CheckLength( 4935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold int(3.5 * block_size), 4, 'foo', 'bar')) 4945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fails, too few blocks. 4955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 4965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckLength, 4975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold int(3.5 * block_size), 3, 'foo', 'bar') 4985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fails, too many blocks. 4995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 5005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckLength, 5015502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold int(3.5 * block_size), 5, 'foo', 'bar') 5025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckExtents(self): 5045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckExtents().""" 5055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 5065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold block_size = payload_checker.block_size 5075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Passes w/ all real extents. 5095502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents = self.NewExtentList((0, 4), (8, 3), (1024, 16)) 5105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertEquals( 511cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold 23, 5125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckExtents(extents, (1024 + 16) * block_size, 513cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold collections.defaultdict(int), 'foo')) 5145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Passes w/ pseudo-extents (aka sparse holes). 5165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents = self.NewExtentList((0, 4), (common.PSEUDO_EXTENT_MARKER, 5), 5175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold (8, 3)) 5185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertEquals( 519cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold 12, 5205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckExtents(extents, (1024 + 16) * block_size, 5215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold collections.defaultdict(int), 'foo', 522cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold allow_pseudo=True)) 5235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Passes w/ pseudo-extent due to a signature. 5255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents = self.NewExtentList((common.PSEUDO_EXTENT_MARKER, 2)) 5265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertEquals( 527cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold 2, 5285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckExtents(extents, (1024 + 16) * block_size, 5295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold collections.defaultdict(int), 'foo', 530cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold allow_signature=True)) 5315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fails, extent missing a start block. 5335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents = self.NewExtentList((-1, 4), (8, 3), (1024, 16)) 5345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 5355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, payload_checker._CheckExtents, 5365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents, (1024 + 16) * block_size, collections.defaultdict(int), 5375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'foo') 5385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fails, extent missing block count. 5405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents = self.NewExtentList((0, -1), (8, 3), (1024, 16)) 5415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 5425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, payload_checker._CheckExtents, 5435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents, (1024 + 16) * block_size, collections.defaultdict(int), 5445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'foo') 5455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5465502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fails, extent has zero blocks. 5475502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents = self.NewExtentList((0, 4), (8, 3), (1024, 0)) 5485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 5495502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, payload_checker._CheckExtents, 5505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents, (1024 + 16) * block_size, collections.defaultdict(int), 5515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'foo') 5525502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fails, extent exceeds partition boundaries. 5545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents = self.NewExtentList((0, 4), (8, 3), (1024, 16)) 5555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 5565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, payload_checker._CheckExtents, 5575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold extents, (1024 + 15) * block_size, collections.defaultdict(int), 5585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'foo') 5595502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckReplaceOperation(self): 5615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckReplaceOperation() where op.type == REPLACE.""" 5625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 5635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold block_size = payload_checker.block_size 5645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold data_length = 10000 5655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op = self.mox.CreateMock( 5672846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo update_metadata_pb2.InstallOperation) 5685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.REPLACE 5695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Pass. 5715502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = [] 5725502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone( 5735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation( 5745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, data_length, (data_length + block_size - 1) / block_size, 5755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'foo')) 5765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, src extents founds. 5785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = ['bar'] 5795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 5805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 5815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation, 5825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, data_length, (data_length + block_size - 1) / block_size, 'foo') 5835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, missing data. 5855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = [] 5865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 5875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 5885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation, 5895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, (data_length + block_size - 1) / block_size, 'foo') 5905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, length / block number mismatch. 5925502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = ['bar'] 5935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 5945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 5955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation, 5965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, data_length, (data_length + block_size - 1) / block_size + 1, 'foo') 5975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 5985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckReplaceBzOperation(self): 5995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckReplaceOperation() where op.type == REPLACE_BZ.""" 6005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 6015502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold block_size = payload_checker.block_size 6025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold data_length = block_size * 3 6035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op = self.mox.CreateMock( 6052846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo update_metadata_pb2.InstallOperation) 6065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.REPLACE_BZ 6075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Pass. 6095502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = [] 6105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone( 6115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation( 6125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, data_length, (data_length + block_size - 1) / block_size + 5, 6135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'foo')) 6145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, src extents founds. 6165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = ['bar'] 6175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 6185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 6195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation, 6205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, data_length, (data_length + block_size - 1) / block_size + 5, 'foo') 6215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, missing data. 6235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = [] 6245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 6255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 6265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation, 6275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, (data_length + block_size - 1) / block_size, 'foo') 6285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, too few blocks to justify BZ. 6305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_extents = [] 6315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 6325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 6335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckReplaceOperation, 6345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, data_length, (data_length + block_size - 1) / block_size, 'foo') 6355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckMoveOperation_Pass(self): 6375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation(); pass case.""" 6385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 6392846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 6405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.MOVE 6415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 643b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 128))) 6445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 6455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((16, 128), (512, 6))) 6465502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone( 6475502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation(op, None, 134, 134, 'foo')) 6485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6495502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckMoveOperation_FailContainsData(self): 6505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation(); fails, message contains data.""" 6515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 6522846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 6535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.MOVE 6545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 656b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 128))) 6575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 6585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((16, 128), (512, 6))) 6595502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 6605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 6615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation, 6625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, 1024, 134, 134, 'foo') 6635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckMoveOperation_FailInsufficientSrcBlocks(self): 6655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation(); fails, not enough actual src blocks.""" 6665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 6672846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 6685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.MOVE 6695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 671b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 127))) 6725502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 6735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((16, 128), (512, 6))) 6745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 6755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 6765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation, 6775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, 134, 134, 'foo') 6785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckMoveOperation_FailInsufficientDstBlocks(self): 6805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation(); fails, not enough actual dst blocks.""" 6815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 6822846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 6835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.MOVE 6845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 686b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 128))) 6875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 6885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((16, 128), (512, 5))) 6895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 6905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 6915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation, 6925502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, 134, 134, 'foo') 6935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 6945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckMoveOperation_FailExcessSrcBlocks(self): 6955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation(); fails, too many actual src blocks.""" 6965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 6972846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 6985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.MOVE 6995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 701b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 128))) 7025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 7035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((16, 128), (512, 5))) 7045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 7055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 7065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation, 7075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, 134, 134, 'foo') 7085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 709b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 129))) 7105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 7115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((16, 128), (512, 6))) 7125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 7135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 7145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation, 7155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, 134, 134, 'foo') 7165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckMoveOperation_FailExcessDstBlocks(self): 7185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation(); fails, too many actual dst blocks.""" 7195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 7202846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 7215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.MOVE 7225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 724b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 128))) 7255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 7265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((16, 128), (512, 7))) 7275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 7285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 7295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation, 7305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, 134, 134, 'foo') 7315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testCheckMoveOperation_FailStagnantBlocks(self): 7335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation(); fails, there are blocks that do not move.""" 7345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 7352846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 7365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = common.OpType.MOVE 7375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 739b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 128))) 740b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.AddToMessage(op.dst_extents, 741b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((8, 128), (512, 6))) 742b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.assertRaises( 743b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood update_payload.PayloadError, 744b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood payload_checker._CheckMoveOperation, 745b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood op, None, 134, 134, 'foo') 746b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood 747b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood def testCheckMoveOperation_FailZeroStartBlock(self): 748b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood """Tests _CheckMoveOperation(); fails, has extent with start block 0.""" 749b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood payload_checker = checker.PayloadChecker(self.MockPayload()) 7502846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 751b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood op.type = common.OpType.MOVE 752b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood 753b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.AddToMessage(op.src_extents, 7545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((0, 4), (12, 2), (1024, 128))) 7555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 7565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((8, 128), (512, 6))) 7575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 7585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 7595502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker._CheckMoveOperation, 7605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op, None, 134, 134, 'foo') 7615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 762b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.AddToMessage(op.src_extents, 763b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 4), (12, 2), (1024, 128))) 764b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.AddToMessage(op.dst_extents, 765b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((0, 128), (512, 6))) 766b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.assertRaises( 767b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood update_payload.PayloadError, 768b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood payload_checker._CheckMoveOperation, 769b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood op, None, 134, 134, 'foo') 770b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood 77192161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang def testCheckAnyDiff(self): 77292161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang """Tests _CheckAnyDiffOperation().""" 7735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 7745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Pass. 7765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertIsNone( 77792161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang payload_checker._CheckAnyDiffOperation(10000, 3, 'foo')) 7785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, missing data blob. 7805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 7815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 78292161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang payload_checker._CheckAnyDiffOperation, 7835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold None, 3, 'foo') 7845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 7855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fail, too big of a diff blob (unjustified). 7865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises( 7875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold update_payload.PayloadError, 78892161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang payload_checker._CheckAnyDiffOperation, 7895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10000, 2, 'foo') 7905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 791f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood def testCheckSourceCopyOperation_Pass(self): 792f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood """Tests _CheckSourceCopyOperation(); pass case.""" 793f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood payload_checker = checker.PayloadChecker(self.MockPayload()) 794f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood self.assertIsNone( 795f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood payload_checker._CheckSourceCopyOperation(None, 134, 134, 'foo')) 796f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 797f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood def testCheckSourceCopyOperation_FailContainsData(self): 798f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood """Tests _CheckSourceCopyOperation(); message contains data.""" 799f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood payload_checker = checker.PayloadChecker(self.MockPayload()) 800f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood self.assertRaises(update_payload.PayloadError, 801f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood payload_checker._CheckSourceCopyOperation, 802f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 134, 0, 0, 'foo') 803f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 804f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood def testCheckSourceCopyOperation_FailBlockCountsMismatch(self): 805f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood """Tests _CheckSourceCopyOperation(); src and dst block totals not equal.""" 806f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood payload_checker = checker.PayloadChecker(self.MockPayload()) 807f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood self.assertRaises(update_payload.PayloadError, 808f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood payload_checker._CheckSourceCopyOperation, 809f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood None, 0, 1, 'foo') 810f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 8115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def DoCheckOperationTest(self, op_type_name, is_last, allow_signature, 8125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold allow_unhashed, fail_src_extents, fail_dst_extents, 8135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_data_offset_length, 8145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_missing_dst_extents, fail_src_length, 8155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_dst_length, fail_data_hash, 8167cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood fail_prev_data_offset, fail_bad_minor_version): 8175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Parametric testing of _CheckOperation(). 8185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 820f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood op_type_name: 'REPLACE', 'REPLACE_BZ', 'MOVE', 'BSDIFF', 'SOURCE_COPY', 821f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood or 'SOURCE_BSDIFF'. 822cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold is_last: Whether we're testing the last operation in a sequence. 823cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold allow_signature: Whether we're testing a signature-capable operation. 824cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold allow_unhashed: Whether we're allowing to not hash the data. 825cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_src_extents: Tamper with src extents. 826cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_dst_extents: Tamper with dst extents. 827cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_mismatched_data_offset_length: Make data_{offset,length} 828cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold inconsistent. 829cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_missing_dst_extents: Do not include dst extents. 830cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_src_length: Make src length inconsistent. 831cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_dst_length: Make dst length inconsistent. 832cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_data_hash: Tamper with the data blob hash. 833cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold fail_prev_data_offset: Make data space uses incontiguous. 8347cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood fail_bad_minor_version: Make minor version incompatible with op. 8355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 8365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op_type = _OpTypeByName(op_type_name) 8375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create the test object. 8395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload = self.MockPayload() 840eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold payload_checker = checker.PayloadChecker(payload, 841eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold allow_unhashed=allow_unhashed) 8425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold block_size = payload_checker.block_size 8435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create auxiliary arguments. 84518f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold old_part_size = test_utils.MiB(4) 84618f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold new_part_size = test_utils.MiB(8) 8475502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold old_block_counters = array.array( 8485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'B', [0] * ((old_part_size + block_size - 1) / block_size)) 8495502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold new_block_counters = array.array( 8505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'B', [0] * ((new_part_size + block_size - 1) / block_size)) 8515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold prev_data_offset = 1876 8525502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold blob_hash_counts = collections.defaultdict(int) 8535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create the operation object for the test. 8552846677f9ec7725d9cf9513768477c873c19ba78Alex Deymo op = update_metadata_pb2.InstallOperation() 8565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.type = op_type 8575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold total_src_blocks = 0 859f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood if op_type in (common.OpType.MOVE, common.OpType.BSDIFF, 860f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood common.OpType.SOURCE_COPY, common.OpType.SOURCE_BSDIFF): 8615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_src_extents: 8625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 863b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 0))) 8645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 8655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.src_extents, 866b065e13f600d0efc7f089a382611ffd93a8afce9Allie Wood self.NewExtentList((1, 16))) 8675502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold total_src_blocks = 16 8685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8697cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood if op_type in (common.OpType.REPLACE, common.OpType.REPLACE_BZ): 8700d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_checker.minor_version = 0 8717cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood elif op_type in (common.OpType.MOVE, common.OpType.BSDIFF): 8720d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_checker.minor_version = 2 if fail_bad_minor_version else 1 8737cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood elif op_type in (common.OpType.SOURCE_COPY, common.OpType.SOURCE_BSDIFF): 8740d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_checker.minor_version = 1 if fail_bad_minor_version else 2 8757cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood 876f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood if op_type not in (common.OpType.MOVE, common.OpType.SOURCE_COPY): 8775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if not fail_mismatched_data_offset_length: 8785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.data_length = 16 * block_size - 8 8795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_prev_data_offset: 8805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.data_offset = prev_data_offset + 16 8815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 8825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.data_offset = prev_data_offset 8835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fake_data = 'fake-data'.ljust(op.data_length) 8855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if not (allow_unhashed or (is_last and allow_signature and 8865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op_type == common.OpType.REPLACE)): 8875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if not fail_data_hash: 8885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create a valid data blob hash. 8895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.data_sha256_hash = hashlib.sha256(fake_data).digest() 8905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload.ReadDataBlob(op.data_offset, op.data_length).AndReturn( 8915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fake_data) 8925502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold elif fail_data_hash: 8935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create an invalid data blob hash. 8945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.data_sha256_hash = hashlib.sha256( 8955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fake_data.replace(' ', '-')).digest() 8965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload.ReadDataBlob(op.data_offset, op.data_length).AndReturn( 8975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fake_data) 8985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 8995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold total_dst_blocks = 0 9005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if not fail_missing_dst_extents: 9015502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold total_dst_blocks = 16 9025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_dst_extents: 9035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 9045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((4, 16), (32, 0))) 9055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 9065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.AddToMessage(op.dst_extents, 9075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.NewExtentList((4, 8), (64, 8))) 9085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9095502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if total_src_blocks: 9105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_src_length: 9115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_length = total_src_blocks * block_size + 8 9125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 9135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_length = total_src_blocks * block_size 9145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold elif fail_src_length: 9155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add an orphaned src_length. 9165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.src_length = 16 9175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if total_dst_blocks: 9195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_dst_length: 9205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.dst_length = total_dst_blocks * block_size + 8 9215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 9225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op.dst_length = total_dst_blocks * block_size 9235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.mox.ReplayAll() 9255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold should_fail = (fail_src_extents or fail_dst_extents or 9265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_data_offset_length or 9275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_missing_dst_extents or fail_src_length or 9287cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood fail_dst_length or fail_data_hash or fail_prev_data_offset or 9297cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood fail_bad_minor_version) 930cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args = (op, 'foo', is_last, old_block_counters, new_block_counters, 931cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold old_part_size, new_part_size, prev_data_offset, allow_signature, 932cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold blob_hash_counts) 9335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if should_fail: 9345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 935cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold payload_checker._CheckOperation, *args) 9365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 937cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEqual(op.data_length if op.HasField('data_length') else 0, 938cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold payload_checker._CheckOperation(*args)) 9395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def testAllocBlockCounters(self): 9415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Tests _CheckMoveOperation().""" 9425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = checker.PayloadChecker(self.MockPayload()) 9435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold block_size = payload_checker.block_size 9445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Check allocation for block-aligned partition size, ensure it's integers. 9465502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold result = payload_checker._AllocBlockCounters(16 * block_size) 947cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEqual(16, len(result)) 948cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEqual(int, type(result[0])) 9495502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Check allocation of unaligned partition sizes. 9515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold result = payload_checker._AllocBlockCounters(16 * block_size - 1) 952cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEqual(16, len(result)) 9535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold result = payload_checker._AllocBlockCounters(16 * block_size + 1) 954cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEqual(17, len(result)) 9555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 956fb04d30e433eed1d7e7b78114c1a747c89091362Allie Wood def DoCheckOperationsTest(self, fail_nonexhaustive_full_update): 9575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Generate a test payload. For this test, we only care about one 9585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # (arbitrary) set of operations, so we'll only be generating kernel and 9595502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # test with them. 9605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen = test_utils.PayloadGenerator() 9615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 96218f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold block_size = test_utils.KiB(4) 9635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetBlockSize(block_size) 9645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 96518f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold rootfs_part_size = test_utils.MiB(8) 9665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9675502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Fake rootfs operations in a full update, tampered with as required. 9685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold rootfs_op_type = common.OpType.REPLACE 9695502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold rootfs_data_length = rootfs_part_size 9705502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_nonexhaustive_full_update: 9715502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold rootfs_data_length -= block_size 9725502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.AddOperation(False, rootfs_op_type, 9745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold dst_extents=[(0, rootfs_data_length / block_size)], 9755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold data_offset=0, 9765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold data_length=rootfs_data_length) 9775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Create the test object. 979eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold payload_checker = _GetPayloadChecker(payload_gen.WriteToFile, 980eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold checker_init_dargs={ 981eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'allow_unhashed': True}) 9825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker.payload_type = checker._TYPE_FULL 9835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold report = checker._PayloadReport() 9845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 985cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args = (payload_checker.payload.manifest.install_operations, report, 986cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold 'foo', 0, rootfs_part_size, rootfs_part_size, 0, False) 987fb04d30e433eed1d7e7b78114c1a747c89091362Allie Wood if fail_nonexhaustive_full_update: 9885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 989cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold payload_checker._CheckOperations, *args) 9905502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 991cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertEqual(rootfs_data_length, 992cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold payload_checker._CheckOperations(*args)) 9935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 9945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold def DoCheckSignaturesTest(self, fail_empty_sigs_blob, fail_missing_pseudo_op, 9955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_pseudo_op, fail_sig_missing_fields, 9965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_unknown_sig_version, fail_incorrect_sig): 9975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Generate a test payload. For this test, we only care about the signature 9985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # block and how it relates to the payload hash. Therefore, we're generating 9995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # a random (otherwise useless) payload for this purpose. 10005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen = test_utils.EnhancedPayloadGenerator() 100118f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold block_size = test_utils.KiB(4) 10025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetBlockSize(block_size) 100318f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold rootfs_part_size = test_utils.MiB(2) 100418f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold kernel_part_size = test_utils.KiB(16) 10055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetPartInfo(False, True, rootfs_part_size, 10065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold hashlib.sha256('fake-new-rootfs-content').digest()) 1007382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold payload_gen.SetPartInfo(True, True, kernel_part_size, 10085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold hashlib.sha256('fake-new-kernel-content').digest()) 10090d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_gen.SetMinorVersion(0) 10105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.AddOperationWithData( 10115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold False, common.OpType.REPLACE, 10125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold dst_extents=[(0, rootfs_part_size / block_size)], 10135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold data_blob=os.urandom(rootfs_part_size)) 10145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold do_forge_pseudo_op = (fail_missing_pseudo_op or fail_mismatched_pseudo_op) 10165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold do_forge_sigs_data = (do_forge_pseudo_op or fail_empty_sigs_blob or 10175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_sig_missing_fields or fail_unknown_sig_version 10185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold or fail_incorrect_sig) 10195502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10205502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sigs_data = None 10215502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if do_forge_sigs_data: 10225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sigs_gen = test_utils.SignaturesGenerator() 10235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if not fail_empty_sigs_blob: 10245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_sig_missing_fields: 10255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sig_data = None 10265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 10275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sig_data = test_utils.SignSha256('fake-payload-content', 102818f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold test_utils._PRIVKEY_FILE_NAME) 10295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sigs_gen.AddSig(5 if fail_unknown_sig_version else 1, sig_data) 10305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sigs_data = sigs_gen.ToBinary() 10325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetSignatures(payload_gen.curr_offset, len(sigs_data)) 10335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if do_forge_pseudo_op: 10355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold assert sigs_data is not None, 'should have forged signatures blob by now' 10365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold sigs_len = len(sigs_data) 10375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.AddOperation( 10385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold False, common.OpType.REPLACE, 10395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold data_offset=payload_gen.curr_offset / 2, 10405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold data_length=sigs_len / 2, 10415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold dst_extents=[(0, (sigs_len / 2 + block_size - 1) / block_size)]) 10425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Generate payload (complete w/ signature) and create the test object. 10445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker = _GetPayloadChecker( 1045eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold payload_gen.WriteToFileWithData, 1046eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold payload_gen_dargs={ 1047eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'sigs_data': sigs_data, 104818f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold 'privkey_file_name': test_utils._PRIVKEY_FILE_NAME, 1049eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'do_add_pseudo_operation': not do_forge_pseudo_op}) 10505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_checker.payload_type = checker._TYPE_FULL 10515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold report = checker._PayloadReport() 10525502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # We have to check the manifest first in order to set signature attributes. 1054382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold payload_checker._CheckManifest(report, rootfs_part_size, kernel_part_size) 10555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold should_fail = (fail_empty_sigs_blob or fail_missing_pseudo_op or 10575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_pseudo_op or fail_sig_missing_fields or 10585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_unknown_sig_version or fail_incorrect_sig) 1059cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold args = (report, test_utils._PUBKEY_FILE_NAME) 10605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if should_fail: 10615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold self.assertRaises(update_payload.PayloadError, 1062cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold payload_checker._CheckSignatures, *args) 10635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 1064cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertIsNone(payload_checker._CheckSignatures(*args)) 10655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 10660d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold def DoCheckManifestMinorVersionTest(self, minor_version, payload_type): 10670d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold """Parametric testing for CheckManifestMinorVersion(). 1068f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 1069f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood Args: 1070f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood minor_version: The payload minor version to test with. 1071f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood payload_type: The type of the payload we're testing, delta or full. 1072f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood """ 1073f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood # Create the test object. 10740d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload = self.MockPayload() 10750d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload.manifest.minor_version = minor_version 10760d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_checker = checker.PayloadChecker(payload) 10770d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_checker.payload_type = payload_type 1078f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood report = checker._PayloadReport() 1079f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 1080f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood should_succeed = ( 1081f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood (minor_version == 0 and payload_type == checker._TYPE_FULL) or 1082f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood (minor_version == 1 and payload_type == checker._TYPE_DELTA) or 1083912c4df6c4f470ddb6937b40cbe281229548783dSen Jiang (minor_version == 2 and payload_type == checker._TYPE_DELTA) or 108492161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang (minor_version == 3 and payload_type == checker._TYPE_DELTA) or 108592161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang (minor_version == 4 and payload_type == checker._TYPE_DELTA)) 10860d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold args = (report,) 1087f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 1088f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood if should_succeed: 10890d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold self.assertIsNone(payload_checker._CheckManifestMinorVersion(*args)) 1090f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood else: 1091f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood self.assertRaises(update_payload.PayloadError, 10920d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_checker._CheckManifestMinorVersion, *args) 1093f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 109406eea33088be4418264d12820f94c700977e3fa6Gilad Arnold def DoRunTest(self, rootfs_part_size_provided, kernel_part_size_provided, 109506eea33088be4418264d12820f94c700977e3fa6Gilad Arnold fail_wrong_payload_type, fail_invalid_block_size, 109606eea33088be4418264d12820f94c700977e3fa6Gilad Arnold fail_mismatched_block_size, fail_excess_data, 109706eea33088be4418264d12820f94c700977e3fa6Gilad Arnold fail_rootfs_part_size_exceeded, 109806eea33088be4418264d12820f94c700977e3fa6Gilad Arnold fail_kernel_part_size_exceeded): 10995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Generate a test payload. For this test, we generate a full update that 1100eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold # has sample kernel and rootfs operations. Since most testing is done with 11015502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # internal PayloadChecker methods that are tested elsewhere, here we only 11025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # tamper with what's actually being manipulated and/or tested in the Run() 11035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # method itself. Note that the checker doesn't verify partition hashes, so 11045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # they're safe to fake. 11055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen = test_utils.EnhancedPayloadGenerator() 110618f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold block_size = test_utils.KiB(4) 11075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.SetBlockSize(block_size) 110806eea33088be4418264d12820f94c700977e3fa6Gilad Arnold kernel_filesystem_size = test_utils.KiB(16) 110906eea33088be4418264d12820f94c700977e3fa6Gilad Arnold rootfs_filesystem_size = test_utils.MiB(2) 111006eea33088be4418264d12820f94c700977e3fa6Gilad Arnold payload_gen.SetPartInfo(False, True, rootfs_filesystem_size, 11115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold hashlib.sha256('fake-new-rootfs-content').digest()) 111206eea33088be4418264d12820f94c700977e3fa6Gilad Arnold payload_gen.SetPartInfo(True, True, kernel_filesystem_size, 11135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold hashlib.sha256('fake-new-kernel-content').digest()) 11140d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold payload_gen.SetMinorVersion(0) 111506eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 111606eea33088be4418264d12820f94c700977e3fa6Gilad Arnold rootfs_part_size = 0 111706eea33088be4418264d12820f94c700977e3fa6Gilad Arnold if rootfs_part_size_provided: 111806eea33088be4418264d12820f94c700977e3fa6Gilad Arnold rootfs_part_size = rootfs_filesystem_size + block_size 111906eea33088be4418264d12820f94c700977e3fa6Gilad Arnold rootfs_op_size = rootfs_part_size or rootfs_filesystem_size 112006eea33088be4418264d12820f94c700977e3fa6Gilad Arnold if fail_rootfs_part_size_exceeded: 112106eea33088be4418264d12820f94c700977e3fa6Gilad Arnold rootfs_op_size += block_size 11225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.AddOperationWithData( 11235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold False, common.OpType.REPLACE, 112406eea33088be4418264d12820f94c700977e3fa6Gilad Arnold dst_extents=[(0, rootfs_op_size / block_size)], 112506eea33088be4418264d12820f94c700977e3fa6Gilad Arnold data_blob=os.urandom(rootfs_op_size)) 112606eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 112706eea33088be4418264d12820f94c700977e3fa6Gilad Arnold kernel_part_size = 0 112806eea33088be4418264d12820f94c700977e3fa6Gilad Arnold if kernel_part_size_provided: 112906eea33088be4418264d12820f94c700977e3fa6Gilad Arnold kernel_part_size = kernel_filesystem_size + block_size 113006eea33088be4418264d12820f94c700977e3fa6Gilad Arnold kernel_op_size = kernel_part_size or kernel_filesystem_size 113106eea33088be4418264d12820f94c700977e3fa6Gilad Arnold if fail_kernel_part_size_exceeded: 113206eea33088be4418264d12820f94c700977e3fa6Gilad Arnold kernel_op_size += block_size 11335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold payload_gen.AddOperationWithData( 11345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold True, common.OpType.REPLACE, 113506eea33088be4418264d12820f94c700977e3fa6Gilad Arnold dst_extents=[(0, kernel_op_size / block_size)], 113606eea33088be4418264d12820f94c700977e3fa6Gilad Arnold data_blob=os.urandom(kernel_op_size)) 11375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 11385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Generate payload (complete w/ signature) and create the test object. 11395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if fail_invalid_block_size: 1140cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold use_block_size = block_size + 5 # Not a power of two. 11415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold elif fail_mismatched_block_size: 1142cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold use_block_size = block_size * 2 # Different that payload stated. 11435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 11445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold use_block_size = block_size 11455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1146cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold kwargs = { 1147eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'payload_gen_dargs': { 114818f4f9fab192e75a3477979c03a89381c35fd974Gilad Arnold 'privkey_file_name': test_utils._PRIVKEY_FILE_NAME, 1149eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'do_add_pseudo_operation': True, 1150eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'is_pseudo_in_kernel': True, 1151eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'padding': os.urandom(1024) if fail_excess_data else None}, 1152eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'checker_init_dargs': { 1153eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'assert_type': 'delta' if fail_wrong_payload_type else 'full', 1154eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold 'block_size': use_block_size}} 1155eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold if fail_invalid_block_size: 1156eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold self.assertRaises(update_payload.PayloadError, _GetPayloadChecker, 1157cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold payload_gen.WriteToFileWithData, **kwargs) 11585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold else: 1159eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold payload_checker = _GetPayloadChecker(payload_gen.WriteToFileWithData, 1160cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold **kwargs) 116106eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 116206eea33088be4418264d12820f94c700977e3fa6Gilad Arnold kwargs = {'pubkey_file_name': test_utils._PUBKEY_FILE_NAME, 116306eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 'rootfs_part_size': rootfs_part_size, 116406eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 'kernel_part_size': kernel_part_size} 1165eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold should_fail = (fail_wrong_payload_type or fail_mismatched_block_size or 116606eea33088be4418264d12820f94c700977e3fa6Gilad Arnold fail_excess_data or 116706eea33088be4418264d12820f94c700977e3fa6Gilad Arnold fail_rootfs_part_size_exceeded or 116806eea33088be4418264d12820f94c700977e3fa6Gilad Arnold fail_kernel_part_size_exceeded) 1169eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold if should_fail: 1170cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertRaises(update_payload.PayloadError, payload_checker.Run, 1171cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold **kwargs) 1172eaed0d1371d781d3f5effa1475f5202dea9467e7Gilad Arnold else: 1173cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold self.assertIsNone(payload_checker.Run(**kwargs)) 11745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 11755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# This implements a generic API, hence the occasional unused args. 11765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold# pylint: disable=W0613 11775502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnolddef ValidateCheckOperationTest(op_type_name, is_last, allow_signature, 11785502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold allow_unhashed, fail_src_extents, 11795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_dst_extents, 11805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_data_offset_length, 11815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_missing_dst_extents, fail_src_length, 11825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_dst_length, fail_data_hash, 11837cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood fail_prev_data_offset, fail_bad_minor_version): 11845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Returns True iff the combination of arguments represents a valid test.""" 11855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold op_type = _OpTypeByName(op_type_name) 11865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 11877cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood # REPLACE/REPLACE_BZ operations don't read data from src partition. They are 11887cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood # compatible with all valid minor versions, so we don't need to check that. 11895502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if (op_type in (common.OpType.REPLACE, common.OpType.REPLACE_BZ) and ( 11907cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood fail_src_extents or fail_src_length or fail_bad_minor_version)): 11915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return False 11925502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 1193f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood # MOVE and SOURCE_COPY operations don't carry data. 1194f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood if (op_type in (common.OpType.MOVE, common.OpType.SOURCE_COPY) and ( 11955502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_mismatched_data_offset_length or fail_data_hash or 11965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold fail_prev_data_offset)): 11975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return False 11985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 11995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return True 12005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12015502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnolddef TestMethodBody(run_method_name, run_dargs): 12035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Returns a function that invokes a named method with named arguments.""" 12045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold return lambda self: getattr(self, run_method_name)(**run_dargs) 12055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12065502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12075502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnolddef AddParametricTests(tested_method_name, arg_space, validate_func=None): 12085502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Enumerates and adds specific parametric tests to PayloadCheckerTest. 12095502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12105502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold This function enumerates a space of test parameters (defined by arg_space), 12115502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold then binds a new, unique method name in PayloadCheckerTest to a test function 12125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold that gets handed the said parameters. This is a preferable approach to doing 12135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold the enumeration and invocation during the tests because this way each test is 12145502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold treated as a complete run by the unittest framework, and so benefits from the 12155502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold usual setUp/tearDown mechanics. 12165502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold Args: 1218cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold tested_method_name: Name of the tested PayloadChecker method. 1219cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold arg_space: A dictionary containing variables (keys) and lists of values 1220cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold (values) associated with them. 1221cb638915dbc2e0898b0562c98019c077d7fc1e8aGilad Arnold validate_func: A function used for validating test argument combinations. 12225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """ 12235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold for value_tuple in itertools.product(*arg_space.itervalues()): 12245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold run_dargs = dict(zip(arg_space.iterkeys(), value_tuple)) 12255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if validate_func and not validate_func(**run_dargs): 12265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold continue 12275502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold run_method_name = 'Do%sTest' % tested_method_name 12285502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold test_method_name = 'test%s' % tested_method_name 12295502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold for arg_key, arg_val in run_dargs.iteritems(): 12305502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold if arg_val or type(arg_val) is int: 12315502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold test_method_name += '__%s=%s' % (arg_key, arg_val) 12325502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold setattr(PayloadCheckerTest, test_method_name, 12335502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold TestMethodBody(run_method_name, run_dargs)) 12345502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12355502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12365502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnolddef AddAllParametricTests(): 12375502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold """Enumerates and adds all parametric tests to PayloadCheckerTest.""" 12385502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all _CheckElem() test cases. 12395502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('AddElem', 12405502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold {'linebreak': (True, False), 12415502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'indent': (0, 1, 2), 12425502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'convert': (str, lambda s: s[::-1]), 12435502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'is_present': (True, False), 12445502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'is_mandatory': (True, False), 12455502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'is_submsg': (True, False)}) 12465502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12475502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all _Add{Mandatory,Optional}Field tests. 12485502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('AddField', 12495502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold {'is_mandatory': (True, False), 12505502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'linebreak': (True, False), 12515502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'indent': (0, 1, 2), 12525502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'convert': (str, lambda s: s[::-1]), 12535502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'is_present': (True, False)}) 12545502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12555502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all _Add{Mandatory,Optional}SubMsg tests. 12565502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('AddSubMsg', 12575502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold {'is_mandatory': (True, False), 12585502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'is_present': (True, False)}) 12595502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12605502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all _CheckManifest() test cases. 12615502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('CheckManifest', 12625502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold {'fail_mismatched_block_size': (True, False), 12635502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_bad_sigs': (True, False), 12645502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_mismatched_oki_ori': (True, False), 12655502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_bad_oki': (True, False), 12665502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_bad_ori': (True, False), 12675502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_bad_nki': (True, False), 12685502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_bad_nri': (True, False), 1269382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold 'fail_old_kernel_fs_size': (True, False), 1270382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold 'fail_old_rootfs_fs_size': (True, False), 1271382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold 'fail_new_kernel_fs_size': (True, False), 1272382df5ce2f4b67bf0998b01c6fedcdb5c35ebef9Gilad Arnold 'fail_new_rootfs_fs_size': (True, False)}) 12735502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12745502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all _CheckOperation() test cases. 12755502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('CheckOperation', 12765502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold {'op_type_name': ('REPLACE', 'REPLACE_BZ', 'MOVE', 1277f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 'BSDIFF', 'SOURCE_COPY', 1278f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 'SOURCE_BSDIFF'), 12795502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'is_last': (True, False), 12805502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'allow_signature': (True, False), 12815502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'allow_unhashed': (True, False), 12825502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_src_extents': (True, False), 12835502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_dst_extents': (True, False), 12845502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_mismatched_data_offset_length': (True, False), 12855502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_missing_dst_extents': (True, False), 12865502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_src_length': (True, False), 12875502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_dst_length': (True, False), 12885502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_data_hash': (True, False), 12897cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood 'fail_prev_data_offset': (True, False), 12907cf9f13f2715d0a033c6300a244b40302d8eb7b7Allie Wood 'fail_bad_minor_version': (True, False)}, 12915502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold validate_func=ValidateCheckOperationTest) 12925502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12935502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all _CheckOperations() test cases. 12945502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('CheckOperations', 1295fb04d30e433eed1d7e7b78114c1a747c89091362Allie Wood {'fail_nonexhaustive_full_update': (True, False)}) 12965502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 12975502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all _CheckOperations() test cases. 12985502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('CheckSignatures', 12995502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold {'fail_empty_sigs_blob': (True, False), 13005502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_missing_pseudo_op': (True, False), 13015502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_mismatched_pseudo_op': (True, False), 13025502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_sig_missing_fields': (True, False), 13035502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_unknown_sig_version': (True, False), 13045502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_incorrect_sig': (True, False)}) 13055502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 13060d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold # Add all _CheckManifestMinorVersion() test cases. 13070d575cde18a1b44e386181dc1abbc611b9ae7a59Gilad Arnold AddParametricTests('CheckManifestMinorVersion', 130892161a7b83c3a491871a167a4d46e4e6b6101e81Sen Jiang {'minor_version': (None, 0, 1, 2, 3, 4, 555), 1309f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 'payload_type': (checker._TYPE_FULL, 1310f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood checker._TYPE_DELTA)}) 1311f5c4f3e2a6e7c93e5b4c09272091f23a935fab86Allie Wood 13125502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold # Add all Run() test cases. 13135502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddParametricTests('Run', 131406eea33088be4418264d12820f94c700977e3fa6Gilad Arnold {'rootfs_part_size_provided': (True, False), 131506eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 'kernel_part_size_provided': (True, False), 131606eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 'fail_wrong_payload_type': (True, False), 13175502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_invalid_block_size': (True, False), 13185502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 'fail_mismatched_block_size': (True, False), 131906eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 'fail_excess_data': (True, False), 132006eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 'fail_rootfs_part_size_exceeded': (True, False), 132106eea33088be4418264d12820f94c700977e3fa6Gilad Arnold 'fail_kernel_part_size_exceeded': (True, False)}) 13225502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 13235502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold 13245502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnoldif __name__ == '__main__': 13255502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold AddAllParametricTests() 13265502b56f34f9703cf053be46e4ea5685c0c9ac26Gilad Arnold unittest.main() 1327