Chromium Code Reviews| Index: tools/gn/runtime_deps_unittest.cc |
| diff --git a/tools/gn/runtime_deps_unittest.cc b/tools/gn/runtime_deps_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..85c13d81fb63c37f506813b8db94295eaa2f2889 |
| --- /dev/null |
| +++ b/tools/gn/runtime_deps_unittest.cc |
| @@ -0,0 +1,212 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <algorithm> |
| + |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "tools/gn/runtime_deps.h" |
| +#include "tools/gn/target.h" |
| +#include "tools/gn/test_with_scope.h" |
| + |
| +namespace { |
| + |
| +void InitTargetWithType(TestWithScope& setup, |
| + Target* target, |
| + Target::OutputType type) { |
| + target->set_output_type(type); |
| + target->visibility().SetPublic(); |
| + target->SetToolchain(setup.toolchain()); |
| +} |
| + |
| +// Convenience function to make the correct kind of pair. |
| +std::pair<OutputFile, const Target*> MakePair(const char* str, |
| + const Target* t) { |
| + return std::pair<OutputFile, const Target*>(OutputFile(str), t); |
| +} |
| + |
| +std::string GetVectorDescription( |
| + const std::vector<std::pair<OutputFile, const Target*>>& v) { |
| + std::string result; |
| + for (size_t i = 0; i < v.size(); i++) { |
| + if (i != 0) |
| + result.append(", "); |
| + result.append("\"" + v[i].first.value() + "\""); |
| + } |
| + return result; |
| +} |
| + |
| +} // namespace |
| + |
| +// Tests an exe depending on different types of libraries. |
| +TEST(RuntimeDeps, Libs) { |
| + TestWithScope setup; |
| + Err err; |
| + |
| + // Dependency hierarchy: main(exe) -> stat |
| + // -> shared |
| + // -> set |
| + |
| + Target stat(setup.settings(), Label(SourceDir("//"), "stat")); |
| + InitTargetWithType(setup, &stat, Target::STATIC_LIBRARY); |
| + stat.data().push_back(SourceFile("//stat.dat")); |
| + ASSERT_TRUE(stat.OnResolved(&err)); |
| + |
| + Target shared(setup.settings(), Label(SourceDir("//"), "shared")); |
| + InitTargetWithType(setup, &shared, Target::SHARED_LIBRARY); |
| + shared.data().push_back(SourceFile("//shared.dat")); |
| + ASSERT_TRUE(shared.OnResolved(&err)); |
| + |
| + Target set(setup.settings(), Label(SourceDir("//"), "set")); |
| + InitTargetWithType(setup, &set, Target::SOURCE_SET); |
| + set.data().push_back(SourceFile("//set.dat")); |
| + ASSERT_TRUE(set.OnResolved(&err)); |
| + |
| + Target main(setup.settings(), Label(SourceDir("//"), "main")); |
| + InitTargetWithType(setup, &main, Target::EXECUTABLE); |
| + main.private_deps().push_back(LabelTargetPair(&stat)); |
| + main.private_deps().push_back(LabelTargetPair(&shared)); |
| + main.private_deps().push_back(LabelTargetPair(&set)); |
| + main.data().push_back(SourceFile("//main.dat")); |
| + ASSERT_TRUE(main.OnResolved(&err)); |
| + |
| + std::vector<std::pair<OutputFile, const Target*>> result = |
| + ComputeRuntimeDeps(&main); |
| + |
| + // The result should have deps of main, all 4 dat files, and libshared.so |
| + ASSERT_EQ(6u, result.size()) << GetVectorDescription(result); |
| + |
| + // The first one should always be the main exe. |
| + EXPECT_TRUE(MakePair("./main", &main) == result[0]); |
| + |
| + // The rest of the ordering is undefined. First the data files. |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../stat.dat", &stat)) != |
| + result.end()) << GetVectorDescription(result); |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../shared.dat", &shared)) != |
| + result.end()) << GetVectorDescription(result); |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../set.dat", &set)) != |
| + result.end()) << GetVectorDescription(result); |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../main.dat", &main)) != |
| + result.end()) << GetVectorDescription(result); |
| + |
| + // Check the static library |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("./libshared.so", &shared)) != |
| + result.end()) << GetVectorDescription(result); |
| +} |
| + |
| +// Tests that executables that aren't listed as data deps aren't included in |
| +// the output, but executables that are data deps are included. |
| +TEST(RuntimeDeps, ExeDataDep) { |
| + TestWithScope setup; |
| + Err err; |
| + |
| + // Dependency hierarchy: main(exe) -> datadep(exe) -> final_in(source set) |
| + // -> dep(exe) -> final_out(source set) |
| + // The final_in/out targets each have data files. final_in's should be |
| + // included, final_out's should not be. |
| + |
| + Target final_in(setup.settings(), Label(SourceDir("//"), "final_in")); |
| + InitTargetWithType(setup, &final_in, Target::SOURCE_SET); |
| + final_in.data().push_back(SourceFile("//final_in.dat")); |
| + ASSERT_TRUE(final_in.OnResolved(&err)); |
| + |
| + Target datadep(setup.settings(), Label(SourceDir("//"), "datadep")); |
| + InitTargetWithType(setup, &datadep, Target::EXECUTABLE); |
| + datadep.private_deps().push_back(LabelTargetPair(&final_in)); |
| + ASSERT_TRUE(datadep.OnResolved(&err)); |
| + |
| + Target final_out(setup.settings(), Label(SourceDir("//"), "final_out")); |
| + InitTargetWithType(setup, &final_out, Target::SOURCE_SET); |
| + final_out.data().push_back(SourceFile("//final_out.dat")); |
| + ASSERT_TRUE(final_out.OnResolved(&err)); |
| + |
| + Target dep(setup.settings(), Label(SourceDir("//"), "dep")); |
| + InitTargetWithType(setup, &dep, Target::EXECUTABLE); |
| + dep.private_deps().push_back(LabelTargetPair(&final_out)); |
| + ASSERT_TRUE(dep.OnResolved(&err)); |
| + |
| + Target main(setup.settings(), Label(SourceDir("//"), "main")); |
| + InitTargetWithType(setup, &main, Target::EXECUTABLE); |
| + main.private_deps().push_back(LabelTargetPair(&dep)); |
| + main.data_deps().push_back(LabelTargetPair(&datadep)); |
| + ASSERT_TRUE(main.OnResolved(&err)); |
| + |
| + std::vector<std::pair<OutputFile, const Target*>> result = |
| + ComputeRuntimeDeps(&main); |
| + |
| + // The result should have deps of main, datadep, final_in.dat |
| + ASSERT_EQ(3u, result.size()) << GetVectorDescription(result); |
| + |
| + // The first one should always be the main exe. |
| + EXPECT_TRUE(MakePair("./main", &main) == result[0]); |
| + |
| + // The rest of the ordering is undefined. |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("./datadep", &datadep)) != |
| + result.end()) << GetVectorDescription(result); |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../final_in.dat", &final_in)) != |
| + result.end()) << GetVectorDescription(result); |
| +} |
| + |
| +// Tests that action outputs are considered if they're data deps, but not if |
| +// they're regular deps. Script "data" files are always included. |
| +TEST(RuntimeDeps, ActionOutputs) { |
| + TestWithScope setup; |
| + Err err; |
| + |
| + // Dependency hierarchy: main(exe) -> datadep(script) |
| + // -> dep(script) |
| + |
| + Target datadep(setup.settings(), Label(SourceDir("//"), "datadep")); |
| + InitTargetWithType(setup, &datadep, Target::ACTION); |
| + datadep.data().push_back(SourceFile("//datadep.data")); |
| + datadep.action_values().outputs() = |
| + SubstitutionList::MakeForTest("//datadep.output"); |
| + ASSERT_TRUE(datadep.OnResolved(&err)); |
| + |
| + Target dep(setup.settings(), Label(SourceDir("//"), "dep")); |
| + InitTargetWithType(setup, &dep, Target::ACTION); |
| + dep.data().push_back(SourceFile("//dep.data")); |
| + dep.action_values().outputs() = |
| + SubstitutionList::MakeForTest("//dep.output"); |
| + ASSERT_TRUE(dep.OnResolved(&err)); |
|
scottmg
2015/05/14 17:42:45
add a copy dependency here?
|
| + |
| + Target main(setup.settings(), Label(SourceDir("//"), "main")); |
| + InitTargetWithType(setup, &main, Target::EXECUTABLE); |
| + main.private_deps().push_back(LabelTargetPair(&dep)); |
| + main.data_deps().push_back(LabelTargetPair(&datadep)); |
| + ASSERT_TRUE(main.OnResolved(&err)); |
| + |
| + std::vector<std::pair<OutputFile, const Target*>> result = |
| + ComputeRuntimeDeps(&main); |
| + |
| + // The result should have deps of main, both datadeps files, but only |
| + // the data file from dep. |
| + ASSERT_EQ(4u, result.size()) << GetVectorDescription(result); |
| + |
| + // The first one should always be the main exe. |
| + EXPECT_TRUE(MakePair("./main", &main) == result[0]); |
| + |
| + // The rest of the ordering is undefined. |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../datadep.data", &datadep)) != |
| + result.end()) << GetVectorDescription(result); |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../datadep.output", &datadep)) != |
| + result.end()) << GetVectorDescription(result); |
| + EXPECT_TRUE(std::find(result.begin(), result.end(), |
| + MakePair("../../dep.data", &dep)) != |
| + result.end()) << GetVectorDescription(result); |
| + |
| + // Explicitly asking for the runtime deps of an action target only includes |
| + // the data and not all outputs. |
| + result = ComputeRuntimeDeps(&dep); |
| + ASSERT_EQ(1u, result.size()); |
| + EXPECT_TRUE(MakePair("../../dep.data", &dep) == result[0]); |
| +} |