• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright 2020 The ChromiumOS Authors
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Tests for upload_lexan_crashes_to_forcey."""
8
9import datetime
10import os
11import unittest
12import unittest.mock
13
14import upload_lexan_crashes_to_forcey
15
16
17class Test(unittest.TestCase):
18    """Tests for upload_lexan_crashes_to_forcey."""
19
20    def test_date_parsing_functions(self):
21        self.assertEqual(
22            datetime.date(2020, 2, 1),
23            upload_lexan_crashes_to_forcey.from_ymd("2020-02-01"),
24        )
25
26    @unittest.mock.patch(
27        "upload_lexan_crashes_to_forcey.test_cases_on_or_after",
28        return_value=(
29            (
30                datetime.date(2020, 1, 1),
31                ("gs://test-case-1", "gs://test-case-1.1"),
32            ),
33            (datetime.date(2020, 1, 2), ("gs://test-case-2",)),
34            (datetime.date(2020, 1, 1), ("gs://test-case-3",)),
35            (datetime.date(2020, 1, 4), ("gs://test-case-4",)),
36        ),
37    )
38    @unittest.mock.patch("upload_lexan_crashes_to_forcey.submit_test_case")
39    @unittest.mock.patch("upload_lexan_crashes_to_forcey.persist_state")
40    def test_new_test_case_submission_functions(
41        self,
42        persist_state_mock,
43        submit_test_case_mock,
44        test_cases_on_or_after_mock,
45    ):
46        forcey_path = "/path/to/4c"
47        real_state_file_path = "/path/to/state/file"
48        earliest_date = datetime.date(2020, 1, 1)
49
50        persist_state_calls = []
51
52        # Since the set this gets is mutated, we need to copy it somehow.
53        def persist_state_side_effect(
54            test_cases_to_persist, state_file_path, most_recent_date
55        ):
56            self.assertEqual(state_file_path, real_state_file_path)
57            persist_state_calls.append(
58                (sorted(test_cases_to_persist), most_recent_date)
59            )
60
61        persist_state_mock.side_effect = persist_state_side_effect
62
63        upload_lexan_crashes_to_forcey.submit_new_test_cases(
64            last_seen_test_cases=(
65                "gs://test-case-0",
66                "gs://test-case-1",
67            ),
68            earliest_date_to_check=earliest_date,
69            forcey=forcey_path,
70            state_file_path=real_state_file_path,
71        )
72
73        test_cases_on_or_after_mock.assert_called_once_with(earliest_date)
74        self.assertEqual(
75            submit_test_case_mock.call_args_list,
76            [
77                unittest.mock.call("gs://test-case-1.1", forcey_path),
78                unittest.mock.call("gs://test-case-2", forcey_path),
79                unittest.mock.call("gs://test-case-3", forcey_path),
80                unittest.mock.call("gs://test-case-4", forcey_path),
81            ],
82        )
83
84        self.assertEqual(
85            persist_state_calls,
86            [
87                (
88                    [
89                        "gs://test-case-0",
90                        "gs://test-case-1",
91                        "gs://test-case-1.1",
92                    ],
93                    datetime.date(2020, 1, 1),
94                ),
95                (
96                    [
97                        "gs://test-case-0",
98                        "gs://test-case-1",
99                        "gs://test-case-1.1",
100                        "gs://test-case-2",
101                    ],
102                    datetime.date(2020, 1, 2),
103                ),
104                (
105                    [
106                        "gs://test-case-0",
107                        "gs://test-case-1",
108                        "gs://test-case-1.1",
109                        "gs://test-case-2",
110                        "gs://test-case-3",
111                    ],
112                    datetime.date(2020, 1, 2),
113                ),
114                (
115                    [
116                        "gs://test-case-0",
117                        "gs://test-case-1",
118                        "gs://test-case-1.1",
119                        "gs://test-case-2",
120                        "gs://test-case-3",
121                        "gs://test-case-4",
122                    ],
123                    datetime.date(2020, 1, 4),
124                ),
125                (
126                    [
127                        "gs://test-case-1",
128                        "gs://test-case-1.1",
129                        "gs://test-case-2",
130                        "gs://test-case-3",
131                        "gs://test-case-4",
132                    ],
133                    datetime.date(2020, 1, 4),
134                ),
135            ],
136        )
137
138    @unittest.mock.patch(
139        "upload_lexan_crashes_to_forcey.download_and_unpack_test_case"
140    )
141    @unittest.mock.patch("subprocess.run")
142    def test_test_case_submission_functions(
143        self, subprocess_run_mock, download_and_unpack_mock
144    ):
145        mock_gs_url = "gs://foo/bar/baz"
146
147        def side_effect(gs_url: str, tempdir: str) -> None:
148            self.assertEqual(gs_url, mock_gs_url)
149
150            with open(os.path.join(tempdir, "test_case.c"), "w") as f:
151                # All we need is an empty file here.
152                pass
153
154            with open(
155                os.path.join(tempdir, "test_case.sh"), "w", encoding="utf-8"
156            ) as f:
157                f.write("# Crash reproducer for clang version 9.0.0 (...)\n")
158                f.write("clang something or other\n")
159
160        download_and_unpack_mock.side_effect = side_effect
161        upload_lexan_crashes_to_forcey.submit_test_case(mock_gs_url, "4c")
162        subprocess_run_mock.assert_not_called()
163
164
165if __name__ == "__main__":
166    unittest.main()
167