mirror of
https://github.com/tailix/libkernaux.git
synced 2025-02-17 15:45:32 -05:00
Main: generate tests for cmdline
This commit is contained in:
parent
b2341a5ca2
commit
619f7004e0
6 changed files with 310 additions and 51 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -116,6 +116,8 @@
|
|||
/tests/multiboot2_info_print1
|
||||
/tests/multiboot2_info_print2
|
||||
/tests/test_cmdline
|
||||
/tests/test_cmdline_gen
|
||||
/tests/test_cmdline_gen.c
|
||||
/tests/test_elf
|
||||
/tests/test_mbr
|
||||
/tests/test_multiboot2_header_helpers
|
||||
|
|
21
Makefile.am
21
Makefile.am
|
@ -321,6 +321,27 @@ tests_test_cmdline_SOURCES = tests/test_cmdline.c
|
|||
endif
|
||||
endif
|
||||
|
||||
##########################
|
||||
# tests/test_cmdline_gen #
|
||||
##########################
|
||||
|
||||
if ENABLE_TESTS_PYTHON
|
||||
if WITH_CMDLINE
|
||||
TESTS += tests/test_cmdline_gen
|
||||
tests_test_cmdline_gen_LDADD = libkernaux.a
|
||||
tests_test_cmdline_gen_SOURCES = \
|
||||
tests/test_cmdline_gen.c \
|
||||
tests/cmdline_gen.py \
|
||||
tests/cmdline_gen.jinja \
|
||||
common/cmdline.yml
|
||||
endif
|
||||
endif
|
||||
|
||||
CLEANFILES += tests/test_cmdline_gen.c
|
||||
|
||||
tests/test_cmdline_gen.c: tests/cmdline_gen.py tests/cmdline_gen.jinja common/cmdline.yml
|
||||
python3 tests/cmdline_gen.py
|
||||
|
||||
##################
|
||||
# tests/test_elf #
|
||||
##################
|
||||
|
|
125
common/cmdline.yml
Normal file
125
common/cmdline.yml
Normal file
|
@ -0,0 +1,125 @@
|
|||
# TODO: move here test cases from tests/test_cmdline.c
|
||||
|
||||
- cmdline: ''
|
||||
count: 0
|
||||
result: []
|
||||
- cmdline: ' '
|
||||
count: 0
|
||||
result: []
|
||||
- cmdline: 'foo'
|
||||
count: 1
|
||||
result: ['foo']
|
||||
- cmdline: 'foo bar'
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: 'foo bar '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: ' foo bar '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: 'foo bar'
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: ' foo bar'
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: 'foo bar '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: ' foo bar '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: 'foo bar car'
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
|
||||
- cmdline: '\"\"'
|
||||
count: 1
|
||||
result: ['']
|
||||
- cmdline: '\"\" \"\"'
|
||||
count: 2
|
||||
result: ['', '']
|
||||
- cmdline: '\"\" \"\" \"\"'
|
||||
count: 3
|
||||
result: ['', '', '']
|
||||
- cmdline: '\"foo\"'
|
||||
count: 1
|
||||
result: ['foo']
|
||||
- cmdline: '\"foo\" \"bar\"'
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: ' \"foo\" \"bar\"'
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: '\"foo\" \"bar\" '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: ' \"foo\" \"bar\" '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: '\"foo\" \"bar\"'
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: '\"foo\" \"bar\" '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: ' \"foo\" \"bar\"'
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: ' \"foo\" \"bar\" '
|
||||
count: 2
|
||||
result: ['foo', 'bar']
|
||||
- cmdline: '\"foo\" \"bar\" \"car\"'
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
|
||||
- cmdline: 'foo bar car'
|
||||
argv_count_max: 3
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
- cmdline: 'foo bar car'
|
||||
buffer_size: 12
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
- cmdline: 'foo bar car'
|
||||
argv_count_max: 3
|
||||
buffer_size: 12
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
|
||||
- cmdline: 'foo bar car'
|
||||
argv_count_max: 2
|
||||
error: 'too many args'
|
||||
- cmdline: 'foo bar car'
|
||||
buffer_size: 11
|
||||
error: 'buffer overflow'
|
||||
- cmdline: 'foo bar car'
|
||||
argv_count_max: 2
|
||||
buffer_size: 11
|
||||
error: 'too many args'
|
||||
|
||||
- cmdline: '\"foo\" \"bar\" \"car\"'
|
||||
argv_count_max: 3
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
- cmdline: '\"foo\" \"bar\" \"car\"'
|
||||
buffer_size: 12
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
- cmdline: '\"foo\" \"bar\" \"car\"'
|
||||
argv_count_max: 3
|
||||
buffer_size: 12
|
||||
count: 3
|
||||
result: ['foo', 'bar', 'car']
|
||||
|
||||
- cmdline: '\"foo\" \"bar\" \"car\"'
|
||||
argv_count_max: 2
|
||||
error: 'too many args'
|
||||
- cmdline: '\"foo\" \"bar\" \"car\"'
|
||||
buffer_size: 11
|
||||
error: 'buffer overflow'
|
||||
- cmdline: '\"foo\" \"bar\" \"car\"'
|
||||
argv_count_max: 2
|
||||
buffer_size: 11
|
||||
error: 'too many args'
|
119
tests/cmdline_gen.jinja
Normal file
119
tests/cmdline_gen.jinja
Normal file
|
@ -0,0 +1,119 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <kernaux/cmdline.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARGV_COUNT_MAX 100
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
static void test(
|
||||
const char *cmdline,
|
||||
size_t argv_count_max,
|
||||
size_t buffer_size,
|
||||
|
||||
bool expected_result,
|
||||
const char *expected_error_msg,
|
||||
size_t expected_argc,
|
||||
const char *const *const expected_argv
|
||||
);
|
||||
|
||||
int main()
|
||||
{
|
||||
{% for case in cases %}
|
||||
{
|
||||
{% if not case.error %}
|
||||
const char *const expected_argv[{{ escape_int(len(case.result) or 1) }}] = {
|
||||
{% if len(case.result) %}
|
||||
{% for item in case.result %}
|
||||
{{ escape_str(item) }},
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
NULL,
|
||||
{% endif %}
|
||||
};
|
||||
{% endif %}
|
||||
|
||||
test(
|
||||
{{ escape_str(case.cmdline) }},
|
||||
{{ escape_int(case.argv_count_max or 0) }},
|
||||
{{ escape_int(case.buffer_size or 0) }},
|
||||
{% if not case.error %}
|
||||
true,
|
||||
"",
|
||||
{{ escape_int(case.count) }},
|
||||
expected_argv
|
||||
{% else %}
|
||||
false,
|
||||
{{ escape_str(case.error) }},
|
||||
0,
|
||||
NULL
|
||||
{% endif %}
|
||||
);
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test(
|
||||
const char *const cmdline,
|
||||
size_t argv_count_max,
|
||||
size_t buffer_size,
|
||||
|
||||
const bool expected_result,
|
||||
const char *const expected_error_msg,
|
||||
size_t expected_argc,
|
||||
const char *const *const expected_argv
|
||||
) {
|
||||
if (argv_count_max == 0) argv_count_max = ARGV_COUNT_MAX;
|
||||
if (buffer_size == 0) buffer_size = BUFFER_SIZE;
|
||||
|
||||
char *error_msg = malloc(KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
|
||||
size_t argc = 1234;
|
||||
char **const argv = malloc(sizeof(char*) * argv_count_max);
|
||||
char *const buffer = malloc(buffer_size);
|
||||
|
||||
assert(error_msg);
|
||||
assert(argv);
|
||||
assert(buffer);
|
||||
|
||||
memset(error_msg, 'x', KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
|
||||
memset(argv, 'x', sizeof(char*) * argv_count_max);
|
||||
memset(buffer, 'x', buffer_size);
|
||||
|
||||
assert(
|
||||
kernaux_cmdline(
|
||||
cmdline,
|
||||
error_msg,
|
||||
&argc,
|
||||
argv,
|
||||
buffer,
|
||||
argv_count_max,
|
||||
buffer_size
|
||||
) == !!expected_result
|
||||
);
|
||||
|
||||
assert(strcmp(error_msg, expected_error_msg) == 0);
|
||||
assert(argc == expected_argc);
|
||||
|
||||
if (expected_argv) {
|
||||
for (size_t index = 0; index < argc; ++index) {
|
||||
assert(strcmp(argv[index], expected_argv[index]) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t index = argc; index < argv_count_max; ++index) {
|
||||
assert(argv[index] == NULL);
|
||||
}
|
||||
|
||||
free(error_msg);
|
||||
free(argv);
|
||||
free(buffer);
|
||||
}
|
43
tests/cmdline_gen.py
Normal file
43
tests/cmdline_gen.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
from jinja2 import Environment, FileSystemLoader
|
||||
from os import path
|
||||
from yaml import SafeLoader, safe_load
|
||||
|
||||
CASES_FILENAME = 'cmdline.yml'
|
||||
TEMPLATE_FILENAME = 'cmdline_gen.jinja'
|
||||
TEST_FILENAME = 'test_cmdline_gen.c'
|
||||
|
||||
ROOT_DIRPATH = path.dirname(path.dirname(path.join(path.abspath(__file__))))
|
||||
|
||||
COMMON_DIRPATH = path.join(ROOT_DIRPATH, 'common')
|
||||
TESTS_DIRPATH = path.join(ROOT_DIRPATH, 'tests')
|
||||
|
||||
CASES_FILEPATH = path.join(COMMON_DIRPATH, CASES_FILENAME)
|
||||
TEST_FILEPATH = path.join(TESTS_DIRPATH, TEST_FILENAME)
|
||||
|
||||
def main():
|
||||
cases = safe_load(open(CASES_FILEPATH))
|
||||
|
||||
jinja_env = Environment(
|
||||
keep_trailing_newline=True,
|
||||
loader=FileSystemLoader(TESTS_DIRPATH),
|
||||
)
|
||||
jinja_template = jinja_env.get_template(TEMPLATE_FILENAME)
|
||||
|
||||
result = jinja_template.render(
|
||||
cases=cases,
|
||||
escape_str=escape_str,
|
||||
escape_int=escape_int,
|
||||
len=len,
|
||||
)
|
||||
|
||||
with open(TEST_FILEPATH, 'w') as f:
|
||||
f.write(result)
|
||||
|
||||
def escape_int(n):
|
||||
return str(n)
|
||||
|
||||
def escape_str(s):
|
||||
return '"' + s + '"'
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -24,14 +24,6 @@ static void test(
|
|||
const char *const *const expected_argv
|
||||
);
|
||||
|
||||
static const char *const argv_empty[] = {""};
|
||||
static const char *const argv_empty_X2[] = {"", ""};
|
||||
static const char *const argv_empty_X3[] = {"", "", ""};
|
||||
|
||||
static const char *const argv_foo[] = {"foo"};
|
||||
static const char *const argv_foo_bar[] = {"foo", "bar"};
|
||||
static const char *const argv_foo_bar_car[] = {"foo", "bar", "car"};
|
||||
|
||||
static const char *const argv_spaceX3_X3[] = {" ", " ", " "};
|
||||
static const char *const argv_backslashX3_X3[] = {"\\\\\\", "\\\\\\", "\\\\\\"};
|
||||
static const char *const argv_quotmarkX3_X3[] = {"\"\"\"", "\"\"\"", "\"\"\""};
|
||||
|
@ -86,49 +78,6 @@ static const char *const argv_a_X6[] = { "a", "a", "a", "a", "a", "a" };
|
|||
|
||||
int main()
|
||||
{
|
||||
test("", 0, 0, true, "", 0, NULL);
|
||||
test(" ", 0, 0, true, "", 0, NULL);
|
||||
test("foo", 0, 0, true, "", 1, argv_foo);
|
||||
test("foo bar", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" foo bar", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("foo bar ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" foo bar ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("foo bar", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" foo bar", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("foo bar ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" foo bar ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("foo bar car", 0, 0, true, "", 3, argv_foo_bar_car);
|
||||
|
||||
test("\"\"", 0, 0, true, "", 1, argv_empty);
|
||||
test("\"\" \"\"", 0, 0, true, "", 2, argv_empty_X2);
|
||||
test("\"\" \"\" \"\"", 0, 0, true, "", 3, argv_empty_X3);
|
||||
test("\"foo\"", 0, 0, true, "", 1, argv_foo);
|
||||
test("\"foo\" \"bar\"", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" \"foo\" \"bar\"", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("\"foo\" \"bar\" ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" \"foo\" \"bar\" ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("\"foo\" \"bar\"", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("\"foo\" \"bar\" ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" \"foo\" \"bar\"", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test(" \"foo\" \"bar\" ", 0, 0, true, "", 2, argv_foo_bar);
|
||||
test("\"foo\" \"bar\" \"car\"", 0, 0, true, "", 3, argv_foo_bar_car);
|
||||
|
||||
test("foo bar car", 3, 0, true, "", 3, argv_foo_bar_car);
|
||||
test("foo bar car", 0, 12, true, "", 3, argv_foo_bar_car);
|
||||
test("foo bar car", 3, 12, true, "", 3, argv_foo_bar_car);
|
||||
|
||||
test("foo bar car", 2, 0, false, "too many args", 0, NULL);
|
||||
test("foo bar car", 0, 11, false, "buffer overflow", 0, NULL);
|
||||
test("foo bar car", 2, 11, false, "too many args", 0, NULL);
|
||||
|
||||
test("\"foo\" \"bar\" \"car\"", 3, 0, true, "", 3, argv_foo_bar_car);
|
||||
test("\"foo\" \"bar\" \"car\"", 0, 12, true, "", 3, argv_foo_bar_car);
|
||||
test("\"foo\" \"bar\" \"car\"", 3, 12, true, "", 3, argv_foo_bar_car);
|
||||
|
||||
test("\"foo\" \"bar\" \"car\"", 2, 0, false, "too many args", 0, NULL);
|
||||
test("\"foo\" \"bar\" \"car\"", 0, 11, false, "buffer overflow", 0, NULL);
|
||||
test("\"foo\" \"bar\" \"car\"", 2, 11, false, "too many args", 0, NULL);
|
||||
|
||||
test("\\ ", 0, 0, true, "", 1, argv_space);
|
||||
test("\"\\ \"", 0, 0, true, "", 1, argv_space);
|
||||
test("\\\\", 0, 0, true, "", 1, argv_backslash);
|
||||
|
|
Loading…
Add table
Reference in a new issue