def test_verify_flushes(): TestRun.LOGGER.info("Testing io events during tracing") iotrace = TestRun.plugins['iotrace'] for disk in TestRun.dut.disks: with TestRun.step("Start tracing"): iotrace.start_tracing([disk.system_path]) time.sleep(5) with TestRun.step("Run test workload with sync"): fio = (Fio().create_command().io_engine(IoEngine.sync).block_size( Size(4, Unit.KibiByte)).time_based().read_write( ReadWrite.randwrite).target( disk.system_path).direct(value=False).run_time( datetime.timedelta(seconds=10)).fsync(value=1)) fio.run() with TestRun.step("Stop tracing"): iotrace.stop_tracing() with TestRun.step("Verify trace correctness"): trace_path = IotracePlugin.get_latest_trace_path() events_parsed = IotracePlugin.get_trace_events(trace_path) result = any('io' in event and 'fua' in event['io'] and bool( event['io']['fua'] is True) for event in events_parsed) if not result: TestRun.fail("Could not find event with fua") result = any('io' in event and 'flush' in event['io'] and bool( event['io']['flush'] is True) for event in events_parsed) if not result: TestRun.fail("Could not find event with flush") result = all( 'flush' in event['io'] and bool(event['io']['flush']) is True for event in filter( lambda event: 'io' in event and 'lba' in event['io'] and int(event['io']['lba']) == 0 and int(event['io'][ 'len']) == 0, events_parsed)) if not result: TestRun.fail( "All events with lba 0 and len 0 should have flush")
def test_io_events(): TestRun.LOGGER.info("Testing io events during tracing") iotrace = TestRun.plugins['iotrace'] for disk in TestRun.dut.disks: with TestRun.step("Start tracing"): iotrace.start_tracing([disk.system_path]) time.sleep(5) with TestRun.step("Send write command"): write_length = Size(17, disk.block_size) write_offset = 2 * write_length.get_value() dd = (Dd().input("/dev/urandom").output(disk.system_path).count( 1).block_size(write_length).oflag('direct,sync').seek( int(write_offset / write_length.get_value()))) dd.run() with TestRun.step("Send read command"): read_length = Size(19, disk.block_size) read_offset = 2 * read_length.get_value() dd = (Dd().input(disk.system_path).output("/dev/null").count( 1).block_size(read_length).iflag('direct,sync').skip( int(read_offset / read_length.get_value()))) dd.run() with TestRun.step("Send discard command"): discard_length = Size(21, disk.block_size).get_value() discard_offset = int(2 * discard_length) TestRun.executor.run_expect_success( f"blkdiscard -o {discard_offset}" f" -l {int(discard_length)} {disk.system_path}") with TestRun.step("Stop tracing"): iotrace.stop_tracing() with TestRun.step("Verify trace correctness"): trace_path = IotracePlugin.get_latest_trace_path() events_parsed = IotracePlugin.get_trace_events(trace_path) result = any( 'io' in event and 'operation' in event['io'] and event['io']['operation'] == 'Write' # LBA 0 events don't have a lba field, so skip them and 'lba' in event['io'] and int(event['io']['lba']) == int( write_offset / iotrace_lba_len) and int(event['io']['len']) == int(write_length.get_value() / iotrace_lba_len) and f"/dev/{event['device']['name']}" == disk.system_path for event in events_parsed) if not result: TestRun.fail("Could not find write event") result = any( 'io' in event and 'operation' in event['io'] and event['io']['operation'] == 'Read' # LBA 0 events don't have a lba field, so skip them and 'lba' in event['io'] and int(event['io']['lba']) == int( read_offset / iotrace_lba_len) and int(event['io']['len']) == int(read_length.get_value() / iotrace_lba_len) and f"/dev/{event['device']['name']}" == disk.system_path for event in events_parsed) if not result: TestRun.fail("Could not find read event") result = any('io' in event and 'operation' in event['io'] and event['io']['operation'] == 'Discard' # LBA 0 events don't have a lba field, so skip them and 'lba' in event['io'] and int(event['io']['lba']) == int(discard_offset / iotrace_lba_len) and int(event['io']['len']) == int(discard_length / iotrace_lba_len) and f"/dev/{event['device']['name']}" == disk.system_path for event in events_parsed) if not result: TestRun.fail("Could not find discard event")
def test_fs_operations(): TestRun.LOGGER.info("Testing file system events during tracing") iotrace = TestRun.plugins['iotrace'] for disk in TestRun.dut.disks: try: with TestRun.step("Create file system"): disk.create_filesystem(Filesystem.ext4) with TestRun.step("Mount device"): disk.mount(mountpoint) with TestRun.step("Start tracing"): iotrace.start_tracing([disk.system_path]) time.sleep(5) with TestRun.step("Create test directory and file"): write_file(f"{mountpoint}/test_file", content="foo") sync() test_file_inode = get_inode(f"{mountpoint}/test_file") create_directory(f"{mountpoint}/test_dir") sync() with TestRun.step("Write to test file"): write_file(f"{mountpoint}/test_file", overwrite=False, content="bar") sync() with TestRun.step("Create new test file"): create_file(f"{mountpoint}/test_file2") test_file2_inode = get_inode(f"{mountpoint}/test_file2") sync() with TestRun.step("Move test file"): move(f"{mountpoint}/test_file", f"{mountpoint}/test_dir") sync() with TestRun.step("Delete test file"): remove(f"{mountpoint}/test_dir/test_file") sync() with TestRun.step("Stop tracing"): sync() iotrace.stop_tracing() with TestRun.step("Verify trace correctness"): trace_path = IotracePlugin.get_latest_trace_path() events_parsed = IotracePlugin.get_trace_events(trace_path) result = any( 'file' in event and event['file']['eventType'] == 'Create' and event['file']['id'] == test_file2_inode for event in events_parsed) if not result: raise Exception("Could not find Create event") result = any( 'file' in event and event['file']['eventType'] == 'Delete' and event['file']['id'] == test_file_inode for event in events_parsed) if not result: raise Exception("Could not find Delete event") result = any( 'file' in event and event['file']['eventType'] == 'MoveTo' and event['file']['id'] == test_file_inode for event in events_parsed) if not result: raise Exception("Could not find MoveTo event") result = any( 'file' in event and event['file']['eventType'] == 'MoveFrom' and event['file']['id'] == test_file_inode for event in events_parsed) if not result: raise Exception("Could not find MoveFrom event") result = any( 'file' in event and event['file']['eventType'] == 'Access' and event['file']['id'] == test_file_inode for event in events_parsed) if not result: raise Exception("Could not find Access event") finally: with TestRun.step("Unmount device"): disk.unmount()