326 auto perfLog{fixture.
perfLog(withFile)};
333 auto labels = std::ranges::to<std::vector>(
kMethodNames);
340 ids.
reserve(labels.size() * 2);
353 for (
int labelIndex = 0; labelIndex < labels.size(); ++labelIndex)
355 for (
int idIndex = 0; idIndex < 2; ++idIndex)
358 perfLog->rpcStart(labels[labelIndex], ids[(labelIndex * 2) + idIndex]);
363 json::Value const countersJson{perfLog->countersJson()[jss::rpc]};
364 BEAST_EXPECT(countersJson.
size() == labels.size() + 1);
365 for (
auto& label : labels)
369 BEAST_EXPECT(counter[jss::duration_us] ==
"0");
370 BEAST_EXPECT(counter[jss::errored] ==
"0");
371 BEAST_EXPECT(counter[jss::finished] ==
"0");
372 BEAST_EXPECT(counter[jss::started] ==
"2");
375 json::Value const& total{countersJson[jss::total]};
376 BEAST_EXPECT(total[jss::duration_us] ==
"0");
377 BEAST_EXPECT(total[jss::errored] ==
"0");
378 BEAST_EXPECT(total[jss::finished] ==
"0");
386 BEAST_EXPECT(currents.
size() == labels.size() * 2);
389 for (
int i = 0; i < currents.
size(); ++i)
391 BEAST_EXPECT(currents[i].name == labels[i / 2].view());
392 BEAST_EXPECT(prevDur > currents[i].dur);
393 prevDur = currents[i].dur;
400 for (
int labelIndex = labels.size() - 1; labelIndex > 0; --labelIndex)
403 perfLog->rpcFinish(labels[labelIndex], ids[(labelIndex * 2) + 1]);
405 perfLog->rpcError(labels[labelIndex], ids[(labelIndex * 2) + 0]);
407 perfLog->rpcFinish(labels[0], ids[0 + 1]);
410 auto validateFinalCounters = [
this, &labels](
json::Value const& countersJson) {
412 json::Value const& jobQueue = countersJson[jss::job_queue];
414 BEAST_EXPECT(jobQueue.
size() == 0);
418 BEAST_EXPECT(
rpc.size() == labels.size() + 1);
426 BEAST_EXPECT(first[jss::duration_us] !=
"0");
427 BEAST_EXPECT(first[jss::errored] ==
"0");
428 BEAST_EXPECT(first[jss::finished] ==
"1");
429 BEAST_EXPECT(first[jss::started] ==
"2");
434 for (
int i = 1; i < labels.size(); ++i)
438 BEAST_EXPECT(dur != 0 && dur < prevDur);
440 BEAST_EXPECT(counter[jss::errored] ==
"1");
441 BEAST_EXPECT(counter[jss::finished] ==
"1");
442 BEAST_EXPECT(counter[jss::started] ==
"2");
447 BEAST_EXPECT(total[jss::duration_us] !=
"0");
448 BEAST_EXPECT(
jsonToUInt64(total[jss::errored]) == labels.size() - 1);
449 BEAST_EXPECT(
jsonToUInt64(total[jss::finished]) == labels.size());
450 BEAST_EXPECT(
jsonToUInt64(total[jss::started]) == labels.size() * 2);
453 auto validateFinalCurrent = [
this, &labels](
json::Value const& currentJson) {
455 json::Value const& jobQueue = currentJson[jss::jobs];
456 BEAST_EXPECT(jobQueue.
isArray());
457 BEAST_EXPECT(jobQueue.
size() == 0);
460 json::Value const& methods = currentJson[jss::methods];
461 BEAST_EXPECT(methods.
size() == 1);
462 BEAST_EXPECT(methods.
isArray());
465 BEAST_EXPECT(only.
size() == 2);
467 BEAST_EXPECT(only[jss::duration_us] !=
"0");
468 BEAST_EXPECT(only[jss::method] ==
std::string{labels[0]});
472 validateFinalCounters(perfLog->countersJson());
473 validateFinalCurrent(perfLog->currentJson());
481 auto const fullPath = fixture.
logFile();
485 BEAST_EXPECT(!
exists(fullPath));
499 lastLine = std::move(line);
511 validateFinalCounters(parsedLastLine[jss::counters]);
512 validateFinalCurrent(parsedLastLine[jss::current_activities]);
524 auto perfLog{fixture.
perfLog(withFile)};
543 for (
auto const& job : jobTypes)
552 for (
int i = 0; i < jobs.
size(); ++i)
554 perfLog->jobQueue(jobs[i].type);
555 json::Value const jqCounters{perfLog->countersJson()[jss::job_queue]};
557 BEAST_EXPECT(jqCounters.
size() == i + 2);
558 for (
int j = 0; j <= i; ++j)
562 json::Value const& counter{jqCounters[jobs[j].typeName]};
563 BEAST_EXPECT(counter.
size() == 5);
564 BEAST_EXPECT(counter[jss::queued] ==
"1");
565 BEAST_EXPECT(counter[jss::started] ==
"0");
566 BEAST_EXPECT(counter[jss::finished] ==
"0");
567 BEAST_EXPECT(counter[jss::queued_duration_us] ==
"0");
568 BEAST_EXPECT(counter[jss::running_duration_us] ==
"0");
573 BEAST_EXPECT(total.
size() == 5);
574 BEAST_EXPECT(
jsonToUInt64(total[jss::queued]) == i + 1);
575 BEAST_EXPECT(total[jss::started] ==
"0");
576 BEAST_EXPECT(total[jss::finished] ==
"0");
577 BEAST_EXPECT(total[jss::queued_duration_us] ==
"0");
578 BEAST_EXPECT(total[jss::running_duration_us] ==
"0");
584 BEAST_EXPECT(current.
size() == 2);
585 BEAST_EXPECT(current.
isMember(jss::jobs));
586 BEAST_EXPECT(current[jss::jobs].
size() == 0);
587 BEAST_EXPECT(current.
isMember(jss::methods));
588 BEAST_EXPECT(current[jss::methods].
size() == 0);
594 perfLog->resizeJobs(jobs.
size() * 2);
600 for (
int i = 0; i < jobs.
size(); ++i)
606 json::Value const jqCounters{perfLog->countersJson()[jss::job_queue]};
607 for (
int j = 0; j < jobs.
size(); ++j)
609 json::Value const& counter{jqCounters[jobs[j].typeName]};
613 BEAST_EXPECT(counter[jss::started] ==
"2");
614 BEAST_EXPECT(queuedDurUs == j + 1);
618 BEAST_EXPECT(counter[jss::started] ==
"1");
619 BEAST_EXPECT(queuedDurUs == j + 1);
623 BEAST_EXPECT(counter[jss::started] ==
"0");
624 BEAST_EXPECT(queuedDurUs == 0);
627 BEAST_EXPECT(counter[jss::queued] ==
"1");
628 BEAST_EXPECT(counter[jss::finished] ==
"0");
629 BEAST_EXPECT(counter[jss::running_duration_us] ==
"0");
635 BEAST_EXPECT(
jsonToUInt64(total[jss::started]) == (i * 2) + 1);
636 BEAST_EXPECT(total[jss::finished] ==
"0");
640 jsonToUInt64(total[jss::queued_duration_us]) == (((i * i) + (3 * i) + 2) / 2));
641 BEAST_EXPECT(total[jss::running_duration_us] ==
"0");
651 BEAST_EXPECT(currents.size() == (i + 1) * 2);
654 for (
int j = 0; j <= i; ++j)
656 BEAST_EXPECT(currents[j * 2].name == jobs[j].typeName);
657 BEAST_EXPECT(prevDur > currents[j * 2].dur);
658 prevDur = currents[j * 2].dur;
660 BEAST_EXPECT(currents[(j * 2) + 1].name == jobs[j].typeName);
661 BEAST_EXPECT(prevDur > currents[(j * 2) + 1].dur);
662 prevDur = currents[(j * 2) + 1].dur;
667 for (
int i = jobs.
size() - 1; i >= 0; --i)
671 int const finished = ((jobs.
size() - i) * 2) - 1;
672 perfLog->jobFinish(jobs[i].type,
microseconds(finished), (i * 2) + 1);
675 json::Value const jqCounters{perfLog->countersJson()[jss::job_queue]};
676 for (
int j = 0; j < jobs.
size(); ++j)
678 json::Value const& counter{jqCounters[jobs[j].typeName]};
682 BEAST_EXPECT(counter[jss::finished] ==
"0");
683 BEAST_EXPECT(runningDurUs == 0);
687 BEAST_EXPECT(counter[jss::finished] ==
"1");
688 BEAST_EXPECT(runningDurUs == ((jobs.
size() - j) * 2) - 1);
692 BEAST_EXPECT(counter[jss::finished] ==
"2");
693 BEAST_EXPECT(runningDurUs == ((jobs.
size() - j) * 4) - 1);
697 BEAST_EXPECT(queuedDurUs == j + 1);
698 BEAST_EXPECT(counter[jss::queued] ==
"1");
699 BEAST_EXPECT(counter[jss::started] ==
"2");
706 BEAST_EXPECT(
jsonToUInt64(total[jss::finished]) == finished);
710 int const queuedDur = ((jobs.
size() * (jobs.
size() + 1)) / 2);
711 BEAST_EXPECT(
jsonToUInt64(total[jss::queued_duration_us]) == queuedDur);
714 int const runningDur = ((finished * (finished + 1)) / 2);
715 BEAST_EXPECT(
jsonToUInt64(total[jss::running_duration_us]) == runningDur);
718 perfLog->jobFinish(jobs[i].type,
microseconds(finished + 1), (i * 2));
724 BEAST_EXPECT(currents.
size() == i * 2);
727 for (
int j = 0; j < i; ++j)
729 BEAST_EXPECT(currents[j * 2].name == jobs[j].typeName);
730 BEAST_EXPECT(prevDur > currents[j * 2].dur);
731 prevDur = currents[j * 2].dur;
733 BEAST_EXPECT(currents[(j * 2) + 1].name == jobs[j].typeName);
734 BEAST_EXPECT(prevDur > currents[(j * 2) + 1].dur);
735 prevDur = currents[(j * 2) + 1].dur;
740 auto validateFinalCounters = [
this, &jobs](
json::Value const& countersJson) {
743 BEAST_EXPECT(
rpc.isObject());
744 BEAST_EXPECT(
rpc.size() == 0);
747 json::Value const& jobQueue = countersJson[jss::job_queue];
748 for (
int i = jobs.
size() - 1; i >= 0; --i)
750 json::Value const& counter{jobQueue[jobs[i].typeName]};
752 BEAST_EXPECT(runningDurUs == ((jobs.
size() - i) * 4) - 1);
755 BEAST_EXPECT(queuedDurUs == i + 1);
757 BEAST_EXPECT(counter[jss::queued] ==
"1");
758 BEAST_EXPECT(counter[jss::started] ==
"2");
759 BEAST_EXPECT(counter[jss::finished] ==
"2");
764 int const finished = jobs.
size() * 2;
766 BEAST_EXPECT(
jsonToUInt64(total[jss::started]) == finished);
767 BEAST_EXPECT(
jsonToUInt64(total[jss::finished]) == finished);
771 int const queuedDur = ((jobs.
size() * (jobs.
size() + 1)) / 2);
772 BEAST_EXPECT(
jsonToUInt64(total[jss::queued_duration_us]) == queuedDur);
775 int const runningDur = ((finished * (finished + 1)) / 2);
776 BEAST_EXPECT(
jsonToUInt64(total[jss::running_duration_us]) == runningDur);
779 auto validateFinalCurrent = [
this](
json::Value const& currentJson) {
783 BEAST_EXPECT(j.
size() == 0);
786 json::Value const& methods = currentJson[jss::methods];
787 BEAST_EXPECT(methods.
size() == 0);
788 BEAST_EXPECT(methods.
isArray());
792 validateFinalCounters(perfLog->countersJson());
793 validateFinalCurrent(perfLog->currentJson());
802 auto const fullPath = fixture.
logFile();
806 BEAST_EXPECT(!
exists(fullPath));
820 lastLine = std::move(line);
832 validateFinalCounters(parsedLastLine[jss::counters]);
833 validateFinalCurrent(parsedLastLine[jss::current_activities]);
847 auto perfLog{fixture.
perfLog(withFile)};
857 auto iter{jobTypes.begin()};
860 jobType = iter->second.type();
861 jobTypeName = iter->second.name();
865 perfLog->resizeJobs(1);
868 auto verifyCounters = [
this, jobTypeName](
874 BEAST_EXPECT(countersJson.
isObject());
875 BEAST_EXPECT(countersJson.
size() == 2);
877 BEAST_EXPECT(countersJson.
isMember(jss::rpc));
878 BEAST_EXPECT(countersJson[jss::rpc].isObject());
879 BEAST_EXPECT(countersJson[jss::rpc].
size() == 0);
881 BEAST_EXPECT(countersJson.
isMember(jss::job_queue));
882 BEAST_EXPECT(countersJson[jss::job_queue].isObject());
883 BEAST_EXPECT(countersJson[jss::job_queue].
size() == 1);
885 json::Value const& job{countersJson[jss::job_queue][jobTypeName]};
889 BEAST_EXPECT(
jsonToUInt64(job[jss::started]) == started);
890 BEAST_EXPECT(
jsonToUInt64(job[jss::finished]) == finished);
892 BEAST_EXPECT(
jsonToUInt64(job[jss::queued_duration_us]) == queuedUs);
893 BEAST_EXPECT(
jsonToUInt64(job[jss::running_duration_us]) == runningUs);
898 auto verifyEmptyCurrent = [
this](
json::Value const& currentJson) {
899 BEAST_EXPECT(currentJson.isObject());
900 BEAST_EXPECT(currentJson.size() == 2);
902 BEAST_EXPECT(currentJson.isMember(jss::jobs));
903 BEAST_EXPECT(currentJson[jss::jobs].isArray());
904 BEAST_EXPECT(currentJson[jss::jobs].
size() == 0);
906 BEAST_EXPECT(currentJson.isMember(jss::methods));
907 BEAST_EXPECT(currentJson[jss::methods].isArray());
908 BEAST_EXPECT(currentJson[jss::methods].
size() == 0);
914 verifyCounters(perfLog->countersJson(), 1, 0, 11, 0);
915 verifyEmptyCurrent(perfLog->currentJson());
920 verifyCounters(perfLog->countersJson(), 2, 0, 24, 0);
921 verifyEmptyCurrent(perfLog->currentJson());
926 verifyCounters(perfLog->countersJson(), 2, 1, 24, 17);
927 verifyEmptyCurrent(perfLog->currentJson());
932 verifyCounters(perfLog->countersJson(), 2, 2, 24, 36);
933 verifyEmptyCurrent(perfLog->currentJson());
942 auto const fullPath = fixture.
logFile();
946 BEAST_EXPECT(!
exists(fullPath));
960 lastLine = std::move(line);
972 verifyCounters(parsedLastLine[jss::counters], 2, 2, 24, 36);
973 verifyEmptyCurrent(parsedLastLine[jss::current_activities]);