]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: cover hostnamectl tag editing and the new hostnamed Varlink methods
authorLennart Poettering <lennart@amutable.com>
Fri, 29 May 2026 20:15:14 +0000 (22:15 +0200)
committerLennart Poettering <lennart@amutable.com>
Mon, 1 Jun 2026 08:56:16 +0000 (10:56 +0200)
Add two testcases to TEST-71-HOSTNAME:

 - testcase_tags exercises the new "hostnamectl tags" +/- prefix syntax
   (add/remove, idempotency, the no-mixing rule, invalid input), the
   AddAndRemoveTags() D-Bus method and the SetTags() Varlink method
   (set/add/remove, explicit empty set, current-list basis).

 - testcase_varlink_setters exercises the new SetHostname(),
   SetStaticHostname(), SetPrettyHostname(), SetIconName(), SetChassis(),
   SetDeployment() and SetLocation() Varlink methods, including resetting
   values via null and rejection of invalid input.

test/units/TEST-71-HOSTNAME.sh

index 9bd743dcaa6613f46c7a528722e308fa17fd4fa6..369bed5f6e9051e8b29b59337ab8da80991c122f 100755 (executable)
@@ -388,6 +388,123 @@ EOF
     assert_rc 1 busctl call org.freedesktop.hostname1 /org/freedesktop/hostname1 org.freedesktop.hostname1 GetMachineInfo s CHASSIS
 }
 
+testcase_tags() {
+    if [[ -f /etc/machine-info ]]; then
+        cp /etc/machine-info /tmp/machine-info.bak
+    fi
+
+    trap restore_machine_info RETURN
+
+    # Start from a clean slate.
+    hostnamectl tags ""
+    assert_eq "$(hostnamectl tags)" ""
+
+    # Plain arguments replace the whole list; each argument may itself be a colon-separated list, and the
+    # result is deduplicated and sorted.
+    hostnamectl tags foo bar:baz
+    assert_eq "$(hostnamectl tags)" "bar:baz:foo"
+
+    # A leading '+' adds, a leading '-' removes, and the prefix applies to all (colon-separated) tags of
+    # the argument.
+    hostnamectl tags +quux
+    assert_eq "$(hostnamectl tags)" "bar:baz:foo:quux"
+    hostnamectl tags -- -foo
+    assert_eq "$(hostnamectl tags)" "bar:baz:quux"
+    hostnamectl tags -- +alpha:beta -bar:baz
+    assert_eq "$(hostnamectl tags)" "alpha:beta:quux"
+
+    # Adding an existing tag and removing a non-existing one are no-ops.
+    hostnamectl tags +alpha
+    assert_eq "$(hostnamectl tags)" "alpha:beta:quux"
+    hostnamectl tags -- -nonexistent
+    assert_eq "$(hostnamectl tags)" "alpha:beta:quux"
+
+    # Plain and prefixed arguments may not be mixed.
+    (! hostnamectl tags foo +bar)
+    (! hostnamectl tags +bar foo)
+    # Invalid tag characters are refused.
+    (! hostnamectl tags "in valid")
+    (! hostnamectl tags "+in/valid")
+
+    # The AddAndRemoveTags() D-Bus method directly.
+    hostnamectl tags ""
+    busctl call org.freedesktop.hostname1 /org/freedesktop/hostname1 org.freedesktop.hostname1 \
+            AddAndRemoveTags asas 2 one two 0
+    assert_eq "$(hostnamectl tags)" "one:two"
+    busctl call org.freedesktop.hostname1 /org/freedesktop/hostname1 org.freedesktop.hostname1 \
+            AddAndRemoveTags asas 1 three 1 one
+    assert_eq "$(hostnamectl tags)" "three:two"
+
+    # The SetTags() Varlink method: 'set' resets the list, then 'add'/'remove' are applied on top.
+    varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags \
+            '{"set":["x","y"],"add":["z"],"remove":["x"]}'
+    assert_eq "$(hostnamectl tags)" "y:z"
+    # An explicit empty 'set' clears the list first.
+    varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"set":[]}'
+    assert_eq "$(hostnamectl tags)" ""
+    # Without 'set' the current list is the basis.
+    varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"add":["aaa","bbb"]}'
+    assert_eq "$(hostnamectl tags)" "aaa:bbb"
+    varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"remove":["aaa"]}'
+    assert_eq "$(hostnamectl tags)" "bbb"
+    # Invalid tags are refused.
+    (! varlinkctl call /run/systemd/io.systemd.Hostname io.systemd.Hostname.SetTags '{"add":["in valid"]}')
+
+    hostnamectl tags ""
+}
+
+testcase_varlink_setters() {
+    local bus=/run/systemd/io.systemd.Hostname
+
+    if [[ -f /etc/hostname ]]; then
+        cp /etc/hostname /tmp/hostname.bak
+    fi
+    if [[ -f /etc/machine-info ]]; then
+        cp /etc/machine-info /tmp/machine-info.bak
+    fi
+
+    trap 'restore_hostname; restore_machine_info' RETURN
+
+    # Static hostname.
+    varlinkctl call "$bus" io.systemd.Hostname.SetStaticHostname '{"newValue":"vl-static"}'
+    assert_eq "$(cat /etc/hostname)" "vl-static"
+    assert_in "Static hostname: vl-static" "$(hostnamectl)"
+
+    varlinkctl call "$bus" io.systemd.Hostname.SetStaticHostname '{"newValue":null}'
+    test ! -e /etc/hostname
+
+    # Transient hostname; a null value resets it back to the fallback
+    varlinkctl call "$bus" io.systemd.Hostname.SetHostname '{"newValue":"vl-transient"}'
+    assert_eq "$(hostname)" "vl-transient"
+    varlinkctl call "$bus" io.systemd.Hostname.SetHostname '{"newValue":null}'
+    assert_neq "$(hostname)" "vl-transient"
+
+    # Machine-info fields.
+    varlinkctl call "$bus" io.systemd.Hostname.SetPrettyHostname '{"newValue":"Pretty VL"}'
+    assert_eq "$(hostnamectl --json=short | jq --raw-output .PrettyHostname)" "Pretty VL"
+
+    varlinkctl call "$bus" io.systemd.Hostname.SetIconName '{"newValue":"computer-vl"}'
+    assert_eq "$(hostnamectl --json=short | jq --raw-output .IconName)" "computer-vl"
+
+    varlinkctl call "$bus" io.systemd.Hostname.SetChassis '{"newValue":"tablet"}'
+    assert_eq "$(hostnamectl chassis)" "tablet"
+
+    varlinkctl call "$bus" io.systemd.Hostname.SetDeployment '{"newValue":"staging"}'
+    assert_eq "$(hostnamectl --json=short | jq --raw-output .Deployment)" "staging"
+
+    varlinkctl call "$bus" io.systemd.Hostname.SetLocation '{"newValue":"Rack 7"}'
+    assert_eq "$(hostnamectl --json=short | jq --raw-output .Location)" "Rack 7"
+
+    # A null value removes the field again.
+    varlinkctl call "$bus" io.systemd.Hostname.SetLocation '{"newValue":null}'
+    assert_eq "$(hostnamectl --json=short | jq --raw-output .Location)" "null"
+
+    # Invalid values are refused.
+    (! varlinkctl call "$bus" io.systemd.Hostname.SetChassis '{"newValue":"nonsense"}')
+    (! varlinkctl call "$bus" io.systemd.Hostname.SetIconName '{"newValue":"in/valid"}')
+    (! varlinkctl call "$bus" io.systemd.Hostname.SetStaticHostname '{"newValue":"invalid hostname"}')
+}
+
 run_testcases
 
 touch /testok