]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
11fdf7f2 | 3 | |
7c673cae FG |
4 | /* |
5 | * Copyright (C) 2016 Red Hat Inc. | |
11fdf7f2 TL |
6 | * |
7 | * Author: J. Eric Ivancich <ivancich@redhat.com> | |
8 | * | |
9 | * This is free software; you can redistribute it and/or modify it | |
10 | * under the terms of the GNU Lesser General Public License version | |
11 | * 2.1, as published by the Free Software Foundation. See file | |
12 | * COPYING. | |
7c673cae FG |
13 | */ |
14 | ||
11fdf7f2 | 15 | |
7c673cae FG |
16 | #include <atomic> |
17 | #include <thread> | |
18 | #include <chrono> | |
19 | #include <iostream> | |
20 | ||
21 | #include "gtest/gtest.h" | |
22 | ||
23 | #include "sim_recs.h" | |
24 | #include "sim_client.h" | |
25 | ||
26 | #include "test_dmclock.h" | |
27 | ||
28 | ||
29 | using namespace std::placeholders; | |
30 | ||
31 | namespace dmc = crimson::dmclock; | |
32 | namespace test = crimson::test_dmc; | |
33 | namespace sim = crimson::qos_simulation; | |
34 | ||
35 | using TimePoint = std::chrono::time_point<std::chrono::system_clock>; | |
36 | ||
37 | static TimePoint now() { return std::chrono::system_clock::now(); } | |
38 | ||
39 | ||
40 | TEST(test_client, full_bore_timing) { | |
41 | std::atomic_ulong count(0); | |
42 | ||
43 | ServerId server_id = 3; | |
44 | ||
45 | sim::TestResponse resp(0); | |
46 | dmc::PhaseType resp_params = dmc::PhaseType::priority; | |
47 | test::DmcClient* client; | |
11fdf7f2 | 48 | const sim::Cost request_cost = 1u; |
7c673cae FG |
49 | |
50 | auto start = now(); | |
51 | client = | |
52 | new test::DmcClient(ClientId(0), | |
53 | [&] (const ServerId& server, | |
54 | const sim::TestRequest& req, | |
55 | const ClientId& client_id, | |
56 | const dmc::ReqParams& req_params) { | |
57 | ++count; | |
11fdf7f2 | 58 | client->receive_response(resp, client_id, resp_params, request_cost); |
7c673cae FG |
59 | }, |
60 | [&] (const uint64_t seed) -> ServerId& { | |
61 | return server_id; | |
62 | }, | |
63 | test::dmc_client_accumulate_f, | |
64 | 1000, // ops to run | |
65 | 100, // iops goal | |
66 | 5); // outstanding ops allowed | |
67 | client->wait_until_done(); | |
68 | auto end = now(); | |
69 | EXPECT_EQ(1000u, count) << "didn't get right number of ops"; | |
70 | ||
71 | int milliseconds = (end - start) / std::chrono::milliseconds(1); | |
72 | EXPECT_LT(10000, milliseconds) << "timing too fast to be correct"; | |
73 | EXPECT_GT(12000, milliseconds) << "timing suspiciously slow"; | |
31f18b77 FG |
74 | |
75 | delete client; | |
7c673cae FG |
76 | } |
77 | ||
78 | ||
79 | TEST(test_client, paused_timing) { | |
80 | std::atomic_ulong count(0); | |
81 | std::atomic_ulong unresponded_count(0); | |
82 | std::atomic_bool auto_respond(false); | |
83 | ||
84 | ClientId my_client_id = 0; | |
85 | ServerId server_id = 3; | |
86 | ||
87 | sim::TestResponse resp(0); | |
88 | dmc::PhaseType resp_params = dmc::PhaseType::priority; | |
11fdf7f2 | 89 | const uint64_t request_cost = 1u; |
7c673cae FG |
90 | test::DmcClient* client; |
91 | ||
92 | auto start = now(); | |
93 | client = | |
94 | new test::DmcClient(my_client_id, | |
95 | [&] (const ServerId& server, | |
96 | const sim::TestRequest& req, | |
97 | const ClientId& client_id, | |
98 | const dmc::ReqParams& req_params) { | |
99 | ++count; | |
100 | if (auto_respond.load()) { | |
11fdf7f2 | 101 | client->receive_response(resp, client_id, resp_params, request_cost); |
7c673cae FG |
102 | } else { |
103 | ++unresponded_count; | |
104 | } | |
105 | }, | |
106 | [&] (const uint64_t seed) -> ServerId& { | |
107 | return server_id; | |
108 | }, | |
109 | test::dmc_client_accumulate_f, | |
110 | ||
111 | 1000, // ops to run | |
112 | 100, // iops goal | |
113 | 50); // outstanding ops allowed | |
114 | std::thread t([&]() { | |
115 | std::this_thread::sleep_for(std::chrono::seconds(5)); | |
116 | EXPECT_EQ(50u, unresponded_count.load()) << | |
117 | "should have 50 unresponded calls"; | |
118 | auto_respond = true; | |
119 | // respond to those 50 calls | |
120 | for(int i = 0; i < 50; ++i) { | |
11fdf7f2 | 121 | client->receive_response(resp, my_client_id, resp_params, 1); |
7c673cae FG |
122 | --unresponded_count; |
123 | } | |
124 | }); | |
125 | ||
126 | client->wait_until_done(); | |
127 | auto end = now(); | |
128 | int milliseconds = (end - start) / std::chrono::milliseconds(1); | |
129 | ||
130 | // the 50 outstanding ops allowed means the first half-second of | |
131 | // requests get responded to during the 5 second pause. So we have | |
132 | // to adjust our expectations by a half-second. | |
133 | EXPECT_LT(15000 - 500, milliseconds) << "timing too fast to be correct"; | |
134 | EXPECT_GT(17000 - 500, milliseconds) << "timing suspiciously slow"; | |
135 | t.join(); | |
31f18b77 FG |
136 | |
137 | delete client; | |
7c673cae | 138 | } |