#!/bin/sh
# simple testing of checkpoint APIs on test driver

# Copyright (C) 2019 Red Hat, Inc.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see
# <http://www.gnu.org/licenses/>.

. "$(dirname $0)/test-lib.sh"

if test "$VERBOSE" = yes; then
  set -x
  $abs_top_builddir/tools/virsh --version
fi

fail=0

mock_xdg_ || framework_failure

# The test driver loses states between restarts, so we perform a script
# with some convenient markers for later post-processing of output.
$abs_top_builddir/tools/virsh --connect test:///default >out 2>err '
  # Create a series of checkpoints, with names that intentionally sort
  # differently by topology than by name. For now, it is not possible
  # to create fanout without hacking through redefines.
  checkpoint-create-as test c1
  checkpoint-create-as test c1
  checkpoint-create-as test c3
  checkpoint-create-as test c2
  # snapshots cannot be created while checkpoints exist
  echo --err marker
  snapshot-create-as test s1
  echo --err marker
  # Checking tree view (siblings sorted alphabetically)
  checkpoint-list test --tree
  # Demonstrate list filtering
  checkpoint-list test --roots
  checkpoint-list test --leaves
  checkpoint-list test --parent --no-leaves
  checkpoint-list test --from c3
  checkpoint-list test --from c1 --descendants --name
  # Now the tree is linear, so we have an unambiguous topological order
  checkpoint-list test --name
  checkpoint-list test --name --topological
  # Capture some XML for later redefine
  checkpoint-delete test c1
  echo "<!--MarkerA-->"
  checkpoint-dumpxml test c3
  echo "<!--MarkerB-->"
  checkpoint-dumpxml test c2
  echo "<!--MarkerC-->"
  # Deleting current checkpoint moves current up to remaining parent
  checkpoint-delete test --children-only c3
  checkpoint-list test --leaves --name
  checkpoint-delete test --children c3
  checkpoint-list test --leaves --name
  # All done
' || fail=1

# First part is expected output, --tree results in trailing spaces,
# and checkpoint-list produces timestamps
sed 's/ *$//; s/[0-9-]\{10\} [0-9:.]* .[0-9]\{4\}/TIMESTAMP/;
   /MarkerA/,/MarkerC/d' < out > out.cooked || fail=1
# Second part holds domain checkpoint XMLs
sed -n '/MarkerA/,/MarkerB/p' < out > c3.xml || fail=1
sed -n '/MarkerB/,/MarkerC/p' < out > c2.xml || fail=1

cat <<\EOF > exp || fail=1
Domain checkpoint c1 created

Domain checkpoint c3 created
Domain checkpoint c2 created



c1
  |
  +- c3
      |
      +- c2


 Name   Creation Time
-----------------------------------
 c1     TIMESTAMP

 Name   Creation Time
-----------------------------------
 c2     TIMESTAMP

 Name   Creation Time               Parent
--------------------------------------------
 c1     TIMESTAMP
 c3     TIMESTAMP   c1

 Name   Creation Time
-----------------------------------
 c2     TIMESTAMP

c2
c3

c1
c2
c3

c1
c3
c2

Domain checkpoint c1 deleted

Domain checkpoint c3 children deleted

c3

Domain checkpoint c3 deleted


EOF
compare exp out.cooked || fail=1

cat <<EOF > exp || fail=1
error: operation failed: domain moment c1 already exists
error: marker
error: Operation not supported: cannot create snapshot while checkpoint exists
error: marker
EOF
compare exp err || fail=1

# Restore state with redefine
$abs_top_builddir/tools/virsh -c test:///default >out 2>err '
  # Redefine must be in topological order; this will fail
  checkpoint-create test --redefine c2.xml
  echo --err marker
  # This is the right order
  checkpoint-create test --redefine c3.xml
  checkpoint-create test --redefine c2.xml
  checkpoint-list test --leaves --name
  checkpoint-info test c2
' || fail=1

cat <<\EOF > exp || fail=1


Domain checkpoint c3 created from 'c3.xml'
Domain checkpoint c2 created from 'c2.xml'
c2

Name:           c2
Domain:         test
Parent:         c3
Children:       0
Descendants:    0

EOF
compare exp out || fail=1

cat <<EOF > exp || fail=1
error: invalid argument: parent c3 for moment c2 not found
error: marker
EOF
compare exp err || fail=1

(exit $fail); exit $fail
