174 using namespace boost::filesystem;
179 BEAST_EXPECT(!exists(fixture.logFile()));
183 BEAST_EXPECT(fixture.stopSignaled ==
false);
184 BEAST_EXPECT(exists(fixture.logFile()));
191 if (!BEAST_EXPECT(!exists(fixture.logDir())))
197 nastyFile.
open(fixture.logDir().c_str(), std::ios::out | std::ios::app);
198 if (!BEAST_EXPECT(nastyFile))
205 BEAST_EXPECT(fixture.stopSignaled ==
false);
207 BEAST_EXPECT(fixture.stopSignaled ==
true);
217 remove(fixture.logDir());
224 if (!BEAST_EXPECT(!exists(fixture.logDir())))
229 boost::system::error_code ec;
230 boost::filesystem::create_directories(fixture.logDir(), ec);
231 if (!BEAST_EXPECT(!ec))
234 auto fileWriteable = [](boost::filesystem::path
const& p) ->
bool {
238 if (!BEAST_EXPECT(fileWriteable(fixture.logFile())))
241 boost::filesystem::permissions(
243 perms::remove_perms | perms::owner_write | perms::others_write |
248 if (fileWriteable(fixture.logFile()))
250 log <<
"Unable to write protect file. Test skipped." <<
std::endl;
256 BEAST_EXPECT(fixture.stopSignaled ==
false);
258 BEAST_EXPECT(fixture.stopSignaled ==
true);
268 boost::filesystem::permissions(
270 perms::add_perms | perms::owner_write | perms::others_write | perms::group_write);
280 auto perfLog{fixture.perfLog(withFile)};
305 for (
int labelIndex = 0; labelIndex < labels.
size(); ++labelIndex)
307 for (
int idIndex = 0; idIndex < 2; ++idIndex)
310 perfLog->rpcStart(labels[labelIndex], ids[(labelIndex * 2) + idIndex]);
315 Json::Value const countersJson{perfLog->countersJson()[jss::rpc]};
316 BEAST_EXPECT(countersJson.size() == labels.
size() + 1);
317 for (
auto& label : labels)
321 BEAST_EXPECT(counter[jss::duration_us] ==
"0");
322 BEAST_EXPECT(counter[jss::errored] ==
"0");
323 BEAST_EXPECT(counter[jss::finished] ==
"0");
324 BEAST_EXPECT(counter[jss::started] ==
"2");
327 Json::Value const& total{countersJson[jss::total]};
328 BEAST_EXPECT(total[jss::duration_us] ==
"0");
329 BEAST_EXPECT(total[jss::errored] ==
"0");
330 BEAST_EXPECT(total[jss::finished] ==
"0");
338 BEAST_EXPECT(currents.size() == labels.
size() * 2);
341 for (
int i = 0; i < currents.size(); ++i)
343 BEAST_EXPECT(currents[i].name == labels[i / 2]);
344 BEAST_EXPECT(prevDur > currents[i].dur);
345 prevDur = currents[i].dur;
352 for (
int labelIndex = labels.
size() - 1; labelIndex > 0; --labelIndex)
355 perfLog->rpcFinish(labels[labelIndex], ids[(labelIndex * 2) + 1]);
357 perfLog->rpcError(labels[labelIndex], ids[(labelIndex * 2) + 0]);
359 perfLog->rpcFinish(labels[0], ids[0 + 1]);
362 auto validateFinalCounters = [
this, &labels](
Json::Value const& countersJson) {
364 Json::Value const& jobQueue = countersJson[jss::job_queue];
366 BEAST_EXPECT(jobQueue.
size() == 0);
370 BEAST_EXPECT(rpc.
size() == labels.
size() + 1);
378 BEAST_EXPECT(first[jss::duration_us] !=
"0");
379 BEAST_EXPECT(first[jss::errored] ==
"0");
380 BEAST_EXPECT(first[jss::finished] ==
"1");
381 BEAST_EXPECT(first[jss::started] ==
"2");
386 for (
int i = 1; i < labels.
size(); ++i)
390 BEAST_EXPECT(dur != 0 && dur < prevDur);
392 BEAST_EXPECT(counter[jss::errored] ==
"1");
393 BEAST_EXPECT(counter[jss::finished] ==
"1");
394 BEAST_EXPECT(counter[jss::started] ==
"2");
399 BEAST_EXPECT(total[jss::duration_us] !=
"0");
405 auto validateFinalCurrent = [
this, &labels](
Json::Value const& currentJson) {
407 Json::Value const& job_queue = currentJson[jss::jobs];
408 BEAST_EXPECT(job_queue.
isArray());
409 BEAST_EXPECT(job_queue.
size() == 0);
412 Json::Value const& methods = currentJson[jss::methods];
413 BEAST_EXPECT(methods.
size() == 1);
414 BEAST_EXPECT(methods.
isArray());
417 BEAST_EXPECT(only.
size() == 2);
419 BEAST_EXPECT(only[jss::duration_us] !=
"0");
420 BEAST_EXPECT(only[jss::method] == labels[0]);
424 validateFinalCounters(perfLog->countersJson());
425 validateFinalCurrent(perfLog->currentJson());
433 auto const fullPath = fixture.logFile();
437 BEAST_EXPECT(!exists(fullPath));
451 lastLine = std::move(line);
463 validateFinalCounters(parsedLastLine[jss::counters]);
464 validateFinalCurrent(parsedLastLine[jss::current_activities]);
476 auto perfLog{fixture.perfLog(withFile)};
495 for (
auto const& job : jobTypes)
504 for (
int i = 0; i < jobs.
size(); ++i)
506 perfLog->jobQueue(jobs[i].type);
507 Json::Value const jq_counters{perfLog->countersJson()[jss::job_queue]};
509 BEAST_EXPECT(jq_counters.size() == i + 2);
510 for (
int j = 0; j <= i; ++j)
514 Json::Value const& counter{jq_counters[jobs[j].typeName]};
515 BEAST_EXPECT(counter.size() == 5);
516 BEAST_EXPECT(counter[jss::queued] ==
"1");
517 BEAST_EXPECT(counter[jss::started] ==
"0");
518 BEAST_EXPECT(counter[jss::finished] ==
"0");
519 BEAST_EXPECT(counter[jss::queued_duration_us] ==
"0");
520 BEAST_EXPECT(counter[jss::running_duration_us] ==
"0");
525 BEAST_EXPECT(total.size() == 5);
526 BEAST_EXPECT(
jsonToUint64(total[jss::queued]) == i + 1);
527 BEAST_EXPECT(total[jss::started] ==
"0");
528 BEAST_EXPECT(total[jss::finished] ==
"0");
529 BEAST_EXPECT(total[jss::queued_duration_us] ==
"0");
530 BEAST_EXPECT(total[jss::running_duration_us] ==
"0");
536 BEAST_EXPECT(
current.size() == 2);
537 BEAST_EXPECT(
current.isMember(jss::jobs));
538 BEAST_EXPECT(
current[jss::jobs].size() == 0);
539 BEAST_EXPECT(
current.isMember(jss::methods));
540 BEAST_EXPECT(
current[jss::methods].size() == 0);
546 perfLog->resizeJobs(jobs.
size() * 2);
552 for (
int i = 0; i < jobs.
size(); ++i)
554 perfLog->jobStart(jobs[i].type,
microseconds{i + 1}, steady_clock::now(), i * 2);
558 Json::Value const jq_counters{perfLog->countersJson()[jss::job_queue]};
559 for (
int j = 0; j < jobs.
size(); ++j)
561 Json::Value const& counter{jq_counters[jobs[j].typeName]};
565 BEAST_EXPECT(counter[jss::started] ==
"2");
566 BEAST_EXPECT(queued_dur_us == j + 1);
570 BEAST_EXPECT(counter[jss::started] ==
"1");
571 BEAST_EXPECT(queued_dur_us == j + 1);
575 BEAST_EXPECT(counter[jss::started] ==
"0");
576 BEAST_EXPECT(queued_dur_us == 0);
579 BEAST_EXPECT(counter[jss::queued] ==
"1");
580 BEAST_EXPECT(counter[jss::finished] ==
"0");
581 BEAST_EXPECT(counter[jss::running_duration_us] ==
"0");
587 BEAST_EXPECT(
jsonToUint64(total[jss::started]) == (i * 2) + 1);
588 BEAST_EXPECT(total[jss::finished] ==
"0");
592 jsonToUint64(total[jss::queued_duration_us]) == (((i * i) + 3 * i + 2) / 2));
593 BEAST_EXPECT(total[jss::running_duration_us] ==
"0");
596 perfLog->jobStart(jobs[i].type,
microseconds{0}, steady_clock::now(), (i * 2) + 1);
603 BEAST_EXPECT(currents.size() == (i + 1) * 2);
606 for (
int j = 0; j <= i; ++j)
608 BEAST_EXPECT(currents[j * 2].name == jobs[j].typeName);
609 BEAST_EXPECT(prevDur > currents[j * 2].dur);
610 prevDur = currents[j * 2].dur;
612 BEAST_EXPECT(currents[(j * 2) + 1].name == jobs[j].typeName);
613 BEAST_EXPECT(prevDur > currents[(j * 2) + 1].dur);
614 prevDur = currents[(j * 2) + 1].dur;
619 for (
int i = jobs.
size() - 1; i >= 0; --i)
623 int const finished = ((jobs.
size() - i) * 2) - 1;
624 perfLog->jobFinish(jobs[i].type,
microseconds(finished), (i * 2) + 1);
627 Json::Value const jq_counters{perfLog->countersJson()[jss::job_queue]};
628 for (
int j = 0; j < jobs.
size(); ++j)
630 Json::Value const& counter{jq_counters[jobs[j].typeName]};
634 BEAST_EXPECT(counter[jss::finished] ==
"0");
635 BEAST_EXPECT(running_dur_us == 0);
639 BEAST_EXPECT(counter[jss::finished] ==
"1");
640 BEAST_EXPECT(running_dur_us == ((jobs.
size() - j) * 2) - 1);
644 BEAST_EXPECT(counter[jss::finished] ==
"2");
645 BEAST_EXPECT(running_dur_us == ((jobs.
size() - j) * 4) - 1);
649 BEAST_EXPECT(queued_dur_us == j + 1);
650 BEAST_EXPECT(counter[jss::queued] ==
"1");
651 BEAST_EXPECT(counter[jss::started] ==
"2");
658 BEAST_EXPECT(
jsonToUint64(total[jss::finished]) == finished);
662 int const queuedDur = ((jobs.
size() * (jobs.
size() + 1)) / 2);
663 BEAST_EXPECT(
jsonToUint64(total[jss::queued_duration_us]) == queuedDur);
666 int const runningDur = ((finished * (finished + 1)) / 2);
667 BEAST_EXPECT(
jsonToUint64(total[jss::running_duration_us]) == runningDur);
670 perfLog->jobFinish(jobs[i].type,
microseconds(finished + 1), (i * 2));
676 BEAST_EXPECT(currents.size() == i * 2);
679 for (
int j = 0; j < i; ++j)
681 BEAST_EXPECT(currents[j * 2].name == jobs[j].typeName);
682 BEAST_EXPECT(prevDur > currents[j * 2].dur);
683 prevDur = currents[j * 2].dur;
685 BEAST_EXPECT(currents[(j * 2) + 1].name == jobs[j].typeName);
686 BEAST_EXPECT(prevDur > currents[(j * 2) + 1].dur);
687 prevDur = currents[(j * 2) + 1].dur;
692 auto validateFinalCounters = [
this, &jobs](
Json::Value const& countersJson) {
696 BEAST_EXPECT(rpc.
size() == 0);
699 Json::Value const& jobQueue = countersJson[jss::job_queue];
700 for (
int i = jobs.
size() - 1; i >= 0; --i)
702 Json::Value const& counter{jobQueue[jobs[i].typeName]};
704 BEAST_EXPECT(running_dur_us == ((jobs.
size() - i) * 4) - 1);
707 BEAST_EXPECT(queued_dur_us == i + 1);
709 BEAST_EXPECT(counter[jss::queued] ==
"1");
710 BEAST_EXPECT(counter[jss::started] ==
"2");
711 BEAST_EXPECT(counter[jss::finished] ==
"2");
716 int const finished = jobs.
size() * 2;
718 BEAST_EXPECT(
jsonToUint64(total[jss::started]) == finished);
719 BEAST_EXPECT(
jsonToUint64(total[jss::finished]) == finished);
723 int const queuedDur = ((jobs.
size() * (jobs.
size() + 1)) / 2);
724 BEAST_EXPECT(
jsonToUint64(total[jss::queued_duration_us]) == queuedDur);
727 int const runningDur = ((finished * (finished + 1)) / 2);
728 BEAST_EXPECT(
jsonToUint64(total[jss::running_duration_us]) == runningDur);
731 auto validateFinalCurrent = [
this](
Json::Value const& currentJson) {
735 BEAST_EXPECT(j.
size() == 0);
738 Json::Value const& methods = currentJson[jss::methods];
739 BEAST_EXPECT(methods.
size() == 0);
740 BEAST_EXPECT(methods.
isArray());
744 validateFinalCounters(perfLog->countersJson());
745 validateFinalCurrent(perfLog->currentJson());
754 auto const fullPath = fixture.logFile();
758 BEAST_EXPECT(!exists(fullPath));
772 lastLine = std::move(line);
784 validateFinalCounters(parsedLastLine[jss::counters]);
785 validateFinalCurrent(parsedLastLine[jss::current_activities]);
799 auto perfLog{fixture.perfLog(withFile)};
809 auto iter{jobTypes.begin()};
812 jobType = iter->second.type();
813 jobTypeName = iter->second.name();
817 perfLog->resizeJobs(1);
820 auto verifyCounters = [
this, jobTypeName](
826 BEAST_EXPECT(countersJson.
isObject());
827 BEAST_EXPECT(countersJson.
size() == 2);
829 BEAST_EXPECT(countersJson.
isMember(jss::rpc));
830 BEAST_EXPECT(countersJson[jss::rpc].isObject());
831 BEAST_EXPECT(countersJson[jss::rpc].size() == 0);
833 BEAST_EXPECT(countersJson.
isMember(jss::job_queue));
834 BEAST_EXPECT(countersJson[jss::job_queue].isObject());
835 BEAST_EXPECT(countersJson[jss::job_queue].size() == 1);
837 Json::Value const& job{countersJson[jss::job_queue][jobTypeName]};
839 BEAST_EXPECT(job.isObject());
841 BEAST_EXPECT(
jsonToUint64(job[jss::started]) == started);
842 BEAST_EXPECT(
jsonToUint64(job[jss::finished]) == finished);
844 BEAST_EXPECT(
jsonToUint64(job[jss::queued_duration_us]) == queued_us);
845 BEAST_EXPECT(
jsonToUint64(job[jss::running_duration_us]) == running_us);
850 auto verifyEmptyCurrent = [
this](
Json::Value const& currentJson) {
851 BEAST_EXPECT(currentJson.isObject());
852 BEAST_EXPECT(currentJson.size() == 2);
854 BEAST_EXPECT(currentJson.isMember(jss::jobs));
855 BEAST_EXPECT(currentJson[jss::jobs].isArray());
856 BEAST_EXPECT(currentJson[jss::jobs].size() == 0);
858 BEAST_EXPECT(currentJson.isMember(jss::methods));
859 BEAST_EXPECT(currentJson[jss::methods].isArray());
860 BEAST_EXPECT(currentJson[jss::methods].size() == 0);
864 perfLog->jobStart(jobType,
microseconds{11}, steady_clock::now(), 2);
866 verifyCounters(perfLog->countersJson(), 1, 0, 11, 0);
867 verifyEmptyCurrent(perfLog->currentJson());
870 perfLog->jobStart(jobType,
microseconds{13}, steady_clock::now(), -1);
872 verifyCounters(perfLog->countersJson(), 2, 0, 24, 0);
873 verifyEmptyCurrent(perfLog->currentJson());
878 verifyCounters(perfLog->countersJson(), 2, 1, 24, 17);
879 verifyEmptyCurrent(perfLog->currentJson());
884 verifyCounters(perfLog->countersJson(), 2, 2, 24, 36);
885 verifyEmptyCurrent(perfLog->currentJson());
894 auto const fullPath = fixture.logFile();
898 BEAST_EXPECT(!exists(fullPath));
912 lastLine = std::move(line);
924 verifyCounters(parsedLastLine[jss::counters], 2, 2, 24, 36);
925 verifyEmptyCurrent(parsedLastLine[jss::current_activities]);