published on in Docker perl

Using Docker to Fix a Perl 5.37 Test Failure

⬅️ Previous post: PrettyGoodPing: Now with, you know, Ping

❤️ It's great to see you here! I'm currently available on evenings and weekends for consulting and freelance work. Let's chat about how I can help you achieve your goals.



calendar

"Tux and Docker" by maijo━ is licensed under CC BY-SA 2.0 .

I recently got a bug report via GitHub that a test in Open::This is failing on Perl 5.37. Let’s take a look at it using gh:

 1gh issue view 48
 2t/open-this.t fails with perl 5.37.x #48
 3Open • eserte opened about 1 day ago • 0 comments
 4
 5
 6  I see the following test failure with recent bleadperls (maybe related to changed serialization of booleans):
 7
 8    #   Failed test 'line 3'
 9    #   at t/open-this.t line 167.
10    # +----+------------------------------------------------+------------------------------------------------+
11    # | Elt|Got                                             |Expected                                        |
12    # +----+------------------------------------------------+------------------------------------------------+
13    # |   0|{                                               |{                                               |
14    # |   1|  file_name => 't/lib/Foo/Bar.pm',              |  file_name => 't/lib/Foo/Bar.pm',              |
15    # *   2|  is_module_name => !!1,                        |  is_module_name => 1,                          *
16    # |   3|  line_number => 3,                             |  line_number => 3,                             |
17    # |   4|  original_text => 'Foo::Bar::do_something()',  |  original_text => 'Foo::Bar::do_something()',  |
18    # |   5|  sub_name => 'do_something'                    |  sub_name => 'do_something'                    |
19    # |   6|}                                               |}                                               |
20    # +----+------------------------------------------------+------------------------------------------------+
21    # Looks like you failed 1 test of 59.
22    t/open-this.t ..........
23    Dubious, test returned 1 (wstat 256, 0x100)
24    Failed 1/59 subtests
25
26
27View this issue on GitHub: https://github.com/oalders/open-this/issues/48

Although the layout of this blog makes it hard to see, the failure in question is on line 15. The test is expecting a value of 1 for the key is_module_name. However, under Perl 5.37 we get !!1 instead. As the ticket suggests, this looks like an issue with how booleans are represented in Perl 5.37. Since some permutation of Perl 5.37 will soon be released in production code as Perl 5.38, it’s a good idea to fix this test failure now. I asked for guidance on #toolchain on irc.perl.org and ilmari helpfully let me know that there are two options to fix this across Perl versions.

One option was to use Test2::Tools::Compare for the comparison. The other was to change the expected value in the test from 1 to !!1. I really like using Test::Differences, so I’m going to change the expected value.

I don’t have Perl 5.37 installed locally and because I’m in a hurry, I don’t want to use plenv to install it. Let’s use Docker instead, because that’s fairly quick and easy.

On host:

docker run -it --rm -v $PWD:/app perl:5.37 bash

This will drop you into a running Docker container. In the container itself, we can run the following commands.

cd /app                            && \
cpm install -g --cpanfile cpanfile && \
prove -lvr t

Alternatively, we can also do this without having to type in the container at all. The difference will be that our container will go away once the command has run to completion. This is handy for really quick things. On my machine it takes ~4 seconds once the Docker images have all been downloaded.

docker run -it --rm -v $PWD:/app \
perl:5.37                        \
bash -c                          \
"cd /app && cpm install -g --cpanfile cpanfile && prove -lvr t"

The output I get is:

#   Failed test 'line 3'
#   at t/open-this.t line 167.
# +----+------------------------------------------------+------------------------------------------------+
# | Elt|Got                                             |Expected                                        |
# +----+------------------------------------------------+------------------------------------------------+
# |   0|{                                               |{                                               |
# |   1|  file_name => 't/lib/Foo/Bar.pm',              |  file_name => 't/lib/Foo/Bar.pm',              |
# *   2|  is_module_name => !!1,                        |  is_module_name => 1,                          *
# |   3|  line_number => 3,                             |  line_number => 3,                             |
# |   4|  original_text => 'Foo::Bar::do_something()',  |  original_text => 'Foo::Bar::do_something()',  |
# |   5|  sub_name => 'do_something'                    |  sub_name => 'do_something'                    |
# |   6|}                                               |}                                               |
# +----+------------------------------------------------+------------------------------------------------+

We’ve been able to replicate the bug. 🥳 On the host machine, I’ll use the ot script which comes via Open::This to open the file locally at the appropriate line in my favourite editor.

ot t/open-this.t line 167

Then I’ll apply the following change:

diff --git a/t/open-this.t b/t/open-this.t
index a2e750e..f0b6220 100644
--- a/t/open-this.t
+++ b/t/open-this.t
@@ -168,7 +168,7 @@ local $ENV{EDITOR} = 'vim';
         parse_text($text),
         {
             file_name      => 't/lib/Foo/Bar.pm',
-            is_module_name => 1,
+            is_module_name => !!1,
             line_number    => 3,
             original_text  => $text,
             sub_name       => 'do_something',

Now, when I run the tests again, they are passing. 🎉 Many thanks to SREZIC for once again helpfully pointing test failures out to me and ILMARI for showing me how to fix the test. 🙏