1+ /*
2+ * Licensed to the Apache Software Foundation (ASF) under one
3+ * or more contributor license agreements. See the NOTICE file
4+ * distributed with this work for additional information
5+ * regarding copyright ownership. The ASF licenses this file
6+ * to you under the Apache License, Version 2.0 (the
7+ * "License"); you may not use this file except in compliance
8+ * with the License. You may obtain a copy of the License at
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing, software
13+ * distributed under the License is distributed on an "AS IS" BASIS,
14+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+ * See the License for the specific language governing permissions and
16+ * limitations under the License.
17+ */
18+
19+ package org .apache .cassandra .guardrails ;
20+
21+ import java .util .Arrays ;
22+ import java .util .Collections ;
23+ import java .util .LinkedHashSet ;
24+ import java .util .Set ;
25+
26+ import com .google .common .collect .ImmutableSet ;
27+ import org .junit .BeforeClass ;
28+ import org .junit .Test ;
29+
30+ import org .apache .cassandra .config .DatabaseDescriptor ;
31+
32+ import static org .junit .Assert .assertEquals ;
33+ import static org .junit .Assert .assertNotNull ;
34+
35+ /**
36+ * Test to verify that the default guardrail values are correctly set
37+ * for HCD, On Prem (DBAaS), and NoProfile configurations via applyConfig and enforceDefault.
38+ */
39+ public class GuardrailsConfigDefaultsTest
40+ {
41+ @ BeforeClass
42+ public static void setup ()
43+ {
44+ // Initialize DatabaseDescriptor with defaults for tests
45+ System .setProperty ("cassandra.config" , "cassandra.yaml" );
46+ DatabaseDescriptor .daemonInitialization ();
47+ }
48+ @ Test
49+ public void testNoProfileDefaults ()
50+ {
51+ testGuardrailDefaults (ProfileType .NO_PROFILE );
52+ }
53+
54+ @ Test
55+ public void testDbaasDefaults ()
56+ {
57+ testGuardrailDefaults (ProfileType .DBAAS );
58+ }
59+
60+ @ Test
61+ public void testHcdDefaults ()
62+ {
63+ testGuardrailDefaults (ProfileType .HCD );
64+ }
65+
66+ private enum ProfileType
67+ {
68+ NO_PROFILE , DBAAS , HCD
69+ }
70+
71+ private void testGuardrailDefaults (ProfileType profileType )
72+ {
73+ // Save current settings
74+ boolean previousDbaas = DatabaseDescriptor .isEmulateDbaasDefaults ();
75+ boolean previousHcd = DatabaseDescriptor .isHcdGuardrailsDefaults ();
76+
77+ try
78+ {
79+ // Set the appropriate profile
80+ switch (profileType )
81+ {
82+ case NO_PROFILE :
83+ DatabaseDescriptor .setEmulateDbaasDefaults (false );
84+ DatabaseDescriptor .setHcdGuardrailsDefaults (false );
85+ break ;
86+ case DBAAS :
87+ DatabaseDescriptor .setEmulateDbaasDefaults (true );
88+ DatabaseDescriptor .setHcdGuardrailsDefaults (false );
89+ break ;
90+ case HCD :
91+ DatabaseDescriptor .setEmulateDbaasDefaults (false );
92+ DatabaseDescriptor .setHcdGuardrailsDefaults (true );
93+ break ;
94+ }
95+
96+ // Create a fresh config and apply defaults
97+ GuardrailsConfig config = new GuardrailsConfig ();
98+ config .applyConfig ();
99+
100+ // Validate the configuration to ensure it's valid
101+ config .validate ();
102+
103+ // Verify the defaults based on the profile
104+ verifyDefaultsForProfile (config , profileType );
105+ }
106+ finally
107+ {
108+ // Restore previous settings
109+ DatabaseDescriptor .setEmulateDbaasDefaults (previousDbaas );
110+ DatabaseDescriptor .setHcdGuardrailsDefaults (previousHcd );
111+ }
112+ }
113+
114+ private void verifyDefaultsForProfile (GuardrailsConfig config , ProfileType profileType )
115+ {
116+ // Test read request guardrails
117+ switch (profileType )
118+ {
119+ case NO_PROFILE :
120+ verifyNoProfileDefaults (config );
121+ break ;
122+ case DBAAS :
123+ verifyDbaasDefaults (config );
124+ break ;
125+ case HCD :
126+ verifyHcdDefaults (config );
127+ break ;
128+ }
129+ }
130+
131+ private void verifyNoProfileDefaults (GuardrailsConfig config )
132+ {
133+ // Read request guardrails
134+ assertEquals ("page_size_failure_threshold_in_kb" , GuardrailsConfig .NO_LIMIT , (int ) config .page_size_failure_threshold_in_kb );
135+ assertEquals ("in_select_cartesian_product_failure_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .in_select_cartesian_product_failure_threshold );
136+ assertEquals ("partition_keys_in_select_failure_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .partition_keys_in_select_failure_threshold );
137+ assertEquals ("tombstone_warn_threshold" , 1000 , (int ) config .tombstone_warn_threshold );
138+ assertEquals ("tombstone_failure_threshold" , 100000 , (int ) config .tombstone_failure_threshold );
139+
140+ // Write request guardrails
141+ assertEquals ("logged_batch_enabled" , true , config .logged_batch_enabled .booleanValue ());
142+ assertEquals ("batch_size_warn_threshold_in_kb" , 64 , (int ) config .batch_size_warn_threshold_in_kb );
143+ assertEquals ("batch_size_fail_threshold_in_kb" , 640 , (int ) config .batch_size_fail_threshold_in_kb );
144+ assertEquals ("unlogged_batch_across_partitions_warn_threshold" , 10 , (int ) config .unlogged_batch_across_partitions_warn_threshold );
145+ assertEquals ("truncate_table_enabled" , true , config .truncate_table_enabled .booleanValue ());
146+ assertEquals ("user_timestamps_enabled" , true , config .user_timestamps_enabled .booleanValue ());
147+ assertEquals ("column_value_size_failure_threshold_in_kb" , -1L , config .column_value_size_failure_threshold_in_kb .longValue ());
148+ assertEquals ("read_before_write_list_operations_enabled" , true , config .read_before_write_list_operations_enabled .booleanValue ());
149+
150+ // Write consistency levels - NoProfile has empty set
151+ assertEquals ("write_consistency_levels_disallowed" , Collections .emptySet (), config .write_consistency_levels_disallowed );
152+
153+ // Schema guardrails
154+ assertEquals ("counter_enabled" , true , config .counter_enabled .booleanValue ());
155+ assertEquals ("fields_per_udt_failure_threshold" , -1L , config .fields_per_udt_failure_threshold .longValue ());
156+ assertEquals ("collection_size_warn_threshold_in_kb" , -1L , config .collection_size_warn_threshold_in_kb .longValue ());
157+ assertEquals ("items_per_collection_warn_threshold" , -1L , config .items_per_collection_warn_threshold .longValue ());
158+ assertEquals ("vector_dimensions_warn_threshold" , -1 , (int ) config .vector_dimensions_warn_threshold );
159+ assertEquals ("vector_dimensions_failure_threshold" , 8192 , (int ) config .vector_dimensions_failure_threshold );
160+ assertEquals ("columns_per_table_failure_threshold" , -1L , config .columns_per_table_failure_threshold .longValue ());
161+ assertEquals ("secondary_index_per_table_failure_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .secondary_index_per_table_failure_threshold );
162+ assertEquals ("sasi_indexes_per_table_failure_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .sasi_indexes_per_table_failure_threshold );
163+ assertEquals ("materialized_view_per_table_failure_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .materialized_view_per_table_failure_threshold );
164+ assertEquals ("tables_warn_threshold" , -1L , config .tables_warn_threshold .longValue ());
165+ assertEquals ("tables_failure_threshold" , -1L , config .tables_failure_threshold .longValue ());
166+
167+ // Table properties
168+ assertEquals ("table_properties_disallowed" , Collections .emptySet (), config .table_properties_disallowed );
169+ assertEquals ("table_properties_ignored" , Collections .emptySet (), config .table_properties_ignored );
170+
171+ // Node status guardrails
172+ assertEquals ("disk_usage_percentage_warn_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .disk_usage_percentage_warn_threshold );
173+ assertEquals ("disk_usage_percentage_failure_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .disk_usage_percentage_failure_threshold );
174+ assertEquals ("disk_usage_max_disk_size_in_gb" , (long ) GuardrailsConfig .NO_LIMIT , config .disk_usage_max_disk_size_in_gb .longValue ());
175+ assertEquals ("partition_size_warn_threshold_in_mb" , 100 , (int ) config .partition_size_warn_threshold_in_mb );
176+
177+ // SAI indexes guardrails
178+ assertEquals ("sai_indexes_per_table_failure_threshold" , GuardrailsConfig .DEFAULT_INDEXES_PER_TABLE_THRESHOLD , (int ) config .sai_indexes_per_table_failure_threshold );
179+ assertEquals ("sai_indexes_total_failure_threshold" , GuardrailsConfig .DEFAULT_INDEXES_TOTAL_THRESHOLD , (int ) config .sai_indexes_total_failure_threshold );
180+
181+ // Offset guardrails
182+ assertEquals ("offset_rows_warn_threshold" , 10000 , (int ) config .offset_rows_warn_threshold );
183+ assertEquals ("offset_rows_failure_threshold" , 20000 , (int ) config .offset_rows_failure_threshold );
184+
185+ // Query filter guardrails
186+ assertEquals ("query_filters_warn_threshold" , -1 , (int ) config .query_filters_warn_threshold );
187+ assertEquals ("query_filters_fail_threshold" , -1 , (int ) config .query_filters_fail_threshold );
188+ }
189+
190+ private void verifyDbaasDefaults (GuardrailsConfig config )
191+ {
192+ // Read request guardrails
193+ assertEquals ("page_size_failure_threshold_in_kb" , 512 , (int ) config .page_size_failure_threshold_in_kb );
194+ assertEquals ("in_select_cartesian_product_failure_threshold" , 25 , (int ) config .in_select_cartesian_product_failure_threshold );
195+ assertEquals ("partition_keys_in_select_failure_threshold" , 20 , (int ) config .partition_keys_in_select_failure_threshold );
196+ assertEquals ("tombstone_warn_threshold" , 1000 , (int ) config .tombstone_warn_threshold );
197+ assertEquals ("tombstone_failure_threshold" , 100000 , (int ) config .tombstone_failure_threshold );
198+
199+ // Write request guardrails
200+ assertEquals ("logged_batch_enabled" , true , config .logged_batch_enabled .booleanValue ());
201+ assertEquals ("batch_size_warn_threshold_in_kb" , 64 , (int ) config .batch_size_warn_threshold_in_kb );
202+ assertEquals ("batch_size_fail_threshold_in_kb" , 640 , (int ) config .batch_size_fail_threshold_in_kb );
203+ assertEquals ("unlogged_batch_across_partitions_warn_threshold" , 10 , (int ) config .unlogged_batch_across_partitions_warn_threshold );
204+ assertEquals ("truncate_table_enabled" , true , config .truncate_table_enabled .booleanValue ());
205+ assertEquals ("user_timestamps_enabled" , true , config .user_timestamps_enabled .booleanValue ());
206+ assertEquals ("column_value_size_failure_threshold_in_kb" , 5 * 1024L , config .column_value_size_failure_threshold_in_kb .longValue ());
207+ assertEquals ("read_before_write_list_operations_enabled" , false , config .read_before_write_list_operations_enabled .booleanValue ());
208+
209+ // Write consistency levels
210+ Set <String > expectedWriteConsistencyLevelsDisallowed = new LinkedHashSet <>(Arrays .asList ("ANY" , "ONE" , "LOCAL_ONE" ));
211+ assertEquals ("write_consistency_levels_disallowed" , expectedWriteConsistencyLevelsDisallowed , config .write_consistency_levels_disallowed );
212+
213+ // Schema guardrails
214+ assertEquals ("counter_enabled" , true , config .counter_enabled .booleanValue ());
215+ assertEquals ("fields_per_udt_failure_threshold" , 10L , config .fields_per_udt_failure_threshold .longValue ());
216+ assertEquals ("collection_size_warn_threshold_in_kb" , 5 * 1024L , config .collection_size_warn_threshold_in_kb .longValue ());
217+ assertEquals ("items_per_collection_warn_threshold" , 20L , config .items_per_collection_warn_threshold .longValue ());
218+ assertEquals ("vector_dimensions_warn_threshold" , -1 , (int ) config .vector_dimensions_warn_threshold );
219+ assertEquals ("vector_dimensions_failure_threshold" , 8192 , (int ) config .vector_dimensions_failure_threshold );
220+ assertEquals ("columns_per_table_failure_threshold" , 50L , config .columns_per_table_failure_threshold .longValue ());
221+ assertEquals ("secondary_index_per_table_failure_threshold" , 1 , (int ) config .secondary_index_per_table_failure_threshold );
222+ assertEquals ("sasi_indexes_per_table_failure_threshold" , 0 , (int ) config .sasi_indexes_per_table_failure_threshold );
223+ assertEquals ("materialized_view_per_table_failure_threshold" , 2 , (int ) config .materialized_view_per_table_failure_threshold );
224+ assertEquals ("tables_warn_threshold" , 100L , config .tables_warn_threshold .longValue ());
225+ assertEquals ("tables_failure_threshold" , 200L , config .tables_failure_threshold .longValue ());
226+
227+ // Table properties
228+ assertEquals ("table_properties_disallowed" , Collections .emptySet (), config .table_properties_disallowed );
229+ assertNotNull ("table_properties_ignored" , config .table_properties_ignored );
230+
231+ // Node status guardrails
232+ assertEquals ("disk_usage_percentage_warn_threshold" , 70 , (int ) config .disk_usage_percentage_warn_threshold );
233+ assertEquals ("disk_usage_percentage_failure_threshold" , 80 , (int ) config .disk_usage_percentage_failure_threshold );
234+ assertEquals ("disk_usage_max_disk_size_in_gb" , (long ) GuardrailsConfig .NO_LIMIT , config .disk_usage_max_disk_size_in_gb .longValue ());
235+ assertEquals ("partition_size_warn_threshold_in_mb" , 100 , (int ) config .partition_size_warn_threshold_in_mb );
236+
237+ // SAI indexes guardrails
238+ assertEquals ("sai_indexes_per_table_failure_threshold" , GuardrailsConfig .DEFAULT_INDEXES_PER_TABLE_THRESHOLD , (int ) config .sai_indexes_per_table_failure_threshold );
239+ assertEquals ("sai_indexes_total_failure_threshold" , GuardrailsConfig .DEFAULT_INDEXES_TOTAL_THRESHOLD , (int ) config .sai_indexes_total_failure_threshold );
240+
241+ // Offset guardrails
242+ assertEquals ("offset_rows_warn_threshold" , 10000 , (int ) config .offset_rows_warn_threshold );
243+ assertEquals ("offset_rows_failure_threshold" , 20000 , (int ) config .offset_rows_failure_threshold );
244+
245+ // Query filter guardrails
246+ assertEquals ("query_filters_warn_threshold" , -1 , (int ) config .query_filters_warn_threshold );
247+ assertEquals ("query_filters_fail_threshold" , -1 , (int ) config .query_filters_fail_threshold );
248+ }
249+
250+ private void verifyHcdDefaults (GuardrailsConfig config )
251+ {
252+ // Read request guardrails
253+ assertEquals ("page_size_failure_threshold_in_kb" , GuardrailsConfig .NO_LIMIT , (int ) config .page_size_failure_threshold_in_kb );
254+ assertEquals ("in_select_cartesian_product_failure_threshold" , 25 , (int ) config .in_select_cartesian_product_failure_threshold );
255+ assertEquals ("partition_keys_in_select_failure_threshold" , 20 , (int ) config .partition_keys_in_select_failure_threshold );
256+ assertEquals ("tombstone_warn_threshold" , 1000 , (int ) config .tombstone_warn_threshold );
257+ assertEquals ("tombstone_failure_threshold" , 100000 , (int ) config .tombstone_failure_threshold );
258+
259+ // Write request guardrails
260+ assertEquals ("logged_batch_enabled" , true , config .logged_batch_enabled .booleanValue ());
261+ assertEquals ("batch_size_warn_threshold_in_kb" , 64 , (int ) config .batch_size_warn_threshold_in_kb );
262+ assertEquals ("batch_size_fail_threshold_in_kb" , 640 , (int ) config .batch_size_fail_threshold_in_kb );
263+ assertEquals ("unlogged_batch_across_partitions_warn_threshold" , 10 , (int ) config .unlogged_batch_across_partitions_warn_threshold );
264+ assertEquals ("truncate_table_enabled" , true , config .truncate_table_enabled .booleanValue ());
265+ assertEquals ("user_timestamps_enabled" , true , config .user_timestamps_enabled .booleanValue ());
266+ assertEquals ("column_value_size_failure_threshold_in_kb" , -1L , config .column_value_size_failure_threshold_in_kb .longValue ());
267+ assertEquals ("read_before_write_list_operations_enabled" , true , config .read_before_write_list_operations_enabled .booleanValue ());
268+
269+ // Write consistency levels
270+ Set <String > expectedWriteConsistencyLevelsDisallowed = new LinkedHashSet <>(Arrays .asList ("ANY" ));
271+ assertEquals ("write_consistency_levels_disallowed" , expectedWriteConsistencyLevelsDisallowed , config .write_consistency_levels_disallowed );
272+
273+ // Schema guardrails
274+ assertEquals ("counter_enabled" , true , config .counter_enabled .booleanValue ());
275+ assertEquals ("fields_per_udt_failure_threshold" , 100L , config .fields_per_udt_failure_threshold .longValue ());
276+ assertEquals ("collection_size_warn_threshold_in_kb" , 10240L , config .collection_size_warn_threshold_in_kb .longValue ());
277+ assertEquals ("items_per_collection_warn_threshold" , 200L , config .items_per_collection_warn_threshold .longValue ());
278+ assertEquals ("vector_dimensions_warn_threshold" , -1 , (int ) config .vector_dimensions_warn_threshold );
279+ assertEquals ("vector_dimensions_failure_threshold" , 8192 , (int ) config .vector_dimensions_failure_threshold );
280+ assertEquals ("columns_per_table_failure_threshold" , 200L , config .columns_per_table_failure_threshold .longValue ());
281+ assertEquals ("secondary_index_per_table_failure_threshold" , 0 , (int ) config .secondary_index_per_table_failure_threshold );
282+ assertEquals ("sasi_indexes_per_table_failure_threshold" , 0 , (int ) config .sasi_indexes_per_table_failure_threshold );
283+ assertEquals ("materialized_view_per_table_failure_threshold" , 0 , (int ) config .materialized_view_per_table_failure_threshold );
284+ assertEquals ("tables_warn_threshold" , 100L , config .tables_warn_threshold .longValue ());
285+ assertEquals ("tables_failure_threshold" , 200L , config .tables_failure_threshold .longValue ());
286+
287+ // Table properties
288+ assertEquals ("table_properties_disallowed" , Collections .emptySet (), config .table_properties_disallowed );
289+ assertEquals ("table_properties_ignored" , Collections .emptySet (), config .table_properties_ignored );
290+
291+ // Node status guardrails
292+ assertEquals ("disk_usage_percentage_warn_threshold" , 70 , (int ) config .disk_usage_percentage_warn_threshold );
293+ assertEquals ("disk_usage_percentage_failure_threshold" , GuardrailsConfig .NO_LIMIT , (int ) config .disk_usage_percentage_failure_threshold );
294+ assertEquals ("disk_usage_max_disk_size_in_gb" , (long ) GuardrailsConfig .NO_LIMIT , config .disk_usage_max_disk_size_in_gb .longValue ());
295+ assertEquals ("partition_size_warn_threshold_in_mb" , 100 , (int ) config .partition_size_warn_threshold_in_mb );
296+
297+ // SAI indexes guardrails
298+ assertEquals ("sai_indexes_per_table_failure_threshold" , GuardrailsConfig .DEFAULT_INDEXES_PER_TABLE_THRESHOLD , (int ) config .sai_indexes_per_table_failure_threshold );
299+ assertEquals ("sai_indexes_total_failure_threshold" , GuardrailsConfig .DEFAULT_INDEXES_TOTAL_THRESHOLD , (int ) config .sai_indexes_total_failure_threshold );
300+
301+ // Offset guardrails
302+ assertEquals ("offset_rows_warn_threshold" , 10000 , (int ) config .offset_rows_warn_threshold );
303+ assertEquals ("offset_rows_failure_threshold" , 20000 , (int ) config .offset_rows_failure_threshold );
304+
305+ // Query filter guardrails
306+ assertEquals ("query_filters_warn_threshold" , -1 , (int ) config .query_filters_warn_threshold );
307+ assertEquals ("query_filters_fail_threshold" , -1 , (int ) config .query_filters_fail_threshold );
308+ }
309+ }
0 commit comments