Skip to content

Commit ce4c481

Browse files
CEL Dev Teamcopybara-github
authored andcommitted
Internal Changes
PiperOrigin-RevId: 808934990
1 parent 4010d6e commit ce4c481

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

testing/testrunner/runner_bin.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
// This binary is a test runner for CEL tests. It is used to run CEL tests
1616
// written in the CEL test suite format.
17+
#include <cerrno>
18+
#include <cstdlib>
19+
#include <cstring>
1720
#include <fstream>
1821
#include <functional>
1922
#include <ios>
@@ -31,6 +34,7 @@
3134
#include "absl/strings/str_cat.h"
3235
#include "absl/strings/str_format.h"
3336
#include "absl/strings/str_join.h"
37+
#include "absl/strings/string_view.h"
3438
#include "eval/public/cel_expression.h"
3539
#include "internal/testing.h"
3640
#include "runtime/runtime.h"
@@ -110,9 +114,54 @@ class CoverageReportingEnvironment : public testing::Environment {
110114
<< absl::StrJoin(coverage_report.unencountered_branches,
111115
"\n");
112116
}
117+
118+
if (!coverage_report.dot_graph.empty()) {
119+
WriteDotGraphToArtifact(coverage_report.dot_graph);
120+
}
113121
}
114122

115123
private:
124+
void WriteDotGraphToArtifact(absl::string_view dot_graph) {
125+
// Save DOT graph to file in TEST_UNDECLARED_OUTPUTS_DIR or default dir
126+
const char* outputs_dir_env = std::getenv("TEST_UNDECLARED_OUTPUTS_DIR");
127+
128+
// For non-Bazel/Blaze users, we write to a subdirectory under the current
129+
// working directory.
130+
std::string outputs_dir =
131+
(outputs_dir_env != nullptr) ? outputs_dir_env : "cel_artifacts";
132+
133+
std::string coverage_dir = absl::StrCat(outputs_dir, "/cel_test_coverage");
134+
135+
// Creates the directory to store CEL test coverage artifacts.
136+
// The second argument, `0755`, sets the directory's permissions in octal
137+
// format, which is a standard for file system operations. It grants:
138+
// - Owner: read, write, and execute permissions (7 = 4+2+1).
139+
// - Group: read and execute permissions (5 = 4+1).
140+
// - Others: read and execute permissions (5 = 4+1).
141+
// This gives the owner full control while allowing other users to access
142+
// the generated artifacts.
143+
int mkdir_result = mkdir(coverage_dir.c_str(), 0755);
144+
145+
// If mkdir fails, it sets the global 'errno' variable to an error code
146+
// indicating the reason. We check this code to specifically ignore the
147+
// EEXIST error, which just means the directory already exists (this is not
148+
// a real failure we need to warn about).
149+
if (mkdir_result != 0 && errno != EEXIST) {
150+
ABSL_LOG(WARNING) << "Failed to create directory: " << coverage_dir
151+
<< " (reason: " << strerror(errno) << ")";
152+
} else {
153+
std::string graph_path =
154+
absl::StrCat(coverage_dir, "/coverage_graph.txt");
155+
std::ofstream out(graph_path);
156+
if (out.is_open()) {
157+
out << dot_graph;
158+
out.close();
159+
} else {
160+
ABSL_LOG(WARNING) << "Failed to open file for writing: " << graph_path;
161+
}
162+
}
163+
}
164+
116165
cel::test::CoverageIndex& coverage_index_;
117166
};
118167

0 commit comments

Comments
 (0)