1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2015 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
169724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
179724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include "shill/json_store.h"
189724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
199724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include <array>
209724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include <limits>
21f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal#include <memory>
222293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal#include <set>
239724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include <string>
242293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal#include <utility>
259724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include <vector>
269724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
27f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal#include <base/files/file_enumerator.h>
2893863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal#include <base/files/file_util.h>
29f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal#include <base/files/scoped_temp_dir.h>
309724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include <base/strings/string_util.h>
319724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include <gtest/gtest.h>
329724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
339724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal#include "shill/mock_log.h"
349724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
35f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawalusing base::FileEnumerator;
36f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawalusing base::FilePath;
37f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawalusing base::ScopedTempDir;
389724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing std::array;
392293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalusing std::pair;
409724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing std::set;
419724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing std::string;
42f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawalusing std::unique_ptr;
439724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing std::vector;
449724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing testing::_;
459724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing testing::AnyNumber;
469724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing testing::ContainsRegex;
479724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing testing::HasSubstr;
48f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawalusing testing::StartsWith;
499724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalusing testing::Test;
509724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
519724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalnamespace shill {
529724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
539724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalclass JsonStoreTest : public Test {
549724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal public:
559724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  JsonStoreTest()
569724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      : kStringWithEmbeddedNulls({0, 'a', 0, 'z'}),
579724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal        kNonUtf8String("ab\xc0") {}
589724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
599724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  virtual void SetUp() {
609724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    ScopeLogger::GetInstance()->EnableScopesByName("+storage");
619724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    ASSERT_FALSE(base::IsStringUTF8(kNonUtf8String));
62f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
63f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal    test_file_ = temp_dir_.path().Append("test-json-store");
6478e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal    store_.reset(new JsonStore(test_file_));
659724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_CALL(log_, Log(_, _, _)).Times(AnyNumber());
669724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
679724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
689724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  virtual void TearDown() {
699724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    ScopeLogger::GetInstance()->EnableScopesByName("-storage");
709724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    ScopeLogger::GetInstance()->set_verbose_level(0);
719724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
729724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
739724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal protected:
749724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  void SetVerboseLevel(int new_level);
7593863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  void SetJsonFileContents(const string& data);
769724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
779724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const string kStringWithEmbeddedNulls;
789724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const string kNonUtf8String;
79f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  ScopedTempDir temp_dir_;
80f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  FilePath test_file_;
81f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  unique_ptr<JsonStore> store_;
829724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  ScopedMockLog log_;
839724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal};
849724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
859724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalvoid JsonStoreTest::SetVerboseLevel(int new_level) {
869724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  ScopeLogger::GetInstance()->set_verbose_level(new_level);
879724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
889724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
8993863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalvoid JsonStoreTest::SetJsonFileContents(const string& data) {
9093863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  EXPECT_EQ(data.size(),
91cbaa24d68afc8e5339059c26101f313f8487dd99mukesh agrawal            base::WriteFile(test_file_, data.data(), data.size()));
9293863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
9393863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
949724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal// In memory operations: basic storage and retrieval.
959724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, StringsCanBeStoredInMemory) {
969724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const array<string, 5> our_values{
979724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    {"", "hello", "world\n", kStringWithEmbeddedNulls, kNonUtf8String}};
989724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  for (const auto& our_value : our_values) {
999724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    string value_from_store;
100f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->SetString("group_a", "knob_1", our_value));
101f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->GetString("group_a", "knob_1", &value_from_store));
1029724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_EQ(our_value, value_from_store);
1039724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
1049724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1059724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1069724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, BoolsCanBeStoredInMemory) {
1079724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const array<bool, 2> our_values{{false, true}};
1089724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  for (const auto& our_value : our_values) {
1099724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    bool value_from_store;
110f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->SetBool("group_a", "knob_1", our_value));
111f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->GetBool("group_a", "knob_1", &value_from_store));
1129724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_EQ(our_value, value_from_store);
1139724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
1149724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1159724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1169724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, IntsCanBeStoredInMemory) {
1179724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const array<int, 3> our_values{{
1189724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      std::numeric_limits<int>::min(), 0, std::numeric_limits<int>::max()}};
1199724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  for (const auto& our_value : our_values) {
1209724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    int value_from_store;
121f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->SetInt("group_a", "knob_1", our_value));
122f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->GetInt("group_a", "knob_1", &value_from_store));
1239724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_EQ(our_value, value_from_store);
1249724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
1259724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1269724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1279724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, Uint64sCanBeStoredInMemory) {
1289724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const array<uint64_t, 3> our_values{{
1299724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      std::numeric_limits<uint64_t>::min(),
1309724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      0,
1319724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      std::numeric_limits<uint64_t>::max()}};
1329724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  for (const auto& our_value : our_values) {
1339724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    uint64_t value_from_store;
134f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->SetUint64("group_a", "knob_1", our_value));
135f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->GetUint64("group_a", "knob_1", &value_from_store));
1369724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_EQ(our_value, value_from_store);
1379724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
1389724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1399724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1409724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, StringListsCanBeStoredInMemory) {
1419724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const array<vector<string>, 7> our_values{{
1429724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      vector<string>{},
1439724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      vector<string>{""},
1449724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      vector<string>{"a"},
1459724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      vector<string>{"", "a"},
1469724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      vector<string>{"a", ""},
1479724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      vector<string>{"", "a", ""},
1489724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      vector<string>{"a", "b", "c", kStringWithEmbeddedNulls, kNonUtf8String}}};
1499724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  for (const auto& our_value : our_values) {
1509724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    vector<string> value_from_store;
151f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->SetStringList("group_a", "knob_1", our_value));
152f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->GetStringList("group_a", "knob_1", &value_from_store));
1539724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_EQ(our_value, value_from_store);
1549724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
1559724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1569724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1579724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, CryptedStringsCanBeStoredInMemory) {
1589724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const array<string, 5> our_values{{
1599724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      string(), string("some stuff"), kStringWithEmbeddedNulls, kNonUtf8String
1609724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }};
1619724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  for (const auto& our_value : our_values) {
1629724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    string value_from_store;
163f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->SetCryptedString("group_a", "knob_1", our_value));
1649724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_TRUE(
165f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal        store_->GetCryptedString("group_a", "knob_1", &value_from_store));
1669724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_EQ(our_value, value_from_store);
1679724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
1689724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1699724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1709724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, RawValuesOfCryptedStringsDifferFromOriginalValues) {
1719724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  const array<string, 3> our_values{{
1729724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      string("simple string"), kStringWithEmbeddedNulls, kNonUtf8String
1739724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }};
1749724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  for (const auto& our_value : our_values) {
1759724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    string raw_value_from_store;
176f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->SetCryptedString("group_a", "knob_1", our_value));
177f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_TRUE(store_->GetString("group_a", "knob_1", &raw_value_from_store));
1789724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal    EXPECT_NE(our_value, raw_value_from_store);
1799724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  }
1809724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1819724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1829724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, DifferentGroupsCanHaveDifferentValuesForSameKey) {
183f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "value_1");
184f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_b", "knob_1", "value_2");
1859724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1869724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  string value_from_store;
187f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetString("group_a", "knob_1", &value_from_store));
1889724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_EQ("value_1", value_from_store);
189f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetString("group_b", "knob_1", &value_from_store));
1909724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_EQ("value_2", value_from_store);
1919724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
1929724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1939724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal// In memory operations: presence checking.
1949724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, CanUseNullptrToCheckPresenceOfKey) {
1959724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  SetVerboseLevel(10);
1969724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
1979724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find group"))).Times(6);
198f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "string_knob", nullptr));
199f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "bool_knob", nullptr));
200f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetInt("group_a", "int_knob", nullptr));
201f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetUint64("group_a", "uint64_knob", nullptr));
202f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetStringList("group_a", "string_list_knob", nullptr));
2039724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_FALSE(
204f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->GetCryptedString("group_a", "crypted_string_knob", nullptr));
2059724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
206f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->SetString("group_a", "random_knob", "random value"));
2079724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find property"))).Times(6);
208f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "string_knob", nullptr));
209f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "bool_knob", nullptr));
210f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetInt("group_a", "int_knob", nullptr));
211f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetUint64("group_a", "uint64_knob", nullptr));
212f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetStringList("group_a", "string_list_knob", nullptr));
2139724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_FALSE(
214f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->GetCryptedString("group_a", "crypted_string_knob", nullptr));
2159724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
216f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->SetString("group_a", "string_knob", "stuff goes here"));
217f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->SetBool("group_a", "bool_knob", true));
218f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->SetInt("group_a", "int_knob", -1));
219f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->SetUint64("group_a", "uint64_knob", 1));
220f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->SetStringList(
2219724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      "group_a", "string_list_knob", vector<string>{{"hello"}}));
2229724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  ASSERT_TRUE(
223f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->SetCryptedString("group_a", "crypted_string_knob", "s3kr!t"));
2249724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
225f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetString("group_a", "string_knob", nullptr));
226f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetBool("group_a", "bool_knob", nullptr));
227f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetInt("group_a", "int_knob", nullptr));
228f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetUint64("group_a", "uint64_knob", nullptr));
229f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetStringList("group_a", "string_list_knob", nullptr));
2309724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_TRUE(
231f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->GetCryptedString("group_a", "crypted_string_knob", nullptr));
2329724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
2339724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
2349724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal// In memory operations: access to missing elements.
2359724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, GetFromEmptyStoreFails) {
2369724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  bool value_from_store;
2379724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  SetVerboseLevel(10);
2389724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find group")));
239f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", &value_from_store));
2409724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
2419724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
2429724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, GetFromNonexistentGroupAndKeyFails) {
2439724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  bool value_from_store;
2449724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  SetVerboseLevel(10);
245f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetBool("group_a", "knob_1", true));
2469724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find group")));
247f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_b", "knob_1", &value_from_store));
2489724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
2499724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
2509724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, GetOfNonexistentPropertyFails) {
2519724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  bool value_from_store;
2529724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  SetVerboseLevel(10);
253f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetBool("group_a", "knob_1", true));
2549724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find property")));
255f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_2", &value_from_store));
2569724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
2579724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
2589724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, GetOfPropertyFromWrongGroupFails) {
2599724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  bool value_from_store;
2609724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  SetVerboseLevel(10);
261f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetBool("group_a", "knob_1", true));
2629724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find group")));
263f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_b", "knob_1", &value_from_store));
2649724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
2659724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
2669724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, GetDoesNotMatchOnValue) {
2679724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  string value_from_store;
2689724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  SetVerboseLevel(10);
269f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetString("group_a", "knob_1", "value_1"));
2709724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find property")));
271f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "value_1", &value_from_store));
2729724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
2739724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
2749724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal// In memory operations: type conversions on read.
2759724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, ConversionFromStringIsProhibited) {
2769724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(
2779724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      log_,
2789724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      Log(logging::LOG_ERROR, _,
2799724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal          ContainsRegex("Can not read \\|.+\\| from \\|.+\\|"))).Times(4);
280f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetString("group_a", "knob_1", "stuff goes here"));
281f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
282f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetInt("group_a", "knob_1", nullptr));
283f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetUint64("group_a", "knob_1", nullptr));
284f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetStringList("group_a", "knob_1", nullptr));
285f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  // We deliberately omit checking store_->GetCryptedString(). While
2869724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  // this "works" right now, it's not something we're committed to.
2879724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
2889724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
2899724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, ConversionFromBoolIsProhibited) {
2909724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(
2919724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      log_,
2929724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      Log(logging::LOG_ERROR, _,
2939724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal          ContainsRegex("Can not read \\|.+\\| from \\|.+\\|"))).Times(5);
294f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetBool("group_a", "knob_1", true));
295f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "knob_1", nullptr));
296f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetInt("group_a", "knob_1", nullptr));
297f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetUint64("group_a", "knob_1", nullptr));
298f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetStringList("group_a", "knob_1", nullptr));
299f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetCryptedString("group_a", "knob_1", nullptr));
3009724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
3019724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
3029724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, ConversionFromIntIsProhibited) {
3039724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(
3049724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      log_,
3059724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      Log(logging::LOG_ERROR, _,
3069724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal          ContainsRegex("Can not read \\|.+\\| from \\|.+\\|"))).Times(5);
307f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetInt("group_a", "knob_1", -1));
308f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "knob_1", nullptr));
309f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
310f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetUint64("group_a", "knob_1", nullptr));
311f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetStringList("group_a", "knob_1", nullptr));
312f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetCryptedString("group_a", "knob_1", nullptr));
3139724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
3149724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
3159724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, ConversionFromUint64IsProhibited) {
3169724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(
3179724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      log_,
3189724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      Log(logging::LOG_ERROR, _,
3199724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal          ContainsRegex("Can not read \\|.+\\| from \\|.+\\|"))).Times(5);
320f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetUint64("group_a", "knob_1", 1));
321f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "knob_1", nullptr));
322f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
323f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetInt("group_a", "knob_1", nullptr));
324f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetStringList("group_a", "knob_1", nullptr));
325f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetCryptedString("group_a", "knob_1", nullptr));
3269724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
3279724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
3289724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, ConversionFromStringListIsProhibited) {
3299724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(
3309724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      log_,
3319724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      Log(logging::LOG_ERROR, _,
3329724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal          ContainsRegex("Can not read \\|.+\\| from \\|.+\\|"))).Times(5);
333f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetStringList(
3349724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      "group_a", "knob_1", vector<string>{{"hello"}}));
335f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "knob_1", nullptr));
336f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
337f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetInt("group_a", "knob_1", nullptr));
338f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetUint64("group_a", "knob_1", nullptr));
339f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetCryptedString("group_a", "knob_1", nullptr));
3409724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
3419724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
3429724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawalTEST_F(JsonStoreTest, ConversionFromCryptedStringIsProhibited) {
3439724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  EXPECT_CALL(
3449724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      log_,
3459724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal      Log(logging::LOG_ERROR, _,
3469724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal          ContainsRegex("Can not read \\|.+\\| from \\|.+\\|"))).Times(4);
347f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->SetCryptedString("group_a", "knob_1", "s3kr!t"));
348f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  // We deliberately omit checking store_->GetString(). While this
3499724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal  // "works" right now, it's not something we're committed to.
350f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
351f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetInt("group_a", "knob_1", nullptr));
352f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetUint64("group_a", "knob_1", nullptr));
353f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetStringList("group_a", "knob_1", nullptr));
3549724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}
3559724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal
3565002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal// In memory operations: key deletion.
3575002ed63ee532d873c64e0acf2b813015b327077mukesh agrawalTEST_F(JsonStoreTest, DeleteKeyDeletesExistingKey) {
3585002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal  SetVerboseLevel(10);
359f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
360f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->DeleteKey("group_a", "knob_1"));
3615002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find property")));
362f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
3635002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal}
3645002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal
3655002ed63ee532d873c64e0acf2b813015b327077mukesh agrawalTEST_F(JsonStoreTest, DeleteKeyDeletesOnlySpecifiedKey) {
366f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
367f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_2", bool());
368f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->DeleteKey("group_a", "knob_1"));
369f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
370f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetBool("group_a", "knob_2", nullptr));
3715002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal}
3725002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal
3735002ed63ee532d873c64e0acf2b813015b327077mukesh agrawalTEST_F(JsonStoreTest, DeleteKeySucceedsOnMissingKey) {
374f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
375f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->DeleteKey("group_a", "knob_2"));
376f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetBool("group_a", "knob_1", nullptr));
3775002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal}
3785002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal
3795002ed63ee532d873c64e0acf2b813015b327077mukesh agrawalTEST_F(JsonStoreTest, DeleteKeyFailsWhenGivenWrongGroup) {
3805002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal  SetVerboseLevel(10);
381f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
3825002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find group")));
383f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->DeleteKey("group_b", "knob_1"));
384f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetBool("group_a", "knob_1", nullptr));
3855002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal}
3865002ed63ee532d873c64e0acf2b813015b327077mukesh agrawal
3872293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal// In memory operations: group operations.
3882293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, EmptyStoreReturnsNoGroups) {
389f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_EQ(set<string>(), store_->GetGroups());
390f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_EQ(set<string>(), store_->GetGroupsWithKey("knob_1"));
391f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_EQ(set<string>(), store_->GetGroupsWithProperties(KeyValueStore()));
3922293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
3932293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
3942293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, GetGroupsReturnsAllGroups) {
395f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
396f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_1", bool());
397f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_EQ(set<string>({"group_a", "group_b"}), store_->GetGroups());
3982293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
3992293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4002293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, GetGroupsWithKeyReturnsAllMatchingGroups) {
401f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
402f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_1", bool());
4032293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  EXPECT_EQ(set<string>({"group_a", "group_b"}),
404f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal            store_->GetGroupsWithKey("knob_1"));
4052293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
4062293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4072293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, GetGroupsWithKeyReturnsOnlyMatchingGroups) {
408f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
409f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_2", bool());
410f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_EQ(set<string>({"group_a"}), store_->GetGroupsWithKey("knob_1"));
4112293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
4122293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4132293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, GetGroupsWithPropertiesReturnsAllMatchingGroups) {
414f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", true);
415f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_1", true);
4162293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4172293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  KeyValueStore required_properties;
4182293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  required_properties.SetBool("knob_1", true);
4192293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  EXPECT_EQ(set<string>({"group_a", "group_b"}),
420f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal            store_->GetGroupsWithProperties(required_properties));
4212293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
4222293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4232293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, GetGroupsWithPropertiesReturnsOnlyMatchingGroups) {
424f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", true);
425f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_1", false);
4262293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4272293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  KeyValueStore required_properties;
4282293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  required_properties.SetBool("knob_1", true);
4292293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  EXPECT_EQ(set<string>({"group_a"}),
430f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal            store_->GetGroupsWithProperties(required_properties));
4312293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
4322293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4332293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, GetGroupsWithPropertiesCanMatchOnMultipleProperties) {
434f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", true);
435f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_2", true);
436f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_1", true);
437f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_2", false);
4382293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4392293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  KeyValueStore required_properties;
4402293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  required_properties.SetBool("knob_1", true);
4412293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  required_properties.SetBool("knob_2", true);
4422293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  EXPECT_EQ(set<string>({"group_a"}),
443f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal            store_->GetGroupsWithProperties(required_properties));
4442293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
4452293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4462293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, GetGroupsWithPropertiesChecksValuesForBoolIntAndString) {
4472293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // Documentation in StoreInterface says GetGroupsWithProperties
4482293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // checks only Bool, Int, and String properties. For now, we interpret
4492293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // that permissively. i.e., checking other types is not guaranteed one
4502293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // way or the other.
4512293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  //
4522293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // Said differently: we test that that Bool, Int, and String are
4532293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // supported. But we don't test that other types are ignored. (In
4542293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // fact, JsonStore supports filtering on uint64 and StringList as
4552293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // well. JsonStore does not, however, support filtering on
4562293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // CryptedStrings.)
4572293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  //
4582293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // This should be fine, as StoreInterface clients currently only use
4592293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  // String value filtering.
46003e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  const brillo::VariantDictionary exact_matcher({
4612293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal      {"knob_1", string("good-string")},
4622293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal      {"knob_2", bool{true}},
4632293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal      {"knob_3", int{1}},
4642293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    });
465f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "good-string");
466f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_2", true);
467f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetInt("group_a", "knob_3", 1);
4682293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4692293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  {
4702293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    KeyValueStore correct_properties;
4712293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    KeyValueStore::ConvertFromVariantDictionary(
4722293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal        exact_matcher, &correct_properties);
4732293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    EXPECT_EQ(set<string>({"group_a"}),
474f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal              store_->GetGroupsWithProperties(correct_properties));
4752293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  }
4762293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
47703e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko  const vector<pair<string, brillo::Any>> bad_matchers({
4782293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal      {"knob_1", string("bad-string")},
4792293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal      {"knob_2", bool{false}},
4802293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal      {"knob_3", int{2}},
4812293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    });
4822293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  for (const auto& match_key_and_value : bad_matchers) {
4832293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    const auto& match_key = match_key_and_value.first;
4842293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    const auto& match_value = match_key_and_value.second;
48503e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko    brillo::VariantDictionary bad_matcher_dict(exact_matcher);
4862293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    KeyValueStore bad_properties;
4872293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    bad_matcher_dict[match_key] = match_value;
4882293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal    KeyValueStore::ConvertFromVariantDictionary(
4892293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal        bad_matcher_dict, &bad_properties);
490f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal    EXPECT_EQ(set<string>(), store_->GetGroupsWithProperties(bad_properties))
4912293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal        << "Failing match key: " << match_key;
4922293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  }
4932293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
4942293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
4952293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, ContainsGroupFindsExistingGroup) {
496f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
497f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->ContainsGroup("group_a"));
4982293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
4992293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
5002293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, ContainsGroupDoesNotFabricateGroups) {
501f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->ContainsGroup("group_a"));
5022293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
5032293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
5042293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, DeleteGroupDeletesExistingGroup) {
5052293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  SetVerboseLevel(10);
506f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
507f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_2", bool());
508f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->DeleteGroup("group_a"));
5092293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find group"))).Times(2);
510f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
511f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_2", nullptr));
5122293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
5132293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
5142293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, DeleteGroupDeletesOnlySpecifiedGroup) {
515f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
516f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_b", "knob_1", bool());
517f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->DeleteGroup("group_a"));
518f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetBool("group_a", "knob_1", nullptr));
519f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetBool("group_b", "knob_1", nullptr));
5202293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
5212293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
5222293273abea61e6185c1df3c17a61fda0d699469mukesh agrawalTEST_F(JsonStoreTest, DeleteGroupSucceedsOnMissingGroup) {
523f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "knob_1", bool());
524f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->DeleteGroup("group_b"));
525f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetBool("group_a", "knob_1", nullptr));
5262293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal}
5272293273abea61e6185c1df3c17a61fda0d699469mukesh agrawal
52893863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal// File open: basic file structure.
52993863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnNonExistentFile) {
53093863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  // If the file does not already exist, we assume the caller will
53193863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  // give us data later.
532f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
53393863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
53493863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
53593863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnNonJsonData) {
53693863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  SetJsonFileContents("some random junk");
53793863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  EXPECT_CALL(log_,
53893863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal              Log(logging::LOG_ERROR, _,
53993863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal                  StartsWith("Failed to parse JSON data")));
540f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
54193863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
54293863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
54393863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal// File open: root element handling.
54493863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalTEST_F(JsonStoreTest, OpenFailsWhenRootIsNonDictionary) {
54593863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  SetJsonFileContents("\"a string\"");
54693863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  EXPECT_CALL(log_,
54793863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal              Log(logging::LOG_ERROR, _,
54893863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal                  StartsWith("JSON value is not a dictionary")));
549f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
55093863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
55193863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
55293863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalTEST_F(JsonStoreTest, OpenWarnsOnRootDictionaryWithNonStringDescription) {
55393863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  SetJsonFileContents("{\"description\": 1}");
55493863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  EXPECT_CALL(
55593863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal      log_,
55693863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal      Log(logging::LOG_WARNING, _, HasSubstr("|description| is not a string")));
557f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Open();
55893863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
55993863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
56093863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnRootDictionaryWithoutSettings) {
56193863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  SetJsonFileContents("{}");
56293863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  EXPECT_CALL(log_,
56393863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal              Log(logging::LOG_ERROR, _,
56493863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal                  StartsWith("Property |settings| is missing")));
565f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
56693863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
56793863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
56893863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal// File open: settings element handling.
56993863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnEmptySettings) {
57093863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  SetJsonFileContents("{\"settings\": {}}");
571f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
57293863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
57393863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
57493863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawalTEST_F(JsonStoreTest, OpenFailsWhenSettingsIsNonDictionary) {
57593863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  SetJsonFileContents("{\"settings\": 1}");
57693863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal  EXPECT_CALL(log_,
57793863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal              Log(logging::LOG_ERROR, _,
57893863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal                  StartsWith("Property |settings| is not a dictionary")));
579f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
58093863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal}
58193863bf643012a02c633d8e95c9fb07487107f6fmukesh agrawal
582ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// File open: group structure.
583ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnEmptyGroup) {
584ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
585ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
586ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {}"
587ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}");
588f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
589ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
590ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
591ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsWhenGroupIsNonDictionary) {
592ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
593ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
594ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": 1"
595ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}");
596ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
597ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _,
598ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal                  StartsWith("Group |group_a| is not a dictionary")));
599f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
600ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
601ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
602ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// File open: each supported property type (with selected valid
603ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// values for each type), ordered by base::Value::Type enum.  Types
604ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// which are not supported by base::Value are ordered as
605ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// TYPE_DICTIONARY.
606ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithBooleanValue) {
607ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
608ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
609ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
610ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": true"
611ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
612f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
613ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
614ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
615ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithMinIntegerValue) {
616ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
617ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
618ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
619ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": -2147483648"  // -2^31
620ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
621f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
622ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
623ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
624ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithMaxIntegerValue) {
625ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
626ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
627ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
628ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": 2147483647"  // 2^31-1
629ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
630f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
631ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
632ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
633ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithStringValue) {
634ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
635ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
636ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
637ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": \"this is \\\"a\\\" string\\n\""
638ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
639f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
640ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
641ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
642ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithEscapedStringValue) {
643ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
644ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
645ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
646ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
647ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"non_ascii_string\","
648ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"0001020304\""
649ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
650f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
651ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
652ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
653ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithMinUint64Value) {
654ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
655ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
656ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
657ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
658ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"uint64\","
659ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"0\""  // 2^64-1
660ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
661f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
662ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
663ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
664ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithMaxUint64Value) {
665ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
666ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
667ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
668ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
669ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"uint64\","
670ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"18446744073709551615\""  // 2^64-1
671ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
672f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
673ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
674ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
675ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithEmptyListValue) {
676ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  // Empty list is presumed to be an empty string list.
677ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
678ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
679ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
680ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": []"
681ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
682f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
683ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
684ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
685ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWithStringListValueWithSingleItem) {
686ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
687ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
688ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
689ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": [ \"a string\" ]"
690ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
691f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
692ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
693ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
694ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(
695ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal    JsonStoreTest, OpenSucceedsOnSettingWithStringListValueWithMultipleItems) {
696ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
697ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
698ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
699ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": [ \"string 1\", \"string 2\\n\" ]"
700ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
701f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
702ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
703ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
704ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenSucceedsOnSettingWhenStringListHasEscapedItem) {
705ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
706ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
707ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
708ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": [{"
709ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"non_ascii_string\","
710ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"0001020304\""
711ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}]}}}");
712f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
713ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
714ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
715ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest,
716ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal       OpenSucceedsOnSettingWhenStringListHasEscapedAndUnescapedItems) {
717ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
718ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
719ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
720ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": ["
721ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            {\"_native_type\": \"non_ascii_string\","
722ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "             \"_encoded_value\": \"0001020304\"},"
723ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"normal string\""
724ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "]}}}");
725f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->Open());
726ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
727ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
728ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// File open: unsupported types, and invalid values. Ordered by
729ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// base::Value::Type enum.  Types which are supported by JsonStore,
730ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// but not directly supported by base::Value, are ordered as
731ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// TYPE_DICTIONARY.
732ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithNullValue) {
733ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
734ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
735ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
736ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": null"
737ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
738ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
739ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _,
740ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal                  HasSubstr("has unsupported TYPE_NULL")));
741f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
742ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
743ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
744ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithBadBooleanValue) {
745ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
746ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
747ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
748ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": truthy"
749ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
750ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
751ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, StartsWith("Failed to parse JSON")));
752f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
753ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
754ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
755ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithOverlySmallInteger) {
756ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
757ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
758ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
759ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": -2147483649"  // -2^31-1
760ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
761ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
762ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, HasSubstr("unsupported TYPE_DOUBLE")));
763f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
764ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
765ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
766ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithOverlyLargeInteger) {
767ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
768ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
769ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
770ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": 2147483648"  // 2^31
771ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
772ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
773ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, HasSubstr("unsupported TYPE_DOUBLE")));
774f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
775ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
776ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
777ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithDoubleValue) {
778ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
779ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
780ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
781ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": 1.234"
782ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
783ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
784ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, HasSubstr("unsupported TYPE_DOUBLE")));
785f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
786ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
787ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
788ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithDictionaryValue) {
789ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
790ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
791ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
792ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {}"
793ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
794ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
795ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _,
796ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal                  HasSubstr("unsupported TYPE_DICTIONARY")));
797f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
798ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
799ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
800ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithOverlayLargeUint64Value) {
801ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
802ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
803ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
804ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
805ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"uint64\","
806ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"18446744073709551616\""  // 2^64
807ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
808ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
809ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, StartsWith("Failed to parse uint64")));
810f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
811ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
812ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
813ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithOverlaySmallUint64Value) {
814ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
815ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
816ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
817ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
818ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"uint64\","
819ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"-1\""
820ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
821ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
822ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, StartsWith("Failed to parse uint64")));
823f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
824ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
825ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
826ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsWhenSettingHasEscapedStringWithInvalidHex) {
827ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
828ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
829ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
830ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
831ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"non_ascii_string\","
832ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"-1\""
833ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
834ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
835ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, StartsWith("Failed to decode hex")));
836f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
837ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
838ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
839ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest,
840ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal       OpenFailsWhenSettingHasEscapedStringListItemWithInvalidHex) {
841ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
842ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
843ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
844ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": [{"
845ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"non_ascii_string\","
846ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"-1\""
847ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}]}}}");
848ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
849ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _, StartsWith("Failed to decode hex")));
850f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
851ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
852ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
853ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnCoercedSettingWithBadNativeType) {
854ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
855ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
856ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
857ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
858ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": true,"
859ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": \"1234\""
860ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
861ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
862ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _,
863ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal                  StartsWith("Property |_native_type| is not a string")));
864f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
865ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
866ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
867ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnCoercedSettingWhenEncodedValueIsNotAString) {
868ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
869ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
870ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
871ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": {"
872ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_native_type\": \"uint64\","
873ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "            \"_encoded_value\": 1234"
874ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}}");
875ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
876ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _,
877ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal                  StartsWith("Property |_encoded_value| is not a string")));
878f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
879ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
880ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
881ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenFailsOnSettingWithIntListValue) {
882ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
883ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
884ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
885ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_1\": [ 1 ]"
886ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
887ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  EXPECT_CALL(log_,
888ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal              Log(logging::LOG_ERROR, _,
889ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal                  HasSubstr("instead of expected type")));
890f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Open());
891ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
892ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
893ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal// File open: miscellaneous.
894ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenClearsExistingInMemoryData) {
895f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "watch me disappear");
896f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->GetString("group_a", "knob_1", nullptr));
897ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
898ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents(
899ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "{\"settings\": {"
900ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "    \"group_a\": {"
901ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "        \"knob_2\": \"new stuff\""
902ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal      "}}}");
903f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->Open());
904f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->GetString("group_a", "knob_1", nullptr));
905f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetString("group_a", "knob_2", nullptr));
906ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
907ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
908ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawalTEST_F(JsonStoreTest, OpenClearsExistingInMemoryGroups) {
909f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "watch me disappear");
910f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_FALSE(store_->GetGroups().empty());
911ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
912ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  // In the delete case, we're non-comittal about whether empty groups
913ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  // are garbage collected. But, in the Open() case, we commit to
914ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  // fully clearing in-memory data.
915ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal  SetJsonFileContents("{\"settings\": {}}");
916f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->Open());
917f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->GetGroups().empty());
918ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal}
919ce1fb4700705476f5202b32427d4d2de200410a8mukesh agrawal
920773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal// File operations: Close() basic functionality.
921773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawalTEST_F(JsonStoreTest, ClosePersistsData) {
922f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_FALSE(store_->IsNonEmpty());
923f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->Close());
924773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal
925773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal  // Verify that the file actually got written with the right name.
926773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal  FileEnumerator file_enumerator(temp_dir_.path(),
927773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal                                 false /* not recursive */,
928773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal                                 FileEnumerator::FILES);
929773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal  EXPECT_EQ(test_file_.value(), file_enumerator.Next().value());
930773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal
931773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal  // Verify that the profile is a regular file, readable and writeable by the
932773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal  // owner only.
933773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal  FileEnumerator::FileInfo file_info = file_enumerator.GetInfo();
934773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal  EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, file_info.stat().st_mode);
935773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal}
936773cf17b04028b19dd7fefcf2c2a291756cc83a7mukesh agrawal
937f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal// File operations: Flush() basics.
938f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawalTEST_F(JsonStoreTest, FlushCreatesPersistentStore) {
939f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_FALSE(store_->IsNonEmpty());
940f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->Flush());
941f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal
942f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  // Verify that the file actually got written with the right name.
943f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  FileEnumerator file_enumerator(temp_dir_.path(),
944f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal                                 false /* not recursive */,
945f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal                                 FileEnumerator::FILES);
946f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  EXPECT_EQ(test_file_.value(), file_enumerator.Next().value());
947f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal
948f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  // Verify that the profile is a regular file, readable and writeable by the
949f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  // owner only.
950f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  FileEnumerator::FileInfo file_info = file_enumerator.GetInfo();
951f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, file_info.stat().st_mode);
952f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal}
953f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal
95489bd073a5e0878e844baf8c08d7ed46782c4b16emukesh agrawalTEST_F(JsonStoreTest, FlushFailsWhenPathIsNotWriteable) {
95589bd073a5e0878e844baf8c08d7ed46782c4b16emukesh agrawal  ASSERT_TRUE(base::CreateDirectory(test_file_));
956f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal  EXPECT_CALL(log_,
957f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal              Log(logging::LOG_ERROR, _, StartsWith("Failed to write")));
958f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->Flush());
959f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal}
960f13a30f7587d12de5807058b76d09b427dbc9e24mukesh agrawal
9618cf96b7dc21200c377f8082342276689004ef719mukesh agrawal// File operations: writing.
9628cf96b7dc21200c377f8082342276689004ef719mukesh agrawal//
9638cf96b7dc21200c377f8082342276689004ef719mukesh agrawal// The ordering of groups, and the ordering of keys within a group,
9648cf96b7dc21200c377f8082342276689004ef719mukesh agrawal// are decided by the JSON writer. Hence, we can not simply compare
9658cf96b7dc21200c377f8082342276689004ef719mukesh agrawal// the written data to an expected literal value.
9668cf96b7dc21200c377f8082342276689004ef719mukesh agrawal//
9678cf96b7dc21200c377f8082342276689004ef719mukesh agrawal// Instead, we write the data out, and verify that reading the data
9688cf96b7dc21200c377f8082342276689004ef719mukesh agrawal// yields the same groups, keys, and values.
9698cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreHeader) {
970f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetHeader("rosetta stone");
971f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_EQ("rosetta stone", store_->file_description_);
972f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
9738cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
97478e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
9758cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
9768cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
977f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->file_description_, persisted_data.file_description_);
9788cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
9798cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
9808cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreAllTypes) {
981f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "string_knob", "our string");
982f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetBool("group_a", "bool_knob", true);
983f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetInt("group_a", "int_knob", 1);
984f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetUint64(
9858cf96b7dc21200c377f8082342276689004ef719mukesh agrawal      "group_a", "uint64_knob", std::numeric_limits<uint64_t>::max());
986f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetStringList(
9878cf96b7dc21200c377f8082342276689004ef719mukesh agrawal      "group_a", "stringlist_knob", vector<string>{"a", "b", "c"});
988f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetCryptedString("group_a", "cryptedstring_knob", "s3kr!t");
989f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
9908cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
99178e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
9928cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
9938cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
994f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->group_name_to_settings_, persisted_data.group_name_to_settings_);
9958cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
9968cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
9978cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreNonUtf8Strings) {
998f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "string_knob", kNonUtf8String);
999f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10008cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
100178e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
10028cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
10038cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
1004f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->group_name_to_settings_, persisted_data.group_name_to_settings_);
10058cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10068cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
10078cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreNonUtf8StringList) {
1008f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetStringList(
10098cf96b7dc21200c377f8082342276689004ef719mukesh agrawal      "group_a", "string_knob", vector<string>({kNonUtf8String}));
1010f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10118cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
101278e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
10138cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
10148cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
1015f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->group_name_to_settings_, persisted_data.group_name_to_settings_);
10168cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10178cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
10188cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreStringsWithEmbeddedNulls) {
1019f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "string_knob", kStringWithEmbeddedNulls);
1020f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10218cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
102278e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
10238cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
10248cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
1025f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->group_name_to_settings_, persisted_data.group_name_to_settings_);
10268cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10278cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
10288cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreStringListWithEmbeddedNulls) {
1029f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetStringList(
10308cf96b7dc21200c377f8082342276689004ef719mukesh agrawal      "group_a", "string_knob", vector<string>({kStringWithEmbeddedNulls}));
1031f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10328cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
103378e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
10348cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
10358cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
1036f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->group_name_to_settings_, persisted_data.group_name_to_settings_);
10378cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10388cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
10398cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreMultipleGroups) {
1040f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "first string");
1041f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_b", "knob_2", "second string");
1042f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10438cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
104478e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
10458cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
10468cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
1047f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->group_name_to_settings_, persisted_data.group_name_to_settings_);
10488cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10498cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
10508cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanPersistAndRestoreMultipleGroupsWithSameKeys) {
1051f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "first string");
1052f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_2", "second string");
1053f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_b", "knob_1", "frist post!");
1054f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetStringList("group_b", "knob_2", vector<string>{"2nd try"});
1055f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10568cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
105778e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data(test_file_);
10588cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data.Open();
10598cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_EQ(
1060f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal      store_->group_name_to_settings_, persisted_data.group_name_to_settings_);
10618cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10628cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
10638cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanDeleteKeyFromPersistedData) {
1064f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "first string");
1065f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10668cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
106778e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data_v1(test_file_);
10688cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data_v1.Open();
10698cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  ASSERT_TRUE(persisted_data_v1.GetString("group_a", "knob_1", nullptr));
1070f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->DeleteKey("group_a", "knob_1");
1071f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10728cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
107378e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data_v2(test_file_);
10748cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  SetVerboseLevel(10);
10758cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  // Whether an empty group is written or not is an implementation
10768cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  // detail.  Hence, we don't care if the error message is about a
10778cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  // missing group, or a missing property.
10788cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find")));
10798cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_FALSE(persisted_data_v2.GetString("group_a", "knob_1", nullptr));
10808cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10818cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
10828cf96b7dc21200c377f8082342276689004ef719mukesh agrawalTEST_F(JsonStoreTest, CanDeleteGroupFromPersistedData) {
1083f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->SetString("group_a", "knob_1", "first string");
1084f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10858cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
108678e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data_v1(test_file_);
10878cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data_v1.Open();
10888cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  ASSERT_TRUE(persisted_data_v1.GetString("group_a", "knob_1", nullptr));
1089f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->DeleteGroup("group_a");
1090f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
10918cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
109278e0584ef181fc8a6cfd4d3b54644af21829d2efmukesh agrawal  JsonStore persisted_data_v2(test_file_);
10938cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  SetVerboseLevel(10);
10948cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  persisted_data_v2.Open();
10958cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_CALL(log_, Log(_, _, HasSubstr("Could not find group")));
10968cf96b7dc21200c377f8082342276689004ef719mukesh agrawal  EXPECT_FALSE(persisted_data_v2.GetString("group_a", "knob_1", nullptr));
10978cf96b7dc21200c377f8082342276689004ef719mukesh agrawal}
10988cf96b7dc21200c377f8082342276689004ef719mukesh agrawal
1099abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawal// File operations: file management.
1100abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawalTEST_F(JsonStoreTest, MarkAsCorruptedFailsWhenStoreHasNotBeenPersisted) {
1101abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawal  EXPECT_CALL(log_,
1102abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawal              Log(logging::LOG_ERROR, _, HasSubstr("rename failed")));
1103f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->MarkAsCorrupted());
1104abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawal}
1105abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawal
1106abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawalTEST_F(JsonStoreTest, MarkAsCorruptedMovesCorruptStore) {
1107f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  store_->Flush();
1108f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  ASSERT_TRUE(store_->IsNonEmpty());
1109cbaa24d68afc8e5339059c26101f313f8487dd99mukesh agrawal  ASSERT_TRUE(base::PathExists(test_file_));
1110f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal
1111f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_TRUE(store_->MarkAsCorrupted());
1112f7e118e52bec7f785f6c7fe6f60092d688a34553mukesh agrawal  EXPECT_FALSE(store_->IsNonEmpty());
1113cbaa24d68afc8e5339059c26101f313f8487dd99mukesh agrawal  EXPECT_FALSE(base::PathExists(test_file_));
1114cbaa24d68afc8e5339059c26101f313f8487dd99mukesh agrawal  EXPECT_TRUE(base::PathExists(FilePath(test_file_.value() + ".corrupted")));
1115abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawal}
1116abd2c09753e4ec353ee8ff0d72c44baadc7316fcmukesh agrawal
11179724f9eac1e16bc1c92caa2b2748597730ab266fmukesh agrawal}  // namespace shill
1118