Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <algorithm> | |
| 6 | |
| 7 #include "testing/gtest/include/gtest/gtest.h" | |
| 8 #include "tools/gn/runtime_deps.h" | |
| 9 #include "tools/gn/target.h" | |
| 10 #include "tools/gn/test_with_scope.h" | |
| 11 | |
| 12 namespace { | |
| 13 | |
| 14 void InitTargetWithType(TestWithScope& setup, | |
| 15 Target* target, | |
| 16 Target::OutputType type) { | |
| 17 target->set_output_type(type); | |
| 18 target->visibility().SetPublic(); | |
| 19 target->SetToolchain(setup.toolchain()); | |
| 20 } | |
| 21 | |
| 22 // Convenience function to make the correct kind of pair. | |
| 23 std::pair<OutputFile, const Target*> MakePair(const char* str, | |
| 24 const Target* t) { | |
| 25 return std::pair<OutputFile, const Target*>(OutputFile(str), t); | |
| 26 } | |
| 27 | |
| 28 std::string GetVectorDescription( | |
| 29 const std::vector<std::pair<OutputFile, const Target*>>& v) { | |
| 30 std::string result; | |
| 31 for (size_t i = 0; i < v.size(); i++) { | |
| 32 if (i != 0) | |
| 33 result.append(", "); | |
| 34 result.append("\"" + v[i].first.value() + "\""); | |
| 35 } | |
| 36 return result; | |
| 37 } | |
| 38 | |
| 39 } // namespace | |
| 40 | |
| 41 // Tests an exe depending on different types of libraries. | |
| 42 TEST(RuntimeDeps, Libs) { | |
| 43 TestWithScope setup; | |
| 44 Err err; | |
| 45 | |
| 46 // Dependency hierarchy: main(exe) -> stat | |
| 47 // -> shared | |
| 48 // -> set | |
| 49 | |
| 50 Target stat(setup.settings(), Label(SourceDir("//"), "stat")); | |
| 51 InitTargetWithType(setup, &stat, Target::STATIC_LIBRARY); | |
| 52 stat.data().push_back(SourceFile("//stat.dat")); | |
| 53 ASSERT_TRUE(stat.OnResolved(&err)); | |
| 54 | |
| 55 Target shared(setup.settings(), Label(SourceDir("//"), "shared")); | |
| 56 InitTargetWithType(setup, &shared, Target::SHARED_LIBRARY); | |
| 57 shared.data().push_back(SourceFile("//shared.dat")); | |
| 58 ASSERT_TRUE(shared.OnResolved(&err)); | |
| 59 | |
| 60 Target set(setup.settings(), Label(SourceDir("//"), "set")); | |
| 61 InitTargetWithType(setup, &set, Target::SOURCE_SET); | |
| 62 set.data().push_back(SourceFile("//set.dat")); | |
| 63 ASSERT_TRUE(set.OnResolved(&err)); | |
| 64 | |
| 65 Target main(setup.settings(), Label(SourceDir("//"), "main")); | |
| 66 InitTargetWithType(setup, &main, Target::EXECUTABLE); | |
| 67 main.private_deps().push_back(LabelTargetPair(&stat)); | |
| 68 main.private_deps().push_back(LabelTargetPair(&shared)); | |
| 69 main.private_deps().push_back(LabelTargetPair(&set)); | |
| 70 main.data().push_back(SourceFile("//main.dat")); | |
| 71 ASSERT_TRUE(main.OnResolved(&err)); | |
| 72 | |
| 73 std::vector<std::pair<OutputFile, const Target*>> result = | |
| 74 ComputeRuntimeDeps(&main); | |
| 75 | |
| 76 // The result should have deps of main, all 4 dat files, and libshared.so | |
| 77 ASSERT_EQ(6u, result.size()) << GetVectorDescription(result); | |
| 78 | |
| 79 // The first one should always be the main exe. | |
| 80 EXPECT_TRUE(MakePair("./main", &main) == result[0]); | |
| 81 | |
| 82 // The rest of the ordering is undefined. First the data files. | |
| 83 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 84 MakePair("../../stat.dat", &stat)) != | |
| 85 result.end()) << GetVectorDescription(result); | |
| 86 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 87 MakePair("../../shared.dat", &shared)) != | |
| 88 result.end()) << GetVectorDescription(result); | |
| 89 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 90 MakePair("../../set.dat", &set)) != | |
| 91 result.end()) << GetVectorDescription(result); | |
| 92 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 93 MakePair("../../main.dat", &main)) != | |
| 94 result.end()) << GetVectorDescription(result); | |
| 95 | |
| 96 // Check the static library | |
| 97 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 98 MakePair("./libshared.so", &shared)) != | |
| 99 result.end()) << GetVectorDescription(result); | |
| 100 } | |
| 101 | |
| 102 // Tests that executables that aren't listed as data deps aren't included in | |
| 103 // the output, but executables that are data deps are included. | |
| 104 TEST(RuntimeDeps, ExeDataDep) { | |
| 105 TestWithScope setup; | |
| 106 Err err; | |
| 107 | |
| 108 // Dependency hierarchy: main(exe) -> datadep(exe) -> final_in(source set) | |
| 109 // -> dep(exe) -> final_out(source set) | |
| 110 // The final_in/out targets each have data files. final_in's should be | |
| 111 // included, final_out's should not be. | |
| 112 | |
| 113 Target final_in(setup.settings(), Label(SourceDir("//"), "final_in")); | |
| 114 InitTargetWithType(setup, &final_in, Target::SOURCE_SET); | |
| 115 final_in.data().push_back(SourceFile("//final_in.dat")); | |
| 116 ASSERT_TRUE(final_in.OnResolved(&err)); | |
| 117 | |
| 118 Target datadep(setup.settings(), Label(SourceDir("//"), "datadep")); | |
| 119 InitTargetWithType(setup, &datadep, Target::EXECUTABLE); | |
| 120 datadep.private_deps().push_back(LabelTargetPair(&final_in)); | |
| 121 ASSERT_TRUE(datadep.OnResolved(&err)); | |
| 122 | |
| 123 Target final_out(setup.settings(), Label(SourceDir("//"), "final_out")); | |
| 124 InitTargetWithType(setup, &final_out, Target::SOURCE_SET); | |
| 125 final_out.data().push_back(SourceFile("//final_out.dat")); | |
| 126 ASSERT_TRUE(final_out.OnResolved(&err)); | |
| 127 | |
| 128 Target dep(setup.settings(), Label(SourceDir("//"), "dep")); | |
| 129 InitTargetWithType(setup, &dep, Target::EXECUTABLE); | |
| 130 dep.private_deps().push_back(LabelTargetPair(&final_out)); | |
| 131 ASSERT_TRUE(dep.OnResolved(&err)); | |
| 132 | |
| 133 Target main(setup.settings(), Label(SourceDir("//"), "main")); | |
| 134 InitTargetWithType(setup, &main, Target::EXECUTABLE); | |
| 135 main.private_deps().push_back(LabelTargetPair(&dep)); | |
| 136 main.data_deps().push_back(LabelTargetPair(&datadep)); | |
| 137 ASSERT_TRUE(main.OnResolved(&err)); | |
| 138 | |
| 139 std::vector<std::pair<OutputFile, const Target*>> result = | |
| 140 ComputeRuntimeDeps(&main); | |
| 141 | |
| 142 // The result should have deps of main, datadep, final_in.dat | |
| 143 ASSERT_EQ(3u, result.size()) << GetVectorDescription(result); | |
| 144 | |
| 145 // The first one should always be the main exe. | |
| 146 EXPECT_TRUE(MakePair("./main", &main) == result[0]); | |
| 147 | |
| 148 // The rest of the ordering is undefined. | |
| 149 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 150 MakePair("./datadep", &datadep)) != | |
| 151 result.end()) << GetVectorDescription(result); | |
| 152 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 153 MakePair("../../final_in.dat", &final_in)) != | |
| 154 result.end()) << GetVectorDescription(result); | |
| 155 } | |
| 156 | |
| 157 // Tests that action outputs are considered if they're data deps, but not if | |
| 158 // they're regular deps. Script "data" files are always included. | |
| 159 TEST(RuntimeDeps, ActionOutputs) { | |
| 160 TestWithScope setup; | |
| 161 Err err; | |
| 162 | |
| 163 // Dependency hierarchy: main(exe) -> datadep(script) | |
| 164 // -> dep(script) | |
| 165 | |
| 166 Target datadep(setup.settings(), Label(SourceDir("//"), "datadep")); | |
| 167 InitTargetWithType(setup, &datadep, Target::ACTION); | |
| 168 datadep.data().push_back(SourceFile("//datadep.data")); | |
| 169 datadep.action_values().outputs() = | |
| 170 SubstitutionList::MakeForTest("//datadep.output"); | |
| 171 ASSERT_TRUE(datadep.OnResolved(&err)); | |
| 172 | |
| 173 Target dep(setup.settings(), Label(SourceDir("//"), "dep")); | |
| 174 InitTargetWithType(setup, &dep, Target::ACTION); | |
| 175 dep.data().push_back(SourceFile("//dep.data")); | |
| 176 dep.action_values().outputs() = | |
| 177 SubstitutionList::MakeForTest("//dep.output"); | |
| 178 ASSERT_TRUE(dep.OnResolved(&err)); | |
|
scottmg
2015/05/14 17:42:45
add a copy dependency here?
| |
| 179 | |
| 180 Target main(setup.settings(), Label(SourceDir("//"), "main")); | |
| 181 InitTargetWithType(setup, &main, Target::EXECUTABLE); | |
| 182 main.private_deps().push_back(LabelTargetPair(&dep)); | |
| 183 main.data_deps().push_back(LabelTargetPair(&datadep)); | |
| 184 ASSERT_TRUE(main.OnResolved(&err)); | |
| 185 | |
| 186 std::vector<std::pair<OutputFile, const Target*>> result = | |
| 187 ComputeRuntimeDeps(&main); | |
| 188 | |
| 189 // The result should have deps of main, both datadeps files, but only | |
| 190 // the data file from dep. | |
| 191 ASSERT_EQ(4u, result.size()) << GetVectorDescription(result); | |
| 192 | |
| 193 // The first one should always be the main exe. | |
| 194 EXPECT_TRUE(MakePair("./main", &main) == result[0]); | |
| 195 | |
| 196 // The rest of the ordering is undefined. | |
| 197 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 198 MakePair("../../datadep.data", &datadep)) != | |
| 199 result.end()) << GetVectorDescription(result); | |
| 200 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 201 MakePair("../../datadep.output", &datadep)) != | |
| 202 result.end()) << GetVectorDescription(result); | |
| 203 EXPECT_TRUE(std::find(result.begin(), result.end(), | |
| 204 MakePair("../../dep.data", &dep)) != | |
| 205 result.end()) << GetVectorDescription(result); | |
| 206 | |
| 207 // Explicitly asking for the runtime deps of an action target only includes | |
| 208 // the data and not all outputs. | |
| 209 result = ComputeRuntimeDeps(&dep); | |
| 210 ASSERT_EQ(1u, result.size()); | |
| 211 EXPECT_TRUE(MakePair("../../dep.data", &dep) == result[0]); | |
| 212 } | |
| OLD | NEW |