Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include <gmock/gmock.h> | ||
4 | #include <gtest/gtest.h> | ||
5 | |||
6 | #include <ast/ASTNodes.h> | ||
7 | #include <util/BlockAllocator.h> | ||
8 | #include <util/CodeLoc.h> | ||
9 | #include <util/Memory.h> | ||
10 | |||
11 | namespace spice::testing { | ||
12 | |||
13 | using namespace spice::compiler; | ||
14 | |||
15 | static size_t destructedDummyNodes = 0; | ||
16 | |||
17 | class DummyNode final : public ASTNode { | ||
18 | // Constructors | ||
19 | using ASTNode::ASTNode; | ||
20 | |||
21 | // Destructors | ||
22 | 101008 | ~DummyNode() override { destructedDummyNodes++; } | |
23 | |||
24 | // Visitor methods | ||
25 | − | std::any accept(AbstractASTVisitor *visitor) override { return {}; } // LCOV_EXCL_LINE | |
26 | − | std::any accept(ParallelizableASTVisitor *visitor) const override { return {}; } // LCOV_EXCL_LINE | |
27 | |||
28 | // Other methods | ||
29 | ✗ | GET_CHILDREN(); | |
30 | }; | ||
31 | static constexpr size_t DUMMY_NODE_SIZE = sizeof(DummyNode); | ||
32 | static_assert(DUMMY_NODE_SIZE == 48, "DummyNode size has changed. Update test accordingly."); | ||
33 | |||
34 | class MockMemoryManager final : public MemoryManager { | ||
35 | public: | ||
36 |
2/4✓ Branch 0 (3→4) taken 2 times.
✗ Branch 1 (3→11) not taken.
✓ Branch 2 (4→5) taken 2 times.
✗ Branch 3 (4→9) not taken.
|
7 | MOCK_METHOD(byte *, allocate, (size_t size), (const override)); |
37 |
2/4✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→11) not taken.
✓ Branch 2 (4→5) taken 1 times.
✗ Branch 3 (4→9) not taken.
|
5 | MOCK_METHOD(void, deallocate, (byte * ptr), (const override)); |
38 | }; | ||
39 | |||
40 | 4 | TEST(BlockAllocatorTest, TestBlockAllocatorLarge) { | |
41 | 1 | destructedDummyNodes = 0; // Reset destruction counter | |
42 | static constexpr size_t NODE_COUNT = 100'000; // 100.000 * 48 bytes = 4.8 MB | ||
43 | |||
44 | { | ||
45 | // Create allocator, that can hold 5 nodes per block | ||
46 | 1 | constexpr DefaultMemoryManager memoryManager; | |
47 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→174) not taken.
|
1 | BlockAllocator<ASTNode> alloc(memoryManager, DUMMY_NODE_SIZE * 5); |
48 | |||
49 | // Allocate nodes | ||
50 | 1 | std::vector<ASTNode *> nodes; | |
51 |
2/2✓ Branch 0 (57→4) taken 100000 times.
✓ Branch 1 (57→58) taken 1 times.
|
100001 | for (size_t i = 0; i < NODE_COUNT; i++) { |
52 |
2/4✓ Branch 0 (4→5) taken 100000 times.
✗ Branch 1 (4→116) not taken.
✓ Branch 2 (5→6) taken 100000 times.
✗ Branch 3 (5→116) not taken.
|
100000 | auto node = alloc.allocate<DummyNode>(CodeLoc(i, 1)); |
53 |
3/12✓ Branch 0 (6→7) taken 100000 times.
✗ Branch 1 (6→117) not taken.
✗ Branch 2 (8→9) not taken.
✓ Branch 3 (8→16) taken 100000 times.
✗ Branch 4 (9→10) not taken.
✗ Branch 5 (9→123) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→120) not taken.
✗ Branch 8 (12→13) not taken.
✗ Branch 9 (12→118) not taken.
✓ Branch 10 (18→19) taken 100000 times.
✗ Branch 11 (18→21) not taken.
|
100000 | ASSERT_NE(nullptr, node); |
54 |
1/2✓ Branch 0 (20→22) taken 100000 times.
✗ Branch 1 (20→127) not taken.
|
100000 | nodes.push_back(node); |
55 |
4/14✓ Branch 0 (22→23) taken 100000 times.
✗ Branch 1 (22→136) not taken.
✓ Branch 2 (23→24) taken 100000 times.
✗ Branch 3 (23→136) not taken.
✗ Branch 4 (25→26) not taken.
✓ Branch 5 (25→33) taken 100000 times.
✗ Branch 6 (26→27) not taken.
✗ Branch 7 (26→133) not taken.
✗ Branch 8 (28→29) not taken.
✗ Branch 9 (28→130) not taken.
✗ Branch 10 (29→30) not taken.
✗ Branch 11 (29→128) not taken.
✓ Branch 12 (35→36) taken 100000 times.
✗ Branch 13 (35→38) not taken.
|
100000 | ASSERT_EQ(i, nodes.at(i)->codeLoc.line); |
56 |
4/14✓ Branch 0 (37→39) taken 100000 times.
✗ Branch 1 (37→146) not taken.
✓ Branch 2 (39→40) taken 100000 times.
✗ Branch 3 (39→137) not taken.
✗ Branch 4 (41→42) not taken.
✓ Branch 5 (41→49) taken 100000 times.
✗ Branch 6 (42→43) not taken.
✗ Branch 7 (42→143) not taken.
✗ Branch 8 (44→45) not taken.
✗ Branch 9 (44→140) not taken.
✗ Branch 10 (45→46) not taken.
✗ Branch 11 (45→138) not taken.
✓ Branch 12 (51→52) taken 100000 times.
✗ Branch 13 (51→54) not taken.
|
100000 | ASSERT_EQ(1, nodes.at(i)->codeLoc.col); |
57 | } | ||
58 | |||
59 | // Check if stats are correct | ||
60 |
3/12✓ Branch 0 (59→60) taken 1 times.
✗ Branch 1 (59→149) not taken.
✗ Branch 2 (61→62) not taken.
✓ Branch 3 (61→69) taken 1 times.
✗ Branch 4 (62→63) not taken.
✗ Branch 5 (62→155) not taken.
✗ Branch 6 (64→65) not taken.
✗ Branch 7 (64→152) not taken.
✗ Branch 8 (65→66) not taken.
✗ Branch 9 (65→150) not taken.
✓ Branch 10 (71→72) taken 1 times.
✗ Branch 11 (71→75) not taken.
|
1 | ASSERT_EQ(NODE_COUNT, alloc.getAllocationCount()); |
61 |
3/12✓ Branch 0 (74→76) taken 1 times.
✗ Branch 1 (74→159) not taken.
✗ Branch 2 (77→78) not taken.
✓ Branch 3 (77→85) taken 1 times.
✗ Branch 4 (78→79) not taken.
✗ Branch 5 (78→166) not taken.
✗ Branch 6 (80→81) not taken.
✗ Branch 7 (80→163) not taken.
✗ Branch 8 (81→82) not taken.
✗ Branch 9 (81→161) not taken.
✓ Branch 10 (87→88) taken 1 times.
✗ Branch 11 (87→90) not taken.
|
1 | ASSERT_EQ(6'000'000, alloc.getTotalAllocatedSize()); |
62 | |||
63 | // Block Allocator gets destructed here and with that, all allocated nodes should be destructed | ||
64 |
2/4✓ Branch 0 (92→93) taken 1 times.
✗ Branch 1 (92→94) not taken.
✓ Branch 2 (96→97) taken 1 times.
✗ Branch 3 (96→99) not taken.
|
1 | } |
65 | |||
66 |
3/12✓ Branch 0 (98→100) taken 1 times.
✗ Branch 1 (98→183) not taken.
✗ Branch 2 (101→102) not taken.
✓ Branch 3 (101→109) taken 1 times.
✗ Branch 4 (102→103) not taken.
✗ Branch 5 (102→180) not taken.
✗ Branch 6 (104→105) not taken.
✗ Branch 7 (104→177) not taken.
✗ Branch 8 (105→106) not taken.
✗ Branch 9 (105→175) not taken.
✓ Branch 10 (111→112) taken 1 times.
✗ Branch 11 (111→114) not taken.
|
1 | ASSERT_EQ(NODE_COUNT, destructedDummyNodes); |
67 | } | ||
68 | |||
69 | 4 | TEST(BlockAllocatorTest, TestBlockAllocatorUnevenBlockSize) { | |
70 | 1 | destructedDummyNodes = 0; // Reset destruction counter | |
71 | static constexpr size_t NODE_COUNT = 1'000; // 1.000 * 48 bytes = 48 KB | ||
72 | |||
73 | { | ||
74 | // Create allocator, that can hold 4.5 nodes per block | ||
75 | 1 | constexpr DefaultMemoryManager memoryManager; | |
76 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→174) not taken.
|
1 | BlockAllocator<ASTNode> alloc(memoryManager, DUMMY_NODE_SIZE * 4.5); |
77 | |||
78 | // Allocate nodes | ||
79 | 1 | std::vector<ASTNode *> nodes; | |
80 |
2/2✓ Branch 0 (57→4) taken 1000 times.
✓ Branch 1 (57→58) taken 1 times.
|
1001 | for (size_t i = 0; i < NODE_COUNT; i++) { |
81 |
2/4✓ Branch 0 (4→5) taken 1000 times.
✗ Branch 1 (4→116) not taken.
✓ Branch 2 (5→6) taken 1000 times.
✗ Branch 3 (5→116) not taken.
|
1000 | auto node = alloc.allocate<DummyNode>(CodeLoc(i, 1)); |
82 |
3/12✓ Branch 0 (6→7) taken 1000 times.
✗ Branch 1 (6→117) not taken.
✗ Branch 2 (8→9) not taken.
✓ Branch 3 (8→16) taken 1000 times.
✗ Branch 4 (9→10) not taken.
✗ Branch 5 (9→123) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→120) not taken.
✗ Branch 8 (12→13) not taken.
✗ Branch 9 (12→118) not taken.
✓ Branch 10 (18→19) taken 1000 times.
✗ Branch 11 (18→21) not taken.
|
1000 | ASSERT_NE(nullptr, node); |
83 |
1/2✓ Branch 0 (20→22) taken 1000 times.
✗ Branch 1 (20→127) not taken.
|
1000 | nodes.push_back(node); |
84 |
4/14✓ Branch 0 (22→23) taken 1000 times.
✗ Branch 1 (22→136) not taken.
✓ Branch 2 (23→24) taken 1000 times.
✗ Branch 3 (23→136) not taken.
✗ Branch 4 (25→26) not taken.
✓ Branch 5 (25→33) taken 1000 times.
✗ Branch 6 (26→27) not taken.
✗ Branch 7 (26→133) not taken.
✗ Branch 8 (28→29) not taken.
✗ Branch 9 (28→130) not taken.
✗ Branch 10 (29→30) not taken.
✗ Branch 11 (29→128) not taken.
✓ Branch 12 (35→36) taken 1000 times.
✗ Branch 13 (35→38) not taken.
|
1000 | ASSERT_EQ(i, nodes.at(i)->codeLoc.line); |
85 |
4/14✓ Branch 0 (37→39) taken 1000 times.
✗ Branch 1 (37→146) not taken.
✓ Branch 2 (39→40) taken 1000 times.
✗ Branch 3 (39→137) not taken.
✗ Branch 4 (41→42) not taken.
✓ Branch 5 (41→49) taken 1000 times.
✗ Branch 6 (42→43) not taken.
✗ Branch 7 (42→143) not taken.
✗ Branch 8 (44→45) not taken.
✗ Branch 9 (44→140) not taken.
✗ Branch 10 (45→46) not taken.
✗ Branch 11 (45→138) not taken.
✓ Branch 12 (51→52) taken 1000 times.
✗ Branch 13 (51→54) not taken.
|
1000 | ASSERT_EQ(1, nodes.at(i)->codeLoc.col); |
86 | } | ||
87 | |||
88 | // Check if stats are correct | ||
89 |
3/12✓ Branch 0 (59→60) taken 1 times.
✗ Branch 1 (59→149) not taken.
✗ Branch 2 (61→62) not taken.
✓ Branch 3 (61→69) taken 1 times.
✗ Branch 4 (62→63) not taken.
✗ Branch 5 (62→155) not taken.
✗ Branch 6 (64→65) not taken.
✗ Branch 7 (64→152) not taken.
✗ Branch 8 (65→66) not taken.
✗ Branch 9 (65→150) not taken.
✓ Branch 10 (71→72) taken 1 times.
✗ Branch 11 (71→75) not taken.
|
1 | ASSERT_EQ(NODE_COUNT, alloc.getAllocationCount()); |
90 |
3/12✓ Branch 0 (74→76) taken 1 times.
✗ Branch 1 (74→159) not taken.
✗ Branch 2 (77→78) not taken.
✓ Branch 3 (77→85) taken 1 times.
✗ Branch 4 (78→79) not taken.
✗ Branch 5 (78→166) not taken.
✗ Branch 6 (80→81) not taken.
✗ Branch 7 (80→163) not taken.
✗ Branch 8 (81→82) not taken.
✗ Branch 9 (81→161) not taken.
✓ Branch 10 (87→88) taken 1 times.
✗ Branch 11 (87→90) not taken.
|
1 | ASSERT_EQ(54'000, alloc.getTotalAllocatedSize()); |
91 | |||
92 | // Block Allocator gets destructed here and with that, all allocated nodes should be destructed | ||
93 |
2/4✓ Branch 0 (92→93) taken 1 times.
✗ Branch 1 (92→94) not taken.
✓ Branch 2 (96→97) taken 1 times.
✗ Branch 3 (96→99) not taken.
|
1 | } |
94 | |||
95 |
3/12✓ Branch 0 (98→100) taken 1 times.
✗ Branch 1 (98→183) not taken.
✗ Branch 2 (101→102) not taken.
✓ Branch 3 (101→109) taken 1 times.
✗ Branch 4 (102→103) not taken.
✗ Branch 5 (102→180) not taken.
✗ Branch 6 (104→105) not taken.
✗ Branch 7 (104→177) not taken.
✗ Branch 8 (105→106) not taken.
✗ Branch 9 (105→175) not taken.
✓ Branch 10 (111→112) taken 1 times.
✗ Branch 11 (111→114) not taken.
|
1 | ASSERT_EQ(NODE_COUNT, destructedDummyNodes); |
96 | } | ||
97 | |||
98 | 4 | TEST(BlockAllocatorTest, TestBlockAllocatorOOM) { | |
99 | 1 | destructedDummyNodes = 0; // Reset destruction counter | |
100 | static constexpr size_t NODE_COUNT = 10; // 10 * 48 bytes = 0.48 KB | ||
101 | |||
102 | // Prepare mock methods | ||
103 |
1/2✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→278) not taken.
|
1 | MockMemoryManager mockMemoryManager; |
104 | |||
105 | // Make sure, that the memory manager returns nullptr when trying to allocate the fifth block | ||
106 |
1/2✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→276) not taken.
|
1 | ::testing::InSequence s; |
107 | 4 | auto mallocCallback = [](size_t size) { return static_cast<byte *>(malloc(size)); }; | |
108 |
7/14✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→142) not taken.
✓ Branch 2 (5→6) taken 1 times.
✗ Branch 3 (5→140) not taken.
✓ Branch 4 (6→7) taken 1 times.
✗ Branch 5 (6→137) not taken.
✓ Branch 6 (8→9) taken 1 times.
✗ Branch 7 (8→137) not taken.
✓ Branch 8 (9→10) taken 1 times.
✗ Branch 9 (9→137) not taken.
✓ Branch 10 (10→11) taken 1 times.
✗ Branch 11 (10→136) not taken.
✓ Branch 12 (11→12) taken 1 times.
✗ Branch 13 (11→134) not taken.
|
1 | EXPECT_CALL(mockMemoryManager, allocate(::testing::_)).Times(4).WillRepeatedly(mallocCallback); |
109 |
8/16✓ Branch 0 (15→16) taken 1 times.
✗ Branch 1 (15→153) not taken.
✓ Branch 2 (16→17) taken 1 times.
✗ Branch 3 (16→151) not taken.
✓ Branch 4 (17→18) taken 1 times.
✗ Branch 5 (17→148) not taken.
✓ Branch 6 (19→20) taken 1 times.
✗ Branch 7 (19→148) not taken.
✓ Branch 8 (20→21) taken 1 times.
✗ Branch 9 (20→148) not taken.
✓ Branch 10 (21→22) taken 1 times.
✗ Branch 11 (21→146) not taken.
✓ Branch 12 (22→23) taken 1 times.
✗ Branch 13 (22→146) not taken.
✓ Branch 14 (23→24) taken 1 times.
✗ Branch 15 (23→144) not taken.
|
1 | EXPECT_CALL(mockMemoryManager, allocate(::testing::_)).Times(1).WillOnce(::testing::Return(nullptr)); |
110 |
7/14✓ Branch 0 (27→28) taken 1 times.
✗ Branch 1 (27→164) not taken.
✓ Branch 2 (28→29) taken 1 times.
✗ Branch 3 (28→162) not taken.
✓ Branch 4 (29→30) taken 1 times.
✗ Branch 5 (29→159) not taken.
✓ Branch 6 (31→32) taken 1 times.
✗ Branch 7 (31→159) not taken.
✓ Branch 8 (32→33) taken 1 times.
✗ Branch 9 (32→159) not taken.
✓ Branch 10 (34→35) taken 1 times.
✗ Branch 11 (34→157) not taken.
✓ Branch 12 (35→36) taken 1 times.
✗ Branch 13 (35→155) not taken.
|
1 | EXPECT_CALL(mockMemoryManager, deallocate(::testing::_)).Times(4).WillRepeatedly(::testing::Invoke(free)); |
111 | |||
112 | { | ||
113 | // Create allocator, that can hold 2 nodes per block | ||
114 |
1/2✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→263) not taken.
|
1 | BlockAllocator<ASTNode> alloc(mockMemoryManager, DUMMY_NODE_SIZE * 2.25); |
115 | |||
116 | try { | ||
117 | // Allocate nodes | ||
118 | 1 | std::vector<ASTNode *> nodes; | |
119 |
1/2✓ Branch 0 (94→41) taken 9 times.
✗ Branch 1 (94→95) not taken.
|
9 | for (size_t i = 0; i < NODE_COUNT; i++) { |
120 |
3/4✓ Branch 0 (41→42) taken 9 times.
✗ Branch 1 (41→166) not taken.
✓ Branch 2 (42→43) taken 8 times.
✓ Branch 3 (42→166) taken 1 times.
|
9 | auto node = alloc.allocate<DummyNode>(CodeLoc(i, 1)); |
121 |
3/12✓ Branch 0 (43→44) taken 8 times.
✗ Branch 1 (43→167) not taken.
✗ Branch 2 (45→46) not taken.
✓ Branch 3 (45→53) taken 8 times.
✗ Branch 4 (46→47) not taken.
✗ Branch 5 (46→173) not taken.
✗ Branch 6 (48→49) not taken.
✗ Branch 7 (48→170) not taken.
✗ Branch 8 (49→50) not taken.
✗ Branch 9 (49→168) not taken.
✓ Branch 10 (55→56) taken 8 times.
✗ Branch 11 (55→58) not taken.
|
8 | ASSERT_NE(nullptr, node); |
122 |
1/2✓ Branch 0 (57→59) taken 8 times.
✗ Branch 1 (57→177) not taken.
|
8 | nodes.push_back(node); |
123 |
4/14✓ Branch 0 (59→60) taken 8 times.
✗ Branch 1 (59→186) not taken.
✓ Branch 2 (60→61) taken 8 times.
✗ Branch 3 (60→186) not taken.
✗ Branch 4 (62→63) not taken.
✓ Branch 5 (62→70) taken 8 times.
✗ Branch 6 (63→64) not taken.
✗ Branch 7 (63→183) not taken.
✗ Branch 8 (65→66) not taken.
✗ Branch 9 (65→180) not taken.
✗ Branch 10 (66→67) not taken.
✗ Branch 11 (66→178) not taken.
✓ Branch 12 (72→73) taken 8 times.
✗ Branch 13 (72→75) not taken.
|
8 | ASSERT_EQ(i, nodes.at(i)->codeLoc.line); |
124 |
4/14✓ Branch 0 (74→76) taken 8 times.
✗ Branch 1 (74→196) not taken.
✓ Branch 2 (76→77) taken 8 times.
✗ Branch 3 (76→187) not taken.
✗ Branch 4 (78→79) not taken.
✓ Branch 5 (78→86) taken 8 times.
✗ Branch 6 (79→80) not taken.
✗ Branch 7 (79→193) not taken.
✗ Branch 8 (81→82) not taken.
✗ Branch 9 (81→190) not taken.
✗ Branch 10 (82→83) not taken.
✗ Branch 11 (82→188) not taken.
✓ Branch 12 (88→89) taken 8 times.
✗ Branch 13 (88→91) not taken.
|
8 | ASSERT_EQ(1, nodes.at(i)->codeLoc.col); |
125 | } | ||
126 | − | FAIL(); // LCOV_EXCL_LINE - Should not reach this point | |
127 |
1/2✗ Branch 0 (208→209) not taken.
✓ Branch 1 (208→210) taken 1 times.
|
2 | } catch (CompilerError &ce) { |
128 |
1/2✓ Branch 0 (211→212) taken 1 times.
✗ Branch 1 (211→258) not taken.
|
1 | std::stringstream ss; |
129 |
1/2✓ Branch 0 (212→213) taken 1 times.
✗ Branch 1 (212→256) not taken.
|
1 | ss << "[Error|Compiler]:\n"; |
130 |
1/2✓ Branch 0 (213→214) taken 1 times.
✗ Branch 1 (213→256) not taken.
|
1 | ss << "An out of memory error occurred: Could not allocate memory for BlockAllocator. Already allocated 4 blocks."; |
131 |
4/14✓ Branch 0 (215→216) taken 1 times.
✗ Branch 1 (215→245) not taken.
✓ Branch 2 (216→217) taken 1 times.
✗ Branch 3 (216→243) not taken.
✗ Branch 4 (219→220) not taken.
✓ Branch 5 (219→227) taken 1 times.
✗ Branch 6 (220→221) not taken.
✗ Branch 7 (220→252) not taken.
✗ Branch 8 (222→223) not taken.
✗ Branch 9 (222→249) not taken.
✗ Branch 10 (223→224) not taken.
✗ Branch 11 (223→247) not taken.
✓ Branch 12 (229→230) taken 1 times.
✗ Branch 13 (229→232) not taken.
|
1 | ASSERT_EQ(ss.str(), ce.what()); |
132 |
2/4✓ Branch 0 (234→235) taken 1 times.
✗ Branch 1 (234→237) not taken.
✓ Branch 2 (239→240) taken 1 times.
✗ Branch 3 (239→241) not taken.
|
2 | } |
133 | |||
134 | // Block Allocator gets destructed here and with that, all allocated nodes should be destructed | ||
135 |
1/2✓ Branch 0 (104→105) taken 1 times.
✗ Branch 1 (104→107) not taken.
|
1 | } |
136 | |||
137 |
3/12✓ Branch 0 (106→108) taken 1 times.
✗ Branch 1 (106→264) not taken.
✗ Branch 2 (109→110) not taken.
✓ Branch 3 (109→117) taken 1 times.
✗ Branch 4 (110→111) not taken.
✗ Branch 5 (110→270) not taken.
✗ Branch 6 (112→113) not taken.
✗ Branch 7 (112→267) not taken.
✗ Branch 8 (113→114) not taken.
✗ Branch 9 (113→265) not taken.
✓ Branch 10 (119→120) taken 1 times.
✗ Branch 11 (119→122) not taken.
|
1 | ASSERT_EQ(8, destructedDummyNodes); // Only 8 blocks were constructed until the OOM error occurred |
138 |
1/2✓ Branch 0 (121→123) taken 1 times.
✗ Branch 1 (121→274) not taken.
|
1 | ::testing::Mock::VerifyAndClearExpectations(&mockMemoryManager); |
139 |
2/4✓ Branch 0 (125→126) taken 1 times.
✗ Branch 1 (125→127) not taken.
✓ Branch 2 (129→130) taken 1 times.
✗ Branch 3 (129→132) not taken.
|
1 | } |
140 | |||
141 | } // namespace spice::testing | ||
142 |