]> xenbits.xensource.com Git - xentesttools/bootstrap.git/commitdiff
livepatch: Add livepatch_test.pl test-case
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tue, 25 Jul 2017 16:53:28 +0000 (12:53 -0400)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 26 Jul 2017 18:37:05 +0000 (14:37 -0400)
which mirrors what is in OSSTest but is standalone.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
root_image/debugspace/livepatch_test.pl [new file with mode: 0755]
root_image/etc/init.d/rcS

diff --git a/root_image/debugspace/livepatch_test.pl b/root_image/debugspace/livepatch_test.pl
new file mode 100755 (executable)
index 0000000..37fb668
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/perl -w
+# Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+#
+
+use Data::Dumper;
+use File::Temp qw(tempfile);
+
+
+my @livepatch_files = qw(xen_hello_world.livepatch
+                        xen_replace_world.livepatch
+                         xen_bye_world.livepatch
+                        xen_nop.livepatch);
+
+my $livepatch_dir="/usr/lib/debug/livepatch";
+my $xen_extra_info;
+my $xen_minor_ver;
+
+sub populate_data {
+    my @lines = split('\n', $_);
+    foreach my $line (@lines) {
+        my ($key, $values) = split /:/, $line;
+        $values = join("", $values);
+        chomp($values);
+        if ($key =~ m/xen_extra/) {
+            $xen_extra_info = $values;
+        }
+        if ($key =~ m/xen_minor/) {
+            $xen_minor_ver = $values;
+        }
+    }
+    return 1 if $xen_extra_info && $xen_minor_ver;
+    return 0;
+}
+
+sub check_for_hello_world {
+    return m/xen_extra/ && m/Hello World/;
+}
+
+sub check_for_stock {
+    return m/xen_extra/ && m/$xen_extra_info/;
+}
+
+# Make sure the xen_major or xen_minor are not the same as
+# $xen_major_ver or $xen_minor_ver
+sub check_versions {
+    my @lines = split('\n', $_);
+    foreach my $line (@lines) {
+        my ($key, $values) = split /:/, $line;
+        $values = join("", $values);
+        chomp($values);
+        if ($key =~ m/xen_minor/) {
+            if ($values ne $xen_minor_ver ) {
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+my @livepatch_tests = (
+    # Whether we can actually execute it.
+    { C => "xen-livepatch list" },
+    # And we better have a clean slate..
+    { C => "xen-livepatch list", OutputCheck => sub { return !m/xen_/; } },
+    # Sets the default values
+    { C => "xl info", OutputCheck => \&populate_data },
+    # Sanity check that populate_data did its job.
+    { C => "xl info",
+      OutputCheck => \&check_for_stock },
+    # Let it rip!
+    { C => "xen-livepatch revert xen_hello_world", rc => 256 },
+    { C => "xen-livepatch load xen_hello_world.livepatch" },
+    { C => "xen-livepatch load xen_hello_world.livepatch", rc => 256 },
+    { C => "xen-livepatch list",
+      OutputCheck => sub { m/xen_hello_world/ } },
+    { C => "xl info",
+      OutputCheck => \&check_for_hello_world },
+    { C => "xen-livepatch revert xen_hello_world" },
+    { C => "xl info",
+      OutputCheck => \&check_for_stock },
+    { C => "xen-livepatch unload xen_hello_world" },
+    { C => "xen-livepatch unload xen_hello_world", rc => 256 },
+    { C => "xl info",
+      OutputCheck => \&check_for_stock },
+    { C => "xen-livepatch load xen_hello_world.livepatch" },
+    { C => "xl info",
+      OutputCheck => \&check_for_hello_world },
+    { C => "xen-livepatch load xen_bye_world.livepatch" },
+    { C => "xl info",
+      OutputCheck => sub { m/xen_extra/ && m/Bye World/ } },
+    { C => "xen-livepatch upload xen_replace xen_replace_world.livepatch" },
+    { C => "xen-livepatch replace xen_replace" },
+    { C => "xl info",
+      OutputCheck => sub { m/xen_extra/ && m/Hello Again Wo/ } },
+    { C => "xen-livepatch apply xen_hello_world", rc => 256 },
+    { C => "xen-livepatch apply xen_bye_world", rc => 256 },
+    { C => "xen-livepatch apply xen_replace" },
+    { C => "xen-livepatch revert xen_replace" },
+    { C => "xen-livepatch unload xen_replace" },
+    { C => "xen-livepatch unload xen_hello_world" },
+    { C => "xen-livepatch unload xen_bye_world" },
+    { C => "xen-livepatch list",
+      OutputCheck => sub { !m/xen_/ } },
+    { C => "xl info",
+      OutputCheck => \&check_for_stock },
+    { C => "xen-livepatch load xen_nop.livepatch" },
+    { C => "xen-livepatch revert xen_nop" },
+    { C => "xen-livepatch apply xen_nop" },
+    { C => "xl info",
+      OutputCheck => \&check_versions },
+    { C => "xen-livepatch unload xen_nop", rc => 256 },
+    { C => "xen-livepatch revert xen_nop" },
+    { C => "xen-livepatch unload xen_nop" },
+    );
+
+# Copied from https://stackoverflow.com/questions/11514947/capture-the-output-of-perl-system
+sub mysystem {
+    my $cmd = shift; #"rsync -avz --progress -h $fullfile $copyfile";
+    my ($fh, $filename) = tempfile();
+    # http://stackoverflow.com/a/6872163/2923406
+    # I want to have rsync progress output on the terminal AND capture it in case of error.
+    # Need to use pipefail because 'tee' would be the last cmd otherwise and hence $? would be wrong.
+    my @cmd = ("bash", "-c", "set -o pipefail && $cmd 2>&1 | tee $filename");
+    my $ret = system(@cmd);
+    my $outerr = join('', <$fh>);
+    close $fh;
+    system("rm $filename");
+    return ($ret,$outerr);
+}
+
+sub livepatch_test () {
+    print "Have ".(scalar @livepatch_tests)." test-cases\n";
+    my $rc;
+    my $output;
+
+    foreach my $test (@livepatch_tests) {
+        # Default rc is zero.
+        my $expected_rc = defined($test->{rc}) ? $test->{rc} : 0;
+        my $cmd = "(set -e;cd $livepatch_dir;$test->{C})";
+       print "Executing: '$cmd' ..";
+       my ($rc, $output)=mysystem($cmd);
+
+        if ($rc != $expected_rc) {
+            print "FAILED (got $rc, expected: $expected_rc): \n";
+            die $rc;
+        }
+        if (defined($test->{OutputCheck})) {
+            $_ = $output;
+            $rc=$test->{OutputCheck}->();
+            if ($rc ne 1) {
+                die "FAILED! OutputCheck=$test->{OutputCheck}, input=$output\n";
+            }
+        }
+   }
+   return 0;
+}
+
+my $livepatch_result = livepatch_test();
+print("Livepatch test returned $livepatch_result");
+exit $livepatch_result;
index c1490c424b01c3f95f1c5b3242d8d8dd5f03b665..3813e1ea7406ba259e09704b05c70b25114dedeb 100755 (executable)
@@ -181,6 +181,9 @@ if [ $? == 0 ]; then
                                reboot
                        fi
                        ;;
+               livepatch)
+                       /livepatch_test.pl
+                       ;;
        esac
 fi
 echo "while (true); do  if [ -e /tmp/go ]; then   sleep 2;init -q; rm /tmp/go; break;  fi;  sleep 1;  echo "."; done" >> /tmp/reinit