tsm-client: add test derivation and a module test

The tsm-client needs a tsm-server to do anything useful.
Without a server, automated tests can just
check diagnostic outputs for plausibility.

The commit at hand adds two tests:

1.
The command line interface `dsmc` is called,
then it is verified that the program does

* report the correct client version,
* find its configuration file,
* report a connection error.

2.
To check the GUI (and the tsm-client nixos module), we add a
vm test which uses the module to install `tsm-client-withGui`.
To verify that the GUI's basic functionality is present,
we skip over all connection failure related error
messages and open the "Connection Information"
dialog from the main application window.
This dialog presents the node name and the client version;
both are verified by the test.

Note: Our `tsm-client` build recipe consists of two packages:
The "unwrapped" package and the final package.
This commit puts the unwrapped one into the final
package's `passthru` so that tests can access
the original version string that is needed to check
the client version reported by the application.
main
Yarny0 3 years ago
parent c2192ed77a
commit f6dca95c5d
  1. 1
      nixos/tests/all-tests.nix
  2. 57
      nixos/tests/tsm-client-gui.nix
  3. 11
      pkgs/tools/backup/tsm-client/default.nix
  4. 58
      pkgs/tools/backup/tsm-client/test-cli.nix

@ -487,6 +487,7 @@ in
trezord = handleTest ./trezord.nix {};
trickster = handleTest ./trickster.nix {};
trilium-server = handleTestOn ["x86_64-linux"] ./trilium-server.nix {};
tsm-client-gui = handleTest ./tsm-client-gui.nix {};
txredisapi = handleTest ./txredisapi.nix {};
tuptime = handleTest ./tuptime.nix {};
turbovnc-headless-server = handleTest ./turbovnc-headless-server.nix {};

@ -0,0 +1,57 @@
# The tsm-client GUI first tries to connect to a server.
# We can't simulate a server, so we just check if
# it reports the correct connection failure error.
# After that the test persuades the GUI
# to show its main application window
# and verifies some configuration information.
import ./make-test-python.nix ({ lib, pkgs, ... }: {
name = "tsm-client";
enableOCR = true;
machine = { pkgs, ... }: {
imports = [ ./common/x11.nix ];
programs.tsmClient = {
enable = true;
package = pkgs.tsm-client-withGui;
defaultServername = "testserver";
servers.testserver = {
# 192.0.0.8 is a "dummy address" according to RFC 7600
server = "192.0.0.8";
node = "SOME-NODE";
passwdDir = "/tmp";
};
};
};
testScript = ''
machine.succeed("which dsmj") # fail early if this is missing
machine.wait_for_x()
machine.execute("DSM_LOG=/tmp dsmj -optfile=/dev/null >&2 &")
# does it report the "TCP/IP connection failure" error code?
machine.wait_for_window("IBM Spectrum Protect")
machine.wait_for_text("ANS2610S")
machine.send_key("esc")
# it asks to continue to restore a local backupset now;
# "yes" (return) leads to the main application window
machine.wait_for_text("backupset")
machine.send_key("ret")
# main window: navigate to "Connection Information"
machine.wait_for_text("Welcome")
machine.send_key("alt-f") # "File" menu
machine.send_key("c") # "Connection Information"
# "Connection Information" dialog box
machine.wait_for_window("Connection Information")
machine.wait_for_text("SOME-NODE")
machine.wait_for_text("${pkgs.tsm-client.passthru.unwrapped.version}")
machine.shutdown()
'';
meta.maintainers = [ lib.maintainers.yarny ];
})

@ -1,4 +1,6 @@
{ lib
, callPackage
, nixosTests
, stdenv
, fetchurl
, autoPatchelfHook
@ -81,6 +83,11 @@ let
'';
};
passthru.tests = {
test-cli = callPackage ./test-cli.nix {};
test-gui = nixosTests.tsm-client-gui;
};
mkSrcUrl = version:
let
major = lib.versions.major version;
@ -96,7 +103,7 @@ let
url = mkSrcUrl version;
sha256 = "0fy9c224g6rkrgd6ls01vs30bk9j9mlhf2x6akd11r7h8bib19zn";
};
inherit meta;
inherit meta passthru;
nativeBuildInputs = [
autoPatchelfHook
@ -152,7 +159,7 @@ buildEnv {
meta = meta // lib.attrsets.optionalAttrs enableGui {
mainProgram = "dsmj";
};
passthru = { inherit unwrapped; };
passthru = passthru // { inherit unwrapped; };
paths = [ unwrapped ];
nativeBuildInputs = [ makeWrapper ];
pathsToLink = [

@ -0,0 +1,58 @@
{ lib
, writeText
, runCommand
, tsm-client
}:
# Let the client try to connect to a server.
# We can't simulate a server, so there's no more to test.
let
# 192.0.0.8 is a "dummy address" according to RFC 7600
dsmSysCli = writeText "cli.dsm.sys" ''
defaultserver testserver
server testserver
commmethod v6tcpip
tcpserveraddress 192.0.0.8
nodename ARBITRARYNODENAME
'';
tsm-client_ = tsm-client.override { inherit dsmSysCli; };
env.nativeBuildInputs = [ tsm-client_ ];
versionString =
let
inherit (tsm-client_.passthru.unwrapped) version;
major = lib.versions.major version;
minor = lib.versions.minor version;
patch = lib.versions.patch version;
fixup = lib.lists.elemAt (lib.versions.splitVersion version) 3;
in
"Client Version ${major}, Release ${minor}, Level ${patch}.${fixup}";
in
runCommand "${tsm-client.name}-test-cli" env ''
set -o nounset
set -o pipefail
export DSM_LOG=$(mktemp -d ./dsm_log.XXXXXXXXXXX)
{ dsmc -optfile=/dev/null || true; } | tee dsmc-stdout
# does it report the correct version?
grep --fixed-strings '${versionString}' dsmc-stdout
# does it use the provided dsm.sys config file?
# if it does, it states the node's name
grep ARBITRARYNODENAME dsmc-stdout
# does it try (and fail) to connect to the server?
# if it does, it reports the "TCP/IP connection failure" error code
grep ANS1017E dsmc-stdout
grep ANS1017E $DSM_LOG/dsmerror.log
touch $out
''
Loading…
Cancel
Save