Skip to content

Commit 8ee6414

Browse files
authored
Add env-based time limits (#525)
- read optional env vars `PPC_TASK_MAX_TIME` and `PPC_PERF_MAX_TIME` - use those env vars when checking execution time - document new environment variables - add regression tests for the env vars
1 parent 1d7e7f8 commit 8ee6414

File tree

8 files changed

+91
-5
lines changed

8 files changed

+91
-5
lines changed

docs/user_guide/environment_variables.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ The following environment variables can be used to configure the project's runti
1414

1515
- ``PPC_IGNORE_TEST_TIME_LIMIT``: Specifies that test time limits are ignored. Used by ``scripts/run_tests.py`` to disable time limit enforcement.
1616
Default: ``0``
17+
- ``PPC_TASK_MAX_TIME``: Maximum allowed execution time in seconds for functional tests.
18+
Default: ``1.0``
19+
- ``PPC_PERF_MAX_TIME``: Maximum allowed execution time in seconds for performance tests.
20+
Default: ``10.0``

modules/performance/include/performance.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <string>
1111

1212
#include "task/include/task.hpp"
13+
#include "util/include/util.hpp"
1314

1415
namespace ppc::performance {
1516

@@ -78,14 +79,15 @@ class Perf {
7879
}
7980

8081
auto time_secs = perf_results_.time_sec;
82+
const auto max_time = ppc::util::GetPerfMaxTime();
8183
std::stringstream perf_res_str;
82-
if (time_secs < PerfResults::kMaxTime) {
84+
if (time_secs < max_time) {
8385
perf_res_str << std::fixed << std::setprecision(10) << time_secs;
8486
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';
8587
} else {
8688
std::stringstream err_msg;
8789
err_msg << '\n' << "Task execute time need to be: ";
88-
err_msg << "time < " << PerfResults::kMaxTime << " secs." << '\n';
90+
err_msg << "time < " << max_time << " secs." << '\n';
8991
err_msg << "Original time in secs: " << time_secs << '\n';
9092
perf_res_str << std::fixed << std::setprecision(10) << -1.0;
9193
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';

modules/performance/tests/perf_tests.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cstdint>
55
#include <filesystem>
66
#include <fstream>
7+
#include <libenvpp/detail/environment.hpp>
78
#include <memory>
89
#include <ostream>
910
#include <stdexcept>
@@ -107,6 +108,23 @@ TEST(perf_tests, check_perf_pipeline_uint8_t_slow_test) {
107108
ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_pipeline_uint8_t_slow_test"));
108109
}
109110

111+
TEST(perf_tests, slow_perf_respects_env_override) {
112+
env::detail::set_scoped_environment_variable scoped("PPC_PERF_MAX_TIME", "12");
113+
std::vector<uint8_t> in(128, 1);
114+
auto test_task = std::make_shared<ppc::test::FakePerfTask<std::vector<uint8_t>, uint8_t>>(in);
115+
Perf<std::vector<uint8_t>, uint8_t> perf_analyzer(test_task);
116+
PerfAttr perf_attr;
117+
perf_attr.num_running = 1;
118+
const auto t0 = std::chrono::high_resolution_clock::now();
119+
perf_attr.current_timer = [&] {
120+
auto current_time_point = std::chrono::high_resolution_clock::now();
121+
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(current_time_point - t0).count();
122+
return static_cast<double>(duration) * 1e-9;
123+
};
124+
perf_analyzer.PipelineRun(perf_attr);
125+
EXPECT_NO_THROW(perf_analyzer.PrintPerfStatistic("slow_perf_respects_env_override"));
126+
}
127+
110128
TEST(perf_tests, check_perf_task_exception) {
111129
std::vector<uint32_t> in(2000, 1);
112130

modules/task/include/task.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,13 @@ class Task {
215215
.count();
216216
auto diff = static_cast<double>(duration) * 1e-9;
217217

218+
const auto max_time = ppc::util::GetTaskMaxTime();
218219
std::stringstream err_msg;
219-
if (diff < kMaxTestTime) {
220+
if (diff < max_time) {
220221
err_msg << "Test time:" << std::fixed << std::setprecision(10) << diff << '\n';
221222
} else {
222223
err_msg << "\nTask execute time need to be: ";
223-
err_msg << "time < " << kMaxTestTime << " secs.\n";
224+
err_msg << "time < " << max_time << " secs.\n";
224225
err_msg << "Original time in secs: " << diff << '\n';
225226
throw std::runtime_error(err_msg.str().c_str());
226227
}
@@ -249,7 +250,6 @@ class Task {
249250
StateOfTesting state_of_testing_ = kFunc;
250251
TypeOfTask type_of_task_ = kUnknown;
251252
StatusOfTask status_of_task_ = kEnabled;
252-
static constexpr double kMaxTestTime = 1.0;
253253
std::chrono::high_resolution_clock::time_point tmp_time_point_;
254254
enum class PipelineStage : uint8_t {
255255
kNone,

modules/task/tests/task_tests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <exception>
77
#include <filesystem>
88
#include <fstream>
9+
#include <libenvpp/env.hpp>
910
#include <memory>
1011
#include <stdexcept>
1112
#include <string>
@@ -88,6 +89,16 @@ TEST(task_tests, check_int32_t_slow) {
8889
ASSERT_ANY_THROW(test_task.PostProcessing());
8990
}
9091

92+
TEST(task_tests, slow_task_respects_env_override) {
93+
env::detail::set_scoped_environment_variable scoped("PPC_TASK_MAX_TIME", "3");
94+
std::vector<int32_t> in(20, 1);
95+
ppc::test::FakeSlowTask<std::vector<int32_t>, int32_t> test_task(in);
96+
ASSERT_EQ(test_task.Validation(), true);
97+
test_task.PreProcessing();
98+
test_task.Run();
99+
EXPECT_NO_THROW(test_task.PostProcessing());
100+
}
101+
91102
TEST(task_tests, check_validate_func) {
92103
std::vector<int32_t> in;
93104
ppc::test::TestTask<std::vector<int32_t>, int32_t> test_task(in);

modules/util/include/util.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ enum GTestParamIndex : uint8_t { kTaskGetter, kNameTest, kTestParams };
5252

5353
std::string GetAbsoluteTaskPath(const std::string& id_path, const std::string& relative_path);
5454
int GetNumThreads();
55+
double GetTaskMaxTime();
56+
double GetPerfMaxTime();
5557

5658
template <typename T>
5759
std::string GetNamespace() {

modules/util/src/util.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ int ppc::util::GetNumThreads() {
2828
return 1;
2929
}
3030

31+
double ppc::util::GetTaskMaxTime() {
32+
const auto val = env::get<double>("PPC_TASK_MAX_TIME");
33+
if (val.has_value()) {
34+
return val.value();
35+
}
36+
return 1.0;
37+
}
38+
39+
double ppc::util::GetPerfMaxTime() {
40+
const auto val = env::get<double>("PPC_PERF_MAX_TIME");
41+
if (val.has_value()) {
42+
return val.value();
43+
}
44+
return 10.0;
45+
}
46+
3147
// List of environment variables that signal the application is running under
3248
// an MPI launcher. The array size must match the number of entries to avoid
3349
// looking up empty environment variable names.

modules/util/tests/util.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <gtest/gtest.h>
44

5+
#include <libenvpp/detail/environment.hpp>
56
#include <libenvpp/detail/get.hpp>
67
#include <string>
78

@@ -75,3 +76,35 @@ TEST(GetNamespaceTest, NoTerminatorCharactersInPrettyFunction) {
7576
std::string k_ns = ppc::util::GetNamespace<crazy::VeryLongTypeNameWithOnlyLettersAndUnderscores>();
7677
EXPECT_EQ(k_ns, "crazy");
7778
}
79+
80+
TEST(GetTaskMaxTime, ReturnsDefaultWhenUnset) {
81+
const auto old = env::get<double>("PPC_TASK_MAX_TIME");
82+
if (old.has_value()) {
83+
env::detail::delete_environment_variable("PPC_TASK_MAX_TIME");
84+
}
85+
EXPECT_DOUBLE_EQ(ppc::util::GetTaskMaxTime(), 1.0);
86+
if (old.has_value()) {
87+
env::detail::set_environment_variable("PPC_TASK_MAX_TIME", std::to_string(*old));
88+
}
89+
}
90+
91+
TEST(GetTaskMaxTime, ReadsFromEnvironment) {
92+
env::detail::set_scoped_environment_variable scoped("PPC_TASK_MAX_TIME", "2.5");
93+
EXPECT_DOUBLE_EQ(ppc::util::GetTaskMaxTime(), 2.5);
94+
}
95+
96+
TEST(GetPerfMaxTime, ReturnsDefaultWhenUnset) {
97+
const auto old = env::get<double>("PPC_PERF_MAX_TIME");
98+
if (old.has_value()) {
99+
env::detail::delete_environment_variable("PPC_PERF_MAX_TIME");
100+
}
101+
EXPECT_DOUBLE_EQ(ppc::util::GetPerfMaxTime(), 10.0);
102+
if (old.has_value()) {
103+
env::detail::set_environment_variable("PPC_PERF_MAX_TIME", std::to_string(*old));
104+
}
105+
}
106+
107+
TEST(GetPerfMaxTime, ReadsFromEnvironment) {
108+
env::detail::set_scoped_environment_variable scoped("PPC_PERF_MAX_TIME", "12.5");
109+
EXPECT_DOUBLE_EQ(ppc::util::GetPerfMaxTime(), 12.5);
110+
}

0 commit comments

Comments
 (0)