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")
Example #3
0
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()