@@ -14,101 +14,102 @@ Y_UNIT_TEST_SUITE(PhantomBlobs) {
1414 };
1515
1616 struct TTestCtx : public TTestCtxBase {
17- TTestCtx (TEnvironmentSetup::TSettings settings)
18- : TTestCtxBase(std::move(settings)) {
17+ TTestCtx (TEnvironmentSetup::TSettings settings, ui32 initialBlobs, ui32 unsyncedBlobs,
18+ std::vector<ENodeState> NodeStates)
19+ : TTestCtxBase(std::move(settings))
20+ , InitialBlobCount(initialBlobs)
21+ , UnsyncedBlobCount(unsyncedBlobs)
22+ , NodeStates(NodeStates)
23+ {
24+ Y_VERIFY (NodeStates.size () == NodeCount);
1925 }
2026
21- void RunTest (ui32 initialBlobs, ui32 unsyncedBlobs, std::vector<ENodeState> nodeStates) {
22- Y_VERIFY (nodeStates.size () == NodeCount);
23- const ui64 blobSize = 10 ;
24- const ui32 unsyncedBatchSize = 1000 ;
25- Initialize ();
26-
27- ui64 tabletId = 5000 ;
28- ui32 channel = 1 ;
29- ui32 generation = 1 ;
30- ui32 step = 1 ;
31- ui32 perGenCtr = 1 ;
32-
27+ std::vector<TLogoBlobID> WriteInitialData () {
3328 Ctest << " Write blobs" << Endl;
3429 std::vector<TLogoBlobID> blobs = WriteCompressedData (TDataProfile{
3530 .GroupId = GroupId,
36- .TotalBlobs = initialBlobs ,
37- .BlobSize = blobSize ,
38- .TabletId = tabletId ,
39- .Channel = channel ,
40- .Generation = generation ,
41- .Step = step ,
31+ .TotalBlobs = InitialBlobCount ,
32+ .BlobSize = BlobSize ,
33+ .TabletId = TabletId ,
34+ .Channel = Channel ,
35+ .Generation = Generation ,
36+ .Step = Step ,
4237 });
4338
44- auto itMiddle = blobs.begin () + blobs.size () / 2 ;
45-
46- auto collectEverything = [&](TVector<TLogoBlobID>* keepFlags, TVector<TLogoBlobID>* doNotKeepFlags) {
47- Env->Runtime ->WrapInActorContext (Edge, [&] {
48- TString data;
49- SendToBSProxy (Edge, GroupId, new TEvBlobStorage::TEvCollectGarbage (
50- tabletId, generation, ++perGenCtr, channel, true , generation, step,
51- keepFlags, doNotKeepFlags, TInstant::Max (), true , false ));
52- });
53- Env->WaitForEdgeActorEvent <TEvBlobStorage::TEvCollectGarbageResult>(
54- Edge, false , TInstant::Max ());
55- };
56-
57- Ctest << " Set Keep flags" << Endl;
58- collectEverything (new TVector<TLogoBlobID>(blobs.begin (), blobs.end ()), nullptr );
39+ return blobs;
40+ }
5941
60- Ctest << " Wait for sync" << Endl;
61- Env->Sim (TDuration::Minutes (30 ));
42+ void CollectBlobs (TVector<TLogoBlobID>* keepFlags, TVector<TLogoBlobID>* doNotKeepFlags) {
43+ Env->Runtime ->WrapInActorContext (Edge, [&] {
44+ TString data;
45+ SendToBSProxy (Edge, GroupId, new TEvBlobStorage::TEvCollectGarbage (
46+ TabletId, Generation, ++GenerationCtr, Channel, true , Generation, Step,
47+ keepFlags, doNotKeepFlags, TInstant::Max (), true , false ));
48+ });
49+ Env->WaitForEdgeActorEvent <TEvBlobStorage::TEvCollectGarbageResult>(
50+ Edge, false , TInstant::Max ());
51+ }
6252
63- Ctest << " Shutdown and restart nodes " << Endl;
53+ void ToggleNodes ( bool stopAndRestart) {
6454 for (ui32 nodeId = 1 ; nodeId <= NodeCount; ++nodeId) {
65- switch (nodeStates [nodeId - 1 ]) {
55+ switch (NodeStates [nodeId - 1 ]) {
6656 case ENodeState::Alive:
6757 break ;
6858 case ENodeState::Dead:
69- Env->StopNode (nodeId);
59+ if (stopAndRestart) {
60+ Ctest << " Stop node# " << nodeId << Endl;
61+ Env->StopNode (nodeId);
62+ } else {
63+ Ctest << " Start node# " << nodeId << Endl;
64+ Env->StartNode (nodeId);
65+ }
7066 break ;
7167 case ENodeState::Restart:
72- Env->StopNode (nodeId);
73- Env->Sim (TDuration::Minutes (1 ));
74- Env->StartNode (nodeId);
68+ if (stopAndRestart) {
69+ Ctest << " Restart node# " << nodeId << Endl;
70+ Env->StopNode (nodeId);
71+ Env->Sim (TDuration::Minutes (1 ));
72+ Env->StartNode (nodeId);
73+ }
7574 break ;
7675 }
7776 Env->Sim (TDuration::Minutes (1 ));
7877 }
79-
80- Ctest << " Wait for sync" << Endl;
81- Env->Sim (TDuration::Minutes (30 ));
82-
8378 AllocateEdgeActor (); // reallocate actor, in case it lived on a restarted or dead node
79+ }
8480
85- Ctest << " Set DoNotKeepFlags on first half of blobs" << Endl;
86- collectEverything (nullptr , new TVector<TLogoBlobID>(blobs.begin (), itMiddle));
87-
88- for (ui32 i = 0 ; i < unsyncedBlobs; i += unsyncedBatchSize) {
89- Ctest << " Write batch, blobs written# " << i << Endl;
90- generation += 10 ;
81+ void WriteUnsyncedBlobs () {
82+ for (ui32 i = 0 ; i < UnsyncedBlobCount; i += UnsyncedBatchSize) {
83+ Ctest << " Write unsynced blobs batch, blobs written# " << i << Endl;
84+ Generation += 10 ;
9185 std::vector<TLogoBlobID> batch = WriteCompressedData (TDataProfile{
9286 .GroupId = GroupId,
93- .TotalBlobs = unsyncedBatchSize ,
94- .BlobSize = blobSize ,
87+ .TotalBlobs = UnsyncedBatchSize ,
88+ .BlobSize = BlobSize ,
9589 .BatchSize = 1000 ,
96- .TabletId = tabletId ,
97- .Channel = channel ,
98- .Generation = generation ,
99- .Step = step ,
90+ .TabletId = TabletId ,
91+ .Channel = Channel ,
92+ .Generation = Generation ,
93+ .Step = Step ,
10094 });
101- collectEverything (nullptr , nullptr );
95+ CollectBlobs (nullptr , nullptr );
10296 }
97+ }
98+
99+ void WaitForSync () {
100+ Ctest << " Wait for sync" << Endl;
101+ Env->Sim (TDuration::Minutes (30 ));
102+ }
103103
104- Ctest << " Send TEvBaldSyncLog" << Endl;
104+ void BaldSyncLog () {
105+ Ctest << " Force syncLog trim" << Endl;
105106 const TIntrusivePtr<TBlobStorageGroupInfo> groupInfo = Env->GetGroupInfo (GroupId);
106107 UNIT_ASSERT (groupInfo);
107108 for (ui32 orderNumber = 0 ; orderNumber < groupInfo->Type .BlobSubgroupSize (); ++orderNumber) {
108109 const TActorId actorId = groupInfo->GetActorId (orderNumber);
109110 const TVDiskID vdiskId = groupInfo->GetVDiskId (orderNumber);
110111 const ui32 nodeId = actorId.NodeId ();
111- if (nodeStates [nodeId - 1 ] == ENodeState::Dead) {
112+ if (NodeStates [nodeId - 1 ] == ENodeState::Dead) {
112113 continue ;
113114 }
114115 const TActorId edge = Env->Runtime ->AllocateEdgeActor (actorId.NodeId ());
@@ -118,39 +119,15 @@ Y_UNIT_TEST_SUITE(PhantomBlobs) {
118119 });
119120 Env->WaitForEdgeActorEvent <TEvBlobStorage::TEvVBaldSyncLogResult>(edge, false );
120121 }
122+ }
121123
122- Ctest << " Set DoNotKeepFlags on second half of blobs" << Endl;
123- collectEverything (nullptr , new TVector<TLogoBlobID>(itMiddle, blobs.end ()));
124-
125- Ctest << " Wait for sync" << Endl;
126- Env->Sim (TDuration::Minutes (30 ));
127-
128- Ctest << " Enable nodes" << Endl;
129- for (ui32 nodeId = 1 ; nodeId <= NodeCount; ++nodeId) {
130- if (nodeStates[nodeId - 1 ] == ENodeState::Dead) {
131- Env->StartNode (nodeId);
132- }
133- }
134-
135- Ctest << " Wait for sync" << Endl;
136- Env->Sim (TDuration::Minutes (30 ));
137-
138- ++generation;
139- Ctest << " Move soft barrier" << Endl;
140- collectEverything (nullptr , nullptr );
141-
142- Env->Sim (TDuration::Minutes (30 ));
143-
144- // Env->Runtime->FilterFunction = [&](ui32, std::unique_ptr<IEventHandle>& ev) {
145- // Cerr << " --- " << ev->Sender << "->" << ev->Recipient << ev->ToString() << Endl;
146- // return true;
147- // };
148-
124+ void CheckStatus () {
149125 auto status = GetGroupStatus (GroupId);
150126 Ctest << " Group status# " << status->ToString () << Endl;
127+ }
151128
129+ void CheckBlobs (const std::vector<TLogoBlobID>& blobs) {
152130 Ctest << " Get group configuration" << Endl;
153-
154131 TIntrusivePtr<TBlobStorageGroupInfo> group = Env->GetGroupInfo (GroupId);
155132
156133 Ctest << " Check blobs" << Endl;
@@ -173,11 +150,61 @@ Y_UNIT_TEST_SUITE(PhantomBlobs) {
173150 UNIT_ASSERT_C (!record.GetResult (0 ).HasIngress (), res->ToString ());
174151 }
175152 }
176- TLogoBlobID from (tabletId , 0 , 0 , channel , 0 , 0 , 1 );
177- TLogoBlobID to (tabletId, generation + 100 , 9000 , channel , TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie, TLogoBlobID::MaxPartId);
153+ TLogoBlobID from (TabletId , 0 , 0 , Channel , 0 , 0 , 1 );
154+ TLogoBlobID to (TabletId, Generation + 100 , 9000 , Channel , TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie, TLogoBlobID::MaxPartId);
178155 });
179156 }
180157 }
158+
159+ void RunTest () {
160+ Initialize ();
161+ const std::vector<TLogoBlobID> blobs = WriteInitialData ();
162+ auto itMiddle = blobs.begin () + blobs.size () / 2 ;
163+
164+ Ctest << " Set Keep flags" << Endl;
165+ CollectBlobs (new TVector<TLogoBlobID>(blobs.begin (), blobs.end ()), nullptr );
166+ WaitForSync ();
167+
168+ ToggleNodes (true );
169+ WaitForSync ();
170+
171+ Ctest << " Set DoNotKeepFlags on first half of blobs" << Endl;
172+ CollectBlobs (nullptr , new TVector<TLogoBlobID>(blobs.begin (), itMiddle));
173+ WaitForSync ();
174+
175+ WriteUnsyncedBlobs ();
176+
177+ BaldSyncLog ();
178+
179+ Ctest << " Set DoNotKeepFlags on second half of blobs" << Endl;
180+ CollectBlobs (nullptr , new TVector<TLogoBlobID>(itMiddle, blobs.end ()));
181+ WaitForSync ();
182+
183+ ToggleNodes (false );
184+ WaitForSync ();
185+
186+ ++Generation;
187+ Ctest << " Move soft barrier" << Endl;
188+ CollectBlobs (nullptr , nullptr );
189+ WaitForSync ();
190+
191+ CheckStatus ();
192+ CheckBlobs (blobs);
193+ }
194+
195+ public:
196+ const ui64 TabletId = 5000 ;
197+ const ui32 Channel = 1 ;
198+ ui32 Generation = 1 ;
199+ ui32 Step = 1 ;
200+ ui32 GenerationCtr = 1 ;
201+
202+ const ui64 BlobSize = 10 ;
203+ const ui32 UnsyncedBatchSize = 1000 ;
204+
205+ const ui32 InitialBlobCount;
206+ const ui32 UnsyncedBlobCount;
207+ const std::vector<ENodeState> NodeStates;
181208 };
182209
183210 std::vector<ENodeState> GetStatesAllAlive (TBlobStorageGroupType erasure) {
@@ -203,20 +230,20 @@ Y_UNIT_TEST_SUITE(PhantomBlobs) {
203230 return states;
204231 }
205232
206- void Test (TBlobStorageGroupType erasure, std::vector<ENodeState> nodeStates ) {
207- auto it = std::find_if (nodeStates .begin (), nodeStates .end (),
233+ void Test (TBlobStorageGroupType erasure, std::vector<ENodeState> NodeStates ) {
234+ auto it = std::find_if (NodeStates .begin (), NodeStates .end (),
208235 [&](const ENodeState& state) { return state != ENodeState::Dead; } );
209- Y_VERIFY (it != nodeStates .end ());
210- ui32 controllerNodeId = it - nodeStates .begin () + 1 ;
236+ Y_VERIFY (it != NodeStates .end ());
237+ ui32 controllerNodeId = it - NodeStates .begin () + 1 ;
211238 TTestCtx ctx ({
212239 .NodeCount = erasure.BlobSubgroupSize (),
213240 .Erasure = erasure,
214241 .ControllerNodeId = controllerNodeId,
215242 .PDiskChunkSize = 32_MB,
216243 .EnablePhantomFlagStorage = true ,
217244 .TinySyncLog = true ,
218- });
219- ctx.RunTest (1000 , 1000 , nodeStates );
245+ }, 1000 , 1000 , NodeStates );
246+ ctx.RunTest ();
220247 }
221248
222249
0 commit comments