| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <unistd.h> |
| |
| #include <gtest/gtest.h> |
| #include <binder/IServiceManager.h> |
| #include <binder/ProcessState.h> |
| #include <utils/threads.h> |
| #include <utils/KeyedVector.h> |
| #include <utils/String8.h> |
| #include <utils/SystemClock.h> |
| #include <VehiclePropertyAccessControlForTesting.h> |
| |
| namespace android { |
| |
| class VehiclePropertyAccessControlTest : public testing::Test { |
| public: |
| VehiclePropertyAccessControlTest() {} |
| ~VehiclePropertyAccessControlTest() {} |
| |
| public: |
| static std::string xmlData; |
| static std::string xmlData2; |
| static const int32_t prop1; |
| static const int32_t prop2; |
| static const int32_t prop3; |
| static const int32_t uid1; |
| static const int32_t uid2; |
| static const int32_t uid3; |
| |
| protected: |
| void SetUp() {} |
| |
| protected: |
| xmlDoc* doc; |
| VehiclePropertyAccessControlForTesting mVehiclePropertyAccessControl; |
| }; |
| |
| std::string VehiclePropertyAccessControlTest::xmlData = |
| "<ALLOW>" |
| "<PROPERTY name=\"PROP1\" value=\"0xA\">" |
| "<UID name=\"UID1\" access=\"r\" value=\"1000\"/>" |
| "</PROPERTY>" |
| "<PROPERTY name=\"PROP2\" value=\"0xB\">" |
| "<UID name=\"UID2\" access=\"w\" value=\"2000\"/>" |
| "</PROPERTY>" |
| "<PROPERTY name=\"PROP3\" value=\"0xC\">" |
| "<UID name=\"UID3\" access=\"rw\" value=\"3000\"/>" |
| "</PROPERTY>" |
| "</ALLOW>"; |
| |
| const int32_t VehiclePropertyAccessControlTest::prop1 = 0xa; |
| const int32_t VehiclePropertyAccessControlTest::prop2 = 0xb; |
| const int32_t VehiclePropertyAccessControlTest::prop3 = 0xc; |
| const int32_t VehiclePropertyAccessControlTest::uid1 = 1000; |
| const int32_t VehiclePropertyAccessControlTest::uid2 = 2000; |
| const int32_t VehiclePropertyAccessControlTest::uid3 = 3000; |
| |
| TEST_F(VehiclePropertyAccessControlTest, isHexNotation) { |
| static const std::string shouldPass[] = |
| {"0x01234567", |
| "0x01abcdef", |
| "0x01ABCDEF", |
| "0x0"}; |
| |
| static const std::string shouldFail[] = |
| {"0", |
| "0x", |
| "01234567", |
| "ABCDEF01", |
| "0xabi"}; |
| |
| for(auto& h : shouldPass) { |
| ASSERT_TRUE(mVehiclePropertyAccessControl.isHexNotation(h)); |
| } |
| |
| for(auto& h : shouldFail) { |
| ASSERT_FALSE(mVehiclePropertyAccessControl.isHexNotation(h)); |
| } |
| } |
| |
| TEST_F(VehiclePropertyAccessControlTest, accessToInt) { |
| static const char* property = "property"; |
| static const char* uid = "uid"; |
| struct ShouldPassType {std::string str; int32_t value;}; |
| static const struct ShouldPassType shouldPass[] = { |
| {"r", VEHICLE_PROP_ACCESS_READ}, |
| {"w", VEHICLE_PROP_ACCESS_WRITE}, |
| {"rw", VEHICLE_PROP_ACCESS_READ_WRITE}, |
| {"wr", VEHICLE_PROP_ACCESS_READ_WRITE} |
| }; |
| static const char* shouldFail[] = {"rr", "ww", "rww", "rwr", "", "k"}; |
| int32_t value; |
| |
| for(auto& h : shouldPass) { |
| ASSERT_TRUE(mVehiclePropertyAccessControl.accessToInt(&value, |
| (const xmlChar*)property, (const xmlChar*)uid, |
| (const xmlChar*)h.str.c_str())); |
| ASSERT_EQ(h.value, value); |
| } |
| |
| for(auto& h : shouldFail) { |
| ASSERT_FALSE(mVehiclePropertyAccessControl.accessToInt(&value, |
| (const xmlChar*)property, (const xmlChar*)uid, (const xmlChar*)h)); |
| } |
| } |
| |
| TEST_F(VehiclePropertyAccessControlTest, updateOrCreate) { |
| std::map<int32_t, int32_t> *accessMap; |
| |
| // Empty the map |
| mVehiclePropertyAccessControl.emptyAccessControlMap(); |
| |
| // Make sure the property does not exist |
| ASSERT_FALSE(mVehiclePropertyAccessControl.getAccessToProperty(prop1, |
| &accessMap)); |
| |
| // Create the property and give uid read access |
| ASSERT_FALSE(mVehiclePropertyAccessControl.updateOrCreate(uid1, prop1, |
| VEHICLE_PROP_ACCESS_READ)); |
| |
| // Make sure the property was created |
| ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1, |
| &accessMap)); |
| |
| // Make sure uid has read access to the property |
| ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_READ); |
| |
| // Give uid2 read/write access to the property |
| ASSERT_FALSE(mVehiclePropertyAccessControl.updateOrCreate(uid2, prop1, |
| VEHICLE_PROP_ACCESS_READ_WRITE)); |
| |
| // Get the accessMap |
| ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1, |
| &accessMap)); |
| // Make sure uid2 has read/write access to the property |
| ASSERT_EQ((*accessMap)[uid2], VEHICLE_PROP_ACCESS_READ_WRITE); |
| |
| // Make sure uid still has read access to the property |
| ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_READ); |
| |
| // Change uid access to write for property |
| ASSERT_TRUE(mVehiclePropertyAccessControl.updateOrCreate(uid1, prop1, |
| VEHICLE_PROP_ACCESS_WRITE)); |
| |
| // Get the accessMap |
| ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1, |
| &accessMap)); |
| |
| // Make sure uid has write access to property |
| ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_WRITE); |
| |
| // Make sure uid2 has read write access to property |
| ASSERT_EQ((*accessMap)[uid2], VEHICLE_PROP_ACCESS_READ_WRITE); |
| } |
| |
| TEST_F(VehiclePropertyAccessControlTest, populate) { |
| xmlNode* root_element; |
| std::map<int32_t, int32_t> *accessMap; |
| |
| // Empty the map |
| mVehiclePropertyAccessControl.emptyAccessControlMap(); |
| |
| doc = xmlReadMemory(xmlData.c_str(), xmlData.length(), NULL, NULL, 0); |
| ASSERT_TRUE(doc != NULL); |
| root_element = xmlDocGetRootElement(doc); |
| ASSERT_TRUE(root_element != NULL); |
| |
| bool result = mVehiclePropertyAccessControl.populate(root_element->children); |
| |
| ASSERT_TRUE(result); |
| |
| // Get the accessMap |
| ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1, |
| &accessMap)); |
| |
| // Make sure uid still has read access to the property |
| ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_READ); |
| |
| // Get the accessMap |
| ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop2, |
| &accessMap)); |
| |
| // Make sure uid still has write access to the property |
| ASSERT_EQ((*accessMap)[uid2], VEHICLE_PROP_ACCESS_WRITE); |
| |
| ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop1, uid1, 0)); |
| ASSERT_FALSE(mVehiclePropertyAccessControl.testAccess(prop1, uid1, 1)); |
| ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop2, uid2, 1)); |
| ASSERT_FALSE(mVehiclePropertyAccessControl.testAccess(prop2, uid2, 0)); |
| ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop3, uid3, 1)); |
| ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop3, uid3, 0)); |
| |
| static const std::string dump_msg = |
| "UID 1000: property 0x0000000a, access read\n" |
| "UID 2000: property 0x0000000b, access write\n" |
| "UID 3000: property 0x0000000c, access read/write\n"; |
| |
| String8 msg; |
| mVehiclePropertyAccessControl.dump(msg); |
| |
| ASSERT_EQ(dump_msg.compare(msg.string()), 0); |
| |
| } |
| |
| TEST_F(VehiclePropertyAccessControlTest, init) { |
| xmlFreeDoc(doc); |
| xmlCleanupParser(); |
| // Empty the map |
| mVehiclePropertyAccessControl.emptyAccessControlMap(); |
| ASSERT_TRUE(mVehiclePropertyAccessControl.init()); |
| } |
| }; // namespace android |