Global Metrics
path: .metrics.loc.ploc
old: 46.0
new: 195.0
path: .metrics.loc.lloc
old: 1.0
new: 80.0
path: .metrics.loc.sloc
old: 73.0
new: 304.0
path: .metrics.loc.cloc
old: 16.0
new: 55.0
path: .metrics.loc.blank
old: 11.0
new: 54.0
path: .metrics.nom.total
old: 1.0
new: 19.0
path: .metrics.nom.functions
old: 1.0
new: 19.0
path: .metrics.cyclomatic.sum
old: 14.0
new: 36.0
path: .metrics.cyclomatic.average
old: 1.0769230769230769
new: 1.565217391304348
path: .metrics.mi.mi_original
old: 62.08127803123237
new: 23.486761122965135
path: .metrics.mi.mi_visual_studio
old: 36.30484095393706
new: 13.73494802512581
path: .metrics.mi.mi_sei
old: 48.45613286110868
new: -7.53688940764081
path: .metrics.halstead.bugs
old: 0.14116263733518505
new: 1.7939110076783071
path: .metrics.halstead.effort
old: 8714.88233045279
new: 394805.5273364016
path: .metrics.halstead.N1
old: 91.0
new: 607.0
path: .metrics.halstead.level
old: 0.12093023255813952
new: 0.019815994338287332
path: .metrics.halstead.n1
old: 10.0
new: 27.0
path: .metrics.halstead.vocabulary
old: 62.0
new: 153.0
path: .metrics.halstead.N2
old: 86.0
new: 471.0
path: .metrics.halstead.estimated_program_length
old: 329.6421462922104
new: 1007.5192329194032
path: .metrics.halstead.n2
old: 52.0
new: 126.0
path: .metrics.halstead.time
old: 484.1601294695995
new: 21933.64040757787
path: .metrics.halstead.difficulty
old: 8.26923076923077
new: 50.464285714285715
path: .metrics.halstead.purity_ratio
old: 1.8623850073006236
new: 0.9346189544706894
path: .metrics.halstead.length
old: 177.0
new: 1078.0
path: .metrics.halstead.volume
old: 1053.8927469384769
new: 7823.464094422679
path: .metrics.nexits.average
old: 1.0
new: 0.21052631578947367
path: .metrics.nexits.sum
old: 1.0
new: 4.0
path: .metrics.nargs.sum
old: 3.0
new: 20.0
path: .metrics.nargs.average
old: 3.0
new: 1.0526315789473684
path: .metrics.cognitive.average
old: 0.0
new: 0.8947368421052632
path: .metrics.cognitive.sum
old: 0.0
new: 17.0
Spaces Data
Minimal test - lines (114, 159)
path: .spaces[2].metrics.nargs.sum
old: 0.0
new: 1.0
path: .spaces[2].metrics.nargs.average
old: null
new: 0.16666666666666666
path: .spaces[2].metrics.loc.ploc
old: 1.0
new: 37.0
path: .spaces[2].metrics.loc.blank
old: 0.0
new: 6.0
path: .spaces[2].metrics.loc.cloc
old: 0.0
new: 3.0
path: .spaces[2].metrics.loc.lloc
old: 0.0
new: 16.0
path: .spaces[2].metrics.loc.sloc
old: 1.0
new: 46.0
path: .spaces[2].metrics.cyclomatic.sum
old: 1.0
new: 7.0
path: .spaces[2].metrics.nexits.average
old: null
new: 0.16666666666666666
path: .spaces[2].metrics.nexits.sum
old: 0.0
new: 1.0
path: .spaces[2].metrics.halstead.n1
old: 0.0
new: 16.0
path: .spaces[2].metrics.halstead.vocabulary
old: 1.0
new: 57.0
path: .spaces[2].metrics.halstead.N1
old: 0.0
new: 111.0
path: .spaces[2].metrics.halstead.n2
old: 1.0
new: 41.0
path: .spaces[2].metrics.halstead.difficulty
old: 0.0
new: 15.414634146341465
path: .spaces[2].metrics.halstead.effort
old: 0.0
new: 17083.25446099761
path: .spaces[2].metrics.halstead.level
old: null
new: 0.06487341772151899
path: .spaces[2].metrics.halstead.purity_ratio
old: null
new: 1.4929454325754812
path: .spaces[2].metrics.halstead.volume
old: 0.0
new: 1108.2491026913008
path: .spaces[2].metrics.halstead.estimated_program_length
old: null
new: 283.65963218934144
path: .spaces[2].metrics.halstead.time
old: 0.0
new: 949.069692277645
path: .spaces[2].metrics.halstead.N2
old: 1.0
new: 79.0
path: .spaces[2].metrics.halstead.length
old: 1.0
new: 190.0
path: .spaces[2].metrics.halstead.bugs
old: 0.0
new: 0.221101905390142
path: .spaces[2].metrics.mi.mi_visual_studio
old: null
new: 41.46854896156351
path: .spaces[2].metrics.mi.mi_original
old: null
new: 70.91121872427361
path: .spaces[2].metrics.mi.mi_sei
old: null
new: 46.58455146213936
path: .spaces[2].metrics.cognitive.average
old: null
new: 0.0
path: .spaces[2].metrics.nom.functions
old: 0.0
new: 6.0
path: .spaces[2].metrics.nom.total
old: 0.0
new: 6.0
Code
class ThreadMetrics : public ::testing::Test {
public:
explicit ThreadMetrics() = default;
protected:
virtual void SetUp() {
// building the DocGroup structure
RefPtr group =
dom::BrowsingContextGroup::Create();
mDocGroup = group->AddDocument("key"_ns, nullptr);
mDocGroup2 = group->AddDocument("key2"_ns, nullptr);
mCounter = mDocGroup->GetPerformanceCounter();
mCounter2 = mDocGroup2->GetPerformanceCounter();
mThreadMgr = do_GetService("@mozilla.org/thread-manager;1");
mOther = DispatchCategory(TaskCategory::Other).GetValue();
mDispatchCount = (uint32_t)TaskCategory::Other + 1;
}
virtual void TearDown() {
// and remove the document from the doc group (actually, a nullptr)
mDocGroup->RemoveDocument(nullptr);
mDocGroup2->RemoveDocument(nullptr);
mDocGroup = nullptr;
mDocGroup2 = nullptr;
ProcessAllEvents();
}
// this is used to get rid of transient events
void initScheduler() { ProcessAllEvents(); }
nsresult Dispatch(nsIRunnable* aRunnable) {
ProcessAllEvents();
return TimedRunnable::DispatchWithDocgroup(aRunnable, mDocGroup);
}
void ProcessAllEvents() { mThreadMgr->SpinEventLoopUntilEmpty(); }
uint32_t mOther;
bool mOldPref;
RefPtr mDocGroup;
RefPtr mDocGroup2;
RefPtr mCounter;
RefPtr mCounter2;
nsCOMPtr mThreadMgr;
uint32_t mDispatchCount;
};
Minimal test - lines (29, 40)
path: .spaces[0].metrics.loc.ploc
old: 4.0
new: 10.0
path: .spaces[0].metrics.loc.cloc
old: 1.0
new: 0.0
path: .spaces[0].metrics.loc.blank
old: 0.0
new: 2.0
path: .spaces[0].metrics.loc.sloc
old: 5.0
new: 12.0
path: .spaces[0].metrics.nargs.sum
old: 0.0
new: 3.0
path: .spaces[0].metrics.nargs.average
old: null
new: 1.5
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 4.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.3333333333333333
path: .spaces[0].metrics.halstead.effort
old: 44.91767875292167
new: 3722.9895505855793
path: .spaces[0].metrics.halstead.volume
old: 22.458839376460833
new: 265.9278250418271
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.5943609377704335
new: 1.483432758919099
path: .spaces[0].metrics.halstead.vocabulary
old: 7.0
new: 24.0
path: .spaces[0].metrics.halstead.n2
old: 3.0
new: 12.0
path: .spaces[0].metrics.halstead.level
old: 0.5
new: 0.07142857142857142
path: .spaces[0].metrics.halstead.N1
old: 5.0
new: 30.0
path: .spaces[0].metrics.halstead.bugs
old: 0.00421201861424495
new: 0.08007063821493973
path: .spaces[0].metrics.halstead.difficulty
old: 2.0
new: 14.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 12.754887502163468
new: 86.03910001730775
path: .spaces[0].metrics.halstead.length
old: 8.0
new: 58.0
path: .spaces[0].metrics.halstead.n1
old: 4.0
new: 12.0
path: .spaces[0].metrics.halstead.N2
old: 3.0
new: 28.0
path: .spaces[0].metrics.halstead.time
old: 2.495426597384537
new: 206.83275281030996
path: .spaces[0].metrics.nexits.average
old: null
new: 0.0
path: .spaces[0].metrics.cognitive.average
old: null
new: 0.0
path: .spaces[0].metrics.mi.mi_visual_studio
old: 75.15575883029284
new: 58.94253953114288
path: .spaces[0].metrics.mi.mi_original
old: 128.51634759980075
new: 100.79174259825432
path: .spaces[0].metrics.mi.mi_sei
old: 141.7463557556368
new: 70.11817465466349
path: .spaces[0].metrics.nom.functions
old: 0.0
new: 2.0
path: .spaces[0].metrics.nom.total
old: 0.0
new: 2.0
Code
struct RunnableDescriptor {
MOZ_IMPLICIT RunnableDescriptor(nsIRunnable* aRunnable,
DocGroup* aDocGroup = nullptr)
: mRunnable(aRunnable), mDocGroup(aDocGroup) {}
RunnableDescriptor(RunnableDescriptor&& aDescriptor)
: mRunnable(std::move(aDescriptor.mRunnable)),
mDocGroup(std::move(aDescriptor.mDocGroup)) {}
nsCOMPtr mRunnable;
RefPtr mDocGroup;
};
Minimal test - lines (222, 258)
path: .spaces[5].metrics.loc.ploc
old: 1.0
new: 22.0
path: .spaces[5].metrics.loc.lloc
old: 0.0
new: 12.0
path: .spaces[5].metrics.loc.cloc
old: 0.0
new: 7.0
path: .spaces[5].metrics.loc.blank
old: 0.0
new: 8.0
path: .spaces[5].metrics.loc.sloc
old: 1.0
new: 37.0
path: .spaces[5].metrics.nargs.sum
old: 0.0
new: 2.0
path: .spaces[5].metrics.nargs.average
old: null
new: 2.0
path: .spaces[5].metrics.cognitive.average
old: null
new: 3.0
path: .spaces[5].metrics.cognitive.sum
old: 0.0
new: 3.0
path: .spaces[5].metrics.cyclomatic.average
old: 1.0
new: 4.0
path: .spaces[5].metrics.cyclomatic.sum
old: 1.0
new: 4.0
path: .spaces[5].metrics.nexits.average
old: null
new: 0.0
path: .spaces[5].metrics.mi.mi_sei
old: null
new: 66.49157998104721
path: .spaces[5].metrics.mi.mi_visual_studio
old: null
new: 44.825856994170834
path: .spaces[5].metrics.mi.mi_original
old: null
new: 76.65221546003212
path: .spaces[5].metrics.halstead.purity_ratio
old: null
new: 1.8727861856939352
path: .spaces[5].metrics.halstead.level
old: null
new: 0.06630824372759857
path: .spaces[5].metrics.halstead.N2
old: 1.0
new: 62.0
path: .spaces[5].metrics.halstead.n2
old: 1.0
new: 37.0
path: .spaces[5].metrics.halstead.bugs
old: 0.0
new: 0.17923015541668944
path: .spaces[5].metrics.halstead.difficulty
old: 0.0
new: 15.08108108108108
path: .spaces[5].metrics.halstead.time
old: 0.0
new: 692.6693948663465
path: .spaces[5].metrics.halstead.N1
old: 0.0
new: 81.0
path: .spaces[5].metrics.halstead.length
old: 1.0
new: 143.0
path: .spaces[5].metrics.halstead.effort
old: 0.0
new: 12468.049107594235
path: .spaces[5].metrics.halstead.n1
old: 0.0
new: 18.0
path: .spaces[5].metrics.halstead.estimated_program_length
old: null
new: 267.8084245542328
path: .spaces[5].metrics.halstead.volume
old: 0.0
new: 826.7344390340264
path: .spaces[5].metrics.halstead.vocabulary
old: 1.0
new: 55.0
path: .spaces[5].metrics.nom.total
old: 0.0
new: 1.0
path: .spaces[5].metrics.nom.functions
old: 0.0
new: 1.0
Code
TEST_F(ThreadMetrics, CollectMultipleRecursiveMetrics) {
nsresult rv;
initScheduler();
// Dispatching a runnable that will last for +75ms
// and run another two recursively that last for 400ms each.
RefPtr runnable = new TimedRunnable(25, 25);
for (auto i : {1, 2}) {
Unused << i;
nsCOMPtr nested = new TimedRunnable(400, 0);
runnable->AddNestedRunnable({nested});
}
rv = Dispatch(runnable);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Flush the queue
ProcessAllEvents();
// let's look at the counters
ASSERT_EQ(mCounter->GetDispatchCounter()[mOther], 1u);
// other counters should stay empty
for (uint32_t i = 0; i < mDispatchCount; i++) {
if (i != mOther) {
ASSERT_EQ(mCounter->GetDispatchCounter()[i], 0u);
}
}
// did we get incremented in the docgroup ?
uint64_t duration = mCounter->GetExecutionDuration();
ASSERT_GE(duration, runnable->TotalSlept());
// let's make sure we don't count the time spent in recursive calls
ASSERT_LT(duration, runnable->TotalSlept() + 200000u);
}
Minimal test - lines (161, 186)
path: .spaces[3].metrics.loc.blank
old: 0.0
new: 5.0
path: .spaces[3].metrics.loc.ploc
old: 1.0
new: 16.0
path: .spaces[3].metrics.loc.sloc
old: 1.0
new: 26.0
path: .spaces[3].metrics.loc.lloc
old: 0.0
new: 9.0
path: .spaces[3].metrics.loc.cloc
old: 0.0
new: 5.0
path: .spaces[3].metrics.mi.mi_original
old: null
new: 84.99972025325582
path: .spaces[3].metrics.mi.mi_visual_studio
old: null
new: 49.70743874459404
path: .spaces[3].metrics.mi.mi_sei
old: null
new: 78.64828687785112
path: .spaces[3].metrics.nom.total
old: 0.0
new: 1.0
path: .spaces[3].metrics.nom.functions
old: 0.0
new: 1.0
path: .spaces[3].metrics.nexits.average
old: null
new: 0.0
path: .spaces[3].metrics.halstead.n2
old: 1.0
new: 28.0
path: .spaces[3].metrics.halstead.difficulty
old: 0.0
new: 11.25
path: .spaces[3].metrics.halstead.estimated_program_length
old: null
new: 193.20929675174068
path: .spaces[3].metrics.halstead.bugs
old: 0.0
new: 0.1083499134576206
path: .spaces[3].metrics.halstead.vocabulary
old: 1.0
new: 43.0
path: .spaces[3].metrics.halstead.length
old: 1.0
new: 96.0
path: .spaces[3].metrics.halstead.effort
old: 0.0
new: 5860.365935078266
path: .spaces[3].metrics.halstead.purity_ratio
old: null
new: 2.0125968411639654
path: .spaces[3].metrics.halstead.time
old: 0.0
new: 325.5758852821259
path: .spaces[3].metrics.halstead.level
old: null
new: 0.08888888888888889
path: .spaces[3].metrics.halstead.volume
old: 0.0
new: 520.9214164514015
path: .spaces[3].metrics.halstead.N1
old: 0.0
new: 54.0
path: .spaces[3].metrics.halstead.N2
old: 1.0
new: 42.0
path: .spaces[3].metrics.halstead.n1
old: 0.0
new: 15.0
path: .spaces[3].metrics.nargs.average
old: null
new: 2.0
path: .spaces[3].metrics.nargs.sum
old: 0.0
new: 2.0
path: .spaces[3].metrics.cyclomatic.average
old: 1.0
new: 3.0
path: .spaces[3].metrics.cyclomatic.sum
old: 1.0
new: 3.0
path: .spaces[3].metrics.cognitive.sum
old: 0.0
new: 3.0
path: .spaces[3].metrics.cognitive.average
old: null
new: 3.0
Code
TEST_F(ThreadMetrics, CollectMetrics) {
nsresult rv;
initScheduler();
// Dispatching a runnable that will last for +50ms
nsCOMPtr runnable = new TimedRunnable(25, 25);
rv = Dispatch(runnable);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Flush the queue
ProcessAllEvents();
// Let's look at the task category "other" counter
ASSERT_EQ(mCounter->GetDispatchCounter()[mOther], 1u);
// other counters should stay empty
for (uint32_t i = 0; i < mDispatchCount; i++) {
if (i != mOther) {
ASSERT_EQ(mCounter->GetDispatchCounter()[i], 0u);
}
}
// Did we get incremented in the docgroup ?
uint64_t duration = mCounter->GetExecutionDuration();
ASSERT_GE(duration, 50000u);
}
Minimal test - lines (260, 304)
path: .spaces[6].metrics.halstead.purity_ratio
old: null
new: 1.4716270698930516
path: .spaces[6].metrics.halstead.estimated_program_length
old: null
new: 263.42124551085624
path: .spaces[6].metrics.halstead.level
old: null
new: 0.060126582278481014
path: .spaces[6].metrics.halstead.n2
old: 1.0
new: 38.0
path: .spaces[6].metrics.halstead.time
old: 0.0
new: 951.8112768198084
path: .spaces[6].metrics.halstead.length
old: 1.0
new: 179.0
path: .spaces[6].metrics.halstead.bugs
old: 0.0
new: 0.2215274997758664
path: .spaces[6].metrics.halstead.volume
old: 0.0
new: 1030.1248628872609
path: .spaces[6].metrics.halstead.vocabulary
old: 1.0
new: 54.0
path: .spaces[6].metrics.halstead.difficulty
old: 0.0
new: 16.63157894736842
path: .spaces[6].metrics.halstead.N2
old: 1.0
new: 79.0
path: .spaces[6].metrics.halstead.n1
old: 0.0
new: 16.0
path: .spaces[6].metrics.halstead.effort
old: 0.0
new: 17132.60298275655
path: .spaces[6].metrics.halstead.N1
old: 0.0
new: 100.0
path: .spaces[6].metrics.mi.mi_original
old: null
new: 72.56740410582209
path: .spaces[6].metrics.mi.mi_sei
old: null
new: 65.1650461648317
path: .spaces[6].metrics.mi.mi_visual_studio
old: null
new: 42.43707842445736
path: .spaces[6].metrics.loc.ploc
old: 1.0
new: 24.0
path: .spaces[6].metrics.loc.blank
old: 0.0
new: 9.0
path: .spaces[6].metrics.loc.cloc
old: 0.0
new: 12.0
path: .spaces[6].metrics.loc.lloc
old: 0.0
new: 15.0
path: .spaces[6].metrics.loc.sloc
old: 1.0
new: 45.0
path: .spaces[6].metrics.nargs.sum
old: 0.0
new: 2.0
path: .spaces[6].metrics.nargs.average
old: null
new: 2.0
path: .spaces[6].metrics.cognitive.average
old: null
new: 3.0
path: .spaces[6].metrics.cognitive.sum
old: 0.0
new: 3.0
path: .spaces[6].metrics.nexits.average
old: null
new: 0.0
path: .spaces[6].metrics.nom.total
old: 0.0
new: 1.0
path: .spaces[6].metrics.nom.functions
old: 0.0
new: 1.0
path: .spaces[6].metrics.cyclomatic.average
old: 1.0
new: 3.0
path: .spaces[6].metrics.cyclomatic.sum
old: 1.0
new: 3.0
Code
TEST_F(ThreadMetrics, CollectMultipleRecursiveMetricsWithTwoDocgroups) {
nsresult rv;
initScheduler();
// Dispatching a runnable that will last for +75ms
// and run another two recursively that last for 400ms each. The
// first nested runnable will have a docgroup, but the second will
// not, to test that the time for first nested event is accounted
// correctly.
RefPtr runnable = new TimedRunnable(25, 25);
RefPtr nested1 = new TimedRunnable(400, 0);
runnable->AddNestedRunnable({nested1, mDocGroup2});
nsCOMPtr nested2 = new TimedRunnable(400, 0);
runnable->AddNestedRunnable({nested2});
rv = Dispatch(runnable);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Flush the queue
ProcessAllEvents();
// let's look at the counters
ASSERT_EQ(mCounter->GetDispatchCounter()[mOther], 1u);
// other counters should stay empty
for (uint32_t i = 0; i < mDispatchCount; i++) {
if (i != mOther) {
ASSERT_EQ(mCounter->GetDispatchCounter()[i], 0u);
}
}
uint64_t duration = mCounter2->GetExecutionDuration();
// Make sure this we incremented the timings for the first nested
// runnable correctly.
ASSERT_GE(duration, nested1->TotalSlept());
ASSERT_LT(duration, nested1->TotalSlept() + 20000u);
// And now for the outer runnable.
duration = mCounter->GetExecutionDuration();
ASSERT_GE(duration, runnable->TotalSlept());
// let's make sure we don't count the time spent in recursive calls
ASSERT_LT(duration, runnable->TotalSlept() + 200000u);
}
Minimal test - lines (188, 220)
path: .spaces[4].metrics.nom.functions
old: 0.0
new: 1.0
path: .spaces[4].metrics.nom.total
old: 0.0
new: 1.0
path: .spaces[4].metrics.halstead.vocabulary
old: 13.0
new: 50.0
path: .spaces[4].metrics.halstead.estimated_program_length
old: 36.529325012980806
new: 236.9737366025115
path: .spaces[4].metrics.halstead.length
old: 21.0
new: 130.0
path: .spaces[4].metrics.halstead.n1
old: 4.0
new: 16.0
path: .spaces[4].metrics.halstead.N1
old: 12.0
new: 73.0
path: .spaces[4].metrics.halstead.purity_ratio
old: 1.7394916672848002
new: 1.8228748969423965
path: .spaces[4].metrics.halstead.time
old: 8.634359342329214
new: 546.6794034801401
path: .spaces[4].metrics.halstead.volume
old: 77.70923408096293
new: 733.7013046707142
path: .spaces[4].metrics.halstead.n2
old: 9.0
new: 34.0
path: .spaces[4].metrics.halstead.difficulty
old: 2.0
new: 13.411764705882351
path: .spaces[4].metrics.halstead.N2
old: 9.0
new: 57.0
path: .spaces[4].metrics.halstead.bugs
old: 0.00963563842219266
new: 0.15306723008731535
path: .spaces[4].metrics.halstead.level
old: 0.5
new: 0.07456140350877193
path: .spaces[4].metrics.halstead.effort
old: 155.41846816192586
new: 9840.22926264252
path: .spaces[4].metrics.nargs.sum
old: 0.0
new: 2.0
path: .spaces[4].metrics.nargs.average
old: null
new: 2.0
path: .spaces[4].metrics.cyclomatic.average
old: 1.0
new: 3.0
path: .spaces[4].metrics.mi.mi_original
old: 116.15079030142728
new: 79.35644708382942
path: .spaces[4].metrics.mi.mi_sei
old: 92.17477674940372
new: 71.81619163441891
path: .spaces[4].metrics.mi.mi_visual_studio
old: 67.9244387727645
new: 46.40727899639147
path: .spaces[4].metrics.loc.blank
old: 0.0
new: 7.0
path: .spaces[4].metrics.loc.lloc
old: 0.0
new: 11.0
path: .spaces[4].metrics.loc.ploc
old: 7.0
new: 19.0
path: .spaces[4].metrics.loc.cloc
old: 0.0
new: 7.0
path: .spaces[4].metrics.loc.sloc
old: 7.0
new: 33.0
path: .spaces[4].metrics.nexits.average
old: null
new: 0.0
path: .spaces[4].metrics.cognitive.average
old: null
new: 3.0
path: .spaces[4].metrics.cognitive.sum
old: 0.0
new: 3.0
Code
TEST_F(ThreadMetrics, CollectRecursiveMetrics) {
nsresult rv;
initScheduler();
// Dispatching a runnable that will last for +50ms
// and run another one recursively that lasts for 400ms
RefPtr runnable = new TimedRunnable(25, 25);
nsCOMPtr nested = new TimedRunnable(400, 0);
runnable->AddNestedRunnable({nested});
rv = Dispatch(runnable);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Flush the queue
ProcessAllEvents();
// let's look at the counters
ASSERT_EQ(mCounter->GetDispatchCounter()[mOther], 1u);
// other counters should stay empty
for (uint32_t i = 0; i < mDispatchCount; i++) {
if (i != mOther) {
ASSERT_EQ(mCounter->GetDispatchCounter()[i], 0u);
}
}
// did we get incremented in the docgroup ?
uint64_t duration = mCounter->GetExecutionDuration();
ASSERT_GE(duration, runnable->TotalSlept());
// let's make sure we don't count the time spent in recursive calls
ASSERT_LT(duration, runnable->TotalSlept() + 200000u);
}
Minimal test - lines (45, 106)
path: .spaces[1].metrics.loc.sloc
old: 1.0
new: 62.0
path: .spaces[1].metrics.loc.ploc
old: 1.0
new: 50.0
path: .spaces[1].metrics.loc.cloc
old: 0.0
new: 5.0
path: .spaces[1].metrics.loc.lloc
old: 0.0
new: 17.0
path: .spaces[1].metrics.loc.blank
old: 0.0
new: 7.0
path: .spaces[1].metrics.nargs.average
old: null
new: 1.1428571428571428
path: .spaces[1].metrics.nargs.sum
old: 0.0
new: 8.0
path: .spaces[1].metrics.mi.mi_sei
old: null
new: 37.96077545834554
path: .spaces[1].metrics.mi.mi_visual_studio
old: null
new: 36.98701826564402
path: .spaces[1].metrics.mi.mi_original
old: null
new: 63.24780123425127
path: .spaces[1].metrics.cyclomatic.average
old: 1.0
new: 1.375
path: .spaces[1].metrics.cyclomatic.sum
old: 1.0
new: 11.0
path: .spaces[1].metrics.cognitive.average
old: null
new: 0.7142857142857143
path: .spaces[1].metrics.cognitive.sum
old: 0.0
new: 5.0
path: .spaces[1].metrics.nom.functions
old: 0.0
new: 7.0
path: .spaces[1].metrics.nom.total
old: 0.0
new: 7.0
path: .spaces[1].metrics.halstead.n2
old: 1.0
new: 52.0
path: .spaces[1].metrics.halstead.volume
old: 0.0
new: 1599.4694434415578
path: .spaces[1].metrics.halstead.effort
old: 0.0
new: 39494.59164190309
path: .spaces[1].metrics.halstead.estimated_program_length
old: null
new: 406.4619653606445
path: .spaces[1].metrics.halstead.level
old: null
new: 0.04049844236760125
path: .spaces[1].metrics.halstead.bugs
old: 0.0
new: 0.3865780257375092
path: .spaces[1].metrics.halstead.N2
old: 1.0
new: 107.0
path: .spaces[1].metrics.halstead.vocabulary
old: 1.0
new: 76.0
path: .spaces[1].metrics.halstead.difficulty
old: 0.0
new: 24.692307692307693
path: .spaces[1].metrics.halstead.N1
old: 0.0
new: 149.0
path: .spaces[1].metrics.halstead.n1
old: 0.0
new: 24.0
path: .spaces[1].metrics.halstead.length
old: 1.0
new: 256.0
path: .spaces[1].metrics.halstead.purity_ratio
old: null
new: 1.5877420521900176
path: .spaces[1].metrics.halstead.time
old: 0.0
new: 2194.1439801057268
path: .spaces[1].metrics.nexits.sum
old: 0.0
new: 3.0
path: .spaces[1].metrics.nexits.average
old: null
new: 0.42857142857142855
Code
class TimedRunnable final : public Runnable {
public:
explicit TimedRunnable(uint32_t aExecutionTime1, uint32_t aExecutionTime2)
: Runnable("TimedRunnable"),
mExecutionTime1(aExecutionTime1),
mExecutionTime2(aExecutionTime2) {}
NS_IMETHODIMP Run() {
Sleep(mExecutionTime1);
for (uint32_t index = 0; index < mNestedRunnables.Length(); ++index) {
if (index != 0) {
Sleep(mExecutionTime1);
}
(void)DispatchNestedRunnable(mNestedRunnables[index].mRunnable,
mNestedRunnables[index].mDocGroup);
}
Sleep(mExecutionTime2);
return NS_OK;
}
void AddNestedRunnable(RunnableDescriptor aDescriptor) {
mNestedRunnables.AppendElement(std::move(aDescriptor));
}
void Sleep(uint32_t aMilliseconds) {
TimeStamp start = TimeStamp::Now();
PR_Sleep(PR_MillisecondsToInterval(aMilliseconds + 5));
TimeStamp stop = TimeStamp::Now();
mTotalSlept += (stop - start).ToMicroseconds();
}
// Total sleep time, in microseconds.
uint64_t TotalSlept() const { return mTotalSlept; }
static void DispatchNestedRunnable(nsIRunnable* aRunnable,
DocGroup* aDocGroup) {
// Dispatch another runnable so nsThread::ProcessNextEvent is called
// recursively
nsCOMPtr thread = do_GetMainThread();
if (aDocGroup) {
(void)DispatchWithDocgroup(aRunnable, aDocGroup);
} else {
thread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
}
(void)NS_ProcessNextEvent(thread, false);
}
static nsresult DispatchWithDocgroup(nsIRunnable* aRunnable,
DocGroup* aDocGroup) {
nsCOMPtr runnable = aRunnable;
runnable = new SchedulerGroup::Runnable(runnable.forget(), aDocGroup);
return aDocGroup->Dispatch(TaskCategory::Other, runnable.forget());
}
private:
uint32_t mExecutionTime1;
uint32_t mExecutionTime2;
// When we sleep, the actual time we sleep might not match how long
// we asked to sleep for. Record how much we actually slept.
uint64_t mTotalSlept = 0;
nsTArray mNestedRunnables;
};