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#include <android-base/logging.h>
18
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21#include <stdio.h>
22#include <unistd.h>
23
24#include "utils-fake.h"
25#include "vintf/VintfObject.h"
26
27using namespace ::testing;
28using namespace ::android::vintf;
29using namespace ::android::vintf::details;
30
31//
32// Set of Xml1 metadata compatible with each other.
33//
34
35const std::string systemMatrixXml1 =
36    "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
37    "    <hal format=\"hidl\" optional=\"false\">\n"
38    "        <name>android.hardware.camera</name>\n"
39    "        <version>2.0-5</version>\n"
40    "        <version>3.4-16</version>\n"
41    "    </hal>\n"
42    "    <hal format=\"hidl\" optional=\"false\">\n"
43    "        <name>android.hardware.nfc</name>\n"
44    "        <version>1.0</version>\n"
45    "        <version>2.0</version>\n"
46    "    </hal>\n"
47    "    <hal format=\"hidl\" optional=\"true\">\n"
48    "        <name>android.hardware.foo</name>\n"
49    "        <version>1.0</version>\n"
50    "    </hal>\n"
51    "    <kernel version=\"3.18.31\"></kernel>\n"
52    "    <sepolicy>\n"
53    "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
54    "        <sepolicy-version>25.5</sepolicy-version>\n"
55    "        <sepolicy-version>26.0-3</sepolicy-version>\n"
56    "    </sepolicy>\n"
57    "    <avb>\n"
58    "        <vbmeta-version>0.0</vbmeta-version>\n"
59    "    </avb>\n"
60    "</compatibility-matrix>\n";
61
62const std::string vendorManifestXml1 =
63    "<manifest version=\"1.0\" type=\"device\">\n"
64    "    <hal format=\"hidl\">\n"
65    "        <name>android.hardware.camera</name>\n"
66    "        <transport>hwbinder</transport>\n"
67    "        <version>3.5</version>\n"
68    "        <interface>\n"
69    "            <name>IBetterCamera</name>\n"
70    "            <instance>camera</instance>\n"
71    "        </interface>\n"
72    "        <interface>\n"
73    "            <name>ICamera</name>\n"
74    "            <instance>default</instance>\n"
75    "            <instance>legacy/0</instance>\n"
76    "        </interface>\n"
77    "    </hal>\n"
78    "    <hal format=\"hidl\">\n"
79    "        <name>android.hardware.nfc</name>\n"
80    "        <transport>hwbinder</transport>\n"
81    "        <version>1.0</version>\n"
82    "        <version>2.0</version>\n"
83    "        <interface>\n"
84    "            <name>INfc</name>\n"
85    "            <instance>nfc_nci</instance>\n"
86    "        </interface>\n"
87    "    </hal>\n"
88    "    <hal format=\"hidl\">\n"
89    "        <name>android.hardware.nfc</name>\n"
90    "        <transport>hwbinder</transport>\n"
91    "        <version>2.0</version>\n"
92    "        <interface>\n"
93    "            <name>INfc</name>\n"
94    "            <instance>default</instance>\n"
95    "        </interface>\n"
96    "    </hal>\n"
97    "    <sepolicy>\n"
98    "        <version>25.5</version>\n"
99    "    </sepolicy>\n"
100    "</manifest>\n";
101
102const std::string systemManifestXml1 =
103    "<manifest version=\"1.0\" type=\"framework\">\n"
104    "    <hal format=\"hidl\">\n"
105    "        <name>android.hidl.manager</name>\n"
106    "        <transport>hwbinder</transport>\n"
107    "        <version>1.0</version>\n"
108    "        <interface>\n"
109    "            <name>IServiceManager</name>\n"
110    "            <instance>default</instance>\n"
111    "        </interface>\n"
112    "    </hal>\n"
113    "    <vndk>\n"
114    "        <version>25.0.5</version>\n"
115    "        <library>libbase.so</library>\n"
116    "        <library>libjpeg.so</library>\n"
117    "    </vndk>\n"
118    "</manifest>\n";
119
120const std::string vendorMatrixXml1 =
121    "<compatibility-matrix version=\"1.0\" type=\"device\">\n"
122    "    <hal format=\"hidl\" optional=\"false\">\n"
123    "        <name>android.hidl.manager</name>\n"
124    "        <version>1.0</version>\n"
125    "    </hal>\n"
126    "    <vndk>\n"
127    "        <version>25.0.1-5</version>\n"
128    "        <library>libbase.so</library>\n"
129    "        <library>libjpeg.so</library>\n"
130    "    </vndk>\n"
131    "</compatibility-matrix>\n";
132
133//
134// Set of Xml2 metadata compatible with each other.
135//
136
137const std::string systemMatrixXml2 =
138    "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
139    "    <hal format=\"hidl\">\n"
140    "        <name>android.hardware.foo</name>\n"
141    "        <version>1.0</version>\n"
142    "    </hal>\n"
143    "    <kernel version=\"3.18.31\"></kernel>\n"
144    "    <sepolicy>\n"
145    "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
146    "        <sepolicy-version>25.5</sepolicy-version>\n"
147    "        <sepolicy-version>26.0-3</sepolicy-version>\n"
148    "    </sepolicy>\n"
149    "    <avb>\n"
150    "        <vbmeta-version>0.0</vbmeta-version>\n"
151    "    </avb>\n"
152    "</compatibility-matrix>\n";
153
154const std::string vendorManifestXml2 =
155    "<manifest version=\"1.0\" type=\"device\">"
156    "    <hal>"
157    "        <name>android.hardware.foo</name>"
158    "        <transport>hwbinder</transport>"
159    "        <version>1.0</version>"
160    "    </hal>"
161    "    <sepolicy>\n"
162    "        <version>25.5</version>\n"
163    "    </sepolicy>\n"
164    "</manifest>";
165
166// Setup the MockFileFetcher used by the fetchAllInformation template
167// so it returns the given metadata info instead of fetching from device.
168void setupMockFetcher(const std::string& vendorManifestXml, const std::string& systemMatrixXml,
169                      const std::string& systemManifestXml, const std::string& vendorMatrixXml) {
170    MockFileFetcher* fetcher = static_cast<MockFileFetcher*>(gFetcher);
171
172    ON_CALL(*fetcher, fetch(StrEq("/vendor/manifest.xml"), _))
173        .WillByDefault(Invoke([vendorManifestXml](const std::string& path, std::string& fetched) {
174            (void)path;
175            fetched = vendorManifestXml;
176            return 0;
177        }));
178    ON_CALL(*fetcher, fetch(StrEq("/system/manifest.xml"), _))
179        .WillByDefault(Invoke([systemManifestXml](const std::string& path, std::string& fetched) {
180            (void)path;
181            fetched = systemManifestXml;
182            return 0;
183        }));
184    ON_CALL(*fetcher, fetch(StrEq("/vendor/compatibility_matrix.xml"), _))
185        .WillByDefault(Invoke([vendorMatrixXml](const std::string& path, std::string& fetched) {
186            (void)path;
187            fetched = vendorMatrixXml;
188            return 0;
189        }));
190    ON_CALL(*fetcher, fetch(StrEq("/system/compatibility_matrix.xml"), _))
191        .WillByDefault(Invoke([systemMatrixXml](const std::string& path, std::string& fetched) {
192            (void)path;
193            fetched = systemMatrixXml;
194            return 0;
195        }));
196}
197
198static MockPartitionMounter &mounter() {
199    return *static_cast<MockPartitionMounter *>(gPartitionMounter);
200}
201static MockFileFetcher &fetcher() {
202    return *static_cast<MockFileFetcher*>(gFetcher);
203}
204
205// Test fixture that provides compatible metadata from the mock device.
206class VintfObjectCompatibleTest : public testing::Test {
207   protected:
208    virtual void SetUp() {
209        setupMockFetcher(vendorManifestXml1, systemMatrixXml1, systemManifestXml1,
210                         vendorMatrixXml1);
211    }
212    virtual void TearDown() {
213        Mock::VerifyAndClear(&mounter());
214        Mock::VerifyAndClear(&fetcher());
215    }
216
217};
218
219// Tests that local info is checked.
220TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibility) {
221    std::string error;
222    std::vector<std::string> packageInfo;
223
224    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
225    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
226    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
227    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _));
228    EXPECT_CALL(mounter(), mountSystem()).Times(0);
229    EXPECT_CALL(mounter(), umountSystem()).Times(0);
230    EXPECT_CALL(mounter(), mountVendor()).Times(0);
231    EXPECT_CALL(mounter(), umountVendor()).Times(0);
232
233    int result = VintfObject::CheckCompatibility(packageInfo, &error);
234
235    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
236    // Check that nothing was ignored.
237    ASSERT_STREQ(error.c_str(), "");
238    EXPECT_FALSE(mounter().systemMounted());
239    EXPECT_FALSE(mounter().vendorMounted());
240}
241
242TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibilityMount) {
243    std::string error;
244    std::vector<std::string> packageInfo;
245
246    EXPECT_CALL(mounter(), mountSystem()).Times(2);
247    EXPECT_CALL(mounter(), umountSystem()).Times(1); // Should only umount once
248    EXPECT_CALL(mounter(), mountVendor()).Times(2);
249    EXPECT_CALL(mounter(), umountVendor()).Times(1);
250
251    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
252
253    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
254    EXPECT_FALSE(mounter().systemMounted());
255    EXPECT_FALSE(mounter().vendorMounted());
256}
257
258// Tests that input info is checked against device and passes.
259TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceSuccess) {
260    std::string error;
261    std::vector<std::string> packageInfo = {systemMatrixXml1};
262
263    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
264    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
265    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
266    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
267    EXPECT_CALL(mounter(), mountSystem()).Times(0);
268    EXPECT_CALL(mounter(), umountSystem()).Times(0);
269    EXPECT_CALL(mounter(), mountVendor()).Times(0);
270    EXPECT_CALL(mounter(), umountVendor()).Times(0);
271
272    int result = VintfObject::CheckCompatibility(packageInfo, &error);
273
274    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
275    ASSERT_STREQ(error.c_str(), "");
276    EXPECT_FALSE(mounter().systemMounted());
277    EXPECT_FALSE(mounter().vendorMounted());
278}
279
280TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceSuccessMount) {
281    std::string error;
282    std::vector<std::string> packageInfo = {systemMatrixXml1};
283
284    EXPECT_CALL(mounter(), mountSystem()).Times(1); // Should only mount once for manifest
285    EXPECT_CALL(mounter(), umountSystem()).Times(1);
286    EXPECT_CALL(mounter(), mountVendor()).Times(2);
287    EXPECT_CALL(mounter(), umountVendor()).Times(1);
288
289    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
290
291    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
292    EXPECT_FALSE(mounter().systemMounted());
293    EXPECT_FALSE(mounter().vendorMounted());
294}
295
296// Tests that input info is checked against device and fails.
297TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceFail) {
298    std::string error;
299    std::vector<std::string> packageInfo = {systemMatrixXml2};
300
301    int result = VintfObject::CheckCompatibility(packageInfo, &error);
302
303    ASSERT_EQ(result, 1) << "Should have failed:" << error.c_str();
304    ASSERT_STREQ(error.c_str(),
305                 "Device manifest and framework compatibility matrix are incompatible: HALs "
306                 "incompatible. android.hardware.foo");
307}
308
309// Tests that complementary info is checked against itself.
310TEST_F(VintfObjectCompatibleTest, TestInputSuccess) {
311    std::string error;
312    std::vector<std::string> packageInfo = {systemMatrixXml2, vendorManifestXml2};
313
314    int result = VintfObject::CheckCompatibility(packageInfo, &error);
315
316    ASSERT_EQ(result, 0) << "Failed message:" << error.c_str();
317    ASSERT_STREQ(error.c_str(), "");
318}
319
320TEST_F(VintfObjectCompatibleTest, TestFrameworkOnlyOta) {
321    std::string error;
322    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1};
323
324    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
325    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _)).Times(0);
326    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
327    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
328    EXPECT_CALL(mounter(), mountSystem()).Times(0);
329    EXPECT_CALL(mounter(), umountSystem()).Times(0);
330    EXPECT_CALL(mounter(), mountVendor()).Times(0);
331    EXPECT_CALL(mounter(), umountVendor()).Times(0);
332
333    int result = VintfObject::CheckCompatibility(packageInfo, &error);
334
335    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
336    ASSERT_STREQ(error.c_str(), "");
337    EXPECT_FALSE(mounter().systemMounted());
338    EXPECT_FALSE(mounter().vendorMounted());
339}
340
341TEST_F(VintfObjectCompatibleTest, TestFrameworkOnlyOtaMount) {
342    std::string error;
343    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1};
344
345    EXPECT_CALL(mounter(), mountSystem()).Times(0);
346    EXPECT_CALL(mounter(), umountSystem()).Times(1);
347    EXPECT_CALL(mounter(), mountVendor()).Times(2);
348    EXPECT_CALL(mounter(), umountVendor()).Times(1);
349
350    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
351
352    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
353    EXPECT_FALSE(mounter().systemMounted());
354    EXPECT_FALSE(mounter().vendorMounted());
355}
356
357TEST_F(VintfObjectCompatibleTest, TestFullOta) {
358    std::string error;
359    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1,
360            vendorMatrixXml1, vendorManifestXml1};
361
362    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _)).Times(0);
363    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _)).Times(0);
364    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _)).Times(0);
365    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
366    EXPECT_CALL(mounter(), mountSystem()).Times(0);
367    EXPECT_CALL(mounter(), umountSystem()).Times(0);
368    EXPECT_CALL(mounter(), mountVendor()).Times(0);
369    EXPECT_CALL(mounter(), umountVendor()).Times(0);
370
371    int result = VintfObject::CheckCompatibility(packageInfo, &error);
372
373    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
374    ASSERT_STREQ(error.c_str(), "");
375    EXPECT_FALSE(mounter().systemMounted());
376    EXPECT_FALSE(mounter().vendorMounted());
377}
378
379TEST_F(VintfObjectCompatibleTest, TestFullOnlyOtaMount) {
380    std::string error;
381    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1,
382            vendorMatrixXml1, vendorManifestXml1};
383
384    EXPECT_CALL(mounter(), mountSystem()).Times(0);
385    EXPECT_CALL(mounter(), umountSystem()).Times(1);
386    EXPECT_CALL(mounter(), mountVendor()).Times(0);
387    EXPECT_CALL(mounter(), umountVendor()).Times(1);
388
389    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
390
391    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
392    EXPECT_FALSE(mounter().systemMounted());
393    EXPECT_FALSE(mounter().vendorMounted());
394}
395
396// Test fixture that provides incompatible metadata from the mock device.
397class VintfObjectIncompatibleTest : public testing::Test {
398   protected:
399    virtual void SetUp() {
400        setupMockFetcher(vendorManifestXml1, systemMatrixXml2, systemManifestXml1,
401                         vendorMatrixXml1);
402    }
403    virtual void TearDown() {
404        Mock::VerifyAndClear(&mounter());
405        Mock::VerifyAndClear(&fetcher());
406    }
407};
408
409// Fetch all metadata from device and ensure that it fails.
410TEST_F(VintfObjectIncompatibleTest, TestDeviceCompatibility) {
411    std::string error;
412    std::vector<std::string> packageInfo;
413
414    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
415    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
416    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
417    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _));
418
419    int result = VintfObject::CheckCompatibility(packageInfo, &error);
420
421    ASSERT_EQ(result, 1) << "Should have failed:" << error.c_str();
422}
423
424// Pass in new metadata that fixes the incompatibility.
425TEST_F(VintfObjectIncompatibleTest, TestInputVsDeviceSuccess) {
426    std::string error;
427    std::vector<std::string> packageInfo = {systemMatrixXml1};
428
429    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
430    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
431    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
432    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
433
434    int result = VintfObject::CheckCompatibility(packageInfo, &error);
435
436    ASSERT_EQ(result, 0) << "Failed message:" << error.c_str();
437    ASSERT_STREQ(error.c_str(), "");
438}
439
440int main(int argc, char** argv) {
441    ::testing::InitGoogleMock(&argc, argv);
442
443    NiceMock<MockFileFetcher> fetcher;
444    gFetcher = &fetcher;
445
446    NiceMock<MockPartitionMounter> mounter;
447    gPartitionMounter = &mounter;
448
449    return RUN_ALL_TESTS();
450}
451