| /* |
| * Copyright (C) 2019 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 <string> |
| |
| #include <android-base/test_utils.h> |
| #include <gtest/gtest.h> |
| |
| #include "ApiChecker.h" |
| #include "Common.h" |
| |
| namespace { |
| |
| constexpr const char* kLatestApi = |
| R"( |
| props { |
| owner: Platform |
| module: "android.all_dep" |
| prop { |
| api_name: "dep1" |
| type: Integer |
| scope: Public |
| access: ReadWrite |
| prop_name: "dep1_int" |
| deprecated: true |
| } |
| } |
| props { |
| owner: Platform |
| module: "android.legacy" |
| prop { |
| api_name: "legacy_prop" |
| type: String |
| scope: Public |
| access: Readonly |
| prop_name: "legacy_prop" |
| } |
| } |
| props { |
| owner: Platform |
| module: "android.platprop" |
| prop { |
| api_name: "prop1" |
| type: Long |
| scope: Public |
| access: ReadWrite |
| prop_name: "prop1" |
| } |
| prop { |
| api_name: "prop3" |
| type: Boolean |
| scope: Public |
| access: ReadWrite |
| prop_name: "ctl.start$prop3" |
| } |
| prop { |
| api_name: "prop4" |
| type: String |
| scope: Public |
| access: Readonly |
| prop_name: "ro.prop4" |
| } |
| } |
| )"; |
| |
| constexpr const char* kCurrentApi = |
| R"( |
| props { |
| owner: Platform |
| module: "android.legacy" |
| prop { |
| api_name: "new_prop" |
| type: String |
| scope: Public |
| access: Readonly |
| prop_name: "new_prop" |
| legacy_prop_name: "legacy_prop" |
| } |
| } |
| props { |
| owner: Platform |
| module: "android.platprop" |
| prop { |
| api_name: "prop1" |
| type: Long |
| scope: Public |
| access: ReadWrite |
| prop_name: "prop1" |
| } |
| prop { |
| api_name: "prop2" |
| type: Integer |
| scope: Public |
| access: Writeonce |
| prop_name: "ro.public.prop2" |
| } |
| prop { |
| api_name: "prop3" |
| type: Boolean |
| scope: Public |
| access: ReadWrite |
| prop_name: "ctl.start$prop3" |
| } |
| prop { |
| api_name: "prop4" |
| type: String |
| scope: Public |
| access: Readonly |
| prop_name: "ro.prop4" |
| deprecated: true |
| } |
| |
| } |
| )"; |
| |
| constexpr const char* kInvalidCurrentApi = |
| R"( |
| props { |
| owner: Platform |
| module: "android.legacy" |
| prop { |
| api_name: "legacy_prop" |
| type: String |
| scope: Public |
| access: Readonly |
| prop_name: "legacy_prop" |
| } |
| } |
| props { |
| prop { |
| api_name: "prop1" |
| type: Integer |
| scope: Public |
| access: Readonly |
| prop_name: "prop1" |
| } |
| owner: Platform |
| module: "android.platprop" |
| prop { |
| api_name: "prop3" |
| type: Boolean |
| scope: Public |
| access: ReadWrite |
| integer_as_bool: true |
| prop_name: "ctl.start$prop3" |
| } |
| } |
| )"; |
| |
| } // namespace |
| |
| TEST(SyspropTest, ApiCheckerTest) { |
| TemporaryFile latest_file; |
| close(latest_file.fd); |
| latest_file.fd = -1; |
| ASSERT_TRUE(android::base::WriteStringToFile(kLatestApi, latest_file.path)); |
| |
| std::string err; |
| auto latest_api = ParseApiFile(latest_file.path); |
| ASSERT_RESULT_OK(latest_api); |
| |
| TemporaryFile current_file; |
| close(current_file.fd); |
| current_file.fd = -1; |
| ASSERT_TRUE(android::base::WriteStringToFile(kCurrentApi, current_file.path)); |
| |
| auto current_api = ParseApiFile(current_file.path); |
| ASSERT_RESULT_OK(current_api); |
| EXPECT_RESULT_OK(CompareApis(*latest_api, *current_api)); |
| |
| TemporaryFile invalid_current_file; |
| close(invalid_current_file.fd); |
| invalid_current_file.fd = -1; |
| ASSERT_TRUE(android::base::WriteStringToFile(kInvalidCurrentApi, |
| invalid_current_file.path)); |
| |
| auto invalid_current_api = ParseApiFile(invalid_current_file.path); |
| ASSERT_RESULT_OK(invalid_current_api); |
| |
| auto res = CompareApis(*latest_api, *invalid_current_api); |
| EXPECT_FALSE(res.ok()); |
| |
| EXPECT_EQ(res.error().message(), |
| "Type of prop prop1 has been changed\n" |
| "Accessibility of prop prop1 has become more restrictive\n" |
| "Integer-as-bool of prop prop3 has been changed\n" |
| "Prop prop4 has been removed\n"); |
| } |