blob: 61c40a06efce9b4072a9c8c3a145c8b32726351b [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 mock
from chromite.scripts import trigger_cr50_signing as trigger
from chromite.lib import cros_logging as logging
from chromite.lib import cros_test_lib
# 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': 0,
'cr50_instructions': {'target': 0},
'image_type': 9,
'keyset': 'test-keyset',
'signer_type': 1})
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': 0,
'cr50_instructions': {'target': 0},
'image_type': 9,
'keyset': 'test-keyset',
'signer_type': 1})
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': 0,
'cr50_instructions': {'target': 0},
'image_type': 9,
'keyset': 'test-keyset',
'signer_type': 1})
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()
self.assertEqual(self.rc.call_args_list, [
mock.call(
['bb', 'add', '-p', '@/dev/stdin', 'chromeos/packaging/sign-image'],
log_output=True,
input='{"cr50_instructions": {'
'"target": 3, "device_id": "00000001-00001234"}, '
'"image_type": 9, "keyset": "test-keyset", "signer_type": 1, '
'"build_target": {"name": "unknown"}, '
'"archive": "gs://test/file.bin", "channel": 0}'),
mock.call(
['bb', 'add', '-p', '@/dev/stdin', 'chromeos/packaging/sign-image'],
log_output=True,
input='{"cr50_instructions": {'
'"target": 3, "device_id": "00000002-00000021"}, '
'"image_type": 9, "keyset": "test-keyset", "signer_type": 1, '
'"build_target": {"name": "unknown"}, '
'"archive": "gs://test/file.bin", "channel": 0}')])