ublox-at-cellular-interface-ext
Dependencies: ublox-at-cellular-interface
TESTS/unit_tests/http/main.cpp
- Committer:
- fahim.alavi@u-blox.com
- Date:
- 2019-01-30
- Revision:
- 18:071ae6c6e581
- Parent:
- 11:3631f62bb359
- Child:
- 19:ee06f3b2b078
File content as of revision 18:071ae6c6e581:
#include "mbed.h" #include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" #include "UbloxATCellularInterfaceExt.h" #include "UDPSocket.h" #ifdef FEATURE_COMMON_PAL #include "mbed_trace.h" #define TRACE_GROUP "TEST" #else #define tr_debug(format, ...) debug(format "\n", ## __VA_ARGS__) #define tr_info(format, ...) debug(format "\n", ## __VA_ARGS__) #define tr_warn(format, ...) debug(format "\n", ## __VA_ARGS__) #define tr_error(format, ...) debug(format "\n", ## __VA_ARGS__) #endif 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\"" // } //} // Whether debug trace is on #ifndef MBED_CONF_APP_DEBUG_ON # define MBED_CONF_APP_DEBUG_ON false #endif // The credentials of the SIM in the board. #ifndef MBED_CONF_APP_DEFAULT_PIN // Note: if PIN is enabled on your SIM, you must define the PIN // for your SIM jere (e.g. using mbed_app.json to do so). # define MBED_CONF_APP_DEFAULT_PIN "0000" #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 20000 // 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 // ---------------------------------------------------------------- #ifdef FEATURE_COMMON_PAL // Lock for debug prints static Mutex mtx; #endif // An instance of the cellular interface static UbloxATCellularInterfaceExt *pDriver = new UbloxATCellularInterfaceExt(MDMTXD, MDMRXD, MBED_CONF_UBLOX_CELL_BAUD_RATE, MBED_CONF_APP_DEBUG_ON); // A few buffers for general use static char buf[2048]; static char buf1[sizeof(buf)]; // ---------------------------------------------------------------- // PRIVATE FUNCTIONS // ---------------------------------------------------------------- #ifdef FEATURE_COMMON_PAL // Locks for debug prints static void lock() { mtx.lock(); } static void unlock() { mtx.unlock(); } #endif // ---------------------------------------------------------------- // 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, "formData=0123456789", 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, "503 Service Temporarily Unavailable") != 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, "raw.githubusercontent.com")); TEST_ASSERT(pDriver->httpSetPar(profiles[0], UbloxATCellularInterfaceExt::HTTP_SECURE, "1")); // Check HTTP get request memset(buf, 0, sizeof (buf)); TEST_ASSERT(pDriver->httpCommand(profiles[0], UbloxATCellularInterfaceExt::HTTP_GET, "/u-blox/mbed-os/master/features/cellular/mbed_lib.json", NULL, NULL, 0, NULL, buf, sizeof (buf)) == NULL); tr_debug("Received: %s", buf); TEST_ASSERT(strstr(buf, "Radio access technology to use. Value in integer: GSM=0, GSM_COMPACT=1, UTRAN=2, EGPRS=3, HSDPA=4, HSUPA=5, HSDPA_HSUPA=6, E_UTRAN=7, CATM1=8 ,NB1=9") != 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, "/u-blox/mbed-os/master/features/cellular/mbed_lib.json", NULL, NULL, 0, NULL, buf, sizeof (buf)) == NULL); tr_debug("Received: %s", buf); TEST_ASSERT(strstr(buf, "Radio access technology to use. Value in integer: GSM=0, GSM_COMPACT=1, UTRAN=2, EGPRS=3, HSDPA=4, HSUPA=5, HSDPA_HSUPA=6, E_UTRAN=7, CATM1=8 ,NB1=9") != 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), #ifndef TARGET_UBLOX_C027 // C027 doesn't support TLS Case("HTTP with TLS", test_http_tls), #endif Case("Alloc max profiles", test_alloc_profiles) }; Specification specification(test_setup, cases); // ---------------------------------------------------------------- // MAIN // ---------------------------------------------------------------- int main() { #ifdef FEATURE_COMMON_PAL mbed_trace_init(); mbed_trace_mutex_wait_function_set(lock); mbed_trace_mutex_release_function_set(unlock); #endif // Run tests return !Harness::run(specification); } // End Of File