#!/bin/bash
#
# Test for the cvmfs_server transaction command returns codes
#
# This sets up a repository with gateway and simulates the case
# when another release manager has already taken the lock for
# the path we want.

cvmfs_test_name="Lease contention with repository gateway"
cvmfs_test_autofs_on_startup=false
cvmfs_test_suites="quick"


cvmfs_run_test() {
    set_up_repository_gateway || return 1

    ## Transaction 1 (Creating a new deep directory sub-tree in place of a former file)
    echo "  *** Starting transaction 1"
    cvmfs_server transaction test.repo.org || return 10
    mkdir -p /cvmfs/test.repo.org/new/c/d || return 11
    echo "New file" > /cvmfs/test.repo.org/new/c/d/new_file.txt || return 12

    echo "  *** Checking that we cannot open a transaction again"
    cvmfs_server transaction test.repo.org
    if [ $? -ne 17 ]; then
        echo "cvmfs_server transaction should tell us that we have a transaction already"
        return 20
    fi

    echo "  *** Publishing the transaction 1"
    cvmfs_server publish test.repo.org || return 30

    # Simulating another release manager taking the lease
    echo "  *** Simulating another node taking a lock on the path we want"
    # session token saved in  /var/spool/cvmfs/test.repo.org/session_token
    cvmfs_swissknife lease -u http://localhost:4929/api/v1 -a acquire \
        -k /etc/cvmfs/keys/test.repo.org.gw -p test.repo.org/new/c \
        || return 40
    # We need to remove the token, otherwise it's just taken by the transaction
    mv /var/spool/cvmfs/test.repo.org/session_token \
      /var/spool/cvmfs/test.repo.org/session_token.save || return 41

    echo "  *** Checking that the lease is taken and that cvmfs_transaction fails"
    cvmfs_server transaction test.repo.org/new/c
    retcode=$?
    if [ $retcode -ne 16 ]; then
        echo "Return code should be 16 EBUSY instead of ${retcode}"
        return 50
    fi

    echo "  *** Checking that the repository is still in a sane state"
    mv /var/spool/cvmfs/test.repo.org/session_token.save \
      /var/spool/cvmfs/test.repo.org/session_token || return 60
    cvmfs_swissknife lease -u http://localhost:4929/api/v1 -a drop \
      -k /etc/cvmfs/keys/test.repo.org.gw -p test.repo.org/new/c || return 61
    ls /var/spool/cvmfs/test.repo.org/session_token && return 62

    cvmfs_server transaction test.repo.org/new/c || return 70
    cvmfs_server abort -f test.repo.org || return 71

    echo "  *** Force abort with invalid lease"
    cvmfs_server transaction test.repo.org/ || return 80
    cp /var/spool/cvmfs/test.repo.org/session_token \
       /var/spool/cvmfs/test.repo.org/session_token.save || return 81
    cvmfs_swissknife lease -u http://localhost:4929/api/v1 -a drop \
      -k /etc/cvmfs/keys/test.repo.org.gw -p test.repo.org/new/c || return 82
    mv /var/spool/cvmfs/test.repo.org/session_token.save \
       /var/spool/cvmfs/test.repo.org/session_token || return 83
    cvmfs_server abort -f test.repo.org || return 84

    echo "  *** Force abort with missing session token"
    cvmfs_server transaction test.repo.org/ || return 90
    mv /var/spool/cvmfs/test.repo.org/session_token \
      /var/spool/cvmfs/test.repo.org/session_token.save || return 91
    cvmfs_server abort -f test.repo.org || return 92
    mv /var/spool/cvmfs/test.repo.org/session_token.save \
      /var/spool/cvmfs/test.repo.org/session_token || return 93
    cvmfs_swissknife lease -u http://localhost:4929/api/v1 -a drop \
      -k /etc/cvmfs/keys/test.repo.org.gw -p test.repo.org/ || return 94

    echo "  *** Force abort after client crash"
    cvmfs_server transaction test.repo.org/ || return 95
    ls /var/spool/cvmfs/test.repo.org/rdonly/ || return 96
    local watchdog_pid=$(cvmfs_talk -p /var/spool/cvmfs/test.repo.org/cvmfs_io pid watchdog)
    local client_pid=$(get_xattr pid /var/spool/cvmfs/test.repo.org/rdonly)
    sudo kill -9 $watchdog_pid $client_pid
    while ls /var/spool/cvmfs/test.repo.org/rdonly/; do
      sleep 1
    done
    cvmfs_server abort -f test.repo.org || return 97

    cvmfs_server transaction test.repo.org/ || return 85
    cvmfs_server abort -f test.repo.org || return 86

    return 0
}

