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