CCTLib
Calling-context and data-object attribution library for Intel Pin
omp_race_integration_test.cpp
Go to the documentation of this file.
1 // GoogleTest-driven integration tests for omp_datarace_client.
2 //
3 // User note: this client is "not very mature". Tests here verify the tool
4 // loads and runs against OpenMP victims without crashing; race-detection
5 // accuracy claims are deferred (would require detailed reference-model
6 // comparison the tool is not currently equipped to satisfy).
7 
8 #include <cerrno>
9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <fcntl.h>
13 #include <fstream>
14 #include <sstream>
15 #include <string>
16 #include <sys/wait.h>
17 #include <unistd.h>
18 #include <vector>
19 
20 #include <gtest/gtest.h>
21 
22 namespace {
23 
24 std::string env(const char* n) { const char* v = getenv(n); return v ? v : ""; }
25 std::string cctlib_root() { std::string r = env("CCTLIB_ROOT"); return r.empty() ? "../.." : r; }
26 std::string pin_root() { return env("PIN_ROOT"); }
27 
28 int run_pin(const std::string& tool, const std::vector<std::string>& args) {
29  std::string pin = pin_root() + "/pin";
30  std::vector<char*> argv;
31  argv.push_back(const_cast<char*>(pin.c_str()));
32  argv.push_back(const_cast<char*>("-t"));
33  argv.push_back(const_cast<char*>(tool.c_str()));
34  argv.push_back(const_cast<char*>("--"));
35  for (auto& a : args) argv.push_back(const_cast<char*>(a.c_str()));
36  argv.push_back(nullptr);
37  pid_t pid = fork();
38  if (pid < 0) return -1;
39  if (pid == 0) {
40  int devnull = open("/dev/null", O_WRONLY);
41  if (devnull >= 0) { dup2(devnull, 1); dup2(devnull, 2); close(devnull); }
42  setenv("OMP_NUM_THREADS", "2", 1);
43  execv(pin.c_str(), argv.data());
44  _exit(127);
45  }
46  int status = 0;
47  if (waitpid(pid, &status, 0) < 0) return -1;
48  if (WIFEXITED(status)) return WEXITSTATUS(status);
49  if (WIFSIGNALED(status)) return 128 + WTERMSIG(status);
50  return -2;
51 }
52 
53 class OmpRaceIntegration : public ::testing::Test {
54  protected:
55  std::string root_, tool_;
56  void SetUp() override {
57  root_ = cctlib_root();
58  ASSERT_FALSE(pin_root().empty());
59  tool_ = root_ + "/clients/obj-intel64/omp_datarace_client.so";
60  ASSERT_EQ(0, access(tool_.c_str(), F_OK)) << tool_ << " missing";
61  ASSERT_EQ(0, chdir(root_.c_str())) << "chdir failed";
62  }
63 };
64 
65 // Basic sanity: the tool runs cleanly on a non-OpenMP target.
66 TEST_F(OmpRaceIntegration, RunsCleanlyOnLs) {
67  EXPECT_EQ(0, run_pin(tool_, {"/bin/ls"}));
68 }
69 
70 // The tool runs on an OpenMP TP victim (concurrent increment without sync)
71 // without crashing. Whether it correctly REPORTS the race is a separate
72 // question addressed by DISABLED_ tests below.
73 TEST_F(OmpRaceIntegration, RunsOnRaceVictim) {
74  EXPECT_EQ(0, run_pin(tool_, {root_ + "/tests/gtest/obj/apps/omp_race_tp_simple"}));
75 }
76 
77 // The tool runs on the TN victim (critical-section-protected increment).
78 TEST_F(OmpRaceIntegration, RunsOnCriticalVictim) {
79  EXPECT_EQ(0, run_pin(tool_, {root_ + "/tests/gtest/obj/apps/omp_race_tn_critical"}));
80 }
81 
82 // Race-detection accuracy tests -- disabled pending broader hardening of
83 // omp_datarace_client.
84 TEST_F(OmpRaceIntegration, DISABLED_TruePositiveReportsRace) {
85  GTEST_SKIP() << "omp_datarace_client race detection is not fully wired";
86 }
87 TEST_F(OmpRaceIntegration, DISABLED_TrueNegativeReportsNoRace) {
88  GTEST_SKIP() << "omp_datarace_client race detection is not fully wired";
89 }
90 
91 } // namespace
volatile uint8_t status
Definition: cctlib.cpp:230
TEST_F(OmpRaceIntegration, DISABLED_TrueNegativeReportsNoRace)
int run_pin(const std::string &tool, const std::vector< std::string > &args)
int a[1000]
Definition: testArray.c:5