Publish tool cleanup and Framework monitoring refinements
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "hardware.h"
|
||||
#include "fan.h"
|
||||
#include "cpu.h"
|
||||
#include "power.h"
|
||||
#include <QTest>
|
||||
#include <QTemporaryDir>
|
||||
#include <QDir>
|
||||
@@ -14,6 +15,76 @@ class HardwareTest : public QObject {
|
||||
QFile file(path); QVERIFY(file.open(QIODevice::WriteOnly)); QCOMPARE(file.write(value), value.size());
|
||||
}
|
||||
private Q_SLOTS:
|
||||
void energyCounters() {
|
||||
EnergyCounter counter;
|
||||
const quint64 range = 262143328850ULL;
|
||||
QVERIFY(!counter.sample(1000000, range, 0, 3000));
|
||||
QCOMPARE(counter.sample(6000000, range, 1000, 3000), std::optional<double>(5));
|
||||
QCOMPARE(counter.sample(16000000, range, 3000, 3000), std::optional<double>(5));
|
||||
QVERIFY(!counter.sample(100, range, 4000, 3000)); // Reset, not a wrap.
|
||||
QCOMPARE(counter.sample(100, range, 5000, 3000), std::optional<double>(0));
|
||||
QVERIFY(!counter.sample(200, range, 10000, 3000)); // Long gaps establish a new baseline.
|
||||
QCOMPARE(counter.sample(1000200, range, 11000, 3000), std::optional<double>(1));
|
||||
EnergyCounter wrapped;
|
||||
QVERIFY(!wrapped.sample(range - 3000000, range, 0, 3000));
|
||||
QCOMPARE(wrapped.sample(2000000, range, 1000, 3000), std::optional<double>(5));
|
||||
QVERIFY(!wrapped.sample(100, 100000000, 2000, 3000)); // Changed range.
|
||||
QVERIFY(!wrapped.sample(100, 0, 3000, 3000));
|
||||
QVERIFY(!wrapped.sample(range + 1, range, 4000, 3000));
|
||||
EnergyCounter large;
|
||||
const quint64 base = 1ULL << 60;
|
||||
QVERIFY(!large.sample(base, base * 2, 0, 3000));
|
||||
QCOMPARE(large.sample(base + 1000, base * 2, 1000, 3000), std::optional<double>(.001));
|
||||
}
|
||||
void powerDiscoveryAndSampling() {
|
||||
QTemporaryDir root;
|
||||
const QString rapl = root.path() + "/class/powercap/intel-rapl:0/";
|
||||
const QString mmio = root.path() + "/class/powercap/intel-rapl-mmio:0/";
|
||||
for (const auto &path : {rapl, mmio}) {
|
||||
put(path + "name", "package-0"); put(path + "energy_uj", "1000000");
|
||||
put(path + "max_energy_range_uj", "262143328850");
|
||||
}
|
||||
const QString fan = root.path() + "/class/hwmon/hwmon9/";
|
||||
put(fan + "name", "power_meter"); put(fan + "power1_input", "250000"); put(fan + "power1_average", "500000");
|
||||
const QString acpiFan = root.path() + "/class/hwmon/hwmon10/";
|
||||
put(acpiFan + "name", "acpi_fan"); put(acpiFan + "power1_input", "0");
|
||||
PowerMonitor monitor(root.path()); QCOMPARE(monitor.sensors().size(), 2);
|
||||
QCOMPARE(monitor.sensors()[0].name, QString("CPU package"));
|
||||
QCOMPARE(monitor.sensors()[0].path, rapl + "energy_uj");
|
||||
const QString cpu = monitor.sensors()[0].id, fanId = monitor.sensors()[1].id;
|
||||
auto values = monitor.sample(1000, 0);
|
||||
QVERIFY(!values.contains(cpu)); QCOMPARE(values.value(fanId), .25);
|
||||
put(rapl + "energy_uj", "6000000");
|
||||
values = monitor.sample(1000, 1000); QCOMPARE(values.value(cpu), 5.);
|
||||
put(rapl + "energy_uj", "unavailable"); QVERIFY(!monitor.sample(1000, 2000).contains(cpu));
|
||||
put(rapl + "energy_uj", "11000000"); QVERIFY(!monitor.sample(1000, 3000).contains(cpu));
|
||||
put(rapl + "energy_uj", "16000000"); QCOMPARE(monitor.sample(1000, 4000).value(cpu), 5.);
|
||||
monitor.reset(); QVERIFY(!monitor.sample(1000, 5000).contains(cpu));
|
||||
put(fan + "power1_input", "0"); QCOMPARE(monitor.sample(1000, 6000).value(fanId), 0.);
|
||||
QTemporaryDir fallback;
|
||||
const QString fallbackZone = fallback.path() + "/class/powercap/intel-rapl-mmio:0/";
|
||||
put(fallbackZone + "name", "package-0"); put(fallbackZone + "energy_uj", "0");
|
||||
PowerMonitor mmioOnly(fallback.path()); QCOMPARE(mmioOnly.sensors().size(), 1);
|
||||
QCOMPARE(mmioOnly.sensors()[0].id, cpu);
|
||||
QVERIFY(mmioOnly.sample(1000, 0).isEmpty()); // Missing range is not a zero reading.
|
||||
}
|
||||
void platformPowerIsExcluded() {
|
||||
for (const auto &prefix : {"intel-rapl:", "intel-rapl-mmio:"}) {
|
||||
QTemporaryDir root;
|
||||
const QStringList names{"package-0", "core", "uncore", "dram", "psys", "psys-0"};
|
||||
for (int i = 0; i < names.size(); ++i) {
|
||||
const QString path = root.path() + "/class/powercap/" + prefix + QString::number(i) + "/";
|
||||
put(path + "name", names[i].toUtf8()); put(path + "energy_uj", "0");
|
||||
put(path + "max_energy_range_uj", "1000000");
|
||||
}
|
||||
PowerMonitor monitor(root.path());
|
||||
QStringList discovered;
|
||||
for (const auto &sensor : monitor.sensors()) discovered.append(sensor.name);
|
||||
QCOMPARE(discovered, QStringList({"CPU package", "CPU cores", "Uncore", "Memory (RAPL)"}));
|
||||
QVERIFY(monitor.sample(1000, 0).isEmpty());
|
||||
QCOMPARE(monitor.sample(1000, 1000).size(), 4);
|
||||
}
|
||||
}
|
||||
void modelGate() {
|
||||
QTemporaryDir root;
|
||||
QVERIFY(!compatibilityError(root.path()).isEmpty());
|
||||
|
||||
Reference in New Issue
Block a user