xref: /aosp_15_r20/external/federated-compute/fcp/tracing/tools/tracing_traits_generator_test.cc (revision 14675a029014e728ec732f129a32e299b2da0601)
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // TODO(team): switch to re2 library
16 #include <regex>  // NOLINT
17 #include <string>
18 
19 #include "gtest/gtest.h"
20 #include "absl/flags/flag.h"
21 #include "absl/strings/str_cat.h"
22 #include "absl/strings/string_view.h"
23 #include "fcp/base/monitoring.h"
24 #include "fcp/base/platform.h"
25 #include "fcp/testing/testing.h"
26 
27 ABSL_FLAG(std::string, codegen_tool_path, "", "Path to codegen tool script");
28 
29 namespace fcp {
30 namespace {
31 
32 const char* kBaselineDir = "fcp/tracing/tools/testdata";
33 
PostProcessOutput(const std::string & input)34 std::string PostProcessOutput(const std::string& input) {
35   std::regex header_guard_simplifier(
36       "(THIRD_PARTY_)?FCP_TRACING_TOOLS_TESTDATA");
37   std::string header_guard_replaced = std::regex_replace(
38       input, header_guard_simplifier, "THIRD_PARTY_FCP_TRACING_TOOLS_TESTDATA");
39   std::regex runfiles_path_simplifier("\".*runfiles.*fcp/tracing");
40   // replaces the runfile directory with {RUNFILE_PATH} for testing purposes
41   std::string runfiles_replaced = std::regex_replace(
42       header_guard_replaced, runfiles_path_simplifier, "\"${RUNFILE_PATH}");
43   std::regex path_simplifier_pattern("( |\")(\\w+/)*fcp/tracing");
44   // replaces the directory of the .fbs for testing purposes
45   std::string directory_replaced = std::regex_replace(
46       runfiles_replaced, path_simplifier_pattern, "$1${DIR}");
47   std::regex fcp_base_path_simplifier("(\\w+/)?fcp/base");
48   return std::regex_replace(directory_replaced, fcp_base_path_simplifier,
49                             "${BASE}");
50 }
51 
DoTest()52 void DoTest() {
53   std::string source_file = absl::StrCat(TestName(), ".fbs");
54   std::string source_path =
55       GetTestDataPath(ConcatPath(kBaselineDir, source_file));
56 
57   // Read fsb source file derived from the test name:
58   StatusOr<std::string> source_s = ReadFileToString(source_path);
59   ASSERT_THAT(source_s, IsOk()) << "Can't read " << source_path;
60   std::string source = source_s.value();
61 
62   std::string out_file =
63       ConcatPath(testing::TempDir(), absl::StrCat(TestName(), ".out"));
64   std::string err_file =
65       ConcatPath(testing::TempDir(), absl::StrCat(TestName(), ".err"));
66 
67   // Run codegen script, redirecting stdout to out_file and stderr to err_file
68   int exit_code = system(
69       absl::StrCat(GetTestDataPath(absl::GetFlag(FLAGS_codegen_tool_path)), " ",
70                    source_path, " ", testing::TempDir(), " ", kBaselineDir,
71                    " 1> ", out_file, " 2> ", err_file)
72           .c_str());
73 
74   // Reading error and out files
75   std::string out = ReadFileToString(out_file).value();
76   std::string err = ReadFileToString(err_file).value();
77 
78   if (exit_code != 0) {
79     // Codegen failed. This might be expected depending on the test.
80     // In the case of failure we're not interested in capturing possible partial
81     // output in baseline file.
82     out.clear();
83     if (err.empty()) {
84       // If error is not empty it already contains relevant diagnostics,
85       // otherwise adding information about exit code.
86       err = absl::StrCat("Exit code ", exit_code);
87     }
88   }
89 
90   // Producing report which is expected to precisely match .baseline file.
91   std::ostringstream report;
92   report << "============== " << source_file << " ============" << std::endl;
93   report << PostProcessOutput(source) << std::endl;
94   report << "============== diagnosis ============" << std::endl;
95   report << PostProcessOutput(err) << std::endl;
96   report << "============== result ============" << std::endl;
97   report << PostProcessOutput(out) << std::endl;
98 
99   // Compare produced report with baseline.
100   std::string baseline_path =
101       ConcatPath(kBaselineDir, absl::StrCat(TestName(), ".baseline"));
102   auto status_s = VerifyAgainstBaseline(baseline_path, report.str());
103   ASSERT_TRUE(status_s.ok()) << status_s.status();
104   auto& diff = status_s.value();
105   if (!diff.empty()) {
106     FAIL() << diff;
107   }
108 }
109 
TEST(Codegen,EmptyTable)110 TEST(Codegen, EmptyTable) { DoTest(); }
TEST(Codegen,FieldsOfDifferentTypes)111 TEST(Codegen, FieldsOfDifferentTypes) { DoTest(); }
TEST(Codegen,DeprecatedField)112 TEST(Codegen, DeprecatedField) { DoTest(); }
TEST(Codegen,NonTableObjectsAreSkipped)113 TEST(Codegen, NonTableObjectsAreSkipped) { DoTest(); }
TEST(Codegen,AllTypes)114 TEST(Codegen, AllTypes) { DoTest(); }
TEST(Codegen,OrderWithIds)115 TEST(Codegen, OrderWithIds) { DoTest(); }
TEST(Codegen,NoTag)116 TEST(Codegen, NoTag) { DoTest(); }
TEST(Codegen,NoAttributes)117 TEST(Codegen, NoAttributes) { DoTest(); }
TEST(Codegen,TagTooLong)118 TEST(Codegen, TagTooLong) { DoTest(); }
TEST(Codegen,DuplicateTags)119 TEST(Codegen, DuplicateTags) { DoTest(); }
TEST(Codegen,UnsupportedType)120 TEST(Codegen, UnsupportedType) { DoTest(); }
TEST(Codegen,TableWithNamespace)121 TEST(Codegen, TableWithNamespace) { DoTest(); }
TEST(Codegen,EnumType)122 TEST(Codegen, EnumType) { DoTest(); }
123 
124 }  // namespace
125 }  // namespace fcp
126