@@ -4523,4 +4523,101 @@ struct S {
45234523 HasSubstr (" #[fuzz_test] is only valid on a function." )));
45244524}
45254525
4526+ TEST_F (ParserTest, FuzzTestAttributeSingleArg) {
4527+ const char * kProgram = R"(
4528+ #[fuzz_test(domains=`u32:0..1`)]
4529+ fn f(x: u32) {}
4530+ )" ;
4531+ XLS_ASSERT_OK_AND_ASSIGN (std::unique_ptr<Module> module , Parse (kProgram ));
4532+ XLS_ASSERT_OK_AND_ASSIGN (Function * f,
4533+ module ->GetMemberOrError <Function>(" f" ));
4534+ ASSERT_EQ (f->attributes ().size (), 1 );
4535+ EXPECT_EQ (f->attributes ()[0 ]->attribute_kind (), AttributeKind::kFuzzTest );
4536+ ASSERT_EQ (f->attributes ()[0 ]->args ().size (), 1 );
4537+ auto arg = std::get<AttributeData::StringKeyValueArgument>(
4538+ f->attributes ()[0 ]->args ()[0 ]);
4539+ EXPECT_EQ (arg.first , " domains" );
4540+ EXPECT_EQ (arg.second , " u32:0..1" );
4541+ EXPECT_EQ (f->attributes ()[0 ]->ToString (),
4542+ " #[fuzz_test(domains = `u32:0..1`)]" );
4543+ }
4544+
4545+ TEST_F (ParserTest, FuzzTestAttributeComplexArgs) {
4546+ const char * kProgram = R"(
4547+ enum Op : u32 { Add = 0, Sub = 1 }
4548+ #[fuzz_test(domains=`[u32:0, u32:10], [Op::Add, Op::Sub]`)]
4549+ fn f(x: u32[2], op: Op[2]) {}
4550+ )" ;
4551+ XLS_ASSERT_OK_AND_ASSIGN (std::unique_ptr<Module> module , Parse (kProgram ));
4552+ XLS_ASSERT_OK_AND_ASSIGN (Function * f,
4553+ module ->GetMemberOrError <Function>(" f" ));
4554+ ASSERT_EQ (f->attributes ().size (), 1 );
4555+ EXPECT_EQ (f->attributes ()[0 ]->attribute_kind (), AttributeKind::kFuzzTest );
4556+ ASSERT_EQ (f->attributes ()[0 ]->args ().size (), 1 );
4557+ auto arg = std::get<AttributeData::StringKeyValueArgument>(
4558+ f->attributes ()[0 ]->args ()[0 ]);
4559+ EXPECT_EQ (arg.first , " domains" );
4560+ EXPECT_EQ (arg.second , " [u32:0, u32:10], [Op::Add, Op::Sub]" );
4561+ }
4562+
4563+ TEST_F (ParserTest, FuzzTestAttributeInvalidNoDomains) {
4564+ const char * kProgram = R"(
4565+ #[fuzz_test(`u32:0..1`)]
4566+ fn f(x: u32) {}
4567+ )" ;
4568+ EXPECT_THAT (Parse (kProgram ),
4569+ StatusIs (absl::StatusCode::kInvalidArgument ,
4570+ HasSubstr (" Expected attribute argument." )));
4571+ }
4572+
4573+ TEST_F (ParserTest, FuzzTestAttributeInvalidNoList) {
4574+ const char * kProgram = R"(
4575+ #[fuzz_test()]
4576+ fn f(x: u32) {}
4577+ )" ;
4578+ EXPECT_THAT (Parse (kProgram ),
4579+ StatusIs (absl::StatusCode::kInvalidArgument ,
4580+ HasSubstr (" Expected attribute argument." )));
4581+ }
4582+
4583+ TEST_F (ParserTest, FuzzTestAttributeInvalidInteger) {
4584+ const char * kProgram = R"(
4585+ #[fuzz_test(domains=1)]
4586+ fn f(x: u32) {}
4587+ )" ;
4588+ EXPECT_THAT (Parse (kProgram ),
4589+ StatusIs (absl::StatusCode::kInvalidArgument ,
4590+ HasSubstr (" that is a backtick-quoted DSLX tuple" )));
4591+ }
4592+
4593+ TEST_F (ParserTest, FuzzTestInvalidArgInvalidInteger) {
4594+ const char * kProgram = R"(
4595+ #[fuzz_test(foo=1)]
4596+ fn f(x: u32) {}
4597+ )" ;
4598+ EXPECT_THAT (Parse (kProgram ),
4599+ StatusIs (absl::StatusCode::kInvalidArgument ,
4600+ HasSubstr (" that is a backtick-quoted DSLX tuple" )));
4601+ }
4602+
4603+ TEST_F (ParserTest, FuzzTestAttributeNoDomainInteger) {
4604+ const char * kProgram = R"(
4605+ #[fuzz_test(1)]
4606+ fn f(x: u32) {}
4607+ )" ;
4608+ EXPECT_THAT (Parse (kProgram ),
4609+ StatusIs (absl::StatusCode::kInvalidArgument ,
4610+ HasSubstr (" Expected attribute argument" )));
4611+ }
4612+
4613+ TEST_F (ParserTest, FuzzTestAttributeInvalidArgName) {
4614+ const char * kProgram = R"(
4615+ #[fuzz_test(foo=`u32:0..1`)]
4616+ fn f(x: u32) {}
4617+ )" ;
4618+ EXPECT_THAT (Parse (kProgram ),
4619+ StatusIs (absl::StatusCode::kInvalidArgument ,
4620+ HasSubstr (" Unknown attribute argument: 'foo'" )));
4621+ }
4622+
45264623} // namespace xls::dslx
0 commit comments