blob: 436d1b405d19c54db02eb5f0f2ddeff9dd9e0ca9 [file] [log] [blame]
Tomáš Pecka9b1c9672020-11-11 15:24:06 +01001/*
2 * Copyright (C) 2017-2018 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Miroslav Mareš <mmares@cesnet.cz>
5 *
6*/
7
8#include "trompeloeil_doctest.h"
9#include <filesystem>
10#include <fstream>
11#include "fs-helpers/FileInjector.h"
12#include "fs-helpers/utils.h"
13#include "ietf-hardware/sysfs/HWMon.h"
14#include "pretty_printers.h"
15#include "test_log_setup.h"
16#include "tests/configure.cmake.h"
17
18using namespace std::literals;
19
20TEST_CASE("HWMon class")
21{
22 TEST_INIT_LOGS;
23
24 const auto fakeHwmonRoot = CMAKE_CURRENT_BINARY_DIR + "/tests/hwmon/"s;
25 removeDirectoryTreeIfExists(fakeHwmonRoot);
26 velia::ietf_hardware::sysfs::HWMon::Attributes expected;
27
28 SECTION("Test hwmon/device1")
29 {
30 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device1/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
31 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
32 expected = {
33 {"temp1_crit", 105'000},
34 {"temp1_input", 66'600},
35 {"temp2_crit", 105'000},
36 {"temp2_input", 29'800},
37 {"temp10_crit", 666'777},
38 {"temp10_input", 66'600},
39 {"temp11_input", 111'222'333'444'555},
40 };
41
42 REQUIRE(hwmon.attributes() == expected);
Václav Kubernát05722e12021-04-13 08:14:37 +020043 REQUIRE(hwmon.attribute("temp1_crit") == 105'000);
44 REQUIRE_THROWS_AS(hwmon.attribute("doesnt'exist"), std::invalid_argument);
Tomáš Pecka9b1c9672020-11-11 15:24:06 +010045 }
46
47 SECTION("Test hwmon/device1 + one of the files unreadable")
48 {
49 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device1/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
50
51 // Inject temporary file for "no read permission" test
52 auto injected_noread = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_write, "-42001");
53
54 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
55 expected = {
56 {"temp1_crit", 105'000},
57 {"temp1_input", 66'600},
58 {"temp2_crit", 105'000},
59 {"temp2_input", 29'800},
60 {"temp3_input", -42'001},
61 {"temp10_crit", 666'777},
62 {"temp10_input", 66'600},
63 {"temp11_input", 111'222'333'444'555},
64 };
65
66 // no read permission now
67 REQUIRE_THROWS_AS(hwmon.attributes(), std::invalid_argument);
68
69 // read permission granted
70 injected_noread->setPermissions(std::filesystem::perms::owner_all);
71 REQUIRE(hwmon.attributes() == expected);
72 }
73
74 SECTION("Test hwmon/device1 + one of the files disappears after construction")
75 {
76 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device1/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
77
78 // Inject temporary file for "file does not exist" test
79 auto injected_notexist = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, "-42001");
80
81 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
82
83 expected = {
84 {"temp1_crit", 105'000},
85 {"temp1_input", 66'600},
86 {"temp2_crit", 105'000},
87 {"temp2_input", 29'800},
88 {"temp3_input", -42'001},
89 {"temp10_crit", 666'777},
90 {"temp10_input", 66'600},
91 {"temp11_input", 111'222'333'444'555},
92 };
93
94 // file exists, should be OK
95 REQUIRE(hwmon.attributes() == expected);
96
97 // file deleted
98 injected_notexist.reset();
99 REQUIRE_THROWS_AS(hwmon.attributes(), std::invalid_argument);
100 }
101
102 SECTION("Test hwmon/device1 + invalid values")
103 {
104 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device1/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
105
106 SECTION("Invalid content")
107 {
108 auto injected = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, "cus bus");
109 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
110 REQUIRE_THROWS_AS(hwmon.attributes(), std::domain_error);
111 }
112
113 SECTION("Invalid value range")
114 {
115 auto injected = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, "-99999999999999999999999999999999");
116 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
117 REQUIRE_THROWS_AS(hwmon.attributes(), std::domain_error);
118 }
119 }
120
121 SECTION("Test hwmon/device2")
122 {
123 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device2/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
124
125 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
126 expected = {
127 {"temp1_crit", std::numeric_limits<int64_t>::max()},
128 {"temp1_input", -34'000},
129 {"temp1_max", 80'000},
130 {"temp2_crit", std::numeric_limits<int64_t>::min()}, // we can't write an integer literal for int64_t min value (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661)
131 {"temp2_input", -34'000},
132 {"temp2_max", 80'000},
133 {"temp3_crit", 100'000},
134 {"temp3_input", 30'000},
135 {"temp3_max", 80'000},
136 {"temp4_crit", 100'000},
137 {"temp4_input", 26'000},
138 {"temp4_max", 80'000},
139 {"temp5_crit", 100'000},
140 {"temp5_input", 29'000},
141 {"temp5_max", 80'000},
142 };
143
144 REQUIRE(hwmon.attributes() == expected);
145 }
146
147 SECTION("Test wrong directory structure")
148 {
149 std::string sourceDir;
150 SECTION("No hwmonX directory")
151 {
152 sourceDir = "tests/sysfs/hwmon/device4/hwmon"s;
153 }
154 SECTION("Multiple hwmonX directories")
155 {
156 sourceDir = "tests/sysfs/hwmon/device3/hwmon"s;
157 }
158
159 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/"s + sourceDir, fakeHwmonRoot, std::filesystem::copy_options::recursive);
160
161 REQUIRE_THROWS_AS(velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot), std::invalid_argument);
162 }
163}