2022-03-09 13:23:51

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 2/3] perf test: Shell - only run .sh shell files to skip other files

From: Carsten Haitzler <[email protected]>

You edit your scripts in the tests and end up with your usual shell
backup files with ~ or .bak or something else at the end, but then your
next perf test run wants to run the backups too. You might also have perf
.data files in the directory or something else undesireable as well. You end
up chasing which test is the one you edited and the backup and have to keep
removing all the backup files, so automatically skip any files that are
not plain *.sh scripts to limit the time wasted in chasing ghosts.

Signed-off-by: Carsten Haitzler <[email protected]>
---
tools/perf/tests/builtin-test.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 3c34cb766724..3a02ba7a7a89 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -296,9 +296,22 @@ static const char *shell_test__description(char *description, size_t size,

#define for_each_shell_test(entlist, nr, base, ent) \
for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
- if (!is_directory(base, ent) && \
+ if (ent->d_name[0] != '.' && \
+ !is_directory(base, ent) && \
is_executable_file(base, ent) && \
- ent->d_name[0] != '.')
+ is_shell_script(ent->d_name))
+
+static bool is_shell_script(const char *file)
+{
+ const char *ext;
+
+ ext = strrchr(file, '.');
+ if (!ext)
+ return false;
+ if (!strcmp(ext, ".sh"))
+ return true;
+ return false;
+}

static const char *shell_tests__dir(char *path, size_t size)
{
--
2.32.0


2022-04-11 08:57:00

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 2/3] perf test: Shell - only run .sh shell files to skip other files

On Wed, Mar 09, 2022 at 12:28:58PM +0000, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> You edit your scripts in the tests and end up with your usual shell
> backup files with ~ or .bak or something else at the end, but then your
> next perf test run wants to run the backups too. You might also have perf
> .data files in the directory or something else undesireable as well. You end
> up chasing which test is the one you edited and the backup and have to keep
> removing all the backup files, so automatically skip any files that are
> not plain *.sh scripts to limit the time wasted in chasing ghosts.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
>
> ---
> tools/perf/tests/builtin-test.c | 17 +++++++++++++++--
> 1 file changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index 3c34cb766724..3a02ba7a7a89 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -296,9 +296,22 @@ static const char *shell_test__description(char *description, size_t size,
>
> #define for_each_shell_test(entlist, nr, base, ent) \
> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
> - if (!is_directory(base, ent) && \
> + if (ent->d_name[0] != '.' && \
> + !is_directory(base, ent) && \
> is_executable_file(base, ent) && \
> - ent->d_name[0] != '.')
> + is_shell_script(ent->d_name))

Just nitpick: since multiple conditions are added, seems to me it's good
to use a single function is_executable_shell_script() to make decision
if a file is an executable shell script.

And the condition checking 'ent->d_name[0] != '.'' would be redundant
after we have checked the file suffix '.sh'.

Thanks,
Leo

> +
> +static bool is_shell_script(const char *file)
> +{
> + const char *ext;
> +
> + ext = strrchr(file, '.');
> + if (!ext)
> + return false;
> + if (!strcmp(ext, ".sh"))
> + return true;
> + return false;
> +}
>
> static const char *shell_tests__dir(char *path, size_t size)
> {
> --
> 2.32.0
>

2022-04-22 19:59:57

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 2/3] perf test: Shell - only run .sh shell files to skip other files



On 4/10/22 03:28, Leo Yan wrote:
> On Wed, Mar 09, 2022 at 12:28:58PM +0000, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> You edit your scripts in the tests and end up with your usual shell
>> backup files with ~ or .bak or something else at the end, but then your
>> next perf test run wants to run the backups too. You might also have perf
>> .data files in the directory or something else undesireable as well. You end
>> up chasing which test is the one you edited and the backup and have to keep
>> removing all the backup files, so automatically skip any files that are
>> not plain *.sh scripts to limit the time wasted in chasing ghosts.
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>>
>> ---
>> tools/perf/tests/builtin-test.c | 17 +++++++++++++++--
>> 1 file changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
>> index 3c34cb766724..3a02ba7a7a89 100644
>> --- a/tools/perf/tests/builtin-test.c
>> +++ b/tools/perf/tests/builtin-test.c
>> @@ -296,9 +296,22 @@ static const char *shell_test__description(char *description, size_t size,
>>
>> #define for_each_shell_test(entlist, nr, base, ent) \
>> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
>> - if (!is_directory(base, ent) && \
>> + if (ent->d_name[0] != '.' && \
>> + !is_directory(base, ent) && \
>> is_executable_file(base, ent) && \
>> - ent->d_name[0] != '.')
>> + is_shell_script(ent->d_name))
>
> Just nitpick: since multiple conditions are added, seems to me it's good
> to use a single function is_executable_shell_script() to make decision
> if a file is an executable shell script.

I'd certainly make a function if this was being re-used, but as the
"coding pattern" was to do all the tests already inside the if() in only
one place, I kept with the style there and didn't change the code that
didn't need changing. I can rewrite this code and basically make a
function that is just an if ...:

bool is_exe_shell_script(const char *base, struct dirent *ent) {
return ent->d_name[0] != '.' && !is_directory(base, ent) &&
is_executable_file(base, ent) && is_shell_script(ent->d_name);
}

And macro becomes:

#define for_each_shell_test(entlist, nr, base, ent) \
for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
if (is_shell(base, ent))

But one catch... it really should be is_non_hidden_exe_shell_script() as
it's checking that it's not a hidden file AND is a shell script. Or do I
keep the hidden file test outside of the function in the if? If we're
nit picking then I need to know exactly what you want here as your
suggested name is actually incorrect.

> And the condition checking 'ent->d_name[0] != '.'' would be redundant
> after we have checked the file suffix '.sh'.

This isn't actually redundant. You can have .something.sh :) If the idea
is we skip anything with a . at the start first always... then the if
(to me) is obvious.

> Thanks,
> Leo
>
>> +
>> +static bool is_shell_script(const char *file)
>> +{
>> + const char *ext;
>> +
>> + ext = strrchr(file, '.');
>> + if (!ext)
>> + return false;
>> + if (!strcmp(ext, ".sh"))
>> + return true;
>> + return false;
>> +}
>>
>> static const char *shell_tests__dir(char *path, size_t size)
>> {
>> --
>> 2.32.0
>>

2022-05-26 19:25:44

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 2/3] perf test: Shell - only run .sh shell files to skip other files

On Thu, Apr 21, 2022 at 05:21:27PM +0100, Carsten Haitzler wrote:
> On 4/10/22 03:28, Leo Yan wrote:
> > On Wed, Mar 09, 2022 at 12:28:58PM +0000, [email protected] wrote:
> > > From: Carsten Haitzler <[email protected]>
> > >
> > > You edit your scripts in the tests and end up with your usual shell
> > > backup files with ~ or .bak or something else at the end, but then your
> > > next perf test run wants to run the backups too. You might also have perf
> > > .data files in the directory or something else undesireable as well. You end
> > > up chasing which test is the one you edited and the backup and have to keep
> > > removing all the backup files, so automatically skip any files that are
> > > not plain *.sh scripts to limit the time wasted in chasing ghosts.
> > >
> > > Signed-off-by: Carsten Haitzler <[email protected]>
> > >
> > > ---
> > > tools/perf/tests/builtin-test.c | 17 +++++++++++++++--
> > > 1 file changed, 15 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> > > index 3c34cb766724..3a02ba7a7a89 100644
> > > --- a/tools/perf/tests/builtin-test.c
> > > +++ b/tools/perf/tests/builtin-test.c
> > > @@ -296,9 +296,22 @@ static const char *shell_test__description(char *description, size_t size,
> > > #define for_each_shell_test(entlist, nr, base, ent) \
> > > for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
> > > - if (!is_directory(base, ent) && \
> > > + if (ent->d_name[0] != '.' && \
> > > + !is_directory(base, ent) && \
> > > is_executable_file(base, ent) && \
> > > - ent->d_name[0] != '.')
> > > + is_shell_script(ent->d_name))
> >
> > Just nitpick: since multiple conditions are added, seems to me it's good
> > to use a single function is_executable_shell_script() to make decision
> > if a file is an executable shell script.
>
> I'd certainly make a function if this was being re-used, but as the "coding
> pattern" was to do all the tests already inside the if() in only one place,
> I kept with the style there and didn't change the code that didn't need
> changing. I can rewrite this code and basically make a function that is just
> an if ...:
>
> bool is_exe_shell_script(const char *base, struct dirent *ent) {
> return ent->d_name[0] != '.' && !is_directory(base, ent) &&
> is_executable_file(base, ent) && is_shell_script(ent->d_name);
> }
>
> And macro becomes:
>
> #define for_each_shell_test(entlist, nr, base, ent) \
> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
> if (is_shell(base, ent))

Sorry for long latency.

If the condition checking gets complex, seems to me it is reasonable to
use a static function (or a macro?) to encapsulate the logics.

> But one catch... it really should be is_non_hidden_exe_shell_script() as
> it's checking that it's not a hidden file AND is a shell script. Or do I
> keep the hidden file test outside of the function in the if? If we're nit
> picking then I need to know exactly what you want here as your suggested
> name is actually incorrect.

I personally prefer to use the condition:

if (is_exe_shell_script() && ent->d_name[0] != '.')
do_something...

The reason is the function is_exe_shell_script() is more common and we
use it easily in wider scope.

> > And the condition checking 'ent->d_name[0] != '.'' would be redundant
> > after we have checked the file suffix '.sh'.
>
> This isn't actually redundant. You can have .something.sh :) If the idea is
> we skip anything with a . at the start first always... then the if (to me)
> is obvious.

Yeah, I agree the checking the start char '.' is the right thing
to do.

Thanks,
Leo

2022-06-13 17:46:48

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 2/3] perf test: Shell - only run .sh shell files to skip other files



On 5/26/22 11:14, Leo Yan wrote:
> On Thu, Apr 21, 2022 at 05:21:27PM +0100, Carsten Haitzler wrote:
>> On 4/10/22 03:28, Leo Yan wrote:
>>> On Wed, Mar 09, 2022 at 12:28:58PM +0000, [email protected] wrote:
>>>> From: Carsten Haitzler <[email protected]>
>>>>
>>>> You edit your scripts in the tests and end up with your usual shell
>>>> backup files with ~ or .bak or something else at the end, but then your
>>>> next perf test run wants to run the backups too. You might also have perf
>>>> .data files in the directory or something else undesireable as well. You end
>>>> up chasing which test is the one you edited and the backup and have to keep
>>>> removing all the backup files, so automatically skip any files that are
>>>> not plain *.sh scripts to limit the time wasted in chasing ghosts.
>>>>
>>>> Signed-off-by: Carsten Haitzler <[email protected]>
>>>>
>>>> ---
>>>> tools/perf/tests/builtin-test.c | 17 +++++++++++++++--
>>>> 1 file changed, 15 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
>>>> index 3c34cb766724..3a02ba7a7a89 100644
>>>> --- a/tools/perf/tests/builtin-test.c
>>>> +++ b/tools/perf/tests/builtin-test.c
>>>> @@ -296,9 +296,22 @@ static const char *shell_test__description(char *description, size_t size,
>>>> #define for_each_shell_test(entlist, nr, base, ent) \
>>>> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
>>>> - if (!is_directory(base, ent) && \
>>>> + if (ent->d_name[0] != '.' && \
>>>> + !is_directory(base, ent) && \
>>>> is_executable_file(base, ent) && \
>>>> - ent->d_name[0] != '.')
>>>> + is_shell_script(ent->d_name))
>>>
>>> Just nitpick: since multiple conditions are added, seems to me it's good
>>> to use a single function is_executable_shell_script() to make decision
>>> if a file is an executable shell script.
>>
>> I'd certainly make a function if this was being re-used, but as the "coding
>> pattern" was to do all the tests already inside the if() in only one place,
>> I kept with the style there and didn't change the code that didn't need
>> changing. I can rewrite this code and basically make a function that is just
>> an if ...:
>>
>> bool is_exe_shell_script(const char *base, struct dirent *ent) {
>> return ent->d_name[0] != '.' && !is_directory(base, ent) &&
>> is_executable_file(base, ent) && is_shell_script(ent->d_name);
>> }
>>
>> And macro becomes:
>>
>> #define for_each_shell_test(entlist, nr, base, ent) \
>> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
>> if (is_shell(base, ent))
>
> Sorry for long latency.

No problem.

> If the condition checking gets complex, seems to me it is reasonable to
> use a static function (or a macro?) to encapsulate the logics.

Well normally my rule i s - if it gets re-used then do it, otherwise it
just involves more indirection to follow. :) But regardless of that,
given some other things you ask for that kind of makes this discussion
moot as it requires much bigger wholesale changes to the test infra
which will make these patches a lot more work. I'll get to that later in
mails.

>> But one catch... it really should be is_non_hidden_exe_shell_script() as
>> it's checking that it's not a hidden file AND is a shell script. Or do I
>> keep the hidden file test outside of the function in the if? If we're nit
>> picking then I need to know exactly what you want here as your suggested
>> name is actually incorrect.
>
> I personally prefer to use the condition:
>
> if (is_exe_shell_script() && ent->d_name[0] != '.')
> do_something...
>
> The reason is the function is_exe_shell_script() is more common and we
> use it easily in wider scope.

As above - will probably have to redo a lot of the test infra involving
the shell tests to handle some of your other requests, but if we don't
go that way, I have got where you want to go and I can do this.

>>> And the condition checking 'ent->d_name[0] != '.'' would be redundant
>>> after we have checked the file suffix '.sh'.
>>
>> This isn't actually redundant. You can have .something.sh :) If the idea is
>> we skip anything with a . at the start first always... then the if (to me)
>> is obvious.
>
> Yeah, I agree the checking the start char '.' is the right thing
> to do.

:)

2022-06-15 09:41:32

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 2/3] perf test: Shell - only run .sh shell files to skip other files

On Mon, Jun 13, 2022 at 02:08:30PM +0100, Carsten Haitzler wrote:

[...]

> > If the condition checking gets complex, seems to me it is reasonable to
> > use a static function (or a macro?) to encapsulate the logics.
>
> Well normally my rule i s - if it gets re-used then do it, otherwise it just
> involves more indirection to follow. :) But regardless of that, given some
> other things you ask for that kind of makes this discussion moot as it
> requires much bigger wholesale changes to the test infra which will make
> these patches a lot more work. I'll get to that later in mails.

Your mentioned rule makes sense to me.

> > > But one catch... it really should be is_non_hidden_exe_shell_script() as
> > > it's checking that it's not a hidden file AND is a shell script. Or do I
> > > keep the hidden file test outside of the function in the if? If we're nit
> > > picking then I need to know exactly what you want here as your suggested
> > > name is actually incorrect.
> >
> > I personally prefer to use the condition:
> >
> > if (is_exe_shell_script() && ent->d_name[0] != '.')
> > do_something...
> >
> > The reason is the function is_exe_shell_script() is more common and we
> > use it easily in wider scope.
>
> As above - will probably have to redo a lot of the test infra involving the
> shell tests to handle some of your other requests, but if we don't go that
> way, I have got where you want to go and I can do this.

To be honest, I am not sure if this patch is related with refactoring
test infrastructure or not. You could reconsider when you spin for next
patch set (as you said, might refactor test infra).

In case you still want to keep this patch as it is, it would be fine for
me and you could add my reviewed tag:

Reviewed-by: Leo Yan <[email protected]>

Thanks,
Leo