xref: /aosp_15_r20/system/linkerconfig/contents/tests/configuration/include/configurationtest.h (revision e5eeaa8e05bc25a862c0c861bda7c8a6bfb42dad)
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