1*e5eeaa8eSAndroid Build Coastguard Worker /*
2*e5eeaa8eSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*e5eeaa8eSAndroid Build Coastguard Worker *
4*e5eeaa8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e5eeaa8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e5eeaa8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e5eeaa8eSAndroid Build Coastguard Worker *
8*e5eeaa8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e5eeaa8eSAndroid Build Coastguard Worker *
10*e5eeaa8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e5eeaa8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e5eeaa8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e5eeaa8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e5eeaa8eSAndroid Build Coastguard Worker * limitations under the License.
15*e5eeaa8eSAndroid Build Coastguard Worker */
16*e5eeaa8eSAndroid Build Coastguard Worker #pragma once
17*e5eeaa8eSAndroid Build Coastguard Worker
18*e5eeaa8eSAndroid Build Coastguard Worker #include <unordered_set>
19*e5eeaa8eSAndroid Build Coastguard Worker
20*e5eeaa8eSAndroid Build Coastguard Worker #include "gtest/gtest.h"
21*e5eeaa8eSAndroid Build Coastguard Worker #include "linkerconfigparser.h"
22*e5eeaa8eSAndroid Build Coastguard Worker #include "modules.h"
23*e5eeaa8eSAndroid Build Coastguard Worker
24*e5eeaa8eSAndroid Build Coastguard Worker namespace {
TraverseLink(const Namespace & ns,std::unordered_set<std::string> & visible_ns)25*e5eeaa8eSAndroid Build Coastguard Worker inline void TraverseLink(const Namespace& ns, std::unordered_set<std::string>& visible_ns) {
26*e5eeaa8eSAndroid Build Coastguard Worker if (visible_ns.count(ns.name) != 0) {
27*e5eeaa8eSAndroid Build Coastguard Worker return;
28*e5eeaa8eSAndroid Build Coastguard Worker }
29*e5eeaa8eSAndroid Build Coastguard Worker
30*e5eeaa8eSAndroid Build Coastguard Worker visible_ns.insert(ns.name);
31*e5eeaa8eSAndroid Build Coastguard Worker
32*e5eeaa8eSAndroid Build Coastguard Worker for (auto& [_, link] : ns.links) {
33*e5eeaa8eSAndroid Build Coastguard Worker TraverseLink(*link.to, visible_ns);
34*e5eeaa8eSAndroid Build Coastguard Worker }
35*e5eeaa8eSAndroid Build Coastguard Worker }
36*e5eeaa8eSAndroid Build Coastguard Worker
ValidateAllNamespacesAreVisible(const Section & section)37*e5eeaa8eSAndroid Build Coastguard Worker inline void ValidateAllNamespacesAreVisible(const Section& section) {
38*e5eeaa8eSAndroid Build Coastguard Worker std::unordered_set<std::string> visible_ns;
39*e5eeaa8eSAndroid Build Coastguard Worker for (auto& [_, ns] : section.namespaces) {
40*e5eeaa8eSAndroid Build Coastguard Worker if (ns.name == "default" || ns.is_visible) {
41*e5eeaa8eSAndroid Build Coastguard Worker TraverseLink(ns, visible_ns);
42*e5eeaa8eSAndroid Build Coastguard Worker }
43*e5eeaa8eSAndroid Build Coastguard Worker }
44*e5eeaa8eSAndroid Build Coastguard Worker
45*e5eeaa8eSAndroid Build Coastguard Worker for (auto& [_, ns] : section.namespaces) {
46*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_EQ(1u, visible_ns.count(ns.name))
47*e5eeaa8eSAndroid Build Coastguard Worker << "Namespace " << ns.name << " is not visible from section " << section.name;
48*e5eeaa8eSAndroid Build Coastguard Worker }
49*e5eeaa8eSAndroid Build Coastguard Worker }
50*e5eeaa8eSAndroid Build Coastguard Worker
ValidateNamespace(const Namespace & target_namespace,const Section & parent_section)51*e5eeaa8eSAndroid Build Coastguard Worker inline void ValidateNamespace(const Namespace& target_namespace, const Section& parent_section) {
52*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_FALSE(target_namespace.name.empty()) << "Namespace name should not be empty";
53*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_FALSE(target_namespace.name != "default" && target_namespace.search_path.empty() &&
54*e5eeaa8eSAndroid Build Coastguard Worker target_namespace.permitted_path.empty())
55*e5eeaa8eSAndroid Build Coastguard Worker << "Search path or permitted path should be defined in namespace " << target_namespace.name
56*e5eeaa8eSAndroid Build Coastguard Worker << " from section " << parent_section.name;
57*e5eeaa8eSAndroid Build Coastguard Worker }
58*e5eeaa8eSAndroid Build Coastguard Worker
ValidateSection(const Section & section)59*e5eeaa8eSAndroid Build Coastguard Worker inline void ValidateSection(const Section& section) {
60*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_FALSE(section.name.empty()) << "Section name should not be empty";
61*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_NE(0u, section.namespaces.size())
62*e5eeaa8eSAndroid Build Coastguard Worker << "Section " << section.name << " should contain at least one namespace";
63*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_NE(0u, section.dirs.size())
64*e5eeaa8eSAndroid Build Coastguard Worker << "Section " << section.name << "does not contain any directory as executable path";
65*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_TRUE(MapContainsKey(section.namespaces, std::string("default")))
66*e5eeaa8eSAndroid Build Coastguard Worker << "Section " << section.name << " should contain namespace named 'default'";
67*e5eeaa8eSAndroid Build Coastguard Worker
68*e5eeaa8eSAndroid Build Coastguard Worker for (auto& [_, target_namespace] : section.namespaces) {
69*e5eeaa8eSAndroid Build Coastguard Worker ValidateNamespace(target_namespace, section);
70*e5eeaa8eSAndroid Build Coastguard Worker }
71*e5eeaa8eSAndroid Build Coastguard Worker
72*e5eeaa8eSAndroid Build Coastguard Worker ValidateAllNamespacesAreVisible(section);
73*e5eeaa8eSAndroid Build Coastguard Worker }
74*e5eeaa8eSAndroid Build Coastguard Worker
ValidateConfiguration(const Configuration & conf)75*e5eeaa8eSAndroid Build Coastguard Worker inline void ValidateConfiguration(const Configuration& conf) {
76*e5eeaa8eSAndroid Build Coastguard Worker EXPECT_NE(0u, conf.sections.size());
77*e5eeaa8eSAndroid Build Coastguard Worker for (auto& [_, section] : conf.sections) {
78*e5eeaa8eSAndroid Build Coastguard Worker ValidateSection(section);
79*e5eeaa8eSAndroid Build Coastguard Worker }
80*e5eeaa8eSAndroid Build Coastguard Worker }
81*e5eeaa8eSAndroid Build Coastguard Worker } // namespace
82*e5eeaa8eSAndroid Build Coastguard Worker
VerifyConfiguration(const std::string & configuration_str)83*e5eeaa8eSAndroid Build Coastguard Worker inline void VerifyConfiguration(const std::string& configuration_str) {
84*e5eeaa8eSAndroid Build Coastguard Worker Configuration conf;
85*e5eeaa8eSAndroid Build Coastguard Worker ParseConfiguration(configuration_str, conf);
86*e5eeaa8eSAndroid Build Coastguard Worker ValidateConfiguration(conf);
87*e5eeaa8eSAndroid Build Coastguard Worker }
88