Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Compiled Object files
\# Compiled Object files
*.slo
*.lo
*.o
Expand Down Expand Up @@ -31,6 +31,16 @@ cmake_build/
.idea/
cmake-build-debug/
cmake-build-linux/
SpeedTest

# Visual Studio 2015/2017 cache/options directory
.vs/
.vs/

# CMake stuff
CMakeFiles/
*.cmake
CMakeCache.txt
Makefile

# Config
SpeedTestConfig.h
6 changes: 5 additions & 1 deletion CmdOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define SPEEDTEST_CMDOPTIONS_H
#include <getopt.h>

enum OutputType { verbose, text, json };
enum OutputType { verbose, text, json, csv, csv_header };


typedef struct program_options_t {
Expand Down Expand Up @@ -67,6 +67,10 @@ bool ParseOptions(const int argc, const char **argv, ProgramOptions& options){
options.output_type = OutputType::text;
else if (strcmp(optarg, "json") == 0)
options.output_type = OutputType::json;
else if (strcmp(optarg, "csv") == 0)
options.output_type = OutputType::csv;
else if (strcmp(optarg, "csv_header") == 0)
options.output_type = OutputType::csv_header;
else {
std::cerr << "Unsupported output type " << optarg << std::endl;
std::cerr << "Supported output type: default, text, json" <<std::endl;
Expand Down
2 changes: 1 addition & 1 deletion SpeedTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ size_t SpeedTest::writeFunc(void *buf, size_t size, size_t nmemb, void *userp) {
}

std::map<std::string, std::string> SpeedTest::parseQueryString(const std::string &query) {
auto map = std::map<std::string, std::string>();
auto map = std::map<std::string, std::string>();
auto pairs = splitString(query, '&');
for (auto &p : pairs){
auto kv = splitString(p, '=');
Expand Down
59 changes: 42 additions & 17 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ void banner(){
void usage(const char* name){
std::cerr << "Usage: " << name << " ";
std::cerr << " [--latency] [--quality] [--download] [--upload] [--share] [--help]\n"
" [--test-server host:port] [--output verbose|text|json]\n";
" [--test-server host:port] [--output verbose|text|json|csv|csv_header]\n";
std::cerr << "optional arguments:" << std::endl;
std::cerr << " --help Show this message and exit\n";
std::cerr << " --latency Perform latency test only\n";
std::cerr << " --quality Perform quality test only. It includes latency test\n";
std::cerr << " --download Perform download test only. It includes latency test\n";
std::cerr << " --upload Perform upload test only. It includes latency test\n";
std::cerr << " --share Generate and provide a URL to the speedtest.net share results image\n";
std::cerr << " --insecure Skip SSL certificate verify (Useful for Embedded devices)\n";
std::cerr << " --test-server host:port Run speed test against a specific server\n";
std::cerr << " --quality-server host:port Run line quality test against a specific server\n";
std::cerr << " --output verbose|text|json Set output type. Default: verbose\n";
std::cerr << " --help Show this message and exit\n";
std::cerr << " --latency Perform latency test only\n";
std::cerr << " --quality Perform quality test only. It includes latency test\n";
std::cerr << " --download Perform download test only. It includes latency test\n";
std::cerr << " --upload Perform upload test only. It includes latency test\n";
std::cerr << " --share Generate and provide a URL to the speedtest.net share results image\n";
std::cerr << " --insecure Skip SSL certificate verify (Useful for Embedded devices)\n";
std::cerr << " --test-server host:port Run speed test against a specific server\n";
std::cerr << " --quality-server host:port Run line quality test against a specific server\n";
std::cerr << " --output verbose|text|json|csv|csv_header Set output type. Default: verbose\n";
}

int main(const int argc, const char **argv) {
Expand All @@ -44,7 +44,12 @@ int main(const int argc, const char **argv) {
banner();
std::cout << std::endl;
}


if (programOptions.output_type == OutputType::csv_header){
std::cout << "IP, IP Lat, IP Lon, Provider, Server Name, Server Location, Distance (km)\
, Server Host, Ping, Jitter, Download Speed, Upload Speed" << std::endl;
return EXIT_SUCCESS;
}

if (programOptions.help) {
usage(argv[0]);
Expand Down Expand Up @@ -89,7 +94,12 @@ int main(const int argc, const char **argv) {
std::cout << "\"lon\":\"" << info.lon << "\",";
std::cout << "\"isp\":\"" << info.isp << "\"";
std::cout << "},";
}
} else if (programOptions.output_type == OutputType::csv) {
std::cout << '"' << info.ip_address << '"' << ","
<< '"' << info.lat << '"' << ","
<< '"' << info.lon << '"' << ","
<< '"' << info.isp << '"' << ",";
}

auto serverList = sp.serverList();

Expand Down Expand Up @@ -135,7 +145,14 @@ int main(const int argc, const char **argv) {
std::cout << "\"latency\":\"" << sp.latency() << "\",";
std::cout << "\"host\":\"" << serverInfo.host << "\"";
std::cout << "},";
}
} else if (programOptions.output_type == OutputType::csv){
std::cout << '"' << serverInfo.name << '"' << "," \
<< '"' << serverInfo.sponsor << '"' << "," \
<< '"' << serverInfo.distance << '"' << "," \
<< '"' << serverInfo.host << '"' << ","\
<< '"' << sp.latency() << '"' << ",";

}

} else {

Expand Down Expand Up @@ -181,7 +198,9 @@ int main(const int argc, const char **argv) {
std::cout << "\"jitter\":\"";
std::cout << std::fixed;
std::cout << jitter << "\",";
}
} else if (programOptions.output_type == OutputType::csv){
std::cout << '"' << jitter << '"' << ",";
}
} else {
std::cerr << "Jitter measurement is unavailable at this time." << std::endl;
}
Expand Down Expand Up @@ -243,7 +262,10 @@ int main(const int argc, const char **argv) {
std::cout << "\"download\":\"";
std::cout << std::fixed;
std::cout << (downloadSpeed*1000*1000) << "\",";
}
} else if (programOptions.output_type == OutputType::csv){
std::cout << std::fixed;
std::cout << '"' << (downloadSpeed * 1000 * 1000) << '"' << ",";
}
} else {
std::cerr << "Download test failed." << std::endl;
if (programOptions.output_type == OutputType::json)
Expand Down Expand Up @@ -281,7 +303,10 @@ int main(const int argc, const char **argv) {
std::cout << "\"upload\":\"";
std::cout << std::fixed;
std::cout << (uploadSpeed*1000*1000) << "\",";
}
} else if (programOptions.output_type == OutputType::csv) {
std::cout << std::fixed;
std::cout << '"' << (uploadSpeed * 1000 * 1000) << '"' << std::endl;
}

} else {
std::cerr << "Upload test failed." << std::endl;
Expand Down
2 changes: 2 additions & 0 deletions makeExec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cmake -DCMAKE_BUILD_TYPE=Release .
make