# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for build stages."""

from unittest import mock

from chromite.cbuildbot import cbuildbot_unittest
from chromite.cbuildbot.stages import generic_stages_unittest
from chromite.cbuildbot.stages import release_stages
from chromite.cbuildbot.stages.generic_stages_unittest import patch
from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import failures_lib
from chromite.lib import parallel
from chromite.lib import parallel_unittest
from chromite.lib import results_lib
from chromite.lib import timeout_util
from chromite.lib.buildstore import FakeBuildStore
from chromite.lib.paygen import gspaths
from chromite.lib.paygen import paygen_build_lib


# pylint: disable=protected-access


class SigningStageTest(
    generic_stages_unittest.AbstractStageTestCase,
    cbuildbot_unittest.SimpleBuilderTestCase,
):
    """Test the SigningStage."""

    RELEASE_TAG = "0.0.1"

    SIGNER_RESULT = """
    { "status": { "status": "passed" }, "board": "link",
    "keyset": "link-mp-v4", "type": "recovery", "channel": "stable" }
    """

    INSNS_URLS_PER_CHANNEL = {
        "chan1": ["chan1_uri1", "chan1_uri2"],
        "chan2": ["chan2_uri1"],
    }

    def setUp(self):
        self._Prepare()
        self.buildstore = FakeBuildStore()

    def ConstructStage(self):
        return release_stages.SigningStage(
            self._run, self.buildstore, self._current_board
        )

    def testWaitForPushImageSuccess(self):
        """Test waiting for input from PushImage."""
        stage = self.ConstructStage()
        stage.board_runattrs.SetParallel(
            "instruction_urls_per_channel", self.INSNS_URLS_PER_CHANNEL
        )

        self.assertEqual(stage.WaitUntilReady(), True)
        self.assertEqual(
            stage.instruction_urls_per_channel, self.INSNS_URLS_PER_CHANNEL
        )

    def testWaitForPushImageError(self):
        """Test WaitForPushImageError with an error output from pushimage."""
        stage = self.ConstructStage()
        stage.board_runattrs.SetParallel("instruction_urls_per_channel", None)

        self.assertEqual(stage.WaitUntilReady(), False)

    def testWaitForSigningResultsSuccess(self):
        """Test that _WaitForSigningResults works when signing works."""
        results = ["chan1_uri1.json", "chan1_uri2.json", "chan2_uri1.json"]

        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.return_value = self.SIGNER_RESULT
            notifier = mock.Mock()

            stage = self.ConstructStage()
            stage._WaitForSigningResults(self.INSNS_URLS_PER_CHANNEL, notifier)

            self.assertEqual(
                notifier.mock_calls, [mock.call("chan1"), mock.call("chan2")]
            )

            for result in results:
                mock_gs_ctx.Cat.assert_any_call(result)

    def testWaitForSigningResultsSuccessNoNotifier(self):
        """Test that _WaitForSigningResults works when signing works."""
        results = ["chan1_uri1.json", "chan1_uri2.json", "chan2_uri1.json"]

        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.return_value = self.SIGNER_RESULT

            stage = self.ConstructStage()
            stage._WaitForSigningResults(self.INSNS_URLS_PER_CHANNEL, None)

            for result in results:
                mock_gs_ctx.Cat.assert_any_call(result)

    def testWaitForSigningResultsSuccessNothingSigned(self):
        """Test _WaitForSigningResults when there are no signed images."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.return_value = self.SIGNER_RESULT
            notifier = mock.Mock()

            stage = self.ConstructStage()
            stage._WaitForSigningResults({}, notifier)

            self.assertEqual(notifier.mock_calls, [])
            self.assertEqual(mock_gs_ctx.Cat.mock_calls, [])

    def testWaitForSigningResultsFailure(self):
        """Test _WaitForSigningResults when the signers report an error."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.return_value = """
          { "status": { "status": "failed" }, "board": "link",
            "keyset": "link-mp-v4", "type": "recovery", "channel": "stable" }
          """
            notifier = mock.Mock()

            stage = self.ConstructStage()

            self.assertRaisesStringifyable(
                release_stages.SignerFailure,
                stage._WaitForSigningResults,
                {"chan1": ["chan1_uri1"]},
                notifier,
            )

            # Ensure we didn't notify anyone of success.
            self.assertEqual(notifier.mock_calls, [])
            self.assertEqual(
                mock_gs_ctx.Cat.mock_calls, [mock.call("chan1_uri1.json")]
            )

    def testWaitForSigningResultsTimeout(self):
        """Test that _WaitForSigningResults reports timeouts correctly."""
        with patch(release_stages.timeout_util, "WaitForSuccess") as mock_wait:
            mock_wait.side_effect = timeout_util.TimeoutError
            notifier = mock.Mock()

            stage = self.ConstructStage()

            self.assertRaises(
                release_stages.SignerResultsTimeout,
                stage._WaitForSigningResults,
                {"chan1": ["chan1_uri1"]},
                notifier,
            )

            self.assertEqual(notifier.mock_calls, [])

    def testCheckForResultsSuccess(self):
        """Test that _CheckForResults works when signing works."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.return_value = self.SIGNER_RESULT
            notifier = mock.Mock()

            stage = self.ConstructStage()
            self.assertTrue(
                stage._CheckForResults(
                    mock_gs_ctx, self.INSNS_URLS_PER_CHANNEL, notifier
                )
            )
            self.assertEqual(
                notifier.mock_calls, [mock.call("chan1"), mock.call("chan2")]
            )

    def testCheckForResultsSuccessNoChannels(self):
        """Test that _CheckForResults works when there is nothing to check for."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            notifier = mock.Mock()

            stage = self.ConstructStage()

            # Ensure we find that we are ready if there are no channels to look for.
            self.assertTrue(stage._CheckForResults(mock_gs_ctx, {}, notifier))

            # Ensure we didn't contact GS while checking for no channels.
            self.assertFalse(mock_gs_ctx.Cat.called)
            self.assertEqual(notifier.mock_calls, [])

    def testCheckForResultsPartialComplete(self):
        """Verify _CheckForResults handles partial signing results."""

        def catChan2Success(url):
            if url.startswith("chan2"):
                return self.SIGNER_RESULT
            else:
                raise release_stages.gs.GSNoSuchKey()

        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.side_effect = catChan2Success
            notifier = mock.Mock()

            stage = self.ConstructStage()
            self.assertFalse(
                stage._CheckForResults(
                    mock_gs_ctx, self.INSNS_URLS_PER_CHANNEL, notifier
                )
            )
            self.assertEqual(
                stage.signing_results,
                {
                    "chan1": {},
                    "chan2": {
                        "chan2_uri1.json": {
                            "board": "link",
                            "channel": "stable",
                            "keyset": "link-mp-v4",
                            "status": {"status": "passed"},
                            "type": "recovery",
                        }
                    },
                },
            )
            self.assertEqual(notifier.mock_calls, [mock.call("chan2")])

    def testCheckForResultsUnexpectedJson(self):
        """Verify _CheckForResults handles unexpected Json values."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.return_value = "{}"
            notifier = mock.Mock()

            stage = self.ConstructStage()
            self.assertFalse(
                stage._CheckForResults(
                    mock_gs_ctx, self.INSNS_URLS_PER_CHANNEL, notifier
                )
            )
            self.assertEqual(stage.signing_results, {"chan1": {}, "chan2": {}})
            self.assertEqual(notifier.mock_calls, [])

    def testCheckForResultsMalformedJson(self):
        """Verify _CheckForResults handles unexpected Json values."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.return_value = "{"
            notifier = mock.Mock()

            stage = self.ConstructStage()
            self.assertFalse(
                stage._CheckForResults(
                    mock_gs_ctx, self.INSNS_URLS_PER_CHANNEL, notifier
                )
            )
            self.assertEqual(stage.signing_results, {"chan1": {}, "chan2": {}})
            self.assertEqual(notifier.mock_calls, [])

    def testCheckForResultsNoResult(self):
        """Verify _CheckForResults handles missing signer results."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.side_effect = release_stages.gs.GSNoSuchKey
            notifier = mock.Mock()

            stage = self.ConstructStage()
            self.assertFalse(
                stage._CheckForResults(
                    mock_gs_ctx, self.INSNS_URLS_PER_CHANNEL, notifier
                )
            )
            self.assertEqual(stage.signing_results, {"chan1": {}, "chan2": {}})
            self.assertEqual(notifier.mock_calls, [])

    def testCheckForResultsFailed(self):
        """Verify _CheckForResults handles missing signer results."""
        with patch(release_stages.gs, "GSContext") as mock_gs_ctx_init:
            mock_gs_ctx = mock_gs_ctx_init.return_value
            mock_gs_ctx.Cat.side_effect = release_stages.gs.GSNoSuchKey
            notifier = mock.Mock()

            stage = self.ConstructStage()
            self.assertFalse(
                stage._CheckForResults(
                    mock_gs_ctx, self.INSNS_URLS_PER_CHANNEL, notifier
                )
            )
            self.assertEqual(stage.signing_results, {"chan1": {}, "chan2": {}})
            self.assertEqual(notifier.mock_calls, [])

    def testPerformStageSuccess(self):
        """Test that SigningStage works when signing works."""
        stage = self.ConstructStage()
        stage.instruction_urls_per_channel = self.INSNS_URLS_PER_CHANNEL
        self.PatchObject(stage, "_WaitForSigningResults")

        stage.PerformStage()

        # Verify that we send the right notifications.
        result = stage.board_runattrs.GetParallel(
            "signed_images_ready", timeout=0
        )
        self.assertEqual(result, ["chan1", "chan2"])


class PaygenStageTest(
    generic_stages_unittest.AbstractStageTestCase,
    cbuildbot_unittest.SimpleBuilderTestCase,
):
    """Test the PaygenStage Stage."""

    # We use a variant board to make sure the '_' is translated to '-'.
    BOT_ID = "beaglebone_servo-release"
    RELEASE_TAG = "0.0.1"

    def setUp(self):
        self._Prepare()
        self.buildstore = FakeBuildStore()

        # This method fetches a file from GS, mock it out.
        self.validateMock = self.PatchObject(
            paygen_build_lib, "ValidateBoardConfig"
        )

        instanceMock = mock.MagicMock()
        self.paygenBuildMock = self.PatchObject(
            paygen_build_lib, "PaygenBuild", return_value=instanceMock
        )

        self.payload_config1 = mock.MagicMock()
        self.payload_config1.payload_type = paygen_build_lib.PAYLOAD_TYPE_FSI
        self.payload_config1.applicable_models = ["model1", "model3"]
        self.payload_config2 = mock.MagicMock()
        self.payload_config2.payload_type = paygen_build_lib.PAYLOAD_TYPE_OMAHA
        self.payload_config2.applicable_models = ["model2", "model3"]
        self.payload_config3 = mock.MagicMock()
        self.payload_config3.payload_type = paygen_build_lib.PAYLOAD_TYPE_OMAHA
        self.payload_config4 = mock.MagicMock()
        self.payload_config4.payload_type = paygen_build_lib.PAYLOAD_TYPE_N2N
        self.payload_config5 = mock.MagicMock()
        self.payload_config5.payload_type = (
            paygen_build_lib.PAYLOAD_TYPE_STEPPING_STONE
        )

        instanceMock.CreatePayloads.side_effect = iter(
            [
                (
                    "foo-suite-name",
                    "foo-archive-board",
                    "foo-archive-build",
                    [
                        self.payload_config1,
                        self.payload_config2,
                        self.payload_config3,
                        self.payload_config4,
                        self.payload_config5,
                    ],
                )
            ]
        )

    # pylint: disable=arguments-differ
    def ConstructStage(self, channels=None):
        return release_stages.PaygenStage(
            self._run, self.buildstore, self._current_board, channels=channels
        )

    def testWaitUntilReadSigning(self):
        """Test that PaygenStage works when signing works."""
        stage = self.ConstructStage()
        stage.board_runattrs.SetParallel(
            "signed_images_ready", ["stable", "beta"]
        )

        self.assertEqual(stage.WaitUntilReady(), True)
        self.assertEqual(stage.channels, ["stable", "beta"])

    def testWaitUntilReadSigningFailure(self):
        """Test that PaygenStage works when signing works."""
        stage = self.ConstructStage()
        stage.board_runattrs.SetParallel("signed_images_ready", None)

        self.assertEqual(stage.WaitUntilReady(), False)

    def testWaitUntilReadSigningEmpty(self):
        """Test that PaygenStage works when signing works."""
        stage = self.ConstructStage()
        stage.board_runattrs.SetParallel("signed_images_ready", [])

        self.assertEqual(stage.WaitUntilReady(), True)
        self.assertEqual(stage.channels, [])

    def testPerformStageSuccess(self):
        """Test that PaygenStage works when signing works."""
        with patch(release_stages.PaygenStage, "_RunPaygenInProcess") as runner:
            channels = ["stable", "beta"]
            stage = self.ConstructStage(channels=channels)

            with parallel_unittest.ParallelMock():
                stage.PerformStage()

            metadata_channels = self._run.attrs.metadata.GetValue("channels")
            self.assertEqual(",".join(channels), metadata_channels)

            # Verify that we validate with the board name in release name space.
            self.assertEqual(
                self.validateMock.call_args_list,
                [mock.call("beaglebone-servo")],
            )

            # Verify that we queue up work.
            runner.assert_has_calls(
                [
                    mock.call(
                        stage,
                        "stable",
                        "beaglebone-servo",
                        "0.0.1",
                        False,
                        False,
                        False,
                    ),
                    mock.call(
                        stage,
                        "beta",
                        "beaglebone-servo",
                        "0.0.1",
                        False,
                        False,
                        False,
                    ),
                ]
            )

    def testPerformStageNoChannels(self):
        """Test that PaygenStage works when signing works."""
        with patch(release_stages.PaygenStage, "_RunPaygenInProcess") as runner:
            stage = self.ConstructStage(channels=[])

            with parallel_unittest.ParallelMock():
                stage.PerformStage()

            # Verify that we did not queue up work.
            runner.assert_not_called()

    def testPerformStageTrybot(self):
        """Test the PerformStage alternate behavior for trybot runs."""
        with patch(release_stages.PaygenStage, "_RunPaygenInProcess") as runner:
            # The stage is constructed differently for trybots, so don't use
            # ConstructStage.
            stage = self.ConstructStage(channels=["foo", "bar"])
            with parallel_unittest.ParallelMock():
                stage.PerformStage()

            # Notice that we didn't put anything in _wait_for_channel_signing, but
            # still got results right away.
            runner.assert_has_calls(
                [
                    mock.call(
                        stage,
                        "foo",
                        "beaglebone-servo",
                        "0.0.1",
                        False,
                        False,
                        False,
                    ),
                    mock.call(
                        stage,
                        "bar",
                        "beaglebone-servo",
                        "0.0.1",
                        False,
                        False,
                        False,
                    ),
                ]
            )

    def testPerformStageUnknownBoard(self):
        """Test that PaygenStage exits when an unknown board is specified."""
        self._current_board = "unknown-board-name"

        # Setup a board validation failure.
        badBoardException = paygen_build_lib.BoardNotConfigured(
            self._current_board
        )
        self.validateMock.side_effect = badBoardException

        stage = self.ConstructStage()

        with self.assertRaises(release_stages.PaygenNoPaygenConfigForBoard):
            stage.PerformStage()

    def testRunPaygenInProcess(self):
        """Test that _RunPaygenInProcess works in the simple case."""
        # Have to patch and verify that the PaygenTestStage is created.
        stage = self.ConstructStage()

        with patch(paygen_build_lib, "ScheduleAutotestTests") as sched_tests:
            # Call the method under test.
            stage._RunPaygenInProcess(
                "foo", "foo-board", "foo-version", True, False, False
            )
            # Ensure that PaygenTestStage is created and schedules the test suite
            # with the correct arguments.
            sched_tests.assert_called_once_with(
                "foo-suite-name",
                "foo-archive-board",
                None,
                "foo-archive-build",
                [
                    self.payload_config1,
                    self.payload_config2,
                    self.payload_config3,
                    self.payload_config4,
                    self.payload_config5,
                ],
            )

        # Ensure arguments are properly converted and passed along.
        self.paygenBuildMock.assert_called_with(
            gspaths.Build(
                version="foo-version",
                board="foo-board",
                channel="foo-channel",
                bucket=gspaths.ChromeosReleases.BUCKET,
            ),
            mock.ANY,
            work_dir=mock.ANY,
            site_config=stage._run.site_config,
            dry_run=True,
            skip_delta_payloads=False,
        )

    def testRunPaygenInProcessInSkylab(self):
        """Test that _RunPaygenInProcess works in Skylab."""
        self._run.config.enable_skylab_hw_tests = True
        # Have to patch and verify that the PaygenTestStage is created.
        stage = self.ConstructStage()

        with patch(paygen_build_lib, "ScheduleAutotestTests") as sched_tests:
            # Call the method under test.
            stage._RunPaygenInProcess(
                "foo", "foo-board", "foo-version", True, False, False
            )
            # Ensure that PaygenTestStage is created and schedules the test suite
            # with the correct arguments.
            sched_tests.assert_called_once_with(
                "foo-suite-name",
                "foo-archive-board",
                None,
                "foo-archive-build",
                [
                    self.payload_config1,
                    self.payload_config2,
                    self.payload_config3,
                    self.payload_config4,
                    self.payload_config5,
                ],
            )

    def testRunPaygenInProcessComplex(self):
        """Test that _RunPaygenInProcess with arguments that are more unusual."""
        # Call the method under test.
        # Use release tools channel naming, and a board name including a variant.
        stage = self.ConstructStage()
        stage._RunPaygenInProcess(
            "foo-channel", "foo-board-variant", "foo-version", True, True, True
        )

        # Ensure arguments are properly converted and passed along.
        self.paygenBuildMock.assert_called_with(
            gspaths.Build(
                version="foo-version",
                board="foo-board-variant",
                channel="foo-channel",
                bucket=gspaths.ChromeosReleases.BUCKET,
            ),
            mock.ANY,
            dry_run=True,
            work_dir=mock.ANY,
            site_config=stage._run.site_config,
            skip_delta_payloads=True,
        )

    def testRunPaygenInProcessWithUnifiedBuild(self):
        self._run.config.models = [
            config_lib.ModelTestConfig("model1", "model1"),
            config_lib.ModelTestConfig("model2", "board", ["au"]),
        ]

        # Have to patch and verify that the PaygenTestStage is created.
        stage = self.ConstructStage()

        with patch(paygen_build_lib, "ScheduleAutotestTests") as sched_tests:
            # Call the method under test.
            stage._RunPaygenInProcess(
                "foo", "foo-board", "foo-version", True, False, False
            )
            # Ensure that the first model from the unified build was selected
            # as the platform to be tested
            sched_tests.assert_called_once_with(
                "foo-suite-name",
                "board",
                "model2",
                "foo-archive-build",
                [
                    self.payload_config1,
                    self.payload_config2,
                    self.payload_config3,
                    self.payload_config4,
                    self.payload_config5,
                ],
            )

    def testRunPaygenInProcessWithUnifiedBuildInSkylab(self):
        """Test that _RunPaygenInProcess works for unibuild in Skylab."""
        self._run.config.enable_skylab_hw_tests = True
        self._run.config.models = [
            config_lib.ModelTestConfig(
                "model2", "board", ["au"], enable_skylab=True
            ),
        ]

        # Have to patch and verify that the PaygenTestStage is created.
        stage = self.ConstructStage()

        with patch(paygen_build_lib, "ScheduleAutotestTests") as sched_tests:
            # Call the method under test.
            stage._RunPaygenInProcess(
                "foo", "foo-board", "foo-version", True, False, False
            )
            # Ensure that the first model from the unified build was selected
            # as the platform to be tested
            sched_tests.assert_called_once_with(
                "foo-suite-name",
                "board",
                "model2",
                "foo-archive-build",
                [
                    self.payload_config1,
                    self.payload_config2,
                    self.payload_config3,
                    self.payload_config4,
                    self.payload_config5,
                ],
            )

    def testRunPaygenInParallelWithUnifiedBuild(self):
        # payload_config1 defines applicable_models as model1 and model3.
        # model3 does not have au enabled but gets scheduled since it has type FSI.
        # payload_config2 defines applicable_models as model2 and model3.
        # model3 does not get scheduled since config2 has type OMAHA.
        # payload_config3 has type OMAHA with no applicable models so doesn't get
        # scheduled.
        # payload_config4 has type N2N and which never have applicable_models but
        # should get scheduled on all ['au'] models.
        # payload_config5 has type STEPPING_STONE which also never has
        # applicable models but should get scheduled on all ['au'] models too.
        self._run.config.models = [
            config_lib.ModelTestConfig("model1", "model1", ["au"]),
            config_lib.ModelTestConfig("model2", "model1", ["au"]),
            config_lib.ModelTestConfig("model3", "model1"),
        ]

        # Have to patch and verify that the PaygenTestStage is created.
        stage = self.ConstructStage()

        with patch(parallel, "RunParallelSteps") as parallel_tests:
            stage._RunPaygenInProcess(
                "foo", "foo-board", "foo-version", True, False, False
            )
            # 2 tests scheduled for FSI, 1 test scheduled for OMAHA,
            # 2 tests scheduled for N2N, 2 tests scheduled for STEPPING_STONE.
            parallel_tests.assert_called_once_with([mock.ANY] * 7)

    def testPayloadBuildSetCorrectly(self):
        """Test that payload build is passed correctly to PaygenBuild."""
        stage = self.ConstructStage()
        self.PatchObject(paygen_build_lib, "ScheduleAutotestTests")

        # Call the method under test.
        stage._RunPaygenInProcess(
            "foo", "foo-board", "foo-version", False, False, False
        )

        # Ensure arguments are properly converted and passed along.
        build = gspaths.Build(
            version="foo-version",
            board="foo-board",
            channel="foo-channel",
            bucket=gspaths.ChromeosReleases.BUCKET,
        )
        self.paygenBuildMock.assert_called_with(
            build,
            build,
            work_dir=mock.ANY,
            site_config=stage._run.site_config,
            dry_run=False,
            skip_delta_payloads=False,
        )

    def testTestPayloadBuildSetCorrectly(self):
        """Test that test payload build is passed correctly to PaygenBuild."""
        stage = self.ConstructStage()
        self.PatchObject(paygen_build_lib, "ScheduleAutotestTests")

        # Call the method under test.
        stage._RunPaygenInProcess(
            "foo", "foo-board", "foo-version", True, False, False
        )

        # Ensure arguments are properly converted and passed along.
        build = gspaths.Build(
            version="foo-version",
            board="foo-board",
            channel="foo-channel",
            bucket=gspaths.ChromeosReleases.BUCKET,
        )
        test_payload_build = gspaths.Build(build)
        test_payload_build.bucket = gspaths.ChromeosReleases.TEST_BUCKET

        self.paygenBuildMock.assert_called_with(
            build,
            test_payload_build,
            work_dir=mock.ANY,
            site_config=stage._run.site_config,
            dry_run=True,
            skip_delta_payloads=False,
        )


class PaygenBuildStageTest(
    generic_stages_unittest.AbstractStageTestCase,
    cbuildbot_unittest.SimpleBuilderTestCase,
):
    """Test the PaygenBuild stage."""

    # We use a variant board to make sure the '_' is translated to '-'.
    BOT_ID = "beaglebone_servo-release"
    RELEASE_TAG = "0.0.1"

    def setUp(self):
        self._Prepare()
        self.buildstore = FakeBuildStore()

    # pylint: disable=arguments-differ
    def ConstructStage(self):
        return release_stages.PaygenBuildStage(
            self._run,
            self.buildstore,
            board=self._current_board,
            channel="foochan",
            version="foo-version",
            debug=True,
            skip_testing=False,
            skip_delta_payloads=False,
        )

    def testStageName(self):
        """See if the stage name is correctly formed."""
        stage = self.ConstructStage()
        self.assertEqual(stage.name, "PaygenBuildFoochan")


class PaygenTestStageTest(
    generic_stages_unittest.AbstractStageTestCase,
    cbuildbot_unittest.SimpleBuilderTestCase,
):
    """Test the PaygenTestStage stage."""

    # We use a variant board to make sure the '_' is translated to '-'.
    BOT_ID = "beaglebone_servo-release"
    RELEASE_TAG = "0.0.1"

    def setUp(self):
        self._Prepare()
        self.buildstore = FakeBuildStore()

    # pylint: disable=arguments-differ
    def ConstructStage(self):
        return release_stages.PaygenTestStage(
            builder_run=self._run,
            buildstore=self.buildstore,
            suite_name="foo-test-suite",
            board=self._current_board,
            model=self._current_board,
            lab_board_name=self._current_board,
            # The PaygenBuild stage will add the '-channel' suffix to the channel
            # when converting to release tools naming.
            channel="foochan-channel",
            build="foo-version",
            debug=True,
            payload_test_configs=[],
            test_env=constants.ENV_AUTOTEST,
        )

    def testStageName(self):
        """See if the stage name is correctly formed."""
        stage = self.ConstructStage()
        self.assertEqual(stage.name, "PaygenTestFoochan [beaglebone_servo]")

    def testPerformStageTestLabFail(self):
        """Test that exception from RunHWTestSuite are properly handled."""
        with patch(paygen_build_lib, "ScheduleAutotestTests") as sched_tests:
            sched_tests.side_effect = failures_lib.TestLabFailure

            stage = self.ConstructStage()

            with patch(stage, "_HandleExceptionAsWarning") as warning_handler:
                warning_handler.return_value = (
                    results_lib.Results.FORGIVEN,
                    "description",
                    0,
                )

                stage.Run()

                # This proves the exception was turned into a warning.
                self.assertTrue(warning_handler.called)
