|
67 | 67 | except ImportError: |
68 | 68 | TEMPLATES = [] |
69 | 69 |
|
| 70 | +try: |
| 71 | + from fusil.python import tricky_cereggii |
| 72 | + _HAS_TRICKY_CEREGGII = True |
| 73 | + print("Loaded tricky_cereggii aggregator for ArgumentGenerator.") |
| 74 | +except ImportError: |
| 75 | + _HAS_TRICKY_CEREGGII = False |
| 76 | + print("Warning: Could not load tricky_cereggii aggregator for ArgumentGenerator.") |
| 77 | + tricky_cereggii = None # Define for type checking |
| 78 | + |
70 | 79 | try: |
71 | 80 | import numpy |
72 | 81 | except ImportError: |
@@ -107,6 +116,10 @@ def __init__( |
107 | 116 | self.filenames = filenames |
108 | 117 | self.errback_name = ERRBACK_NAME_CONST |
109 | 118 |
|
| 119 | + is_cereggii_target = ( |
| 120 | + self.options.modules == "cereggii" or getattr(self.options, "fuzz_cereggii_scenarios", False) |
| 121 | + ) |
| 122 | + |
110 | 123 | self.h5py_argument_generator = H5PyArgumentGenerator(self) if use_h5py and H5PyArgumentGenerator else None |
111 | 124 |
|
112 | 125 | # Initialize generators for various data types |
@@ -158,6 +171,35 @@ def __init__( |
158 | 171 | self.genTrickyObjects, |
159 | 172 | ) |
160 | 173 |
|
| 174 | + if is_cereggii_target and _HAS_TRICKY_CEREGGII: |
| 175 | + print("Activating cereggii-specific argument generators...") |
| 176 | + # Add hashable cereggii objects |
| 177 | + self.hashable_argument_generators += ( |
| 178 | + self.genTrickyAtomicInt64, # AtomicInt64 is hashable |
| 179 | + self.genTrickyHashableKeyCereggii, # Keys specifically chosen for hashability |
| 180 | + ) * 10 # Weight: make them appear reasonably often |
| 181 | + |
| 182 | + # Add simple (potentially non-hashable) cereggii objects |
| 183 | + self.simple_argument_generators += ( |
| 184 | + self.genTrickyWeirdCereggii, |
| 185 | + self.genTrickyRecursiveCereggii, |
| 186 | + self.genTrickyThreadHandle, |
| 187 | + ) * 10 |
| 188 | + |
| 189 | + # Add complex cereggii objects (AtomicDict itself) |
| 190 | + self.complex_argument_generators += ( |
| 191 | + self.genTrickyAtomicDict, |
| 192 | + ) * 10 |
| 193 | + |
| 194 | + # Also add the simple ones to complex, as complex can include simple |
| 195 | + self.complex_argument_generators += ( |
| 196 | + self.genTrickyAtomicInt64, |
| 197 | + self.genTrickyHashableKeyCereggii, |
| 198 | + self.genTrickyWeirdCereggii, |
| 199 | + self.genTrickyRecursiveCereggii, |
| 200 | + self.genTrickyThreadHandle, |
| 201 | + ) * 5 # Lower weight here as they are already in simple |
| 202 | + |
161 | 203 | # Handle NumPy, h5py, and t-strings conditionally |
162 | 204 | if not self.options.no_numpy and use_numpy and H5PyArgumentGenerator: |
163 | 205 | if allow_external_references: |
@@ -289,6 +331,60 @@ def genInterestingValues(self) -> list[str]: |
289 | 331 | """Generate an 'interesting' predefined value.""" |
290 | 332 | return [choice(INTERESTING)] |
291 | 333 |
|
| 334 | + def genTrickyAtomicInt64(self) -> list[str]: |
| 335 | + """Generate a reference to a tricky AtomicInt64 instance.""" |
| 336 | + # Check if the aggregator and its specific list are available |
| 337 | + if not _HAS_TRICKY_CEREGGII or not tricky_cereggii or not tricky_cereggii.tricky_atomicint64_instance_names: |
| 338 | + # Fallback to creating a simple default instance if tricky ones aren't loaded |
| 339 | + return ["cereggii.AtomicInt64(0)"] |
| 340 | + # Select a random name from the aggregated list |
| 341 | + name = choice(tricky_cereggii.tricky_atomicint64_instance_names) |
| 342 | + # Return the code to access it from the dictionary defined in the boilerplate |
| 343 | + # The name 'tricky_atomic_ints' must match the variable in tricky_atomicint64.py |
| 344 | + return [f"tricky_atomic_ints['{name}']"] |
| 345 | + |
| 346 | + def genTrickyAtomicDict(self) -> list[str]: |
| 347 | + """Generate a reference to a tricky AtomicDict instance.""" |
| 348 | + if not _HAS_TRICKY_CEREGGII or not tricky_cereggii or not tricky_cereggii.tricky_atomicdict_instance_names: |
| 349 | + return ["cereggii.AtomicDict()"] # Fallback |
| 350 | + name = choice(tricky_cereggii.tricky_atomicdict_instance_names) |
| 351 | + # Assumes 'tricky_atomic_dicts' dict is defined in boilerplate |
| 352 | + return [f"tricky_atomic_dicts['{name}']"] |
| 353 | + |
| 354 | + def genTrickyWeirdCereggii(self) -> list[str]: |
| 355 | + """Generate a reference to a weird cereggii subclass instance.""" |
| 356 | + if not _HAS_TRICKY_CEREGGII or not tricky_cereggii or not tricky_cereggii.tricky_weird_cereggii_instance_names: |
| 357 | + return ["object()"] # Generic fallback |
| 358 | + name = choice(tricky_cereggii.tricky_weird_cereggii_instance_names) |
| 359 | + # Assumes 'tricky_weird_cereggii_objects' dict is defined in boilerplate |
| 360 | + return [f"tricky_weird_cereggii_objects['{name}']"] |
| 361 | + |
| 362 | + def genTrickyRecursiveCereggii(self) -> list[str]: |
| 363 | + """Generate a reference to a tricky recursive cereggii object.""" |
| 364 | + if not _HAS_TRICKY_CEREGGII or not tricky_cereggii or not tricky_cereggii.tricky_recursive_object_names: |
| 365 | + return ["['recursive_fallback']"] # Fallback |
| 366 | + name = choice(tricky_cereggii.tricky_recursive_object_names) |
| 367 | + # Assumes 'tricky_recursive_objects' dict is defined in boilerplate |
| 368 | + return [f"tricky_recursive_objects['{name}']"] |
| 369 | + |
| 370 | + def genTrickyThreadHandle(self) -> list[str]: |
| 371 | + """Generate a reference to a tricky ThreadHandle instance or callable.""" |
| 372 | + if not _HAS_TRICKY_CEREGGII or not tricky_cereggii or not tricky_cereggii.tricky_threadhandle_instance_names: |
| 373 | + # Fallback needs a valid object to wrap |
| 374 | + return ["cereggii.ThreadHandle(None)"] |
| 375 | + name = choice(tricky_cereggii.tricky_threadhandle_instance_names) |
| 376 | + # Assumes 'tricky_threadhandle_collection' dict is defined in boilerplate |
| 377 | + return [f"tricky_threadhandle_collection['{name}']"] |
| 378 | + |
| 379 | + def genTrickyHashableKeyCereggii(self) -> list[str]: |
| 380 | + """Generate a reference to a tricky but hashable object for use as a dict key.""" |
| 381 | + # Use the specific list aggregated in tricky_atomicdict.py |
| 382 | + if not _HAS_TRICKY_CEREGGII or not tricky_cereggii or not tricky_cereggii.tricky_hashable_key_names: |
| 383 | + return ["'fallback_key'"] # Fallback to a simple string |
| 384 | + name = choice(tricky_cereggii.tricky_hashable_key_names) |
| 385 | + # Assumes 'tricky_hashable_keys' dict is defined in boilerplate |
| 386 | + return [f"tricky_hashable_keys['{name}']"] |
| 387 | + |
292 | 388 | def genTrickyObjects(self) -> list[str]: |
293 | 389 | """Generate a name of a 'tricky' predefined object from tricky_weird.""" |
294 | 390 | tricky_name = choice(fusil.python.tricky_weird.tricky_objects_names) |
|
0 commit comments