kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/extractor/testdata/root_directory_test.cc (about) 1 /* 2 * Copyright 2019 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <algorithm> 18 #include <optional> 19 #include <string> 20 #include <utility> 21 22 #include "absl/strings/str_cat.h" 23 #include "absl/strings/string_view.h" 24 #include "gmock/gmock.h" 25 #include "gtest/gtest.h" 26 #include "kythe/cxx/common/path_utils.h" 27 #include "kythe/cxx/extractor/testlib.h" 28 #include "kythe/proto/analysis.pb.h" 29 #include "protobuf-matchers/protocol-buffer-matchers.h" 30 31 namespace kythe { 32 namespace { 33 using ::kythe::proto::CompilationUnit; 34 using ::protobuf_matchers::EquivToProto; 35 using ::testing::SizeIs; 36 37 constexpr absl::string_view kFilePath = 38 "kythe/cxx/extractor/testdata/altroot/altpath/file.cc"; 39 40 CompilationUnit ExpectedCompilation() { 41 return ParseTextCompilationUnitOrDie(R"pb( 42 v_name { language: "c++" } 43 required_input { 44 v_name { path: "altpath/file.cc" } 45 info { 46 path: "file.cc" 47 digest: "a24091884bc15b53e380fe5b874d1bb52d89269fdf2592808ac70ba189204730" 48 } 49 details { 50 [type.googleapis.com/kythe.proto.ContextDependentVersion] { 51 row { source_context: "hash0" always_process: true } 52 } 53 } 54 } 55 argument: "/dummy/bin/g++" 56 argument: "-target" 57 argument: "dummy-target" 58 argument: "-DKYTHE_IS_RUNNING=1" 59 argument: "-resource-dir" 60 argument: "/kythe_builtins" 61 argument: "--driver-mode=g++" 62 argument: "file.cc" 63 argument: "-fsyntax-only" 64 source_file: "file.cc" 65 working_directory: "/root" 66 entry_context: "hash0")pb"); 67 } 68 69 // Verifies that the extractor properly handles KYTHE_ROOT_DIRECTORY 70 // other than the working directory. 71 TEST(RootDirectoryTest, AlternateRootDirectoryExtracts) { 72 std::optional<std::string> resolved_path = ResolveRunfiles(kFilePath); 73 ASSERT_TRUE(resolved_path.has_value()); 74 75 std::string filename(Basename(*resolved_path)); 76 std::string working_directory(Dirname(*resolved_path)); 77 std::string root_directory(Dirname(working_directory)); 78 79 ExtractorOptions extraction; 80 extraction.working_directory = working_directory; 81 extraction.arguments = {"--with_executable", "/dummy/bin/g++", filename}; 82 extraction.environment = { 83 {"KYTHE_ROOT_DIRECTORY", root_directory}, 84 }; 85 86 CompilationUnit unit = ExtractSingleCompilationOrDie(std::move(extraction)); 87 ASSERT_THAT(unit.argument(), SizeIs(9)); 88 89 // Fix up things which may legitmately vary between runs. 90 // TODO(shahms): use gMock protobuf matchers when available. 91 CanonicalizeHashes(&unit); 92 unit.set_argument(2, "dummy-target"); 93 unit.clear_details(); 94 95 EXPECT_THAT(unit, EquivToProto(ExpectedCompilation())); 96 } 97 98 // Verifies that the extractor properly picks a stable 99 // compilation unit working_directory that doesn't conflict 100 // with another compilation unit path. 101 TEST(RootDirectoryTest, WorkingDirectoryAvoidsConflict) { 102 std::optional<std::string> resolved_path = ResolveRunfiles(kFilePath); 103 ASSERT_TRUE(resolved_path.has_value()); 104 105 std::string filename(Basename(*resolved_path)); 106 std::string working_directory(Dirname(*resolved_path)); 107 std::string root_directory(Dirname(working_directory)); 108 109 ExtractorOptions extraction; 110 extraction.working_directory = working_directory; 111 extraction.arguments = { 112 "--with_executable", "/dummy/bin/g++", 113 // The extractor should avoid using a stable working_directory if the 114 // actual working_directory is present in the argument list. 115 absl::StrCat("-DUNUSED=", working_directory), filename}; 116 extraction.environment = { 117 {"KYTHE_ROOT_DIRECTORY", root_directory}, 118 }; 119 120 CompilationUnit unit = ExtractSingleCompilationOrDie(std::move(extraction)); 121 ASSERT_THAT(unit.argument(), SizeIs(10)); 122 123 // Fix up things which may legitmately vary between runs. 124 // TODO(shahms): use gMock protobuf matchers when available. 125 CanonicalizeHashes(&unit); 126 unit.set_argument(2, "dummy-target"); 127 unit.clear_details(); 128 129 auto expected = ExpectedCompilation(); 130 expected.add_argument(absl::StrCat("-DUNUSED=", working_directory)); 131 // RepeatedPtrField lacks an "insert" method, so we have to use rotate 132 // to position it correctly. 133 std::rotate(expected.mutable_argument()->pointer_begin() + 7, 134 expected.mutable_argument()->pointer_end() - 1, 135 expected.mutable_argument()->pointer_end()); 136 expected.set_working_directory(working_directory); 137 138 EXPECT_THAT(unit, EquivToProto(expected)); 139 } 140 141 } // namespace 142 } // namespace kythe