xref: /aosp_15_r20/system/libvintf/test/AssembleVintfTest.cpp (revision 70a7ec852fcefd15a4fb57f8f183a8b1c3aacb08)
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "AssembleVintfTest"
18 
19 #include <android-base/logging.h>
20 #include <android-base/stringprintf.h>
21 #include <gtest/gtest.h>
22 
23 #include <aidl/metadata.h>
24 #include <vintf/AssembleVintf.h>
25 #include <vintf/parse_string.h>
26 #include "constants-private.h"
27 #include "test_constants.h"
28 
29 using android::base::StringPrintf;
30 
31 namespace android {
32 namespace vintf {
33 
In(const std::string & sub,const std::string & str)34 static bool In(const std::string& sub, const std::string& str) {
35     return str.find(sub) != std::string::npos;
36 }
37 #define EXPECT_IN(sub, str) EXPECT_TRUE(In((sub), (str))) << (str);
38 
39 class AssembleVintfTest : public ::testing::Test {
40    public:
SetUp()41     virtual void SetUp() override {
42         mInstance = AssembleVintf::newInstance();
43         auto s = makeStream("");
44         mOutputStream = s.get();
45         mInstance->setOutputStream(std::move(s));
46         s = makeStream("");
47         mErrorStream = s.get();
48         mInstance->setErrorStream(std::move(s));
49 
50         getInstance()->setFakeEnv("PRODUCT_ENFORCE_VINTF_MANIFEST", "true");
51     }
TearDown()52     virtual void TearDown() override { mInstance = nullptr; }
53 
getInstance()54     const std::unique_ptr<AssembleVintf>& getInstance() { return mInstance; }
55 
getOutput()56     std::string getOutput() { return mOutputStream->str(); }
getError()57     std::string getError() { return mErrorStream->str(); }
58 
resetOutput()59     void resetOutput() { mOutputStream->str(""); }
60 
setFakeEnvs(const std::map<std::string,std::string> & envs)61     void setFakeEnvs(const std::map<std::string, std::string>& envs) {
62         for (const auto& pair : envs) {
63             getInstance()->setFakeEnv(pair.first, pair.second);
64         }
65     }
66 
setFakeAidlMetadata(const std::vector<AidlInterfaceMetadata> & metadata)67     void setFakeAidlMetadata(const std::vector<AidlInterfaceMetadata>& metadata) {
68         getInstance()->setFakeAidlMetadata(metadata);
69     }
70 
setFakeAidlUseUnfrozen(bool use)71     void setFakeAidlUseUnfrozen(bool use) { getInstance()->setFakeAidlUseUnfrozen(use); }
72 
addInput(const std::string & name,const std::string & s)73     void addInput(const std::string& name, const std::string& s) {
74         getInstance()->addInputStream(name, makeStream(s));
75     }
76 
makeStream(const std::string & s)77     std::unique_ptr<std::stringstream> makeStream(const std::string& s) {
78         return std::make_unique<std::stringstream>(s);
79     }
80 
81     std::unique_ptr<AssembleVintf> mInstance;
82     // do not own this object.
83     std::stringstream* mOutputStream;
84     std::stringstream* mErrorStream;
85 };
86 
87 // clang-format off
88 
TEST_F(AssembleVintfTest,FrameworkMatrixEmpty)89 TEST_F(AssembleVintfTest, FrameworkMatrixEmpty) {
90     std::string xmlEmpty = "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" />";
91     std::string kernel318 = "CONFIG_FOO=y\n";
92     std::string kernel318_64 = "CONFIG_BAR=y\n";
93     std::string kernel44 = "# CONFIG_FOO is not set\n";
94     std::string kernel44_64 = "CONFIG_BAR=y\n";
95 
96     addInput("compatibility_matrix.empty.xml", xmlEmpty);
97     setFakeEnvs({
98         {"POLICYVERS", "30"},
99         {"PLATFORM_SEPOLICY_VERSION", "202404"},
100         {"FRAMEWORK_VBMETA_VERSION", "1.0"},
101     });
102     getInstance()->addKernelConfigInputStream({3, 18, 0}, "android-base.config",
103                                               makeStream(kernel318));
104     getInstance()->addKernelConfigInputStream({3, 18, 0}, "android-base-arm64.config",
105                                               makeStream(kernel318_64));
106     getInstance()->addKernelConfigInputStream({4, 4, 0}, "android-base.config", makeStream(kernel44));
107     getInstance()->addKernelConfigInputStream({4, 4, 0}, "android-base-arm64.config",
108                                               makeStream(kernel44_64));
109 
110     EXPECT_TRUE(getInstance()->assemble());
111 
112     EXPECT_IN(
113         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
114         "    <kernel version=\"3.18.0\">\n"
115         "        <config>\n"
116         "            <key>CONFIG_FOO</key>\n"
117         "            <value type=\"tristate\">y</value>\n"
118         "        </config>\n"
119         "    </kernel>\n"
120         "    <kernel version=\"3.18.0\">\n"
121         "        <conditions>\n"
122         "            <config>\n"
123         "                <key>CONFIG_ARM64</key>\n"
124         "                <value type=\"tristate\">y</value>\n"
125         "            </config>\n"
126         "        </conditions>\n"
127         "        <config>\n"
128         "            <key>CONFIG_BAR</key>\n"
129         "            <value type=\"tristate\">y</value>\n"
130         "        </config>\n"
131         "    </kernel>\n"
132         "    <kernel version=\"4.4.0\">\n"
133         "        <config>\n"
134         "            <key>CONFIG_FOO</key>\n"
135         "            <value type=\"tristate\">n</value>\n"
136         "        </config>\n"
137         "    </kernel>\n"
138         "    <kernel version=\"4.4.0\">\n"
139         "        <conditions>\n"
140         "            <config>\n"
141         "                <key>CONFIG_ARM64</key>\n"
142         "                <value type=\"tristate\">y</value>\n"
143         "            </config>\n"
144         "        </conditions>\n"
145         "        <config>\n"
146         "            <key>CONFIG_BAR</key>\n"
147         "            <value type=\"tristate\">y</value>\n"
148         "        </config>\n"
149         "    </kernel>\n"
150         "    <sepolicy>\n"
151         "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
152         "        <sepolicy-version>202404</sepolicy-version>\n"
153         "    </sepolicy>\n"
154         "    <avb>\n"
155         "        <vbmeta-version>1.0</vbmeta-version>\n"
156         "    </avb>\n"
157         "</compatibility-matrix>\n",
158         getOutput());
159 }
160 
TEST_F(AssembleVintfTest,FrameworkMatrix)161 TEST_F(AssembleVintfTest, FrameworkMatrix) {
162     std::string tail =
163         "        <config>\n"
164         "            <key>CONFIG_FOO</key>\n"
165         "            <value type=\"tristate\">y</value>\n"
166         "        </config>\n"
167         "    </kernel>\n"
168         "    <sepolicy>\n"
169         "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
170         "        <sepolicy-version>202404</sepolicy-version>\n"
171         "    </sepolicy>\n"
172         "    <avb>\n"
173         "        <vbmeta-version>1.0</vbmeta-version>\n"
174         "    </avb>\n"
175         "</compatibility-matrix>\n";
176 
177     std::string xmlEmpty =
178         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
179         "    <kernel version=\"3.18.0\">\n" +
180         tail;
181 
182     std::string xml1 =
183         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
184         "    <hal format=\"hidl\" optional=\"true\">\n"
185         "        <name>android.hardware.foo</name>\n"
186         "        <version>1.0</version>\n"
187         "        <interface>\n"
188         "            <name>IFoo</name>\n"
189         "            <instance>default</instance>\n"
190         "        </interface>\n"
191         "    </hal>\n"
192         "</compatibility-matrix>\n";
193 
194     std::string xml2 =
195         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"2\">\n"
196         "    <hal format=\"hidl\" optional=\"true\">\n"
197         "        <name>android.hardware.foo</name>\n"
198         "        <version>1.0-1</version>\n"
199         "        <interface>\n"
200         "            <name>IFoo</name>\n"
201         "            <instance>default</instance>\n"
202         "        </interface>\n"
203         "    </hal>\n"
204         "</compatibility-matrix>\n";
205 
206     std::string xml3 =
207         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"3\">\n"
208         "    <hal format=\"hidl\" optional=\"false\">\n"
209         "        <name>android.hardware.foo</name>\n"
210         "        <version>2.0</version>\n"
211         "        <interface>\n"
212         "            <name>IFoo</name>\n"
213         "            <instance>default</instance>\n"
214         "        </interface>\n"
215         "    </hal>\n"
216         "</compatibility-matrix>\n";
217 
218     auto manifest = [](size_t level) {
219         return "<manifest " +
220                     kMetaVersionStr +
221                     " type=\"device\"" +
222                     " target-level=\"" + std::to_string(level) + "\">\n" +
223                "    <hal format=\"hidl\">\n"
224                "        <name>android.hardware.foo</name>\n"
225                "        <version>1.1</version>\n"
226                "        <transport>hwbinder</transport>\n"
227                "        <interface>\n"
228                "            <name>IFoo</name>\n"
229                "            <instance>default</instance>\n"
230                "        </interface>\n"
231                "    </hal>\n"
232                "    <hal format=\"hidl\">\n"
233                "        <name>android.hardware.foo</name>\n"
234                "        <version>2.0</version>\n"
235                "        <transport>hwbinder</transport>\n"
236                "        <interface>\n"
237                "            <name>IFoo</name>\n"
238                "            <instance>default</instance>\n"
239                "        </interface>\n"
240                "    </hal>\n"
241                "    <sepolicy>\n"
242                "        <version>202404</version>\n"
243                "    </sepolicy>\n"
244                "</manifest>\n";
245     };
246 
247     addInput("compatibility_matrix.1.xml", xml1);
248     addInput("compatibility_matrix.2.xml", xml2);
249     addInput("compatibility_matrix.3.xml", xml3);
250     addInput("compatibility_matrix.empty.xml", xmlEmpty);
251     getInstance()->setFakeEnv("PRODUCT_ENFORCE_VINTF_MANIFEST", "true");
252 
253     resetOutput();
254     getInstance()->setCheckInputStream("check.xml", makeStream(manifest(1)));
255     EXPECT_TRUE(getInstance()->assemble());
256     EXPECT_IN(
257         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
258         "    <hal format=\"hidl\" optional=\"true\">\n"
259         "        <name>android.hardware.foo</name>\n"
260         "        <version>1.0-1</version>\n"
261         "        <version>2.0</version>\n"
262         "        <interface>\n"
263         "            <name>IFoo</name>\n"
264         "            <instance>default</instance>\n"
265         "        </interface>\n"
266         "    </hal>\n"
267         "    <kernel version=\"3.18.0\" level=\"1\">\n" +
268             tail,
269         getOutput());
270 
271     resetOutput();
272     getInstance()->setCheckInputStream("check.xml", makeStream(manifest(2)));
273     EXPECT_TRUE(getInstance()->assemble());
274     EXPECT_IN(
275         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"2\">\n"
276         "    <hal format=\"hidl\" optional=\"true\">\n"
277         "        <name>android.hardware.foo</name>\n"
278         "        <version>1.0-1</version>\n"
279         "        <version>2.0</version>\n"
280         "        <interface>\n"
281         "            <name>IFoo</name>\n"
282         "            <instance>default</instance>\n"
283         "        </interface>\n"
284         "    </hal>\n"
285         "    <kernel version=\"3.18.0\" level=\"2\">\n" +
286             tail,
287         getOutput());
288 
289     resetOutput();
290     getInstance()->setCheckInputStream("check.xml", makeStream(manifest(3)));
291     EXPECT_TRUE(getInstance()->assemble());
292     EXPECT_IN(
293         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"3\">\n"
294         "    <hal format=\"hidl\" optional=\"false\">\n"
295         "        <name>android.hardware.foo</name>\n"
296         "        <version>2.0</version>\n"
297         "        <interface>\n"
298         "            <name>IFoo</name>\n"
299         "            <instance>default</instance>\n"
300         "        </interface>\n"
301         "    </hal>\n"
302         "    <kernel version=\"3.18.0\" level=\"3\">\n" +
303             tail,
304         getOutput());
305 }
306 
TEST_F(AssembleVintfTest,MatrixVendorNdk)307 TEST_F(AssembleVintfTest, MatrixVendorNdk) {
308     addInput("compatibility_matrix.xml",
309              "<compatibility-matrix " + kMetaVersionStr + " type=\"device\"/>\n");
310     getInstance()->setFakeEnv("REQUIRED_VNDK_VERSION", "P");
311     EXPECT_TRUE(getInstance()->assemble());
312     EXPECT_IN(
313         "<compatibility-matrix " + kMetaVersionStr + " type=\"device\">\n"
314         "    <vendor-ndk>\n"
315         "        <version>P</version>\n"
316         "    </vendor-ndk>\n"
317         "</compatibility-matrix>\n",
318         getOutput());
319 }
320 
TEST_F(AssembleVintfTest,ManifestVendorNdk)321 TEST_F(AssembleVintfTest, ManifestVendorNdk) {
322     addInput("manifest.xml", "<manifest " + kMetaVersionStr + " type=\"framework\"/>\n");
323     getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P  26 27   ");
324     EXPECT_TRUE(getInstance()->assemble());
325     EXPECT_IN(
326         "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
327         "    <vendor-ndk>\n"
328         "        <version>P</version>\n"
329         "    </vendor-ndk>\n"
330         "    <vendor-ndk>\n"
331         "        <version>26</version>\n"
332         "    </vendor-ndk>\n"
333         "    <vendor-ndk>\n"
334         "        <version>27</version>\n"
335         "    </vendor-ndk>\n"
336         "</manifest>\n",
337         getOutput());
338 }
339 
TEST_F(AssembleVintfTest,VendorNdkCheckEmpty)340 TEST_F(AssembleVintfTest, VendorNdkCheckEmpty) {
341     addInput("manifest.xml", "<manifest " + kMetaVersionStr + " type=\"framework\"/>\n");
342     getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 ");
343 
344     std::string matrix = "<compatibility-matrix " + kMetaVersionStr + " type=\"device\"/>\n";
345     getInstance()->setCheckInputStream("check.xml", makeStream(matrix));
346     EXPECT_TRUE(getInstance()->assemble());
347 }
348 
TEST_F(AssembleVintfTest,VendorNdkCheckIncompat)349 TEST_F(AssembleVintfTest, VendorNdkCheckIncompat) {
350     addInput("manifest.xml", "<manifest " + kMetaVersionStr + " type=\"framework\"/>\n");
351     getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 ");
352     std::string matrix =
353         "<compatibility-matrix " + kMetaVersionStr + " type=\"device\">\n"
354         "    <vendor-ndk>\n"
355         "        <version>O</version>\n"
356         "    </vendor-ndk>\n"
357         "</compatibility-matrix>\n";
358     getInstance()->setCheckInputStream("check.xml", makeStream(matrix));
359     EXPECT_FALSE(getInstance()->assemble());
360 }
361 
TEST_F(AssembleVintfTest,VendorNdkCheckCompat)362 TEST_F(AssembleVintfTest, VendorNdkCheckCompat) {
363     addInput("manifest.xml", "<manifest " + kMetaVersionStr + " type=\"framework\"/>\n");
364     getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 ");
365     std::string matrix =
366         "<compatibility-matrix " + kMetaVersionStr + " type=\"device\">\n"
367         "    <vendor-ndk>\n"
368         "        <version>27</version>\n"
369         "    </vendor-ndk>\n"
370         "</compatibility-matrix>\n";
371     getInstance()->setCheckInputStream("check.xml", makeStream(matrix));
372     EXPECT_TRUE(getInstance()->assemble());
373 }
374 
TEST_F(AssembleVintfTest,MatrixSystemSdk)375 TEST_F(AssembleVintfTest, MatrixSystemSdk) {
376     addInput("compatibility_matrix.xml",
377              "<compatibility-matrix " + kMetaVersionStr + " type=\"device\"/>\n");
378     getInstance()->setFakeEnv("BOARD_SYSTEMSDK_VERSIONS", "P 1 2 ");
379     EXPECT_TRUE(getInstance()->assemble());
380     EXPECT_IN(
381         "<compatibility-matrix " + kMetaVersionStr + " type=\"device\">\n"
382         "    <system-sdk>\n"
383         "        <version>1</version>\n"
384         "        <version>2</version>\n"
385         "        <version>P</version>\n"
386         "    </system-sdk>\n"
387         "</compatibility-matrix>\n",
388         getOutput());
389 }
390 
TEST_F(AssembleVintfTest,ManifestSystemSdk)391 TEST_F(AssembleVintfTest, ManifestSystemSdk) {
392     addInput("manifest.xml", "<manifest " + kMetaVersionStr + " type=\"framework\"/>\n");
393     getInstance()->setFakeEnv("PLATFORM_SYSTEMSDK_VERSIONS", "P 1 2 ");
394     EXPECT_TRUE(getInstance()->assemble());
395     EXPECT_IN(
396         "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
397         "    <system-sdk>\n"
398         "        <version>1</version>\n"
399         "        <version>2</version>\n"
400         "        <version>P</version>\n"
401         "    </system-sdk>\n"
402         "</manifest>\n",
403         getOutput());
404 }
405 
406 const std::string gEmptyOutManifest =
407     "<manifest " + kMetaVersionStr + " type=\"device\">\n"
408     "    <sepolicy>\n"
409     "        <version>202404</version>\n"
410     "    </sepolicy>\n"
411     "</manifest>\n";
412 
TEST_F(AssembleVintfTest,EmptyManifest)413 TEST_F(AssembleVintfTest, EmptyManifest) {
414     const std::string emptyManifest = "<manifest " + kMetaVersionStr + " type=\"device\" />";
415     setFakeEnvs({{"BOARD_SEPOLICY_VERS", "202404"}, {"IGNORE_TARGET_FCM_VERSION", "true"}});
416     addInput("manifest.empty.xml", emptyManifest);
417     EXPECT_TRUE(getInstance()->assemble());
418     EXPECT_IN(gEmptyOutManifest, getOutput());
419 }
420 
TEST_F(AssembleVintfTest,DeviceFrameworkMatrixOptional)421 TEST_F(AssembleVintfTest, DeviceFrameworkMatrixOptional) {
422     setFakeEnvs({{"POLICYVERS", "30"},
423                  {"PLATFORM_SEPOLICY_VERSION", "202404"},
424                  {"PLATFORM_SEPOLICY_COMPAT_VERSIONS", "26.0 27.0"},
425                  {"FRAMEWORK_VBMETA_VERSION", "1.0"},
426                  {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}});
427     getInstance()->setCheckInputStream("check.xml", makeStream(gEmptyOutManifest));
428 
429     addInput("compatibility_matrix.empty.xml",
430              "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
431              "    <hal format=\"hidl\" optional=\"true\">\n"
432              "        <name>vendor.foo.bar</name>\n"
433              "        <version>1.0</version>\n"
434              "        <interface>\n"
435              "            <name>IFoo</name>\n"
436              "            <instance>default</instance>\n"
437              "        </interface>\n"
438              "    </hal>\n"
439              "</compatibility-matrix>");
440 
441     EXPECT_TRUE(getInstance()->assemble());
442     EXPECT_IN(
443         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
444         "    <hal format=\"hidl\" optional=\"true\">\n"
445         "        <name>vendor.foo.bar</name>\n"
446         "        <version>1.0</version>\n"
447         "        <interface>\n"
448         "            <name>IFoo</name>\n"
449         "            <instance>default</instance>\n"
450         "        </interface>\n"
451         "    </hal>\n"
452         "    <sepolicy>\n"
453         "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
454         "        <sepolicy-version>26.0</sepolicy-version>\n"
455         "        <sepolicy-version>27.0</sepolicy-version>\n"
456         "        <sepolicy-version>202404</sepolicy-version>\n"
457         "    </sepolicy>\n"
458         "    <avb>\n"
459         "        <vbmeta-version>1.0</vbmeta-version>\n"
460         "    </avb>\n"
461         "</compatibility-matrix>",
462         getOutput());
463 }
464 
TEST_F(AssembleVintfTest,DeviceFrameworkMatrixRequired)465 TEST_F(AssembleVintfTest, DeviceFrameworkMatrixRequired) {
466     setFakeEnvs({{"POLICYVERS", "30"},
467                  {"PLATFORM_SEPOLICY_VERSION", "202404"},
468                  {"PLATFORM_SEPOLICY_COMPAT_VERSIONS", "26.0 27.0"},
469                  {"FRAMEWORK_VBMETA_VERSION", "1.0"},
470                  {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}});
471     getInstance()->setCheckInputStream("check.xml", makeStream(gEmptyOutManifest));
472 
473     addInput("compatibility_matrix.empty.xml",
474              "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
475              "    <hal format=\"hidl\" optional=\"false\">\n"
476              "        <name>vendor.foo.bar</name>\n"
477              "        <version>1.0</version>\n"
478              "        <interface>\n"
479              "            <name>IFoo</name>\n"
480              "            <instance>default</instance>\n"
481              "        </interface>\n"
482              "    </hal>\n"
483              "</compatibility-matrix>");
484 
485     EXPECT_FALSE(getInstance()->assemble());
486 }
487 
TEST_F(AssembleVintfTest,DeviceFrameworkMatrixMultiple)488 TEST_F(AssembleVintfTest, DeviceFrameworkMatrixMultiple) {
489     setFakeEnvs({{"POLICYVERS", "30"},
490                  {"PLATFORM_SEPOLICY_VERSION", "202404"},
491                  {"PLATFORM_SEPOLICY_COMPAT_VERSIONS", "26.0 27.0"},
492                  {"FRAMEWORK_VBMETA_VERSION", "1.0"},
493                  {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}});
494     getInstance()->setCheckInputStream("check.xml", makeStream(gEmptyOutManifest));
495 
496     addInput("compatibility_matrix.foobar.xml",
497              "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
498              "    <hal format=\"hidl\" optional=\"true\">\n"
499              "        <name>vendor.foo.bar</name>\n"
500              "        <version>1.0</version>\n"
501              "        <interface>\n"
502              "            <name>IFoo</name>\n"
503              "            <instance>default</instance>\n"
504              "        </interface>\n"
505              "    </hal>\n"
506              "</compatibility-matrix>");
507 
508     addInput("compatibility_matrix.bazquux.xml",
509              "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
510              "    <hal format=\"hidl\" optional=\"true\">\n"
511              "        <name>vendor.baz.quux</name>\n"
512              "        <version>1.0</version>\n"
513              "        <interface>\n"
514              "            <name>IBaz</name>\n"
515              "            <instance>default</instance>\n"
516              "        </interface>\n"
517              "    </hal>\n"
518              "</compatibility-matrix>");
519 
520     EXPECT_TRUE(getInstance()->assemble());
521     EXPECT_IN(
522         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
523         "    <hal format=\"hidl\" optional=\"true\">\n"
524         "        <name>vendor.baz.quux</name>\n"
525         "        <version>1.0</version>\n"
526         "        <interface>\n"
527         "            <name>IBaz</name>\n"
528         "            <instance>default</instance>\n"
529         "        </interface>\n"
530         "    </hal>\n"
531         "    <hal format=\"hidl\" optional=\"true\">\n"
532         "        <name>vendor.foo.bar</name>\n"
533         "        <version>1.0</version>\n"
534         "        <interface>\n"
535         "            <name>IFoo</name>\n"
536         "            <instance>default</instance>\n"
537         "        </interface>\n"
538         "    </hal>\n"
539         "    <sepolicy>\n"
540         "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
541         "        <sepolicy-version>26.0</sepolicy-version>\n"
542         "        <sepolicy-version>27.0</sepolicy-version>\n"
543         "        <sepolicy-version>202404</sepolicy-version>\n"
544         "    </sepolicy>\n"
545         "    <avb>\n"
546         "        <vbmeta-version>1.0</vbmeta-version>\n"
547         "    </avb>\n"
548         "</compatibility-matrix>",
549         getOutput());
550 }
551 
TEST_F(AssembleVintfTest,OutputFileMatrixTest)552 TEST_F(AssembleVintfTest, OutputFileMatrixTest) {
553     const std::string kFile = "file_name_1.xml";
554     const std::string kMatrix =
555         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\"/>";
556     addInput(kFile, kMatrix);
557     EXPECT_TRUE(getInstance()->assemble());
558     EXPECT_IN(kFile, getOutput());
559 }
560 
TEST_F(AssembleVintfTest,OutputFileManifestTest)561 TEST_F(AssembleVintfTest, OutputFileManifestTest) {
562     const std::string kFile = "file_name_1.xml";
563     std::string kManifest = "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"1\"/>";
564     addInput(kFile, kManifest);
565     EXPECT_TRUE(getInstance()->assemble());
566     EXPECT_IN(kFile, getOutput());
567 }
568 
TEST_F(AssembleVintfTest,AidlAndHidlNames)569 TEST_F(AssembleVintfTest, AidlAndHidlNames) {
570     addInput("manifest1.xml",
571         "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
572         "    <hal format=\"aidl\">\n"
573         "        <name>android.system.foo</name>\n"
574         "        <fqname>IFoo/default</fqname>\n"
575         "    </hal>\n"
576         "</manifest>\n");
577     addInput("manifest2.xml",
578         "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
579         "    <hal format=\"hidl\">\n"
580         "        <name>android.system.foo</name>\n"
581         "        <transport>hwbinder</transport>\n"
582         "        <fqname>@1.0::IFoo/default</fqname>\n"
583         "    </hal>\n"
584         "</manifest>\n");
585     std::vector<AidlInterfaceMetadata> aidl{
586         {.name = "android.system.foo",
587          .types = {"android.system.foo.IFoo"}}};
588     setFakeAidlMetadata(aidl);
589     EXPECT_TRUE(getInstance()->assemble());
590     EXPECT_IN(
591         "    <hal format=\"aidl\">\n"
592         "        <name>android.system.foo</name>\n"
593         "        <fqname>IFoo/default</fqname>\n"
594         "    </hal>\n",
595         getOutput());
596     EXPECT_IN(
597         "    <hal format=\"hidl\">\n"
598         "        <name>android.system.foo</name>\n"
599         "        <transport>hwbinder</transport>\n"
600         "        <fqname>@1.0::IFoo/default</fqname>\n"
601         "    </hal>\n",
602         getOutput());
603 }
604 
605 // Merge kernel FCM from manually written device manifest and <config> from
606 // parsing kernel prebuilt.
TEST_F(AssembleVintfTest,MergeKernelFcmAndConfigs)607 TEST_F(AssembleVintfTest, MergeKernelFcmAndConfigs) {
608     addInput("manifest.xml",
609         "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"1\">\n"
610         "    <kernel target-level=\"2\"/>\n"
611         "</manifest>\n");
612     getInstance()->addKernelConfigInputStream({3, 18, 10}, "android-base.config",
613                                               makeStream("CONFIG_FOO=y"));
614     EXPECT_TRUE(getInstance()->assemble());
615     EXPECT_IN("<kernel version=\"3.18.10\" target-level=\"2\">", getOutput());
616 }
617 
TEST_F(AssembleVintfTest,NoAutoSetKernelFcm)618 TEST_F(AssembleVintfTest, NoAutoSetKernelFcm) {
619     addInput("manifest.xml",
620         "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"1\">\n"
621         "    <kernel version=\"3.18.10\"/>\n"
622         "</manifest>\n");
623     EXPECT_TRUE(getInstance()->assemble());
624     EXPECT_IN("<kernel version=\"3.18.10\"/>", getOutput());
625 }
626 
TEST_F(AssembleVintfTest,NoAutoSetKernelFcmWithConfig)627 TEST_F(AssembleVintfTest, NoAutoSetKernelFcmWithConfig) {
628     addInput("manifest.xml",
629         "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"1\" />\n");
630     getInstance()->addKernelConfigInputStream({3, 18, 10}, "android-base.config",
631                                               makeStream("CONFIG_FOO=y"));
632     EXPECT_TRUE(getInstance()->assemble());
633     EXPECT_IN("<kernel version=\"3.18.10\">", getOutput());
634 }
635 
TEST_F(AssembleVintfTest,NoKernelFcmT)636 TEST_F(AssembleVintfTest, NoKernelFcmT) {
637     addInput("manifest.xml",
638         StringPrintf(R"(<manifest %s type="device" target-level="%s">
639                             <kernel target-level="8"/>
640                         </manifest>)", kMetaVersionStr.c_str(),
641                         to_string(details::kEnforceDeviceManifestNoKernelLevel).c_str()));
642     EXPECT_FALSE(getInstance()->assemble());
643 }
644 
645 // Automatically add kernel FCM when parsing framework matrix for a single FCM version.
TEST_F(AssembleVintfTest,AutoSetMatrixKernelFcm)646 TEST_F(AssembleVintfTest, AutoSetMatrixKernelFcm) {
647     addInput("compatibility_matrix.xml",
648         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\"/>\n"
649     );
650     getInstance()->addKernelConfigInputStream({3, 18, 10}, "android-base.config",
651                                               makeStream(""));
652     EXPECT_TRUE(getInstance()->assemble());
653     EXPECT_IN("<kernel version=\"3.18.10\" level=\"1\"/>", getOutput());
654 }
655 
656 
TEST_F(AssembleVintfTest,WithKernelRequirements)657 TEST_F(AssembleVintfTest, WithKernelRequirements) {
658     setFakeEnvs({{"POLICYVERS", "30"},
659                  {"PLATFORM_SEPOLICY_VERSION", "202404"},
660                  {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}});
661     addInput("compatibility_matrix.xml",
662         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
663         "    <kernel version=\"3.18.1\" level=\"1\">\n"
664         "        <config>\n"
665         "            <key>CONFIG_FOO</key>\n"
666         "            <value type=\"tristate\">y</value>\n"
667         "        </config>\n"
668         "    </kernel>\n"
669         "</compatibility-matrix>\n");
670     getInstance()->setCheckInputStream("check.xml", makeStream(
671         "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"1\">\n"
672         "    <kernel target-level=\"1\" version=\"3.18.0\"/>\n"
673         "    <sepolicy>\n"
674         "        <version>202404</version>\n"
675         "    </sepolicy>\n"
676         "</manifest>\n"));
677 
678     EXPECT_FALSE(getInstance()->assemble());
679 }
680 
TEST_F(AssembleVintfTest,NoKernelRequirements)681 TEST_F(AssembleVintfTest, NoKernelRequirements) {
682     setFakeEnvs({{"POLICYVERS", "30"},
683                  {"PLATFORM_SEPOLICY_VERSION", "202404"},
684                  {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}});
685     addInput("compatibility_matrix.xml",
686         "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
687         "    <kernel version=\"3.18.0\" level=\"1\"/>\n"
688         "</compatibility-matrix>\n");
689     getInstance()->setCheckInputStream("check.xml", makeStream(
690         "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"1\">\n"
691         "    <kernel target-level=\"1\"/>\n"
692         "    <sepolicy>\n"
693         "        <version>202404</version>\n"
694         "    </sepolicy>\n"
695         "</manifest>\n"));
696 
697     EXPECT_TRUE(getInstance()->setNoKernelRequirements());
698     EXPECT_TRUE(getInstance()->assemble());
699 }
700 
701 // clang-format on
702 
TEST_F(AssembleVintfTest,ManifestLevelConflictCorrectLocation)703 TEST_F(AssembleVintfTest, ManifestLevelConflictCorrectLocation) {
704     addInput("manifest.xml", "<manifest " + kMetaVersionStr + R"( type="device" />)");
705     addInput("manifest_1.xml",
706              "<manifest " + kMetaVersionStr + R"( type="device" target-level="1" />)");
707     addInput("manifest_2.xml",
708              "<manifest " + kMetaVersionStr + R"( type="device" target-level="2" />)");
709     EXPECT_FALSE(getInstance()->assemble());
710     EXPECT_IN("File 'manifest_1.xml' has level 1", getError());
711     EXPECT_IN("File 'manifest_2.xml' has level 2", getError());
712 }
713 
TEST_F(AssembleVintfTest,PassMultipleManifestEntrySameModule)714 TEST_F(AssembleVintfTest, PassMultipleManifestEntrySameModule) {
715     setFakeEnvs({{"VINTF_IGNORE_TARGET_FCM_VERSION", "true"}});
716     std::vector<AidlInterfaceMetadata> aidl{
717         {.name = "android.system.foo",
718          .stability = "vintf",
719          .versions = {1, 2},
720          .types = {"android.system.foobar.IFoo", "android.system.foobar.IBar"}}};
721     setFakeAidlMetadata(aidl);
722     addInput("manifest1.xml", StringPrintf(
723                                   R"(
724                 <manifest %s type="framework">
725                    <hal format="aidl">
726                         <name>android.system.foobar</name>\n"
727                         <fqname>IFoo/default</fqname>\n"
728                         <fqname>IBar/default</fqname>\n"
729                         <version>3</version>\n"
730                     </hal>
731                 </manifest>)",
732                                   kMetaVersionStr.c_str()));
733     EXPECT_TRUE(getInstance()->assemble());
734 }
735 
TEST_F(AssembleVintfTest,FailOnMultipleModulesInSameManifestEntry)736 TEST_F(AssembleVintfTest, FailOnMultipleModulesInSameManifestEntry) {
737     setFakeEnvs({{"VINTF_IGNORE_TARGET_FCM_VERSION", "true"}});
738     std::vector<AidlInterfaceMetadata> aidl{{.name = "android.system.foo",
739                                              .stability = "vintf",
740                                              .versions = {1, 2},
741                                              .types = {"android.system.foobar.IFoo"}},
742                                             {.name = "android.system.bar",
743                                              .stability = "vintf",
744                                              .versions = {1, 2},
745                                              .types = {"android.system.foobar.IBar"}}};
746     setFakeAidlMetadata(aidl);
747     addInput("manifest1.xml", StringPrintf(
748                                   R"(
749                 <manifest %s type="framework">
750                    <hal format="aidl">
751                         <name>android.system.foobar</name>\n"
752                         <fqname>IFoo/default</fqname>\n"
753                         <fqname>IBar/default</fqname>\n"
754                         <version>3</version>\n"
755                     </hal>
756                 </manifest>)",
757                                   kMetaVersionStr.c_str()));
758     EXPECT_FALSE(getInstance()->assemble());
759     EXPECT_IN("HAL manifest entries must only contain", getError());
760     EXPECT_IN("android.system.foobar.IFoo is in android.system.foo", getError());
761 }
762 
TEST_F(AssembleVintfTest,ForceDowngradeVersion)763 TEST_F(AssembleVintfTest, ForceDowngradeVersion) {
764     setFakeEnvs({{"VINTF_IGNORE_TARGET_FCM_VERSION", "true"}});
765     std::vector<AidlInterfaceMetadata> aidl{
766         {.name = "foo_android.system.bar",
767          .stability = "vintf",
768          .types = {"android.system.bar.IFoo", "android.system.bar.MyFoo"},
769          .versions = {1, 2},
770          .has_development = true}};
771     setFakeAidlMetadata(aidl);
772     setFakeAidlUseUnfrozen(false);
773     addInput("manifest1.xml", StringPrintf(
774                                   R"(
775                 <manifest %s type="framework">
776                    <hal format="aidl">
777                         <name>android.system.bar</name>\n"
778                         <fqname>IFoo/default</fqname>\n"
779                         <version>3</version>\n"
780                     </hal>
781                 </manifest>)",
782                                   kMetaVersionStr.c_str()));
783     EXPECT_TRUE(getInstance()->assemble());
784     EXPECT_IN("<version>2</version>", getOutput());
785 }
786 
787 TEST_F(AssembleVintfTest, InfoDowngradeVersionTypo) {
788     setFakeEnvs({{"VINTF_IGNORE_TARGET_FCM_VERSION", "true"}});
789     std::vector<AidlInterfaceMetadata> aidl{
790         {.name = "foo_android.system.bar",
791          .stability = "vintf",
792          .types = {"android.system.bar.IFoo", "android.system.bar.MyFoo"},
793          .versions = {1, 2},
794          .has_development = true}};
795     setFakeAidlMetadata(aidl);
796     setFakeAidlUseUnfrozen(false);
797     addInput("manifest1.xml", StringPrintf(
798                                   R"(
799                 <manifest %s type="framework">
800                    <hal format="aidl">
801                         <name>android.system.bar</name>\n"
802                         <fqname>IFooooooooo/default</fqname>\n"
803                         <version>3</version>\n"
804                     </hal>
805                 </manifest>)",
806                                   kMetaVersionStr.c_str()));
807     // It doesn't fail because there may be prebuilts, but make sure we do log it.
808     EXPECT_TRUE(getInstance()->assemble());
809     EXPECT_IN(
810         "INFO: Couldn't find AIDL metadata for: android.system.bar.IFooooooooo in file "
811         "manifest1.xml. "
812         "Check "
813         "spelling?",
814         getError());
815 }
816 
TEST_F(AssembleVintfTest,AllowUnfrozenVersion)817 TEST_F(AssembleVintfTest, AllowUnfrozenVersion) {
818     setFakeEnvs({{"VINTF_IGNORE_TARGET_FCM_VERSION", "true"}});
819     std::vector<AidlInterfaceMetadata> aidl{
820         {.name = "foo_android.system.bar",
821          .stability = "vintf",
822          .types = {"android.system.bar.IFoo", "android.system.bar.MyFoo"},
823          .versions = {1, 2},
824          .has_development = true}};
825     setFakeAidlMetadata(aidl);
826     setFakeAidlUseUnfrozen(true);
827     addInput("manifest1.xml", StringPrintf(
828                                   R"(
829                 <manifest %s type="framework">
830                    <hal format="aidl">
831                         <name>android.system.bar</name>\n"
832                         <fqname>IFoo/default</fqname>\n"
833                         <version>3</version>\n"
834                     </hal>
835                 </manifest>)",
836                                   kMetaVersionStr.c_str()));
837     EXPECT_TRUE(getInstance()->assemble());
838     EXPECT_IN("<version>3</version>", getOutput());
839 }
840 
841 TEST_F(AssembleVintfTest, KeepFrozenVersion) {
842     setFakeEnvs({{"VINTF_IGNORE_TARGET_FCM_VERSION", "true"}});
843     // V3 is already frozen
844     std::vector<AidlInterfaceMetadata> aidl{
845         {.name = "foo_android.system.bar",
846          .stability = "vintf",
847          .types = {"android.system.bar.IFoo", "android.system.bar.MyFoo"},
848          .versions = {1, 2, 3},
849          .has_development = true}};
850     setFakeAidlMetadata(aidl);
851     setFakeAidlUseUnfrozen(false);
852     addInput("manifest1.xml", StringPrintf(
853                                   R"(
854                 <manifest %s type="framework">
855                    <hal format="aidl">
856                         <name>android.system.bar</name>\n"
857                         <fqname>IFoo/default</fqname>\n"
858                         <version>3</version>\n"
859                     </hal>
860                 </manifest>)",
861                                   kMetaVersionStr.c_str()));
862     EXPECT_TRUE(getInstance()->assemble());
863     EXPECT_IN("<version>3</version>", getOutput());
864 }
865 
866 }  // namespace vintf
867 }  // namespace android
868