1 /* Copyright (c) 2017-2019. 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");
24 class MockedResource : public simgrid::kernel::resource::Resource {
26 explicit MockedResource() : simgrid::kernel::resource::Resource(nullptr, "fake", nullptr) {}
27 void apply_event(simgrid::kernel::profile::Event* event, double value) override
29 XBT_VERB("t=%.1f: Change value to %lg (idx: %u)", thedate, value, event->idx);
30 tmgr_trace_event_unref(&event);
32 bool is_used() override { return true; }
35 static std::vector<simgrid::kernel::profile::DatedValue> trace2vector(const char* str)
37 std::vector<simgrid::kernel::profile::DatedValue> res;
38 simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
39 XBT_VERB("---------------------------------------------------------");
40 XBT_VERB("data>>\n%s<<data\n", str);
41 for (auto const& evt : trace->event_list)
42 XBT_VERB("event: d:%lg v:%lg", evt.date_, evt.value_);
44 MockedResource daResource;
45 simgrid::kernel::profile::FutureEvtSet fes;
46 simgrid::kernel::profile::Event* insertedIt = trace->schedule(&fes, &daResource);
48 while (fes.next_date() <= 20.0 && fes.next_date() >= 0) {
49 thedate = fes.next_date();
51 simgrid::kernel::resource::Resource* resource;
52 simgrid::kernel::profile::Event* it = fes.pop_leq(thedate, &value, &resource);
56 REQUIRE(it == insertedIt); // Check that we find what we've put
58 res.push_back(simgrid::kernel::profile::DatedValue(thedate, value));
60 XBT_DEBUG("%.1f: ignore an event (idx: %u)\n", thedate, it->idx);
62 resource->apply_event(it, value);
68 static std::vector<simgrid::kernel::profile::StochasticDatedValue> trace2selist(const char* str)
70 simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
71 std::vector<simgrid::kernel::profile::StochasticDatedValue> stocevlist = trace->stochastic_event_list;
76 TEST_CASE("kernel::profile: Resource profiles, defining the external load", "kernel::profile")
79 SECTION("No event, no loop")
81 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("");
82 std::vector<simgrid::kernel::profile::DatedValue> want;
86 SECTION("One event no loop")
88 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("9.0 3.0\n");
90 std::vector<simgrid::kernel::profile::DatedValue> want;
91 want.push_back(simgrid::kernel::profile::DatedValue(9, 3));
95 SECTION("Two events, no loop")
97 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
100 std::vector<simgrid::kernel::profile::DatedValue> want;
101 want.push_back(simgrid::kernel::profile::DatedValue(3, 1));
102 want.push_back(simgrid::kernel::profile::DatedValue(9, 3));
104 REQUIRE(want == got);
107 SECTION("Three events, no loop")
110 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("3.0 1.0\n"
114 std::vector<simgrid::kernel::profile::DatedValue> want;
115 want.push_back(simgrid::kernel::profile::DatedValue(3, 1));
116 want.push_back(simgrid::kernel::profile::DatedValue(5, 2));
117 want.push_back(simgrid::kernel::profile::DatedValue(9, 3));
119 REQUIRE(want == got);
122 SECTION("Two events, looping")
124 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("1.0 1.0\n"
128 std::vector<simgrid::kernel::profile::DatedValue> want;
129 want.push_back(simgrid::kernel::profile::DatedValue(1, 1));
130 want.push_back(simgrid::kernel::profile::DatedValue(3, 3));
131 want.push_back(simgrid::kernel::profile::DatedValue(6, 1));
132 want.push_back(simgrid::kernel::profile::DatedValue(8, 3));
133 want.push_back(simgrid::kernel::profile::DatedValue(11, 1));
134 want.push_back(simgrid::kernel::profile::DatedValue(13, 3));
135 want.push_back(simgrid::kernel::profile::DatedValue(16, 1));
136 want.push_back(simgrid::kernel::profile::DatedValue(18, 3));
138 REQUIRE(want == got);
141 SECTION("Two events, looping, start at 0")
143 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("0.0 1\n"
147 std::vector<simgrid::kernel::profile::DatedValue> want;
148 want.push_back(simgrid::kernel::profile::DatedValue(0, 1));
149 want.push_back(simgrid::kernel::profile::DatedValue(5, 2));
150 want.push_back(simgrid::kernel::profile::DatedValue(10, 1));
151 want.push_back(simgrid::kernel::profile::DatedValue(15, 2));
152 want.push_back(simgrid::kernel::profile::DatedValue(20, 1));
154 REQUIRE(want == got);
157 SECTION("One stochastic event (parsing)")
159 std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
162 std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
163 want.push_back(simgrid::kernel::profile::StochasticDatedValue(0, -1)); // The initial fake event
164 want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Det, {0},
165 simgrid::kernel::profile::Dist_Unif, {10, 20}));
167 REQUIRE(want == got);
170 SECTION("Several stochastic events (all possible parsing forms)")
172 std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
174 "NORMAL 25 10 DET 3\n"
175 "UNIF 10 20 NORMAL 25 10\n"
178 std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
179 want.push_back(simgrid::kernel::profile::StochasticDatedValue(0, -1));
180 want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Det, {0},
181 simgrid::kernel::profile::Dist_Det, {4}));
182 want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Norm, {25, 10},
183 simgrid::kernel::profile::Dist_Det, {3}));
184 want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Unif, {10, 20},
185 simgrid::kernel::profile::Dist_Norm, {25, 10}));
186 want.push_back(simgrid::kernel::profile::StochasticDatedValue(simgrid::kernel::profile::Dist_Det, {5},
187 simgrid::kernel::profile::Dist_Unif, {5, 25}));
189 REQUIRE(want == got);
192 SECTION("Two stochastic events (drawing each distribution)")
194 simgrid::xbt::random::set_mersenne_seed(12345);
195 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC\n"
197 "EXP 0.05 NORMAL 15 5");
199 std::vector<simgrid::kernel::profile::DatedValue> want;
200 // The following values were drawn using the XBT_RNG_xbt method /outside/ the testcase.
201 want.push_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
202 want.push_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
204 REQUIRE(want == got);
207 SECTION("Two stochastic events, with a loop")
209 simgrid::xbt::random::set_mersenne_seed(12345);
210 std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC LOOP\n"
212 "EXP 0.05 NORMAL 15 5\n"
215 // In this case, the main use of the last stochastic event is to set when the first event takes place.
217 std::vector<simgrid::kernel::profile::DatedValue> want;
218 want.push_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
219 want.push_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
220 want.push_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 0));
221 want.push_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 10.39759496468994726115));
223 REQUIRE(want == got);