Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / tools / lint / test / test_perfdocs_generation.py
blobe79983a189fa297db10fe20053d0de212d8cbc6f
1 import os
2 import pathlib
3 from unittest import mock
5 import mozunit
7 LINTER = "perfdocs"
10 def setup_sample_logger(logger, structured_logger, top_dir):
11 from perfdocs.logger import PerfDocLogger
13 PerfDocLogger.LOGGER = structured_logger
14 PerfDocLogger.PATHS = ["perfdocs"]
15 PerfDocLogger.TOP_DIR = top_dir
17 import perfdocs.gatherer as gt
18 import perfdocs.generator as gn
19 import perfdocs.utils as utls
20 import perfdocs.verifier as vf
22 gt.logger = logger
23 vf.logger = logger
24 gn.logger = logger
25 utls.logger = logger
28 @mock.patch("perfdocs.logger.PerfDocLogger")
29 def test_perfdocs_generator_generate_perfdocs_pass(
30 logger, structured_logger, perfdocs_sample
32 from test_perfdocs import temp_file
34 top_dir = perfdocs_sample["top_dir"]
35 setup_sample_logger(logger, structured_logger, top_dir)
37 templates_dir = pathlib.Path(top_dir, "tools", "lint", "perfdocs", "templates")
38 templates_dir.mkdir(parents=True, exist_ok=True)
40 from perfdocs.generator import Generator
41 from perfdocs.verifier import Verifier
43 verifier = Verifier(top_dir)
44 verifier.validate_tree()
46 generator = Generator(verifier, generate=True, workspace=top_dir)
47 with temp_file("index.rst", tempdir=templates_dir, content="{test_documentation}"):
48 generator.generate_perfdocs()
50 assert logger.warning.call_count == 0
53 @mock.patch("perfdocs.logger.PerfDocLogger")
54 def test_perfdocs_generator_generate_perfdocs_metrics_pass(
55 logger, structured_logger, perfdocs_sample
57 from test_perfdocs import temp_file
59 top_dir = perfdocs_sample["top_dir"]
60 setup_sample_logger(logger, structured_logger, top_dir)
62 templates_dir = pathlib.Path(top_dir, "tools", "lint", "perfdocs", "templates")
63 templates_dir.mkdir(parents=True, exist_ok=True)
65 from perfdocs.generator import Generator
66 from perfdocs.verifier import Verifier
68 sample_gatherer_result = {
69 "suite": {"Example": {"metrics": ["fcp", "SpeedIndex"]}},
70 "another_suite": {"Example": {}},
72 sample_test_list_result = {
73 "suite": [{"metrics": ["fcp", "SpeedIndex"], "name": "Example"}],
74 "another_suite": [{"name": "Example"}],
77 with temp_file(
78 "metrics.rst",
79 tempdir=pathlib.Path(top_dir, "perfdocs"),
80 content="{metrics_documentation}",
82 with mock.patch(
83 "perfdocs.framework_gatherers.RaptorGatherer.get_test_list"
84 ) as m:
85 m.return_value = sample_gatherer_result
86 with perfdocs_sample["config"].open("w") as f1, perfdocs_sample[
87 "config_metrics"
88 ].open("r") as f2:
89 # Overwrite content of config.yml with metrics config
90 f1.write(f2.read())
92 verifier = Verifier(top_dir)
93 verifier.validate_tree()
95 verifier._gatherer.framework_gatherers["raptor"]._descriptions = (
96 sample_test_list_result
99 generator = Generator(verifier, generate=True, workspace=top_dir)
100 with temp_file(
101 "index.rst", tempdir=templates_dir, content="{test_documentation}"
103 generator.generate_perfdocs()
105 with pathlib.Path(generator.perfdocs_path, "raptor-metrics.rst").open() as f:
106 metrics_content = f.read()
107 assert "{metrics_documentation}" not in metrics_content
108 assert "a description" in metrics_content
109 assert "**Tests using it**" in metrics_content
111 with pathlib.Path(generator.perfdocs_path, "raptor.rst").open() as f:
112 raptor_index_content = f.read()
113 assert "{metrics_rst_name}" not in raptor_index_content
114 assert "raptor-metrics" in raptor_index_content
116 assert logger.warning.call_count == 0
119 @mock.patch("perfdocs.logger.PerfDocLogger")
120 def test_perfdocs_generator_needed_regeneration(
121 logger, structured_logger, perfdocs_sample
123 top_dir = perfdocs_sample["top_dir"]
124 setup_sample_logger(logger, structured_logger, top_dir)
126 from perfdocs.generator import Generator
127 from perfdocs.verifier import Verifier
129 verifier = Verifier(top_dir)
130 verifier.validate_tree()
132 generator = Generator(verifier, generate=False, workspace=top_dir)
133 generator.generate_perfdocs()
135 expected = "PerfDocs need to be regenerated."
136 args, _ = logger.warning.call_args
138 assert logger.warning.call_count == 1
139 assert args[0] == expected
142 @mock.patch("perfdocs.generator.get_changed_files", new=lambda x: [])
143 @mock.patch("perfdocs.generator.ON_TRY", new=True)
144 @mock.patch("perfdocs.logger.PerfDocLogger")
145 def test_perfdocs_generator_needed_update(logger, structured_logger, perfdocs_sample):
146 from test_perfdocs import temp_file
148 top_dir = perfdocs_sample["top_dir"]
149 setup_sample_logger(logger, structured_logger, top_dir)
151 templates_dir = pathlib.Path(top_dir, "tools", "lint", "perfdocs", "templates")
152 templates_dir.mkdir(parents=True, exist_ok=True)
154 from perfdocs.generator import Generator
155 from perfdocs.verifier import Verifier
157 # Initializing perfdocs
158 verifier = Verifier(top_dir)
159 verifier.validate_tree()
161 generator = Generator(verifier, generate=True, workspace=top_dir)
162 with temp_file("index.rst", tempdir=templates_dir, content="{test_documentation}"):
163 generator.generate_perfdocs()
165 # Removed file for testing and run again
166 generator._generate = False
167 files = [f for f in os.listdir(generator.perfdocs_path)]
168 for f in files:
169 os.remove(str(pathlib.Path(generator.perfdocs_path, f)))
171 generator.generate_perfdocs()
173 expected = (
174 "PerfDocs are outdated, run ./mach lint -l perfdocs --fix .` to update them. "
175 "You can also apply the perfdocs.diff patch file produced from this "
176 "reviewbot test to fix the issue."
178 args, _ = logger.warning.call_args
180 assert logger.warning.call_count == 1
181 assert args[0] == expected
183 # Check to ensure a diff was produced
184 assert logger.log.call_count == 6
186 logs = [v[0][0] for v in logger.log.call_args_list]
187 for failure_log in (
188 "Some files are missing or are funny.",
189 "Missing in existing docs: index.rst",
190 "Missing in existing docs: mozperftest.rst",
192 assert failure_log in logs
195 @mock.patch("perfdocs.generator.get_changed_files", new=lambda x: [])
196 @mock.patch("perfdocs.generator.ON_TRY", new=True)
197 def test_perfdocs_generator_update_with_no_changes(structured_logger, perfdocs_sample):
198 """This test ensures that when no changed files exist, we'll still trigger a failure."""
199 from perfdocs.logger import PerfDocLogger
200 from test_perfdocs import temp_file
202 top_dir = perfdocs_sample["top_dir"]
204 logger_mock = mock.MagicMock()
205 PerfDocLogger.LOGGER = logger_mock
206 PerfDocLogger.PATHS = ["perfdocs"]
207 PerfDocLogger.TOP_DIR = top_dir
208 logger = PerfDocLogger()
210 setup_sample_logger(logger, logger_mock, top_dir)
212 templates_dir = pathlib.Path(top_dir, "tools", "lint", "perfdocs", "templates")
213 templates_dir.mkdir(parents=True, exist_ok=True)
215 from perfdocs.generator import Generator
216 from perfdocs.verifier import Verifier
218 # Initializing perfdocs
219 verifier = Verifier(top_dir)
220 verifier.validate_tree()
222 generator = Generator(verifier, generate=True, workspace=top_dir)
223 with temp_file("index.rst", tempdir=templates_dir, content="{test_documentation}"):
224 generator.generate_perfdocs()
226 # Removed file for testing and run again
227 generator._generate = False
228 files = [f for f in os.listdir(generator.perfdocs_path)]
229 for f in files:
230 os.remove(str(pathlib.Path(generator.perfdocs_path, f)))
232 generator.generate_perfdocs()
234 expected = (
235 "PerfDocs are outdated, run ./mach lint -l perfdocs --fix .` to update them. "
236 "You can also apply the perfdocs.diff patch file produced from this "
237 "reviewbot test to fix the issue."
239 assert logger.LOGGER.lint_error.call_args is not None
240 _, msg = logger.LOGGER.lint_error.call_args
242 assert logger.FAILED
243 assert logger.LOGGER.lint_error.call_count == 1
244 assert msg["message"] == expected
245 assert msg["rule"] == "Flawless performance docs (unknown file)"
248 @mock.patch("perfdocs.logger.PerfDocLogger")
249 def test_perfdocs_generator_created_perfdocs(
250 logger, structured_logger, perfdocs_sample
252 from test_perfdocs import temp_file
254 top_dir = perfdocs_sample["top_dir"]
255 setup_sample_logger(logger, structured_logger, top_dir)
257 templates_dir = pathlib.Path(top_dir, "tools", "lint", "perfdocs", "templates")
258 templates_dir.mkdir(parents=True, exist_ok=True)
260 from perfdocs.generator import Generator
261 from perfdocs.verifier import Verifier
263 verifier = Verifier(top_dir)
264 verifier.validate_tree()
266 generator = Generator(verifier, generate=True, workspace=top_dir)
267 with temp_file("index.rst", tempdir=templates_dir, content="{test_documentation}"):
268 perfdocs_tmpdir = generator._create_perfdocs()
270 files = [f for f in os.listdir(perfdocs_tmpdir)]
271 files.sort()
272 expected_files = ["index.rst", "mozperftest.rst"]
274 for i, file in enumerate(files):
275 assert file == expected_files[i]
277 with pathlib.Path(perfdocs_tmpdir, expected_files[0]).open() as f:
278 filedata = f.readlines()
279 assert "".join(filedata) == " * :doc:`mozperftest`"
282 @mock.patch("perfdocs.logger.PerfDocLogger")
283 def test_perfdocs_generator_build_perfdocs(logger, structured_logger, perfdocs_sample):
284 top_dir = perfdocs_sample["top_dir"]
285 setup_sample_logger(logger, structured_logger, top_dir)
287 from perfdocs.generator import Generator
288 from perfdocs.verifier import Verifier
290 verifier = Verifier(top_dir)
291 verifier.validate_tree()
293 generator = Generator(verifier, generate=True, workspace=top_dir)
294 frameworks_info = generator.build_perfdocs_from_tree()
296 expected = ["dynamic", "metrics", "static"]
298 for framework in sorted(frameworks_info.keys()):
299 for i, framework_info in enumerate(frameworks_info[framework]):
300 assert framework_info == expected[i]
303 @mock.patch("perfdocs.logger.PerfDocLogger")
304 def test_perfdocs_generator_create_temp_dir(logger, structured_logger, perfdocs_sample):
305 top_dir = perfdocs_sample["top_dir"]
306 setup_sample_logger(logger, structured_logger, top_dir)
308 from perfdocs.generator import Generator
309 from perfdocs.verifier import Verifier
311 verifier = Verifier(top_dir)
312 verifier.validate_tree()
314 generator = Generator(verifier, generate=True, workspace=top_dir)
315 tmpdir = generator._create_temp_dir()
317 assert pathlib.Path(tmpdir).is_dir()
320 @mock.patch("perfdocs.logger.PerfDocLogger")
321 def test_perfdocs_generator_create_temp_dir_fail(
322 logger, structured_logger, perfdocs_sample
324 top_dir = perfdocs_sample["top_dir"]
325 setup_sample_logger(logger, structured_logger, top_dir)
327 from perfdocs.generator import Generator
328 from perfdocs.verifier import Verifier
330 verifier = Verifier(top_dir)
331 verifier.validate_tree()
333 generator = Generator(verifier, generate=True, workspace=top_dir)
334 with mock.patch("perfdocs.generator.pathlib") as path_mock:
335 path_mock.Path().mkdir.side_effect = OSError()
336 path_mock.Path().is_dir.return_value = False
337 tmpdir = generator._create_temp_dir()
339 expected = "Error creating temp file: "
340 args, _ = logger.critical.call_args
342 assert not tmpdir
343 assert logger.critical.call_count == 1
344 assert args[0] == expected
347 @mock.patch("perfdocs.logger.PerfDocLogger")
348 def test_perfdocs_generator_save_perfdocs_pass(
349 logger, structured_logger, perfdocs_sample
351 from test_perfdocs import temp_file
353 top_dir = perfdocs_sample["top_dir"]
354 setup_sample_logger(logger, structured_logger, top_dir)
356 templates_dir = pathlib.Path(top_dir, "tools", "lint", "perfdocs", "templates")
357 templates_dir.mkdir(parents=True, exist_ok=True)
359 from perfdocs.generator import Generator
360 from perfdocs.verifier import Verifier
362 verifier = Verifier(top_dir)
363 verifier.validate_tree()
365 generator = Generator(verifier, generate=True, workspace=top_dir)
367 assert not generator.perfdocs_path.is_dir()
369 with temp_file("index.rst", tempdir=templates_dir, content="{test_documentation}"):
370 perfdocs_tmpdir = generator._create_perfdocs()
372 generator._save_perfdocs(perfdocs_tmpdir)
374 expected = ["index.rst", "mozperftest.rst"]
375 files = [f for f in os.listdir(generator.perfdocs_path)]
376 files.sort()
378 for i, file in enumerate(files):
379 assert file == expected[i]
382 @mock.patch("perfdocs.generator.shutil")
383 @mock.patch("perfdocs.logger.PerfDocLogger")
384 def test_perfdocs_generator_save_perfdocs_fail(
385 logger, shutil, structured_logger, perfdocs_sample
387 from test_perfdocs import temp_file
389 top_dir = perfdocs_sample["top_dir"]
390 setup_sample_logger(logger, structured_logger, top_dir)
392 templates_dir = pathlib.Path(top_dir, "tools", "lint", "perfdocs", "templates")
393 templates_dir.mkdir(parents=True, exist_ok=True)
395 from perfdocs.generator import Generator
396 from perfdocs.verifier import Verifier
398 verifier = Verifier(top_dir)
399 verifier.validate_tree()
401 generator = Generator(verifier, generate=True, workspace=top_dir)
402 with temp_file("index.rst", tempdir=templates_dir, content="{test_documentation}"):
403 perfdocs_tmpdir = generator._create_perfdocs()
405 shutil.copytree = mock.Mock(side_effect=Exception())
406 generator._save_perfdocs(perfdocs_tmpdir)
408 expected = "There was an error while saving the documentation: "
409 args, _ = logger.critical.call_args
411 assert logger.critical.call_count == 1
412 assert args[0] == expected
415 if __name__ == "__main__":
416 mozunit.main()