Added version field to state and migrate from unversioned data
State in older format must be migrated to new one.
BUG:24869252
Change-Id: Iacadd1efb9e45e840b029652f8582d815ae0380e
Reviewed-on: https://weave-review.googlesource.com/1305
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/libweave/src/config.cc b/libweave/src/config.cc
index 4f59497..b1b3e30 100644
--- a/libweave/src/config.cc
+++ b/libweave/src/config.cc
@@ -22,6 +22,8 @@
namespace config_keys {
+const char kVersion[] = "version";
+
const char kClientId[] = "client_id";
const char kClientSecret[] = "client_secret";
const char kApiKey[] = "api_key";
@@ -44,6 +46,17 @@
namespace {
+const int kCurrentConfigVersion = 1;
+
+void MigrateFromV0(base::DictionaryValue* dict) {
+ std::string cloud_id;
+ if (dict->GetString(config_keys::kCloudId, &cloud_id) && !cloud_id.empty())
+ return;
+ scoped_ptr<base::Value> tmp;
+ if (dict->Remove(config_keys::kDeviceId, &tmp))
+ dict->Set(config_keys::kCloudId, std::move(tmp));
+}
+
Config::Settings CreateDefaultSettings() {
Config::Settings result;
result.oauth_url = "https://accounts.google.com/o/oauth2/";
@@ -115,12 +128,25 @@
return;
auto value = base::JSONReader::Read(json_string);
- const base::DictionaryValue* dict = nullptr;
+ base::DictionaryValue* dict = nullptr;
if (!value || !value->GetAsDictionary(&dict)) {
LOG(ERROR) << "Failed to parse settings.";
return;
}
+ int loaded_version = 0;
+ dict->GetInteger(config_keys::kVersion, &loaded_version);
+
+ if (loaded_version != kCurrentConfigVersion) {
+ LOG(INFO) << "State version mismatch. expected: " << kCurrentConfigVersion
+ << ", loaded: " << loaded_version;
+ save_ = true;
+ }
+
+ if (loaded_version == 0) {
+ MigrateFromV0(dict);
+ }
+
std::string tmp;
bool tmp_bool{false};
@@ -184,6 +210,8 @@
return;
base::DictionaryValue dict;
+ dict.SetInteger(config_keys::kVersion, kCurrentConfigVersion);
+
dict.SetString(config_keys::kClientId, settings_.client_id);
dict.SetString(config_keys::kClientSecret, settings_.client_secret);
dict.SetString(config_keys::kApiKey, settings_.api_key);
diff --git a/libweave/src/config_unittest.cc b/libweave/src/config_unittest.cc
index f65f203..3078b1d 100644
--- a/libweave/src/config_unittest.cc
+++ b/libweave/src/config_unittest.cc
@@ -79,8 +79,35 @@
EXPECT_EQ("", GetSettings().secret);
}
+TEST_F(ConfigTest, LoadStateV0) {
+ EXPECT_CALL(config_store_, LoadSettings())
+ .WillOnce(Return(R"({
+ "device_id": "state_device_id"
+ })"));
+
+ EXPECT_CALL(*this, OnConfigChanged(_)).Times(1);
+ config_.Load();
+
+ EXPECT_EQ("state_device_id", GetSettings().cloud_id);
+ EXPECT_FALSE(GetSettings().device_id.empty());
+ EXPECT_NE(GetSettings().cloud_id, GetSettings().device_id);
+
+ EXPECT_CALL(config_store_, LoadSettings())
+ .WillOnce(Return(R"({
+ "device_id": "state_device_id",
+ "cloud_id": "state_cloud_id"
+ })"));
+
+ EXPECT_CALL(*this, OnConfigChanged(_)).Times(1);
+ config_.Load();
+
+ EXPECT_EQ("state_cloud_id", GetSettings().cloud_id);
+ EXPECT_EQ("state_device_id", GetSettings().device_id);
+}
+
TEST_F(ConfigTest, LoadState) {
auto state = R"({
+ "version": 1,
"api_key": "state_api_key",
"client_id": "state_client_id",
"client_secret": "state_client_secret",
@@ -205,6 +232,7 @@
EXPECT_CALL(config_store_, SaveSettings(_))
.WillOnce(Invoke([](const std::string& json) {
auto expected = R"({
+ 'version': 1,
'api_key': 'set_api_key',
'client_id': 'set_client_id',
'client_secret': 'set_client_secret',
diff --git a/libweave/src/weave_unittest.cc b/libweave/src/weave_unittest.cc
index 74e8c41..c61bc69 100644
--- a/libweave/src/weave_unittest.cc
+++ b/libweave/src/weave_unittest.cc
@@ -195,6 +195,7 @@
}
EXPECT_CALL(dns_sd_, PublishService("_privet._tcp", 11, MatchTxt(txt)))
+ .Times(AtMost(1))
.WillOnce(Return());
}