adding API and tests for IOCTL requests (and bypassing casadm)#920
adding API and tests for IOCTL requests (and bypassing casadm)#920kajakoltan wants to merge 1 commit intoOpen-CAS:masterfrom
Conversation
Signed-off-by: Karolina Rogowska <karolina.rogowska@intel.com>
|
Hello @karolinavelkaja! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found: There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻 Comment last updated at 2021-08-12 12:44:45 UTC |
5c36023 to
6bcd126
Compare
| class CacheLineSize(Enum): | ||
| ocf_cache_line_size_4 = ctypes.c_ulonglong(4).value * KiB | ||
| ocf_cache_line_size_8 = ctypes.c_ulonglong(8).value * KiB | ||
| ocf_cache_line_size16 = ctypes.c_ulonglong(16).value * KiB | ||
| ocf_cache_line_size_32 = ctypes.c_ulonglong(32).value * KiB | ||
| ocf_cache_line_size_64 = ctypes.c_ulonglong(64).value * KiB | ||
| default = ocf_cache_line_size_4 |
There was a problem hiding this comment.
Why don't we use class Size for proper units and then convert bytes value to ctypes type?
| IOC_NRBITS = 8 | ||
| IOC_TYPEBITS = 8 | ||
| IOC_SIZEBITS = 14 | ||
| IOC_DIRBITS = 2 | ||
|
|
||
| IOC_NRMASK = (1 << IOC_NRBITS) - 1 # 255 | ||
| IOC_TYPEMASK = (1 << IOC_TYPEBITS) - 1 # 255 | ||
| IOC_SIZEMASK = (1 << IOC_SIZEBITS) - 1 # 16 383 | ||
| IOC_DIRMASK = (1 << IOC_DIRBITS) - 1 # 3 | ||
|
|
||
| IOC_NRSHIFT = 0 # 0 | ||
| IOC_TYPESHIFT = IOC_NRSHIFT + IOC_NRBITS # 8 | ||
| IOC_SIZESHIFT = IOC_TYPESHIFT + IOC_TYPEBITS # 16 | ||
| IOC_DIRSHIFT = IOC_SIZESHIFT + IOC_SIZEBITS # 30 | ||
|
|
||
| IOC_NONE = 0 | ||
| IOC_WRITE = 1 | ||
| IOC_READ = 2 | ||
|
|
||
| KCAS_IOCTL_MAGIC = 0xBA # 186 | ||
|
|
||
| IOC_IN = IOC_WRITE << IOC_DIRSHIFT # 1 073 741 824 | ||
| IOC_OUT = IOC_READ << IOC_DIRSHIFT # 2 147 483 648 | ||
| IOC_INOUT = (IOC_WRITE | IOC_READ) << IOC_DIRSHIFT # 3 221 225 472 | ||
| IOCSIZE_MASK = IOC_SIZEMASK << IOC_SIZESHIFT # 1 073 676 288 | ||
| IOCSIZE_SHIFT = IOC_SIZESHIFT # 16 | ||
|
|
||
|
|
||
| def IOC(dir, type, nr, size): | ||
| if dir > IOC_DIRMASK: | ||
| raise OverflowError(f"IO direction value {dir} exceeds {IOC_DIRMASK}") | ||
| dir <<= IOC_DIRSHIFT | ||
|
|
||
| if type > IOC_TYPEMASK: | ||
| raise OverflowError(f"IO type value {type} exceeds {IOC_TYPEMASK}") | ||
| type <<= IOC_TYPESHIFT | ||
|
|
||
| if nr > IOC_NRMASK: | ||
| raise OverflowError(f"IO command value {nr} exceeds {IOC_NRMASK}") | ||
| nr <<= IOC_NRSHIFT | ||
|
|
||
| if size > IOC_SIZEMASK: | ||
| raise OverflowError(f"IO size value {size} exceeds {IOC_SIZEMASK}") | ||
| size <<= IOC_SIZESHIFT | ||
|
|
||
| return dir | type | nr | size |
There was a problem hiding this comment.
There are libs for that https://pypi.org/project/ioctl-opt/
| def send_script_with_dumped_args(): | ||
| if not check_if_directory_exists(temp_dir): | ||
| create_directory(temp_dir, True) | ||
|
|
||
| TestRun.executor.rsync_to(script_source, script_dest) | ||
| chmod_numerical(script_dest, 550) | ||
|
|
||
| TestRun.executor.rsync_to(struct_path, struct_path) | ||
| chmod_numerical(struct_path, 440) |
There was a problem hiding this comment.
We finally have DUT-side scripting! ❤️
Although it may have been more generalized for use in other places (even as a part of TF).
| sleep(2) | ||
| TestRun.executor.kill_process(pid) |
There was a problem hiding this comment.
This function should at least take timeout as an argument. Otherwise it's unusable with commands like cache flush, which typically takes much longer than 2 seconds.
| if check_if_directory_exists(temp_dir): | ||
| remove(temp_dir, True, True, True) | ||
| if os.path.exists(struct_path): | ||
| os.remove(struct_path) |
There was a problem hiding this comment.
Virtually all ioctls handled by CAS return information from kernel via ioctl structure, which means we want to have a way to receive this information back from DUT once ioctl is finished.
|
|
||
|
|
||
| class RequestCode(Enum): | ||
| START_CACHE_CODE = ctypes.c_uint(21).value |
There was a problem hiding this comment.
What does this construct do? I just checked that type(c_uint(21).value) == int so its equivalent with START_CACHE_CODE = 21 (maybe aside from integer wraparound effects, but that doesn't seem to be needed here)
| interrupt_stop = [ | ||
| r"Waiting for cache stop interrupted\. Stop will finish asynchronously\." | ||
| ] | ||
|
|
||
| interrupt_start = [ | ||
| r"Cache added successfully, but waiting interrupted\. Rollback" | ||
| ] | ||
|
|
||
| load_and_force = [ | ||
| r"cache\d+: Using \'force\' flag is forbidden for load operation\." | ||
| ] |
There was a problem hiding this comment.
I don't think those messages should be in this file. Maybe more appropriate place would be in api/cas/cli_messages.py?
There was a problem hiding this comment.
or keep separate api/cas/ioctl/cli_messages.py
| def clear_dmesg(): | ||
| TestRun.executor.run_expect_success('dmesg -C') | ||
|
|
||
|
|
||
| def check_dmesg(searched_phrase: str): | ||
| dmesg_out = TestRun.executor.run_expect_success("dmesg").stdout | ||
| __check_string_msg(dmesg_out, searched_phrase) |
There was a problem hiding this comment.
Those as well, I think clearing/checking dmesg is more generic operation, not limited only to ioctl tests.
| TestRun.executor.rsync_to(script_source, script_dest) | ||
| chmod_numerical(script_dest, 550) | ||
|
|
||
| TestRun.executor.rsync_to(struct_path, struct_path) | ||
| chmod_numerical(struct_path, 440) |
| temp_dir = '/tmp/cas' | ||
| struct_path = os.path.join(temp_dir, 'dump_file') | ||
| script_source = os.path.join(f'{os.path.dirname(__file__)}', 'send_ioctl_script.py') | ||
| script_dest = os.path.join(temp_dir, 'send_ioctl_script.py') |
There was a problem hiding this comment.
struct_path and script_source and local (so os.path is ok), but script_dest is remote (so Linux - posixpath required)
both struct_path (local) and script_dest (remote) use the same temp_dir, which is posix-style
| interrupt_stop = [ | ||
| r"Waiting for cache stop interrupted\. Stop will finish asynchronously\." | ||
| ] | ||
|
|
||
| interrupt_start = [ | ||
| r"Cache added successfully, but waiting interrupted\. Rollback" | ||
| ] | ||
|
|
||
| load_and_force = [ | ||
| r"cache\d+: Using \'force\' flag is forbidden for load operation\." | ||
| ] |
There was a problem hiding this comment.
or keep separate api/cas/ioctl/cli_messages.py
| - Cache started successfully without any errors if 'force' and 'load' flags are not used. | ||
| - When 'force' and 'load' flags are used cache is not started. |
There was a problem hiding this comment.
| - Cache started successfully without any errors if 'force' and 'load' flags are not used. | |
| - When 'force' and 'load' flags are used cache is not started. | |
| - Cache started successfully without any errors if 'force' and 'load' flags are not used simultaneously. | |
| - When 'force' and 'load' flags are both used cache is not started. |
Initial/old reviews:
Signed-off-by: Karolina Rogowska karolina.rogowska@intel.com