1 /* Copyright (c) 2017-2020. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
8 #include "simgrid/kernel/resource/Resource.hpp"
9 #include "src/kernel/resource/profile/DatedValue.hpp"
10 #include "src/kernel/resource/profile/Event.hpp"
11 #include "src/kernel/resource/profile/Profile.hpp"
12 #include "src/kernel/resource/profile/StochasticDatedValue.hpp"
13 #include "src/surf/surf_interface.hpp"
17 #include "xbt/random.hpp"
21 XBT_LOG_NEW_DEFAULT_CATEGORY(unit, "Unit tests of the Trace Manager");
23 class MockedResource : public simgrid::kernel::resource::Resource {
25 static double the_date;
27 explicit MockedResource() : simgrid::kernel::resource::Resource(nullptr, "fake", nullptr) {}
28 void apply_event(simgrid::kernel::profile::Event* event, double value) override
30 XBT_VERB("t=%.1f: Change value to %lg (idx: %u)", the_date, value, event->idx);
31 tmgr_trace_event_unref(&event);
33 bool is_used() const override { return true; }
36 double MockedResource::the_date;
38 static std::vector<simgrid::kernel::profile::DatedValue> trace2vector(const char* str)
40 std::vector<simgrid::kernel::profile::DatedValue> res;
41 simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
42 XBT_VERB("---------------------------------------------------------");
43 XBT_VERB("data>>\n%s<<data\n", str);
44 for (auto const& evt : trace->event_list)
45 XBT_VERB("event: d:%lg v:%lg", evt.date_, evt.value_);
47 MockedResource daResource;
48 simgrid::kernel::profile::FutureEvtSet fes;
49 simgrid::kernel::profile::Event* insertedIt = trace->schedule(&fes, &daResource);
51 while (fes.next_date() <= 20.0 && fes.next_date() >= 0) {
52 MockedResource::the_date = fes.next_date();
54 simgrid::kernel::resource::Resource* resource;
55 simgrid::kernel::profile::Event* it = fes.pop_leq(MockedResource::the_date, &value, &resource);
59 REQUIRE(it == insertedIt); // Check that we find what we've put
61 res.emplace_back(MockedResource::the_date, value);
63 XBT_DEBUG("%.1f: ignore an event (idx: %u)\n", MockedResource::the_date, it->idx);
65 resource->apply_event(it, value);
71 static std::vector<simgrid::kernel::profile::StochasticDatedValue> trace2selist(const char* str)
73 const simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
74 std::vector<simgrid::kernel::profile::StochasticDatedValue> stocevlist = trace->stochastic_event_list;
79 TEST_CASE("kernel::profile: Resource profiles, defining the external load", "kernel::profile")
81 SECTION("No event, no loop")
83 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("");
84 std::vector<simgrid::kernel::profile::DatedValue> want;
88 SECTION("One event no loop")
90 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("9.0 3.0\n");
92 std::vector<simgrid::kernel::profile::DatedValue> want;
93 want.emplace_back(9, 3);
97 SECTION("Two events, no loop")
99 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
102 std::vector<simgrid::kernel::profile::DatedValue> want;
103 want.emplace_back(3, 1);
104 want.emplace_back(9, 3);
106 REQUIRE(want == got);
109 SECTION("Three events, no loop")
111 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
115 std::vector<simgrid::kernel::profile::DatedValue> want;
116 want.emplace_back(3, 1);
117 want.emplace_back(5, 2);
118 want.emplace_back(9, 3);
120 REQUIRE(want == got);
123 SECTION("Two events, looping")
125 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("1.0 1.0\n"
129 std::vector<simgrid::kernel::profile::DatedValue> want;
130 want.emplace_back(1, 1);
131 want.emplace_back(3, 3);
132 want.emplace_back(6, 1);
133 want.emplace_back(8, 3);
134 want.emplace_back(11, 1);
135 want.emplace_back(13, 3);
136 want.emplace_back(16, 1);
137 want.emplace_back(18, 3);
139 REQUIRE(want == got);
142 SECTION("Two events, looping, start at 0")
144 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("0.0 1\n"
148 std::vector<simgrid::kernel::profile::DatedValue> want;
149 want.emplace_back(0, 1);
150 want.emplace_back(5, 2);
151 want.emplace_back(10, 1);
152 want.emplace_back(15, 2);
153 want.emplace_back(20, 1);
155 REQUIRE(want == got);
158 SECTION("One stochastic event (parsing)")
160 using simgrid::kernel::profile::Distribution;
161 std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
164 std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
165 want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(0, -1)); // The initial fake event
166 want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::DET, {0},
167 Distribution::UNIF, {10, 20}));
169 REQUIRE(want == got);
172 SECTION("Several stochastic events (all possible parsing forms)")
174 using simgrid::kernel::profile::Distribution;
175 std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
177 "NORMAL 25 10 DET 3\n"
178 "UNIF 10 20 NORMAL 25 10\n"
181 std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
182 want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(0, -1));
183 want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::DET, {0},
184 Distribution::DET, {4}));
185 want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::NORM, {25, 10},
186 Distribution::DET, {3}));
187 want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::UNIF, {10, 20},
188 Distribution::NORM, {25, 10}));
189 want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::DET, {5},
190 Distribution::UNIF, {5, 25}));
192 REQUIRE(want == got);
195 SECTION("Two stochastic events (drawing each distribution)")
197 simgrid::xbt::random::set_implem_xbt();
198 simgrid::xbt::random::set_mersenne_seed(12345);
199 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC\n"
201 "EXP 0.05 NORMAL 15 5");
203 std::vector<simgrid::kernel::profile::DatedValue> want;
204 // The following values were drawn using the XBT_RNG_xbt method /outside/ the testcase.
205 want.emplace_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
206 want.emplace_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
208 REQUIRE(want == got);
211 SECTION("Two stochastic events, with a loop")
213 simgrid::xbt::random::set_implem_xbt();
214 simgrid::xbt::random::set_mersenne_seed(12345);
215 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC LOOP\n"
217 "EXP 0.05 NORMAL 15 5\n"
220 // In this case, the main use of the last stochastic event is to set when the first event takes place.
222 std::vector<simgrid::kernel::profile::DatedValue> want;
223 want.emplace_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
224 want.emplace_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
225 want.emplace_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 0));
226 want.emplace_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 10.39759496468994726115));
228 REQUIRE(want == got);