blob: 3f9fb63f97119d07555138d5f2c87f405e1d83fe [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);
43 }
44
45 SECTION("Test hwmon/device1 + one of the files unreadable")
46 {
47 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device1/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
48
49 // Inject temporary file for "no read permission" test
50 auto injected_noread = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_write, "-42001");
51
52 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
53 expected = {
54 {"temp1_crit", 105'000},
55 {"temp1_input", 66'600},
56 {"temp2_crit", 105'000},
57 {"temp2_input", 29'800},
58 {"temp3_input", -42'001},
59 {"temp10_crit", 666'777},
60 {"temp10_input", 66'600},
61 {"temp11_input", 111'222'333'444'555},
62 };
63
64 // no read permission now
65 REQUIRE_THROWS_AS(hwmon.attributes(), std::invalid_argument);
66
67 // read permission granted
68 injected_noread->setPermissions(std::filesystem::perms::owner_all);
69 REQUIRE(hwmon.attributes() == expected);
70 }
71
72 SECTION("Test hwmon/device1 + one of the files disappears after construction")
73 {
74 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device1/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
75
76 // Inject temporary file for "file does not exist" test
77 auto injected_notexist = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, "-42001");
78
79 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
80
81 expected = {
82 {"temp1_crit", 105'000},
83 {"temp1_input", 66'600},
84 {"temp2_crit", 105'000},
85 {"temp2_input", 29'800},
86 {"temp3_input", -42'001},
87 {"temp10_crit", 666'777},
88 {"temp10_input", 66'600},
89 {"temp11_input", 111'222'333'444'555},
90 };
91
92 // file exists, should be OK
93 REQUIRE(hwmon.attributes() == expected);
94
95 // file deleted
96 injected_notexist.reset();
97 REQUIRE_THROWS_AS(hwmon.attributes(), std::invalid_argument);
98 }
99
100 SECTION("Test hwmon/device1 + invalid values")
101 {
102 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device1/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
103
104 SECTION("Invalid content")
105 {
106 auto injected = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, "cus bus");
107 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
108 REQUIRE_THROWS_AS(hwmon.attributes(), std::domain_error);
109 }
110
111 SECTION("Invalid value range")
112 {
113 auto injected = std::make_unique<FileInjector>(fakeHwmonRoot + "/hwmon0/temp3_input", std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, "-99999999999999999999999999999999");
114 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
115 REQUIRE_THROWS_AS(hwmon.attributes(), std::domain_error);
116 }
117 }
118
119 SECTION("Test hwmon/device2")
120 {
121 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/tests/sysfs/hwmon/device2/hwmon"s, fakeHwmonRoot, std::filesystem::copy_options::recursive);
122
123 auto hwmon = velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot);
124 expected = {
125 {"temp1_crit", std::numeric_limits<int64_t>::max()},
126 {"temp1_input", -34'000},
127 {"temp1_max", 80'000},
128 {"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)
129 {"temp2_input", -34'000},
130 {"temp2_max", 80'000},
131 {"temp3_crit", 100'000},
132 {"temp3_input", 30'000},
133 {"temp3_max", 80'000},
134 {"temp4_crit", 100'000},
135 {"temp4_input", 26'000},
136 {"temp4_max", 80'000},
137 {"temp5_crit", 100'000},
138 {"temp5_input", 29'000},
139 {"temp5_max", 80'000},
140 };
141
142 REQUIRE(hwmon.attributes() == expected);
143 }
144
145 SECTION("Test wrong directory structure")
146 {
147 std::string sourceDir;
148 SECTION("No hwmonX directory")
149 {
150 sourceDir = "tests/sysfs/hwmon/device4/hwmon"s;
151 }
152 SECTION("Multiple hwmonX directories")
153 {
154 sourceDir = "tests/sysfs/hwmon/device3/hwmon"s;
155 }
156
157 std::filesystem::copy(CMAKE_CURRENT_SOURCE_DIR + "/"s + sourceDir, fakeHwmonRoot, std::filesystem::copy_options::recursive);
158
159 REQUIRE_THROWS_AS(velia::ietf_hardware::sysfs::HWMon(fakeHwmonRoot), std::invalid_argument);
160 }
161}