xref: /aosp_15_r20/external/toolchain-utils/cros_utils/buildbot_utils_unittest.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1*760c253cSXin Li#!/usr/bin/env python3
2*760c253cSXin Li# Copyright 2018 The ChromiumOS Authors
3*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be
4*760c253cSXin Li# found in the LICENSE file.
5*760c253cSXin Li
6*760c253cSXin Li"""Unittest for buildbot_utils.py."""
7*760c253cSXin Li
8*760c253cSXin Li
9*760c253cSXin Liimport time
10*760c253cSXin Liimport unittest
11*760c253cSXin Lifrom unittest.mock import patch
12*760c253cSXin Li
13*760c253cSXin Lifrom cros_utils import buildbot_utils
14*760c253cSXin Lifrom cros_utils import command_executer
15*760c253cSXin Li
16*760c253cSXin Li
17*760c253cSXin Liclass TrybotTest(unittest.TestCase):
18*760c253cSXin Li    """Test for CommandExecuter class."""
19*760c253cSXin Li
20*760c253cSXin Li    tryjob_out = (
21*760c253cSXin Li        '[{"buildbucket_id": "8952721143823688176", "build_config": '
22*760c253cSXin Li        '"cave-llvm-toolchain-tryjob", "url": '
23*760c253cSXin Li        # pylint: disable=line-too-long
24*760c253cSXin Li        '"http://cros-goldeneye/chromeos/healthmonitoring/buildDetails?buildbucketId=8952721143823688176"}]'
25*760c253cSXin Li    )
26*760c253cSXin Li
27*760c253cSXin Li    GSUTILS_LS = "\n".join(
28*760c253cSXin Li        [
29*760c253cSXin Li            "gs://chromeos-image-archive/{0}/R78-12421.0.0/",
30*760c253cSXin Li            "gs://chromeos-image-archive/{0}/R78-12422.0.0/",
31*760c253cSXin Li            "gs://chromeos-image-archive/{0}/R78-12423.0.0/",
32*760c253cSXin Li        ]
33*760c253cSXin Li    )
34*760c253cSXin Li
35*760c253cSXin Li    GSUTILS_LS_RECIPE = "\n".join(
36*760c253cSXin Li        [
37*760c253cSXin Li            "gs://chromeos-image-archive/{0}/R83-12995.0.0-30031-8885075268947031/",
38*760c253cSXin Li            "gs://chromeos-image-archive/{0}/R83-13003.0.0-30196-8884755532184725/",
39*760c253cSXin Li            "gs://chromeos-image-archive/{0}/R83-13003.0.0-30218-8884712858556419/",
40*760c253cSXin Li        ]
41*760c253cSXin Li    )
42*760c253cSXin Li
43*760c253cSXin Li    buildresult_out = (
44*760c253cSXin Li        '{"8952721143823688176": {"status": "pass", "artifacts_url":'
45*760c253cSXin Li        '"gs://chromeos-image-archive/trybot-elm-release-tryjob/R67-10468.0.0-'
46*760c253cSXin Li        'b20789"}}'
47*760c253cSXin Li    )
48*760c253cSXin Li
49*760c253cSXin Li    buildbucket_id = "8952721143823688176"
50*760c253cSXin Li    counter_1 = 10
51*760c253cSXin Li
52*760c253cSXin Li    def testGetTrybotImage(self):
53*760c253cSXin Li        with patch.object(buildbot_utils, "SubmitTryjob") as mock_submit:
54*760c253cSXin Li            with patch.object(buildbot_utils, "PeekTrybotImage") as mock_peek:
55*760c253cSXin Li                with patch.object(time, "sleep", return_value=None):
56*760c253cSXin Li
57*760c253cSXin Li                    def peek(_chromeos_root, _buildbucket_id):
58*760c253cSXin Li                        self.counter_1 -= 1
59*760c253cSXin Li                        if self.counter_1 >= 0:
60*760c253cSXin Li                            return ("running", "")
61*760c253cSXin Li                        return (
62*760c253cSXin Li                            "pass",
63*760c253cSXin Li                            "gs://chromeos-image-archive/trybot-elm-release-tryjob/"
64*760c253cSXin Li                            "R67-10468.0.0-b20789",
65*760c253cSXin Li                        )
66*760c253cSXin Li
67*760c253cSXin Li                    mock_peek.side_effect = peek
68*760c253cSXin Li                    mock_submit.return_value = self.buildbucket_id
69*760c253cSXin Li
70*760c253cSXin Li                    # sync
71*760c253cSXin Li                    buildbucket_id, image = buildbot_utils.GetTrybotImage(
72*760c253cSXin Li                        "/tmp", "falco-release-tryjob", []
73*760c253cSXin Li                    )
74*760c253cSXin Li                    self.assertEqual(buildbucket_id, self.buildbucket_id)
75*760c253cSXin Li                    self.assertEqual(
76*760c253cSXin Li                        "trybot-elm-release-tryjob/" "R67-10468.0.0-b20789",
77*760c253cSXin Li                        image,
78*760c253cSXin Li                    )
79*760c253cSXin Li
80*760c253cSXin Li                    # async
81*760c253cSXin Li                    buildbucket_id, image = buildbot_utils.GetTrybotImage(
82*760c253cSXin Li                        "/tmp", "falco-release-tryjob", [], asynchronous=True
83*760c253cSXin Li                    )
84*760c253cSXin Li                    self.assertEqual(buildbucket_id, self.buildbucket_id)
85*760c253cSXin Li                    self.assertEqual(" ", image)
86*760c253cSXin Li
87*760c253cSXin Li    def testSubmitTryjob(self):
88*760c253cSXin Li        with patch.object(
89*760c253cSXin Li            command_executer.CommandExecuter, "RunCommandWOutput"
90*760c253cSXin Li        ) as mocked_run:
91*760c253cSXin Li            mocked_run.return_value = (0, self.tryjob_out, "")
92*760c253cSXin Li            buildbucket_id = buildbot_utils.SubmitTryjob(
93*760c253cSXin Li                "/", "falco-release-tryjob", [], []
94*760c253cSXin Li            )
95*760c253cSXin Li            self.assertEqual(buildbucket_id, self.buildbucket_id)
96*760c253cSXin Li
97*760c253cSXin Li    def testPeekTrybotImage(self):
98*760c253cSXin Li        with patch.object(
99*760c253cSXin Li            command_executer.CommandExecuter, "RunCommandWOutput"
100*760c253cSXin Li        ) as mocked_run:
101*760c253cSXin Li            # pass
102*760c253cSXin Li            mocked_run.return_value = (0, self.buildresult_out, "")
103*760c253cSXin Li            status, image = buildbot_utils.PeekTrybotImage(
104*760c253cSXin Li                "/", self.buildbucket_id
105*760c253cSXin Li            )
106*760c253cSXin Li            self.assertEqual("pass", status)
107*760c253cSXin Li            self.assertEqual(
108*760c253cSXin Li                "gs://chromeos-image-archive/trybot-elm-release-tryjob/"
109*760c253cSXin Li                "R67-10468.0.0-b20789",
110*760c253cSXin Li                image,
111*760c253cSXin Li            )
112*760c253cSXin Li
113*760c253cSXin Li            # running
114*760c253cSXin Li            mocked_run.return_value = (1, "", "")
115*760c253cSXin Li            status, image = buildbot_utils.PeekTrybotImage(
116*760c253cSXin Li                "/", self.buildbucket_id
117*760c253cSXin Li            )
118*760c253cSXin Li            self.assertEqual("running", status)
119*760c253cSXin Li            self.assertEqual(None, image)
120*760c253cSXin Li
121*760c253cSXin Li            # fail
122*760c253cSXin Li            buildresult_fail = self.buildresult_out.replace('"pass"', '"fail"')
123*760c253cSXin Li            mocked_run.return_value = (0, buildresult_fail, "")
124*760c253cSXin Li            status, image = buildbot_utils.PeekTrybotImage(
125*760c253cSXin Li                "/", self.buildbucket_id
126*760c253cSXin Li            )
127*760c253cSXin Li            self.assertEqual("fail", status)
128*760c253cSXin Li            self.assertEqual(
129*760c253cSXin Li                "gs://chromeos-image-archive/trybot-elm-release-tryjob/"
130*760c253cSXin Li                "R67-10468.0.0-b20789",
131*760c253cSXin Li                image,
132*760c253cSXin Li            )
133*760c253cSXin Li
134*760c253cSXin Li    def testParseTryjobBuildbucketId(self):
135*760c253cSXin Li        buildbucket_id = buildbot_utils.ParseTryjobBuildbucketId(
136*760c253cSXin Li            self.tryjob_out
137*760c253cSXin Li        )
138*760c253cSXin Li        self.assertEqual(buildbucket_id, self.buildbucket_id)
139*760c253cSXin Li
140*760c253cSXin Li    def testGetLatestImageValid(self):
141*760c253cSXin Li        with patch.object(
142*760c253cSXin Li            command_executer.CommandExecuter, "ChrootRunCommandWOutput"
143*760c253cSXin Li        ) as mocked_run:
144*760c253cSXin Li            with patch.object(
145*760c253cSXin Li                buildbot_utils, "DoesImageExist"
146*760c253cSXin Li            ) as mocked_imageexist:
147*760c253cSXin Li                IMAGE_DIR = "lulu-release"
148*760c253cSXin Li                mocked_run.return_value = (
149*760c253cSXin Li                    0,
150*760c253cSXin Li                    self.GSUTILS_LS.format(IMAGE_DIR),
151*760c253cSXin Li                    "",
152*760c253cSXin Li                )
153*760c253cSXin Li                mocked_imageexist.return_value = True
154*760c253cSXin Li                image = buildbot_utils.GetLatestImage("", IMAGE_DIR)
155*760c253cSXin Li                self.assertEqual(image, f"{IMAGE_DIR}/R78-12423.0.0")
156*760c253cSXin Li
157*760c253cSXin Li    def testGetLatestImageInvalid(self):
158*760c253cSXin Li        with patch.object(
159*760c253cSXin Li            command_executer.CommandExecuter, "ChrootRunCommandWOutput"
160*760c253cSXin Li        ) as mocked_run:
161*760c253cSXin Li            with patch.object(
162*760c253cSXin Li                buildbot_utils, "DoesImageExist"
163*760c253cSXin Li            ) as mocked_imageexist:
164*760c253cSXin Li                IMAGE_DIR = "kefka-release"
165*760c253cSXin Li                mocked_run.return_value = (
166*760c253cSXin Li                    0,
167*760c253cSXin Li                    self.GSUTILS_LS.format(IMAGE_DIR),
168*760c253cSXin Li                    "",
169*760c253cSXin Li                )
170*760c253cSXin Li                mocked_imageexist.return_value = False
171*760c253cSXin Li                image = buildbot_utils.GetLatestImage("", IMAGE_DIR)
172*760c253cSXin Li                self.assertIsNone(image)
173*760c253cSXin Li
174*760c253cSXin Li    def testGetLatestRecipeImageValid(self):
175*760c253cSXin Li        with patch.object(
176*760c253cSXin Li            command_executer.CommandExecuter, "ChrootRunCommandWOutput"
177*760c253cSXin Li        ) as mocked_run:
178*760c253cSXin Li            with patch.object(
179*760c253cSXin Li                buildbot_utils, "DoesImageExist"
180*760c253cSXin Li            ) as mocked_imageexist:
181*760c253cSXin Li                IMAGE_DIR = "lulu-llvm-next-nightly"
182*760c253cSXin Li                mocked_run.return_value = (
183*760c253cSXin Li                    0,
184*760c253cSXin Li                    self.GSUTILS_LS_RECIPE.format(IMAGE_DIR),
185*760c253cSXin Li                    "",
186*760c253cSXin Li                )
187*760c253cSXin Li                mocked_imageexist.return_value = True
188*760c253cSXin Li                image = buildbot_utils.GetLatestRecipeImage("", IMAGE_DIR)
189*760c253cSXin Li                self.assertEqual(
190*760c253cSXin Li                    image,
191*760c253cSXin Li                    f"{IMAGE_DIR}/R83-13003.0.0-30218-8884712858556419",
192*760c253cSXin Li                )
193*760c253cSXin Li
194*760c253cSXin Li    def testGetLatestRecipeImageInvalid(self):
195*760c253cSXin Li        with patch.object(
196*760c253cSXin Li            command_executer.CommandExecuter, "ChrootRunCommandWOutput"
197*760c253cSXin Li        ) as mocked_run:
198*760c253cSXin Li            with patch.object(
199*760c253cSXin Li                buildbot_utils, "DoesImageExist"
200*760c253cSXin Li            ) as mocked_imageexist:
201*760c253cSXin Li                IMAGE_DIR = "kefka-llvm-next-nightly"
202*760c253cSXin Li                mocked_run.return_value = (
203*760c253cSXin Li                    0,
204*760c253cSXin Li                    self.GSUTILS_LS_RECIPE.format(IMAGE_DIR),
205*760c253cSXin Li                    "",
206*760c253cSXin Li                )
207*760c253cSXin Li                mocked_imageexist.return_value = False
208*760c253cSXin Li                image = buildbot_utils.GetLatestRecipeImage("", IMAGE_DIR)
209*760c253cSXin Li                self.assertIsNone(image)
210*760c253cSXin Li
211*760c253cSXin Li    def testGetLatestRecipeImageTwodays(self):
212*760c253cSXin Li        with patch.object(
213*760c253cSXin Li            command_executer.CommandExecuter, "ChrootRunCommandWOutput"
214*760c253cSXin Li        ) as mocked_run:
215*760c253cSXin Li            with patch.object(
216*760c253cSXin Li                buildbot_utils, "DoesImageExist"
217*760c253cSXin Li            ) as mocked_imageexist:
218*760c253cSXin Li                IMAGE_DIR = "lulu-llvm-next-nightly"
219*760c253cSXin Li                mocked_run.return_value = (
220*760c253cSXin Li                    0,
221*760c253cSXin Li                    self.GSUTILS_LS_RECIPE.format(IMAGE_DIR),
222*760c253cSXin Li                    "",
223*760c253cSXin Li                )
224*760c253cSXin Li                mocked_imageexist.side_effect = [False, False, True]
225*760c253cSXin Li                image = buildbot_utils.GetLatestRecipeImage("", IMAGE_DIR)
226*760c253cSXin Li                self.assertIsNone(image)
227*760c253cSXin Li                mocked_imageexist.side_effect = [False, True, True]
228*760c253cSXin Li                image = buildbot_utils.GetLatestRecipeImage("", IMAGE_DIR)
229*760c253cSXin Li                self.assertEqual(
230*760c253cSXin Li                    image,
231*760c253cSXin Li                    f"{IMAGE_DIR}/R83-13003.0.0-30196-8884755532184725",
232*760c253cSXin Li                )
233*760c253cSXin Li
234*760c253cSXin Li
235*760c253cSXin Liif __name__ == "__main__":
236*760c253cSXin Li    unittest.main()
237