1 // Part of Measurement Kit <https://measurement-kit.github.io/>.
2 // Measurement Kit is free software under the BSD license. See AUTHORS
3 // and LICENSE for more information on the copying conditions.
4
5 #include "src/measurement_kit/cmdline.hpp"
6
7 #include <measurement_kit/common/nlohmann/json.hpp>
8 #include <measurement_kit/ndt.hpp>
9
10 namespace ndt {
11
12 #define USAGE \
13 "usage: measurement_kit [options] ndt [-m metro] [-N tool] [-p port]\n" \
14 " [-T phase] [host]\n" \
15 "\n" \
16 "Available tool names for mlab-ns: ndt, neubot (default: ndt)\n" \
17 "Available phases: download, download-ext, none, upload\n" \
18 " (default: -T download -T upload)\n"
19
main(std::list<Callback<BaseTest &>> & initializers,int argc,char ** argv)20 int main(std::list<Callback<BaseTest &>> &initializers, int argc, char **argv) {
21 NdtTest test;
22 int test_suite = 0;
23 int use_default_test_suite = true;
24
25 for (int ch; (ch = getopt(argc, argv, "C:m:N:p:T:")) != -1;) {
26 switch (ch) {
27 case 'C':
28 test.set_option("mlabns/policy", "country");
29 test.set_option("mlabns/country", optarg);
30 break;
31 case 'm':
32 test.set_option("mlabns/policy", "metro");
33 test.set_option("mlabns/metro", optarg);
34 break;
35 case 'N':
36 test.set_option("mlabns_tool_name", optarg);
37 break;
38 case 'p':
39 test.set_option("port", must_convert_to_int(optarg));
40 break;
41 case 'T':
42 use_default_test_suite = false;
43 if (strcmp(optarg, "download") == 0) {
44 test_suite |= MK_NDT_DOWNLOAD;
45 } else if (strcmp(optarg, "download-ext") == 0) {
46 test_suite |= MK_NDT_DOWNLOAD_EXT;
47 } else if (strcmp(optarg, "none") == 0) {
48 test_suite = 0;
49 } else if (strcmp(optarg, "upload") == 0) {
50 test_suite |= MK_NDT_UPLOAD;
51 } else {
52 fprintf(stderr, "invalid parameter for -T option: %s", optarg);
53 exit(1);
54 }
55 break;
56 default:
57 fprintf(stderr, "%s\n", USAGE);
58 exit(1);
59 /* NOTREACHED */
60 }
61 }
62 argc -= optind, argv += optind;
63 if (argc > 1) {
64 fprintf(stderr, "%s\n", USAGE);
65 exit(1);
66 /* NOTREACHED */
67 }
68
69 // If the user expressed preference force test suite, otherwise the
70 // code would use the default test suite (download|upload).
71 if (!use_default_test_suite) {
72 test.set_option("test_suite", test_suite);
73 }
74
75 if (argc == 1) {
76 test.set_option("address", argv[0]);
77 }
78
79 ndt_init(initializers, test)
80 .on_entry([](std::string s) {
81 nlohmann::json doc = nlohmann::json::parse(s);
82 auto simple = doc["test_keys"]["simple"];
83 auto advanced = doc["test_keys"]["advanced"];
84 printf("\nTest summary\n");
85 printf("------------\n");
86 double download = simple["download"];
87 double upload = simple["upload"];
88 printf("Upload speed: %.2f kbit/s\n", upload);
89 printf("Download speed: %.2f kbit/s\n", download);
90 double packet_loss = advanced["packet_loss"];
91 double out_of_order = advanced["out_of_order"];
92 double max_rtt = advanced["max_rtt"];
93 double avg_rtt = advanced["avg_rtt"];
94 double min_rtt = advanced["min_rtt"];
95 long mss = advanced["mss"];
96 long timeouts = advanced["timeouts"];
97 printf("Packet loss rate: %.2f%%\n", packet_loss * 100.0);
98 printf("Out of order: %.2f%%\n", out_of_order * 100.0);
99 printf("RTT (min/avg/max): %.2f/%.2f/%.2f ms\n", min_rtt, avg_rtt,
100 max_rtt);
101 printf("MSS: %ld\n", mss);
102 printf("Timeouts: %ld\n", timeouts);
103 printf("\n");
104 fflush(stdout);
105 })
106 .run();
107 return 0;
108 }
109
110 } // namespace ndt
111