1# Copyright 2023 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from __future__ import annotations 6 7import datetime as dt 8import os 9import pathlib 10import sys 11import tempfile 12import unittest 13 14from crossbench import compat, plt 15from crossbench.plt.base import DEFAULT_CACHE_DIR 16from crossbench.plt.posix import PosixPlatform 17from tests import test_helper 18 19 20class NativePlatformTestCase(unittest.TestCase): 21 22 def setUp(self): 23 self.platform: plt.Platform = plt.PLATFORM 24 25 def test_sleep(self): 26 self.platform.sleep(0) 27 self.platform.sleep(0.01) 28 self.platform.sleep(dt.timedelta()) 29 self.platform.sleep(dt.timedelta(seconds=0.1)) 30 31 def test_cpu_details(self): 32 details = self.platform.cpu_details() 33 self.assertLess(0, details["physical cores"]) 34 35 def test_get_relative_cpu_speed(self): 36 self.assertGreater(self.platform.get_relative_cpu_speed(), 0) 37 38 def test_is_thermal_throttled(self): 39 self.assertIsInstance(self.platform.is_thermal_throttled(), bool) 40 41 def test_is_battery_powered(self): 42 self.assertIsInstance(self.platform.is_battery_powered, bool) 43 self.assertEqual( 44 self.platform.is_battery_powered, 45 plt.PLATFORM.is_battery_powered, 46 ) 47 48 def test_cpu_usage(self): 49 self.assertGreaterEqual(self.platform.cpu_usage(), 0) 50 51 def test_system_details(self): 52 self.assertIsNotNone(self.platform.system_details()) 53 54 def test_environ(self): 55 env = self.platform.environ 56 self.assertTrue(env) 57 58 def test_which_none(self): 59 with self.assertRaises(ValueError): 60 self.platform.which("") 61 62 def test_which_invalid_binary(self): 63 with tempfile.TemporaryDirectory() as tmp_dirname: 64 self.assertIsNone(self.platform.which(tmp_dirname)) 65 66 def test_search_binary_empty_path(self): 67 with self.assertRaises(ValueError) as cm: 68 self.platform.search_binary(pathlib.Path()) 69 self.assertIn("empty", str(cm.exception)) 70 with self.assertRaises(ValueError) as cm: 71 self.platform.search_binary(pathlib.Path("")) 72 self.assertIn("empty", str(cm.exception)) 73 74 def test_search_app_empty_path(self): 75 with self.assertRaises(ValueError) as cm: 76 self.platform.search_app(pathlib.Path()) 77 self.assertIn("empty", str(cm.exception)) 78 with self.assertRaises(ValueError) as cm: 79 self.platform.search_app(pathlib.Path("")) 80 self.assertIn("empty", str(cm.exception)) 81 82 def test_cat(self): 83 with tempfile.TemporaryDirectory() as tmp_dirname: 84 file = pathlib.Path(tmp_dirname) / "test.txt" 85 with file.open("w") as f: 86 f.write("a b c d e f 11") 87 result = self.platform.cat(file) 88 self.assertEqual(result, "a b c d e f 11") 89 90 def test_cat_bytes(self): 91 with tempfile.TemporaryDirectory() as tmp_dirname: 92 file = pathlib.Path(tmp_dirname) / "test.data" 93 with file.open("wb") as f: 94 f.write(b"a b c d e f 11") 95 result = self.platform.cat_bytes(file) 96 self.assertEqual(result, b"a b c d e f 11") 97 98 def test_mkdir(self): 99 with tempfile.TemporaryDirectory() as tmp_dirname: 100 path = pathlib.Path(tmp_dirname) / "foo" / "bar" 101 self.assertFalse(self.platform.exists(path)) 102 self.platform.mkdir(path) 103 self.assertTrue(path.is_dir()) 104 105 def test_rm_file(self): 106 with tempfile.TemporaryDirectory() as tmp_dirname: 107 path = pathlib.Path(tmp_dirname) / "foo.txt" 108 path.touch() 109 self.assertTrue(path.is_file()) 110 self.platform.rm(path) 111 self.assertFalse(self.platform.exists(path)) 112 113 def test_rm_dir(self): 114 with tempfile.TemporaryDirectory() as tmp_dirname: 115 path = pathlib.Path(tmp_dirname) / "foo" / "bar" 116 path.mkdir(parents=True, exist_ok=False) 117 self.assertTrue(path.is_dir()) 118 with self.assertRaises(Exception): 119 self.platform.rm(path.parent) 120 self.platform.rm(path.parent, dir=True) 121 self.assertFalse(self.platform.exists(path)) 122 self.assertFalse(path.parent.exists()) 123 124 def test_mkdtemp(self): 125 result = self.platform.mkdtemp(prefix="a_custom_prefix") 126 self.assertTrue(self.platform.is_dir(result)) 127 self.assertIn("a_custom_prefix", result.name) 128 self.platform.rm(result, dir=True) 129 self.assertFalse(self.platform.exists(result)) 130 131 def test_mkdtemp_dir(self): 132 with tempfile.TemporaryDirectory() as tmp_dirname: 133 tmp_dir = pathlib.Path(tmp_dirname) 134 result = self.platform.mkdtemp(dir=tmp_dir) 135 self.assertTrue(self.platform.is_dir(result)) 136 self.assertTrue(compat.is_relative_to(result, tmp_dir)) 137 self.assertFalse(self.platform.exists(result)) 138 139 def test_mktemp(self): 140 result = self.platform.mktemp(prefix="a_custom_prefix") 141 self.assertTrue(self.platform.is_file(result)) 142 self.assertIn("a_custom_prefix", result.name) 143 self.platform.rm(result) 144 self.assertFalse(self.platform.exists(result)) 145 146 def test_mktemp_dir(self): 147 with tempfile.TemporaryDirectory() as tmp_dirname: 148 tmp_dir = pathlib.Path(tmp_dirname) 149 result = self.platform.mktemp(dir=tmp_dir) 150 self.assertTrue(self.platform.is_file(result)) 151 self.assertTrue(compat.is_relative_to(result, tmp_dir)) 152 self.assertFalse(self.platform.exists(result)) 153 154 def test_exists(self): 155 with tempfile.TemporaryDirectory() as tmp_dirname: 156 tmp_dir = pathlib.Path(tmp_dirname) 157 self.assertTrue(self.platform.exists(tmp_dir)) 158 self.assertFalse(self.platform.exists(tmp_dir / "foo")) 159 160 def test_touch(self): 161 with tempfile.TemporaryDirectory() as tmp_dirname: 162 tmp_file = pathlib.Path(tmp_dirname) / "test.txt" 163 self.assertFalse(tmp_file.exists()) 164 self.assertFalse(self.platform.exists(tmp_file)) 165 self.platform.touch(tmp_file) 166 self.assertTrue(tmp_file.exists()) 167 self.assertTrue(self.platform.exists(tmp_file)) 168 self.assertEqual(tmp_file.stat().st_size, 0) 169 170 def test_rename(self): 171 with tempfile.TemporaryDirectory() as tmp_dirname: 172 tmp_file = pathlib.Path(tmp_dirname) / "test.txt" 173 tmp_file_renamed = tmp_file.with_name("test_renamed.txt") 174 self.platform.touch(tmp_file) 175 self.assertTrue(tmp_file.exists()) 176 self.assertFalse(tmp_file_renamed.exists()) 177 result = self.platform.rename(tmp_file, tmp_file_renamed) 178 self.assertEqual(result, tmp_file_renamed) 179 self.assertFalse(tmp_file.exists()) 180 self.assertTrue(tmp_file_renamed.exists()) 181 182 def test_default_tmp_dir(self): 183 self.assertTrue(self.platform.is_dir(self.platform.default_tmp_dir)) 184 185 def test_NamedTemporaryFile(self): 186 with self.platform.NamedTemporaryFile("custom_prefix") as path: 187 self.assertIn("custom_prefix", str(path)) 188 self.assertTrue(self.platform.is_file(path)) 189 self.assertTrue(self.platform.exists(path)) 190 self.assertFalse(self.platform.exists(path)) 191 192 def test_copy(self): 193 with tempfile.TemporaryDirectory() as tmp_dirname: 194 src_file = pathlib.Path(tmp_dirname) / "src.txt" 195 dst_file = pathlib.Path(tmp_dirname) / "dst.txt" 196 with self.assertRaises(ValueError) as cm: 197 self.assertFalse(self.platform.exists(src_file)) 198 self.platform.copy(src_file, dst_file) 199 self.assertIn(str(src_file), str(cm.exception)) 200 self.assertFalse(self.platform.exists(src_file)) 201 self.assertFalse(self.platform.exists(dst_file)) 202 203 src_file.write_text("some data") 204 self.assertTrue(self.platform.exists(src_file)) 205 self.platform.copy(src_file, dst_file) 206 self.assertTrue(self.platform.exists(src_file)) 207 self.assertTrue(self.platform.exists(dst_file)) 208 self.assertEqual(self.platform.cat(src_file), "some data") 209 self.assertEqual(self.platform.cat(dst_file), "some data") 210 211 def test_home(self): 212 self.assertEqual(self.platform.home(), pathlib.Path.home()) 213 214 def test_absolute_absolute(self): 215 if self.platform.is_win: 216 absolute_path = pathlib.Path("C:/foo") 217 else: 218 absolute_path = pathlib.Path("/foo") 219 self.assertTrue(absolute_path.is_absolute()) 220 self.assertEqual(self.platform.absolute(absolute_path), absolute_path) 221 222 def test_absolute_relative(self): 223 if self.platform.is_remote: 224 self.skipTest("Not supported yet on remote platforms.") 225 relative_path = pathlib.Path("../../foo") 226 self.assertFalse(relative_path.is_absolute()) 227 self.assertEqual( 228 self.platform.absolute(relative_path), relative_path.absolute()) 229 230 def test_glob(self): 231 if self.platform.is_remote: 232 self.skipTest("Not supported yet on remote platforms.") 233 with tempfile.TemporaryDirectory() as tmp_dirname: 234 tmp_dir = pathlib.Path(tmp_dirname) 235 self.assertFalse(list(self.platform.glob(tmp_dir, "*"))) 236 a = tmp_dir / "a" 237 b = tmp_dir / "b" 238 self.platform.touch(a) 239 self.platform.touch(b) 240 self.assertListEqual(sorted(self.platform.glob(tmp_dir, "*")), [a, b]) 241 242 def test_set_file_contents(self): 243 if self.platform.is_remote: 244 self.skipTest("Not supported yet on remote platforms.") 245 with tempfile.TemporaryDirectory() as tmp_dirname: 246 tmp_file = pathlib.Path(tmp_dirname) / "test.txt" 247 self.assertFalse(self.platform.exists(tmp_file)) 248 self.platform.mkdir(tmp_file.parent) 249 self.platform.touch(tmp_file) 250 self.assertFalse(self.platform.cat(tmp_file)) 251 252 self.platform.set_file_contents(tmp_file, "custom data") 253 self.assertTrue(self.platform.exists(tmp_file)) 254 self.assertEqual(self.platform.cat(tmp_file), "custom data") 255 256 def test_set_file_contents_dir(self): 257 if self.platform.is_remote: 258 self.skipTest("Not supported yet on remote platforms.") 259 with tempfile.TemporaryDirectory() as tmp_dirname: 260 self.assertTrue(self.platform.is_dir(tmp_dirname)) 261 tmp_dir_path = self.platform.path(tmp_dirname) 262 self.assertTrue(self.platform.is_dir(tmp_dir_path)) 263 with self.assertRaises(Exception) as cm: 264 self.platform.set_file_contents(tmp_dirname, "data") 265 self.assertIn(tmp_dir_path.name, str(cm.exception)) 266 267 def test_path_tests(self): 268 with tempfile.TemporaryDirectory() as tmp_dirname: 269 tmp_dir = pathlib.Path(tmp_dirname) 270 self.assertTrue(self.platform.exists(tmp_dir)) 271 self.assertTrue(self.platform.is_dir(tmp_dir)) 272 self.assertFalse(self.platform.is_file(tmp_dir)) 273 274 foo_dir = tmp_dir / "foo" 275 self.assertFalse(self.platform.exists(foo_dir)) 276 self.assertFalse(self.platform.is_dir(foo_dir)) 277 self.assertFalse(self.platform.is_file(foo_dir)) 278 self.platform.mkdir(foo_dir) 279 self.assertTrue(self.platform.exists(foo_dir)) 280 self.assertTrue(self.platform.is_dir(foo_dir)) 281 self.assertFalse(self.platform.is_file(foo_dir)) 282 283 bar_file = tmp_dir / "bar.txt" 284 self.assertFalse(self.platform.exists(bar_file)) 285 self.assertFalse(self.platform.is_dir(bar_file)) 286 self.assertFalse(self.platform.is_file(bar_file)) 287 self.platform.touch(bar_file) 288 self.assertTrue(self.platform.exists(bar_file)) 289 self.assertFalse(self.platform.is_dir(bar_file)) 290 self.assertTrue(self.platform.is_file(bar_file)) 291 292 def test_cache_dir(self): 293 with self.platform.TemporaryDirectory() as tmp_dir: 294 try: 295 self.platform.set_cache_dir(tmp_dir) 296 cache_dir = self.platform.local_cache_dir("test") 297 self.assertTrue(self.platform.is_dir(cache_dir)) 298 self.assertEqual(cache_dir.parent, tmp_dir) 299 finally: 300 self.platform.rm(cache_dir, dir=True, missing_ok=True) 301 if self.platform.is_local: 302 self.platform.set_cache_dir(DEFAULT_CACHE_DIR) 303 304 def test_default_local_cache_dir(self): 305 if self.platform.is_remote: 306 return 307 cache_dir = self.platform.local_cache_dir() 308 try: 309 self.assertTrue(self.platform.is_dir(cache_dir)) 310 self.assertEqual(cache_dir, DEFAULT_CACHE_DIR) 311 finally: 312 self.platform.rm(cache_dir, dir=True, missing_ok=True) 313 314 def test_local_cache_dir(self): 315 if self.platform.is_remote: 316 return 317 cache_dir = self.platform.local_cache_dir("test") 318 try: 319 self.assertTrue(self.platform.is_dir(cache_dir)) 320 self.assertEqual(cache_dir.parent, DEFAULT_CACHE_DIR) 321 finally: 322 self.platform.rm(cache_dir, dir=True, missing_ok=True) 323 324 def test_has_display(self): 325 self.assertIn(self.platform.has_display, (True, False)) 326 327 def test_processes(self): 328 if self.platform.is_remote: 329 self.skipTest("Not supported yet on remote platforms.") 330 processes = self.platform.processes(["name"]) 331 self.assertTrue(processes) 332 for process_info in processes: 333 self.assertIn("name", process_info) 334 335 def test_process_running(self): 336 if self.platform.is_remote: 337 self.skipTest("Not supported yet on remote platforms.") 338 if self.platform.is_win: 339 self.skipTest("Too Slow on windows") 340 if test_helper.is_google_env(): 341 self.skipTest("Not supported yet in google environment.") 342 self.assertFalse(self.platform.process_running([])) 343 self.assertFalse( 344 self.platform.process_running(["crossbench_invalid_test_bin"])) 345 executable = pathlib.Path(sys.executable) 346 self.assertTrue(self.platform.process_running([executable.name])) 347 348 def test_process_info(self): 349 if self.platform.is_remote: 350 self.skipTest("Not supported yet on remote platforms.") 351 if test_helper.is_google_env(): 352 self.skipTest("Not supported yet in google environment.") 353 process_info = self.platform.process_info(os.getpid()) 354 self.assertIn("python", process_info["name"].lower()) 355 356 def test_process_children(self): 357 if self.platform.is_remote: 358 self.skipTest("Not supported yet on remote platforms.") 359 process_info = self.platform.process_children(os.getpid()) 360 self.assertIsInstance(process_info, list) 361 process_info = self.platform.process_children(os.getpid(), recursive=True) 362 self.assertIsInstance(process_info, list) 363 364 @unittest.skipIf( 365 not plt.PLATFORM.which("python3"), reason="python3 not installed") 366 def test_binary_lookup_override(self): 367 test_binary = "crossbench-non-existing-test-binary" 368 self.assertIsNone(self.platform.lookup_binary_override(test_binary)) 369 self.assertIsNone(self.platform.which(test_binary)) 370 # Use an arbitrary existing binary for testing. 371 override_binary = self.platform.which("python3") 372 self.assertTrue(override_binary) 373 with self.platform.override_binary(test_binary, override_binary): 374 self.assertEqual(self.platform.which(test_binary), override_binary) 375 with self.platform.override_binary(test_binary, None): 376 self.assertIsNone(self.platform.lookup_binary_override(test_binary)) 377 self.assertIsNone(self.platform.which(test_binary)) 378 self.assertEqual(self.platform.which(test_binary), override_binary) 379 self.assertIsNone(self.platform.lookup_binary_override(test_binary)) 380 self.assertIsNone(self.platform.which(test_binary)) 381 382 383@unittest.skipIf(not plt.PLATFORM.is_posix, "Incompatible platform") 384class PosixNativePlatformTestCase(NativePlatformTestCase): 385 platform: PosixPlatform 386 387 def setUp(self): 388 super().setUp() 389 assert isinstance(plt.PLATFORM, PosixPlatform) 390 self.platform: PosixPlatform = plt.PLATFORM 391 392 def test_sh(self): 393 ls = self.platform.sh_stdout("ls") 394 self.assertTrue(ls) 395 lsa = self.platform.sh_stdout("ls", "-a") 396 self.assertTrue(lsa) 397 self.assertNotEqual(ls, lsa) 398 399 def test_sh_bytes(self): 400 ls_bytes = self.platform.sh_stdout_bytes("ls") 401 self.assertIsInstance(ls_bytes, bytes) 402 ls_str = self.platform.sh_stdout("ls") 403 self.assertEqual(ls_str, ls_bytes.decode("utf-8")) 404 405 def test_which(self): 406 ls_bin = self.platform.which("ls") 407 self.assertIsNotNone(ls_bin) 408 bash_bin = self.platform.which("bash") 409 self.assertIsNotNone(bash_bin) 410 self.assertNotEqual(ls_bin, bash_bin) 411 self.assertTrue(pathlib.Path(ls_bin).exists()) 412 self.assertTrue(pathlib.Path(bash_bin).exists()) 413 414 def test_system_details(self): 415 details = self.platform.system_details() 416 self.assertTrue(details) 417 418 def test_search_binary(self): 419 result_path = self.platform.search_binary(pathlib.Path("ls")) 420 self.assertIsNotNone(result_path) 421 self.assertIn("ls", result_path.parts) 422 self.assertTrue(self.platform.exists(result_path)) 423 424 def test_search_binary_posix_lookup_override(self): 425 path = pathlib.Path("ls") 426 override = self.platform.which("cp") 427 with self.platform.override_binary(path, override): 428 result_path = self.platform.search_binary(path) 429 self.assertEqual(result_path, override) 430 self.assertTrue(self.platform.exists(result_path)) 431 432 result_path_2 = self.platform.search_binary(path) 433 self.assertNotEqual(result_path_2, result_path) 434 self.assertTrue(self.platform.exists(result_path_2)) 435 self.assertIsNone(self.platform.lookup_binary_override(path)) 436 437 def test_environ(self): 438 env = self.platform.environ 439 self.assertTrue(env) 440 self.assertIn("PATH", env) 441 self.assertTrue(list(env)) 442 443 def test_environ_set_property(self): 444 env = self.platform.environ 445 custom_key = f"CROSSBENCH_TEST_KEY_{len(env)}" 446 self.assertNotIn(custom_key, env) 447 with self.assertRaises(Exception): 448 env[custom_key] = 1234 449 env[custom_key] = "1234" 450 self.assertEqual(env[custom_key], "1234") 451 self.assertIn(custom_key, env) 452 del env[custom_key] 453 self.assertNotIn(custom_key, env) 454 455 def test_app_version(self): 456 if test_helper.is_google_env(): 457 self.skipTest("Not supported yet in google environment.") 458 python_path = sys.executable 459 with self.assertRaises(ValueError): 460 self.platform.app_version("path/to/invalid/test/crossbench/bin") 461 version = self.platform.app_version(python_path) 462 self.assertTrue(version) 463 464class MockRemotePosixPlatform(type(plt.PLATFORM)): 465 466 @property 467 def host_platform(self): 468 return plt.PLATFORM 469 470 def is_remote(self) -> bool: 471 return True 472 473 def local_path(self, path): 474 # override to bypass is_local checks 475 return pathlib.Path(path) 476 477 def sh(self, *args, **kwargs): 478 return plt.PLATFORM.sh(*args, **kwargs) 479 480 def sh_stdout(self, *args, **kwargs): 481 return plt.PLATFORM.sh_stdout(*args, **kwargs) 482 483 484@unittest.skipIf(not plt.PLATFORM.is_posix, "Incompatible platform") 485class MockRemotePosixPlatformTestCase(PosixNativePlatformTestCase): 486 """All Posix operations should also work on a remote platform (e.g. via SSH). 487 This test fakes this by temporarily changing the current PLATFORM's is_remote 488 getter to return True""" 489 490 def setUp(self): 491 super().setUp() 492 self.platform = MockRemotePosixPlatform() 493 494 def test_is_remote(self): 495 self.assertTrue(self.platform.is_remote) 496 497 def tests_default_tmp_dir(self): 498 self.assertEqual(self.platform.default_tmp_dir, 499 plt.PLATFORM.default_tmp_dir) 500 501 def test_environ_set_property(self): 502 raise self.skipTest("Not supported on remote platforms") 503 504 def test_cpu_usage(self): 505 raise self.skipTest("Not supported on remote platforms") 506 507 508@unittest.skipIf(not plt.PLATFORM.is_macos, "Incompatible platform") 509class MacOSNativePlatformTestCase(PosixNativePlatformTestCase): 510 platform: plt.MacOSPlatform 511 512 def setUp(self): 513 super().setUp() 514 assert isinstance(plt.PLATFORM, plt.MacOSPlatform) 515 self.platform = plt.PLATFORM 516 517 def test_search_app_binary_not_found(self): 518 binary = self.platform.search_binary(pathlib.Path("Invalid App Name")) 519 self.assertIsNone(binary) 520 binary = self.platform.search_binary(pathlib.Path("Non-existent App.app")) 521 self.assertIsNone(binary) 522 523 def test_search_app_binary(self): 524 binary = self.platform.search_binary(pathlib.Path("Safari.app")) 525 self.assertIsNotNone(binary) 526 self.assertTrue(self.platform.is_file(binary)) 527 # We should get the binary not the app bundle 528 self.assertFalse(binary.suffix, ".app") 529 self.assertEqual(binary.name, "Safari") 530 531 def test_search_app_binary_override(self): 532 override = pathlib.Path("/System/Applications/Calendar.app") 533 with self.platform.override_binary("Safari.app", override): 534 binary = self.platform.search_binary(pathlib.Path("Safari.app")) 535 self.assertIsNotNone(binary) 536 self.assertTrue(self.platform.is_file(binary)) 537 # We should get the binary not the app bundle 538 self.assertFalse(binary.suffix, ".app") 539 self.assertEqual(binary.name, "Calendar") 540 541 def test_search_app_invalid(self): 542 with self.assertRaises(ValueError): 543 self.platform.search_app(pathlib.Path("Invalid App Name")) 544 545 def test_search_app_none(self): 546 self.assertIsNone(self.platform.search_app(pathlib.Path("No App.app"))) 547 548 def test_search_app(self): 549 binary = self.platform.search_app(pathlib.Path("Safari.app")) 550 self.assertIsNotNone(binary) 551 self.assertTrue(self.platform.exists(binary)) 552 self.assertTrue(self.platform.is_dir(binary)) 553 554 def test_search_app_override(self): 555 override = pathlib.Path("/System/Applications/Calendar.app") 556 with self.platform.override_binary("Safari.app", override): 557 binary = self.platform.search_app(pathlib.Path("Safari.app")) 558 self.assertIsNotNone(binary) 559 self.assertTrue(self.platform.exists(binary)) 560 self.assertTrue(self.platform.is_dir(binary)) 561 self.assertEqual(binary.name, "Calendar.app") 562 563 def test_app_version_app(self): 564 app = self.platform.search_app(pathlib.Path("Safari.app")) 565 self.assertIsNotNone(app) 566 self.assertTrue(app.is_dir()) 567 version = self.platform.app_version(app) 568 self.assertRegex(version, r"[0-9]+\.[0-9]+") 569 570 def test_app_version_app_binary(self): 571 binary = self.platform.search_binary(pathlib.Path("Safari.app")) 572 self.assertIsNotNone(binary) 573 self.assertTrue(binary.is_file()) 574 version = self.platform.app_version(binary) 575 self.assertRegex(version, r"[0-9]+\.[0-9]+") 576 577 def test_app_version_binary(self): 578 binary = pathlib.Path("/usr/bin/safaridriver") 579 self.assertTrue(binary.is_file()) 580 version = self.platform.app_version(binary) 581 self.assertRegex(version, r"[0-9]+\.[0-9]+") 582 583 def test_name(self): 584 self.assertEqual(self.platform.name, "macos") 585 586 def test_version(self): 587 self.assertTrue(self.platform.version) 588 self.assertRegex(self.platform.version, r"[0-9]+\.[0-9]") 589 590 def test_device(self): 591 self.assertTrue(self.platform.device) 592 self.assertRegex(self.platform.device, r"[a-zA-Z]+[0-9]+,[0-9]+") 593 594 def test_cpu(self): 595 self.assertTrue(self.platform.cpu) 596 self.assertRegex(self.platform.cpu, r".* [0-9]+ cores") 597 598 def test_foreground_process(self): 599 self.assertTrue(self.platform.foreground_process()) 600 601 def test_is_macos(self): 602 self.assertTrue(self.platform.is_macos) 603 self.assertFalse(self.platform.is_linux) 604 self.assertFalse(self.platform.is_win) 605 self.assertFalse(self.platform.is_remote) 606 607 def test_set_main_screen_brightness(self): 608 prev_level = plt.PLATFORM.get_main_display_brightness() 609 brightness_level = 32 610 plt.PLATFORM.set_main_display_brightness(brightness_level) 611 self.assertEqual(brightness_level, 612 plt.PLATFORM.get_main_display_brightness()) 613 plt.PLATFORM.set_main_display_brightness(prev_level) 614 self.assertEqual(prev_level, plt.PLATFORM.get_main_display_brightness()) 615 616 def test_check_autobrightness(self): 617 self.platform.check_autobrightness() 618 619 def test_exec_apple_script(self): 620 self.assertEqual( 621 self.platform.exec_apple_script('copy "a value" to stdout').strip(), 622 "a value") 623 624 def test_exec_apple_script_args(self): 625 result = self.platform.exec_apple_script( # pylint: disable=assignment-from-no-return 626 "copy item 1 of argv to stdout", "a value", "b") 627 self.assertEqual(result.strip(), "a value") 628 result = self.platform.exec_apple_script( # pylint: disable=assignment-from-no-return 629 "copy item 2 of argv to stdout", "a value", "b") 630 self.assertEqual(result.strip(), "b") 631 632 def test_exec_apple_script_invalid(self): 633 with self.assertRaises(plt.SubprocessError): 634 self.platform.exec_apple_script("something is not right 11") 635 636 637@unittest.skipIf(not plt.PLATFORM.is_win, "Incompatible platform") 638class WinNativePlatformTestCase(NativePlatformTestCase): 639 platform: plt.WinPlatform 640 641 def setUp(self): 642 super().setUp() 643 assert isinstance(plt.PLATFORM, plt.WinPlatform) 644 self.platform = plt.PLATFORM 645 646 def test_sh(self): 647 ls = self.platform.sh_stdout("ls") 648 self.assertTrue(ls) 649 650 def test_search_binary(self): 651 with self.assertRaises(ValueError): 652 self.platform.search_binary(pathlib.Path("does not exist")) 653 path = self.platform.search_binary( 654 pathlib.Path("Windows NT/Accessories/wordpad.exe")) 655 self.assertTrue(path and path.exists()) 656 657 def test_app_version(self): 658 path = self.platform.search_binary( 659 pathlib.Path("Windows NT/Accessories/wordpad.exe")) 660 self.assertTrue(path and path.exists()) 661 version = self.platform.app_version(path) 662 self.assertIsNotNone(version) 663 664 def test_is_macos(self): 665 self.assertFalse(self.platform.is_macos) 666 self.assertFalse(self.platform.is_linux) 667 self.assertTrue(self.platform.is_win) 668 self.assertFalse(self.platform.is_remote) 669 670 def test_has_display(self): 671 self.assertIn(self.platform.has_display, (True, False)) 672 673 def test_version(self): 674 self.assertTrue(self.platform.version) 675 676 677if __name__ == "__main__": 678 test_helper.run_pytest(__file__) 679