buffet: PropType::CreateValue() should do constraint validation
Make PropType::CreateValue(v,...) validate the value against type
contraints which eliminates additional ValidateConstraints() call
and ensure the produced values conforms to the type schema specified.
Also parameter-less PropType::CreateValue() should use the default
value specified in PropType when constructing the value.
BUG=brillo:107
TEST=`FEATURES=test emerge-link buffet`
Change-Id: I3712b8e0a14515c153c987078863b2904c89cafd
Reviewed-on: https://chromium-review.googlesource.com/262205
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Trybot-Ready: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/commands/prop_types.cc b/buffet/commands/prop_types.cc
index a31f135..74e2be6 100644
--- a/buffet/commands/prop_types.cc
+++ b/buffet/commands/prop_types.cc
@@ -211,8 +211,7 @@
bool PropType::ValidateValue(const chromeos::Any& value,
chromeos::ErrorPtr* error) const {
- std::unique_ptr<PropValue> val = CreateValue(value, error);
- return val && ValidateConstraints(*val, error);
+ return !!CreateValue(value, error);
}
bool PropType::ValidateConstraints(const PropValue& value,
diff --git a/buffet/commands/prop_types.h b/buffet/commands/prop_types.h
index 10ca853..473a6c8 100644
--- a/buffet/commands/prop_types.h
+++ b/buffet/commands/prop_types.h
@@ -186,6 +186,8 @@
public:
ValueType GetType() const override { return GetValueType<T>(); }
std::unique_ptr<PropValue> CreateValue() const override {
+ if (GetDefaultValue())
+ return GetDefaultValue()->Clone();
return std::unique_ptr<PropValue>{new Value{Clone()}};
}
std::unique_ptr<PropValue> CreateValue(
@@ -194,7 +196,8 @@
if (v.IsTypeCompatible<T>()) {
std::unique_ptr<Value> value{new Value{Clone()}};
value->SetValue(v.Get<T>());
- prop_value = std::move(value);
+ if (ValidateConstraints(*value, error))
+ prop_value = std::move(value);
} else {
GenerateErrorValueTypeMismatch(error);
}
diff --git a/buffet/commands/schema_utils.cc b/buffet/commands/schema_utils.cc
index 10e9797..06e5ded 100644
--- a/buffet/commands/schema_utils.cc
+++ b/buffet/commands/schema_utils.cc
@@ -138,6 +138,7 @@
const ObjectSchema* object_schema = type->GetObject()->GetObjectSchemaPtr();
std::set<std::string> keys_processed;
+ value_out->clear(); // Clear possible default values already in |value_out|.
for (const auto& pair : object_schema->GetProps()) {
const PropValue* def_value = pair.second->GetDefaultValue();
if (dict->HasKey(pair.first)) {
@@ -154,9 +155,9 @@
pair.first.c_str());
return false;
}
- value_out->insert(std::make_pair(pair.first, std::move(value)));
+ value_out->emplace_hint(value_out->end(), pair.first, std::move(value));
} else if (def_value) {
- value_out->insert(std::make_pair(pair.first, def_value->Clone()));
+ value_out->emplace_hint(value_out->end(), pair.first, def_value->Clone());
} else {
return ErrorMissingProperty(error, pair.first.c_str());
}
@@ -207,6 +208,9 @@
const PropType* item_type = type->GetArray()->GetItemTypePtr();
CHECK(item_type) << "Incomplete array type definition";
+ // This value might already contain values from the type defaults.
+ // Clear them first before proceeding.
+ value_out->clear();
value_out->reserve(list->GetSize());
for (const base::Value* item : *list) {
std::unique_ptr<PropValue> prop_value = item_type->CreateValue();
@@ -309,8 +313,6 @@
result = type->CreateValue(value, error);
}
- if (result && !type->ValidateConstraints(*result, error))
- result.reset();
return result;
}
@@ -319,6 +321,7 @@
native_types::Object* obj,
chromeos::ErrorPtr* error) {
std::set<std::string> keys_processed;
+ obj->clear();
// First go over all object parameters defined by type's object schema and
// extract the corresponding parameters from the source dictionary.
for (const auto& pair : object_schema->GetProps()) {
diff --git a/buffet/states/state_package.cc b/buffet/states/state_package.cc
index a023c14..1292339 100644
--- a/buffet/states/state_package.cc
+++ b/buffet/states/state_package.cc
@@ -39,11 +39,7 @@
for (const auto& pair : schema.GetProps()) {
types_.AddProp(pair.first, pair.second->Clone());
// Create default value for this state property.
- if (pair.second->GetDefaultValue()) {
- values_.emplace(pair.first, pair.second->GetDefaultValue()->Clone());
- } else {
- values_.emplace(pair.first, pair.second->CreateValue());
- }
+ values_.emplace(pair.first, pair.second->CreateValue());
}
return true;