ATF-devel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ATF confusion with improperly terminated script



On Sun, Feb 6, 2011 at 1:48 PM, Julio Merino 
<jmmv%homeworld.netbsd.org@localhost> wrote:
> On Sun, Feb 06, 2011 at 01:36:48PM -0800, Garrett Cooper wrote:
>> On Sun, Feb 6, 2011 at 12:03 PM, Julio Merino 
>> <jmmv%homeworld.netbsd.org@localhost> wrote:
>> > On Sun, Feb 06, 2011 at 11:00:59AM -0800, Garrett Cooper wrote:
>>
>> >> # $FreeBSD$
>> >>
>> >> export SH=${SH:=/bin/sh}
>> >>
>> >> do_test() {
>> >> ? ? ? ? local atf_args expected_exit_status testcase_path testcase_prefix
>> >>
>> >> ? ? ? ? testcase_path=$1
>> >
>> > If you need access to data files that live in the same directory as the 
>> > test
>> > program, you should query $(atf_get_srcdir).
>>
>> Sadly, they're in subdirectories (otherwise I wouldn't care about the
>> path a lot).
>
> That's fine.  But my point was: test cases are executed within a temporary
> directory not known a priori.  The canonical way to refer to the directory
> from which they come from is by using $(atf_get_srcdir) (which just gives
> you the value of the argument passed to the test program through the -s
> flag).
>
> And now this gives me an idea of why your code does not work; see below.
>
>> It's not even getting that far. When I don't execute the testcase
>> standalone it's getting hung up on some logic in libatf-sh.subr (in
>> particular the testcase names aren't ending up in calls to
>> atf_test_case ... curious). The contents of Defined_Test_Cases is ok
>> for a while, but the majority of the content in the value is getting
>> dropped about halfway through the invocation.
>
> OK, I think I know what the problem in your code is: your attempts to do
> too much magic from the "initialization function" are dangerous.  (Didn't
> want to mention it before because they looked sane... but it seems they
> won't work after all!)
>
> As I mentioned in some other email to Giorgios, atf-run does the following
> to run test cases of the foo_test program:
>
> 1) Run 'foo_test -l' to extract the list of test cases.  This happens
>   without changing the current work directory (I believe).
> 2) For every test case, create a _new temp dir_ and run:
>   - /path/to/srcdir/foo_test test_case_name:body
>   - /path/to/srcdir/foo_test test_case_name:cleanup
>
> All of these 3 invocations go through the initialization function because
> they are different processes and thus they need to reconstruct the internal
> test program state.
>
> In your example code, the first time the test program is run to extract
> its list of test cases, the "find ." command does the right thing because
> it happens from the directory in which the files are found.
>
> However, when atf-run decides to run your test programs, it will run them
> with the cwd pointing somewhere else and "find ." will yield no results.
> Which in turn means that the test program does not define any test cases
> and thus it is "bogus".
>
> If you really want to make the test case dynamic, you need to do
> "find $(atf_get_srcdir)" instead.  Or you could use some Makefile magic
> to generate a static list of names to bundle into the test program.
>
> Take a look at the atf-test-case(4) manpage, as it describes how test cases
> are isolated during execution.
>
> But all the above are wild guesses.  Maybe your problem comes from
> somewhere else ;-)

    Close, but not quite. The issue is scope [and/or whether or not
it's executing the functions in a subshell?], and it's something that
I didn't realize before now. Note that magically everything works
within the scope of the function, but outside of foo(), bar() and
baz() aren't visible. So that's why the ATF functions work in the
script I attached earlier, but filters out the nested functions when
it checks for the testcases, whereas the standalone functions executed
without complaint. Guess that's what I get for trying to be foolishly
clever.
    AFAICT POSIX doesn't have anything to say on the subject of
function scope (probably because no one thought someone would abuse
function nesting), but the inability to execute nested functions in my
clever manner appears to be consistent behavior with FreeBSD's ash and
bash at least, so slap on the wrist for me :). It's interesting how
bash barfs on the eval'ed command, but that's purely an `academic'
observation.
    So, I guess I'll use some Makefile-fu to produce the testcases instead.
Thanks!
-Garrett

PS. The end-result is the same when you change the eval below into a
bareword function definition, but the symptoms up to that point are a
wee bit different.

$ cat ~/test_something.sh
#!/bin/sh

echo "hello ${1:-world}; my pid is: $$"

type bar baz foo

foo() {
    eval "bar() { $_ $0 bar; }"
    baz() { $_ $0 baz; bar; }
    baz
}

type bar baz foo

if [ $# -eq 0 ]; then
    foo
fi
$ sh ~/test_something.sh
hello world; my pid is: 32706
bar: not found
baz: not found
foo: not found
foo is a shell function
bar: not found
baz: not found
hello baz; my pid is: 32707
bar: not found
baz: not found
foo: not found
foo is a shell function
bar: not found
baz: not found
hello bar; my pid is: 32708
bar: not found
baz: not found
foo: not found
foo is a shell function
bar: not found
baz: not found
$ bash ~/test_something.sh
hello world; my pid is: 32709
/usr/home/gcooper/test_something.sh: line 5: type: bar: not found
/usr/home/gcooper/test_something.sh: line 5: type: baz: not found
/usr/home/gcooper/test_something.sh: line 5: type: foo: not found
/usr/home/gcooper/test_something.sh: line 13: type: bar: not found
/usr/home/gcooper/test_something.sh: line 13: type: baz: not found
foo is a function
foo ()
{
    eval "bar() { $_ $0 bar; }";
    function baz ()
    {
        $_ $0 baz;
        bar
    };
    baz
}
/usr/home/gcooper/test_something.sh: line 9: bar(): command not found
/usr/home/gcooper/test_something.sh: line 8: ]: command not found


Home | Main Index | Thread Index | Old Index