Skip to content

Commit e024c75

Browse files
committed
t/helper/fsmonitor-client: create stress test
Create a stress test to hammer on the fsmonitor daemon. Create a client-side thread pool of n threads and have each of them make m requests as fast as they can. NEEDSWORK: This is just the client-side thread pool and is useful for interactive testing and experimentation. We need to add a script test to drive this. Signed-off-by: Jeff Hostetler <[email protected]>
1 parent e1055f3 commit e024c75

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

t/helper/test-fsmonitor-client.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "cache.h"
88
#include "parse-options.h"
99
#include "fsmonitor-ipc.h"
10+
#include "thread-utils.h"
11+
#include "trace2.h"
1012

1113
#ifndef HAVE_FSMONITOR_DAEMON_BACKEND
1214
int cmd__fsmonitor_client(int argc, const char **argv)
@@ -79,20 +81,120 @@ static int do_send_flush(void)
7981
return 0;
8082
}
8183

84+
struct hammer_thread_data
85+
{
86+
pthread_t pthread_id;
87+
int thread_nr;
88+
89+
int nr_requests;
90+
const char *token;
91+
92+
int sum_successful;
93+
int sum_errors;
94+
};
95+
96+
static void *hammer_thread_proc(void *_hammer_thread_data)
97+
{
98+
struct hammer_thread_data *data = _hammer_thread_data;
99+
struct strbuf answer = STRBUF_INIT;
100+
int k;
101+
int ret;
102+
103+
trace2_thread_start("hammer");
104+
105+
for (k = 0; k < data->nr_requests; k++) {
106+
strbuf_reset(&answer);
107+
108+
ret = fsmonitor_ipc__send_query(data->token, &answer);
109+
if (ret < 0)
110+
data->sum_errors++;
111+
else
112+
data->sum_successful++;
113+
}
114+
115+
strbuf_release(&answer);
116+
trace2_thread_exit();
117+
return NULL;
118+
}
119+
120+
/*
121+
* Start a pool of client threads that will each send a series of
122+
* commands to the daemon.
123+
*
124+
* The goal is to overload the daemon with a sustained series of
125+
* concurrent requests.
126+
*/
127+
static int do_hammer(const char *token, int nr_threads, int nr_requests)
128+
{
129+
struct hammer_thread_data *data = NULL;
130+
int k;
131+
int sum_join_errors = 0;
132+
int sum_commands = 0;
133+
int sum_errors = 0;
134+
135+
if (!token || !*token)
136+
token = get_token_from_index();
137+
if (nr_threads < 1)
138+
nr_threads = 1;
139+
if (nr_requests < 1)
140+
nr_requests = 1;
141+
142+
CALLOC_ARRAY(data, nr_threads);
143+
144+
for (k = 0; k < nr_threads; k++) {
145+
struct hammer_thread_data *p = &data[k];
146+
p->thread_nr = k;
147+
p->nr_requests = nr_requests;
148+
p->token = token;
149+
150+
if (pthread_create(&p->pthread_id, NULL, hammer_thread_proc, p)) {
151+
warning("failed to create thread[%d] skipping remainder", k);
152+
nr_threads = k;
153+
break;
154+
}
155+
}
156+
157+
for (k = 0; k < nr_threads; k++) {
158+
struct hammer_thread_data *p = &data[k];
159+
160+
if (pthread_join(p->pthread_id, NULL))
161+
sum_join_errors++;
162+
sum_commands += p->sum_successful;
163+
sum_errors += p->sum_errors;
164+
}
165+
166+
fprintf(stderr, "HAMMER: [threads %d][requests %d] [ok %d][err %d][join %d]\n",
167+
nr_threads, nr_requests, sum_commands, sum_errors, sum_join_errors);
168+
169+
free(data);
170+
171+
/*
172+
* TODO Decide if/when to return an error or call die().
173+
*/
174+
return 0;
175+
}
176+
82177
int cmd__fsmonitor_client(int argc, const char **argv)
83178
{
84179
const char *subcmd;
85180
const char *token = NULL;
181+
int nr_threads = 1;
182+
int nr_requests = 1;
86183

87184
const char * const fsmonitor_client_usage[] = {
88185
N_("test-helper fsmonitor-client query [<token>]"),
89186
N_("test-helper fsmonitor-client flush"),
187+
N_("test-helper fsmonitor-client hammer [<token>] [<threads>] [<requests>]"),
90188
NULL,
91189
};
92190

93191
struct option options[] = {
94192
OPT_STRING(0, "token", &token, N_("token"),
95193
N_("command token to send to the server")),
194+
195+
OPT_INTEGER(0, "threads", &nr_threads, N_("number of client threads")),
196+
OPT_INTEGER(0, "requests", &nr_requests, N_("number of requests per thread")),
197+
96198
OPT_END()
97199
};
98200

@@ -116,6 +218,9 @@ int cmd__fsmonitor_client(int argc, const char **argv)
116218
if (!strcmp(subcmd, "flush"))
117219
return !!do_send_flush();
118220

221+
if (!strcmp(subcmd, "hammer"))
222+
return !!do_hammer(token, nr_threads, nr_requests);
223+
119224
die("Unhandled subcommand: '%s'", subcmd);
120225
}
121226
#endif

0 commit comments

Comments
 (0)