diff mbox series

[v4,3/5] shell: add kconfig parse api

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

Commit Message

Yang Xu \(Fujitsu\) Jan. 11, 2022, 6:10 a.m. UTC
Use tst_check_kconfigs command to call tst_kconfig_check function in internal.
It introduces two variables in tst_test.sh
TST_NEEDS_KCONFIGS
TST_NEEDS_KCONFIGS_IFS (default value is comma)

Also, we can use tst_check_kconfigs in your shell case if you want to skip subtest
case instead the whole test. Of course, ltp shell test library can use
tst_require_kconfigs in the future if needs. The delim parameter is optional for
tst_require_kconfigs or tst_check_kconfigs api because they have default value for
themselves.

Fixes:#891
Reviewed-by: Li Wang <liwang@redhat.com>
Suggested-by: Petr Vorel <pvorel@suse.cz>
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 doc/shell-test-api.txt                        | 51 +++++++++++++------
 lib/newlib_tests/runtest.sh                   |  5 +-
 lib/newlib_tests/shell/tst_check_kconfig01.sh | 15 ++++++
 lib/newlib_tests/shell/tst_check_kconfig02.sh | 14 +++++
 lib/newlib_tests/shell/tst_check_kconfig03.sh | 15 ++++++
 lib/newlib_tests/shell/tst_check_kconfig04.sh | 24 +++++++++
 lib/newlib_tests/shell/tst_check_kconfig05.sh | 16 ++++++
 testcases/lib/.gitignore                      |  1 +
 testcases/lib/Makefile                        |  3 +-
 testcases/lib/tst_check_kconfigs.c            | 46 +++++++++++++++++
 testcases/lib/tst_test.sh                     | 24 +++++++++
 11 files changed, 196 insertions(+), 18 deletions(-)
 create mode 100755 lib/newlib_tests/shell/tst_check_kconfig01.sh
 create mode 100755 lib/newlib_tests/shell/tst_check_kconfig02.sh
 create mode 100755 lib/newlib_tests/shell/tst_check_kconfig03.sh
 create mode 100755 lib/newlib_tests/shell/tst_check_kconfig04.sh
 create mode 100755 lib/newlib_tests/shell/tst_check_kconfig05.sh
 create mode 100644 testcases/lib/tst_check_kconfigs.c

Comments

Li Wang Jan. 11, 2022, 7:52 a.m. UTC | #1
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;
> +}
Yang Xu \(Fujitsu\) Jan. 11, 2022, 8:37 a.m. UTC | #2
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;
>> +}
>
Yang Xu \(Fujitsu\) Jan. 13, 2022, 9:15 a.m. UTC | #3
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;
>>> +}
>>
>
Li Wang Jan. 13, 2022, 9:42 a.m. UTC | #4
> > 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;
> > }
Cyril Hrubis Jan. 13, 2022, 3:51 p.m. UTC | #5
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>
Yang Xu \(Fujitsu\) Jan. 14, 2022, 6:26 a.m. UTC | #6
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>
>
Yang Xu \(Fujitsu\) Jan. 14, 2022, 9:19 a.m. UTC | #7
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>
>>
>
Petr Vorel Jan. 14, 2022, 9:49 a.m. UTC | #8
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 mbox series

Patch

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"