summary: Run a smoke test on UC20 with encryption enabled

details: |
    This test checks basic snapd commands on UC20 with secure boot and encryption enabled

systems: [ubuntu-20.04-64]

execute: |
    echo "Wait for the system to be seeded first"
    tests.nested exec "sudo snap wait system seed.loaded"

    echo "Wait for device initialisation to be done"
    tests.nested exec "retry --wait 5 -n 10 sh -c 'snap changes | MATCH \"Done.*Initialize device\"'"

    echo "Ensure 'snap install' works"
    # The install command could cause a ssh break, so || true is used
    # and then we check the installation was completed successfully
    tests.nested exec "sudo snap install test-snapd-sh" || true

    echo "Ensure 'snap list' works and test-snapd-sh snap is installed"
    tests.nested exec "snap list" | MATCH test-snapd-sh

    echo "Ensure 'snap find' works"
    tests.nested exec "snap find test-snapd-sh" | MATCH ^test-snapd-sh

    echo "Ensure 'snap info' works"
    tests.nested exec "snap info test-snapd-sh" | MATCH '^name:\ +test-snapd-sh'

    echo "Ensure 'snap remove' works"
    # The install command could cause a ssh break, so || true is used
    # and then we check the removal was completed successfully
    tests.nested exec "sudo snap remove test-snapd-sh" || true

    echo "Ensure 'snap list' works and test-snapd-sh snap is removed"
    tests.nested exec "! snap list test-snapd-sh"

    echo "Ensure that recovery keys are not present in fresh install"
    tests.nested exec "test ! -f /var/lib/snapd/device/fde/recovery.key"
    tests.nested exec "test ! -f /var/lib/snapd/device/fde/reinstall.key"

    # single key for ubuntu-data and ubuntu-save
    test "$(tests.nested exec "sudo cryptsetup luksDump /dev/vda4 |grep Key:" | wc -l)" = "1"
    test "$(tests.nested exec "sudo cryptsetup luksDump /dev/vda5 |grep Key:" | wc -l)" = "1"

    echo "Ensure 'snap debug show-keys' works as root"
    tests.nested exec "sudo snap recovery --show-keys" > show-keys.out
    MATCH 'recovery:\s+[0-9]{5}-[0-9]{5}-[0-9]{5}-[0-9]{5}-[0-9]{5}-[0-9]{5}-[0-9]{5}-[0-9]{5}' < show-keys.out
    # reinstall key is not generated anymore
    # show-keys should be idempotent, so let's call it multiple times
    tests.nested exec "sudo snap recovery --show-keys" > show-keys-again.out
    # outputs are identical
    diff -u show-keys.out show-keys-again.out

    # key files are present
    tests.nested exec "test -f /var/lib/snapd/device/fde/recovery.key"
    tests.nested exec "test ! -f /var/lib/snapd/device/fde/reinstall.key"
    # and each partition has 2 keys now
    test "$(tests.nested exec "sudo cryptsetup luksDump /dev/vda4 |grep Key:" | wc -l)" = "2"
    test "$(tests.nested exec "sudo cryptsetup luksDump /dev/vda5 |grep Key:" | wc -l)" = "2"

    echo "But not as user (normal file permissions prevent this)"
    if tests.nested exec "snap recovery --show-keys"; then
        echo "snap recovery --show-keys should not work as a user"
        exit 1
    fi

    # the remove API isn't exposed by snap recovery yet
    tests.nested exec "sudo snap install --devmode --edge test-snapd-curl"
    tests.nested exec "sudo test-snapd-curl.curl --unix-socket /run/snapd.socket -D- -d '{\"action\":\"remove\"}' http://localhost/v2/system-recovery-keys"

    # keys were removed
    tests.nested exec "test ! -f /var/lib/snapd/device/fde/recovery.key"
    tests.nested exec "test ! -f /var/lib/snapd/device/fde/reinstall.key"
    # back to having just one key
    test "$(tests.nested exec "sudo cryptsetup luksDump /dev/vda4 |grep Key:" | wc -l)" = "1"
    test "$(tests.nested exec "sudo cryptsetup luksDump /dev/vda5 |grep Key:" | wc -l)" = "1"

    echo "Check that the serial backed up to save is as expected"
    tests.nested exec 'cat /var/lib/snapd/save/device/asserts-v0/serial/'"$(tests.nested get model-authority)"'/pc/*/active' >serial.saved
    tests.nested exec snap model --serial --assertion >serial
    cmp serial serial.saved

    echo "Check that we go the install log after the transition to run mode"
    tests.nested exec "test -e /var/log/install-mode.log.gz"

    echo "Transparently verify that the format is gzip"
    tests.nested exec "zcat /var/log/install-mode.log.gz" | MATCH 'installing a new system'

    echo "Check that we go the timings after the transition to run mode"
    tests.nested exec "test -e /var/log/install-timings.txt.gz"
    tests.nested exec "zcat /var/log/install-timings.txt.gz" > install-timings.txt
    MATCH "Install the system"        < install-timings.txt
    MATCH "^seed"                     < install-timings.txt
    MATCH "Mark system seeded"        < install-timings.txt
    MATCH "Setup system for run mode" < install-timings.txt
    MATCH "ensure=install-system"     < install-timings.txt

    echo "Check seeding info"
    tests.nested exec "snap debug seeding" | MATCH "^seeded: +true"
    tests.nested exec "snap debug seeding" | MATCH "^preseeded: +false"
