| 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));
|
| +
|
| + 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]);
|
| +}
|
|
|