1 // Copyright 2022 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #define PW_LOG_MODULE_NAME "pw_perf_test"
15 #define PW_LOG_LEVEL PW_LOG_LEVEL_INFO
16
17 #include "pw_perf_test/perf_test.h"
18
19 #include <cstdint>
20
21 #include "pw_log/log.h"
22 #include "pw_perf_test/event_handler.h"
23 #include "pw_perf_test/internal/timer.h"
24
25 namespace pw::perf_test {
26 namespace internal {
27
28 Framework Framework::framework_;
29
RunAllTests()30 int Framework::RunAllTests() {
31 if (!internal::TimerPrepare()) {
32 return false;
33 }
34
35 event_handler_->RunAllTestsStart(run_info_);
36
37 for (const TestInfo* test = tests_; test != nullptr; test = test->next()) {
38 State test_state =
39 CreateState(kDefaultIterations, *event_handler_, test->test_name());
40 test->Run(test_state);
41 }
42 internal::TimerCleanup();
43 event_handler_->RunAllTestsEnd();
44 return true;
45 }
46
RegisterTest(TestInfo & new_test)47 void Framework::RegisterTest(TestInfo& new_test) {
48 ++run_info_.total_tests;
49 if (tests_ == nullptr) {
50 tests_ = &new_test;
51 return;
52 }
53 TestInfo* info = tests_;
54 for (; info->next() != nullptr; info = info->next()) {
55 }
56 info->SetNext(&new_test);
57 }
58
CreateState(int durations,EventHandler & event_handler,const char * test_name)59 State CreateState(int durations,
60 EventHandler& event_handler,
61 const char* test_name) {
62 return State(durations, event_handler, test_name);
63 }
64 } // namespace internal
65
KeepRunning()66 bool State::KeepRunning() {
67 internal::Timestamp iteration_end = internal::GetCurrentTimestamp();
68 if (current_iteration_ == -1) {
69 ++current_iteration_;
70 event_handler_->TestCaseStart(test_info);
71 iteration_start_ = internal::GetCurrentTimestamp();
72 return true;
73 }
74 int64_t duration = internal::GetDuration(iteration_start_, iteration_end);
75 if (duration > max_) {
76 max_ = duration;
77 }
78 if (duration < min_) {
79 min_ = duration;
80 }
81 total_duration_ += duration;
82 ++current_iteration_;
83 PW_LOG_DEBUG("Iteration number: %d - Duration: %ld",
84 current_iteration_,
85 static_cast<long>(duration));
86 event_handler_->TestCaseIteration({current_iteration_, duration});
87 if (current_iteration_ == test_iterations_) {
88 PW_LOG_DEBUG("Total Duration: %ld Total Iterations: %d",
89 static_cast<long>(total_duration_),
90 test_iterations_);
91 mean_ = total_duration_ / test_iterations_;
92 PW_LOG_DEBUG("Mean: %ld: ", static_cast<long>(mean_));
93 PW_LOG_DEBUG("Minimum: %ld", static_cast<long>(min_));
94 PW_LOG_DEBUG("Maxmimum: %ld", static_cast<long>(max_));
95 event_handler_->TestCaseEnd(test_info,
96 Results{mean_, max_, min_, test_iterations_});
97 return false;
98 }
99 iteration_start_ = internal::GetCurrentTimestamp();
100 return true;
101 }
102
RunAllTests(EventHandler & handler)103 void RunAllTests(EventHandler& handler) {
104 internal::Framework::Get().RegisterEventHandler(handler);
105 internal::Framework::Get().RunAllTests();
106 }
107
108 } // namespace pw::perf_test
109