def test_first_n_seeds(self, seed): rng = ast_generator.RngState(seed) run_fuzz.run_fuzz( rng, ast_generator.AstGeneratorOptions( disallow_divide=True, binop_allowlist=[ast.BinopKind.SHLL]), **self.KWARGS)
def test_generate_single_bits_arguments(self): rng = ast_generator.RngState(0) args = ast_generator.generate_arguments( (BitsType(signed=False, size=42), ), rng) self.assertLen(args, 1) self.assertTrue(args[0].is_ubits()) self.assertEqual(args[0].get_bit_count(), 42)
def test_generate_tuple_argument(self): rng = ast_generator.RngState(0) args = ast_generator.generate_arguments((TupleType((BitsType( signed=False, size=123), BitsType(signed=True, size=22))), ), rng) self.assertLen(args, 1) self.assertTrue(args[0].is_tuple()) self.assertEqual(args[0].get_elements()[0].get_bit_count(), 123) self.assertEqual(args[0].get_elements()[1].get_bit_count(), 22)
def test_randrange_biased_towards_zero(self): rng = ast_generator.RngState(0) counter = collections.Counter() for _ in range(16384): counter[rng.randrange_biased_towards_zero(16)] += 1 print(sorted(counter.items())) self.assertTrue(all(k < 16 for k in counter.keys())) self.assertTrue(all(counter[0] > counter[i] for i in range(1, 16)))
def test_generate_array_argument(self): rng = ast_generator.RngState(0) args = ast_generator.generate_arguments( (ArrayType(BitsType(signed=True, size=4), 24), ), rng) self.assertLen(args, 1) self.assertTrue(args[0].is_array()) self.assertLen(args[0].get_elements(), 24) self.assertTrue(args[0].index(0).is_sbits()) self.assertTrue(args[0].index(0).get_bit_count(), 4)
def test_generate_mixed_bits_arguments(self): rng = ast_generator.RngState(0) args = sample_generator.generate_arguments( (BitsType(signed=False, size=123), BitsType(signed=True, size=22)), rng) self.assertLen(args, 2) self.assertTrue(args[0].is_ubits()) self.assertEqual(args[0].get_bit_count(), 123) self.assertTrue(args[1].is_sbits()) self.assertEqual(args[1].get_bit_count(), 22)
def setup_worker(): """Creates arguments to repeatedly pass to benchmark_worker.""" rng = ast_generator.RngState(0) smp = ast_generator.generate_sample( ast_generator.AstGeneratorOptions(disallow_divide=DISALLOW_DIVIDE), CALLS_PER_SAMPLE, sample.SampleOptions(convert_to_ir=True, optimize_ir=True, codegen=FLAGS.codegen, simulate=FLAGS.simulate), rng) run_dir = tempfile.mkdtemp('run_fuzz_') return (run_dir, smp)
def test_generate_codegen_sample(self): rng = ast_generator.RngState(0) sample = sample_generator.generate_sample( rng, ast_generator.AstGeneratorOptions(), calls_per_sample=0, default_options=SampleOptions( convert_to_ir=True, optimize_ir=True, codegen=True, simulate=True)) self.assertTrue(sample.options.input_is_dslx) self.assertTrue(sample.options.convert_to_ir) self.assertTrue(sample.options.optimize_ir) self.assertTrue(sample.options.codegen) self.assertTrue(sample.options.simulate) self.assertNotEmpty(sample.options.codegen_args) self.assertEmpty(sample.args_batch)
def test_generate_basic_sample(self): rng = ast_generator.RngState(0) sample = sample_generator.generate_sample( rng, ast_generator.AstGeneratorOptions(), calls_per_sample=3, default_options=SampleOptions( convert_to_ir=True, optimize_ir=True, codegen=False, simulate=False)) self.assertTrue(sample.options.input_is_dslx) self.assertTrue(sample.options.convert_to_ir) self.assertTrue(sample.options.optimize_ir) self.assertFalse(sample.options.codegen) self.assertFalse(sample.options.simulate) self.assertLen(sample.args_batch, 3) self.assertIn('fn main', sample.input_text)
def test_generate_empty_arguments(self): rng = ast_generator.RngState(0) self.assertEqual(ast_generator.generate_arguments((), rng), ())
def test_first_n_seeds(self, seed): run_fuzz.run_fuzz(ast_generator.RngState(seed), self._get_ast_options(), **self.KWARGS)
def test_repeatable_within_process(self): samples0 = run_fuzz.run_fuzz(ast_generator.RngState(7), self._get_ast_options(), **self.KWARGS) samples1 = run_fuzz.run_fuzz(ast_generator.RngState(7), self._get_ast_options(), **self.KWARGS) self.assertEqual(samples0, samples1)
def do_generator_task(queues: Tuple[mp.Queue, ...], seed: int, ast_generator_options: ast_generator.AstGeneratorOptions, sample_count: int, calls_per_sample: int, default_sample_options: SampleOptions, duration: Optional[datetime.timedelta] = None, print_samples: bool = False) -> int: """Makes DSLX text / args as fuzz samples and pushes them to workers.""" start = datetime.datetime.now() i = 0 rng = ast_generator.RngState(seed) while True: if duration: # Note: duration overrides sample count. if datetime.datetime.now() - start >= duration: print('-- Hit target generator duration of {}'.format(duration)) sys.stdout.flush() break elif i >= sample_count: print('-- Hit target sample_count of {}'.format(sample_count)) sys.stdout.flush() break if i != 0 and i % len(queues) == 0: delta = datetime.datetime.now() - start elapsed = delta.total_seconds() print(f'-- Generating sample {i:8,d}; elapsed: {delta}; ' f'aggregate generate samples/s: {i/elapsed:6.2f}') sys.stdout.flush() # Generate a command message. with sample_runner.Timer() as t: sample = sample_generator.generate_sample(rng, ast_generator_options, calls_per_sample, default_sample_options) if print_samples: print_with_linenos(sample.input_text) message = QueueMessage( command=Command.RUN, sample=sample, sampleno=i, generate_sample_ns=t.elapsed_ns) # Cycle through the queues seeing if we can find one to enqueue into. In the # common case where queues are not full it'll happen on the first one. This # helps avoid the case where a single worker gums up other (ready) workers # from receiving samples. queueno = i while True: queue = queues[queueno % len(queues)] try: queue.put_nowait(message) except queue_mod.Full: queueno += 1 else: break if (queueno - i) % len(queues) == 0: # Avoid burning this core on spin polling all the time by sleeping for a # millisecond after we've visited all the queues. time.sleep(0.001) # Bump the generated sample count. i += 1 print('-- Putting stop command in worker queues after generating {} samples' .format(i)) sys.stdout.flush() for queue in queues: queue.put(QueueMessage(command=Command.STOP)) print('-- Generator task complete') sys.stdout.flush() return i
def test_a_few_samples(self): run_fuzz.run_fuzz(ast_generator.RngState(0), self._get_options(), **self.KWARGS)
def test_no_codegen(self): kwargs = dict(self.KWARGS) kwargs['codegen'] = False run_fuzz.run_fuzz(ast_generator.RngState(0), self._get_options(kwargs['codegen']), **kwargs)