diff options
author | Alex Deymo <deymo@chromium.org> | 2015-06-26 19:34:26 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-07-01 19:48:17 +0000 |
commit | 665bc53fdf6b4b4ffd3d24f60e6a573ca52828a1 (patch) | |
tree | c880d351e330778482553784eaaaec8b8b20e2a4 /chromeos | |
parent | 30ef934cd07bebb0f57f1449feb62facb3b647cc (diff) | |
download | libbrillo-665bc53fdf6b4b4ffd3d24f60e6a573ca52828a1.tar.gz |
libchromeos: Add {LoadFrom,SaveTo}String to KeyValueStore.
This patch extends the chromeos::KeyValueStore to support loading and
saving from strings directly.
BUG=None
TEST=Updated unittests.
Change-Id: I2b33cc9d427bba7b51733db3068cba08071c7b2b
Reviewed-on: https://chromium-review.googlesource.com/282380
Tested-by: Alex Deymo <deymo@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
Diffstat (limited to 'chromeos')
-rw-r--r-- | chromeos/key_value_store.cc | 12 | ||||
-rw-r--r-- | chromeos/key_value_store.h | 18 | ||||
-rw-r--r-- | chromeos/key_value_store_unittest.cc | 90 |
3 files changed, 57 insertions, 63 deletions
diff --git a/chromeos/key_value_store.cc b/chromeos/key_value_store.cc index 4e1872d..8d91dac 100644 --- a/chromeos/key_value_store.cc +++ b/chromeos/key_value_store.cc @@ -41,10 +41,13 @@ bool KeyValueStore::Load(const base::FilePath& path) { string file_data; if (!base::ReadFileToString(path, &file_data)) return false; + return LoadFromString(file_data); +} +bool KeyValueStore::LoadFromString(const std::string& data) { // Split along '\n', then along '='. vector<string> lines; - base::SplitStringDontTrim(file_data, '\n', &lines); + base::SplitStringDontTrim(data, '\n', &lines); for (auto it = lines.begin(); it != lines.end(); ++it) { std::string line; base::TrimWhitespace(*it, base::TRIM_LEADING, &line); @@ -76,11 +79,14 @@ bool KeyValueStore::Load(const base::FilePath& path) { } bool KeyValueStore::Save(const base::FilePath& path) const { + return base::ImportantFileWriter::WriteFileAtomically(path, SaveToString()); +} + +string KeyValueStore::SaveToString() const { string data; for (const auto& key_value : store_) data += key_value.first + "=" + key_value.second + "\n"; - - return base::ImportantFileWriter::WriteFileAtomically(path, data); + return data; } bool KeyValueStore::GetString(const string& key, string* value) const { diff --git a/chromeos/key_value_store.h b/chromeos/key_value_store.h index a7bb84f..10f273c 100644 --- a/chromeos/key_value_store.h +++ b/chromeos/key_value_store.h @@ -32,12 +32,22 @@ class CHROMEOS_EXPORT KeyValueStore { // whether reading the file succeeded. bool Load(const base::FilePath& path); - // Saves the current store to the given |path| file. Returns whether the file - // creation succeeded. Calling Load() and then Save() may result in different - // data being written if the original file contained backslash-terminated - // lines (i.e. these values will be rewritten on single lines). + // Loads the key=value pairs parsing the text passed in |data|. See Load() for + // details. + // Returns whether the parsing succeeded. + bool LoadFromString(const std::string& data); + + // Saves the current store to the given |path| file. See SaveToString() for + // details on the formate of the created file. + // Returns whether the file creation succeeded. bool Save(const base::FilePath& path) const; + // Returns a string with the contents of the store as key=value lines. + // Calling LoadFromString() and then SaveToString() may result in different + // result if the original string contained backslash-terminated lines (i.e. + // these values will be rewritten on single lines), comments or empty lines. + std::string SaveToString() const; + // Getter for the given key. Returns whether the key was found on the store. bool GetString(const std::string& key, std::string* value) const; diff --git a/chromeos/key_value_store_unittest.cc b/chromeos/key_value_store_unittest.cc index c1a99d9..649832b 100644 --- a/chromeos/key_value_store_unittest.cc +++ b/chromeos/key_value_store_unittest.cc @@ -24,12 +24,6 @@ using std::vector; namespace chromeos { class KeyValueStoreTest : public ::testing::Test { - public: - void SetUp() override { - CHECK(temp_dir_.CreateUniqueTempDir()); - temp_file_ = temp_dir_.path().Append("temp.conf"); - } - protected: // Returns the value from |store_| corresponding to |key|, or an empty string // if the key is not present. Crashes if the store returns an empty value. @@ -40,36 +34,43 @@ class KeyValueStoreTest : public ::testing::Test { return value; } - base::FilePath temp_file_; - base::ScopedTempDir temp_dir_; KeyValueStore store_; // KeyValueStore under test. }; -TEST_F(KeyValueStoreTest, CommentsAreIgnored) { - string blob = "# comment\nA=B\n\n\n#another=comment\n # leading spaces\n"; +TEST_F(KeyValueStoreTest, LoadAndSaveFromFile) { + base::ScopedTempDir temp_dir_; + CHECK(temp_dir_.CreateUniqueTempDir()); + base::FilePath temp_file_ = temp_dir_.path().Append("temp.conf"); + base::FilePath saved_temp_file_ = temp_dir_.path().Append("saved_temp.conf"); + + string blob = "A=B\n# Comment\n"; ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); ASSERT_TRUE(store_.Load(temp_file_)); - ASSERT_TRUE(store_.Save(temp_file_)); + string value; + EXPECT_TRUE(store_.GetString("A", &value)); + EXPECT_EQ("B", value); + + ASSERT_TRUE(store_.Save(saved_temp_file_)); string read_blob; - ASSERT_TRUE(ReadFileToString(FilePath(temp_file_), &read_blob)); + ASSERT_TRUE(ReadFileToString(FilePath(saved_temp_file_), &read_blob)); EXPECT_EQ("A=B\n", read_blob); } -TEST_F(KeyValueStoreTest, EmptyTest) { - ASSERT_EQ(0, base::WriteFile(temp_file_, "", 0)); - ASSERT_TRUE(store_.Load(temp_file_)); +TEST_F(KeyValueStoreTest, CommentsAreIgnored) { + EXPECT_TRUE(store_.LoadFromString( + "# comment\nA=B\n\n\n#another=comment\n # leading spaces\n")); + EXPECT_EQ("A=B\n", store_.SaveToString()); +} - ASSERT_TRUE(store_.Save(temp_file_)); - string read_blob; - ASSERT_TRUE(ReadFileToString(FilePath(temp_file_), &read_blob)); - EXPECT_EQ("", read_blob); +TEST_F(KeyValueStoreTest, EmptyTest) { + EXPECT_TRUE(store_.LoadFromString("")); + EXPECT_EQ("", store_.SaveToString()); } TEST_F(KeyValueStoreTest, LoadAndReloadTest) { - string blob = "A=B\nC=\nFOO=BAR=BAZ\nBAR=BAX\nMISSING=NEWLINE"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - ASSERT_TRUE(store_.Load(temp_file_)); + EXPECT_TRUE(store_.LoadFromString( + "A=B\nC=\nFOO=BAR=BAZ\nBAR=BAX\nMISSING=NEWLINE")); map<string, string> expected = {{"A", "B"}, {"C", ""}, @@ -85,9 +86,8 @@ TEST_F(KeyValueStoreTest, LoadAndReloadTest) { } // Save, load and test again. - ASSERT_TRUE(store_.Save(temp_file_)); KeyValueStore new_store; - ASSERT_TRUE(new_store.Load(temp_file_)); + ASSERT_TRUE(new_store.LoadFromString(store_.SaveToString())); for (const auto& it : expected) { EXPECT_TRUE(new_store.GetString(it.first, &value)) << "key: " << it.first; @@ -110,8 +110,7 @@ TEST_F(KeyValueStoreTest, SimpleBooleanTest) { TEST_F(KeyValueStoreTest, BooleanParsingTest) { string blob = "TRUE=true\nfalse=false\nvar=false\nDONT_SHOUT=TRUE\n"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - ASSERT_TRUE(store_.Load(temp_file_)); + EXPECT_TRUE(store_.LoadFromString(blob)); map<string, bool> expected = { {"TRUE", true}, {"false", false}, {"var", false}}; @@ -128,9 +127,7 @@ TEST_F(KeyValueStoreTest, BooleanParsingTest) { } TEST_F(KeyValueStoreTest, TrimWhitespaceAroundKey) { - string blob = " a=1\nb =2\n c =3\n"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - ASSERT_TRUE(store_.Load(temp_file_)); + EXPECT_TRUE(store_.LoadFromString(" a=1\nb =2\n c =3\n")); EXPECT_EQ("1", GetNonemptyStringValue("a")); EXPECT_EQ("2", GetNonemptyStringValue("b")); @@ -147,22 +144,15 @@ TEST_F(KeyValueStoreTest, TrimWhitespaceAroundKey) { } TEST_F(KeyValueStoreTest, IgnoreWhitespaceLine) { - string blob = "a=1\n \t \nb=2"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - ASSERT_TRUE(store_.Load(temp_file_)); + EXPECT_TRUE(store_.LoadFromString("a=1\n \t \nb=2")); EXPECT_EQ("1", GetNonemptyStringValue("a")); EXPECT_EQ("2", GetNonemptyStringValue("b")); } TEST_F(KeyValueStoreTest, RejectEmptyKeys) { - string blob = "=1"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - EXPECT_FALSE(store_.Load(temp_file_)); - - blob = " =2"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - EXPECT_FALSE(store_.Load(temp_file_)); + EXPECT_FALSE(store_.LoadFromString("=1")); + EXPECT_FALSE(store_.LoadFromString(" =2")); // Trying to set an empty (after trimming) key should fail an assert. EXPECT_DEATH(store_.SetString(" ", "3"), ""); @@ -170,15 +160,11 @@ TEST_F(KeyValueStoreTest, RejectEmptyKeys) { } TEST_F(KeyValueStoreTest, RejectBogusLines) { - string blob = "a=1\nbogus\nb=2"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - EXPECT_FALSE(store_.Load(temp_file_)); + EXPECT_FALSE(store_.LoadFromString("a=1\nbogus\nb=2")); } TEST_F(KeyValueStoreTest, MultilineValue) { - string blob = "a=foo\nb=bar\\\n baz \\ \nc=3\n"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - ASSERT_TRUE(store_.Load(temp_file_)); + EXPECT_TRUE(store_.LoadFromString("a=foo\nb=bar\\\n baz \\ \nc=3\n")); EXPECT_EQ("foo", GetNonemptyStringValue("a")); EXPECT_EQ("bar baz \\ ", GetNonemptyStringValue("b")); @@ -186,17 +172,9 @@ TEST_F(KeyValueStoreTest, MultilineValue) { } TEST_F(KeyValueStoreTest, UnterminatedMultilineValue) { - string blob = "a=foo\\"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - EXPECT_FALSE(store_.Load(temp_file_)); - - blob = "a=foo\\\n"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - EXPECT_FALSE(store_.Load(temp_file_)); - - blob = "a=foo\\\n\n# blah\n"; - ASSERT_EQ(blob.size(), base::WriteFile(temp_file_, blob.data(), blob.size())); - EXPECT_FALSE(store_.Load(temp_file_)); + EXPECT_FALSE(store_.LoadFromString("a=foo\\")); + EXPECT_FALSE(store_.LoadFromString("a=foo\\\n")); + EXPECT_FALSE(store_.LoadFromString("a=foo\\\n\n# blah\n")); } TEST_F(KeyValueStoreTest, GetKeys) { |