Add automation test for http client based on httpbin.org

master
Chunting Gu 6 years ago
parent df4bb33bd8
commit ddfcecccc6

@ -21,7 +21,7 @@ bool kSslVerify = true;
const std::string kUrlRoot = "https://api.github.com";
// -----------------------------------------------------------------------------
// JSON helper functions (based on cppjson).
// JSON helper functions (based on jsoncpp).
// Parse a string to JSON object.
Json::Value StringToJson(const std::string& str) {

@ -25,34 +25,6 @@ void ExampleBasic() {
std::cout << r->content() << std::endl;
}
// Use predefined shortcuts.
void ExampleShortcut() {
webcc::HttpClientSession session;
auto r = session.Get("http://httpbin.org/get",
{"key1", "value1", "key2", "value2"},
{"Accept", "application/json"});
std::cout << r->content() << std::endl;
}
#if WEBCC_ENABLE_SSL
// HTTPS is auto-detected from the URL scheme.
void ExampleHttps() {
webcc::HttpClientSession session;
session.set_ssl_verify(kSslVerify);
auto r = session.Request(webcc::HttpRequestBuilder{}.Get().
Url("https://httpbin.org/get").
Query("key1", "value1").
Header("Accept", "application/json")());
std::cout << r->content() << std::endl;
}
#endif // WEBCC_ENABLE_SSL
// Example for testing Keep-Alive connection.
//
// Boost.org doesn't support persistent connection so always includes
@ -79,33 +51,6 @@ void ExampleKeepAlive(const std::string& url) {
session.Get(url);
}
void ExampleCompression() {
webcc::HttpClientSession session;
auto r = session.Get("http://httpbin.org/gzip");
std::cout << r->content() << std::endl;
r = session.Get("http://httpbin.org/deflate");
std::cout << r->content() << std::endl;
}
// Get an image from HttpBin.org and save to the given file path.
// E.g., ExampleImage("E:\\example.jpg")
void ExampleImage(const std::string& path) {
webcc::HttpClientSession session;
auto r = session.Get("http://httpbin.org/image/jpeg");
// Or
// auto r = session.Get("http://httpbin.org/image", {},
// {"Accept", "image/jpeg"});
std::ofstream ofs(path, std::ios::binary);
ofs << r->content();
}
int main() {
WEBCC_LOG_INIT("", webcc::LOG_CONSOLE);

@ -1,19 +1,25 @@
# Tests
# Common libraries to link.
set(TEST_COMMON_LIBS webcc ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES}
"${CMAKE_THREAD_LIBS_INIT}")
set(TEST_LIBS webcc ${Boost_LIBRARIES} "${CMAKE_THREAD_LIBS_INIT}")
if(WEBCC_ENABLE_SSL)
set(TEST_LIBS ${TEST_LIBS} ${OPENSSL_LIBRARIES})
endif()
if(WIN32)
set(TEST_COMMON_LIBS ${TEST_COMMON_LIBS} zlibstatic crypt32)
set(TEST_LIBS ${TEST_LIBS} zlibstatic crypt32)
else()
set(TEST_COMMON_LIBS ${TEST_COMMON_LIBS} ${ZLIB_LIBRARIES})
set(TEST_LIBS ${TEST_LIBS} ${ZLIB_LIBRARIES})
endif()
if(UNIX)
# Add `-ldl` for Linux to avoid "undefined reference to `dlopen'".
set(TEST_COMMON_LIBS ${TEST_COMMON_LIBS} ${CMAKE_DL_LIBS})
set(TEST_LIBS ${TEST_LIBS} ${CMAKE_DL_LIBS})
endif()
add_executable(test_logger test_logger.cc)
target_link_libraries(test_logger ${TEST_COMMON_LIBS})
target_link_libraries(test_logger ${TEST_LIBS})
add_executable(test_http_client test_http_client.cc)
target_link_libraries(test_http_client gtest jsoncpp ${TEST_LIBS})

@ -0,0 +1,230 @@
#include "gtest/gtest.h"
#include "boost/algorithm/string.hpp"
#include "json/json.h"
#include "webcc/http_client_session.h"
#include "webcc/logger.h"
// -----------------------------------------------------------------------------
#if (defined(WIN32) || defined(_WIN64))
// You need to set environment variable SSL_CERT_FILE properly to enable
// SSL verification.
bool kSslVerify = false;
#else
bool kSslVerify = true;
#endif
// -----------------------------------------------------------------------------
// JSON helper functions (based on jsoncpp).
// Parse a string to JSON object.
Json::Value StringToJson(const std::string& str) {
Json::Value json;
Json::CharReaderBuilder builder;
std::stringstream stream(str);
std::string errors;
if (!Json::parseFromStream(builder, stream, &json, &errors)) {
std::cerr << errors << std::endl;
}
return json;
}
// -----------------------------------------------------------------------------
#if 1
static void AssertGet(webcc::HttpResponsePtr r) {
Json::Value json = StringToJson(r->content());
Json::Value args = json["args"];
EXPECT_EQ(2, args.size());
EXPECT_EQ("value1", args["key1"].asString());
EXPECT_EQ("value2", args["key2"].asString());
Json::Value headers = json["headers"];
EXPECT_EQ("application/json", headers["Accept"].asString());
EXPECT_EQ("gzip, deflate", headers["Accept-Encoding"].asString());
EXPECT_EQ("httpbin.org", headers["Host"].asString());
}
TEST(TestHttpClient, Get_RequestFunc) {
webcc::HttpClientSession session;
try {
auto r = session.Request(webcc::HttpRequestBuilder{}.Get().
Url("http://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2").
Header("Accept", "application/json")
());
AssertGet(r);
} catch (const webcc::Exception& e) {
std::cerr << e.what() << std::endl;
}
}
TEST(TestHttpClient, Get_Shortcut) {
webcc::HttpClientSession session;
try {
// Use predefined shortcuts.
auto r = session.Get("http://httpbin.org/get",
{ "key1", "value1", "key2", "value2" },
{ "Accept", "application/json" });
AssertGet(r);
} catch (const webcc::Exception& e) {
std::cerr << e.what() << std::endl;
}
}
#if WEBCC_ENABLE_SSL
TEST(TestHttpClient, Get_SSL) {
webcc::HttpClientSession session;
session.set_ssl_verify(kSslVerify);
try {
// HTTPS is auto-detected from the URL scheme.
auto r = session.Request(webcc::HttpRequestBuilder{}.Get().
Url("https://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2").
Header("Accept", "application/json")
());
AssertGet(r);
} catch (const webcc::Exception& e) {
std::cerr << e.what() << std::endl;
}
}
#endif // WEBCC_ENABLE_SSL
// -----------------------------------------------------------------------------
// Test Gzip compressed response.
TEST(TestHttpClient, Compression_Gzip) {
webcc::HttpClientSession session;
try {
auto r = session.Get("http://httpbin.org/gzip");
Json::Value json = StringToJson(r->content());
EXPECT_EQ(true, json["gzipped"].asBool());
} catch (const webcc::Exception& e) {
std::cerr << e.what() << std::endl;
}
}
// Test Deflate compressed response.
TEST(TestHttpClient, Compression_Deflate) {
webcc::HttpClientSession session;
try {
auto r = session.Get("http://httpbin.org/deflate");
std::cout << r->content() << std::endl;
Json::Value json = StringToJson(r->content());
EXPECT_EQ(true, json["deflated"].asBool());
} catch (const webcc::Exception& e) {
std::cerr << e.what() << std::endl;
}
}
// -----------------------------------------------------------------------------
// Test persistent connections.
TEST(TestHttpClient, KeepAlive) {
webcc::HttpClientSession session;
std::string url = "http://httpbin.org/get";
try {
// Keep-Alive by default.
auto r = session.Get(url);
using boost::iequals;
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Keep-alive"));
// Close by setting Connection header.
r = session.Get(url, {}, { "Connection", "Close" });
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Close"));
// Close by using request builder.
r = session.Request(webcc::HttpRequestBuilder{}.Get().
KeepAlive(false)
());
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Close"));
// Keep-Alive explicitly by using request builder.
r = session.Request(webcc::HttpRequestBuilder{}.Get().
KeepAlive(true)
());
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Keep-alive"));
} catch (const webcc::Exception& e) {
std::cerr << e.what() << std::endl;
}
}
// -----------------------------------------------------------------------------
// Get a JPEG image.
TEST(TestHttpClient, GetImageJpeg) {
webcc::HttpClientSession session;
std::string url = "http://httpbin.org/get";
try {
auto r = session.Get("http://httpbin.org/image/jpeg");
// Or
// auto r = session.Get("http://httpbin.org/image", {},
// {"Accept", "image/jpeg"});
//std::ofstream ofs(path, std::ios::binary);
//ofs << r->content();
// TODO: Verify the response is a valid JPEG image.
} catch (const webcc::Exception& e) {
std::cerr << e.what() << std::endl;
}
}
#endif
// -----------------------------------------------------------------------------
// TODO: Post requests
// -----------------------------------------------------------------------------
int main(int argc, char* argv[]) {
// Set webcc::LOG_CONSOLE to enable logging.
WEBCC_LOG_INIT("", 0);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

@ -85,37 +85,4 @@ void HttpRequestBuilder::SetContent(HttpRequestPtr request,
request->SetContent(std::move(data), true);
}
//void HttpRequestBuilder::CreateFormData(std::string* data,
// const std::string& boundary) {
// for (auto& pair : files_) {
// data->append("--" + boundary + kCRLF);
//
// // Content-Disposition header
// data->append("Content-Disposition: form-data");
// if (!pair.first.empty()) {
// data->append("; name=\"" + pair.first + "\"");
// }
// if (!pair.second.file_name().empty()) {
// data->append("; filename=\"" + pair.second.file_name() + "\"");
// }
// data->append(kCRLF);
//
// // Content-Type header
// if (!pair.second.mime_type().empty()) {
// data->append("Content-Type: " + pair.second.mime_type());
// data->append(kCRLF);
// }
//
// data->append(kCRLF);
//
// // Payload
// data->append(pair.second.data());
//
// data->append(kCRLF);
// }
//
// data->append("--" + boundary + "--");
// data->append(kCRLF);
//}
} // namespace webcc

@ -94,7 +94,7 @@ public:
return *this;
}
HttpRequestBuilder& KeepAlive(bool keep_alive) {
HttpRequestBuilder& KeepAlive(bool keep_alive = true) {
keep_alive_ = keep_alive;
return *this;
}
@ -107,8 +107,6 @@ public:
private:
void SetContent(HttpRequestPtr request, std::string&& data);
//void CreateFormData(std::string* data, const std::string& boundary);
private:
std::string method_;

Loading…
Cancel
Save