@@ -278,8 +278,17 @@ TEST(TaskTest, GetDynamicTypeReturnsCorrectEnum) {
278
278
}
279
279
280
280
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 ();
283
292
}
284
293
285
294
namespace my {
@@ -351,6 +360,249 @@ TEST(PerfTest, GetStringParamNameTest) {
351
360
EXPECT_EQ (GetStringParamName (PerfResults::kNone ), " none" );
352
361
}
353
362
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
+
354
606
TEST (TaskTest, Destructor_InvalidPipelineOrderTerminates_PartialPipeline) {
355
607
{
356
608
struct BadTask : Task<int , int > {
0 commit comments