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