1#!/usr/bin/env python 2# 3# Python-bindings handle type test script 4# 5# Copyright (C) 2010-2021, Joachim Metz <joachim.metz@gmail.com> 6# 7# Refer to AUTHORS for acknowledgements. 8# 9# This program is free software: you can redistribute it and/or modify 10# it under the terms of the GNU Lesser General Public License as published by 11# the Free Software Foundation, either version 3 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU Lesser General Public License 20# along with this program. If not, see <https://www.gnu.org/licenses/>. 21 22import argparse 23import random 24import os 25import sys 26import unittest 27 28import pysmraw 29 30 31class HandleTypeTests(unittest.TestCase): 32 """Tests the handle type.""" 33 34 def test_signal_abort(self): 35 """Tests the signal_abort function.""" 36 smraw_handle = pysmraw.handle() 37 38 smraw_handle.signal_abort() 39 40 def test_open(self): 41 """Tests the open function.""" 42 test_source = unittest.source 43 if not test_source: 44 raise unittest.SkipTest("missing source") 45 46 smraw_handle = pysmraw.handle() 47 filenames = pysmraw.glob(test_source) 48 49 smraw_handle.open(filenames) 50 51 with self.assertRaises(IOError): 52 smraw_handle.open(filenames) 53 54 smraw_handle.close() 55 56 with self.assertRaises(TypeError): 57 smraw_handle.open(None) 58 59 # TODO: add open write test. 60 61 def test_open_file_objects(self): 62 """Tests the open_file_objects function.""" 63 test_source = unittest.source 64 if not test_source: 65 raise unittest.SkipTest("missing source") 66 67 smraw_handle = pysmraw.handle() 68 69 filenames = pysmraw.glob(test_source) 70 file_objects = [] 71 for filename in filenames: 72 file_object = open(filename, "rb") 73 file_objects.append(file_object) 74 75 smraw_handle.open_file_objects(file_objects) 76 77 with self.assertRaises(IOError): 78 smraw_handle.open_file_objects(file_objects) 79 80 smraw_handle.close() 81 82 # TODO: change IOError into TypeError 83 with self.assertRaises(IOError): 84 smraw_handle.open_file_objects(None) 85 86 with self.assertRaises(ValueError): 87 smraw_handle.open_file_objects(file_objects, mode="w") 88 89 def test_close(self): 90 """Tests the close function.""" 91 test_source = unittest.source 92 if not test_source: 93 raise unittest.SkipTest("missing source") 94 95 smraw_handle = pysmraw.handle() 96 97 with self.assertRaises(IOError): 98 smraw_handle.close() 99 100 def test_open_close(self): 101 """Tests the open and close functions.""" 102 test_source = unittest.source 103 if not test_source: 104 return 105 106 smraw_handle = pysmraw.handle() 107 filenames = pysmraw.glob(test_source) 108 109 # Test open and close. 110 smraw_handle.open(filenames) 111 smraw_handle.close() 112 113 # Test open and close a second time to validate clean up on close. 114 smraw_handle.open(filenames) 115 smraw_handle.close() 116 117 file_object = open(test_source, "rb") 118 119 # Test open_file_objects and close. 120 smraw_handle.open_file_objects([file_object]) 121 smraw_handle.close() 122 123 # Test open_file_objects and close a second time to validate clean up on close. 124 smraw_handle.open_file_objects([file_object]) 125 smraw_handle.close() 126 127 # Test open_file_objects and close and dereferencing file_object. 128 smraw_handle.open_file_objects([file_object]) 129 del file_object 130 smraw_handle.close() 131 132 def test_read_buffer(self): 133 """Tests the read_buffer function.""" 134 test_source = unittest.source 135 if not test_source: 136 raise unittest.SkipTest("missing source") 137 138 smraw_handle = pysmraw.handle() 139 filenames = pysmraw.glob(test_source) 140 141 smraw_handle.open(filenames) 142 143 media_size = smraw_handle.get_media_size() 144 145 # Test read without maximum size. 146 smraw_handle.seek_offset(0, os.SEEK_SET) 147 148 data = smraw_handle.read_buffer() 149 150 self.assertIsNotNone(data) 151 self.assertEqual(len(data), media_size) 152 153 # Test read with maximum size. 154 smraw_handle.seek_offset(0, os.SEEK_SET) 155 156 data = smraw_handle.read_buffer(size=4096) 157 158 self.assertIsNotNone(data) 159 self.assertEqual(len(data), min(media_size, 4096)) 160 161 if media_size > 8: 162 smraw_handle.seek_offset(-8, os.SEEK_END) 163 164 # Read buffer on media_size boundary. 165 data = smraw_handle.read_buffer(size=4096) 166 167 self.assertIsNotNone(data) 168 self.assertEqual(len(data), 8) 169 170 # Read buffer beyond media_size boundary. 171 data = smraw_handle.read_buffer(size=4096) 172 173 self.assertIsNotNone(data) 174 self.assertEqual(len(data), 0) 175 176 # Stress test read buffer. 177 smraw_handle.seek_offset(0, os.SEEK_SET) 178 179 remaining_media_size = media_size 180 181 for _ in range(1024): 182 read_size = int(random.random() * 4096) 183 184 data = smraw_handle.read_buffer(size=read_size) 185 186 self.assertIsNotNone(data) 187 188 data_size = len(data) 189 190 if read_size > remaining_media_size: 191 read_size = remaining_media_size 192 193 self.assertEqual(data_size, read_size) 194 195 remaining_media_size -= data_size 196 197 if not remaining_media_size: 198 smraw_handle.seek_offset(0, os.SEEK_SET) 199 200 remaining_media_size = media_size 201 202 with self.assertRaises(ValueError): 203 smraw_handle.read_buffer(size=-1) 204 205 smraw_handle.close() 206 207 # Test the read without open. 208 with self.assertRaises(IOError): 209 smraw_handle.read_buffer(size=4096) 210 211 def test_read_buffer_file_objects(self): 212 """Tests the read_buffer function on file-like objects.""" 213 test_source = unittest.source 214 if not test_source: 215 raise unittest.SkipTest("missing source") 216 217 file_object = open(test_source, "rb") 218 219 smraw_handle = pysmraw.handle() 220 221 smraw_handle.open_file_objects([file_object]) 222 223 media_size = smraw_handle.get_media_size() 224 225 # Test normal read. 226 data = smraw_handle.read_buffer(size=4096) 227 228 self.assertIsNotNone(data) 229 self.assertEqual(len(data), min(media_size, 4096)) 230 231 smraw_handle.close() 232 233 def test_read_buffer_at_offset(self): 234 """Tests the read_buffer_at_offset function.""" 235 test_source = unittest.source 236 if not test_source: 237 raise unittest.SkipTest("missing source") 238 239 smraw_handle = pysmraw.handle() 240 filenames = pysmraw.glob(test_source) 241 242 smraw_handle.open(filenames) 243 244 media_size = smraw_handle.get_media_size() 245 246 # Test normal read. 247 data = smraw_handle.read_buffer_at_offset(4096, 0) 248 249 self.assertIsNotNone(data) 250 self.assertEqual(len(data), min(media_size, 4096)) 251 252 if media_size > 8: 253 # Read buffer on media_size boundary. 254 data = smraw_handle.read_buffer_at_offset(4096, media_size - 8) 255 256 self.assertIsNotNone(data) 257 self.assertEqual(len(data), 8) 258 259 # Read buffer beyond media_size boundary. 260 data = smraw_handle.read_buffer_at_offset(4096, media_size + 8) 261 262 self.assertIsNotNone(data) 263 self.assertEqual(len(data), 0) 264 265 # Stress test read buffer. 266 for _ in range(1024): 267 random_number = random.random() 268 269 media_offset = int(random_number * media_size) 270 read_size = int(random_number * 4096) 271 272 data = smraw_handle.read_buffer_at_offset(read_size, media_offset) 273 274 self.assertIsNotNone(data) 275 276 remaining_media_size = media_size - media_offset 277 278 data_size = len(data) 279 280 if read_size > remaining_media_size: 281 read_size = remaining_media_size 282 283 self.assertEqual(data_size, read_size) 284 285 remaining_media_size -= data_size 286 287 if not remaining_media_size: 288 smraw_handle.seek_offset(0, os.SEEK_SET) 289 290 with self.assertRaises(ValueError): 291 smraw_handle.read_buffer_at_offset(-1, 0) 292 293 with self.assertRaises(ValueError): 294 smraw_handle.read_buffer_at_offset(4096, -1) 295 296 smraw_handle.close() 297 298 # Test the read without open. 299 with self.assertRaises(IOError): 300 smraw_handle.read_buffer_at_offset(4096, 0) 301 302 def test_seek_offset(self): 303 """Tests the seek_offset function.""" 304 test_source = unittest.source 305 if not test_source: 306 raise unittest.SkipTest("missing source") 307 308 smraw_handle = pysmraw.handle() 309 filenames = pysmraw.glob(test_source) 310 311 smraw_handle.open(filenames) 312 313 media_size = smraw_handle.get_media_size() 314 315 smraw_handle.seek_offset(16, os.SEEK_SET) 316 317 offset = smraw_handle.get_offset() 318 self.assertEqual(offset, 16) 319 320 smraw_handle.seek_offset(16, os.SEEK_CUR) 321 322 offset = smraw_handle.get_offset() 323 self.assertEqual(offset, 32) 324 325 smraw_handle.seek_offset(-16, os.SEEK_CUR) 326 327 offset = smraw_handle.get_offset() 328 self.assertEqual(offset, 16) 329 330 if media_size > 16: 331 smraw_handle.seek_offset(-16, os.SEEK_END) 332 333 offset = smraw_handle.get_offset() 334 self.assertEqual(offset, media_size - 16) 335 336 smraw_handle.seek_offset(16, os.SEEK_END) 337 338 offset = smraw_handle.get_offset() 339 self.assertEqual(offset, media_size + 16) 340 341 # TODO: change IOError into ValueError 342 with self.assertRaises(IOError): 343 smraw_handle.seek_offset(-1, os.SEEK_SET) 344 345 # TODO: change IOError into ValueError 346 with self.assertRaises(IOError): 347 smraw_handle.seek_offset(-32 - media_size, os.SEEK_CUR) 348 349 # TODO: change IOError into ValueError 350 with self.assertRaises(IOError): 351 smraw_handle.seek_offset(-32 - media_size, os.SEEK_END) 352 353 # TODO: change IOError into ValueError 354 with self.assertRaises(IOError): 355 smraw_handle.seek_offset(0, -1) 356 357 smraw_handle.close() 358 359 # Test the seek without open. 360 with self.assertRaises(IOError): 361 smraw_handle.seek_offset(16, os.SEEK_SET) 362 363 def test_get_offset(self): 364 """Tests the get_offset function and offset property.""" 365 test_source = unittest.source 366 if not test_source: 367 raise unittest.SkipTest("missing source") 368 369 smraw_handle = pysmraw.handle() 370 filenames = pysmraw.glob(test_source) 371 smraw_handle.open(filenames) 372 373 offset = smraw_handle.get_offset() 374 self.assertIsNotNone(offset) 375 376 smraw_handle.close() 377 378 def test_get_media_size(self): 379 """Tests the get_media_size function and media_size property.""" 380 test_source = unittest.source 381 if not test_source: 382 raise unittest.SkipTest("missing source") 383 384 smraw_handle = pysmraw.handle() 385 filenames = pysmraw.glob(test_source) 386 smraw_handle.open(filenames) 387 388 media_size = smraw_handle.get_media_size() 389 self.assertIsNotNone(media_size) 390 391 self.assertIsNotNone(smraw_handle.media_size) 392 393 smraw_handle.close() 394 395 396if __name__ == "__main__": 397 argument_parser = argparse.ArgumentParser() 398 399 argument_parser.add_argument( 400 "source", nargs="?", action="store", metavar="PATH", 401 default=None, help="path of the source file.") 402 403 options, unknown_options = argument_parser.parse_known_args() 404 unknown_options.insert(0, sys.argv[0]) 405 406 setattr(unittest, "source", options.source) 407 408 unittest.main(argv=unknown_options, verbosity=2) 409