blob: 872e9a1ffebf9e18f61fcf15e692c0713877d4d0 [file] [log] [blame]
Tom Cherry16fad422017-08-04 15:59:03 -07001/*
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 "persistent_properties.h"
18
19#include <errno.h>
20
Tom Cherrya97faba2017-09-15 15:44:04 -070021#include <vector>
22
Tom Cherry16fad422017-08-04 15:59:03 -070023#include <android-base/test_utils.h>
24#include <gtest/gtest.h>
25
26#include "util.h"
27
28using namespace std::string_literals;
29
30namespace android {
31namespace init {
32
Tom Cherrya97faba2017-09-15 15:44:04 -070033PersistentProperties VectorToPersistentProperties(
34 const std::vector<std::pair<std::string, std::string>>& input_properties) {
35 PersistentProperties persistent_properties;
36
37 for (const auto& [name, value] : input_properties) {
38 auto persistent_property_record = persistent_properties.add_properties();
39 persistent_property_record->set_name(name);
40 persistent_property_record->set_value(value);
41 }
42
43 return persistent_properties;
44}
45
46void CheckPropertiesEqual(std::vector<std::pair<std::string, std::string>> expected,
47 const PersistentProperties& persistent_properties) {
48 for (const auto& persistent_property_record : persistent_properties.properties()) {
49 auto it = std::find_if(expected.begin(), expected.end(),
50 [persistent_property_record](const auto& entry) {
51 return entry.first == persistent_property_record.name() &&
52 entry.second == persistent_property_record.value();
53 });
54 ASSERT_TRUE(it != expected.end())
Tom Cherrya1419072017-09-19 13:12:57 -070055 << "Found unexpected property (" << persistent_property_record.name() << ", "
Tom Cherrya97faba2017-09-15 15:44:04 -070056 << persistent_property_record.value() << ")";
57 expected.erase(it);
58 }
59 auto joiner = [](const std::vector<std::pair<std::string, std::string>>& vector) {
60 std::string result;
61 for (const auto& [name, value] : vector) {
62 result += " (" + name + ", " + value + ")";
63 }
64 return result;
Tom Cherry16fad422017-08-04 15:59:03 -070065 };
Tom Cherrya97faba2017-09-15 15:44:04 -070066 EXPECT_TRUE(expected.empty()) << "Did not find expected properties:" << joiner(expected);
Tom Cherry16fad422017-08-04 15:59:03 -070067}
68
69TEST(persistent_properties, EndToEnd) {
70 TemporaryFile tf;
71 ASSERT_TRUE(tf.fd != -1);
72 persistent_property_filename = tf.path;
73
74 std::vector<std::pair<std::string, std::string>> persistent_properties = {
75 {"persist.sys.locale", "en-US"},
76 {"persist.sys.timezone", "America/Los_Angeles"},
77 {"persist.test.empty.value", ""},
78 {"persist.test.new.line", "abc\n\n\nabc"},
79 {"persist.test.numbers", "1234567890"},
80 {"persist.test.non.ascii", "\x00\x01\x02\xFF\xFE\xFD\x7F\x8F\x9F"},
Tom Cherrya97faba2017-09-15 15:44:04 -070081 // We don't currently allow for non-ascii names for system properties, but this is a policy
Tom Cherry16fad422017-08-04 15:59:03 -070082 // decision, not a technical limitation.
Tom Cherrya97faba2017-09-15 15:44:04 -070083 {"persist.\x00\x01\x02\xFF\xFE\xFD\x7F\x8F\x9F", "non-ascii-name"},
Tom Cherry16fad422017-08-04 15:59:03 -070084 };
85
Tom Cherrya97faba2017-09-15 15:44:04 -070086 ASSERT_TRUE(WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
Tom Cherry16fad422017-08-04 15:59:03 -070087
88 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -070089 CheckPropertiesEqual(persistent_properties, read_back_properties);
Tom Cherry16fad422017-08-04 15:59:03 -070090}
91
92TEST(persistent_properties, AddProperty) {
93 TemporaryFile tf;
94 ASSERT_TRUE(tf.fd != -1);
95 persistent_property_filename = tf.path;
96
97 std::vector<std::pair<std::string, std::string>> persistent_properties = {
98 {"persist.sys.timezone", "America/Los_Angeles"},
99 };
Tom Cherrya97faba2017-09-15 15:44:04 -0700100 ASSERT_TRUE(WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
Tom Cherry16fad422017-08-04 15:59:03 -0700101
102 WritePersistentProperty("persist.sys.locale", "pt-BR");
103
104 std::vector<std::pair<std::string, std::string>> persistent_properties_expected = {
105 {"persist.sys.timezone", "America/Los_Angeles"},
106 {"persist.sys.locale", "pt-BR"},
107 };
108
109 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -0700110 CheckPropertiesEqual(persistent_properties_expected, read_back_properties);
Tom Cherry16fad422017-08-04 15:59:03 -0700111}
112
113TEST(persistent_properties, UpdateProperty) {
114 TemporaryFile tf;
115 ASSERT_TRUE(tf.fd != -1);
116 persistent_property_filename = tf.path;
117
118 std::vector<std::pair<std::string, std::string>> persistent_properties = {
119 {"persist.sys.locale", "en-US"},
120 {"persist.sys.timezone", "America/Los_Angeles"},
121 };
Tom Cherrya97faba2017-09-15 15:44:04 -0700122 ASSERT_TRUE(WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
Tom Cherry16fad422017-08-04 15:59:03 -0700123
124 WritePersistentProperty("persist.sys.locale", "pt-BR");
125
126 std::vector<std::pair<std::string, std::string>> persistent_properties_expected = {
127 {"persist.sys.locale", "pt-BR"},
128 {"persist.sys.timezone", "America/Los_Angeles"},
129 };
130
131 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -0700132 CheckPropertiesEqual(persistent_properties_expected, read_back_properties);
Tom Cherry16fad422017-08-04 15:59:03 -0700133}
134
135TEST(persistent_properties, UpdatePropertyBadParse) {
136 TemporaryFile tf;
137 ASSERT_TRUE(tf.fd != -1);
138 persistent_property_filename = tf.path;
139
140 ASSERT_TRUE(WriteFile(tf.path, "ab"));
141
142 WritePersistentProperty("persist.sys.locale", "pt-BR");
143
144 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -0700145 EXPECT_GT(read_back_properties.properties().size(), 0);
Tom Cherry16fad422017-08-04 15:59:03 -0700146
Tom Cherrya97faba2017-09-15 15:44:04 -0700147 auto it =
148 std::find_if(read_back_properties.properties().begin(),
149 read_back_properties.properties().end(), [](const auto& entry) {
150 return entry.name() == "persist.sys.locale" && entry.value() == "pt-BR";
151 });
152 EXPECT_FALSE(it == read_back_properties.properties().end());
Tom Cherry16fad422017-08-04 15:59:03 -0700153}
154
155} // namespace init
156} // namespace android