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