Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 1 | """Tests for the logfiles REST API.""" |
| 2 | |
| 3 | import os |
Mitja Nikolaus | c2da285 | 2018-10-04 15:09:11 +0200 | [diff] [blame] | 4 | import zipfile |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 5 | |
| 6 | from django.urls import reverse |
| 7 | |
| 8 | from rest_framework import status |
| 9 | |
Mitja Nikolaus | c2da285 | 2018-10-04 15:09:11 +0200 | [diff] [blame] | 10 | from crashreports.models import crashreport_file_name, Device |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 11 | from crashreports.tests.utils import HiccupCrashreportsAPITestCase, Dummy |
| 12 | |
| 13 | |
| 14 | class LogfileUploadTest(HiccupCrashreportsAPITestCase): |
| 15 | """Test cases for upload of log files.""" |
| 16 | |
| 17 | LIST_CREATE_URL = "api_v1_crashreports" |
| 18 | PUT_LOGFILE_URL = "api_v1_putlogfile_for_device_id" |
| 19 | |
Mitja Nikolaus | 188bca6 | 2018-10-04 15:17:48 +0200 | [diff] [blame^] | 20 | def setUp(self): |
| 21 | """Call the super setup method and register a device.""" |
| 22 | super().setUp() |
| 23 | self.device_uuid, self.user, _ = self._register_device() |
| 24 | |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 25 | def _upload_crashreport(self, user, uuid): |
| 26 | """ |
| 27 | Upload dummy crashreport data. |
| 28 | |
| 29 | Args: |
| 30 | user: The user which should be used for uploading the report |
| 31 | uuid: The uuid of the device to which the report should be uploaded |
| 32 | |
| 33 | Returns: The local id of the device for which the report was uploaded. |
| 34 | |
| 35 | """ |
| 36 | data = Dummy.crashreport_data(uuid=uuid) |
| 37 | response = user.post(reverse(self.LIST_CREATE_URL), data) |
| 38 | self.assertEqual(status.HTTP_201_CREATED, response.status_code) |
| 39 | self.assertTrue("device_local_id" in response.data) |
| 40 | device_local_id = response.data["device_local_id"] |
| 41 | |
| 42 | return device_local_id |
| 43 | |
Mitja Nikolaus | c2da285 | 2018-10-04 15:09:11 +0200 | [diff] [blame] | 44 | def _assert_zip_file_contents_equal(self, file1, file2): |
| 45 | """Assert that the files within two zip files are equal.""" |
| 46 | zip_file_1 = zipfile.ZipFile(file1) |
| 47 | zip_file_2 = zipfile.ZipFile(file2) |
| 48 | for file_name_1, file_name_2 in zip( |
| 49 | zip_file_1.filelist, zip_file_2.filelist |
| 50 | ): |
| 51 | file_1 = zip_file_1.open(file_name_1) |
| 52 | file_2 = zip_file_2.open(file_name_2) |
| 53 | |
| 54 | self.assertEqual(file_1.read(), file_2.read()) |
| 55 | |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 56 | def _test_logfile_upload(self, user, uuid): |
| 57 | # Upload crashreport |
| 58 | device_local_id = self._upload_crashreport(user, uuid) |
| 59 | |
| 60 | # Upload a logfile for the crashreport |
Mitja Nikolaus | 6e11847 | 2018-10-04 11:15:29 +0200 | [diff] [blame] | 61 | logfile = open(Dummy.DEFAULT_DUMMY_LOG_FILE_PATH, "rb") |
| 62 | |
Mitja Nikolaus | c2da285 | 2018-10-04 15:09:11 +0200 | [diff] [blame] | 63 | logfile_name = os.path.basename(logfile.name) |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 64 | response = user.post( |
| 65 | reverse( |
Mitja Nikolaus | c2da285 | 2018-10-04 15:09:11 +0200 | [diff] [blame] | 66 | self.PUT_LOGFILE_URL, args=[uuid, device_local_id, logfile_name] |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 67 | ), |
| 68 | {"file": logfile}, |
| 69 | format="multipart", |
| 70 | ) |
Mitja Nikolaus | 6e11847 | 2018-10-04 11:15:29 +0200 | [diff] [blame] | 71 | logfile.close() |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 72 | self.assertEqual(status.HTTP_201_CREATED, response.status_code) |
| 73 | |
Mitja Nikolaus | c2da285 | 2018-10-04 15:09:11 +0200 | [diff] [blame] | 74 | logfile_instance = ( |
| 75 | Device.objects.get(uuid=uuid) |
| 76 | .crashreports.get(device_local_id=device_local_id) |
| 77 | .logfiles.last() |
| 78 | ) |
| 79 | uploaded_logfile_path = crashreport_file_name( |
| 80 | logfile_instance, logfile_name |
| 81 | ) |
| 82 | |
| 83 | self.assertTrue(os.path.isfile(uploaded_logfile_path)) |
| 84 | # The files are not 100% equal, because the server adds some extra |
| 85 | # bytes. However, we mainly care that the contents are equal: |
| 86 | self._assert_zip_file_contents_equal( |
| 87 | uploaded_logfile_path, Dummy.DEFAULT_DUMMY_LOG_FILE_PATH |
| 88 | ) |
| 89 | |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 90 | def test_logfile_upload_as_user(self): |
| 91 | """Test upload of logfiles as device owner.""" |
Mitja Nikolaus | 188bca6 | 2018-10-04 15:17:48 +0200 | [diff] [blame^] | 92 | self._test_logfile_upload(self.user, self.device_uuid) |
Mitja Nikolaus | 03e412b | 2018-09-18 17:50:15 +0200 | [diff] [blame] | 93 | |
| 94 | def test_logfile_upload_as_admin(self): |
| 95 | """Test upload of logfiles as admin user.""" |
Mitja Nikolaus | 188bca6 | 2018-10-04 15:17:48 +0200 | [diff] [blame^] | 96 | self._test_logfile_upload(self.admin, self.device_uuid) |
| 97 | |
| 98 | def tearDown(self): |
| 99 | """Remove the file and directories that were created for the test.""" |
| 100 | device = Device.objects.get(uuid=self.device_uuid) |
| 101 | for crashreport_instance in device.crashreports.all(): |
| 102 | for logfile_instance in crashreport_instance.logfiles.all(): |
| 103 | uploaded_logfile_path = crashreport_file_name( |
| 104 | logfile_instance, |
| 105 | os.path.basename(Dummy.DEFAULT_DUMMY_LOG_FILE_PATH), |
| 106 | ) |
| 107 | try: |
| 108 | os.remove(uploaded_logfile_path) |
| 109 | os.removedirs(os.path.dirname(uploaded_logfile_path)) |
| 110 | except (FileNotFoundError, OSError): |
| 111 | pass |