blob: 0246908e8eb896181310be2c875312c2659a355e [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unittests for trigger_cr50_signing.py."""
from __future__ import print_function
import json
import sys
import mock
from chromite.scripts import trigger_cr50_signing as trigger
from chromite.api.gen.chromiumos import common_pb2
from chromite.api.gen.chromiumos import sign_image_pb2
from chromite.lib import cros_logging as logging
from chromite.lib import cros_test_lib
assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
# pylint: disable=protected-access
class TestLaunchOne(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for the LaunchOne function."""
def setUp(self):
self.log_info = self.PatchObject(logging, 'info')
self.properties = {'keyset': 'test-keyest'}
self.json_prop = json.dumps(self.properties)
def testDryRunOnlyLogs(self):
"""Test that dry_run=True results in only a log message."""
trigger.LaunchOne(True, 'chromeos/packaging/test', self.properties)
self.assertEqual(0, self.rc.call_count)
self.log_info.assert_called_once()
def testCallsRun(self):
"""Test that dry_run=False calls run()."""
trigger.LaunchOne(False, 'chromeos/packaging/test', self.properties)
self.log_info.assert_not_called()
self.assertEqual(
[mock.call(
['bb', 'add', '-p', '@/dev/stdin', 'chromeos/packaging/test'],
input=self.json_prop, log_output=True)],
self.rc.call_args_list)
class TestMain(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for the main function."""
def setUp(self):
self.log_error = self.PatchObject(logging, 'error')
def testMinimal(self):
"""Test minimal instructions."""
launch = self.PatchObject(trigger, 'LaunchOne')
args = ['--archive', 'gs://test/file.bin', '--keyset', 'test-keyset']
self.assertEqual(0, trigger.main(args))
launch.assert_called_once_with(
False, trigger.CR50_PRODUCTION_JOB, {
'archive': 'gs://test/file.bin',
'build_target': {'name': 'unknown'},
'channel': common_pb2.CHANNEL_UNSPECIFIED,
'cr50_instructions': {
'target': sign_image_pb2.Cr50Instructions.PREPVT},
'image_type': common_pb2.CR50_FIRMWARE,
'keyset': 'test-keyset',
'signer_type': sign_image_pb2.SIGNER_PRODUCTION})
def testPropertiesCorrect(self):
"""Test minimal instructions."""
launch = self.PatchObject(trigger, 'LaunchOne')
archive = 'gs://test/file.bin'
keyset = 'keyset'
channel = 'canary'
build_target = 'board'
target = 'prepvt'
signer = 'production'
image = 'cr50_firmware'
args = ['--archive', archive, '--keyset', keyset, '--channel', channel,
'--build-target', build_target, '--target', target,
'--signer-type', signer, '--image-type', image]
self.assertEqual(0, trigger.main(args))
launch.assert_called_once_with(
False, trigger.CR50_PRODUCTION_JOB, {
'archive': archive,
'build_target': {'name': build_target},
'channel': trigger._channels[channel],
'cr50_instructions': {'target': trigger._target_types[target]},
'image_type': trigger._image_types[image],
'keyset': keyset,
'signer_type': trigger._signer_types[signer]})
def testStaging(self):
"""Test --staging works."""
launch = self.PatchObject(trigger, 'LaunchOne')
args = ['--archive', 'gs://test/file.bin', '--keyset', 'test-keyset',
'--staging']
self.assertEqual(0, trigger.main(args))
launch.assert_called_once_with(
False, trigger.CR50_STAGING_JOB, {
'archive': 'gs://test/file.bin',
'build_target': {'name': 'unknown'},
'channel': common_pb2.CHANNEL_UNSPECIFIED,
'cr50_instructions': {
'target': sign_image_pb2.Cr50Instructions.PREPVT},
'image_type': common_pb2.CR50_FIRMWARE,
'keyset': 'test-keyset',
'signer_type': sign_image_pb2.SIGNER_PRODUCTION})
def testDryRun(self):
"""Test --dry-run works."""
launch = self.PatchObject(trigger, 'LaunchOne')
args = ['--archive', 'gs://test/file.bin', '--keyset', 'test-keyset',
'--dry-run']
self.assertEqual(0, trigger.main(args))
launch.assert_called_once_with(
True, trigger.CR50_PRODUCTION_JOB, {
'archive': 'gs://test/file.bin',
'build_target': {'name': 'unknown'},
'channel': common_pb2.CHANNEL_UNSPECIFIED,
'cr50_instructions': {
'target': sign_image_pb2.Cr50Instructions.PREPVT},
'image_type': common_pb2.CR50_FIRMWARE,
'keyset': 'test-keyset',
'signer_type': sign_image_pb2.SIGNER_PRODUCTION})
def testNodeLockedCatchesBadDeviceId(self):
"""Test --target node_locked catches bad --device-id."""
launch = self.PatchObject(trigger, 'LaunchOne')
args = ['--archive', 'gs://test/file.bin', '--keyset', 'test-keyset',
'--target', 'node_locked', '--device-id', '12345678-9ABCDEFG',
'--dev01', '-1', '0x1234']
self.assertEqual(1, trigger.main(args))
launch.assert_not_called()
self.assertEqual(1, self.log_error.call_count)
def testNodeLockedRequiresDeviceId(self):
"""Test --target node_locked requires --device-id."""
launch = self.PatchObject(trigger, 'LaunchOne')
args = ['--archive', 'gs://test/file.bin', '--keyset', 'test-keyset',
'--target', 'node_locked']
self.assertEqual(1, trigger.main(args))
launch.assert_not_called()
self.assertEqual(1, self.log_error.call_count)
def testDeviceIdRequiresNodeLocked(self):
"""Test --device_id is rejected if not node_locked."""
launch = self.PatchObject(trigger, 'LaunchOne')
args = ['--archive', 'gs://test/file.bin', '--keyset', 'test-keyset',
'--target', 'general_release', '--dev01', '1', '0x1234']
self.assertEqual(1, trigger.main(args))
launch.assert_not_called()
self.assertEqual(1, self.log_error.call_count)
def testNodeLockedLaunchesMultiple(self):
"""Test --target node_locked launches multiple jobs."""
# Do not mock LaunchOne, so that we can grab the input= passed to run().
args = ['--archive', 'gs://test/file.bin', '--keyset', 'test-keyset',
'--target', 'node_locked', '--dev01', '1', '0x1234',
'--dev01', '2', '33']
self.assertEqual(0, trigger.main(args))
self.log_error.assert_not_called()
expected_properties = [
{'archive': 'gs://test/file.bin', 'build_target': {'name': 'unknown'},
'channel': 0,
'cr50_instructions': {'target': trigger._target_types['node_locked'],
'device_id': '00000001-00001234'},
'signer_type': sign_image_pb2.SIGNER_PRODUCTION,
'image_type': common_pb2.CR50_FIRMWARE, 'keyset': 'test-keyset'},
{'archive': 'gs://test/file.bin', 'build_target': {'name': 'unknown'},
'channel': 0,
'cr50_instructions': {'target': trigger._target_types['node_locked'],
'device_id': '00000002-00000021'},
'signer_type': sign_image_pb2.SIGNER_PRODUCTION,
'image_type': common_pb2.CR50_FIRMWARE, 'keyset': 'test-keyset'}]
# Check the calls in two parts, since we need to convert the json string
# back to a dict.
self.assertEqual(self.rc.call_args_list, [
mock.call(
['bb', 'add', '-p', '@/dev/stdin', trigger.CR50_PRODUCTION_JOB],
log_output=True, input=mock.ANY) for _ in expected_properties])
self.assertEqual(
expected_properties,
[json.loads(x[1]['input']) for x in self.rc.call_args_list])