1919#include " src/stirling/obj_tools/go_syms.h"
2020
2121#include < memory>
22+ #include < tuple>
23+ #include < utility>
2224
2325#include " src/common/testing/testing.h"
2426
@@ -27,7 +29,9 @@ namespace stirling {
2729namespace obj_tools {
2830
2931using ::testing::Field;
32+ using ::testing::Matcher;
3033using ::testing::StrEq;
34+ using ::testing::UnorderedElementsAre;
3135
3236constexpr std::string_view kTestGoLittleEndiani386BinaryPath =
3337 " src/stirling/obj_tools/testdata/go/test_go1_13_i386_binary" ;
@@ -37,6 +41,8 @@ constexpr std::string_view kTestGoLittleEndianBinaryPath =
3741
3842constexpr std::string_view kTestGoBinaryPath =
3943 " src/stirling/obj_tools/testdata/go/test_go_1_19_binary" ;
44+ constexpr std::string_view kTestGo1_21BinaryPath =
45+ " src/stirling/obj_tools/testdata/go/test_go_1_21_binary" ;
4046
4147// The "endian agnostic" case refers to where the Go version data is varint encoded
4248// directly within the buildinfo header. See the following reference for more details.
@@ -68,44 +74,95 @@ TEST(IsGoExecutableTest, WorkingOnBasicGoBinary) {
6874 EXPECT_TRUE (IsGoExecutable (elf_reader.get ()));
6975}
7076
71- TEST (ElfGolangItableTest, ExtractInterfaceTypes) {
72- const std::string kPath = px::testing::BazelRunfilePath (kTestGoBinaryPath );
77+ class ElfGolangItableTest
78+ : public ::testing::TestWithParam<std::tuple<
79+ std::string,
80+ Matcher<const std::vector<std::pair<std::string, std::vector<IntfImplTypeInfo>>>>>> {};
81+
82+ INSTANTIATE_TEST_SUITE_P (
83+ ElfGolangItableTestSuite, ElfGolangItableTest,
84+ ::testing::Values (
85+ std::make_tuple (
86+ kTestGo1_21BinaryPath ,
87+ UnorderedElementsAre (
88+ Pair (" fmt.State" ,
89+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name, " *fmt.pp" ))),
90+ Pair(" internal/bisect.Writer" ,
91+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name,
92+ " *internal/godebug.runtimeStderr" ))),
93+ Pair(" internal/reflectlite.Type" ,
94+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name,
95+ " internal/reflectlite.rtype" ))),
96+ Pair(" error" ,
97+ UnorderedElementsAre (
98+ Field (&IntfImplTypeInfo::type_name, " main.IntStruct" ),
99+ Field(&IntfImplTypeInfo::type_name, " *errors.errorString" ),
100+ Field(&IntfImplTypeInfo::type_name, " syscall.Errno" ),
101+ Field(&IntfImplTypeInfo::type_name, " *io/fs.PathError" ),
102+ Field(&IntfImplTypeInfo::type_name, " runtime.errorString" ),
103+ Field(&IntfImplTypeInfo::type_name, " internal/poll.errNetClosing" ),
104+ Field(&IntfImplTypeInfo::type_name,
105+ " *internal/poll.DeadlineExceededError" ),
106+ Field(&IntfImplTypeInfo::type_name, " *internal/bisect.parseError" ))),
107+ Pair(" io.Writer" ,
108+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name, " *os.File" ))),
109+ Pair(" sort.Interface" , UnorderedElementsAre(Field(&IntfImplTypeInfo::type_name,
110+ " *internal/fmtsort.SortedMap" ))),
111+ Pair(" reflect.Type" ,
112+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name, " *reflect.rtype" ))),
113+ Pair(" math/rand.Source64" , UnorderedElementsAre(Field(&IntfImplTypeInfo::type_name,
114+ " *math/rand.fastSource" ))),
115+ Pair(" math/rand.Source" , UnorderedElementsAre(Field(&IntfImplTypeInfo::type_name,
116+ " *math/rand.lockedSource" ),
117+ Field(&IntfImplTypeInfo::type_name,
118+ " *math/rand.fastSource" ))))),
119+ std::make_tuple(
120+ kTestGoBinaryPath ,
121+ UnorderedElementsAre (
122+ Pair (" error" ,
123+ UnorderedElementsAre (
124+ Field (&IntfImplTypeInfo::type_name, " main.IntStruct" ),
125+ Field(&IntfImplTypeInfo::type_name, " *errors.errorString" ),
126+ Field(&IntfImplTypeInfo::type_name, " *io/fs.PathError" ),
127+ Field(&IntfImplTypeInfo::type_name,
128+ " *internal/poll.DeadlineExceededError" ),
129+ Field(&IntfImplTypeInfo::type_name, " internal/poll.errNetClosing" ),
130+ Field(&IntfImplTypeInfo::type_name, " runtime.errorString" ),
131+ Field(&IntfImplTypeInfo::type_name, " syscall.Errno" ))),
132+ Pair(" sort.Interface" , UnorderedElementsAre(Field(&IntfImplTypeInfo::type_name,
133+ " *internal/fmtsort.SortedMap" ))),
134+ Pair(" math/rand.Source" , UnorderedElementsAre(Field(&IntfImplTypeInfo::type_name,
135+ " *math/rand.lockedSource" ))),
136+ Pair(" io.Writer" ,
137+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name, " *os.File" ))),
138+ Pair(" internal/reflectlite.Type" ,
139+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name,
140+ " *internal/reflectlite.rtype" ))),
141+ Pair(" reflect.Type" ,
142+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name, " *reflect.rtype" ))),
143+ Pair(" fmt.State" ,
144+ UnorderedElementsAre (Field(&IntfImplTypeInfo::type_name, " *fmt.pp" )))))));
145+
146+ TEST_P (ElfGolangItableTest, ExtractInterfaceTypes) {
147+ const std::string kPath = px::testing::BazelRunfilePath (std::get<0 >(GetParam ()));
73148
74149 ASSERT_OK_AND_ASSIGN (std::unique_ptr<ElfReader> elf_reader, ElfReader::Create (kPath ));
75- ASSERT_OK_AND_ASSIGN (const auto interfaces, ExtractGolangInterfaces (elf_reader.get ()));
150+
151+ ASSERT_OK_AND_ASSIGN (const auto interfaces_map, ExtractGolangInterfaces (elf_reader.get ()));
152+ std::vector<std::pair<std::string, std::vector<IntfImplTypeInfo>>> interfaces (
153+ interfaces_map.begin (), interfaces_map.end ());
76154
77155 // Check for `bazel coverage` so we can bypass the final checks.
78156 // Note that we still get accurate coverage metrics, because this only skips the final check.
79157 // Ideally, we'd get bazel to deterministically build test_go_binary,
80158 // but it's not easy to tell bazel to use a different config for just one target.
159+
81160#ifdef PL_COVERAGE
82161 LOG (INFO) << " Whoa...`bazel coverage` is messaging with test_go_binary. Shame on you bazel. "
83162 " Ending this test early." ;
84163 return ;
85164#else
86- EXPECT_THAT (
87- interfaces,
88- UnorderedElementsAre (
89- Pair (" error" ,
90- UnorderedElementsAre (
91- Field (&IntfImplTypeInfo::type_name, " main.IntStruct" ),
92- Field (&IntfImplTypeInfo::type_name, " *errors.errorString" ),
93- Field (&IntfImplTypeInfo::type_name, " *io/fs.PathError" ),
94- Field (&IntfImplTypeInfo::type_name, " *internal/poll.DeadlineExceededError" ),
95- Field (&IntfImplTypeInfo::type_name, " internal/poll.errNetClosing" ),
96- Field (&IntfImplTypeInfo::type_name, " runtime.errorString" ),
97- Field (&IntfImplTypeInfo::type_name, " syscall.Errno" ))),
98- Pair (" sort.Interface" , UnorderedElementsAre (Field (&IntfImplTypeInfo::type_name,
99- " *internal/fmtsort.SortedMap" ))),
100- Pair (" math/rand.Source" , UnorderedElementsAre (Field (&IntfImplTypeInfo::type_name,
101- " *math/rand.lockedSource" ))),
102- Pair (" io.Writer" , UnorderedElementsAre (Field (&IntfImplTypeInfo::type_name, " *os.File" ))),
103- Pair (" internal/reflectlite.Type" ,
104- UnorderedElementsAre (
105- Field (&IntfImplTypeInfo::type_name, " *internal/reflectlite.rtype" ))),
106- Pair (" reflect.Type" ,
107- UnorderedElementsAre (Field (&IntfImplTypeInfo::type_name, " *reflect.rtype" ))),
108- Pair (" fmt.State" , UnorderedElementsAre (Field (&IntfImplTypeInfo::type_name, " *fmt.pp" )))));
165+ EXPECT_THAT (interfaces, std::get<1 >(GetParam ()));
109166#endif
110167}
111168
0 commit comments