Commit 4d4b0d910c for openssl.org
commit 4d4b0d910c3bcf7b95d06af098c5714919c3998b
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date: Sat Aug 29 13:58:26 2026 +0200
test framework: add app_fails and slurp_file to OpenSSL::Test
Several test recipes duplicate a helper that runs an openssl
application expecting a failure exit status and checks that the
stderr output matches a regular expression. Add a shared app_fails
function so new recipes do not need to repeat it, together with a
slurp_file function for reading back a captured output file.
Assisted-by: Claude:claude-fable-5
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Mon Sep 7 14:15:49 2026
Merged-from: https://github.com/openssl/openssl/pull/32592
diff --git a/util/perl/OpenSSL/Test.pm b/util/perl/OpenSSL/Test.pm
index fab84f8d7a..67e59b65e6 100644
--- a/util/perl/OpenSSL/Test.pm
+++ b/util/perl/OpenSSL/Test.pm
@@ -23,7 +23,8 @@ $VERSION = "1.0";
srctop_dir srctop_file
data_file data_dir
result_file result_dir
- pipe with cmdstr
+ pipe with cmdstr app_fails
+ slurp_file
openssl_versions
ok_nofips is_nofips isnt_nofips));
@@ -837,6 +838,60 @@ sub with {
=over 4
+=item B<slurp_file FILENAME>
+
+C<slurp_file> reads back the whole file FILENAME, usually an output
+captured with the C<stdout> or C<stderr> option of C<cmd> and its
+derivatives, and returns its content as a single string. If the file
+cannot be opened, an empty string is returned.
+
+=back
+
+=cut
+
+sub slurp_file {
+ my ($file) = @_;
+ my $content = '';
+
+ if (open(my $fh, '<', $file)) {
+ $content = do { local $/; <$fh> };
+ close($fh);
+ }
+ return $content;
+}
+
+=over 4
+
+=item B<app_fails APPNAME, TEST_NAME, REGEXP, LIST>
+
+C<app_fails> runs the C<openssl> sub-command B<APPNAME> with the command
+line arguments in LIST, expecting a non-zero (failure) exit status, as a
+test named B<TEST_NAME>. If REGEXP is defined, it additionally checks, as
+a second test, that the stderr output of the command matches it.
+
+=back
+
+=cut
+
+sub app_fails {
+ my ($appname, $testtext, $re, @args) = @_;
+
+ my $stderr_file = "app_fails_stderr.txt";
+
+ with({ exit_checker => sub { return shift != 0; } },
+ sub {
+ ok(run(app(['openssl', $appname, @args], stderr => $stderr_file)),
+ $testtext);
+ });
+
+ if (defined $re) {
+ ok(slurp_file($stderr_file) =~ $re, "$testtext: stderr matches");
+ }
+ unlink($stderr_file) if -f $stderr_file;
+}
+
+=over 4
+
=item B<cmdstr CODEREF, OPTS>
C<cmdstr> takes a CODEREF from C<app> or C<test> and simply returns the