blob: 60cecde252009785364939f3b90bd9216896bdfc [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
Mark Salyzyn9f1cf252018-11-12 12:45:59 -080023#include <android-base/file.h>
Tom Cherry16fad422017-08-04 15:59:03 -070024#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
Bernie Innocenticecebbb2020-02-06 03:49:33 +090086 ASSERT_RESULT_OK(
87 WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
Tom Cherry16fad422017-08-04 15:59:03 -070088
89 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -070090 CheckPropertiesEqual(persistent_properties, read_back_properties);
Tom Cherry16fad422017-08-04 15:59:03 -070091}
92
93TEST(persistent_properties, AddProperty) {
94 TemporaryFile tf;
95 ASSERT_TRUE(tf.fd != -1);
96 persistent_property_filename = tf.path;
97
98 std::vector<std::pair<std::string, std::string>> persistent_properties = {
99 {"persist.sys.timezone", "America/Los_Angeles"},
100 };
Bernie Innocenticecebbb2020-02-06 03:49:33 +0900101 ASSERT_RESULT_OK(
102 WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
Tom Cherry16fad422017-08-04 15:59:03 -0700103
104 WritePersistentProperty("persist.sys.locale", "pt-BR");
105
106 std::vector<std::pair<std::string, std::string>> persistent_properties_expected = {
107 {"persist.sys.timezone", "America/Los_Angeles"},
108 {"persist.sys.locale", "pt-BR"},
109 };
110
111 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -0700112 CheckPropertiesEqual(persistent_properties_expected, read_back_properties);
Tom Cherry16fad422017-08-04 15:59:03 -0700113}
114
115TEST(persistent_properties, UpdateProperty) {
116 TemporaryFile tf;
117 ASSERT_TRUE(tf.fd != -1);
118 persistent_property_filename = tf.path;
119
120 std::vector<std::pair<std::string, std::string>> persistent_properties = {
121 {"persist.sys.locale", "en-US"},
122 {"persist.sys.timezone", "America/Los_Angeles"},
123 };
Bernie Innocenticecebbb2020-02-06 03:49:33 +0900124 ASSERT_RESULT_OK(
125 WritePersistentPropertyFile(VectorToPersistentProperties(persistent_properties)));
Tom Cherry16fad422017-08-04 15:59:03 -0700126
127 WritePersistentProperty("persist.sys.locale", "pt-BR");
128
129 std::vector<std::pair<std::string, std::string>> persistent_properties_expected = {
130 {"persist.sys.locale", "pt-BR"},
131 {"persist.sys.timezone", "America/Los_Angeles"},
132 };
133
134 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -0700135 CheckPropertiesEqual(persistent_properties_expected, read_back_properties);
Tom Cherry16fad422017-08-04 15:59:03 -0700136}
137
138TEST(persistent_properties, UpdatePropertyBadParse) {
139 TemporaryFile tf;
140 ASSERT_TRUE(tf.fd != -1);
141 persistent_property_filename = tf.path;
142
Bernie Innocenticecebbb2020-02-06 03:49:33 +0900143 ASSERT_RESULT_OK(WriteFile(tf.path, "ab"));
Tom Cherry16fad422017-08-04 15:59:03 -0700144
145 WritePersistentProperty("persist.sys.locale", "pt-BR");
146
147 auto read_back_properties = LoadPersistentProperties();
Tom Cherrya97faba2017-09-15 15:44:04 -0700148 EXPECT_GT(read_back_properties.properties().size(), 0);
Tom Cherry16fad422017-08-04 15:59:03 -0700149
Tom Cherrya97faba2017-09-15 15:44:04 -0700150 auto it =
151 std::find_if(read_back_properties.properties().begin(),
152 read_back_properties.properties().end(), [](const auto& entry) {
153 return entry.name() == "persist.sys.locale" && entry.value() == "pt-BR";
154 });
155 EXPECT_FALSE(it == read_back_properties.properties().end());
Tom Cherry16fad422017-08-04 15:59:03 -0700156}
157
158} // namespace init
159} // namespace android