Skip to content

Commit

Permalink
d fs_mark harness
Browse files Browse the repository at this point in the history
JIRA: CI-307
  • Loading branch information
adamdebek committed Dec 5, 2023
1 parent c789b19 commit cef2eb5
Show file tree
Hide file tree
Showing 12 changed files with 1,232 additions and 1 deletion.
1 change: 1 addition & 0 deletions fs_mark/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$(eval $(call add_test, fs_mark_clean))
158 changes: 158 additions & 0 deletions fs_mark/fs_mark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import trunner
import time
import re
import pexpect
import timing_data as t_data
import psh.tools.psh as psh

from trunner.ctx import TestContext
from trunner.dut import Dut
from trunner.types import TestResult, Status


def clean(dut, test_name, ctx: TestContext) -> int:
# Dummyfs doesn't need clean since target is rebooted after every test
if not ctx.target.rootfs:
return 0

if test_name and ('-k' in test_name or '-L' in test_name or '-F' in test_name):
args = test_name.split()
args = args[1:]

def get_dir(x):
if args[x[0] - 1] == '-d':
return x[1]

dirs = list(map(lambda x: get_dir(x), enumerate(args)))
dirs = [x for x in dirs if x is not None]

dut.expect(re.escape(ctx.target.shell_prompt), timeout=120)
psh._send(dut, f'/bin/fs_mark_clean {" ".join(dirs)}')
try:
idx = dut.expect([re.escape(ctx.target.shell_prompt),
r".+?Error in remove_dir_recursive.+?"], timeout=1800)

if idx == 1:
return -1
elif idx == 0:
return 0
except pexpect.TIMEOUT:
return -2
else:
return 0


def harness(dut: Dut, ctx: TestContext, result: TestResult):
target = trunner.ctx.target.name
test_status = Status.OK

test_name = None
test_msg = ''

loop_start = None
loop_end = None
loop_time = 1200
first_loop_done = False

NAME = r".+?# (?P<name>(/bin/)?fs_mark.+?)\r+\n"
MSG_LINE = r"(?P<line>(\s+\d+){3}.+?)\r+\n"
NO_SPC = r"Insufficient free space.+?\r+\n"
END = r"Average Files/sec:.+?\r+\n"
ERR = r".+?(?P<err>EIO|ENOSPC|ENOMEM).+?"
NO_CONT_BLOCK = r"(?P<msg>Lack of contiguous memory block of size \d+ bytes.+?)\r+\n"

while True:
if loop_start and loop_end:
loop_time = 3 * (loop_end - loop_start)
loop_start = None
loop_end = None

try:
idx = dut.expect([
NAME,
MSG_LINE,
NO_SPC,
END,
NO_CONT_BLOCK,
ERR
], timeout=loop_time)
parsed = dut.match.groupdict()

except pexpect.TIMEOUT:
test_msg = 'Got timeout, probably fs hang-up'
test_status = Status.FAIL
break

if idx == 0:
test_name = parsed["name"]
loop_start = time.time()
elif idx == 1:
first_loop_done = True
splitted_line = parsed["line"].split()
f_use = splitted_line[0]
count = splitted_line[1]
size = splitted_line[2]
files_sec = splitted_line[3]
app_overhead = splitted_line[4]

line_dict = {}
line_dict['creatMin'] = splitted_line[5]
line_dict['creatAvg'] = splitted_line[6]
line_dict['creatMax'] = splitted_line[7]
line_dict['writeMin'] = splitted_line[8]
line_dict['writeAvg'] = splitted_line[9]
line_dict['writeMax'] = splitted_line[10]
line_dict['closeMin'] = splitted_line[17]
line_dict['closeAvg'] = splitted_line[18]
line_dict['closeMax'] = splitted_line[19]

# If files are kept, fs_mark will unlink them so unlink time can be caught
if not ('-k' in test_name or '-L' in test_name or '-F' in test_name):
line_dict['unlinkMin'] = splitted_line[20]
line_dict['unlinkAvg'] = splitted_line[21]
line_dict['unlinkMax'] = splitted_line[22]

for name, value in line_dict.items():
if not t_data.timing_dict[(target, name)][0] <= int(value) <= t_data.timing_dict[(target, name)][1]:
test_status = Status.FAIL
test_msg += ''.join(('\n\t', name, ' exec time - ', value, ' out of range [',
str(t_data.timing_dict[(target, name)][0]), ' - ',
str(t_data.timing_dict[(target, name)][1]), ']'))

if test_status == Status.FAIL:
test_msg += "\n\n\tF_Use%: " + str(f_use)
test_msg += "\n\tCount: " + str(count)
test_msg += "\n\tSize: " + str(size)
test_msg += "\n\tFiles/sec: " + str(files_sec)
test_msg += "\n\tApp overhead: " + str(app_overhead) + "\n\t"
break

elif idx in [2, 3, 4]:
# Tests have to run at least 1 loop
if not first_loop_done:
test_status = Status.FAIL
if idx == 2:
test_msg = 'Insufficient free space'
elif idx == 3:
loop_end = time.time()
test_msg = 'Got no timings'
elif idx == 4:
test_msg = parsed['msg']

break
elif idx == 5:
test_msg = parsed['err']
test_status = Status.FAIL
break

ret = clean(dut, test_name, ctx)
if ret < 0 and first_loop_done:
test_status = Status.FAIL
msg = ''
if ret == -1:
msg = 'Error while cleaning'
elif ret == -2:
msg = 'Timeout during cleaning'
test_msg = msg

return TestResult(name=test_name, msg=test_msg, status=test_status)
95 changes: 95 additions & 0 deletions fs_mark/fs_mark_clean.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Phoenix-RTOS
*
* Cleanup after fs_mark (executed with files kept).
*
* Copyright 2023 Phoenix Systems
* Author: Adam Debek
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <stdint.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <limits.h>

int remove_dir_recursive(const char *dirPath)
{
DIR *dir;
char entryPath[PATH_MAX];
struct dirent *entry;
int (*remove_func)(const char *);
int ret, try = 0;

dir = opendir(dirPath);
if (dir == NULL) {
fprintf(stderr, "Opendir() failed errno: %s\n", strerror(errno));
return -1;
}

if (dir) {
while ((entry = readdir(dir)) != NULL) {
if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name)) {
continue;
}
sprintf(entryPath, "%s/%s", dirPath, entry->d_name);
remove_func = entry->d_type == DT_DIR ? remove_dir_recursive : remove;
if (remove_func(entryPath) != 0) {
closedir(dir);
return -1;
}
}

if (closedir(dir)) {
return -1;
}
}

errno = 0;
while ((ret = rmdir(dirPath)) < 0 && errno == ENOTEMPTY && try < 5) {
remove_dir_recursive(dirPath);
try++;
}

if (try == 5) {
return -1;
}
else {
return ret;
}
}

int main(int argc, char **argv)
{
int i;
DIR *dir;

if (argc < 2) {
fprintf(stderr, "Usage: %s [dir1] ... [dirN]\n", argv[0]);
return 1;
}

for (i = 1; i < argc; i++) {
if ((dir = opendir(argv[i])) == NULL && errno == ENOENT) {
closedir(dir);
fprintf(stderr, "Nonexistent directory name\n");
return 1;
}
/* Clean test directory */
errno = 0;
if (remove_dir_recursive(argv[i]) < 0) {
fprintf(stderr, "Error in remove_dir_recursive() errno: %s\n", strerror(errno));
return 1;
}
}

fprintf(stderr, "Clean successful\n");
return 0;
}
132 changes: 132 additions & 0 deletions fs_mark/test_armv7a7-imx6ull-evk.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# This yaml contain armv7a7-imx6ull-evk specific fs_mark tests
test:
type: harness
harness: fs_mark.py
# nightly: true

targets:
value: [armv7a7-imx6ull-evk]

# TODO: full fs filling tests
tests:
# empty files
- name: fs_mark_emptyFiles
execute: fs_mark -d /fs_mark_test -s 0 -n 100 -v -S 0 -L 50

- name: fs_mark_emptyFiles_5_dirs
execute: fs_mark -d /fs_mark_test -D 5 -N 20 -s 0 -n 100 -v -S 0 -L 50

- name: fs_mark_emptyFiles_100_dirs
execute: fs_mark -d /fs_mark_test -D 100 -N 1 -s 0 -n 100 -v -S 0 -L 50

- name: fs_mark_emptyFiles_5_threads
execute: fs_mark -d /fs_mark_test -t 5 -D 4 -N 20 -s 0 -n 100 -v -S 0 -L 50

- name: fs_mark_emptyFiles_64_threads
execute: fs_mark -d /fs_mark_test -t 64 -D 64 -N 1 -s 0 -n 64 -v -S 0 -L 4

# big file
- name: fs_mark_bigFile_allignedWrite
execute: fs_mark -d /fs_mark_test -s 2000000 -w 32 -n 1 -v -S 0

- name: fs_mark_bigFile_notAllignedWrite
execute: fs_mark -d /fs_mark_test -s 2000000 -w 113 -n 1 -v -S 0

- name: fs_mark_bigFile_bigWrite
execute: fs_mark -d /fs_mark_test -s 2000000 -w 1024 -n 1 -v -S 0

# s=256 w=32
- name: fs_mark_smallFiles_alignedWrite
execute: fs_mark -d /fs_mark_test -s 256 -w 32 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_alignedWrite_5_dirs
execute: fs_mark -d /fs_mark_test -D 5 -N 20 -s 256 -w 32 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_alignedWrite_100_dirs
execute: fs_mark -d /fs_mark_test -D 100 -N 1 -s 256 -w 32 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_alignedWrite_5_threads
execute: fs_mark -d /fs_mark_test -t 5 -D 5 -N 20 -s 256 -w 32 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_alignedWrite_64_threads
execute: fs_mark -d /fs_mark_test -t 64 -D 64 -N 1 -s 256 -w 32 -n 64 -v -S 0 -L 4

# s=4096 w=32
- name: fs_mark_pageSizeFiles_alignedWrite
execute: fs_mark -d /fs_mark_test -s 4096 -w 32 -n 10 -v -S 0 -L 30

- name: fs_mark_pageSizeFiles_alignedWrite_5_dirs
execute: fs_mark -d /fs_mark_test -D 5 -N 2 -s 4096 -w 32 -n 10 -v -S 0 -L 30

- name: fs_mark_pageSizeFiles_alignedWrite_25_dirs
execute: fs_mark -d /fs_mark_test -D 25 -N 1 -s 4096 -w 32 -n 25 -v -S 0 -L 30

- name: fs_mark_pageSizeFiles_alignedWrite_5_threads
execute: fs_mark -d /fs_mark_test -t 5 -D 5 -N 2 -s 4096 -w 32 -n 10 -v -S 0 -L 15

- name: fs_mark_pageSizeFiles_alignedWrite_20_threads
execute: fs_mark -d /fs_mark_test -t 20 -D 20 -N 1 -s 4096 -w 32 -n 20 -v -S 0 -L 5

# s=10000 w=32
- name: fs_mark_bigFiles_alignedWrite
execute: fs_mark -d /fs_mark_test -s 10000 -w 32 -n 10 -v -S 0 -L 30

- name: fs_mark_bigFiles_alignedWrite_5_dirs
execute: fs_mark -d /fs_mark_test -D 5 -N 2 -s 10000 -w 32 -n 10 -v -S 0 -L 30

- name: fs_mark_bigFiles_alignedWrite_25_dirs
execute: fs_mark -d /fs_mark_test -D 25 -N 1 -s 10000 -w 32 -n 25 -v -S 0 -L 10

- name: fs_mark_bigFiles_alignedWrite_5_threads
execute: fs_mark -d /fs_mark_test -t 5 -D 5 -N 2 -s 10000 -w 32 -n 10 -v -S 0 -L 10

- name: fs_mark_bigFiles_alignedWrite_10_threads
execute: fs_mark -d /fs_mark_test -t 10 -D 10 -N 1 -s 10000 -w 32 -n 10 -v -S 0 -L 5

# s=256 w=113
- name: fs_mark_smallFiles_notAlignedWrite
execute: fs_mark -d /fs_mark_test -s 256 -w 113 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_notAlignedWrite_5_dirs
execute: fs_mark -d /fs_mark_test -D 5 -N 20 -s 256 -w 113 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_notAlignedWrite_100_dirs
execute: fs_mark -d /fs_mark_test -D 100 -N 1 -s 256 -w 113 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_notAlignedWrite_5_threads
execute: fs_mark -d /fs_mark_test -t 5 -D 5 -N 20 -s 256 -w 113 -n 100 -v -S 0 -L 30

- name: fs_mark_smallFiles_notAlignedWrite_64_threads
execute: fs_mark -d /fs_mark_test -t 64 -D 64 -N 1 -s 256 -w 113 -n 64 -v -S 0 -L 3

# # s=4096 w=113
- name: fs_mark_pageSizeFiles_notAlignedWrite
execute: fs_mark -d /fs_mark_test -s 4096 -w 113 -n 10 -v -S 0 -L 30

- name: fs_mark_pageSizeFiles_notAlignedWrite_5_dirs
execute: fs_mark -d /fs_mark_test -D 5 -N 2 -s 4096 -w 113 -n 10 -v -S 0 -L 30

- name: fs_mark_pageSizeFiles_notAlignedWrite_25_dirs
execute: fs_mark -d /fs_mark_test -D 25 -N 1 -s 4096 -w 113 -n 25 -v -S 0 -L 30

- name: fs_mark_pageSizeFiles_notAlignedWrite_5_threads
execute: fs_mark -d /fs_mark_test -t 5 -D 5 -N 2 -s 4096 -w 113 -n 10 -v -S 0 -L 15

- name: fs_mark_pageSizeFiles_notAlignedWrite_20_threads
execute: fs_mark -d /fs_mark_test -t 20 -D 20 -N 1 -s 4096 -w 113 -n 20 -v -S 0 -L 5

# # s=10000 w=113
- name: fs_mark_bigFiles_notAlignedWrite
execute: fs_mark -d /fs_mark_test -s 10000 -w 113 -n 10 -v -S 0 -L 30

- name: fs_mark_bigFiles_notAlignedWrite_5_dirs
execute: fs_mark -d /fs_mark_test -D 5 -N 2 -s 10000 -w 113 -n 10 -v -S 0 -L 30

- name: fs_mark_bigFiles_notAlignedWrite_25_dirs
execute: fs_mark -d /fs_mark_test -D 25 -N 1 -s 10000 -w 113 -n 25 -v -S 0 -L 20

- name: fs_mark_bigFiles_notAlignedWrite_5_threads
execute: fs_mark -d /fs_mark_test -t 5 -D 5 -N 2 -s 10000 -w 113 -n 10 -v -S 0 -L 10

- name: fs_mark_bigFiles_notAlignedWrite_10_threads
execute: fs_mark -d /fs_mark_test -t 10 -D 10 -N 1 -s 10000 -w 113 -n 10 -v -S 0 -L 5
Loading

0 comments on commit cef2eb5

Please sign in to comment.