file_move_safe() ignores PermissionError thrown by copystat() and copymode(). For example, PermissionError can be raised when the destination filesystem is CIFS, or when relabel is disabled by SELinux across filesystems.
(self)
| 444 | os.close(handle_b) |
| 445 | |
| 446 | def test_file_move_permissionerror(self): |
| 447 | """ |
| 448 | file_move_safe() ignores PermissionError thrown by copystat() and |
| 449 | copymode(). |
| 450 | For example, PermissionError can be raised when the destination |
| 451 | filesystem is CIFS, or when relabel is disabled by SELinux across |
| 452 | filesystems. |
| 453 | """ |
| 454 | permission_error = PermissionError(errno.EPERM, "msg") |
| 455 | os_error = OSError("msg") |
| 456 | handle_a, self.file_a = tempfile.mkstemp() |
| 457 | handle_b, self.file_b = tempfile.mkstemp() |
| 458 | handle_c, self.file_c = tempfile.mkstemp() |
| 459 | try: |
| 460 | # This exception is required to reach the copystat() call in |
| 461 | # file_safe_move(). |
| 462 | with mock.patch("django.core.files.move.os.rename", side_effect=OSError()): |
| 463 | # An error besides PermissionError isn't ignored. |
| 464 | with mock.patch( |
| 465 | "django.core.files.move.copystat", side_effect=os_error |
| 466 | ): |
| 467 | with self.assertRaises(OSError): |
| 468 | file_move_safe(self.file_a, self.file_b, allow_overwrite=True) |
| 469 | # When copystat() throws PermissionError, copymode() error |
| 470 | # besides PermissionError isn't ignored. |
| 471 | with mock.patch( |
| 472 | "django.core.files.move.copystat", side_effect=permission_error |
| 473 | ): |
| 474 | with mock.patch( |
| 475 | "django.core.files.move.copymode", side_effect=os_error |
| 476 | ): |
| 477 | with self.assertRaises(OSError): |
| 478 | file_move_safe( |
| 479 | self.file_a, self.file_b, allow_overwrite=True |
| 480 | ) |
| 481 | # PermissionError raised by copystat() is ignored. |
| 482 | with mock.patch( |
| 483 | "django.core.files.move.copystat", side_effect=permission_error |
| 484 | ): |
| 485 | self.assertIsNone( |
| 486 | file_move_safe(self.file_a, self.file_b, allow_overwrite=True) |
| 487 | ) |
| 488 | # PermissionError raised by copymode() is ignored too. |
| 489 | with mock.patch( |
| 490 | "django.core.files.move.copymode", side_effect=permission_error |
| 491 | ): |
| 492 | self.assertIsNone( |
| 493 | file_move_safe( |
| 494 | self.file_c, self.file_b, allow_overwrite=True |
| 495 | ) |
| 496 | ) |
| 497 | finally: |
| 498 | os.close(handle_a) |
| 499 | os.close(handle_b) |
| 500 | os.close(handle_c) |
| 501 | |
| 502 | def test_file_move_ensure_truncation(self): |
| 503 | with tempfile.NamedTemporaryFile(delete=False) as src: |
nothing calls this directly
no test coverage detected