170 using namespace boost::filesystem;
175 BEAST_EXPECT(!exists(fixture.logFile()));
179 BEAST_EXPECT(fixture.stopSignaled ==
false);
180 BEAST_EXPECT(exists(fixture.logFile()));
187 if (!BEAST_EXPECT(!exists(fixture.logDir())))
193 nastyFile.
open(fixture.logDir().c_str(), std::ios::out | std::ios::app);
194 if (!BEAST_EXPECT(nastyFile))
201 BEAST_EXPECT(fixture.stopSignaled ==
false);
203 BEAST_EXPECT(fixture.stopSignaled ==
true);
213 remove(fixture.logDir());
220 if (!BEAST_EXPECT(!exists(fixture.logDir())))
225 boost::system::error_code ec;
226 boost::filesystem::create_directories(fixture.logDir(), ec);
227 if (!BEAST_EXPECT(!ec))
230 auto fileWriteable = [](boost::filesystem::path
const& p) ->
bool {
234 if (!BEAST_EXPECT(fileWriteable(fixture.logFile())))
237 boost::filesystem::permissions(
238 fixture.logFile(), perms::remove_perms | perms::owner_write | perms::others_write | perms::group_write);
242 if (fileWriteable(fixture.logFile()))
244 log <<
"Unable to write protect file. Test skipped." <<
std::endl;
250 BEAST_EXPECT(fixture.stopSignaled ==
false);
252 BEAST_EXPECT(fixture.stopSignaled ==
true);
262 boost::filesystem::permissions(
263 fixture.logFile(), perms::add_perms | perms::owner_write | perms::others_write | perms::group_write);
273 auto perfLog{fixture.perfLog(withFile)};
298 for (
int labelIndex = 0; labelIndex < labels.
size(); ++labelIndex)
300 for (
int idIndex = 0; idIndex < 2; ++idIndex)
303 perfLog->rpcStart(labels[labelIndex], ids[(labelIndex * 2) + idIndex]);
308 Json::Value const countersJson{perfLog->countersJson()[jss::rpc]};
309 BEAST_EXPECT(countersJson.size() == labels.
size() + 1);
310 for (
auto& label : labels)
314 BEAST_EXPECT(counter[jss::duration_us] ==
"0");
315 BEAST_EXPECT(counter[jss::errored] ==
"0");
316 BEAST_EXPECT(counter[jss::finished] ==
"0");
317 BEAST_EXPECT(counter[jss::started] ==
"2");
320 Json::Value const& total{countersJson[jss::total]};
321 BEAST_EXPECT(total[jss::duration_us] ==
"0");
322 BEAST_EXPECT(total[jss::errored] ==
"0");
323 BEAST_EXPECT(total[jss::finished] ==
"0");
331 BEAST_EXPECT(currents.size() == labels.
size() * 2);
334 for (
int i = 0; i < currents.size(); ++i)
336 BEAST_EXPECT(currents[i].name == labels[i / 2]);
337 BEAST_EXPECT(prevDur > currents[i].dur);
338 prevDur = currents[i].dur;
345 for (
int labelIndex = labels.
size() - 1; labelIndex > 0; --labelIndex)
348 perfLog->rpcFinish(labels[labelIndex], ids[(labelIndex * 2) + 1]);
350 perfLog->rpcError(labels[labelIndex], ids[(labelIndex * 2) + 0]);
352 perfLog->rpcFinish(labels[0], ids[0 + 1]);
355 auto validateFinalCounters = [
this, &labels](
Json::Value const& countersJson) {
357 Json::Value const& jobQueue = countersJson[jss::job_queue];
359 BEAST_EXPECT(jobQueue.
size() == 0);
363 BEAST_EXPECT(rpc.
size() == labels.
size() + 1);
371 BEAST_EXPECT(first[jss::duration_us] !=
"0");
372 BEAST_EXPECT(first[jss::errored] ==
"0");
373 BEAST_EXPECT(first[jss::finished] ==
"1");
374 BEAST_EXPECT(first[jss::started] ==
"2");
379 for (
int i = 1; i < labels.
size(); ++i)
383 BEAST_EXPECT(dur != 0 && dur < prevDur);
385 BEAST_EXPECT(counter[jss::errored] ==
"1");
386 BEAST_EXPECT(counter[jss::finished] ==
"1");
387 BEAST_EXPECT(counter[jss::started] ==
"2");
392 BEAST_EXPECT(total[jss::duration_us] !=
"0");
398 auto validateFinalCurrent = [
this, &labels](
Json::Value const& currentJson) {
400 Json::Value const& job_queue = currentJson[jss::jobs];
401 BEAST_EXPECT(job_queue.
isArray());
402 BEAST_EXPECT(job_queue.
size() == 0);
405 Json::Value const& methods = currentJson[jss::methods];
406 BEAST_EXPECT(methods.
size() == 1);
407 BEAST_EXPECT(methods.
isArray());
410 BEAST_EXPECT(only.
size() == 2);
412 BEAST_EXPECT(only[jss::duration_us] !=
"0");
413 BEAST_EXPECT(only[jss::method] == labels[0]);
417 validateFinalCounters(perfLog->countersJson());
418 validateFinalCurrent(perfLog->currentJson());
426 auto const fullPath = fixture.logFile();
430 BEAST_EXPECT(!exists(fullPath));
444 lastLine = std::move(line);
454 validateFinalCounters(parsedLastLine[jss::counters]);
455 validateFinalCurrent(parsedLastLine[jss::current_activities]);
467 auto perfLog{fixture.perfLog(withFile)};
486 for (
auto const& job : jobTypes)
495 for (
int i = 0; i < jobs.
size(); ++i)
497 perfLog->jobQueue(jobs[i].type);
498 Json::Value const jq_counters{perfLog->countersJson()[jss::job_queue]};
500 BEAST_EXPECT(jq_counters.size() == i + 2);
501 for (
int j = 0; j <= i; ++j)
505 Json::Value const& counter{jq_counters[jobs[j].typeName]};
506 BEAST_EXPECT(counter.size() == 5);
507 BEAST_EXPECT(counter[jss::queued] ==
"1");
508 BEAST_EXPECT(counter[jss::started] ==
"0");
509 BEAST_EXPECT(counter[jss::finished] ==
"0");
510 BEAST_EXPECT(counter[jss::queued_duration_us] ==
"0");
511 BEAST_EXPECT(counter[jss::running_duration_us] ==
"0");
516 BEAST_EXPECT(total.size() == 5);
517 BEAST_EXPECT(
jsonToUint64(total[jss::queued]) == i + 1);
518 BEAST_EXPECT(total[jss::started] ==
"0");
519 BEAST_EXPECT(total[jss::finished] ==
"0");
520 BEAST_EXPECT(total[jss::queued_duration_us] ==
"0");
521 BEAST_EXPECT(total[jss::running_duration_us] ==
"0");
527 BEAST_EXPECT(
current.size() == 2);
528 BEAST_EXPECT(
current.isMember(jss::jobs));
529 BEAST_EXPECT(
current[jss::jobs].size() == 0);
530 BEAST_EXPECT(
current.isMember(jss::methods));
531 BEAST_EXPECT(
current[jss::methods].size() == 0);
537 perfLog->resizeJobs(jobs.
size() * 2);
543 for (
int i = 0; i < jobs.
size(); ++i)
545 perfLog->jobStart(jobs[i].type,
microseconds{i + 1}, steady_clock::now(), i * 2);
549 Json::Value const jq_counters{perfLog->countersJson()[jss::job_queue]};
550 for (
int j = 0; j < jobs.
size(); ++j)
552 Json::Value const& counter{jq_counters[jobs[j].typeName]};
556 BEAST_EXPECT(counter[jss::started] ==
"2");
557 BEAST_EXPECT(queued_dur_us == j + 1);
561 BEAST_EXPECT(counter[jss::started] ==
"1");
562 BEAST_EXPECT(queued_dur_us == j + 1);
566 BEAST_EXPECT(counter[jss::started] ==
"0");
567 BEAST_EXPECT(queued_dur_us == 0);
570 BEAST_EXPECT(counter[jss::queued] ==
"1");
571 BEAST_EXPECT(counter[jss::finished] ==
"0");
572 BEAST_EXPECT(counter[jss::running_duration_us] ==
"0");
578 BEAST_EXPECT(
jsonToUint64(total[jss::started]) == (i * 2) + 1);
579 BEAST_EXPECT(total[jss::finished] ==
"0");
582 BEAST_EXPECT(
jsonToUint64(total[jss::queued_duration_us]) == (((i * i) + 3 * i + 2) / 2));
583 BEAST_EXPECT(total[jss::running_duration_us] ==
"0");
586 perfLog->jobStart(jobs[i].type,
microseconds{0}, steady_clock::now(), (i * 2) + 1);
593 BEAST_EXPECT(currents.size() == (i + 1) * 2);
596 for (
int j = 0; j <= i; ++j)
598 BEAST_EXPECT(currents[j * 2].name == jobs[j].typeName);
599 BEAST_EXPECT(prevDur > currents[j * 2].dur);
600 prevDur = currents[j * 2].dur;
602 BEAST_EXPECT(currents[(j * 2) + 1].name == jobs[j].typeName);
603 BEAST_EXPECT(prevDur > currents[(j * 2) + 1].dur);
604 prevDur = currents[(j * 2) + 1].dur;
609 for (
int i = jobs.
size() - 1; i >= 0; --i)
613 int const finished = ((jobs.
size() - i) * 2) - 1;
614 perfLog->jobFinish(jobs[i].type,
microseconds(finished), (i * 2) + 1);
617 Json::Value const jq_counters{perfLog->countersJson()[jss::job_queue]};
618 for (
int j = 0; j < jobs.
size(); ++j)
620 Json::Value const& counter{jq_counters[jobs[j].typeName]};
624 BEAST_EXPECT(counter[jss::finished] ==
"0");
625 BEAST_EXPECT(running_dur_us == 0);
629 BEAST_EXPECT(counter[jss::finished] ==
"1");
630 BEAST_EXPECT(running_dur_us == ((jobs.
size() - j) * 2) - 1);
634 BEAST_EXPECT(counter[jss::finished] ==
"2");
635 BEAST_EXPECT(running_dur_us == ((jobs.
size() - j) * 4) - 1);
639 BEAST_EXPECT(queued_dur_us == j + 1);
640 BEAST_EXPECT(counter[jss::queued] ==
"1");
641 BEAST_EXPECT(counter[jss::started] ==
"2");
648 BEAST_EXPECT(
jsonToUint64(total[jss::finished]) == finished);
652 int const queuedDur = ((jobs.
size() * (jobs.
size() + 1)) / 2);
653 BEAST_EXPECT(
jsonToUint64(total[jss::queued_duration_us]) == queuedDur);
656 int const runningDur = ((finished * (finished + 1)) / 2);
657 BEAST_EXPECT(
jsonToUint64(total[jss::running_duration_us]) == runningDur);
660 perfLog->jobFinish(jobs[i].type,
microseconds(finished + 1), (i * 2));
666 BEAST_EXPECT(currents.size() == i * 2);
669 for (
int j = 0; j < i; ++j)
671 BEAST_EXPECT(currents[j * 2].name == jobs[j].typeName);
672 BEAST_EXPECT(prevDur > currents[j * 2].dur);
673 prevDur = currents[j * 2].dur;
675 BEAST_EXPECT(currents[(j * 2) + 1].name == jobs[j].typeName);
676 BEAST_EXPECT(prevDur > currents[(j * 2) + 1].dur);
677 prevDur = currents[(j * 2) + 1].dur;
682 auto validateFinalCounters = [
this, &jobs](
Json::Value const& countersJson) {
686 BEAST_EXPECT(rpc.
size() == 0);
689 Json::Value const& jobQueue = countersJson[jss::job_queue];
690 for (
int i = jobs.
size() - 1; i >= 0; --i)
692 Json::Value const& counter{jobQueue[jobs[i].typeName]};
694 BEAST_EXPECT(running_dur_us == ((jobs.
size() - i) * 4) - 1);
697 BEAST_EXPECT(queued_dur_us == i + 1);
699 BEAST_EXPECT(counter[jss::queued] ==
"1");
700 BEAST_EXPECT(counter[jss::started] ==
"2");
701 BEAST_EXPECT(counter[jss::finished] ==
"2");
706 int const finished = jobs.
size() * 2;
708 BEAST_EXPECT(
jsonToUint64(total[jss::started]) == finished);
709 BEAST_EXPECT(
jsonToUint64(total[jss::finished]) == finished);
713 int const queuedDur = ((jobs.
size() * (jobs.
size() + 1)) / 2);
714 BEAST_EXPECT(
jsonToUint64(total[jss::queued_duration_us]) == queuedDur);
717 int const runningDur = ((finished * (finished + 1)) / 2);
718 BEAST_EXPECT(
jsonToUint64(total[jss::running_duration_us]) == runningDur);
721 auto validateFinalCurrent = [
this](
Json::Value const& currentJson) {
725 BEAST_EXPECT(j.
size() == 0);
728 Json::Value const& methods = currentJson[jss::methods];
729 BEAST_EXPECT(methods.
size() == 0);
730 BEAST_EXPECT(methods.
isArray());
734 validateFinalCounters(perfLog->countersJson());
735 validateFinalCurrent(perfLog->currentJson());
744 auto const fullPath = fixture.logFile();
748 BEAST_EXPECT(!exists(fullPath));
762 lastLine = std::move(line);
772 validateFinalCounters(parsedLastLine[jss::counters]);
773 validateFinalCurrent(parsedLastLine[jss::current_activities]);
787 auto perfLog{fixture.perfLog(withFile)};
797 auto iter{jobTypes.begin()};
800 jobType = iter->second.type();
801 jobTypeName = iter->second.name();
805 perfLog->resizeJobs(1);
808 auto verifyCounters =
810 Json::Value const& countersJson,
int started,
int finished,
int queued_us,
int running_us) {
811 BEAST_EXPECT(countersJson.
isObject());
812 BEAST_EXPECT(countersJson.
size() == 2);
814 BEAST_EXPECT(countersJson.
isMember(jss::rpc));
815 BEAST_EXPECT(countersJson[jss::rpc].isObject());
816 BEAST_EXPECT(countersJson[jss::rpc].size() == 0);
818 BEAST_EXPECT(countersJson.
isMember(jss::job_queue));
819 BEAST_EXPECT(countersJson[jss::job_queue].isObject());
820 BEAST_EXPECT(countersJson[jss::job_queue].size() == 1);
822 Json::Value const& job{countersJson[jss::job_queue][jobTypeName]};
824 BEAST_EXPECT(job.isObject());
826 BEAST_EXPECT(
jsonToUint64(job[jss::started]) == started);
827 BEAST_EXPECT(
jsonToUint64(job[jss::finished]) == finished);
829 BEAST_EXPECT(
jsonToUint64(job[jss::queued_duration_us]) == queued_us);
830 BEAST_EXPECT(
jsonToUint64(job[jss::running_duration_us]) == running_us);
835 auto verifyEmptyCurrent = [
this](
Json::Value const& currentJson) {
836 BEAST_EXPECT(currentJson.isObject());
837 BEAST_EXPECT(currentJson.size() == 2);
839 BEAST_EXPECT(currentJson.isMember(jss::jobs));
840 BEAST_EXPECT(currentJson[jss::jobs].isArray());
841 BEAST_EXPECT(currentJson[jss::jobs].size() == 0);
843 BEAST_EXPECT(currentJson.isMember(jss::methods));
844 BEAST_EXPECT(currentJson[jss::methods].isArray());
845 BEAST_EXPECT(currentJson[jss::methods].size() == 0);
849 perfLog->jobStart(jobType,
microseconds{11}, steady_clock::now(), 2);
851 verifyCounters(perfLog->countersJson(), 1, 0, 11, 0);
852 verifyEmptyCurrent(perfLog->currentJson());
855 perfLog->jobStart(jobType,
microseconds{13}, steady_clock::now(), -1);
857 verifyCounters(perfLog->countersJson(), 2, 0, 24, 0);
858 verifyEmptyCurrent(perfLog->currentJson());
863 verifyCounters(perfLog->countersJson(), 2, 1, 24, 17);
864 verifyEmptyCurrent(perfLog->currentJson());
869 verifyCounters(perfLog->countersJson(), 2, 2, 24, 36);
870 verifyEmptyCurrent(perfLog->currentJson());
879 auto const fullPath = fixture.logFile();
883 BEAST_EXPECT(!exists(fullPath));
897 lastLine = std::move(line);
907 verifyCounters(parsedLastLine[jss::counters], 2, 2, 24, 36);
908 verifyEmptyCurrent(parsedLastLine[jss::current_activities]);