Skip to content

Commit dea8e28

Browse files
committed
add test isolation and extend coverage in task and performance modules
1 parent a1e3e0e commit dea8e28

File tree

2 files changed

+323
-44
lines changed

2 files changed

+323
-44
lines changed

modules/performance/tests/perf_tests.cpp

Lines changed: 254 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,17 @@ TEST(TaskTest, GetDynamicTypeReturnsCorrectEnum) {
278278
}
279279

280280
TEST(TaskTest, DestructorTerminatesIfWrongOrder) {
281-
DummyTask task;
282-
EXPECT_THROW(task.Run(), std::runtime_error);
281+
{
282+
DummyTask task;
283+
EXPECT_THROW(task.Run(), std::runtime_error);
284+
}
285+
286+
// Create a new task to complete the lifecycle properly
287+
DummyTask task2;
288+
task2.Validation();
289+
task2.PreProcessing();
290+
task2.Run();
291+
task2.PostProcessing();
283292
}
284293

285294
namespace my {
@@ -351,6 +360,249 @@ TEST(PerfTest, GetStringParamNameTest) {
351360
EXPECT_EQ(GetStringParamName(PerfResults::kNone), "none");
352361
}
353362

363+
TEST(PerfTest, DefaultTimerReturnsNegativeOne) {
364+
EXPECT_EQ(DefaultTimer(), -1.0);
365+
}
366+
367+
TEST(PerfTest, PerfAttrDefaultValues) {
368+
PerfAttr attr;
369+
EXPECT_EQ(attr.num_running, 5U);
370+
EXPECT_EQ(attr.current_timer(), -1.0);
371+
}
372+
373+
TEST(PerfTest, PerfResultsDefaultValues) {
374+
PerfResults results;
375+
EXPECT_EQ(results.time_sec, 0.0);
376+
EXPECT_EQ(results.type_of_running, PerfResults::kNone);
377+
EXPECT_EQ(PerfResults::kMaxTime, 10.0);
378+
}
379+
380+
TEST(PerfTest, PerfResultsEnumValues) {
381+
EXPECT_EQ(static_cast<uint8_t>(PerfResults::kPipeline), 0);
382+
EXPECT_EQ(static_cast<uint8_t>(PerfResults::kTaskRun), 1);
383+
EXPECT_EQ(static_cast<uint8_t>(PerfResults::kNone), 2);
384+
}
385+
386+
TEST(PerfTest, PerfConstructorSetsTaskState) {
387+
auto task_ptr = std::make_shared<DummyTask>();
388+
Perf<int, int> perf(task_ptr);
389+
390+
EXPECT_EQ(task_ptr->GetStateOfTesting(), ppc::task::StateOfTesting::kPerf);
391+
392+
// Complete the task lifecycle to avoid destructor issues
393+
task_ptr->Validation();
394+
task_ptr->PreProcessing();
395+
task_ptr->Run();
396+
task_ptr->PostProcessing();
397+
}
398+
399+
TEST(PerfTest, GetPerfResultsReturnsCorrectResults) {
400+
auto task_ptr = std::make_shared<DummyTask>();
401+
Perf<int, int> perf(task_ptr);
402+
403+
// Initially should be default values
404+
auto initial_results = perf.GetPerfResults();
405+
EXPECT_EQ(initial_results.time_sec, 0.0);
406+
EXPECT_EQ(initial_results.type_of_running, PerfResults::kNone);
407+
408+
PerfAttr attr;
409+
double time = 0.0;
410+
attr.current_timer = [&time]() {
411+
double t = time;
412+
time += 0.5;
413+
return t;
414+
};
415+
416+
perf.PipelineRun(attr);
417+
auto pipeline_results = perf.GetPerfResults();
418+
EXPECT_EQ(pipeline_results.type_of_running, PerfResults::kPipeline);
419+
EXPECT_GT(pipeline_results.time_sec, 0.0);
420+
421+
perf.TaskRun(attr);
422+
auto taskrun_results = perf.GetPerfResults();
423+
EXPECT_EQ(taskrun_results.type_of_running, PerfResults::kTaskRun);
424+
EXPECT_GT(taskrun_results.time_sec, 0.0);
425+
}
426+
427+
TEST(PerfTest, CommonRunCalculatesAverageTime) {
428+
auto task_ptr = std::make_shared<DummyTask>();
429+
Perf<int, int> perf(task_ptr);
430+
431+
PerfAttr attr;
432+
int call_count = 0;
433+
attr.num_running = 3;
434+
attr.current_timer = [&call_count]() {
435+
if (call_count == 0) {
436+
call_count++;
437+
return 0.0; // Start time
438+
} else {
439+
return 3.0; // End time after 3 runs
440+
}
441+
};
442+
443+
perf.PipelineRun(attr);
444+
auto results = perf.GetPerfResults();
445+
446+
// Total time should be 3 seconds, average should be 1 second (3.0 - 0.0) / 3
447+
EXPECT_DOUBLE_EQ(results.time_sec, 1.0);
448+
}
449+
450+
TEST(PerfTest, PrintPerfStatisticPipelineOutput) {
451+
auto task_ptr = std::make_shared<DummyTask>();
452+
Perf<int, int> perf(task_ptr);
453+
454+
PerfAttr attr;
455+
double time = 0.0;
456+
attr.current_timer = [&time]() {
457+
double t = time;
458+
time += 0.1;
459+
return t;
460+
};
461+
462+
perf.PipelineRun(attr);
463+
464+
testing::internal::CaptureStdout();
465+
perf.PrintPerfStatistic("test_pipeline");
466+
std::string output = testing::internal::GetCapturedStdout();
467+
468+
EXPECT_NE(output.find("test_pipeline:pipeline:"), std::string::npos);
469+
EXPECT_NE(output.find("0.0200000000"), std::string::npos); // 0.1/5 = 0.02
470+
}
471+
472+
TEST(PerfTest, PrintPerfStatisticTaskRunOutput) {
473+
auto task_ptr = std::make_shared<DummyTask>();
474+
Perf<int, int> perf(task_ptr);
475+
476+
PerfAttr attr;
477+
double time = 0.0;
478+
attr.current_timer = [&time]() {
479+
double t = time;
480+
time += 0.25;
481+
return t;
482+
};
483+
484+
perf.TaskRun(attr);
485+
486+
testing::internal::CaptureStdout();
487+
perf.PrintPerfStatistic("test_taskrun");
488+
std::string output = testing::internal::GetCapturedStdout();
489+
490+
EXPECT_NE(output.find("test_taskrun:task_run:"), std::string::npos);
491+
}
492+
493+
TEST(PerfTest, PrintPerfStatisticThrowsOnExceedingMaxTime) {
494+
auto task_ptr = std::make_shared<DummyTask>();
495+
Perf<int, int> perf(task_ptr);
496+
497+
PerfAttr attr;
498+
double time = 0.0;
499+
attr.current_timer = [&time]() {
500+
double t = time;
501+
time += 55.0; // Exceeds kMaxTime (10.0)
502+
return t;
503+
};
504+
505+
perf.PipelineRun(attr);
506+
507+
testing::internal::CaptureStdout();
508+
try {
509+
perf.PrintPerfStatistic("test_exceed_time");
510+
FAIL() << "Expected std::runtime_error";
511+
} catch (const std::runtime_error& e) {
512+
std::string error_msg = e.what();
513+
EXPECT_NE(error_msg.find("Task execute time need to be"), std::string::npos);
514+
EXPECT_NE(error_msg.find("time < 10"), std::string::npos);
515+
EXPECT_NE(error_msg.find("Original time in secs: 11"), std::string::npos);
516+
}
517+
std::string output = testing::internal::GetCapturedStdout();
518+
EXPECT_NE(output.find("test_exceed_time:pipeline:-1.0000000000"), std::string::npos);
519+
}
520+
521+
TEST(PerfTest, TaskRunCompletesPipelineAfterTiming) {
522+
int validation_count = 0;
523+
int preprocessing_count = 0;
524+
int run_count = 0;
525+
int postprocessing_count = 0;
526+
527+
// Create a custom task that counts method calls
528+
class CountingTask : public Task<int, int> {
529+
public:
530+
int* validation_count_;
531+
int* preprocessing_count_;
532+
int* run_count_;
533+
int* postprocessing_count_;
534+
535+
CountingTask(int* vc, int* pc, int* rc, int* ppc)
536+
: validation_count_(vc), preprocessing_count_(pc), run_count_(rc), postprocessing_count_(ppc) {}
537+
538+
bool ValidationImpl() override {
539+
(*validation_count_)++;
540+
return true;
541+
}
542+
543+
bool PreProcessingImpl() override {
544+
(*preprocessing_count_)++;
545+
return true;
546+
}
547+
548+
bool RunImpl() override {
549+
(*run_count_)++;
550+
return true;
551+
}
552+
553+
bool PostProcessingImpl() override {
554+
(*postprocessing_count_)++;
555+
return true;
556+
}
557+
};
558+
559+
auto counting_task = std::make_shared<CountingTask>(&validation_count, &preprocessing_count, &run_count, &postprocessing_count);
560+
Perf<int, int> counting_perf(counting_task);
561+
562+
PerfAttr attr;
563+
attr.num_running = 1;
564+
565+
counting_perf.TaskRun(attr);
566+
567+
// TaskRun should call:
568+
// 1. Validation + PreProcessing + Run (num_running times) + PostProcessing
569+
// 2. Validation + PreProcessing + Run + PostProcessing (one additional complete cycle)
570+
EXPECT_EQ(validation_count, 2); // Called twice
571+
EXPECT_EQ(preprocessing_count, 2); // Called twice
572+
EXPECT_EQ(run_count, 2); // Called twice (once in timing, once in final cycle)
573+
EXPECT_EQ(postprocessing_count, 2); // Called twice
574+
}
575+
576+
namespace test_namespace {
577+
struct TestType {};
578+
}
579+
580+
TEST(PerfTest, TemplateInstantiationWithDifferentTypes) {
581+
// Test that Perf template can be instantiated with different types
582+
auto int_task = std::make_shared<DummyTask>();
583+
Perf<int, int> int_perf(int_task);
584+
585+
auto vector_task = std::make_shared<ppc::test::TestPerfTask<std::vector<int>, int>>(std::vector<int>{1, 2, 3});
586+
Perf<std::vector<int>, int> vector_perf(vector_task);
587+
588+
PerfAttr attr;
589+
590+
EXPECT_NO_THROW(int_perf.PipelineRun(attr));
591+
EXPECT_NO_THROW(vector_perf.PipelineRun(attr));
592+
593+
EXPECT_EQ(int_perf.GetPerfResults().type_of_running, PerfResults::kPipeline);
594+
EXPECT_EQ(vector_perf.GetPerfResults().type_of_running, PerfResults::kPipeline);
595+
}
596+
597+
TEST(PerfTest, PerfAttrCustomValues) {
598+
PerfAttr attr;
599+
attr.num_running = 10;
600+
attr.current_timer = []() { return 42.0; };
601+
602+
EXPECT_EQ(attr.num_running, 10U);
603+
EXPECT_EQ(attr.current_timer(), 42.0);
604+
}
605+
354606
TEST(TaskTest, Destructor_InvalidPipelineOrderTerminates_PartialPipeline) {
355607
{
356608
struct BadTask : Task<int, int> {

0 commit comments

Comments
 (0)