Add X509_self_signed(), extending and improving documenation and tests
[openssl.git] / test / recipes / 02-test_errstr.t
index 745c3c0e72f50df15629a207c91d1bf50eddbe63..76e0bba43cddf543d4da8c189918ff330b199315 100644 (file)
@@ -1,7 +1,7 @@
 #! /usr/bin/env perl
 # Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
 #
-# Licensed under the OpenSSL license (the "License").  You may not use
+# Licensed under the Apache License 2.0 (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
 # in the file LICENSE in the source distribution or at
 # https://www.openssl.org/source/license.html
@@ -31,10 +31,56 @@ setup('test_errstr');
 plan skip_all => 'This is unsupported for cross compiled configurations'
     if config('CROSS_COMPILE');
 
+# The same can be said when compiling OpenSSL with mingw configuration
+# on Windows when built with msys perl.  Similar problems are also observed
+# in MSVC builds, depending on the perl implementation used.
+plan skip_all => 'This is unsupported on MSYS/MinGW or MSWin32'
+    if $^O eq 'msys' or $^O eq 'MSWin32';
+
+plan skip_all => 'OpenSSL is configured "no-autoerrinit" or "no-err"'
+    if disabled('autoerrinit') || disabled('err');
+
 # These are POSIX error names, which Errno implements as functions
 # (this is documented)
 my @posix_errors = @{$Errno::EXPORT_TAGS{POSIX}};
 
+if ($^O eq 'MSWin32') {
+    # On Windows, these errors have been observed to not always be loaded by
+    # apps/openssl, while they are in perl, which causes a difference that we
+    # consider a false alarm.  So we skip checking these errors.
+    # Because we can't know exactly what symbols exist in a perticular perl
+    # version, we resort to discovering them directly in the Errno package
+    # symbol table.
+    my @error_skiplist = qw(
+        ENETDOWN
+        ENETUNREACH
+        ENETRESET
+        ECONNABORTED
+        EISCONN
+        ENOTCONN
+        ESHUTDOWN
+        ETOOMANYREFS
+        ETIMEDOUT
+        EHOSTDOWN
+        EHOSTUNREACH
+        EALREADY
+        EINPROGRESS
+        ESTALE
+        EUCLEAN
+        ENOTNAM
+        ENAVAIL
+        ENOMEDIUM
+        ENOKEY
+    );
+    @posix_errors =
+        grep {
+            my $x = $_;
+            ! grep {
+                exists $Errno::{$_} && $x == $Errno::{$_}
+            } @error_skiplist
+        } @posix_errors;
+}
+
 plan tests => scalar @posix_errors
     +1                          # Checking that error 128 gives 'reason(128)'
     +1                          # Checking that error 0 gives the library name
@@ -58,18 +104,31 @@ foreach my $errname (@posix_errors) {
         my @oerr = run(app([ qw(openssl errstr), sprintf("2%06x", $errnum) ]),
                        capture => 1);
         $oerr[0] =~ s|\R$||;
-        $oerr[0] =~ s|.*system library:||g; # The actual message is last
-
-        ok($oerr[0] eq $perr, "($errnum) '$oerr[0]' == '$perr'");
+        @oerr = split_error($oerr[0]);
+        ok($oerr[3] eq $perr, "($errnum) '$oerr[3]' == '$perr'");
     }
 }
 
 my @after = run(app([ qw(openssl errstr 2000080) ]), capture => 1);
 $after[0] =~ s|\R$||;
-$after[0] =~ s|.*system library:||g;
-ok($after[0] eq "reason(128)", "(128) '$after[0]' == 'reason(128)'");
+@after = split_error($after[0]);
+ok($after[3] eq "reason(128)", "(128) '$after[3]' == 'reason(128)'");
 
 my @zero = run(app([ qw(openssl errstr 2000000) ]), capture => 1);
 $zero[0] =~ s|\R$||;
-$zero[0] =~ s|.*system library:||g;
-ok($zero[0] eq "system library", "(0) '$zero[0]' == 'system library'");
+@zero = split_error($zero[0]);
+ok($zero[3] eq "system library", "(0) '$zero[3]' == 'system library'");
+
+# For an error string "error:xxxxxxxx:lib:func:reason", this returns
+# the following array:
+#
+# ( "xxxxxxxx", "lib", "func", "reason" )
+sub split_error {
+    # Limit to 5 items, in case the reason contains a colon
+    my @erritems = split /:/, $_[0], 5;
+
+    # Remove the first item, which is always "error"
+    shift @erritems;
+
+    return @erritems;
+}