blob: 11de62a778b15e51cb5cbc054942e1ed71f07be7 [file] [log] [blame]
Tomáš Peckaaf7b7042021-04-20 20:14:13 +02001#include "trompeloeil_doctest.h"
2#include "dbus-helpers/dbus_rauc_server.h"
Tomáš Pecka5be83e42021-04-21 17:26:40 +02003#include "fs-helpers/utils.h"
Tomáš Peckaaf7b7042021-04-20 20:14:13 +02004#include "pretty_printers.h"
5#include "system/LED.h"
6#include "test_log_setup.h"
Tomáš Peckaaf7b7042021-04-20 20:14:13 +02007#include "tests/configure.cmake.h"
Tomáš Peckac164ca62024-01-24 13:38:03 +01008#include "tests/sysrepo-helpers/common.h"
Tomáš Pecka5be83e42021-04-21 17:26:40 +02009#include "utils/io.h"
Tomáš Peckaaf7b7042021-04-20 20:14:13 +020010
11using namespace std::literals;
12
13TEST_CASE("Sysrepo reports system LEDs")
14{
15 trompeloeil::sequence seq1;
16
17 TEST_SYSREPO_INIT_LOGS;
18 TEST_SYSREPO_INIT;
19 TEST_SYSREPO_INIT_CLIENT;
20
Jan Kundrátaf905722021-12-01 20:00:05 +010021 auto fakeSysfsDir = std::filesystem::path {CMAKE_CURRENT_BINARY_DIR + "/tests/sysrepo_system-leds/"s};
Tomáš Pecka5be83e42021-04-21 17:26:40 +020022 removeDirectoryTreeIfExists(fakeSysfsDir);
23 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/leds"s, fakeSysfsDir, std::filesystem::copy_options::recursive);
24
Tomáš Peckabe858e22023-05-17 16:14:37 +020025 const auto WAIT = 125ms /* poll interval */ + 100ms /* just to be sure */;
Tomáš Pecka63b2d652021-04-22 19:03:14 +020026
Tomáš Peckaaf7b7042021-04-20 20:14:13 +020027 velia::system::LED led(srConn, fakeSysfsDir);
28
Tomáš Peckabe858e22023-05-17 16:14:37 +020029 std::this_thread::sleep_for(WAIT);
Tomáš Peckaaf7b7042021-04-20 20:14:13 +020030
Václav Kubernát7efd6d52021-11-09 01:31:11 +010031 REQUIRE(dataFromSysrepo(client, "/czechlight-system:leds", sysrepo::Datastore::Operational) == std::map<std::string, std::string> {
Tomáš Peckaaf7b7042021-04-20 20:14:13 +020032 {"/led[name='line:green']", ""},
33 {"/led[name='line:green']/brightness", "100"},
34 {"/led[name='line:green']/name", "line:green"},
35 {"/led[name='uid:blue']", ""},
36 {"/led[name='uid:blue']/brightness", "0"},
37 {"/led[name='uid:blue']/name", "uid:blue"},
38 {"/led[name='uid:green']", ""},
39 {"/led[name='uid:green']/brightness", "39"},
40 {"/led[name='uid:green']/name", "uid:green"},
41 {"/led[name='uid:red']", ""},
42 {"/led[name='uid:red']/brightness", "100"},
43 {"/led[name='uid:red']/name", "uid:red"},
44 });
Tomáš Pecka5be83e42021-04-21 17:26:40 +020045
Tomáš Pecka63b2d652021-04-22 19:03:14 +020046 SECTION("Change uid:green brightness")
Tomáš Pecka5be83e42021-04-21 17:26:40 +020047 {
Tomáš Pecka63b2d652021-04-22 19:03:14 +020048 velia::utils::writeFile(fakeSysfsDir / "uid:green" / "brightness", "0");
49 std::this_thread::sleep_for(WAIT);
50
Václav Kubernát7efd6d52021-11-09 01:31:11 +010051 REQUIRE(dataFromSysrepo(client, "/czechlight-system:leds", sysrepo::Datastore::Operational) == std::map<std::string, std::string> {
Tomáš Pecka63b2d652021-04-22 19:03:14 +020052 {"/led[name='line:green']", ""},
53 {"/led[name='line:green']/brightness", "100"},
54 {"/led[name='line:green']/name", "line:green"},
55 {"/led[name='uid:blue']", ""},
56 {"/led[name='uid:blue']/brightness", "0"},
57 {"/led[name='uid:blue']/name", "uid:blue"},
58 {"/led[name='uid:green']", ""},
59 {"/led[name='uid:green']/brightness", "0"},
60 {"/led[name='uid:green']/name", "uid:green"},
61 {"/led[name='uid:red']", ""},
62 {"/led[name='uid:red']/brightness", "100"},
63 {"/led[name='uid:red']/name", "uid:red"},
64 });
Tomáš Pecka5be83e42021-04-21 17:26:40 +020065 }
66
Tomáš Pecka63b2d652021-04-22 19:03:14 +020067 SECTION("Test UID RPC")
Tomáš Pecka5be83e42021-04-21 17:26:40 +020068 {
Tomáš Pecka63b2d652021-04-22 19:03:14 +020069 std::string state;
70 std::string expectedTrigger;
71 std::string expectedBrightness;
Tomáš Pecka5be83e42021-04-21 17:26:40 +020072
Tomáš Pecka63b2d652021-04-22 19:03:14 +020073 /* This isn't what actually happens in real-life. The contents of the trigger file is usually something like this (i.e., list of available triggers).
74 *
75 * [none] kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock mmc0 timer oneshot heartbeat gpio default-on transient panic netdev f1072004.mdio-mii:01:link f1072004.mdio-mii:01:1Gbps f1072004.mdio-mii:01:100Mbps f1072004.mdio-mii:01:10Mbps f1072004.mdio-mii:00:link f1072004.mdio-mii:00:1Gbps f1072004.mdio-mii:00:100Mbps f1072004.mdio-mii:00:10Mbps
76 *
77 * The value enclosed in brackets is the current active trigger. You can change it by writing a value corresponding to a trigger to the trigger file.
78 * I'm not going to simulate sysfs led behaviour here, so just test that the original contents was "none" and the value written by the RPC is the expected value.
79 * Also, I'm not implementing the 'timer' trigger behaviour, so the value written to the brightness file is static.
80 */
81 REQUIRE(velia::utils::readFileString(fakeSysfsDir / "uid:blue" / "trigger") == "none");
Tomáš Pecka5be83e42021-04-21 17:26:40 +020082
Tomáš Pecka63b2d652021-04-22 19:03:14 +020083 SECTION("UID led on")
84 {
85 state = "on";
86 expectedTrigger = "none";
87 expectedBrightness = "256";
88 }
89
90 SECTION("UID led off")
91 {
92 state = "off";
93 expectedTrigger = "none";
94 expectedBrightness = "0";
95 }
96
97 SECTION("UID led blinking")
98 {
99 state = "blinking";
100 expectedTrigger = "timer";
101 expectedBrightness = "256";
102 }
103
Jan Kundrátb3e99982022-03-18 17:38:20 +0100104 auto rpcInput = client.getContext().newPath("/czechlight-system:leds/uid/state", state);
Václav Kubernát7efd6d52021-11-09 01:31:11 +0100105
106 auto res = client.sendRPC(rpcInput);
107 REQUIRE(res.child() == std::nullopt);
Tomáš Pecka63b2d652021-04-22 19:03:14 +0200108 REQUIRE(velia::utils::readFileString(fakeSysfsDir / "uid:blue" / "trigger") == expectedTrigger);
109 REQUIRE(velia::utils::readFileString(fakeSysfsDir / "uid:blue" / "brightness") == expectedBrightness);
110 }
Tomáš Peckaaf7b7042021-04-20 20:14:13 +0200111}