Commit c15b5c87 authored by Sandipan Das's avatar Sandipan Das

Fix 'test_libbcc' from failing because of ruby

This fixes 'test_usdt_probes', called from 'test_libbcc', from
failing if the static markers are in libruby rather than a ruby
executable. So, when the path of the binary having the markers
is tested, we must check if either "/ruby" or "/libruby" is a
substring rather than only checking for the former.

Also, rather than relying on hardcoded values for the number of
locations and arguments for a given probe, we capture this info
using the readelf tool and then compare these with the values
reported by bcc. This is because these numbers may vary across
different versions of ruby and will cause the tests to fail.
For example, 'test_libbcc' fails on Fedora 26 with ruby-2.4 as
the number of locations where it expects 'array__create' is 7
even when it is actually 2 as reported by bcc and verified with
readelf output.
Signed-off-by: default avatarSandipan Das <sandipan@linux.vnet.ibm.com>
parent 5ac03dda
...@@ -86,6 +86,35 @@ public: ...@@ -86,6 +86,35 @@ public:
pid_t pid() const { return pid_; } pid_t pid() const { return pid_; }
}; };
extern int cmd_scanf(const char *cmd, const char *fmt, ...);
static int probe_num_locations(const char *bin_path, const char *func_name) {
int num_locations;
char cmd[512];
const char *cmdfmt = "readelf -n %s | grep -c \"Name: %s$\"";
sprintf(cmd, cmdfmt, bin_path, func_name);
if (cmd_scanf(cmd, "%d", &num_locations) != 0) {
return -1;
}
return num_locations;
}
static int probe_num_arguments(const char *bin_path, const char *func_name) {
int num_arguments;
char cmd[512];
const char *cmdfmt = "readelf -n %s | grep -m 1 -A 2 \" %s$\" | " \
"tail -1 | cut -d \" \" -f 6- | wc -w";
sprintf(cmd, cmdfmt, bin_path, func_name);
if (cmd_scanf(cmd, "%d", &num_arguments) != 0) {
return -1;
}
return num_arguments;
}
TEST_CASE("test listing all USDT probes in Ruby/MRI", "[usdt]") { TEST_CASE("test listing all USDT probes in Ruby/MRI", "[usdt]") {
size_t mri_probe_count = 0; size_t mri_probe_count = 0;
...@@ -99,40 +128,63 @@ TEST_CASE("test listing all USDT probes in Ruby/MRI", "[usdt]") { ...@@ -99,40 +128,63 @@ TEST_CASE("test listing all USDT probes in Ruby/MRI", "[usdt]") {
mri_probe_count = ctx.num_probes(); mri_probe_count = ctx.num_probes();
SECTION("GC static probe") { SECTION("GC static probe") {
auto probe = ctx.get("gc__mark__begin"); auto name = "gc__mark__begin";
auto probe = ctx.get(name);
REQUIRE(probe); REQUIRE(probe);
REQUIRE(probe->in_shared_object() == true); REQUIRE(probe->in_shared_object() == true);
REQUIRE(probe->name() == "gc__mark__begin"); REQUIRE(probe->name() == name);
REQUIRE(probe->provider() == "ruby"); REQUIRE(probe->provider() == "ruby");
REQUIRE(probe->bin_path().find("/ruby") != std::string::npos);
REQUIRE(probe->num_locations() == 1); auto bin_path = probe->bin_path();
REQUIRE(probe->num_arguments() == 0); bool bin_path_match =
(bin_path.find("/ruby") != std::string::npos) ||
(bin_path.find("/libruby") != std::string::npos);
REQUIRE(bin_path_match);
int exp_locations, exp_arguments;
exp_locations = probe_num_locations(bin_path.c_str(), name);
exp_arguments = probe_num_arguments(bin_path.c_str(), name);
REQUIRE(probe->num_locations() == exp_locations);
REQUIRE(probe->num_arguments() == exp_arguments);
REQUIRE(probe->need_enable() == true); REQUIRE(probe->need_enable() == true);
} }
SECTION("object creation probe") { SECTION("object creation probe") {
auto probe = ctx.get("object__create"); auto name = "object__create";
auto probe = ctx.get(name);
REQUIRE(probe); REQUIRE(probe);
REQUIRE(probe->in_shared_object() == true); REQUIRE(probe->in_shared_object() == true);
REQUIRE(probe->name() == "object__create"); REQUIRE(probe->name() == name);
REQUIRE(probe->provider() == "ruby"); REQUIRE(probe->provider() == "ruby");
REQUIRE(probe->bin_path().find("/ruby") != std::string::npos);
REQUIRE(probe->num_locations() == 1); auto bin_path = probe->bin_path();
REQUIRE(probe->num_arguments() == 3); bool bin_path_match =
(bin_path.find("/ruby") != std::string::npos) ||
(bin_path.find("/libruby") != std::string::npos);
REQUIRE(bin_path_match);
int exp_locations, exp_arguments;
exp_locations = probe_num_locations(bin_path.c_str(), name);
exp_arguments = probe_num_arguments(bin_path.c_str(), name);
REQUIRE(probe->num_locations() == exp_locations);
REQUIRE(probe->num_arguments() == exp_arguments);
REQUIRE(probe->need_enable() == true); REQUIRE(probe->need_enable() == true);
} }
SECTION("array creation probe") { SECTION("array creation probe") {
auto probe = ctx.get("array__create"); auto name = "array__create";
auto probe = ctx.get(name);
REQUIRE(probe); REQUIRE(probe);
REQUIRE(probe->name() == "array__create"); REQUIRE(probe->name() == name);
REQUIRE(probe->num_locations() == 7); auto bin_path = probe->bin_path().c_str();
REQUIRE(probe->num_arguments() == 3); int exp_locations, exp_arguments;
exp_locations = probe_num_locations(bin_path, name);
exp_arguments = probe_num_arguments(bin_path, name);
REQUIRE(probe->num_locations() == exp_locations);
REQUIRE(probe->num_arguments() == exp_arguments);
REQUIRE(probe->need_enable() == true); REQUIRE(probe->need_enable() == true);
} }
} }
...@@ -149,16 +201,25 @@ TEST_CASE("test listing all USDT probes in Ruby/MRI", "[usdt]") { ...@@ -149,16 +201,25 @@ TEST_CASE("test listing all USDT probes in Ruby/MRI", "[usdt]") {
REQUIRE(ctx.num_probes() >= mri_probe_count); REQUIRE(ctx.num_probes() >= mri_probe_count);
SECTION("get probe in running process") { SECTION("get probe in running process") {
auto probe = ctx.get("gc__mark__begin"); auto name = "gc__mark__begin";
auto probe = ctx.get(name);
REQUIRE(probe); REQUIRE(probe);
REQUIRE(probe->in_shared_object() == true); REQUIRE(probe->in_shared_object() == true);
REQUIRE(probe->name() == "gc__mark__begin"); REQUIRE(probe->name() == name);
REQUIRE(probe->provider() == "ruby"); REQUIRE(probe->provider() == "ruby");
REQUIRE(probe->bin_path().find("/ruby") != std::string::npos);
REQUIRE(probe->num_locations() == 1); auto bin_path = probe->bin_path();
REQUIRE(probe->num_arguments() == 0); bool bin_path_match =
(bin_path.find("/ruby") != std::string::npos) ||
(bin_path.find("/libruby") != std::string::npos);
REQUIRE(bin_path_match);
int exp_locations, exp_arguments;
exp_locations = probe_num_locations(bin_path.c_str(), name);
exp_arguments = probe_num_arguments(bin_path.c_str(), name);
REQUIRE(probe->num_locations() == exp_locations);
REQUIRE(probe->num_arguments() == exp_arguments);
REQUIRE(probe->need_enable() == true); REQUIRE(probe->need_enable() == true);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment