Message ID | 1641881435-2351-3-git-send-email-xuyang2018.jy@fujitsu.com |
---|---|
State | Accepted |
Headers | show |
Series | [v4,1/5] lib/tst_kconfig: Modify the return type of tst_kconfig_check function | expand |
On Tue, Jan 11, 2022 at 2:10 PM Yang Xu <xuyang2018.jy@fujitsu.com> wrote: > +++ b/testcases/lib/tst_check_kconfigs.c > @@ -0,0 +1,46 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.*/ > + > +#include <stdio.h> > +#include <string.h> > +#include <stdlib.h> > +#include "tst_kconfig.h" > + > +int main(int argc, char *argv[]) > +{ > + char *str = argv[1]; > + char *delim = argv[2]; > + unsigned int i, cnt = 1; > + int ret = 0; > + > + if (argc == 2 || strlen(delim) == 0) { I doubt that this syntax really works here. How can we get the strlen(delim) equal to 0? if the argc is not 2, why the length of delimi is zero? but if we change || to &&, then get a segment fault. I don't understand this. > + delim = ","; > + } else if (argc == 3) { > + if (strlen(delim) > 1) { > + fprintf(stderr, "The delim must be a single character\n"); > + return 1; > + } > + } else { > + fprintf(stderr, "Please provide kernel kconfig list and delim " > + "(optinal, default value is ',')\n"); > + return 1; > + } > + > + for (i = 0; str[i]; i++) { > + if (str[i] == delim[0]) > + cnt++; > + } > + > + char **kconfigs = malloc(++i * sizeof(char *)); Shouldn't this be malloc(++cnt * sizeof(char*)) ? > + > + for (i = j0; i < cnt; i++) > + kconfigs[i] = strtok_r(str, delim, &str); > + > + kconfigs[i] = NULL; > + > + if (tst_kconfig_check((const char * const*)kconfigs)) > + ret = 1; > + > + free(kconfigs); > + return ret; > +}
Hi Li > On Tue, Jan 11, 2022 at 2:10 PM Yang Xu<xuyang2018.jy@fujitsu.com> wrote: > >> +++ b/testcases/lib/tst_check_kconfigs.c >> @@ -0,0 +1,46 @@ >> +// SPDX-License-Identifier: GPL-2.0-or-later >> +/* Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.*/ >> + >> +#include<stdio.h> >> +#include<string.h> >> +#include<stdlib.h> >> +#include "tst_kconfig.h" >> + >> +int main(int argc, char *argv[]) >> +{ >> + char *str = argv[1]; >> + char *delim = argv[2]; >> + unsigned int i, cnt = 1; >> + int ret = 0; >> + >> + if (argc == 2 || strlen(delim) == 0) { > > I doubt that this syntax really works here. > > How can we get the strlen(delim) equal to 0? if the argc is > not 2, why the length of delimi is zero? but if we change || > to&&, then get a segment fault. I don't understand this. Sorry, this is ugly code. please see the lastest code. > >> + delim = ","; >> + } else if (argc == 3) { >> + if (strlen(delim)> 1) { >> + fprintf(stderr, "The delim must be a single character\n"); >> + return 1; >> + } >> + } else { >> + fprintf(stderr, "Please provide kernel kconfig list and delim " >> + "(optinal, default value is ',')\n"); >> + return 1; >> + } >> + >> + for (i = 0; str[i]; i++) { >> + if (str[i] == delim[0]) >> + cnt++; >> + } >> + >> + char **kconfigs = malloc(++i * sizeof(char *)); > > Shouldn't this be malloc(++cnt * sizeof(char*)) ? Oh, yes. Sorry for this typo. > >> + >> + for (i = j0; i< cnt; i++) >> + kconfigs[i] = strtok_r(str, delim,&str); >> + >> + kconfigs[i] = NULL; This is also useless. The lastest code should be as below: int main(int argc, char *argv[]) { char *str = argv[1]; char *delim = argv[2]; unsigned int i, cnt = 1; int ret = 0; if (argc == 2) { delim = ","; } else if (argc == 3) { if (strlen(delim) > 1) { fprintf(stderr, "The delim must be a single character\n"); return 1; } } else { fprintf(stderr, "Please provide kernel kconfig list and delim " "(optinal, default value is ',')\n"); return 1; } for (i = 0; str[i]; i++) { if (str[i] == delim[0]) cnt++; } char **kconfigs = malloc(++cnt * sizeof(char *)); for (i = 0; i < cnt; i++) kconfigs[i] = strtok_r(str, delim, &str); if (tst_kconfig_check((const char * const*)kconfigs)) ret = 1; free(kconfigs); return ret; } Best Regards Yang Xu >> + >> + if (tst_kconfig_check((const char * const*)kconfigs)) >> + ret = 1; >> + >> + free(kconfigs); >> + return ret; >> +} >
Hi Li, Cyril, Petr Any comment for this patchset? Best Regards Yang Xu > Hi Li >> On Tue, Jan 11, 2022 at 2:10 PM Yang Xu<xuyang2018.jy@fujitsu.com> wrote: >> >>> +++ b/testcases/lib/tst_check_kconfigs.c >>> @@ -0,0 +1,46 @@ >>> +// SPDX-License-Identifier: GPL-2.0-or-later >>> +/* Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.*/ >>> + >>> +#include<stdio.h> >>> +#include<string.h> >>> +#include<stdlib.h> >>> +#include "tst_kconfig.h" >>> + >>> +int main(int argc, char *argv[]) >>> +{ >>> + char *str = argv[1]; >>> + char *delim = argv[2]; >>> + unsigned int i, cnt = 1; >>> + int ret = 0; >>> + >>> + if (argc == 2 || strlen(delim) == 0) { >> >> I doubt that this syntax really works here. >> >> How can we get the strlen(delim) equal to 0? if the argc is >> not 2, why the length of delimi is zero? but if we change || >> to&&, then get a segment fault. I don't understand this. > > Sorry, this is ugly code. please see the lastest code. >> >>> + delim = ","; >>> + } else if (argc == 3) { >>> + if (strlen(delim)> 1) { >>> + fprintf(stderr, "The delim must be a single character\n"); >>> + return 1; >>> + } >>> + } else { >>> + fprintf(stderr, "Please provide kernel kconfig list and delim " >>> + "(optinal, default value is ',')\n"); >>> + return 1; >>> + } >>> + >>> + for (i = 0; str[i]; i++) { >>> + if (str[i] == delim[0]) >>> + cnt++; >>> + } >>> + >>> + char **kconfigs = malloc(++i * sizeof(char *)); >> >> Shouldn't this be malloc(++cnt * sizeof(char*)) ? > Oh, yes. Sorry for this typo. >> >>> + >>> + for (i = j0; i< cnt; i++) >>> + kconfigs[i] = strtok_r(str, delim,&str); >>> + >>> + kconfigs[i] = NULL; > This is also useless. > > The lastest code should be as below: > > int main(int argc, char *argv[]) > { > char *str = argv[1]; > char *delim = argv[2]; > unsigned int i, cnt = 1; > int ret = 0; > > if (argc == 2) { > delim = ","; > } else if (argc == 3) { > if (strlen(delim)> 1) { > fprintf(stderr, "The delim must be a single > character\n"); > return 1; > } > } else { > fprintf(stderr, "Please provide kernel kconfig list and > delim " > "(optinal, default value is ',')\n"); > return 1; > } > > for (i = 0; str[i]; i++) { > if (str[i] == delim[0]) > cnt++; > } > > char **kconfigs = malloc(++cnt * sizeof(char *)); > > for (i = 0; i< cnt; i++) > kconfigs[i] = strtok_r(str, delim,&str); > > if (tst_kconfig_check((const char * const*)kconfigs)) > ret = 1; > > free(kconfigs); > return ret; > } > > > Best Regards > Yang Xu >>> + >>> + if (tst_kconfig_check((const char * const*)kconfigs)) >>> + ret = 1; >>> + >>> + free(kconfigs); >>> + return ret; >>> +} >> >
> > The lastest code should be as below: > > > > int main(int argc, char *argv[]) > > { > > char *str = argv[1]; > > char *delim = argv[2]; > > unsigned int i, cnt = 1; > > int ret = 0; The statement of ‘ret‘ can move up to unsigned int as well. Otherwise, this version LGTM. > > > > if (argc == 2) { > > delim = ","; > > } else if (argc == 3) { > > if (strlen(delim)> 1) { > > fprintf(stderr, "The delim must be a single > > character\n"); > > return 1; > > } > > } else { > > fprintf(stderr, "Please provide kernel kconfig list and > > delim " > > "(optinal, default value is ',')\n"); > > return 1; > > } > > > > for (i = 0; str[i]; i++) { > > if (str[i] == delim[0]) > > cnt++; > > } > > > > char **kconfigs = malloc(++cnt * sizeof(char *)); > > > > for (i = 0; i< cnt; i++) > > kconfigs[i] = strtok_r(str, delim,&str); > > > > if (tst_kconfig_check((const char * const*)kconfigs)) > > ret = 1; > > > > free(kconfigs); > > return ret; > > }
Hi! > int main(int argc, char *argv[]) > { > char *str = argv[1]; > char *delim = argv[2]; > unsigned int i, cnt = 1; > int ret = 0; > > if (argc == 2) { > delim = ","; > } else if (argc == 3) { > if (strlen(delim) > 1) { > fprintf(stderr, "The delim must be a single > character\n"); > return 1; > } > } else { > fprintf(stderr, "Please provide kernel kconfig list and > delim " > "(optinal, default value is ',')\n"); > return 1; > } We can make the code a bit easier to read with a switch() switch (argc) { case 2: delim = ","; break; case 3: if (strlen(delim) > 1) { fprintf(stderr, "..."); return 1; } break; default: fprintf(stderr, "..."); return 1; } > for (i = 0; str[i]; i++) { > if (str[i] == delim[0]) > cnt++; > } > > char **kconfigs = malloc(++cnt * sizeof(char *)); It's unlikely that this will fail the allocation, but for the sake of correctness we should also do: if (!kconfigs) { fprintf(stderr, "malloc failed"); return 1; } > for (i = 0; i < cnt; i++) > kconfigs[i] = strtok_r(str, delim, &str); > > if (tst_kconfig_check((const char * const*)kconfigs)) > ret = 1; > > free(kconfigs); > return ret; > } Other than the two minor issues this version looks good to me: Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Hi Cyril, Li, Petr > Hi! >> int main(int argc, char *argv[]) >> { >> char *str = argv[1]; >> char *delim = argv[2]; >> unsigned int i, cnt = 1; >> int ret = 0; >> >> if (argc == 2) { >> delim = ","; >> } else if (argc == 3) { >> if (strlen(delim)> 1) { >> fprintf(stderr, "The delim must be a single >> character\n"); >> return 1; >> } >> } else { >> fprintf(stderr, "Please provide kernel kconfig list and >> delim " >> "(optinal, default value is ',')\n"); >> return 1; >> } > > We can make the code a bit easier to read with a switch() > > switch (argc) { > case 2: > delim = ","; > break; > case 3: > if (strlen(delim)> 1) { > fprintf(stderr, "..."); > return 1; > } > break; > default: > fprintf(stderr, "..."); > return 1; > } > > >> for (i = 0; str[i]; i++) { >> if (str[i] == delim[0]) >> cnt++; >> } >> >> char **kconfigs = malloc(++cnt * sizeof(char *)); > > It's unlikely that this will fail the allocation, but for the sake of > correctness we should also do: > > if (!kconfigs) { > fprintf(stderr, "malloc failed"); > return 1; > } > >> for (i = 0; i< cnt; i++) >> kconfigs[i] = strtok_r(str, delim,&str); >> >> if (tst_kconfig_check((const char * const*)kconfigs)) >> ret = 1; >> >> free(kconfigs); >> return ret; >> } > > Other than the two minor issues this version looks good to me: I modify this patch with the above comment and also move tst_res into kconfig_skip_check in the 2nd patch. Then I pushed this patchset. Thanks for your patient review. Best Regards Yang Xu > > Reviewed-by: Cyril Hrubis<chrubis@suse.cz> >
Hi Petr I find ltp doesn't update wiki automatically. Or I miss something? This occurs the last patch doesn't update doc when we merged a patchset. Best Regards Yang Xu > Hi Cyril, Li, Petr > >> Hi! >>> int main(int argc, char *argv[]) >>> { >>> char *str = argv[1]; >>> char *delim = argv[2]; >>> unsigned int i, cnt = 1; >>> int ret = 0; >>> >>> if (argc == 2) { >>> delim = ","; >>> } else if (argc == 3) { >>> if (strlen(delim)> 1) { >>> fprintf(stderr, "The delim must be a single >>> character\n"); >>> return 1; >>> } >>> } else { >>> fprintf(stderr, "Please provide kernel kconfig list and >>> delim " >>> "(optinal, default value is ',')\n"); >>> return 1; >>> } >> >> We can make the code a bit easier to read with a switch() >> >> switch (argc) { >> case 2: >> delim = ","; >> break; >> case 3: >> if (strlen(delim)> 1) { >> fprintf(stderr, "..."); >> return 1; >> } >> break; >> default: >> fprintf(stderr, "..."); >> return 1; >> } >> >> >>> for (i = 0; str[i]; i++) { >>> if (str[i] == delim[0]) >>> cnt++; >>> } >>> >>> char **kconfigs = malloc(++cnt * sizeof(char *)); >> >> It's unlikely that this will fail the allocation, but for the sake of >> correctness we should also do: >> >> if (!kconfigs) { >> fprintf(stderr, "malloc failed"); >> return 1; >> } >> >>> for (i = 0; i< cnt; i++) >>> kconfigs[i] = strtok_r(str, delim,&str); >>> >>> if (tst_kconfig_check((const char * const*)kconfigs)) >>> ret = 1; >>> >>> free(kconfigs); >>> return ret; >>> } >> >> Other than the two minor issues this version looks good to me: > > I modify this patch with the above comment and also move tst_res into > kconfig_skip_check in the 2nd patch. Then I pushed this patchset. > > Thanks for your patient review. > > Best Regards > Yang Xu >> >> Reviewed-by: Cyril Hrubis<chrubis@suse.cz> >> >
Hi Xu, > Hi Petr > I find ltp doesn't update wiki automatically. Or I miss something? > This occurs the last patch doesn't update doc when we merged a patchset. Hm, I need to look into it. Thx for info. Kind regards, Petr > Best Regards > Yang Xu
diff --git a/doc/shell-test-api.txt b/doc/shell-test-api.txt index b993a9e1e..e082808f7 100644 --- a/doc/shell-test-api.txt +++ b/doc/shell-test-api.txt @@ -193,22 +193,25 @@ simply by setting right '$TST_NEEDS_FOO'. [options="header"] |============================================================================= -| Variable name | Action done -| 'TST_NEEDS_ROOT' | Exit the test with 'TCONF' unless executed under root. -| | Alternatively the 'tst_require_root' command can be used. -| 'TST_NEEDS_TMPDIR' | Create test temporary directory and cd into it. -| 'TST_NEEDS_DEVICE' | Prepare test temporary device, the path to testing - device is stored in '$TST_DEVICE' variable. - The option implies 'TST_NEEDS_TMPDIR'. -| 'TST_NEEDS_CMDS' | String with command names that has to be present for - the test (see below). -| 'TST_NEEDS_MODULE' | Test module name needed for the test (see below). -| 'TST_NEEDS_DRIVERS'| Checks kernel drivers support for the test. -| 'TST_TIMEOUT' | Maximum timeout set for the test in sec. Must be int >= 1, - or -1 (special value to disable timeout), default is 300. - Variable is meant be set in tests, not by user. - It's an equivalent of `tst_test.timeout` in C, can be set - via 'tst_set_timeout(timeout)' after test has started. +| Variable name | Action done +| 'TST_NEEDS_ROOT' | Exit the test with 'TCONF' unless executed under root. +| | Alternatively the 'tst_require_root' command can be used. +| 'TST_NEEDS_TMPDIR' | Create test temporary directory and cd into it. +| 'TST_NEEDS_DEVICE' | Prepare test temporary device, the path to testing + device is stored in '$TST_DEVICE' variable. + The option implies 'TST_NEEDS_TMPDIR'. +| 'TST_NEEDS_CMDS' | String with command names that has to be present for + the test (see below). +| 'TST_NEEDS_MODULE' | Test module name needed for the test (see below). +| 'TST_NEEDS_DRIVERS' | Checks kernel drivers support for the test. +| 'TST_NEEDS_KCONFIGS' | Checks kernel kconfigs support for the test (see below). +| 'TST_NEEDS_KCONFIGS_IFS' | Used for splitting '$TST_NEEDS_KCONFIGS' variable, + default value is comma, it only supports single character. +| 'TST_TIMEOUT' | Maximum timeout set for the test in sec. Must be int >= 1, + or -1 (special value to disable timeout), default is 300. + Variable is meant be set in tests, not by user. + It's an equivalent of `tst_test.timeout` in C, can be set + via 'tst_set_timeout(timeout)' after test has started. |============================================================================= [options="header"] @@ -742,3 +745,19 @@ TST_NEEDS_CHECKPOINTS=1 Since both the implementations are compatible, it's also possible to start a child binary process from a shell test and synchronize with it. This process must have checkpoints initialized by calling 'tst_reinit()'. + +1.7 Parsing kernel .config +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The shell library provides an implementation of the kconfig parsing interface +compatible with the C version. + +It's possible to pass kernel kconfig list for tst_require_kconfigs API with +'$TST_NEEDS_KCONFIGS'. +Optional '$TST_NEEDS_KCONFIGS_IFS' is used for splitting, default value is comma. + +------------------------------------------------------------------------------- +#!/bin/sh +TST_NEEDS_KCONFIGS="CONFIG_EXT4_FS, CONFIG_QUOTACTL=y" + +. tst_test.sh +------------------------------------------------------------------------------- diff --git a/lib/newlib_tests/runtest.sh b/lib/newlib_tests/runtest.sh index 8b2fe347a..ad213eef6 100755 --- a/lib/newlib_tests/runtest.sh +++ b/lib/newlib_tests/runtest.sh @@ -6,7 +6,8 @@ tst_needs_cmds01 tst_needs_cmds02 tst_needs_cmds03 tst_needs_cmds06 tst_needs_cmds07 tst_bool_expr test_exec test_timer tst_res_hexd tst_strstatus tst_fuzzy_sync03 test_zero_hugepage.sh}" -LTP_SHELL_API_TESTS="${LTP_SHELL_API_TESTS:-shell/tst_check_driver.sh shell/net/*.sh}" +LTP_SHELL_API_TESTS="${LTP_SHELL_API_TESTS:-shell/tst_check_driver.sh +shell/tst_check_kconfig0[1-5].sh shell/net/*.sh}" cd $(dirname $0) PATH="$PWD/../../testcases/lib/:$PATH" @@ -179,6 +180,8 @@ if [ -z "$run" -o "$run" = "c" ]; then fi if [ -z "$run" -o "$run" = "s" ]; then + export KCONFIG_PATH=config02 + runtest_res TINFO "KCONFIG_PATH='$KCONFIG_PATH'" run_shell_tests shell_fail=$? fi diff --git a/lib/newlib_tests/shell/tst_check_kconfig01.sh b/lib/newlib_tests/shell/tst_check_kconfig01.sh new file mode 100755 index 000000000..03f86266d --- /dev/null +++ b/lib/newlib_tests/shell/tst_check_kconfig01.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 FUJITSU LIMITED. All rights reserved. + +TST_TESTFUNC=do_test +TST_NEEDS_KCONFIGS="CONFIG_EXT4" + +. tst_test.sh + +do_test() +{ + tst_res TFAIL "kernel .config doesn't have CONFIG_EXT4" +} + +tst_run diff --git a/lib/newlib_tests/shell/tst_check_kconfig02.sh b/lib/newlib_tests/shell/tst_check_kconfig02.sh new file mode 100755 index 000000000..6a20cfc3d --- /dev/null +++ b/lib/newlib_tests/shell/tst_check_kconfig02.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 FUJITSU LIMITED. All rights reserved. + +TST_TESTFUNC=do_test +TST_NEEDS_KCONFIGS="CONFIG_EXT4_FS : CONFIG_XFS_FS" +. tst_test.sh + +do_test() +{ + tst_res TFAIL "invalid kconfig delimter" +} + +tst_run diff --git a/lib/newlib_tests/shell/tst_check_kconfig03.sh b/lib/newlib_tests/shell/tst_check_kconfig03.sh new file mode 100755 index 000000000..361b6bf0b --- /dev/null +++ b/lib/newlib_tests/shell/tst_check_kconfig03.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 FUJITSU LIMITED. All rights reserved. + +TST_TESTFUNC=do_test +TST_NEEDS_KCONFIGS="CONFIG_EXT4_FS : CONFIG_XFS_FS" +TST_NEEDS_KCONFIGS_IFS=":" +. tst_test.sh + +do_test() +{ + tst_res TPASS "valid kconfig delimter" +} + +tst_run diff --git a/lib/newlib_tests/shell/tst_check_kconfig04.sh b/lib/newlib_tests/shell/tst_check_kconfig04.sh new file mode 100755 index 000000000..21cd998dd --- /dev/null +++ b/lib/newlib_tests/shell/tst_check_kconfig04.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 FUJITSU LIMITED. All rights reserved. + +TST_TESTFUNC=do_test +. tst_test.sh + +do_test() +{ + tst_check_kconfigs "CONFIG_EXT4_FS" + if [ $? -eq 0 ]; then + tst_res TPASS "kernel .config has CONFIG_EXT4_FS" + else + tst_res TFAIL "kernel .config doesn't have CONFIG_EXT4_FS" + fi + + tst_check_kconfigs "CONFIG_EXT4" + if [ $? -eq 0 ]; then + tst_res TFAIL "kernel .config has CONFIG_EXT4" + else + tst_res TPASS "kernel .config doesn't have CONFIG_EXT4" + fi +} +tst_run diff --git a/lib/newlib_tests/shell/tst_check_kconfig05.sh b/lib/newlib_tests/shell/tst_check_kconfig05.sh new file mode 100755 index 000000000..f118f27a5 --- /dev/null +++ b/lib/newlib_tests/shell/tst_check_kconfig05.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 FUJITSU LIMITED. All rights reserved. + +TST_TESTFUNC=do_test +. tst_test.sh + +do_test() +{ + tst_require_kconfigs "CONFIG_EXT4_FS" + tst_res TPASS "kernel .config has CONFIG_EXT4_FS" + + tst_require_kconfigs "CONFIG_EXT4" + tst_res TFAIL "kernel .config has CONFIG_EXT4" +} +tst_run diff --git a/testcases/lib/.gitignore b/testcases/lib/.gitignore index 9625d9043..c0d4dc851 100644 --- a/testcases/lib/.gitignore +++ b/testcases/lib/.gitignore @@ -1,4 +1,5 @@ /tst_check_drivers +/tst_check_kconfigs /tst_checkpoint /tst_device /tst_getconf diff --git a/testcases/lib/Makefile b/testcases/lib/Makefile index d6b4c7a91..f2de0c832 100644 --- a/testcases/lib/Makefile +++ b/testcases/lib/Makefile @@ -11,6 +11,7 @@ INSTALL_TARGETS := *.sh MAKE_TARGETS := tst_sleep tst_random tst_checkpoint tst_rod tst_kvcmp\ tst_device tst_net_iface_prefix tst_net_ip_prefix tst_net_vars\ tst_getconf tst_supported_fs tst_check_drivers tst_get_unused_port\ - tst_get_median tst_hexdump tst_get_free_pids tst_timeout_kill + tst_get_median tst_hexdump tst_get_free_pids tst_timeout_kill\ + tst_check_kconfigs include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/lib/tst_check_kconfigs.c b/testcases/lib/tst_check_kconfigs.c new file mode 100644 index 000000000..b0f1f201a --- /dev/null +++ b/testcases/lib/tst_check_kconfigs.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "tst_kconfig.h" + +int main(int argc, char *argv[]) +{ + char *str = argv[1]; + char *delim = argv[2]; + unsigned int i, cnt = 1; + int ret = 0; + + if (argc == 2 || strlen(delim) == 0) { + delim = ","; + } else if (argc == 3) { + if (strlen(delim) > 1) { + fprintf(stderr, "The delim must be a single character\n"); + return 1; + } + } else { + fprintf(stderr, "Please provide kernel kconfig list and delim " + "(optinal, default value is ',')\n"); + return 1; + } + + for (i = 0; str[i]; i++) { + if (str[i] == delim[0]) + cnt++; + } + + char **kconfigs = malloc(++i * sizeof(char *)); + + for (i = 0; i < cnt; i++) + kconfigs[i] = strtok_r(str, delim, &str); + + kconfigs[i] = NULL; + + if (tst_kconfig_check((const char * const*)kconfigs)) + ret = 1; + + free(kconfigs); + return ret; +} diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh index 2556b28f5..30614974c 100644 --- a/testcases/lib/tst_test.sh +++ b/testcases/lib/tst_test.sh @@ -412,6 +412,26 @@ tst_require_drivers() return 0 } +tst_require_kconfigs() +{ + local delim + + if [ $# -gt 2 ]; then + return 0 + elif [ $# -eq 1 ]; then + delim="$TST_NEEDS_KCONFIGS_IFS" + else + delim="$2" + fi + + [ -z "$1" ] && return 0 + + tst_check_kconfigs "$1" "$delim" > /dev/null + + [ $? -ne 0 ] && tst_brk TCONF "Aborting due to unsuitable kernel config, see above!" + return 0 +} + tst_is_int() { [ "$1" -eq "$1" ] 2>/dev/null @@ -587,6 +607,7 @@ tst_run() NEEDS_ROOT|NEEDS_TMPDIR|TMPDIR|NEEDS_DEVICE|DEVICE);; NEEDS_CMDS|NEEDS_MODULE|MODPATH|DATAROOT);; NEEDS_DRIVERS|FS_TYPE|MNTPOINT|MNT_PARAMS);; + NEEDS_KCONFIGS|NEEDS_KCONFIGS_IFS);; IPV6|IPV6_FLAG|IPVER|TEST_DATA|TEST_DATA_IFS);; RETRY_FUNC|RETRY_FN_EXP_BACKOFF|TIMEOUT);; NET_DATAROOT|NET_MAX_PKT|NET_RHOST_RUN_DEBUG|NETLOAD_CLN_NUMBER);; @@ -627,6 +648,7 @@ tst_run() [ "$TST_DISABLE_SELINUX" = 1 ] && tst_disable_selinux tst_require_cmds $TST_NEEDS_CMDS + tst_require_kconfigs "$TST_NEEDS_KCONFIGS" tst_require_drivers $TST_NEEDS_DRIVERS if [ -n "$TST_MIN_KVER" ]; then @@ -748,6 +770,8 @@ if [ -z "$TST_NO_DEFAULT_RUN" ]; then TST_TEST_DATA_IFS="${TST_TEST_DATA_IFS:- }" + TST_NEEDS_KCONFIGS_IFS="${TST_NEEDS_KCONFIGS_IFS:-,}" + if [ -n "$TST_CNT" ]; then if ! tst_is_int "$TST_CNT"; then tst_brk TBROK "TST_CNT must be integer"