@@ -648,6 +648,219 @@ TEST_F(ProbeCompilerTest, parse_bpftrace) {
648648 testing::proto::EqualsProto (absl::Substitute (kBPFTraceProgramPb , literal_bpf_trace)));
649649}
650650
651+ constexpr char kBPFTraceProgramMaxKernel [] = R"bpftrace(
652+ kprobe:tcp_drop
653+ {
654+ ...
655+ }
656+ )bpftrace" ;
657+
658+ constexpr char kBPFTraceProgramMinKernel [] = R"bpftrace(
659+ tracepoint:skb:kfree_skb
660+ {
661+ ...
662+ }
663+ )bpftrace" ;
664+
665+ // Test that we can compile/parse a single TraceProgram object with a valid selector
666+ constexpr char kBPFSingleTraceProgramObjectPxl [] = R"pxl(
667+ import pxtrace
668+ import px
669+
670+ after_519_trace_program = pxtrace.TraceProgram(
671+ program="""$0""",
672+ min_kernel='5.19',
673+ )
674+
675+ table_name = 'tcp_drop_table'
676+ pxtrace.UpsertTracepoint('tcp_drop_tracer',
677+ table_name,
678+ after_519_trace_program,
679+ pxtrace.kprobe(),
680+ '10m')
681+ )pxl" ;
682+
683+ constexpr char kBPFSingleTraceProgramObjectPb [] = R"proto(
684+ name: "tcp_drop_tracer"
685+ ttl {
686+ seconds: 600
687+ }
688+ programs {
689+ table_name: "tcp_drop_table"
690+ bpftrace {
691+ program: "$0"
692+ }
693+ selectors {
694+ selector_type: MIN_KERNEL
695+ value: "5.19"
696+ }
697+ }
698+ )proto" ;
699+
700+ TEST_F (ProbeCompilerTest, parse_single_bpftrace_program_object) {
701+ ASSERT_OK_AND_ASSIGN (auto probe_ir,
702+ CompileProbeScript (absl::Substitute (kBPFSingleTraceProgramObjectPxl ,
703+ kBPFTraceProgramMinKernel )));
704+ plannerpb::CompileMutationsResponse pb;
705+ EXPECT_OK (probe_ir->ToProto (&pb));
706+ ASSERT_EQ (pb.mutations_size (), 1 );
707+
708+ std::string literal_bpf_trace_min = kBPFTraceProgramMinKernel ;
709+ literal_bpf_trace_min = std::regex_replace (literal_bpf_trace_min, std::regex (" \n " ), " \\ n" );
710+
711+ EXPECT_THAT (pb.mutations ()[0 ].trace (),
712+ testing::proto::EqualsProto (
713+ absl::Substitute (kBPFSingleTraceProgramObjectPb , literal_bpf_trace_min)));
714+ }
715+
716+ // Test that we can compile a list of TraceProgram objects with valid selectors
717+ constexpr char kBPFTraceProgramObjectsPxl [] = R"pxl(
718+ import pxtrace
719+ import px
720+
721+ before_518_trace_program = pxtrace.TraceProgram(
722+ program="""$0""",
723+ max_kernel='5.18',
724+ )
725+
726+ after_519_trace_program = pxtrace.TraceProgram(
727+ program="""$1""",
728+ min_kernel='5.19',
729+ )
730+
731+ table_name = 'tcp_drop_table'
732+ pxtrace.UpsertTracepoint('tcp_drop_tracer',
733+ table_name,
734+ [before_518_trace_program, after_519_trace_program],
735+ pxtrace.kprobe(),
736+ '10m')
737+ )pxl" ;
738+
739+ constexpr char kBPFTraceProgramObjectsPb [] = R"proto(
740+ name: "tcp_drop_tracer"
741+ ttl {
742+ seconds: 600
743+ }
744+ programs {
745+ table_name: "tcp_drop_table"
746+ bpftrace {
747+ program: "$0"
748+ }
749+ selectors {
750+ selector_type: MAX_KERNEL
751+ value: "5.18"
752+ }
753+ }
754+ programs {
755+ table_name: "tcp_drop_table"
756+ bpftrace {
757+ program: "$1"
758+ }
759+ selectors {
760+ selector_type: MIN_KERNEL
761+ value: "5.19"
762+ }
763+ }
764+ )proto" ;
765+
766+ TEST_F (ProbeCompilerTest, parse_multiple_bpftrace_program_objects) {
767+ ASSERT_OK_AND_ASSIGN (auto probe_ir, CompileProbeScript (absl::Substitute (
768+ kBPFTraceProgramObjectsPxl , kBPFTraceProgramMinKernel ,
769+ kBPFTraceProgramMaxKernel )));
770+ plannerpb::CompileMutationsResponse pb;
771+ EXPECT_OK (probe_ir->ToProto (&pb));
772+ ASSERT_EQ (pb.mutations_size (), 1 );
773+
774+ std::string literal_bpf_trace_min = kBPFTraceProgramMinKernel ;
775+ literal_bpf_trace_min = std::regex_replace (literal_bpf_trace_min, std::regex (" \n " ), " \\ n" );
776+
777+ std::string literal_bpf_trace_max = kBPFTraceProgramMaxKernel ;
778+ literal_bpf_trace_max = std::regex_replace (literal_bpf_trace_max, std::regex (" \n " ), " \\ n" );
779+
780+ EXPECT_THAT (pb.mutations ()[0 ].trace (),
781+ testing::proto::EqualsProto (absl::Substitute (
782+ kBPFTraceProgramObjectsPb , literal_bpf_trace_min, literal_bpf_trace_max)));
783+ }
784+
785+ // Test that passing an unsupported selector type to TraceProgram throws a compiler error
786+ constexpr char kBPFUnsupportedTraceProgramObjectSelectorPxl [] = R"pxl(
787+ import pxtrace
788+ import px
789+
790+ after_519_trace_program = pxtrace.TraceProgram(
791+ program="""$0""",
792+ min_kernel='5.19',
793+ my_unsupported_selector='12345',
794+ )
795+
796+ table_name = 'tcp_drop_table'
797+ pxtrace.UpsertTracepoint('tcp_drop_tracer',
798+ table_name,
799+ after_519_trace_program,
800+ pxtrace.kprobe(),
801+ '10m')
802+ )pxl" ;
803+
804+ TEST_F (ProbeCompilerTest, parse_unsupported_selector_in_trace_program_object) {
805+ auto probe_ir_or_s = CompileProbeScript (kBPFUnsupportedTraceProgramObjectSelectorPxl );
806+ ASSERT_NOT_OK (probe_ir_or_s);
807+ EXPECT_THAT (
808+ probe_ir_or_s.status (),
809+ HasCompilerError (" Unsupported selector argument provided \' my_unsupported_selector\' " ));
810+ }
811+
812+ // Test that an invalid selector value throws a compiler error (currently needs to be a string)
813+ constexpr char kBPFInvalidTraceProgramObjectSelectorPxl [] = R"pxl(
814+ import pxtrace
815+ import px
816+
817+ after_519_trace_program = pxtrace.TraceProgram(
818+ program="""$0""",
819+ min_kernel='5.19',
820+ max_kernel=None,
821+ )
822+
823+ table_name = 'tcp_drop_table'
824+ pxtrace.UpsertTracepoint('tcp_drop_tracer',
825+ table_name,
826+ after_519_trace_program,
827+ pxtrace.kprobe(),
828+ '10m')
829+ )pxl" ;
830+
831+ TEST_F (ProbeCompilerTest, parse_invalid_trace_program_object) {
832+ auto probe_ir_or_s = CompileProbeScript (kBPFInvalidTraceProgramObjectSelectorPxl );
833+ ASSERT_NOT_OK (probe_ir_or_s);
834+ EXPECT_THAT (probe_ir_or_s.status (),
835+ HasCompilerError (" Expected \' String\' in arg \' max_kernel\' , got \' none\' " ));
836+ }
837+
838+ // Test that an empty selector value throws a compiler error
839+ constexpr char kBPFEmptyTraceProgramObjectSelectorPxl [] = R"pxl(
840+ import pxtrace
841+ import px
842+
843+ after_519_trace_program = pxtrace.TraceProgram(
844+ program="""$0""",
845+ min_kernel='5.19',
846+ max_kernel='',
847+ )
848+
849+ table_name = 'tcp_drop_table'
850+ pxtrace.UpsertTracepoint('tcp_drop_tracer',
851+ table_name,
852+ after_519_trace_program,
853+ pxtrace.kprobe(),
854+ '10m')
855+ )pxl" ;
856+
857+ TEST_F (ProbeCompilerTest, parse_empty_trace_program_object) {
858+ auto probe_ir_or_s = CompileProbeScript (kBPFEmptyTraceProgramObjectSelectorPxl );
859+ ASSERT_NOT_OK (probe_ir_or_s);
860+ EXPECT_THAT (probe_ir_or_s.status (),
861+ HasCompilerError (" Empty selector value provided for \' max_kernel\' " ));
862+ }
863+
651864constexpr char kConfigChangePxl [] = R"pxl(
652865import pxconfig
653866import px
0 commit comments