ublox-at-cellular-interface-ext
Dependencies: ublox-at-cellular-interface
Diff: TESTS/unit_tests/http/main.cpp
- Revision:
- 0:0b75e22c9231
- Child:
- 5:9fd89567f769
diff -r 000000000000 -r 0b75e22c9231 TESTS/unit_tests/http/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TESTS/unit_tests/http/main.cpp Mon Jun 05 12:58:04 2017 +0000 @@ -0,0 +1,335 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "UbloxATCellularInterfaceExt.h" +#include "UDPSocket.h" +#include "FEATURE_COMMON_PAL/nanostack-libservice/mbed-client-libservice/common_functions.h" +#include "mbed_trace.h" +#define TRACE_GROUP "TEST" + +using namespace utest::v1; + +// ---------------------------------------------------------------- +// COMPILE-TIME MACROS +// ---------------------------------------------------------------- + +// These macros can be overridden with an mbed_app.json file and +// contents of the following form: +// +//{ +// "config": { +// "apn": { +// "value": "\"my_apn\"" +// } +//} + +// The credentials of the SIM in the board. +#ifndef MBED_CONF_APP_DEFAULT_PIN +// Note: this is the PIN for the SIM with ICCID +// 8944501104169548380. +# define MBED_CONF_APP_DEFAULT_PIN "5134" +#endif + +// Network credentials. +#ifndef MBED_CONF_APP_APN +# define MBED_CONF_APP_APN NULL +#endif +#ifndef MBED_CONF_APP_USERNAME +# define MBED_CONF_APP_USERNAME NULL +#endif +#ifndef MBED_CONF_APP_PASSWORD +# define MBED_CONF_APP_PASSWORD NULL +#endif + +// The time to wait for a HTTP command to complete +#define HTTP_TIMEOUT 10000 + +// The HTTP echo server, as described in the +// first answer here: +// http://stackoverflow.com/questions/5725430/http-test-server-that-accepts-get-post-calls +// !!! IMPORTANT: this test relies on that server behaving in the same way forever !!! +#define HTTP_ECHO_SERVER "httpbin.org" + +// The size of the test file +#define TEST_FILE_SIZE 100 + +// The maximum number of HTTP profiles +#define MAX_PROFILES 4 + +// ---------------------------------------------------------------- +// PRIVATE VARIABLES +// ---------------------------------------------------------------- + +// Lock for debug prints +static Mutex mtx; + +// An instance of the cellular interface +static UbloxATCellularInterfaceExt *pDriver = + new UbloxATCellularInterfaceExt(MDMTXD, MDMRXD, + MBED_CONF_UBLOX_CELL_BAUD_RATE, + true); +// A few buffers for general use +static char buf[1024]; +static char buf1[sizeof(buf)]; + +// ---------------------------------------------------------------- +// PRIVATE FUNCTIONS +// ---------------------------------------------------------------- + +// Locks for debug prints +static void lock() +{ + mtx.lock(); +} + +static void unlock() +{ + mtx.unlock(); +} + +// ---------------------------------------------------------------- +// TESTS +// ---------------------------------------------------------------- + +// Test HTTP commands +void test_http_cmd() { + int profile; + char * pData; + + TEST_ASSERT(pDriver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN, + MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0); + + profile = pDriver->httpAllocProfile(); + TEST_ASSERT(profile >= 0); + + pDriver->httpSetTimeout(profile, HTTP_TIMEOUT); + + // Set up the server to talk to + TEST_ASSERT(pDriver->httpSetPar(profile, UbloxATCellularInterfaceExt::HTTP_SERVER_NAME, HTTP_ECHO_SERVER)); + + // Check HTTP head request + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_HEAD, + "/headers", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + TEST_ASSERT(strstr(buf, "Content-Length:") != NULL); + + // Check HTTP get request + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_GET, + "/get", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + TEST_ASSERT(strstr(buf, "\"http://httpbin.org/get\"") != NULL); + + // Check HTTP delete request + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_DELETE, + "/delete", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + TEST_ASSERT(strstr(buf, "\"http://httpbin.org/delete\"") != NULL); + + // Check HTTP put request (this will fail as the echo server doesn't support it) + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_PUT, + "/put", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) != NULL); + + // Check HTTP post request with data + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_POST_DATA, + "/post", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + TEST_ASSERT(strstr(buf, "\"http://httpbin.org/post\"") != NULL); + + // Check HTTP post request with a file, also checking that writing the response + // to a named file works + for (int x = 0; x < TEST_FILE_SIZE; x++) { + buf[x] = (x % 10) + 0x30; + } + pDriver->delFile("post_test.txt"); + TEST_ASSERT(pDriver->writeFile("post_test.txt", buf, TEST_FILE_SIZE) == TEST_FILE_SIZE); + + // This may fail if rsp.txt doesn't happen to be sitting around from a previous run + // so don't check the return value + pDriver->delFile("rsp.txt"); + + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_POST_FILE, + "/post", + "rsp.txt", "post_test.txt", + UbloxATCellularInterfaceExt::HTTP_CONTENT_TEXT, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + // Find the data in the response and check it + pData = strstr(buf, "\"data\": \""); + TEST_ASSERT(pData != NULL); + pData += 9; + for (int x = 0; x < TEST_FILE_SIZE; x++) { + TEST_ASSERT(*(pData + x) == (x % 10) + 0x30); + } + + // Also check that rsp.txt exists and is the same as buf + pDriver->readFile("rsp.txt", buf1, sizeof (buf1)); + memcmp(buf1, buf, sizeof (buf1)); + TEST_ASSERT(pDriver->delFile("rsp.txt")); + TEST_ASSERT(!pDriver->delFile("rsp.txt")); // Should fail + + TEST_ASSERT(pDriver->httpFreeProfile(profile)); + TEST_ASSERT(pDriver->disconnect() == 0); + // Wait for printfs to leave the building or the test result string gets messed up + wait_ms(500); +} + +// Test HTTP with TLS +void test_http_tls() { + int profile; + SocketAddress address; + + TEST_ASSERT(pDriver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN, + MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0); + + profile = pDriver->httpAllocProfile(); + TEST_ASSERT(profile >= 0); + + pDriver->httpSetTimeout(profile, HTTP_TIMEOUT); + + // Set up the server to talk to and TLS, using the IP address this time just for variety + TEST_ASSERT(pDriver->gethostbyname("amazon.com", &address) == 0); + TEST_ASSERT(pDriver->httpSetPar(profile, UbloxATCellularInterfaceExt::HTTP_IP_ADDRESS, address.get_ip_address())); + TEST_ASSERT(pDriver->httpSetPar(profile, UbloxATCellularInterfaceExt::HTTP_SECURE, "1")); + + // Check HTTP get request + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_GET, + "/", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + // This is what amazon.com returns if TLS is set + TEST_ASSERT(strstr(buf, "302 MovedTemporarily") != NULL); + + // Reset the profile and check that this now fails + TEST_ASSERT(pDriver->httpResetProfile(profile)); + TEST_ASSERT(pDriver->httpSetPar(profile, UbloxATCellularInterfaceExt::HTTP_IP_ADDRESS, address.get_ip_address())); + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profile, UbloxATCellularInterfaceExt::HTTP_GET, + "/", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + // This is what amazon.com returns if TLS is NOT set + TEST_ASSERT(strstr(buf, "301 Moved Permanently") != NULL); + + TEST_ASSERT(pDriver->httpFreeProfile(profile)); + TEST_ASSERT(pDriver->disconnect() == 0); + // Wait for printfs to leave the building or the test result string gets messed up + wait_ms(500); +} + +// Allocate max profiles +void test_alloc_profiles() { + int profiles[MAX_PROFILES]; + + TEST_ASSERT(pDriver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN, + MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0); + + // Allocate first profile and use it + profiles[0] = pDriver->httpAllocProfile(); + TEST_ASSERT(profiles[0] >= 0); + TEST_ASSERT(pDriver->httpSetPar(profiles[0], UbloxATCellularInterfaceExt::HTTP_SERVER_NAME, "developer.mbed.org")); + + // Check HTTP get request + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profiles[0], UbloxATCellularInterfaceExt::HTTP_GET, + "/media/uploads/mbed_official/hello.txt", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + TEST_ASSERT(strstr(buf, "Hello world!") != NULL); + + // Check that we stop being able to get profiles at the max number + for (int x = 1; x < sizeof (profiles) / sizeof (profiles[0]); x++) { + profiles[x] = pDriver->httpAllocProfile(); + TEST_ASSERT(profiles[0] >= 0); + } + TEST_ASSERT(pDriver->httpAllocProfile() < 0); + + // Now use the last one and check that it doesn't affect the first one + TEST_ASSERT(pDriver->httpSetPar(profiles[sizeof (profiles) / sizeof (profiles[0]) - 1], + UbloxATCellularInterfaceExt::HTTP_SERVER_NAME, HTTP_ECHO_SERVER)); + + // Check HTTP head request on last profile + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profiles[sizeof (profiles) / sizeof (profiles[0]) - 1], + UbloxATCellularInterfaceExt::HTTP_HEAD, + "/headers", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + TEST_ASSERT(strstr(buf, "Content-Length:") != NULL); + + // Check HTTP get request on first profile once more + memset(buf, 0, sizeof (buf)); + TEST_ASSERT(pDriver->httpCommand(profiles[0], UbloxATCellularInterfaceExt::HTTP_GET, + "/media/uploads/mbed_official/hello.txt", + NULL, NULL, 0, NULL, + buf, sizeof (buf)) == NULL); + tr_debug("Received: %s", buf); + TEST_ASSERT(strstr(buf, "Hello world!") != NULL); + + // Free the profiles again + for (int x = 0; x < sizeof (profiles) / sizeof (profiles[0]); x++) { + TEST_ASSERT(pDriver->httpFreeProfile(profiles[x])); + } + + TEST_ASSERT(pDriver->disconnect() == 0); + // Wait for printfs to leave the building or the test result string gets messed up + wait_ms(500); +} + +// ---------------------------------------------------------------- +// TEST ENVIRONMENT +// ---------------------------------------------------------------- + +// Setup the test environment +utest::v1::status_t test_setup(const size_t number_of_cases) { + // Setup Greentea with a timeout + GREENTEA_SETUP(540, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +// Test cases +Case cases[] = { + Case("HTTP commands", test_http_cmd), + Case("HTTP with TLS", test_http_tls), + Case("Alloc max profiles", test_alloc_profiles) +}; + +Specification specification(test_setup, cases); + +// ---------------------------------------------------------------- +// MAIN +// ---------------------------------------------------------------- + +int main() { + mbed_trace_init(); + + mbed_trace_mutex_wait_function_set(lock); + mbed_trace_mutex_release_function_set(unlock); + + // Run tests + return !Harness::run(specification); +} + +// End Of File +