| // Copyright 2019 The Fuchsia 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 SRC_TESTING_LOADBENCH_WORKLOAD_H_ | |
| #define SRC_TESTING_LOADBENCH_WORKLOAD_H_ | |
| #include <lib/syslog/cpp/macros.h> | |
| #include <lib/zx/time.h> | |
| #include <optional> | |
| #include <unordered_map> | |
| #include <variant> | |
| #include <vector> | |
| #include "action.h" | |
| #include "object.h" | |
| #include "rapidjson/document.h" | |
| struct WorkerConfig { | |
| WorkerConfig() = default; | |
| WorkerConfig(WorkerConfig&&) = default; | |
| WorkerConfig& operator=(WorkerConfig&&) = default; | |
| WorkerConfig(const WorkerConfig& other) { *this = other; } | |
| WorkerConfig& operator=(const WorkerConfig& other) { | |
| if (this != &other) { | |
| name = other.name; | |
| group = other.group; | |
| priority = other.priority; | |
| for (auto& action : other.actions) { | |
| actions.emplace_back(action->Copy()); | |
| } | |
| } | |
| return *this; | |
| } | |
| struct DeadlineParams { | |
| zx::duration capacity; | |
| zx::duration deadline; | |
| zx::duration period; | |
| }; | |
| using PriorityType = std::variant<std::monostate, int, DeadlineParams>; | |
| std::string name; | |
| std::string group; | |
| PriorityType priority; | |
| std::vector<std::unique_ptr<Action>> actions; | |
| }; | |
| struct TracingConfig { | |
| uint32_t group_mask; | |
| std::optional<std::string> filepath; | |
| std::optional<std::string> trace_string_ref; | |
| }; | |
| // Represents the configuration and state parsed from a workload JSON | |
| // definition file. | |
| class Workload { | |
| public: | |
| static Workload Load(const std::string& path); | |
| Workload() = default; | |
| Workload(const Workload&) = delete; | |
| Workload& operator=(const Workload&) = delete; | |
| Workload(Workload&&) = default; | |
| Workload& operator=(Workload&&) = default; | |
| const auto& name() const { return name_; } | |
| const auto& priority() const { return priority_; } | |
| const auto& interval() const { return interval_; } | |
| const auto& tracing() const { return tracing_; } | |
| auto& workers() { return workers_; } | |
| private: | |
| struct Duration { | |
| std::chrono::nanoseconds value; | |
| }; | |
| struct Uniform { | |
| std::chrono::nanoseconds min; | |
| std::chrono::nanoseconds max; | |
| }; | |
| enum AcceptNamedIntervalFlag { | |
| RejectNamedInterval = false, | |
| AcceptNamedInterval = true, | |
| }; | |
| void Add(const std::string& name, std::unique_ptr<Object> object) { | |
| auto [iter, okay] = objects_.emplace(name, std::move(object)); | |
| FX_CHECK(okay) << "Object with name \"" << name << "\" defined more than once!"; | |
| } | |
| Object& Get(const std::string& name) { | |
| const auto search = objects_.find(name); | |
| FX_CHECK(search != objects_.end()) << "name=" << name; | |
| auto& [key, value] = *search; | |
| return *value; | |
| } | |
| template <typename T> | |
| T& Get(const std::string& name) { | |
| const auto search = objects_.find(name); | |
| FX_CHECK(search != objects_.end()) << "name=" << name; | |
| auto& [key, value] = *search; | |
| FX_CHECK(value->type() == T::Type) << "actual=" << value->type() << " expected=" << T::Type; | |
| return static_cast<T&>(*value); | |
| } | |
| void ParseObject(const std::string& name, const rapidjson::Value& object); | |
| Duration ParseDuration(const rapidjson::Value& object); | |
| Uniform ParseUniform(const rapidjson::Value& object); | |
| std::variant<Duration, Uniform> ParseInterval(const rapidjson::Value& object, | |
| AcceptNamedIntervalFlag accept_named_interval); | |
| void ParseNamedInterval(const std::string& name, const rapidjson::Value& object); | |
| zx::unowned_handle ParseTargetObjectAndGetHandle(const std::string& name, | |
| const rapidjson::Value& object, | |
| const std::string& context); | |
| std::unique_ptr<Action> ParseAction(const rapidjson::Value& action); | |
| void ParseNamedBehavior(const std::string& name, const rapidjson::Value& behavior); | |
| void ParseWorker(const rapidjson::Value& worker); | |
| void ParseTracing(const rapidjson::Value& tracing); | |
| std::string name_; | |
| std::optional<int> priority_; | |
| std::optional<std::chrono::nanoseconds> interval_; | |
| std::unordered_map<std::string, std::variant<Duration, Uniform>> intervals_; | |
| std::unordered_map<std::string, std::unique_ptr<Object>> objects_; | |
| std::unordered_map<std::string, std::unique_ptr<Action>> behaviors_; | |
| std::vector<WorkerConfig> workers_; | |
| std::optional<TracingConfig> tracing_; | |
| }; | |
| #endif // SRC_TESTING_LOADBENCH_WORKLOAD_H_ |