@@ -194,6 +194,83 @@ public void testDiskUsage() throws Throwable
194194 }
195195 }
196196
197+ @ Test
198+ public void testDiskUsageNodetoolDisableWhenDiskIsFullShouldEnableWrites ()
199+ {
200+ schemaChange ("CREATE TABLE %s (k int PRIMARY KEY, v int)" );
201+ String insert = format ("INSERT INTO %s(k, v) VALUES (?, 0)" );
202+
203+ // With both nodes in SPACIOUS state, we can write without warnings nor failures
204+ for (int i = 0 ; i < NUM_ROWS ; i ++)
205+ {
206+ ResultSet rs = driverSession .execute (insert , i );
207+ Assertions .assertThat (rs .getExecutionInfo ().getWarnings ()).isEmpty ();
208+ }
209+
210+ // If the STUFFED node becomes FULL, the writes targeting that node will fail, while the writes targeting
211+ // the node that remains SPACIOUS will keep succeeding without warnings
212+ DiskStateInjection .setState (getCluster (), 2 , DiskUsageState .FULL );
213+ int numFailures = 0 ;
214+ for (int i = 0 ; i < NUM_ROWS ; i ++)
215+ {
216+ try
217+ {
218+ ResultSet rs = driverSession .execute (insert , i );
219+ Assertions .assertThat (rs .getExecutionInfo ().getWarnings ()).isEmpty ();
220+ }
221+ catch (InvalidQueryException e )
222+ {
223+ Assertions .assertThat (e ).hasMessageContaining (FAIL_MESSAGE );
224+ numFailures ++;
225+ }
226+ }
227+ Assertions .assertThat (numFailures ).isGreaterThan (0 ).isLessThan (NUM_ROWS );
228+
229+ // After disabling the guardrail, we should be able to write again.
230+ cluster .get (2 ).runOnInstance (() -> Guardrails .instance .setDataDiskUsagePercentageThreshold (-1 , -1 ));
231+ int stateDissemenationTimeoutSec = 2 * 60 ; // 2 minutes.
232+ Util .spinAssertEquals (true ,
233+ () -> cluster .get (1 ).callOnInstance (() -> !DiskUsageBroadcaster .instance .hasStuffedOrFullNode ()),
234+ stateDissemenationTimeoutSec
235+ );
236+
237+ for (int i = 0 ; i < NUM_ROWS ; i ++)
238+ {
239+ ResultSet rs = driverSession .execute (insert , i );
240+ Assertions .assertThat (rs .getExecutionInfo ().getWarnings ()).isEmpty ();
241+ }
242+
243+ // Re-enabling the guardrail should again cause writes to fail
244+ cluster .get (2 ).runOnInstance (() -> Guardrails .instance .setDataDiskUsagePercentageThreshold (98 , 99 ));
245+ Util .spinAssertEquals (true ,
246+ () -> cluster .get (1 ).callOnInstance (() -> DiskUsageBroadcaster .instance .hasStuffedOrFullNode ()),
247+ stateDissemenationTimeoutSec
248+ );
249+ numFailures = 0 ;
250+ for (int i = 0 ; i < NUM_ROWS ; i ++)
251+ {
252+ try
253+ {
254+ ResultSet rs = driverSession .execute (insert , i );
255+ Assertions .assertThat (rs .getExecutionInfo ().getWarnings ()).isEmpty ();
256+ }
257+ catch (InvalidQueryException e )
258+ {
259+ Assertions .assertThat (e ).hasMessageContaining (FAIL_MESSAGE );
260+ numFailures ++;
261+ }
262+ }
263+ Assertions .assertThat (numFailures ).isGreaterThan (0 ).isLessThan (NUM_ROWS );
264+
265+ // Finally, if both nodes go back to SPACIOUS, all queries will succeed again
266+ DiskStateInjection .setState (getCluster (), 2 , DiskUsageState .SPACIOUS );
267+ for (int i = 0 ; i < NUM_ROWS ; i ++)
268+ {
269+ ResultSet rs = driverSession .execute (insert , i );
270+ Assertions .assertThat (rs .getExecutionInfo ().getWarnings ()).isEmpty ();
271+ }
272+ }
273+
197274 /**
198275 * ByteBuddy rule to override the disk usage state of each node.
199276 */
0 commit comments