blob: 470d16fe644ab3a60aa4383485126bb441af80a3 [file] [log] [blame]
/* Copyright 2018 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef RUNTIME_PROBE_PROBE_RESULT_CHECKER_H_
#define RUNTIME_PROBE_PROBE_RESULT_CHECKER_H_
#include <map>
#include <memory>
#include <string>
#include <base/values.h>
#include <gtest/gtest.h>
namespace runtime_probe {
class FieldConverter {
public:
enum class ReturnCode {
OK = 0,
FIELD_NOT_FOUND = 1,
/* Failed to convert the field */
INCOMPATIBLE_VALUE = 2,
};
/* Try to find |field_name| in dict_value, and convert it to expected type.
*
* @return |ReturnCode| to indicate success or reason of failure.
*/
virtual ReturnCode Convert(const std::string& field_name,
base::DictionaryValue* const dict_value) const = 0;
virtual std::string ToString() const = 0;
virtual ~FieldConverter() = default;
};
/* Convert a field to string. */
class StringFieldConverter : public FieldConverter {
public:
ReturnCode Convert(const std::string& field_name,
base::DictionaryValue* const dict_value) const override;
std::string ToString() const override { return "StringFieldConverter()"; }
};
/* Convert a field to integer.
*
* However, heximal value is not allowed, please use |HexFieldConverter|
* instead.
*/
class IntegerFieldConverter : public FieldConverter {
public:
ReturnCode Convert(const std::string& field_name,
base::DictionaryValue* const dict_value) const override;
std::string ToString() const override { return "IntegerFieldConverter()"; }
};
/* Convert a hex string field to integer.
*
* If the original field is string, this class assumes it is base 16.
* Otherwise, if the field is already a number (int or double), the behavior wil
* be identical to |IntegerFieldConverter|.
*/
class HexFieldConverter : public FieldConverter {
public:
ReturnCode Convert(const std::string& field_name,
base::DictionaryValue* const dict_value) const override;
std::string ToString() const override { return "HexFieldConverter()"; }
};
/* Convert a field to double. */
class DoubleFieldConverter : public FieldConverter {
public:
ReturnCode Convert(const std::string& field_name,
base::DictionaryValue* const dict_value) const override;
std::string ToString() const override { return "DoubleFieldConverter()"; }
};
/* Holds |expect| attribute of a |ProbeStatement|.
*
* |expect| attribute should be a |DictionaryValue| with following format:
* {
* <key_of_probe_result>: [<required:bool>, <expected_type:string>,
* <optional_validate_rule:string>]
* }
*
* Currently, we support the following expected types:
* - "int" (use |IntegerFieldConverter|)
* - "hex" (use |HexFieldConverter|)
* - "double" (use |DoubleFieldConverter|)
* - "str" (use |StringFieldConverter|)
*
* |ProbeResultChecker| will first try to convert each field to |expected_type|.
* Then, if |optional_validate_rule| is given, will check if converted value
* match the rule.
*
* TODO(b/121354690): Handle |optional_validate_rule|.
*/
class ProbeResultChecker {
public:
static std::unique_ptr<ProbeResultChecker> FromDictionaryValue(
const base::DictionaryValue& dict_value);
/* Apply |expect| rules to |probe_result|
*
* @return |true| if all required fields are converted successfully.
*/
bool Apply(base::DictionaryValue* probe_result) const;
private:
std::map<std::string, std::unique_ptr<FieldConverter>> required_fields_;
std::map<std::string, std::unique_ptr<FieldConverter>> optional_fields_;
FRIEND_TEST(ProbeResultCheckerTest, TestFromDictionaryValue);
};
} // namespace runtime_probe
#endif // RUNTIME_PROBE_PROBE_RESULT_CHECKER_H_