Skip to content

Commit b17e89f

Browse files
committedMar 22, 2022
Measure overall usage
1 parent 16c3ed4 commit b17e89f

File tree

3 files changed

+62
-67
lines changed

3 files changed

+62
-67
lines changed
 

‎coppers_sensors/src/lib.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,23 @@ impl Sensor for RAPLSensor {
9696

9797
// Implementation of RAPLSensor sepcific functions
9898
impl RAPLSensor {
99-
pub fn new(location: String) -> Result<RAPLSensor, &'static str> {
100-
let enabled_location = location.to_string() + "/enabled";
101-
let enabled = read_to_string(enabled_location);
99+
pub fn new(location: String) -> Result<RAPLSensor, String> {
100+
let enabled_location = format!("{location}/enabled");
101+
let enabled = read_to_string(&enabled_location);
102102
// Check whether the location is actually reachable
103103
if enabled.is_err() {
104-
return Err("Given location is unreachable");
104+
return Err(format!("The location `{location}` is unreachable"));
105105
}
106106
// Check if RAPL is enabled at this location
107107
// No error received to unwrap is possible
108108
/*if !enabled.unwrap().starts_with("1") { ENABLED ONLY IN PARENT DIRECTORY NOT USABLE IN CURRENT STATE
109109
return Err("RAPL sensor is not enabled");
110110
}*/
111111
// Check whether permission is set correctly of the measuring location
112-
let measuring_location = location.to_string() + "/energy_uj";
113-
let measured_energy = read_to_string(measuring_location);
112+
let measuring_location = format!("{location}/energy_uj");
113+
let measured_energy = read_to_string(&measuring_location);
114114
if measured_energy.is_err() {
115-
return Err("Missing rights to read from /energy_uj");
115+
return Err(format!("Insufficient permissions to read from {measuring_location}. You might want to retry as root."));
116116
}
117117
// Retrieve the max range value of the sensor
118118
let max_range_location = location.to_string() + "/max_energy_range_uj";

‎coppers_test_runner/test_runner/mod.rs

+55-55
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
use coppers_sensors::{RAPLSensor, Sensor};
1818
use std::any::Any;
1919
use std::io::{self, Write};
20-
use std::panic::{catch_unwind, AssertUnwindSafe};
20+
use std::panic::catch_unwind;
2121
use std::sync::{Arc, Mutex};
22-
use std::time::Instant;
2322
use test::{StaticTestFn, TestDescAndFn};
2423

2524
pub fn runner(tests: &[&test::TestDescAndFn]) {
@@ -28,34 +27,34 @@ pub fn runner(tests: &[&test::TestDescAndFn]) {
2827
println!("Running {} tests", tests.len());
2928

3029
let mut ignored = 0;
31-
let mut filtered = 0;
32-
33-
let now = Instant::now();
30+
//let mut filtered = 0;
3431

3532
let mut passed_tests = Vec::new();
3633
let mut failed_tests = Vec::new();
3734

35+
let mut sensor =
36+
RAPLSensor::new("/sys/devices/virtual/powercap/intel-rapl/intel-rapl:0".to_string())
37+
.unwrap();
38+
sensor.start_measuring();
39+
3840
for test in tests {
3941
let result = run_test(test);
4042
print_test_result(&result);
4143
match result.state {
4244
TestResult::Passed => passed_tests.push(result),
4345
TestResult::Failed(_) => failed_tests.push(result),
4446
TestResult::Ignored => ignored += 1,
45-
TestResult::Filtered => filtered += 1,
47+
//TestResult::Filtered => filtered += 1,
4648
}
47-
48-
//println!("{}", result.sensor.unwrap().get_measured_uj())
4949
}
5050

51-
let elapsed = now.elapsed();
52-
let seconds = elapsed.as_secs();
53-
let millis = elapsed.subsec_millis();
51+
sensor.stop_measuring();
52+
let elapsed = sensor.get_elapsed_time_us();
53+
let uj = sensor.get_measured_uj();
5454

5555
print_failures(&failed_tests).unwrap();
5656

57-
let total = passed_tests.len() + failed_tests.len();
58-
println!("test result: {}. {} passed; {} failed; {ignored} ignored; {filtered} filtered out; finished in {seconds}.{millis}s", passed(failed_tests.is_empty()), passed_tests.len(), failed_tests.len())
57+
println!("test result: {}. {} passed; {} failed; {ignored} ignored; finished in {elapsed} μs consuming {uj} μJ", passed(failed_tests.is_empty()), passed_tests.len(), failed_tests.len())
5958
}
6059

6160
fn print_failures(tests: &Vec<CompletedTest>) -> std::io::Result<()> {
@@ -65,39 +64,36 @@ fn print_failures(tests: &Vec<CompletedTest>) -> std::io::Result<()> {
6564
for test in tests {
6665
if let Some(captured) = &test.stdout {
6766
handle.write_fmt(format_args!("\n---- {} stdout ----\n", test.desc.name))?;
68-
handle.write_all(&captured)?;
69-
handle.write(b"\n")?;
67+
handle.write_all(captured)?;
68+
handle.write_all(b"\n")?;
7069
}
7170
}
72-
handle.write(b"\nfailures:\n")?;
71+
handle.write_all(b"\nfailures:\n")?;
7372
for test in tests {
7473
handle.write_fmt(format_args!("\t{}", test.desc.name))?;
7574
if let TestResult::Failed(Some(msg)) = &test.state {
76-
handle.write_fmt(format_args!(": {}\n", msg));
75+
handle.write_fmt(format_args!(": {}\n", msg))?;
7776
}
7877
}
79-
handle.write(b"\n")?;
78+
handle.write_all(b"\n")?;
8079
}
8180
Ok(())
8281
}
8382

8483
fn print_test_result(test: &CompletedTest) {
8584
match test.state {
8685
TestResult::Passed => {
87-
let sensor = test.sensor.as_ref().unwrap();
88-
let uj = (*sensor).get_measured_uj();
89-
let us = (*sensor).get_elapsed_time_us();
90-
println!("test {} ... {} - [{uj} μJ in {us} μs]", test.desc.name, passed(true))
91-
},
86+
let uj = test.uj.unwrap();
87+
let us = test.us.unwrap();
88+
println!(
89+
"test {} ... {} - [{uj} μJ in {us} μs]",
90+
test.desc.name,
91+
passed(true)
92+
)
93+
}
9294
TestResult::Failed(_) => {
93-
if let Some(sensor) = &test.sensor {
94-
let uj = (*sensor).get_measured_uj();
95-
let us = (*sensor).get_elapsed_time_us();
96-
println!("test {} ... {} - [{uj} μJ in {us} μs]", test.desc.name, passed(false))
97-
} else {
98-
println!("test {} ... {}", test.desc.name, passed(false))
99-
}
100-
},
95+
println!("test {} ... {}", test.desc.name, passed(false))
96+
}
10197
_ => {}
10298
}
10399
}
@@ -125,13 +121,14 @@ enum TestResult {
125121
Passed,
126122
Failed(Option<String>),
127123
Ignored,
128-
Filtered,
124+
//Filtered,
129125
}
130126

131127
struct CompletedTest {
132128
desc: test::TestDesc,
133129
state: TestResult,
134-
sensor: Option<Box<dyn Sensor>>,
130+
uj: Option<u128>,
131+
us: Option<u128>,
135132
stdout: Option<Vec<u8>>,
136133
}
137134

@@ -140,7 +137,8 @@ impl CompletedTest {
140137
CompletedTest {
141138
desc,
142139
state: TestResult::Ignored,
143-
sensor: None,
140+
uj: None,
141+
us: None,
144142
stdout: None,
145143
}
146144
}
@@ -151,34 +149,36 @@ fn run_test(test: test::TestDescAndFn) -> CompletedTest {
151149
if test.desc.ignore {
152150
CompletedTest::empty(test.desc)
153151
} else {
154-
let sensor =
155-
RAPLSensor::new("/sys/devices/virtual/powercap/intel-rapl/intel-rapl:0".to_string());
156-
157-
// If the sensor could not be properly created, mark the test as failed.
158-
if sensor.is_err() {
159-
return sensor
160-
.map_err(|err| CompletedTest {
161-
state: TestResult::Failed(Some(err.to_string())),
162-
..CompletedTest::empty(test.desc)
163-
})
164-
.unwrap_err();
165-
}
166-
let mut sensor = sensor.unwrap();
152+
let mut sensor =
153+
RAPLSensor::new("/sys/devices/virtual/powercap/intel-rapl/intel-rapl:0".to_string())
154+
.unwrap();
167155

168156
// Use internal compiler function `set_output_capture` to capture the output of the
169157
// tests.
170158
let data = Arc::new(Mutex::new(Vec::new()));
171159
io::set_output_capture(Some(data.clone()));
172160

173-
let result = match test.testfn {
174-
test::TestFn::StaticTestFn(f) => catch_unwind(AssertUnwindSafe(|| {
175-
sensor.start_measuring();
161+
let mut uj = 0;
162+
let mut us = 0;
163+
164+
let state = match test.testfn {
165+
test::TestFn::StaticTestFn(f) => {
166+
let mut state = TestResult::Ignored;
176167
// Run the test function 100 times in a row
177168
for _ in 0..100 {
178-
f();
169+
sensor.start_measuring();
170+
let result = catch_unwind(f);
171+
sensor.stop_measuring();
172+
uj += sensor.get_measured_uj();
173+
us += sensor.get_elapsed_time_us();
174+
175+
state = test_state(&test.desc, result);
176+
if state != TestResult::Passed {
177+
break;
178+
}
179179
}
180-
sensor.stop_measuring();
181-
})),
180+
state
181+
}
182182
_ => unimplemented!("Only StaticTestFns are supported right now"),
183183
};
184184

@@ -187,11 +187,11 @@ fn run_test(test: test::TestDescAndFn) -> CompletedTest {
187187
io::set_output_capture(None);
188188
let stdout = Some(data.lock().unwrap_or_else(|e| e.into_inner()).to_vec());
189189

190-
let state = test_state(&test.desc, result);
191190
CompletedTest {
192191
desc: test.desc,
193192
state,
194-
sensor: Some(Box::new(sensor)),
193+
uj: Some(uj),
194+
us: Some(us),
195195
stdout,
196196
}
197197
}

‎tests/example_tests_with_runner.rs

-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ fn test_succesful_test() {
66
assert_eq!(1 + 1, 2);
77
}
88

9-
#[test]
10-
fn test_unsuccesful_test() {
11-
assert_eq!(1 + 1, 3);
12-
}
13-
149
#[test]
1510
#[ignore]
1611
fn test_ignored_test() {

0 commit comments

Comments
 (0)
Please sign in to comment.