For a load test of my application (under Linux), I'm looking for a tool that outputs data on stdout at a specific rate (like 100 bytes/s), so that I can pipe the output to netcat which sends it to my application. Some option for dd would be ideal, but I didn't find anything so far. It doesn't really matter what kind of data is printed (NUL bytes are OK). Any hints?
-
If you're fine with getting all hundred bytes at a time, you could do a loop with
sleepand plain oldechoin the shell as a first attempt at least.oliver : good idea - something like "while [ true ]; do echo -n "1234567890"; usleep 10000; done" already works.From unwind -
Well, I'm now using nuttcp to do "real" load tests instead. It seems to have quite low overhead, so the test system is not too much disturbed.
From oliver -
I wrote a quick program that takes one argument, how many
Acharacters to print to standard output per second (negative argument means no rate limiting). Hope this helps! :-) (On GNU libc, you will need to link your program with-lrt.)Edit: revised to print dot by default, unless a second argument is specified, in which case the first character of that is used. (And that means, if you want to print the NUL character, just specify an empty string as the second argument. :-))
#include <math.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> int sleeptill(const struct timespec *when) { struct timespec now, diff; clock_gettime(CLOCK_REALTIME, &now); diff.tv_sec = when->tv_sec - now.tv_sec; diff.tv_nsec = when->tv_nsec - now.tv_nsec; while (diff.tv_nsec < 0) { diff.tv_nsec += 1000000000; --diff.tv_sec; } if (diff.tv_sec < 0) return 0; return nanosleep(&diff, 0); } int main(int argc, char **argv) { double rate = 0.0; char *endp; struct timespec start; double offset; if (argc >= 2) { rate = strtod(argv[1], &endp); if (endp == argv[1] || *endp) rate = 0.0; else rate = 1 / rate; if (!argv[2]) argv[2] = "."; } if (!rate) { fprintf(stderr, "usage: %s rate [char]\n", argv[0]); return 1; } clock_gettime(CLOCK_REALTIME, &start); offset = start.tv_nsec / 1000000000.0; while (1) { struct timespec till = start; double frac; double whole; frac = modf(offset += rate, &whole); till.tv_sec += whole; till.tv_nsec = frac * 1000000000.0; sleeptill(&till); write(STDOUT_FILENO, argv[2], 1); } }Chris Jester-Young : With the latest revision, you can now specify 0 as the rate. Technically, it doesn't wait "forever" (as it should, mathematically); rather, it waits until the end of time_t (January 2038, on platforms with a 32-bit time_t). That's still quite a while to wait, though. :-Doliver : Nice stuff - thanks! How about putting it up on some revision control site (github, launchpad, sourceforge...) so people can add changes? Also, I think for performance it would be useful to write() a whole block of data at once.Chris Jester-Young : I deliberately used write() with no buffering so the data is guaranteed to come at a constant rate. To use buffering, change the write() call to putchar(*argv[2]). :-) I'll see what I can do about public revision control....Chris Jester-Young : Also, if you're using something small for the rate like 100 (as in your original question), most of the time will be taken by the sleep, not by the write. I wrote the sleeptill() function expressly to avoid "time slippage" due to the time taken, such as by the write.Chris Jester-Young : Okay, this isn't github or anything like it, however it'll hopefully do the trick: http://refactormycode.com/codes/566-writing-characters-to-stdout-at-a-specified-rateFrom Chris Jester-Young
0 comments:
Post a Comment