xref: /aosp_15_r20/system/libvintf/test/VintfObjectRecoveryTest.cpp (revision 70a7ec852fcefd15a4fb57f8f183a8b1c3aacb08)
1*70a7ec85SAndroid Build Coastguard Worker /*
2*70a7ec85SAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*70a7ec85SAndroid Build Coastguard Worker  *
4*70a7ec85SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*70a7ec85SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*70a7ec85SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*70a7ec85SAndroid Build Coastguard Worker  *
8*70a7ec85SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*70a7ec85SAndroid Build Coastguard Worker  *
10*70a7ec85SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*70a7ec85SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*70a7ec85SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*70a7ec85SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*70a7ec85SAndroid Build Coastguard Worker  * limitations under the License.
15*70a7ec85SAndroid Build Coastguard Worker  */
16*70a7ec85SAndroid Build Coastguard Worker 
17*70a7ec85SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
18*70a7ec85SAndroid Build Coastguard Worker #include <android-base/strings.h>
19*70a7ec85SAndroid Build Coastguard Worker #include <gmock/gmock.h>
20*70a7ec85SAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*70a7ec85SAndroid Build Coastguard Worker #include <vintf/VintfObjectRecovery.h>
22*70a7ec85SAndroid Build Coastguard Worker #include <vintf/parse_string.h>
23*70a7ec85SAndroid Build Coastguard Worker 
24*70a7ec85SAndroid Build Coastguard Worker #include "constants-private.h"
25*70a7ec85SAndroid Build Coastguard Worker #include "test_constants.h"
26*70a7ec85SAndroid Build Coastguard Worker #include "utils-fake.h"
27*70a7ec85SAndroid Build Coastguard Worker 
28*70a7ec85SAndroid Build Coastguard Worker using android::base::ConsumePrefix;
29*70a7ec85SAndroid Build Coastguard Worker using android::base::StringPrintf;
30*70a7ec85SAndroid Build Coastguard Worker using testing::_;
31*70a7ec85SAndroid Build Coastguard Worker using testing::Combine;
32*70a7ec85SAndroid Build Coastguard Worker using testing::Invoke;
33*70a7ec85SAndroid Build Coastguard Worker using testing::IsEmpty;
34*70a7ec85SAndroid Build Coastguard Worker using testing::Mock;
35*70a7ec85SAndroid Build Coastguard Worker using testing::NiceMock;
36*70a7ec85SAndroid Build Coastguard Worker using testing::StartsWith;
37*70a7ec85SAndroid Build Coastguard Worker using testing::StrEq;
38*70a7ec85SAndroid Build Coastguard Worker using testing::TestParamInfo;
39*70a7ec85SAndroid Build Coastguard Worker using testing::UnorderedElementsAre;
40*70a7ec85SAndroid Build Coastguard Worker using testing::ValuesIn;
41*70a7ec85SAndroid Build Coastguard Worker 
42*70a7ec85SAndroid Build Coastguard Worker namespace android::vintf::testing {
43*70a7ec85SAndroid Build Coastguard Worker 
44*70a7ec85SAndroid Build Coastguard Worker using details::kSystemManifest;
45*70a7ec85SAndroid Build Coastguard Worker using details::kSystemManifestFragmentDir;
46*70a7ec85SAndroid Build Coastguard Worker using details::MockFileSystemWithError;
47*70a7ec85SAndroid Build Coastguard Worker using details::MockPropertyFetcher;
48*70a7ec85SAndroid Build Coastguard Worker using details::MockRuntimeInfo;
49*70a7ec85SAndroid Build Coastguard Worker using details::MockRuntimeInfoFactory;
50*70a7ec85SAndroid Build Coastguard Worker 
51*70a7ec85SAndroid Build Coastguard Worker template <typename T>
52*70a7ec85SAndroid Build Coastguard Worker using StatusOr = std::variant<status_t, T>;
53*70a7ec85SAndroid Build Coastguard Worker 
54*70a7ec85SAndroid Build Coastguard Worker using DirectoryContent = std::map<std::string, StatusOr<std::string>>;
55*70a7ec85SAndroid Build Coastguard Worker 
56*70a7ec85SAndroid Build Coastguard Worker using OptionalType = std::optional<SchemaType>;
OptionalTypes()57*70a7ec85SAndroid Build Coastguard Worker std::vector<OptionalType> OptionalTypes() {
58*70a7ec85SAndroid Build Coastguard Worker     return {std::nullopt, SchemaType::DEVICE, SchemaType::FRAMEWORK};
59*70a7ec85SAndroid Build Coastguard Worker }
60*70a7ec85SAndroid Build Coastguard Worker 
OptionalTypeToString(const OptionalType & optionalType)61*70a7ec85SAndroid Build Coastguard Worker std::string OptionalTypeToString(const OptionalType& optionalType) {
62*70a7ec85SAndroid Build Coastguard Worker     if (!optionalType.has_value()) return "broken";
63*70a7ec85SAndroid Build Coastguard Worker     return to_string(*optionalType);
64*70a7ec85SAndroid Build Coastguard Worker }
65*70a7ec85SAndroid Build Coastguard Worker 
66*70a7ec85SAndroid Build Coastguard Worker constexpr const char* kMainFmt = R"(<manifest %s type="%s">
67*70a7ec85SAndroid Build Coastguard Worker     <hal format="aidl">
68*70a7ec85SAndroid Build Coastguard Worker         <name>android.hardware.main</name>
69*70a7ec85SAndroid Build Coastguard Worker         <fqname>IMain/default</fqname>
70*70a7ec85SAndroid Build Coastguard Worker     </hal>
71*70a7ec85SAndroid Build Coastguard Worker </manifest>
72*70a7ec85SAndroid Build Coastguard Worker )";
73*70a7ec85SAndroid Build Coastguard Worker 
74*70a7ec85SAndroid Build Coastguard Worker constexpr const char* kFragment1Fmt = R"(<manifest %s type="%s">
75*70a7ec85SAndroid Build Coastguard Worker     <hal format="aidl">
76*70a7ec85SAndroid Build Coastguard Worker         <name>android.hardware.fragment1</name>
77*70a7ec85SAndroid Build Coastguard Worker         <fqname>IFragment/default</fqname>
78*70a7ec85SAndroid Build Coastguard Worker     </hal>
79*70a7ec85SAndroid Build Coastguard Worker </manifest>
80*70a7ec85SAndroid Build Coastguard Worker )";
81*70a7ec85SAndroid Build Coastguard Worker 
82*70a7ec85SAndroid Build Coastguard Worker constexpr const char* kFragment2Fmt = R"(<manifest %s type="%s">
83*70a7ec85SAndroid Build Coastguard Worker     <hal format="aidl">
84*70a7ec85SAndroid Build Coastguard Worker         <name>android.hardware.fragment2</name>
85*70a7ec85SAndroid Build Coastguard Worker         <fqname>IFragment/default</fqname>
86*70a7ec85SAndroid Build Coastguard Worker     </hal>
87*70a7ec85SAndroid Build Coastguard Worker </manifest>
88*70a7ec85SAndroid Build Coastguard Worker )";
89*70a7ec85SAndroid Build Coastguard Worker 
formatManifest(const char * fmt,const OptionalType & optionalType)90*70a7ec85SAndroid Build Coastguard Worker std::string formatManifest(const char* fmt, const OptionalType& optionalType) {
91*70a7ec85SAndroid Build Coastguard Worker     if (!optionalType.has_value()) {
92*70a7ec85SAndroid Build Coastguard Worker         return "(broken manifest)";
93*70a7ec85SAndroid Build Coastguard Worker     }
94*70a7ec85SAndroid Build Coastguard Worker     return StringPrintf(fmt, kMetaVersionStr.c_str(), to_string(*optionalType).c_str());
95*70a7ec85SAndroid Build Coastguard Worker }
96*70a7ec85SAndroid Build Coastguard Worker 
97*70a7ec85SAndroid Build Coastguard Worker using VintfObjectRecoveryTestParam = std::tuple<OptionalType, OptionalType, OptionalType>;
98*70a7ec85SAndroid Build Coastguard Worker class VintfObjectRecoveryTest : public ::testing::TestWithParam<VintfObjectRecoveryTestParam> {
99*70a7ec85SAndroid Build Coastguard Worker    public:
SetUp()100*70a7ec85SAndroid Build Coastguard Worker     virtual void SetUp() {
101*70a7ec85SAndroid Build Coastguard Worker         vintfObject = VintfObjectRecovery::Builder()
102*70a7ec85SAndroid Build Coastguard Worker                           .setFileSystem(std::make_unique<NiceMock<MockFileSystemWithError>>())
103*70a7ec85SAndroid Build Coastguard Worker                           .setRuntimeInfoFactory(std::make_unique<NiceMock<MockRuntimeInfoFactory>>(
104*70a7ec85SAndroid Build Coastguard Worker                               std::make_shared<NiceMock<MockRuntimeInfo>>()))
105*70a7ec85SAndroid Build Coastguard Worker                           .setPropertyFetcher(std::make_unique<NiceMock<MockPropertyFetcher>>())
106*70a7ec85SAndroid Build Coastguard Worker                           .build<VintfObjectRecovery>();
107*70a7ec85SAndroid Build Coastguard Worker         auto [mainType, fragType1, fragType2] = GetParam();
108*70a7ec85SAndroid Build Coastguard Worker         main = formatManifest(kMainFmt, mainType);
109*70a7ec85SAndroid Build Coastguard Worker         frag1 = formatManifest(kFragment1Fmt, fragType1);
110*70a7ec85SAndroid Build Coastguard Worker         frag2 = formatManifest(kFragment2Fmt, fragType2);
111*70a7ec85SAndroid Build Coastguard Worker     }
TearDown()112*70a7ec85SAndroid Build Coastguard Worker     virtual void TearDown() { Mock::VerifyAndClear(&fs()); }
113*70a7ec85SAndroid Build Coastguard Worker 
fs()114*70a7ec85SAndroid Build Coastguard Worker     MockFileSystemWithError& fs() {
115*70a7ec85SAndroid Build Coastguard Worker         return static_cast<MockFileSystemWithError&>(*vintfObject->getFileSystem());
116*70a7ec85SAndroid Build Coastguard Worker     }
117*70a7ec85SAndroid Build Coastguard Worker 
setUpManifests(const StatusOr<std::string> & mainContent,const StatusOr<DirectoryContent> & frags)118*70a7ec85SAndroid Build Coastguard Worker     void setUpManifests(const StatusOr<std::string>& mainContent,
119*70a7ec85SAndroid Build Coastguard Worker                         const StatusOr<DirectoryContent>& frags) {
120*70a7ec85SAndroid Build Coastguard Worker         // By default, no files exist in the file system.
121*70a7ec85SAndroid Build Coastguard Worker         ON_CALL(fs(), listFiles(_, _, _)).WillByDefault(Return(NAME_NOT_FOUND));
122*70a7ec85SAndroid Build Coastguard Worker         ON_CALL(fs(), fetch(_, _, _))
123*70a7ec85SAndroid Build Coastguard Worker             .WillByDefault(Invoke([](const auto& path, auto*, auto* error) {
124*70a7ec85SAndroid Build Coastguard Worker                 if (error != nullptr) {
125*70a7ec85SAndroid Build Coastguard Worker                     *error = "fetch " + path + ": cannot be found on empty filesystem: " +
126*70a7ec85SAndroid Build Coastguard Worker                              statusToString(NAME_NOT_FOUND);
127*70a7ec85SAndroid Build Coastguard Worker                 }
128*70a7ec85SAndroid Build Coastguard Worker                 return NAME_NOT_FOUND;
129*70a7ec85SAndroid Build Coastguard Worker             }));
130*70a7ec85SAndroid Build Coastguard Worker         ON_CALL(fs(), fetch(StrEq(kSystemManifest), _, _))
131*70a7ec85SAndroid Build Coastguard Worker             .WillByDefault(Invoke([=](const auto& path, auto* content, auto* error) -> status_t {
132*70a7ec85SAndroid Build Coastguard Worker                 if (std::holds_alternative<status_t>(mainContent)) {
133*70a7ec85SAndroid Build Coastguard Worker                     if (error != nullptr) {
134*70a7ec85SAndroid Build Coastguard Worker                         *error = "fetch " + path + ": set to return " +
135*70a7ec85SAndroid Build Coastguard Worker                                  statusToString(std::get<status_t>(mainContent));
136*70a7ec85SAndroid Build Coastguard Worker                     }
137*70a7ec85SAndroid Build Coastguard Worker                     return std::get<status_t>(mainContent);
138*70a7ec85SAndroid Build Coastguard Worker                 }
139*70a7ec85SAndroid Build Coastguard Worker                 *content = std::get<std::string>(mainContent);
140*70a7ec85SAndroid Build Coastguard Worker                 return OK;
141*70a7ec85SAndroid Build Coastguard Worker             }));
142*70a7ec85SAndroid Build Coastguard Worker         ON_CALL(fs(), listFiles(StrEq(kSystemManifestFragmentDir), _, _))
143*70a7ec85SAndroid Build Coastguard Worker             .WillByDefault(Invoke([=](const std::string& path, std::vector<std::string>* out,
144*70a7ec85SAndroid Build Coastguard Worker                                       auto* error) -> status_t {
145*70a7ec85SAndroid Build Coastguard Worker                 if (std::holds_alternative<status_t>(frags)) {
146*70a7ec85SAndroid Build Coastguard Worker                     if (error != nullptr) {
147*70a7ec85SAndroid Build Coastguard Worker                         *error = "list " + path + ": set to return " +
148*70a7ec85SAndroid Build Coastguard Worker                                  statusToString(std::get<status_t>(frags));
149*70a7ec85SAndroid Build Coastguard Worker                     }
150*70a7ec85SAndroid Build Coastguard Worker                     return std::get<status_t>(frags);
151*70a7ec85SAndroid Build Coastguard Worker                 }
152*70a7ec85SAndroid Build Coastguard Worker                 for (const auto& [name, statusOrFile] : std::get<DirectoryContent>(frags)) {
153*70a7ec85SAndroid Build Coastguard Worker                     out->push_back(name);
154*70a7ec85SAndroid Build Coastguard Worker                 }
155*70a7ec85SAndroid Build Coastguard Worker                 return OK;
156*70a7ec85SAndroid Build Coastguard Worker             }));
157*70a7ec85SAndroid Build Coastguard Worker         ON_CALL(fs(), fetch(StartsWith(kSystemManifestFragmentDir), _, _))
158*70a7ec85SAndroid Build Coastguard Worker             .WillByDefault(Invoke([=](const auto& path, auto* content, auto* error) -> status_t {
159*70a7ec85SAndroid Build Coastguard Worker                 if (std::holds_alternative<status_t>(frags)) {
160*70a7ec85SAndroid Build Coastguard Worker                     if (error != nullptr) {
161*70a7ec85SAndroid Build Coastguard Worker                         *error = "fetch " + path + ": for dir, set to return " +
162*70a7ec85SAndroid Build Coastguard Worker                                  statusToString(std::get<status_t>(frags));
163*70a7ec85SAndroid Build Coastguard Worker                     }
164*70a7ec85SAndroid Build Coastguard Worker                     return std::get<status_t>(frags);
165*70a7ec85SAndroid Build Coastguard Worker                 }
166*70a7ec85SAndroid Build Coastguard Worker                 const auto& directoryContent = std::get<DirectoryContent>(frags);
167*70a7ec85SAndroid Build Coastguard Worker                 std::string_view subpath = path;
168*70a7ec85SAndroid Build Coastguard Worker                 bool consumed = ConsumePrefix(&subpath, kSystemManifestFragmentDir);
169*70a7ec85SAndroid Build Coastguard Worker                 EXPECT_TRUE(consumed)
170*70a7ec85SAndroid Build Coastguard Worker                     << path << " does not start with " << kSystemManifestFragmentDir;
171*70a7ec85SAndroid Build Coastguard Worker                 auto it = directoryContent.find(std::string(subpath));
172*70a7ec85SAndroid Build Coastguard Worker                 if (it == directoryContent.end()) {
173*70a7ec85SAndroid Build Coastguard Worker                     if (error != nullptr) {
174*70a7ec85SAndroid Build Coastguard Worker                         *error = "fetch " + path +
175*70a7ec85SAndroid Build Coastguard Worker                                  ": not in DirectoryContent: " + statusToString(NAME_NOT_FOUND);
176*70a7ec85SAndroid Build Coastguard Worker                     }
177*70a7ec85SAndroid Build Coastguard Worker                     return NAME_NOT_FOUND;
178*70a7ec85SAndroid Build Coastguard Worker                 }
179*70a7ec85SAndroid Build Coastguard Worker 
180*70a7ec85SAndroid Build Coastguard Worker                 const auto& [name, statusOrFile] = *it;
181*70a7ec85SAndroid Build Coastguard Worker                 if (std::holds_alternative<status_t>(statusOrFile)) {
182*70a7ec85SAndroid Build Coastguard Worker                     *error = "fetch " + path + ": for file, set to return " +
183*70a7ec85SAndroid Build Coastguard Worker                              statusToString(std::get<status_t>(statusOrFile));
184*70a7ec85SAndroid Build Coastguard Worker                     return std::get<status_t>(statusOrFile);
185*70a7ec85SAndroid Build Coastguard Worker                 }
186*70a7ec85SAndroid Build Coastguard Worker                 *content = std::get<std::string>(statusOrFile);
187*70a7ec85SAndroid Build Coastguard Worker                 return OK;
188*70a7ec85SAndroid Build Coastguard Worker             }));
189*70a7ec85SAndroid Build Coastguard Worker     }
190*70a7ec85SAndroid Build Coastguard Worker 
ParamToString(const TestParamInfo<ParamType> & info)191*70a7ec85SAndroid Build Coastguard Worker     static std::string ParamToString(const TestParamInfo<ParamType>& info) {
192*70a7ec85SAndroid Build Coastguard Worker         auto [mainType, fragType1, fragType2] = info.param;
193*70a7ec85SAndroid Build Coastguard Worker         auto s = "main_" + OptionalTypeToString(mainType);
194*70a7ec85SAndroid Build Coastguard Worker         s += "_frag1_" + OptionalTypeToString(fragType1);
195*70a7ec85SAndroid Build Coastguard Worker         s += "_frag2_" + OptionalTypeToString(fragType2);
196*70a7ec85SAndroid Build Coastguard Worker         return s;
197*70a7ec85SAndroid Build Coastguard Worker     }
198*70a7ec85SAndroid Build Coastguard Worker 
199*70a7ec85SAndroid Build Coastguard Worker     std::unique_ptr<VintfObjectRecovery> vintfObject;
200*70a7ec85SAndroid Build Coastguard Worker     std::string main;
201*70a7ec85SAndroid Build Coastguard Worker     std::string frag1;
202*70a7ec85SAndroid Build Coastguard Worker     std::string frag2;
203*70a7ec85SAndroid Build Coastguard Worker };
204*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,Empty)205*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, Empty) {
206*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(NAME_NOT_FOUND, NAME_NOT_FOUND);
207*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
208*70a7ec85SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, manifest);
209*70a7ec85SAndroid Build Coastguard Worker     auto hals = manifest->getHalNames();
210*70a7ec85SAndroid Build Coastguard Worker     EXPECT_THAT(hals, IsEmpty());
211*70a7ec85SAndroid Build Coastguard Worker }
212*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,InaccessibleMainManifest)213*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, InaccessibleMainManifest) {
214*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(UNKNOWN_ERROR, NAME_NOT_FOUND);
215*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
216*70a7ec85SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, manifest);
217*70a7ec85SAndroid Build Coastguard Worker }
218*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,MainManifestOnly)219*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, MainManifestOnly) {
220*70a7ec85SAndroid Build Coastguard Worker     auto [mainType, fragType1, fragType2] = GetParam();
221*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(main, NAME_NOT_FOUND);
222*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
223*70a7ec85SAndroid Build Coastguard Worker     if (!mainType.has_value()) {  // main manifest is broken
224*70a7ec85SAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, manifest);
225*70a7ec85SAndroid Build Coastguard Worker         return;
226*70a7ec85SAndroid Build Coastguard Worker     }
227*70a7ec85SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, manifest);
228*70a7ec85SAndroid Build Coastguard Worker     EXPECT_THAT(manifest->getHalNames(), UnorderedElementsAre("android.hardware.main"));
229*70a7ec85SAndroid Build Coastguard Worker }
230*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,MainManifestAndDirectoryOnly)231*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, MainManifestAndDirectoryOnly) {
232*70a7ec85SAndroid Build Coastguard Worker     auto [mainType, fragType1, fragType2] = GetParam();
233*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(main, {});
234*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
235*70a7ec85SAndroid Build Coastguard Worker     if (!mainType.has_value()) {  // main manifest is broken
236*70a7ec85SAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, manifest);
237*70a7ec85SAndroid Build Coastguard Worker         return;
238*70a7ec85SAndroid Build Coastguard Worker     }
239*70a7ec85SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, manifest);
240*70a7ec85SAndroid Build Coastguard Worker     EXPECT_THAT(manifest->getHalNames(), UnorderedElementsAre("android.hardware.main"));
241*70a7ec85SAndroid Build Coastguard Worker }
242*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,MainManifestAndInaccessibleFragment)243*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, MainManifestAndInaccessibleFragment) {
244*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(main, DirectoryContent{{"frag1.xml", UNKNOWN_ERROR}});
245*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
246*70a7ec85SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, manifest);
247*70a7ec85SAndroid Build Coastguard Worker }
248*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,MainManifestAndFragments)249*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, MainManifestAndFragments) {
250*70a7ec85SAndroid Build Coastguard Worker     auto [mainType, fragType1, fragType2] = GetParam();
251*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(main, DirectoryContent{{"frag1.xml", frag1}, {"frag2.xml", frag2}});
252*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
253*70a7ec85SAndroid Build Coastguard Worker     if (!mainType.has_value() || !fragType1.has_value() || !fragType2.has_value()) {
254*70a7ec85SAndroid Build Coastguard Worker         // some manifest(s) are broken
255*70a7ec85SAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, manifest);
256*70a7ec85SAndroid Build Coastguard Worker         return;
257*70a7ec85SAndroid Build Coastguard Worker     }
258*70a7ec85SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, manifest);
259*70a7ec85SAndroid Build Coastguard Worker     EXPECT_THAT(manifest->getHalNames(),
260*70a7ec85SAndroid Build Coastguard Worker                 UnorderedElementsAre("android.hardware.main", "android.hardware.fragment1",
261*70a7ec85SAndroid Build Coastguard Worker                                      "android.hardware.fragment2"));
262*70a7ec85SAndroid Build Coastguard Worker }
263*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,InaccessibleDirectory)264*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, InaccessibleDirectory) {
265*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(NAME_NOT_FOUND, UNKNOWN_ERROR);
266*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
267*70a7ec85SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, manifest);
268*70a7ec85SAndroid Build Coastguard Worker }
269*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,InaccessibleFragment)270*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, InaccessibleFragment) {
271*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(NAME_NOT_FOUND, DirectoryContent{{"frag1.xml", UNKNOWN_ERROR}});
272*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
273*70a7ec85SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, manifest);
274*70a7ec85SAndroid Build Coastguard Worker }
275*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,SomeInaccessibleFragment)276*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, SomeInaccessibleFragment) {
277*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(NAME_NOT_FOUND,
278*70a7ec85SAndroid Build Coastguard Worker                    DirectoryContent{{"frag1.xml", UNKNOWN_ERROR}, {"frag2.xml", frag2}});
279*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
280*70a7ec85SAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, manifest);
281*70a7ec85SAndroid Build Coastguard Worker }
282*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,DirectoryOnly)283*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, DirectoryOnly) {
284*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(NAME_NOT_FOUND, {});
285*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
286*70a7ec85SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, manifest);
287*70a7ec85SAndroid Build Coastguard Worker     EXPECT_THAT(manifest->getHalNames(), IsEmpty());
288*70a7ec85SAndroid Build Coastguard Worker }
289*70a7ec85SAndroid Build Coastguard Worker 
TEST_P(VintfObjectRecoveryTest,FragmentsOnly)290*70a7ec85SAndroid Build Coastguard Worker TEST_P(VintfObjectRecoveryTest, FragmentsOnly) {
291*70a7ec85SAndroid Build Coastguard Worker     auto [mainType, fragType1, fragType2] = GetParam();
292*70a7ec85SAndroid Build Coastguard Worker     setUpManifests(NAME_NOT_FOUND, DirectoryContent{{"frag1.xml", frag1}, {"frag2.xml", frag2}});
293*70a7ec85SAndroid Build Coastguard Worker     auto manifest = vintfObject->getRecoveryHalManifest();
294*70a7ec85SAndroid Build Coastguard Worker     if (!fragType1.has_value() || !fragType2.has_value()) {
295*70a7ec85SAndroid Build Coastguard Worker         // some manifest(s) are broken
296*70a7ec85SAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, manifest);
297*70a7ec85SAndroid Build Coastguard Worker         return;
298*70a7ec85SAndroid Build Coastguard Worker     }
299*70a7ec85SAndroid Build Coastguard Worker     ASSERT_NE(nullptr, manifest);
300*70a7ec85SAndroid Build Coastguard Worker     EXPECT_THAT(manifest->getHalNames(),
301*70a7ec85SAndroid Build Coastguard Worker                 UnorderedElementsAre("android.hardware.fragment1", "android.hardware.fragment2"));
302*70a7ec85SAndroid Build Coastguard Worker }
303*70a7ec85SAndroid Build Coastguard Worker 
304*70a7ec85SAndroid Build Coastguard Worker INSTANTIATE_TEST_CASE_P(VintfObjectRecoveryTest, VintfObjectRecoveryTest,
305*70a7ec85SAndroid Build Coastguard Worker                         Combine(ValuesIn(OptionalTypes()), ValuesIn(OptionalTypes()),
306*70a7ec85SAndroid Build Coastguard Worker                                 ValuesIn(OptionalTypes())),
307*70a7ec85SAndroid Build Coastguard Worker                         VintfObjectRecoveryTest::ParamToString);
308*70a7ec85SAndroid Build Coastguard Worker 
309*70a7ec85SAndroid Build Coastguard Worker }  // namespace android::vintf::testing
310