commit 6e8a844541a2677ea9f3a9ee3e993073a0a764e2 parent 4f9ffc179d27eb03562bbbe3950f233fb22736cb Author: JohnMcPMS <johnmcp@microsoft.com> Date: Wed, 17 Mar 2021 21:33:23 -0700 Remove tests due to credscan false positive (#805) Diffstat:
221 files changed, 0 insertions(+), 41730 deletions(-)
diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/.gitignore b/src/cpprestsdk/cpprestsdk/Release/tests/.gitignore @@ -1 +0,0 @@ -*.cmake diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/CMakeLists.txt @@ -1,7 +0,0 @@ -set(UnitTestpp_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common/UnitTestpp) -set(Utilities_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common/utilities/include) - -include_directories (${UnitTestpp_INCLUDE_DIR} ${Utilities_INCLUDE_DIR}) - -add_subdirectory(common) -add_subdirectory(functional) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/common/CMakeLists.txt @@ -1,3 +0,0 @@ -add_subdirectory(utilities) -add_subdirectory(UnitTestpp) -add_subdirectory(TestRunner) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/CMakeLists.txt @@ -1,67 +0,0 @@ -if (WIN32) - if (WINDOWS_STORE OR WINDOWS_PHONE) - add_definitions(-DWINRT_TEST_RUNNER -D_CONSOLE) - else() - add_definitions(-DDESKTOP_TEST_RUNNER) - endif() -endif() - -add_executable(test_runner test_runner.cpp test_module_loader.cpp) -target_link_libraries(test_runner PRIVATE unittestpp ${CMAKE_DL_LIBS}) -if (WIN32) - target_sources(test_runner PRIVATE test_runner.manifest) -endif() - -if(BUILD_SHARED_LIBS AND NOT TEST_LIBRARY_TARGET_TYPE STREQUAL "OBJECT") -elseif(APPLE) - target_link_libraries(test_runner PRIVATE - -Wl,-force_load httpclient_test - -Wl,-force_load json_test - -Wl,-force_load uri_test - -Wl,-force_load pplx_test - -Wl,-force_load httplistener_test - -Wl,-force_load streams_test - -Wl,-force_load utils_test - ) -elseif(UNIX) - target_link_libraries(test_runner PRIVATE - -Wl,--whole-archive - httpclient_test - json_test - uri_test - pplx_test - httplistener_test - streams_test - utils_test - -Wl,--no-whole-archive - ) -else() - # In order to achieve --whole-archive on windows, we link all the test files into the test_runner directly - # This means that the tests themselves must be created as "OBJECT" libraries - target_sources(test_runner PRIVATE - $<TARGET_OBJECTS:httpclient_test> - $<TARGET_OBJECTS:json_test> - $<TARGET_OBJECTS:uri_test> - $<TARGET_OBJECTS:pplx_test> - $<TARGET_OBJECTS:streams_test> - $<TARGET_OBJECTS:utils_test> - ) - if(NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) - target_sources(test_runner PRIVATE $<TARGET_OBJECTS:httplistener_test>) - endif() - target_link_libraries(test_runner PRIVATE - common_utilities - httptest_utilities - cpprest - ) - if(TARGET websockettest_utilities) - target_link_libraries(test_runner PRIVATE websockettest_utilities) - endif() - if(CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") - cpprest_find_websocketpp() - target_link_libraries(test_runner PRIVATE cpprestsdk_websocketpp_internal) - endif() - if (WINDOWS_STORE) - target_link_libraries(test_runner PRIVATE ucrtd.lib vcruntimed.lib vccorlibd.lib msvcrtd.lib msvcprtd.lib concrtd.lib RuntimeObject.lib) - endif() -endif() diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_module_loader.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_module_loader.cpp @@ -1,166 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - */ -#ifdef WIN32 -#include <Windows.h> -#else -#include "dlfcn.h" -#include <boost/filesystem.hpp> -#endif - -#include "test_module_loader.h" -#include <iostream> - -class test_module -{ -public: - test_module(const std::string& dllName) : m_dllName(dllName), m_handle(nullptr) {} - - GetTestsFunc get_test_list() - { -#if defined(_WIN32) - return (GetTestsFunc)GetProcAddress(m_handle, "GetTestList"); -#else - auto ptr = dlsym(m_handle, "GetTestList"); - if (ptr == nullptr) - { - std::cerr << "couldn't find GetTestList" - << -#ifdef __APPLE__ - " " << dlerror() << -#endif - std::endl; - } - return (GetTestsFunc)ptr; -#endif - } - - unsigned long load() - { - if (m_handle == nullptr) - { -#if defined(_WIN32) - // Make sure ends in .dll - if (*(m_dllName.end() - 1) != 'l' || *(m_dllName.end() - 2) != 'l' || *(m_dllName.end() - 3) != 'd' || - *(m_dllName.end() - 4) != '.') - { - return (unsigned long)-1; - } - m_handle = LoadLibraryA(m_dllName.c_str()); - if (m_handle == nullptr) - { - return GetLastError(); - } - return 0; -#else -#ifdef __APPLE__ - auto exe_directory = getcwd(nullptr, 0); - auto path = std::string(exe_directory) + "/" + m_dllName; - free(exe_directory); -#else - auto path = boost::filesystem::initial_path().string() + "/" + m_dllName; -#endif - - m_handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL); - if (m_handle == nullptr) - { - std::cerr << std::string(dlerror()) << std::endl; - return -1; - } - return 0; -#endif - } - return 0; - } - - unsigned long unload() - { - if (m_handle != nullptr) - { -#if defined(_WIN32) - if (!FreeLibrary(m_handle)) - { - return GetLastError(); - } - m_handle = nullptr; - return 0; -#else - if (dlclose(m_handle) != 0) - { - std::cerr << std::string(dlerror()) << std::endl; - return -1; - } - m_handle = nullptr; - return 0; -#endif - } - return 0; - } - -private: - const std::string m_dllName; - -#if defined(_WIN32) - HMODULE m_handle; -#else - void* m_handle; -#endif - - test_module(const test_module&) = delete; - test_module& operator=(const test_module&) = delete; -}; - -test_module_loader::test_module_loader() {} - -test_module_loader::~test_module_loader() -{ - for (auto iter = m_modules.begin(); iter != m_modules.end(); ++iter) - { - iter->second->unload(); - delete iter->second; - } -} - -unsigned long test_module_loader::load(const std::string& dllName) -{ - // Check if the module is already loaded. - if (m_modules.find(dllName) != m_modules.end()) - { - return 0; - } - - test_module* pModule; - pModule = new test_module(dllName); - - // Load dll. - const unsigned long error_code = pModule->load(); - if (error_code != 0) - { - delete pModule; - return error_code; - } - else - { - m_modules[dllName] = pModule; - } - return 0; -} - -UnitTest::TestList g_list; - -UnitTest::TestList& test_module_loader::get_test_list(const std::string& dllName) -{ - GetTestsFunc getTestsFunc = m_modules[dllName]->get_test_list(); - - // If there is no GetTestList function then it must be a dll without any tests. - // Simply return an empty TestList. - if (getTestsFunc == nullptr) - { - return g_list; - } - - return getTestsFunc(); -} diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_module_loader.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_module_loader.h @@ -1,40 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - ***/ - -#ifndef INCLUDED_TEST_MODULE_LOADER -#define INCLUDED_TEST_MODULE_LOADER - -#include "unittestpp.h" -#include <string> - -// Exported function from all test dlls. -typedef UnitTest::TestList&(__cdecl* GetTestsFunc)(); - -// Interface to implement on each platform to be be able to load/unload and call global functions. -class test_module; - -// Handles organizing all test binaries and using the correct module loader. -class test_module_loader -{ -public: - test_module_loader(); - ~test_module_loader(); - - // Does't complain if module with same name is already loaded. - unsigned long load(const std::string& dllName); - - // Module must have already been loaded. - UnitTest::TestList& get_test_list(const std::string& dllName); - -private: - test_module_loader(const test_module_loader&) = delete; - test_module_loader& operator=(const test_module_loader&) = delete; - - std::map<std::string, test_module*> m_modules; -}; - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_runner.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_runner.cpp @@ -1,643 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ -// TestRunner.cpp : Defines the entry point for the console application. -// - -#include <algorithm> -#include <iostream> -#include <map> -#include <regex> -#include <vector> - -#ifdef _WIN32 -#include <conio.h> - -#include <Windows.h> -#else -#include <unistd.h> -#ifdef __APPLE__ -#include <dirent.h> -#else -#include <boost/filesystem.hpp> -#endif -#endif - -#include "../UnitTestpp/src/GlobalSettings.h" -#include "../UnitTestpp/src/TestReporterStdout.h" -#include "../UnitTestpp/src/TimeHelpers.h" -#include "test_module_loader.h" - -static void print_help() -{ - std::cout - << "Usage: testrunner.exe <test_binaries> [/list] [/listproperties] [/noignore] [/breakonerror] [/detectleaks]" - << std::endl; - std::cout << " [/name:<test_name>] [/select:@key=value] [/loop:<num_times>]" << std::endl; - std::cout << std::endl; - std::cout << " /list List all the names of the test_binaries and their" << std::endl; - std::cout << " test cases." << std::endl; - std::cout << std::endl; - std::cout << " /listproperties List all the names of the test binaries, test cases, and" << std::endl; - std::cout << " test properties." << std::endl; - std::cout << std::endl; - std::cout << " /breakonerror Break into the debugger when a failure is encountered." << std::endl; - std::cout << " /detectleaks Turns CRT leak detection and prints any leaks, Windows only." << std::endl; - std::cout << std::endl; - std::cout << " /name:<test_name> Run only test cases with matching name. Can contain the" << std::endl; - std::cout << " wildcard '*' character." << std::endl; - std::cout << std::endl; - std::cout << " /noignore Include tests even if they have the 'Ignore' property set" << std::endl; - std::cout << std::endl; - std::cout << " /select:@key=value Filter by the value of a particular test property." << std::endl; - std::cout << std::endl; - std::cout << " /loop:<num_times> Run test cases a specified number of times." << std::endl; - - std::cout << std::endl; - std::cout << "Can also specify general global settings with the following:" << std::endl; - std::cout << " /global_key:global_value OR /global_key" << std::endl << std::endl; -} - -static std::string to_lower(const std::string& str) -{ - std::string lower; - for (auto iter = str.begin(); iter != str.end(); ++iter) - { - lower.push_back((char)tolower(*iter)); - } - return lower; -} - -static std::vector<std::string> get_files_in_directory() -{ - std::vector<std::string> files; - -#ifdef _WIN32 - - char exe_directory_buffer[MAX_PATH]; - GetModuleFileNameA(NULL, exe_directory_buffer, MAX_PATH); - std::string exe_directory = to_lower(exe_directory_buffer); - auto location = exe_directory.rfind("\\"); - if (location != std::string::npos) - { - exe_directory.erase(location + 1); - } - else - { - std::cout << "Could not determine execution directory" << std::endl; - exit(-1); - } - - exe_directory.append("*"); - WIN32_FIND_DATAA findFileData; - HANDLE hFind = FindFirstFileA(exe_directory.c_str(), &findFileData); - if (hFind != INVALID_HANDLE_VALUE && !(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - files.push_back(findFileData.cFileName); - } - while (FindNextFileA(hFind, &findFileData) != 0) - { - if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - files.push_back(findFileData.cFileName); - } - } - FindClose(hFind); - -#elif defined(__APPLE__) - auto exe_directory = getcwd(nullptr, 0); - - DIR* dir = opendir(exe_directory); - free(exe_directory); - - if (dir != nullptr) - { - struct dirent* ent = readdir(dir); - while (ent != nullptr) - { - if (ent->d_type == DT_REG) - { - files.push_back(ent->d_name); - } - ent = readdir(dir); - } - closedir(dir); - } -#else - using namespace boost::filesystem; - - auto exe_directory = initial_path().string(); - for (auto it = directory_iterator(path(exe_directory)); it != directory_iterator(); ++it) - { - if (is_regular_file(*it)) - { - files.push_back(it->path().filename().string()); - } - } -#endif - - return files; -} - -static std::string replace_wildcard_for_regex(const std::string& str) -{ - std::string result; - for (auto iter = str.begin(); iter != str.end(); ++iter) - { - if (*iter == '*') - { - result.push_back('.'); - } - result.push_back(*iter); - } - return result; -} - -static std::vector<std::string> get_matching_binaries(const std::string& dllName) -{ - std::vector<std::string> matchingFiles; - - // If starts with .\ remove it. - std::string expandedDllName(dllName); - if (expandedDllName.size() > 2 && expandedDllName[0] == '.' && expandedDllName[1] == '\\') - { - expandedDllName = expandedDllName.substr(2); - } - - // Escape any '.' - size_t oldLocation = 0; - size_t location = expandedDllName.find(".", oldLocation); - while (location != std::string::npos) - { - expandedDllName.insert(expandedDllName.find(".", oldLocation), "\\"); - oldLocation = location + 2; - location = expandedDllName.find(".", oldLocation); - } - - // Replace all '*' in dllName with '.*' - expandedDllName = replace_wildcard_for_regex(expandedDllName); - - std::vector<std::string> allFiles = get_files_in_directory(); - - // Filter out any files that don't match. - std::regex dllRegex(expandedDllName, std::regex_constants::icase); - - for (auto iter = allFiles.begin(); iter != allFiles.end(); ++iter) - { - if (std::regex_match(*iter, dllRegex)) - { - matchingFiles.push_back(*iter); - } - } - - return matchingFiles; -} - -static std::multimap<std::string, std::string> g_properties; -static std::vector<std::string> g_test_binaries; -static int g_individual_test_timeout = 60000 * 3; - -static int parse_command_line(int argc, char** argv) -{ - for (int i = 1; i < argc; ++i) - { - std::string arg(argv[i]); - arg = to_lower(arg); - - if (arg.compare("/?") == 0) - { - print_help(); - return -1; - } - else if (arg.find("/") == 0) - { - if (arg.find("/select:@") == 0) - { - std::string prop_asgn = std::string(argv[i]).substr(std::string("/select:@").size()); - auto eqsgn = prop_asgn.find('='); - if (eqsgn < prop_asgn.size()) - { - auto key = prop_asgn.substr(0, eqsgn); - auto value = prop_asgn.substr(eqsgn + 1); - g_properties.insert(std::make_pair(key, value)); - } - else - { - g_properties.insert(std::make_pair(prop_asgn, "*")); - } - } - else if (arg.find(":") != std::string::npos) - { - const size_t index = arg.find(":"); - const std::string key = std::string(argv[i]).substr(1, index - 1); - const std::string value = std::string(argv[i]).substr(index + 1); - UnitTest::GlobalSettings::Add(key, value); - } - else - { - UnitTest::GlobalSettings::Add(arg.substr(1), std::string{}); - } - } - else if (arg.find("/debug") == 0) - { - printf("Attach debugger now...\n"); - int temp; - std::cin >> temp; - } - else - { - g_test_binaries.push_back(arg); - } - } - - return 0; -} - -static bool matched_properties(const UnitTest::TestProperties& test_props) -{ - // TestRunner can only execute either desktop or winrt tests, but not both. - // This starts with visual studio versions after VS 2012. -#if defined(_MSC_VER) && (_MSC_VER >= 1800) -#ifdef WINRT_TEST_RUNNER - UnitTest::GlobalSettings::Add("winrt", std::string{}); -#elif defined DESKTOP_TEST_RUNNER - UnitTest::GlobalSettings::Add("desktop", std::string{}); -#endif -#endif - - // The 'Require' property on a test case is special. - // It requires a certain global setting to be fulfilled to execute. - if (test_props.Has("Requires")) - { - const std::string requires = test_props.Get("Requires"); - std::vector<std::string> requirements; - - // Can be multiple requirements, a semi colon seperated list - std::string::size_type pos = requires.find_first_of(';'); - std::string::size_type last_pos = 0; - while (pos != std::string::npos) - { - requirements.push_back(requires.substr(last_pos, pos - last_pos)); - last_pos = pos + 1; - pos = requires.find_first_of(';', last_pos); - } - requirements.push_back(requires.substr(last_pos)); - for (auto iter = requirements.begin(); iter != requirements.end(); ++iter) - { - if (!UnitTest::GlobalSettings::Has(to_lower(*iter))) - { - return false; - } - } - } - - if (g_properties.size() == 0) return true; - - // All the properties specified at the cmd line act as a 'filter'. - for (auto iter = g_properties.begin(); iter != g_properties.end(); ++iter) - { - auto name = iter->first; - auto value = iter->second; - if (test_props.Has(name) && (value == "*" || test_props[name] == value)) - { - return true; - } - } - return false; -} - -// Functions to list all the test cases and their properties. -static void handle_list_option(bool listProperties, const UnitTest::TestList& tests, const std::regex& nameRegex) -{ - UnitTest::Test* pTest = tests.GetFirst(); - while (pTest != nullptr) - { - std::string fullTestName = pTest->m_details.suiteName; - fullTestName.append(":"); - fullTestName.append(pTest->m_details.testName); - - if (matched_properties(pTest->m_properties) && std::regex_match(fullTestName, nameRegex)) - { - std::cout << " " << fullTestName << std::endl; - if (listProperties) - { - std::for_each(pTest->m_properties.begin(), - pTest->m_properties.end(), - [&](const std::pair<std::string, std::string> key_value) { - std::cout << " " << key_value.first << ": " << key_value.second << std::endl; - }); - } - } - pTest = pTest->m_nextTest; - } -} - -static void ChangeConsoleTextColorToRed() -{ -#if defined(__cplusplus_winrt) -#elif defined(_WIN32) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0004 | 0x0008); -#else - std::cout << "\033[1;31m"; -#endif -} - -static void ChangeConsoleTextColorToGreen() -{ -#if defined(__cplusplus_winrt) -#elif defined(_WIN32) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0002 | 0x0008); -#else - std::cout << "\033[1;32m"; -#endif -} - -static void ChangeConsoleTextColorToGrey() -{ -#if defined(__cplusplus_winrt) -#elif defined(_WIN32) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN); -#else - std::cout << "\033[0m"; -#endif -} - -bool IsTestIgnored(UnitTest::Test* pTest) -{ - if (pTest->m_properties.Has("Ignore")) return true; -#ifdef _WIN32 - if (pTest->m_properties.Has("Ignore:Windows")) return true; -#elif defined(__APPLE__) - if (pTest->m_properties.Has("Ignore:Apple")) return true; -#elif (defined(ANDROID) || defined(__ANDROID__)) - if (pTest->m_properties.Has("Ignore:Android")) return true; -#else - if (pTest->m_properties.Has("Ignore:Linux")) return true; -#endif - return false; -} - -typedef std::map<std::string, UnitTest::TestList> testlist_t; - -void list_test_options(testlist_t& testlists) -{ - std::regex nameRegex; - - if (UnitTest::GlobalSettings::Has("name")) - { - nameRegex = replace_wildcard_for_regex(UnitTest::GlobalSettings::Get("name")); - } - else - { - nameRegex = std::regex(".*"); - } - - bool listProperties = UnitTest::GlobalSettings::Has("listproperties"); - - for (auto& test_p : testlists) - { - std::cout << "=== Showing options for " << test_p.first << " ===" << std::endl; - handle_list_option(listProperties, test_p.second, nameRegex); - } -} - -testlist_t load_all_tests(test_module_loader& module_loader) -{ - // Remember where each list of tests came from. - testlist_t testlists; - - // Retrieve the static tests and clear for dll loading. - testlists.insert({"<static>", UnitTest::GetTestList()}); - UnitTest::GetTestList().Clear(); - - // Cycle through all the test binaries and load them - for (auto& binary_names : g_test_binaries) - { - std::vector<std::string> matchingBinaries = get_matching_binaries(binary_names); - if (matchingBinaries.empty()) - { - ChangeConsoleTextColorToRed(); - std::cout << "Pattern '" << binary_names << "' not found." << std::endl; - ChangeConsoleTextColorToGrey(); - } - for (auto& binary : matchingBinaries) - { - unsigned long error_code = module_loader.load(binary); - if (error_code != 0) - { - // Only omit an error if a wildcard wasn't used. - if (binary_names.find('*') == std::string::npos) - { - ChangeConsoleTextColorToRed(); - std::cout << "Error loading " << binary << ": " << error_code << std::endl; - ChangeConsoleTextColorToGrey(); - - std::exit(error_code); - } - else - { - continue; - } - } - std::cout << "Loaded " << binary << "..." << std::endl; - - // Store the loaded binary into the test list map - testlists.insert({binary, UnitTest::GetTestList()}); - UnitTest::GetTestList().Clear(); - } - } - - return testlists; -} - -void run_all_tests(UnitTest::TestRunner& testRunner, testlist_t& testlists) -{ - int numTimesToRun = 1; - if (UnitTest::GlobalSettings::Has("loop")) - { - std::istringstream strstream(UnitTest::GlobalSettings::Get("loop")); - strstream >> numTimesToRun; - } - - const bool include_ignored_tests = UnitTest::GlobalSettings::Has("noignore"); - - for (int i = 0; i < numTimesToRun; ++i) - { - for (auto& test_p : testlists) - { - std::cout << "=== Running tests from: " << test_p.first << " ===" << std::endl; - UnitTest::TestList& tests = test_p.second; - - std::regex nameRegex(".*"); - - if (UnitTest::GlobalSettings::Has("name")) - { - nameRegex = replace_wildcard_for_regex(UnitTest::GlobalSettings::Get("name")); - } - testRunner.RunTestsIf(tests, - [&](UnitTest::Test* pTest) -> bool { - // Combine suite and test name - std::string fullTestName = pTest->m_details.suiteName; - fullTestName.append(":"); - fullTestName.append(pTest->m_details.testName); - - if (IsTestIgnored(pTest) && !include_ignored_tests) - return false; - else - return matched_properties(pTest->m_properties) && - std::regex_match(fullTestName, nameRegex); - }, - g_individual_test_timeout); - } - } -} - -#if defined(__cplusplus_winrt) -#include "ROApi.h" -#endif - -int main(int argc, char* argv[]) -{ -#if defined(__cplusplus_winrt) - Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); -#elif defined(_WIN32) - // Add standard error as output as well. - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_WNDW | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_WNDW | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); - - // The test runner built with WinRT support might be used on a pre Win8 machine. - // Obviously in that case WinRT test cases can't run, but non WinRT ones should be - // fine. So dynamically try to call RoInitialize/RoUninitialize. - HMODULE hComBase = LoadLibrary(L"combase.dll"); - if (hComBase != nullptr) - { - typedef HRESULT(WINAPI * RoInit)(int); - RoInit roInitFunc = (RoInit)GetProcAddress(hComBase, "RoInitialize"); - if (roInitFunc != nullptr) - { - roInitFunc(1); // RO_INIT_MULTITHREADED - } - } - - struct console_restorer - { - CONSOLE_SCREEN_BUFFER_INFO m_originalConsoleInfo; - console_restorer() { GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &m_originalConsoleInfo); } - ~console_restorer() - { - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), m_originalConsoleInfo.wAttributes); - } - } local; -#endif - - if (parse_command_line(argc, argv) != 0) - { - return -1; - } - - if (g_test_binaries.empty()) - { - std::cout << "Warning: no test binaries were specified" << std::endl; - } - - int totalTestCount = 0, failedTestCount = 0; - std::vector<std::string> failedTests; - UnitTest::TestReporterStdout testReporter; - - bool breakOnError = false; - if (UnitTest::GlobalSettings::Has("breakonerror")) - { - breakOnError = true; - } - - // The list_test_options() function determines if list or listProperties. - bool listOption = false; - if (UnitTest::GlobalSettings::Has("list")) - { - listOption = true; - } - if (UnitTest::GlobalSettings::Has("listproperties")) - { - listOption = true; - } -#ifdef _WIN32 - if (UnitTest::GlobalSettings::Has("detectleaks")) - { - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - } -#endif - - // Start timer. - UnitTest::Timer timer; - timer.Start(); - - test_module_loader module_loader; - - testlist_t testlists = load_all_tests(module_loader); - - if (listOption) - { - list_test_options(testlists); - return 0; - } - - // Run test cases - UnitTest::TestRunner testRunner(testReporter, breakOnError); - - run_all_tests(testRunner, testlists); - - totalTestCount += testRunner.GetTestResults()->GetTotalTestCount(); - failedTestCount += testRunner.GetTestResults()->GetFailedTestCount(); - if (totalTestCount == 0) - { - std::cout << "No tests were run. Check the command line syntax (try 'TestRunner.exe /help')" << std::endl; - } - else - { - if (testRunner.GetTestResults()->GetFailedTestCount() > 0) - { - ChangeConsoleTextColorToRed(); - const std::vector<std::string>& failed = testRunner.GetTestResults()->GetFailedTests(); - std::for_each(failed.begin(), failed.end(), [](const std::string& failedTest) { - std::cout << "**** " << failedTest << " FAILED ****" << std::endl << std::endl; - std::fflush(stdout); - }); - ChangeConsoleTextColorToGrey(); - } - else - { - ChangeConsoleTextColorToGreen(); - std::cout << "All test cases PASSED" << std::endl << std::endl; - ChangeConsoleTextColorToGrey(); - } - const std::vector<std::string>& newFailedTests = testRunner.GetTestResults()->GetFailedTests(); - failedTests.insert(failedTests.end(), newFailedTests.begin(), newFailedTests.end()); - - const double elapsedTime = timer.GetTimeInMs(); - std::cout << "Finished running all " << totalTestCount << " tests." << std::endl - << "Took " << elapsedTime << "ms" << std::endl; - } - -#if defined(__cplusplus_winrt) -#elif defined(_WIN32) - if (hComBase != nullptr) - { - typedef void(WINAPI * RoUnInit)(); - RoUnInit roUnInitFunc = (RoUnInit)GetProcAddress(hComBase, "RoUninitialize"); - if (roUnInitFunc != nullptr) - { - roUnInitFunc(); - } - FreeLibrary(hComBase); - } -#endif - - return failedTestCount; -} diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_runner.manifest b/src/cpprestsdk/cpprestsdk/Release/tests/common/TestRunner/test_runner.manifest @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <!--This Id value indicates the application supports Windows Vista functionality --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - <!--This Id value indicates the application supports Windows 7 functionality--> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <!--This Id value indicates the application supports Windows 8 functionality--> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - <!--This Id value indicates the application supports Windows 8.1 functionality--> - <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> - <!--This Id value indicates the application supports Windows 10 functionality --> - <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> - </application> - </compatibility> -</assembly> diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/CMakeLists.txt @@ -1,59 +0,0 @@ -set(UT_SOURCES - src/AssertException.cpp - src/CompositeTestReporter.cpp - src/CurrentTest.cpp - src/DeferredTestReporter.cpp - src/DeferredTestResult.cpp - src/GlobalSettings.cpp - src/MemoryOutStream.cpp - src/ReportAssert.cpp - src/Test.cpp - src/TestDetails.cpp - src/TestList.cpp - src/TestReporter.cpp - src/TestReporterStdout.cpp - src/TestResults.cpp - src/TestRunner.cpp - src/XmlTestReporter.cpp - ) - -set(TEST_SOURCES - src/tests/TestAssertHandler.cpp - src/tests/TestCheckMacros.cpp - src/tests/TestChecks.cpp - src/tests/TestCompositeTestReporter.cpp - src/tests/TestCurrentTest.cpp - src/tests/TestDeferredTestReporter.cpp - src/tests/TestMemoryOutStream.cpp - src/tests/TestTest.cpp - src/tests/TestTestList.cpp - src/tests/TestTestMacros.cpp - src/tests/TestTestResults.cpp - src/tests/TestTestRunner.cpp - src/tests/TestTestSuite.cpp - src/tests/TestUnitTestPP.cpp - src/tests/TestXmlTestReporter.cpp - ) - -if(UNIX) - list(APPEND UT_SOURCES - src/Posix/SignalTranslator.cpp - src/Posix/TimeHelpers.cpp - ) -elseif(WIN32) - list(APPEND UT_SOURCES src/Win32/TimeHelpers.cpp) - - add_definitions(-DWIN32 -D_USRDLL -D_CRT_SECURE_NO_DEPRECATE -DUNITTEST_DLL_EXPORT) -endif() - -add_library(unittestpp ${UT_SOURCES}) -target_link_libraries(unittestpp PUBLIC cpprest) - -if(UNIX) - cpprest_find_boost() - target_link_libraries(unittestpp PUBLIC cpprestsdk_boost_internal) -endif() -target_link_libraries(unittestpp ${ANDROID_STL_FLAGS}) - -target_include_directories(unittestpp PRIVATE src) -target_include_directories(unittestpp PUBLIC .) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/COPYING b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/COPYING @@ -1,19 +0,0 @@ -Copyright(c) 2006 Noel Llopis and Charles Nicholson - - Permission is hereby granted, - free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), - to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and / or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions : - - The above copyright notice and this permission notice shall be included in all copies - or - substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", - WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/ThirdPartyNotices.txt b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/ThirdPartyNotices.txt @@ -1,20 +0,0 @@ ------------------ ThirdPartyNotices---------------------------------------------- - -This file is based on or incorporates material from the UnitTest++ r30 open source project.Microsoft is not the original author of this code but has modified it and is licensing the code under the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, whether by implication, estoppel or otherwise. - -UnitTest++ r30 - -Copyright (c) 2006 Noel Llopis and Charles Nicholson -Portions Copyright (c) Microsoft Corporation - -All Rights Reserved. - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - --------------End of ThirdPartyNotices--------------------------------------- diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/config.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/config.h @@ -1,83 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_CONFIG_H -#define UNITTEST_CONFIG_H - -// Standard defines documented here: http://predef.sourceforge.net - -#if defined(_MSC_VER) -#pragma warning(disable : 4702) // unreachable code -#pragma warning(disable : 4722) // destructor never returns, potential memory leak - -#if (_MSC_VER == 1200) // VC6 -#pragma warning(disable : 4786) -#pragma warning(disable : 4290) -#endif - -#ifdef _USRDLL -#define UNITTEST_WIN32_DLL -#endif -#define UNITTEST_WIN32 -#endif - -#if defined(unix) || defined(__unix__) || defined(__unix) || defined(linux) || defined(__APPLE__) || \ - defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) -#define UNITTEST_POSIX -#endif - -#if defined(__MINGW32__) -#define UNITTEST_MINGW -#endif - -// MemoryOutStream is a custom reimplementation of parts of std::ostringstream. -// Uncomment this line to have MemoryOutStream implemented in terms of std::ostringstream. -// This is useful if you are using the CHECK macros on objects that have something like this defined: -// std::ostringstream& operator<<(std::ostringstream& s, const YourObject& value) - -#define UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -// DeferredTestReporter uses the STL to collect test results for subsequent export by reporters like -// XmlTestReporter. If you don't want to use this functionality, uncomment this line and no STL -// headers or code will be compiled into UnitTest++ - -//#define UNITTEST_NO_DEFERRED_REPORTER - -// By default, asserts that you report via UnitTest::ReportAssert() abort the current test and -// continue to the next one by throwing an exception, which unwinds the stack naturally, destroying -// all auto variables on its way back down. If you don't want to (or can't) use exceptions for your -// platform/compiler, uncomment this line. All exception code will be removed from UnitTest++, -// assert recovery will be done via setjmp/longjmp, and NO correct stack unwinding will happen! - -//#define UNITTEST_NO_EXCEPTIONS - -#include <cpprest/details/basic_types.h> -#endif- \ No newline at end of file diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/AssertException.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/AssertException.cpp @@ -1,44 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifndef UNITTEST_NO_EXCEPTIONS - -namespace UnitTest -{ -AssertException::AssertException() {} - -AssertException::~AssertException() throw() {} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/AssertException.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/AssertException.h @@ -1,54 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_ASSERTEXCEPTION_H -#define UNITTEST_ASSERTEXCEPTION_H - -#include "../config.h" -#ifndef UNITTEST_NO_EXCEPTIONS - -#include "HelperMacros.h" -#include <exception> - -namespace UnitTest -{ -class AssertException : public std::exception -{ -public: - UNITTEST_LINKAGE AssertException(); - UNITTEST_LINKAGE virtual ~AssertException() throw(); -}; - -} // namespace UnitTest - -#endif - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CheckMacros.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CheckMacros.h @@ -1,311 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_CHECKMACROS_H -#define UNITTEST_CHECKMACROS_H - -#include "AssertException.h" -#include "Checks.h" -#include "CurrentTest.h" -#include "ExceptionMacros.h" -#include "HelperMacros.h" -#include "MemoryOutStream.h" -#include "ReportAssertImpl.h" -#include "TestDetails.h" -#include <stdarg.h> - -#ifdef CHECK -#error UnitTest++ redefines CHECK -#endif - -#ifdef CHECK_EQUAL -#error UnitTest++ redefines CHECK_EQUAL -#endif - -#ifdef CHECK_CLOSE -#error UnitTest++ redefines CHECK_CLOSE -#endif - -#ifdef CHECK_ARRAY_EQUAL -#error UnitTest++ redefines CHECK_ARRAY_EQUAL -#endif - -#ifdef CHECK_ARRAY_CLOSE -#error UnitTest++ redefines CHECK_ARRAY_CLOSE -#endif - -#ifdef CHECK_ARRAY2D_CLOSE -#error UnitTest++ redefines CHECK_ARRAY2D_CLOSE -#endif - -#ifdef VERIFY_IS_TRUE -#error UnitTest++ redefines VERIFY_IS_TRUE -#endif - -#ifdef VERIFY_IS_FALSE -#error UnitTest++ redefines VERIFY_IS_FALSE -#endif - -#ifdef VERIFY_ARE_EQUAL -#error UnitTest++ redefines VERIFY_ARE_EQUAL -#endif - -#ifdef VERIFY_ARE_NOT_EQUAL -#error UnitTest++ redefines VERIFY_ARE_NOT_EQUAL -#endif - -#ifdef VERIFY_THROWS -#error UnitTest++ redefines VERIFY_THROWS -#endif - -#ifdef VERIFY_IS_NOT_NULL -#error UnitTest++ redefines VERIFY_IS_NOT_NULL -#endif - -#ifdef VERIFY_IS_NULL -#error UnitTest++ redefines VERIFY_IS_NULL -#endif - -#ifdef WIN32 -#define VERIFY_IS_TRUE(expression, ...) CHECK_EQUAL(true, expression, __VA_ARGS__) -#define VERIFY_IS_FALSE(expression, ...) CHECK_EQUAL(false, expression, __VA_ARGS__) -#define VERIFY_ARE_NOT_EQUAL(expected, actual, ...) CHECK_NOT_EQUAL(expected, actual, __VA_ARGS__) -#define VERIFY_ARE_EQUAL(expected, actual, ...) CHECK_EQUAL(expected, actual, __VA_ARGS__) -#else -#define VERIFY_IS_TRUE(expression, ...) CHECK_EQUAL(true, expression, ##__VA_ARGS__) -#define VERIFY_IS_FALSE(expression, ...) CHECK_EQUAL(false, expression, ##__VA_ARGS__) -#define VERIFY_ARE_NOT_EQUAL(expected, actual, ...) CHECK_NOT_EQUAL(expected, actual, ##__VA_ARGS__) -#define VERIFY_ARE_EQUAL(expected, actual, ...) CHECK_EQUAL(expected, actual, ##__VA_ARGS__) -#endif - -#define VERIFY_NO_THROWS(expression) CHECK_NO_THROW(expression) -#define VERIFY_THROWS(expression, exception) CHECK_THROW(expression, exception) -#define VERIFY_IS_NOT_NULL(expression) CHECK_NOT_NULL(expression) -#define VERIFY_IS_NULL(expression) CHECK_NULL(expression) - -#define CHECK(value) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - if (!UnitTest::Check(value)) \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \ - UNITTEST_MULTILINE_MACRO_END - -#ifdef WIN32 - -#define CHECK_EQUAL(expected, actual, ...) \ - do \ - { \ - UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), \ - #expected, \ - #actual, \ - expected, \ - actual, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - __VA_ARGS__); \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_NOT_EQUAL(expected, actual, ...) \ - do \ - { \ - UnitTest::CheckNotEqual(*UnitTest::CurrentTest::Results(), \ - #expected, \ - #actual, \ - expected, \ - actual, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - __VA_ARGS__); \ - UNITTEST_MULTILINE_MACRO_END - -#else - -#define CHECK_EQUAL(expected, actual, ...) \ - do \ - { \ - try \ - { \ - UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), \ - #expected, \ - #actual, \ - expected, \ - actual, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - ##__VA_ARGS__); \ - } \ - catch (const std::exception& ex) \ - { \ - std::cerr << ex.what() << std::endl; \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ") - details: "); \ - } \ - UT_CATCH_ALL({ \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_NOT_EQUAL(expected, actual, ...) \ - do \ - { \ - try \ - { \ - UnitTest::CheckNotEqual(*UnitTest::CurrentTest::Results(), \ - #expected, \ - #actual, \ - expected, \ - actual, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - ##__VA_ARGS__); \ - } \ - UT_CATCH_ALL({ \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Unhandled exception in CHECK_NOT_EQUAL(" #expected ", " #actual ")"); \ - }) \ - UNITTEST_MULTILINE_MACRO_END -#endif - -#define CHECK_NULL(expression) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::CheckNull(*UnitTest::CurrentTest::Results(), \ - #expression, \ - expression, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_NOT_NULL(expression) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::CheckNotNull(*UnitTest::CurrentTest::Results(), \ - #expression, \ - expression, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_CLOSE(expected, actual, tolerance) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::CheckClose(*UnitTest::CurrentTest::Results(), \ - expected, \ - actual, \ - tolerance, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_ARRAY_EQUAL(expected, actual, count) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::CheckArrayEqual(*UnitTest::CurrentTest::Results(), \ - expected, \ - actual, \ - count, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::CheckArrayClose(*UnitTest::CurrentTest::Results(), \ - expected, \ - actual, \ - count, \ - tolerance, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::CheckArray2DClose(*UnitTest::CurrentTest::Results(), \ - expected, \ - actual, \ - rows, \ - columns, \ - tolerance, \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \ - UNITTEST_MULTILINE_MACRO_END - -// CHECK_THROW and CHECK_ASSERT only exist when UNITTEST_NO_EXCEPTIONS isn't defined (see config.h) -#ifndef UNITTEST_NO_EXCEPTIONS -#define CHECK_THROW(expression, ExpectedExceptionType) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - bool caught_ = false; \ - try \ - { \ - try \ - { \ - expression; \ - } \ - catch (const std::exception& _exc) \ - { \ - std::string _msg(_exc.what()); \ - VERIFY_IS_TRUE(_msg.size() > 0); \ - throw; \ - } \ - } \ - catch (ExpectedExceptionType const&) \ - { \ - caught_ = true; \ - } \ - catch (...) \ - { \ - } \ - if (!caught_) \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_NO_THROW(expression) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - try \ - { \ - expression; \ - } \ - catch (const std::exception& _exc) \ - { \ - std::string _msg("(" #expression ") threw exception: "); \ - _msg.append(_exc.what()); \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), _msg.c_str()); \ - } \ - catch (...) \ - { \ - std::string _msg("(" #expression ") threw exception: <...>"); \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), _msg.c_str()); \ - } \ - UNITTEST_MULTILINE_MACRO_END - -#define CHECK_ASSERT(expression) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - UnitTest::Detail::ExpectAssert(true); \ - CHECK_THROW(expression, UnitTest::AssertException); \ - UnitTest::Detail::ExpectAssert(false); \ - UNITTEST_MULTILINE_MACRO_END -#endif -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Checks.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Checks.h @@ -1,383 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_CHECKS_H -#define UNITTEST_CHECKS_H - -#include "MemoryOutStream.h" -#include "TestResults.h" -#include "config.h" -#include <cstring> -#include <memory> -#include <string> - -#ifndef _WIN32 -#include <boost/locale/encoding_utf.hpp> -#endif - -namespace UnitTest -{ -namespace details -{ -inline std::string utf16_to_utf8(const std::basic_string<utf16char>& w) -{ -#ifdef _WIN32 - std::string result; - size_t size; - wcstombs_s(&size, nullptr, 0, (const wchar_t*)w.c_str(), w.size()); - result.resize(size); - // integr0808: added cast - wcstombs_s(&size, &result[0], size, (const wchar_t*)w.c_str(), w.size()); - return result; -#else - return boost::locale::conv::utf_to_utf<char, utf16char>(w, boost::locale::conv::stop); -#endif -} - -typedef char yes; -typedef char (&no)[2]; - -struct anyx -{ - template<typename T> - anyx(const T&); -}; -no operator<<(const anyx&, const anyx&); - -template<typename T> -yes check(T const&); -no check(no); - -template<typename StreamType, typename T1, typename T2> -struct support_stream_write -{ - static StreamType& stream; - static T1& x; - static T2& y; - static const bool value = - (sizeof(check(stream << x)) == sizeof(yes)) && (sizeof(check(stream << y)) == sizeof(yes)); -}; - -template<typename T1, typename T2> -inline std::string BuildFailureStringWithStream(const char* expectedStr, - const char* actualStr, - const T1& expected, - const T2& actual) -{ - UnitTest::MemoryOutStream stream; - stream << " where " << expectedStr << "=" << expected << " and " << actualStr << "=" << actual; - return stream.GetText(); -} - -template<typename T1, typename T2, bool UseStreams> -struct BuildFailureStringImpl -{ - std::string BuildString(const char*, const char*, const T1&, const T2&) - { - // Don't do anything since operator<< isn't supported. - return std::string{}; - } -}; - -template<typename T1, typename T2> -struct BuildFailureStringImpl<T1, T2, true> -{ - std::string BuildString(const char* expectedStr, const char* actualStr, const T1& expected, const T2& actual) - { - return BuildFailureStringWithStream(expectedStr, actualStr, expected, actual); - } -}; - -template<typename T1, typename T2> -inline std::string BuildFailureString(const char* expectedStr, - const char* actualStr, - const T1& expected, - const T2& actual) -{ - return BuildFailureStringImpl<T1, T2, support_stream_write<UnitTest::MemoryOutStream, T1, T2>::value>().BuildString( - expectedStr, actualStr, expected, actual); -} -inline std::string BuildFailureString(const char* expectedStr, - const char* actualStr, - const std::basic_string<utf16char>& expected, - const std::basic_string<utf16char>& actual) -{ - return BuildFailureStringWithStream(expectedStr, actualStr, utf16_to_utf8(expected), utf16_to_utf8(actual)); -} -inline std::string BuildFailureString(const char* expectedStr, - const char* actualStr, - const utf16char* expected, - const utf16char* actual) -{ - return BuildFailureStringWithStream(expectedStr, actualStr, utf16_to_utf8(expected), utf16_to_utf8(actual)); -} -inline std::string BuildFailureString(const char* expectedStr, - const char* actualStr, - const std::basic_string<utf16char>& expected, - const utf16char* actual) -{ - return BuildFailureStringWithStream(expectedStr, actualStr, utf16_to_utf8(expected), utf16_to_utf8(actual)); -} -inline std::string BuildFailureString(const char* expectedStr, - const char* actualStr, - const utf16char* expected, - const std::basic_string<utf16char>& actual) -{ - return BuildFailureStringWithStream(expectedStr, actualStr, utf16_to_utf8(expected), utf16_to_utf8(actual)); -} -} // namespace details - -template<typename Value> -bool Check(Value const value) -{ - return !!value; // doing double negative to avoid silly VS warnings -} - -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4389) -#endif -template<typename Expected, typename Actual> -bool CheckEqualImpl(const Expected& expected, const Actual& actual) -{ - return !(expected == actual); -} -#ifdef _WIN32 -#pragma warning(pop) -#endif - -inline bool CheckEqualImpl(const char* expected, const char* actual) { return !(std::strcmp(expected, actual) == 0); } -inline bool CheckEqualImpl(char* expected, const char* actual) { return !(std::strcmp(expected, actual) == 0); } -inline bool CheckEqualImpl(const char* expected, char* actual) { return !(std::strcmp(expected, actual) == 0); } -inline bool CheckEqualImpl(char* expected, char* actual) { return !(std::strcmp(expected, actual) == 0); } -inline bool CheckEqualImpl(const wchar_t* expected, const wchar_t* actual) { return !(wcscmp(expected, actual) == 0); } -inline bool CheckEqualImpl(wchar_t* expected, const wchar_t* actual) { return !(wcscmp(expected, actual) == 0); } -inline bool CheckEqualImpl(const wchar_t* expected, wchar_t* actual) { return !(wcscmp(expected, actual) == 0); } -inline bool CheckEqualImpl(wchar_t* expected, wchar_t* actual) { return !(wcscmp(expected, actual) == 0); } - -template<typename Expected, typename Actual> -void CheckEqual(TestResults& results, - const char* expectedStr, - const char* actualStr, - const Expected& expected, - const Actual& actual, - TestDetails const& details, - const char* msg = nullptr) -{ - if (CheckEqualImpl(expected, actual)) - { - UnitTest::MemoryOutStream stream; - stream << "CHECK_EQUAL(" << expectedStr << ", " << actualStr << ")"; - stream << details::BuildFailureString(expectedStr, actualStr, expected, actual) << std::endl; - if (msg != nullptr) - { - stream << msg; - } - results.OnTestFailure(details, stream.GetText()); - } -} - -template<typename Expected, typename Actual> -void CheckNotEqual(TestResults& results, - const char* expectedStr, - const char* actualStr, - Expected const& expected, - Actual const& actual, - TestDetails const& details, - const char* msg = nullptr) -{ - if (!CheckEqualImpl(expected, actual)) - { - UnitTest::MemoryOutStream stream; - stream << "CHECK_NOT_EQUAL(" << expectedStr << ", " << actualStr << ")"; - stream << details::BuildFailureString(expectedStr, actualStr, expected, actual) << std::endl; - if (msg != nullptr) - { - stream << msg; - } - results.OnTestFailure(details, stream.GetText()); - } -} - -template<typename Actual> -void CheckNull(TestResults& results, const char* actualStr, Actual const& actual, TestDetails const& details) -{ - if (actual) - { - UnitTest::MemoryOutStream stream; - stream << "CHECK_NULL(" << actualStr << ")"; - results.OnTestFailure(details, stream.GetText()); - } -} - -template<typename Actual> -void CheckNotNull(TestResults& results, const char* actualStr, Actual const& actual, TestDetails const& details) -{ - if (!actual) - { - UnitTest::MemoryOutStream stream; - stream << "CHECK_NOT_NULL(" << actualStr << ")"; - results.OnTestFailure(details, stream.GetText()); - } -} - -template<typename Expected, typename Actual, typename Tolerance> -bool AreClose(Expected const& expected, Actual const& actual, Tolerance const& tolerance) -{ - return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance)); -} - -template<typename Expected, typename Actual, typename Tolerance> -void CheckClose(TestResults& results, - Expected const& expected, - Actual const& actual, - Tolerance const& tolerance, - TestDetails const& details) -{ - if (!AreClose(expected, actual, tolerance)) - { - UnitTest::MemoryOutStream stream; - stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual; - - results.OnTestFailure(details, stream.GetText()); - } -} - -template<typename Expected, typename Actual> -void CheckArrayEqual( - TestResults& results, Expected const& expected, Actual const& actual, int const count, TestDetails const& details) -{ - bool equal = true; - for (int i = 0; i < count; ++i) - equal &= (expected[i] == actual[i]); - - if (!equal) - { - UnitTest::MemoryOutStream stream; - - stream << "Expected [ "; - - for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex) - stream << expected[expectedIndex] << " "; - - stream << "] but was [ "; - - for (int actualIndex = 0; actualIndex < count; ++actualIndex) - stream << actual[actualIndex] << " "; - - stream << "]"; - - results.OnTestFailure(details, stream.GetText()); - } -} - -template<typename Expected, typename Actual, typename Tolerance> -bool ArrayAreClose(Expected const& expected, Actual const& actual, int const count, Tolerance const& tolerance) -{ - bool equal = true; - for (int i = 0; i < count; ++i) - equal &= AreClose(expected[i], actual[i], tolerance); - return equal; -} - -template<typename Expected, typename Actual, typename Tolerance> -void CheckArrayClose(TestResults& results, - Expected const& expected, - Actual const& actual, - int const count, - Tolerance const& tolerance, - TestDetails const& details) -{ - bool equal = ArrayAreClose(expected, actual, count, tolerance); - - if (!equal) - { - UnitTest::MemoryOutStream stream; - - stream << "Expected [ "; - for (int expectedIndex = 0; expectedIndex < count; ++expectedIndex) - stream << expected[expectedIndex] << " "; - stream << "] +/- " << tolerance << " but was [ "; - - for (int actualIndex = 0; actualIndex < count; ++actualIndex) - stream << actual[actualIndex] << " "; - stream << "]"; - - results.OnTestFailure(details, stream.GetText()); - } -} - -template<typename Expected, typename Actual, typename Tolerance> -void CheckArray2DClose(TestResults& results, - Expected const& expected, - Actual const& actual, - int const rows, - int const columns, - Tolerance const& tolerance, - TestDetails const& details) -{ - bool equal = true; - for (int i = 0; i < rows; ++i) - equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance); - - if (!equal) - { - UnitTest::MemoryOutStream stream; - - stream << "Expected [ "; - - for (int expectedRow = 0; expectedRow < rows; ++expectedRow) - { - stream << "[ "; - for (int expectedColumn = 0; expectedColumn < columns; ++expectedColumn) - stream << expected[expectedRow][expectedColumn] << " "; - stream << "] "; - } - - stream << "] +/- " << tolerance << " but was [ "; - - for (int actualRow = 0; actualRow < rows; ++actualRow) - { - stream << "[ "; - for (int actualColumn = 0; actualColumn < columns; ++actualColumn) - stream << actual[actualRow][actualColumn] << " "; - stream << "] "; - } - - stream << "]"; - - results.OnTestFailure(details, stream.GetText()); - } -} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CompositeTestReporter.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CompositeTestReporter.cpp @@ -1,101 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "CompositeTestReporter.h" - -namespace UnitTest -{ -CompositeTestReporter::CompositeTestReporter() : m_reporterCount(0) {} - -int CompositeTestReporter::GetReporterCount() const { return m_reporterCount; } - -bool CompositeTestReporter::AddReporter(TestReporter* reporter) -{ - if (m_reporterCount == kMaxReporters) return false; - -// Safe to ignore we check the size to make sure no buffer overruns before. -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 6386) -#endif - m_reporters[m_reporterCount++] = reporter; -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - - return true; -} - -bool CompositeTestReporter::RemoveReporter(TestReporter* reporter) -{ - for (int index = 0; index < m_reporterCount; ++index) - { - if (m_reporters[index] == reporter) - { - m_reporters[index] = m_reporters[m_reporterCount - 1]; - --m_reporterCount; - return true; - } - } - - return false; -} - -void CompositeTestReporter::ReportFailure(TestDetails const& details, char const* failure) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportFailure(details, failure); -} - -void CompositeTestReporter::ReportTestStart(TestDetails const& test) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportTestStart(test); -} - -void CompositeTestReporter::ReportTestFinish(TestDetails const& test, bool passed, float secondsElapsed) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportTestFinish(test, passed, secondsElapsed); -} - -void CompositeTestReporter::ReportSummary(int totalTestCount, - int failedTestCount, - int failureCount, - float secondsElapsed) -{ - for (int index = 0; index < m_reporterCount; ++index) - m_reporters[index]->ReportSummary(totalTestCount, failedTestCount, failureCount, secondsElapsed); -} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CompositeTestReporter.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CompositeTestReporter.h @@ -1,71 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_COMPOSITETESTREPORTER_H -#define UNITTEST_COMPOSITETESTREPORTER_H - -#include "TestReporter.h" - -namespace UnitTest -{ -class CompositeTestReporter : public TestReporter -{ -public: - UNITTEST_LINKAGE CompositeTestReporter(); - - UNITTEST_LINKAGE int GetReporterCount() const; - UNITTEST_LINKAGE bool AddReporter(TestReporter* reporter); - UNITTEST_LINKAGE bool RemoveReporter(TestReporter* reporter); - - UNITTEST_LINKAGE virtual void ReportTestStart(TestDetails const& test); - UNITTEST_LINKAGE virtual void ReportFailure(TestDetails const& test, char const* failure); - UNITTEST_LINKAGE virtual void ReportTestFinish(TestDetails const& test, bool passed, float secondsElapsed); - UNITTEST_LINKAGE virtual void ReportSummary(int totalTestCount, - int failedTestCount, - int failureCount, - float secondsElapsed); - -private: - enum - { - kMaxReporters = 16 - }; - TestReporter* m_reporters[kMaxReporters]; - int m_reporterCount; - - // revoked - CompositeTestReporter(const CompositeTestReporter&); - CompositeTestReporter& operator=(const CompositeTestReporter&); -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CurrentTest.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CurrentTest.cpp @@ -1,55 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include <atomic> - -namespace -{ -std::atomic<UnitTest::TestResults*> testResults; -std::atomic<UnitTest::TestDetails*> testDetails; // non-const pointer to avoid VS2013 STL bug -} // namespace - -namespace UnitTest -{ -UNITTEST_LINKAGE TestResults* CurrentTest::Results() { return testResults; } - -UNITTEST_LINKAGE void CurrentTest::SetResults(TestResults* r) { testResults.store(r); } - -UNITTEST_LINKAGE const TestDetails* CurrentTest::Details() { return testDetails; } - -UNITTEST_LINKAGE void CurrentTest::SetDetails(const UnitTest::TestDetails* d) -{ - testDetails.store(const_cast<UnitTest::TestDetails*>(d)); -} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CurrentTest.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/CurrentTest.h @@ -1,52 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_CURRENTTESTRESULTS_H -#define UNITTEST_CURRENTTESTRESULTS_H - -#include "HelperMacros.h" - -namespace UnitTest -{ -class TestResults; -class TestDetails; - -namespace CurrentTest -{ -UNITTEST_LINKAGE TestResults* __cdecl Results(); -UNITTEST_LINKAGE void __cdecl SetResults(TestResults*); -UNITTEST_LINKAGE const TestDetails* __cdecl Details(); -UNITTEST_LINKAGE void __cdecl SetDetails(const TestDetails*); -} // namespace CurrentTest - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestReporter.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestReporter.cpp @@ -1,59 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -using namespace UnitTest; - -void DeferredTestReporter::ReportTestStart(TestDetails const& details) -{ - m_results.push_back(DeferredTestResult(details.suiteName, details.testName)); -} - -void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure) -{ - DeferredTestResult& r = m_results.back(); - r.failed = true; - r.failures.push_back(DeferredTestFailure(details.lineNumber, failure)); - r.failureFile = details.filename; -} - -void DeferredTestReporter::ReportTestFinish(TestDetails const&, bool, float secondsElapsed) -{ - DeferredTestResult& r = m_results.back(); - r.timeElapsed = secondsElapsed; -} - -DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults() { return m_results; } - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestReporter.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestReporter.h @@ -1,62 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_DEFERREDTESTREPORTER_H -#define UNITTEST_DEFERREDTESTREPORTER_H - -#include "../config.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "DeferredTestResult.h" -#include "TestReporter.h" -#include <vector> - -namespace UnitTest -{ -class DeferredTestReporter : public TestReporter -{ -public: - UNITTEST_LINKAGE virtual void ReportTestStart(TestDetails const& details); - UNITTEST_LINKAGE virtual void ReportFailure(TestDetails const& details, char const* failure); - UNITTEST_LINKAGE virtual void ReportTestFinish(TestDetails const& details, bool passed, float secondsElapsed); - - typedef std::vector<DeferredTestResult> DeferredTestResultList; - UNITTEST_LINKAGE DeferredTestResultList& GetResults(); - -private: - DeferredTestResultList m_results; -}; - -} // namespace UnitTest - -#endif -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestResult.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestResult.cpp @@ -1,70 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "DeferredTestResult.h" - -namespace UnitTest -{ -DeferredTestFailure::DeferredTestFailure() : lineNumber(-1) { failureStr[0] = '\0'; } - -DeferredTestFailure::DeferredTestFailure(int lineNumber_, const char* failureStr_) : lineNumber(lineNumber_) -{ -// Ignoring warning about possible overrun because we aren't going to entirely -// change how unittestpp deals with strings. -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 6204) -#endif - std::strcpy(failureStr, failureStr_); -#if defined(_MSC_VER) -#pragma warning(pop) -#endif -} - -DeferredTestResult::DeferredTestResult() - : suiteName(), testName(), failureFile(), timeElapsed(0.0f), failed(false) -{ -} - -DeferredTestResult::DeferredTestResult(char const* const suite, char const* const test) - : suiteName(suite), testName(test), failureFile(), timeElapsed(0.0f), failed(false) -{ -} - -DeferredTestResult::~DeferredTestResult() {} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestResult.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/DeferredTestResult.h @@ -1,79 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_DEFERREDTESTRESULT_H -#define UNITTEST_DEFERREDTESTRESULT_H - -#include "../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "HelperMacros.h" -#include <string> -#include <vector> - -namespace UnitTest -{ -class DeferredTestFailure -{ -public: - UNITTEST_LINKAGE DeferredTestFailure(); - UNITTEST_LINKAGE DeferredTestFailure(int lineNumber_, const char* failureStr_); - - int lineNumber; - char failureStr[1024]; -}; - -} // namespace UnitTest - -namespace UnitTest -{ -class DeferredTestResult -{ -public: - UNITTEST_LINKAGE DeferredTestResult(); - UNITTEST_LINKAGE DeferredTestResult(char const* suite, char const* test); - UNITTEST_LINKAGE ~DeferredTestResult(); - - std::string suiteName; - std::string testName; - std::string failureFile; - - typedef std::vector<DeferredTestFailure> FailureVec; - FailureVec failures; - - float timeElapsed; - bool failed; -}; - -} // namespace UnitTest - -#endif -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ExceptionMacros.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ExceptionMacros.h @@ -1,51 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_EXCEPTIONMACROS_H -#define UNITTEST_EXCEPTIONMACROS_H - -#include "../config.h" - -#ifndef UNITTEST_NO_EXCEPTIONS -#define UT_TRY(x) \ - try \ - x -#define UT_THROW(x) throw x -#define UT_CATCH(ExceptionType, ExceptionName, CatchBody) catch (ExceptionType & ExceptionName) CatchBody -#define UT_CATCH_ALL(CatchBody) catch (...) CatchBody -#else -#define UT_TRY(x) x -#define UT_THROW(x) -#define UT_CATCH(ExceptionType, ExceptionName, CatchBody) -#define UT_CATCH_ALL(CatchBody) -#endif - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ExecuteTest.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ExecuteTest.h @@ -1,89 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_EXECUTE_TEST_H -#define UNITTEST_EXECUTE_TEST_H - -#include "../config.h" -#include "AssertException.h" -#include "CurrentTest.h" -#include "ExceptionMacros.h" -#include "MemoryOutStream.h" -#include "TestDetails.h" -#include "TestResults.h" - -#ifdef UNITTEST_NO_EXCEPTIONS -#include "ReportAssertImpl.h" -#endif - -#ifdef UNITTEST_POSIX -#include "Posix/SignalTranslator.h" -#endif - -#include <iostream> - -namespace UnitTest -{ -template<typename T> -void ExecuteTest(T& testObject, TestDetails const& details, bool isMockTest) -{ - if (isMockTest == false) - { - CurrentTest::SetDetails(&details); - } - -#ifdef UNITTEST_NO_EXCEPTIONS - if (UNITTEST_SET_ASSERT_JUMP_TARGET() == 0) - { -#endif -#ifndef UNITTEST_POSIX - UT_TRY({ testObject.RunImpl(); }) -#else - UT_TRY({ - UNITTEST_THROW_SIGNALS_POSIX_ONLY - testObject.RunImpl(); - }) -#endif - UT_CATCH(AssertException, e, { (void)e; }) - UT_CATCH(std::exception, e, { - MemoryOutStream stream; - stream << "Unhandled exception: " << e.what(); - CurrentTest::Results()->OnTestFailure(details, stream.GetText()); - }) - UT_CATCH_ALL({ CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: test crashed"); }) -#ifdef UNITTEST_NO_EXCEPTIONS - } -#endif -} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/GlobalSettings.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/GlobalSettings.cpp @@ -1,64 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "GlobalSettings.h" - -#include <algorithm> -#include <map> - -namespace UnitTest -{ -static std::string to_lower(const std::string& str) -{ - std::string retVal; - retVal.resize(str.size()); - std::transform(str.begin(), str.end(), retVal.begin(), ::tolower); - return retVal; -} - -std::map<std::string, std::string> g_settings; - -void GlobalSettings::Add(const std::string& key, const std::string& value) { g_settings[to_lower(key)] = value; } - -bool GlobalSettings::Has(const std::string& key) { return g_settings.find(to_lower(key)) != g_settings.end(); } - -const std::string& GlobalSettings::Get(const std::string& key) -{ - if (!Has(key)) - { - throw std::invalid_argument("Error: property is not found"); - } - return g_settings.find(to_lower(key))->second; -} - -} // namespace UnitTest- \ No newline at end of file diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/GlobalSettings.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/GlobalSettings.h @@ -1,59 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_GLOBAL_PROPERTIES_H -#define UNITTEST_GLOBAL_PROPERTIES_H - -#include "HelperMacros.h" -#include <string> - -namespace UnitTest -{ -// Simple key value pairs for global properties. -// Any test case which specifies a 'Requires' TestProperty will only execute if -// the required property is satisfied as a key in the GlobalSettings. -class GlobalSettings -{ -public: - UNITTEST_LINKAGE static void __cdecl Add(const std::string& key, const std::string& value); - - UNITTEST_LINKAGE static bool __cdecl Has(const std::string& key); - - UNITTEST_LINKAGE static const std::string& __cdecl Get(const std::string& key); - -private: - GlobalSettings(); - GlobalSettings(const GlobalSettings&); - GlobalSettings& operator=(const GlobalSettings&); -}; -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/HelperMacros.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/HelperMacros.h @@ -1,85 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_HELPERMACROS_H -#define UNITTEST_HELPERMACROS_H - -#include "../config.h" - -#define UNITTEST_MULTILINE_MACRO_BEGIN \ - do \ - { -#ifdef UNITTEST_WIN32 -#define UNITTEST_MULTILINE_MACRO_END \ - } \ - __pragma(warning(push)) __pragma(warning(disable : 4127)) while (0) __pragma(warning(pop)) -#else -#define UNITTEST_MULTILINE_MACRO_END \ - } \ - while (0) -#endif - -#ifdef UNITTEST_WIN32_DLL -#define UNITTEST_IMPORT __declspec(dllimport) -#define UNITTEST_EXPORT __declspec(dllexport) - -#ifdef UNITTEST_DLL_EXPORT -#define UNITTEST_LINKAGE UNITTEST_EXPORT -#define UNITTEST_IMPEXP_TEMPLATE -#else -#define UNITTEST_LINKAGE UNITTEST_IMPORT -#define UNITTEST_IMPEXP_TEMPLATE extern -#endif - -#define UNITTEST_STDVECTOR_LINKAGE(T) \ - __pragma(warning(push)) __pragma(warning(disable : 4231)) \ - UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::allocator<T>; \ - UNITTEST_IMPEXP_TEMPLATE template class UNITTEST_LINKAGE std::vector<T>; \ - __pragma(warning(pop)) -#else -#define UNITTEST_IMPORT -#define UNITTEST_EXPORT -#define UNITTEST_LINKAGE -#define UNITTEST_IMPEXP_TEMPLATE -#define UNITTEST_STDVECTOR_LINKAGE(T) -#endif - -#ifdef UNITTEST_WIN32 -#define UNITTEST_JMPBUF jmp_buf -#define UNITTEST_SETJMP setjmp -#define UNITTEST_LONGJMP longjmp -#elif defined UNITTEST_POSIX -#define UNITTEST_JMPBUF std::jmp_buf -#define UNITTEST_SETJMP setjmp -#define UNITTEST_LONGJMP std::longjmp -#endif - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/MemoryOutStream.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/MemoryOutStream.cpp @@ -1,186 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -namespace UnitTest -{ -MemoryOutStream::MemoryOutStream() {} - -MemoryOutStream::~MemoryOutStream() {} - -char const* MemoryOutStream::GetText() const -{ - m_text = this->str(); - return m_text.c_str(); -} - -void MemoryOutStream::Clear() -{ - this->str(std::string()); - m_text = this->str(); -} - -} // namespace UnitTest - -#else - -namespace UnitTest -{ -namespace -{ -template<typename ValueType> -void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value) -{ - using namespace std; - - char txt[32]; - sprintf(txt, format, value); - stream << txt; -} - -int RoundUpToMultipleOfPow2Number(int n, int pow2Number) { return (n + (pow2Number - 1)) & ~(pow2Number - 1); } - -} // namespace - -MemoryOutStream::MemoryOutStream(int const size) : m_capacity(0), m_buffer(0) { GrowBuffer(size); } - -MemoryOutStream::~MemoryOutStream() { delete[] m_buffer; } - -void MemoryOutStream::Clear() { m_buffer[0] = '\0'; } - -char const* MemoryOutStream::GetText() const { return m_buffer; } - -MemoryOutStream& MemoryOutStream::operator<<(char const* txt) -{ - using namespace std; - - int const bytesLeft = m_capacity - (int)strlen(m_buffer); - int const bytesRequired = (int)strlen(txt) + 1; - - if (bytesRequired > bytesLeft) - { - int const requiredCapacity = bytesRequired + m_capacity - bytesLeft; - GrowBuffer(requiredCapacity); - } - - strcat(m_buffer, txt); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(int const n) -{ - FormatToStream(*this, "%i", n); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(long const n) -{ - FormatToStream(*this, "%li", n); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(unsigned long const n) -{ - FormatToStream(*this, "%lu", n); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(long long const n) -{ -#ifdef UNITTEST_WIN32 - FormatToStream(*this, "%I64d", n); -#else - FormatToStream(*this, "%lld", n); -#endif - - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(unsigned long long const n) -{ -#ifdef UNITTEST_WIN32 - FormatToStream(*this, "%I64u", n); -#else - FormatToStream(*this, "%llu", n); -#endif - - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(float const f) -{ - FormatToStream(*this, "%ff", f); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(void const* p) -{ - FormatToStream(*this, "%p", p); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(unsigned int const s) -{ - FormatToStream(*this, "%u", s); - return *this; -} - -MemoryOutStream& MemoryOutStream::operator<<(double const d) -{ - FormatToStream(*this, "%f", d); - return *this; -} - -int MemoryOutStream::GetCapacity() const { return m_capacity; } - -void MemoryOutStream::GrowBuffer(int const desiredCapacity) -{ - int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE); - - using namespace std; - - char* buffer = new char[newCapacity]; - if (m_buffer) - strcpy(buffer, m_buffer); - else - *buffer = '\0'; - - delete[] m_buffer; - m_buffer = buffer; - m_capacity = newCapacity; -} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/MemoryOutStream.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/MemoryOutStream.h @@ -1,105 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_MEMORYOUTSTREAM_H -#define UNITTEST_MEMORYOUTSTREAM_H - -#include "../config.h" -#include "HelperMacros.h" - -#ifdef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -#include <sstream> - -namespace UnitTest -{ -class MemoryOutStream : public std::ostringstream -{ -public: - UNITTEST_LINKAGE MemoryOutStream(); - UNITTEST_LINKAGE ~MemoryOutStream(); - UNITTEST_LINKAGE void Clear(); - UNITTEST_LINKAGE char const* GetText() const; - -private: - MemoryOutStream(MemoryOutStream const&); - void operator=(MemoryOutStream const&); - - mutable std::string m_text; -}; - -} // namespace UnitTest - -#else - -#include <cstddef> - -namespace UnitTest -{ -class UNITTEST_LINKAGE MemoryOutStream -{ -public: - explicit MemoryOutStream(int const size = 256); - ~MemoryOutStream(); - - void Clear(); - char const* GetText() const; - - MemoryOutStream& operator<<(char const* txt); - MemoryOutStream& operator<<(int n); - MemoryOutStream& operator<<(long n); - MemoryOutStream& operator<<(long long n); - MemoryOutStream& operator<<(unsigned long n); - MemoryOutStream& operator<<(unsigned long long n); - MemoryOutStream& operator<<(float f); - MemoryOutStream& operator<<(double d); - MemoryOutStream& operator<<(void const* p); - MemoryOutStream& operator<<(unsigned int s); - - enum - { - GROW_CHUNK_SIZE = 32 - }; - int GetCapacity() const; - -private: - void operator=(MemoryOutStream const&); - void GrowBuffer(int capacity); - - int m_capacity; - char* m_buffer; -}; - -} // namespace UnitTest - -#endif - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/SignalTranslator.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/SignalTranslator.cpp @@ -1,72 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "SignalTranslator.h" - -namespace UnitTest -{ -sigjmp_buf* SignalTranslator::s_jumpTarget = 0; - -namespace -{ -void SignalHandler(int sig) { siglongjmp(*SignalTranslator::s_jumpTarget, sig); } - -} // namespace - -SignalTranslator::SignalTranslator() -{ - m_oldJumpTarget = s_jumpTarget; - s_jumpTarget = &m_currentJumpTarget; - - struct sigaction action; - action.sa_flags = 0; - action.sa_handler = SignalHandler; - sigemptyset(&action.sa_mask); - - sigaction(SIGSEGV, &action, &m_old_SIGSEGV_action); - sigaction(SIGFPE, &action, &m_old_SIGFPE_action); - sigaction(SIGTRAP, &action, &m_old_SIGTRAP_action); - sigaction(SIGBUS, &action, &m_old_SIGBUS_action); - sigaction(SIGILL, &action, &m_old_SIGBUS_action); -} - -SignalTranslator::~SignalTranslator() -{ - sigaction(SIGILL, &m_old_SIGBUS_action, 0); - sigaction(SIGBUS, &m_old_SIGBUS_action, 0); - sigaction(SIGTRAP, &m_old_SIGTRAP_action, 0); - sigaction(SIGFPE, &m_old_SIGFPE_action, 0); - sigaction(SIGSEGV, &m_old_SIGSEGV_action, 0); - - s_jumpTarget = m_oldJumpTarget; -} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/SignalTranslator.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/SignalTranslator.h @@ -1,72 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_SIGNALTRANSLATOR_H -#define UNITTEST_SIGNALTRANSLATOR_H - -#include <setjmp.h> -#include <signal.h> - -namespace UnitTest -{ -class SignalTranslator -{ -public: - SignalTranslator(); - ~SignalTranslator(); - - static sigjmp_buf* s_jumpTarget; - - sigjmp_buf m_currentJumpTarget; - sigjmp_buf* m_oldJumpTarget; - - struct sigaction m_old_SIGFPE_action; - struct sigaction m_old_SIGTRAP_action; - struct sigaction m_old_SIGSEGV_action; - struct sigaction m_old_SIGBUS_action; - struct sigaction m_old_SIGABRT_action; - struct sigaction m_old_SIGALRM_action; -}; - -#if !defined(__GNUC__) -#define UNITTEST_EXTENSION -#else -#define UNITTEST_EXTENSION __extension__ -#endif - -#define UNITTEST_THROW_SIGNALS_POSIX_ONLY \ - UnitTest::SignalTranslator sig; \ - if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \ - throw("Unhandled system exception"); - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/TimeHelpers.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/TimeHelpers.cpp @@ -1,59 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "TimeHelpers.h" - -#include <unistd.h> - -namespace UnitTest -{ -Timer::Timer() -{ - m_startTime.tv_sec = 0; - m_startTime.tv_usec = 0; -} - -void Timer::Start() { gettimeofday(&m_startTime, 0); } - -double Timer::GetTimeInMs() const -{ - struct timeval currentTime; - gettimeofday(¤tTime, 0); - - double const dsecs = currentTime.tv_sec - m_startTime.tv_sec; - double const dus = currentTime.tv_usec - m_startTime.tv_usec; - - return (dsecs * 1000.0) + (dus / 1000.0); -} - -void TimeHelpers::SleepMs(int ms) { usleep(ms * 1000); } - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/TimeHelpers.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Posix/TimeHelpers.h @@ -1,57 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TIMEHELPERS_H -#define UNITTEST_TIMEHELPERS_H - -#include <sys/time.h> - -namespace UnitTest -{ -class Timer -{ -public: - Timer(); - void Start(); - double GetTimeInMs() const; - -private: - struct timeval m_startTime; -}; - -namespace TimeHelpers -{ -void SleepMs(int ms); -} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ReportAssert.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ReportAssert.cpp @@ -1,94 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "ReportAssert.h" - -#include "ReportAssertImpl.h" - -#ifdef UNITTEST_NO_EXCEPTIONS -#include "ReportAssertImpl.h" -#endif - -namespace UnitTest -{ -namespace -{ -bool& AssertExpectedFlag() -{ - static bool s_assertExpected = false; - return s_assertExpected; -} -} // namespace - -UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber) -{ - Detail::ReportAssertEx(CurrentTest::Results(), CurrentTest::Details(), description, filename, lineNumber); -} - -namespace Detail -{ -#ifdef UNITTEST_NO_EXCEPTIONS -UNITTEST_JMPBUF* GetAssertJmpBuf() -{ - static UNITTEST_JMPBUF s_jmpBuf; - return &s_jmpBuf; -} -#endif - -UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults, - const TestDetails* testDetails, - char const* description, - char const* filename, - int lineNumber) -{ - if (AssertExpectedFlag() == false) - { - TestDetails assertDetails(testDetails->testName, testDetails->suiteName, filename, lineNumber); - testResults->OnTestFailure(assertDetails, description); - } - - ExpectAssert(false); - -#ifndef UNITTEST_NO_EXCEPTIONS - throw AssertException(); -#else - UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET(); -#endif -} - -UNITTEST_LINKAGE void ExpectAssert(bool expected) { AssertExpectedFlag() = expected; } - -UNITTEST_LINKAGE bool AssertExpected() { return AssertExpectedFlag(); } - -} // namespace Detail -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ReportAssert.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ReportAssert.h @@ -1,43 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_ASSERT_H -#define UNITTEST_ASSERT_H - -#include "HelperMacros.h" - -namespace UnitTest -{ -UNITTEST_LINKAGE void ReportAssert(char const* description, char const* filename, int lineNumber); - -} - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ReportAssertImpl.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/ReportAssertImpl.h @@ -1,76 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_REPORTASSERTIMPL_H -#define UNITTEST_REPORTASSERTIMPL_H - -#include "../config.h" -#include "HelperMacros.h" - -#ifdef UNITTEST_NO_EXCEPTIONS -#include <csetjmp> -#endif - -namespace UnitTest -{ -class TestResults; -class TestDetails; - -namespace Detail -{ -UNITTEST_LINKAGE void ExpectAssert(bool expected); - -UNITTEST_LINKAGE void ReportAssertEx(TestResults* testResults, - const TestDetails* testDetails, - char const* description, - char const* filename, - int lineNumber); - -UNITTEST_LINKAGE bool AssertExpected(); - -#ifdef UNITTEST_NO_EXCEPTIONS -UNITTEST_LINKAGE UNITTEST_JMPBUF* GetAssertJmpBuf(); - -#ifdef UNITTEST_WIN32 -#define UNITTEST_SET_ASSERT_JUMP_TARGET() \ - __pragma(warning(push)) __pragma(warning(disable : 4611)) UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf()) \ - __pragma(warning(pop)) -#else -#define UNITTEST_SET_ASSERT_JUMP_TARGET() UNITTEST_SETJMP(*UnitTest::Detail::GetAssertJmpBuf()) -#endif - -#define UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET() UNITTEST_LONGJMP(*UnitTest::Detail::GetAssertJmpBuf(), 1) -#endif - -} // namespace Detail -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Test.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Test.cpp @@ -1,53 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "ExecuteTest.h" - -#ifdef UNITTEST_POSIX -#include "Posix/SignalTranslator.h" -#endif - -namespace UnitTest -{ -Test::Test(char const* testName, char const* suiteName, char const* filename, int lineNumber) - : m_details(testName, suiteName, filename, lineNumber), m_nextTest(0), m_isMockTest(false) -{ -} - -Test::~Test() {} - -void Test::Run() { ExecuteTest(*this, m_details, m_isMockTest); } - -void Test::RunImpl() const {} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Test.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Test.h @@ -1,67 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TEST_H -#define UNITTEST_TEST_H - -#include "TestDetails.h" -#include "TestProperties.h" - -namespace UnitTest -{ -class TestResults; - -class Test -{ -public: - UNITTEST_LINKAGE explicit Test(char const* testName, - char const* suiteName = "DefaultSuite", - char const* filename = "", - int lineNumber = 0); - UNITTEST_LINKAGE virtual ~Test(); - UNITTEST_LINKAGE void Run(); - - TestProperties m_properties; - - TestDetails const m_details; - Test* m_nextTest; - mutable bool m_isMockTest; - - UNITTEST_LINKAGE virtual void RunImpl() const; - -private: - Test(Test const&); - Test& operator=(Test const&); -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestDetails.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestDetails.cpp @@ -1,46 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -namespace UnitTest -{ -TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_) - : suiteName(suiteName_), testName(testName_), filename(filename_), lineNumber(lineNumber_) -{ -} - -TestDetails::TestDetails(const TestDetails& details, int lineNumber_) - : suiteName(details.suiteName), testName(details.testName), filename(details.filename), lineNumber(lineNumber_) -{ -} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestDetails.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestDetails.h @@ -1,57 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTDETAILS_H -#define UNITTEST_TESTDETAILS_H - -#include "HelperMacros.h" - -namespace UnitTest -{ -class TestDetails -{ -public: - UNITTEST_LINKAGE TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber); - UNITTEST_LINKAGE TestDetails(const TestDetails& details, int lineNumber); - - char const* const suiteName; - char const* const testName; - char const* const filename; - int const lineNumber; - - UNITTEST_LINKAGE TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind -private: - TestDetails& operator=(TestDetails const&); -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestList.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestList.cpp @@ -1,110 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include <cassert> -#include <stdarg.h> - -namespace UnitTest -{ -TestList::TestList() : m_head(nullptr), m_tail(nullptr) {} - -void TestList::Clear() -{ - m_head = nullptr; - m_tail = nullptr; -} - -void TestList::Add(Test* test) -{ - if (m_tail == 0) - { - assert(m_head == 0); - m_head = test; - m_tail = test; - } - else - { - m_tail->m_nextTest = test; - m_tail = test; - } -} - -Test* TestList::GetFirst() const { return m_head; } - -bool TestList::IsEmpty() const { return m_head == nullptr; } - -ListAdder::ListAdder(TestList& list, Test* test, ...) -{ - char* arg; - va_list argList; - va_start(argList, test); - for (arg = va_arg(argList, char*); arg != nullptr; arg = va_arg(argList, char*)) - { - char* key = arg; - arg = va_arg(argList, char*); - if (arg != nullptr) - { - char* value = arg; - test->m_properties.Add(key, value); - } - } - va_end(argList); - - // If on windows we could be either desktop or winrt. Make a requires property for the correct version. - // Only a desktop runner environment can execute a desktop test case and vice versa on winrt. - // This starts with visual studio versions after VS 2012. -#if defined(_MSC_VER) && (_MSC_VER >= 1800) -#ifdef __cplusplus_winrt - test->m_properties.Add("Requires", "winrt"); -#else - test->m_properties.Add("Requires", "desktop"); -#endif -#endif - - list.Add(test); -} - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" -#endif -extern "C" UNITTEST_LINKAGE TestList& GetTestList() -#if defined(__clang__) -#pragma clang diagnostic pop -#endif -{ - static TestList GLOBAL_TESTLIST; - return GLOBAL_TESTLIST; -} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestList.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestList.h @@ -1,66 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTLIST_H -#define UNITTEST_TESTLIST_H - -#include "HelperMacros.h" - -namespace UnitTest -{ -class Test; - -class TestList -{ -public: - UNITTEST_LINKAGE TestList(); - UNITTEST_LINKAGE void Add(Test* test); - - UNITTEST_LINKAGE Test* GetFirst() const; - - UNITTEST_LINKAGE bool IsEmpty() const; - - UNITTEST_LINKAGE void Clear(); - -private: - Test* m_head; - Test* m_tail; -}; - -class UNITTEST_LINKAGE ListAdder -{ -public: - ListAdder(TestList& list, Test* test, ...); -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestMacros.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestMacros.h @@ -1,251 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTMACROS_H -#define UNITTEST_TESTMACROS_H - -#include "../config.h" -#include "AssertException.h" -#include "ExceptionMacros.h" -#include "ExecuteTest.h" -#include "MemoryOutStream.h" -#include "TestDetails.h" -#include "TestList.h" -#include "TestSuite.h" - -#ifndef UNITTEST_POSIX -#define UNITTEST_THROW_SIGNALS_POSIX_ONLY -#else -#include "Posix/SignalTranslator.h" -#endif - -#ifdef TEST -#error UnitTest++ redefines TEST -#endif - -#ifdef TEST_EX -#error UnitTest++ redefines TEST_EX -#endif - -#ifdef TEST_FIXTURE_EX -#error UnitTest++ redefines TEST_FIXTURE_EX -#endif - -#ifndef CREATED_GET_TEST_LIST -#define CREATED_GET_TEST_LIST - -#ifdef _WIN32 -#define _DLL_EXPORT __declspec(dllexport) -#elif __APPLE__ -#define _DLL_EXPORT __attribute__((visibility("default"))) -#else -#define _DLL_EXPORT -#endif - -namespace UnitTest -{ -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" -#endif -extern "C" _DLL_EXPORT TestList& __cdecl GetTestList(); -#if defined(__clang__) -#pragma clang diagnostic pop -#endif -} // namespace UnitTest -#endif - -#define SUITE(Name) \ - namespace Suite##Name \ - { \ - namespace UnitTestSuite \ - { \ - inline char const* GetSuiteName() { return #Name; } \ - } \ - } \ - namespace Suite##Name - -#ifdef _WIN32 -#define TEST_EX(Name, List, ...) \ - class Test##Name : public UnitTest::Test \ - { \ - public: \ - Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ - \ - private: \ - virtual void RunImpl() const; \ - } test##Name##Instance; \ - \ - UnitTest::ListAdder adder##Name(List, &test##Name##Instance, __VA_ARGS__, NULL); \ - \ - void Test##Name::RunImpl() const - -#else -#define TEST_EX(Name, List, ...) \ - class Test##Name : public UnitTest::Test \ - { \ - public: \ - Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ - \ - private: \ - virtual void RunImpl() const; \ - } test##Name##Instance; \ - \ - UnitTest::ListAdder adder##Name(List, &test##Name##Instance, ##__VA_ARGS__, nullptr); \ - \ - void Test##Name::RunImpl() const -#endif - -#ifdef _WIN32 -#define TEST(Name, ...) TEST_EX(Name, UnitTest::GetTestList(), __VA_ARGS__) -#else -#define TEST(Name, ...) TEST_EX(Name, UnitTest::GetTestList(), ##__VA_ARGS__) -#endif - -#ifdef _WIN32 -#define TEST_FIXTURE_EX(Fixture, Name, List, ...) \ - class Fixture##Name##Helper : public Fixture \ - { \ - public: \ - explicit Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \ - void RunImpl(); \ - UnitTest::TestDetails const& m_details; \ - \ - private: \ - Fixture##Name##Helper(Fixture##Name##Helper const&); \ - Fixture##Name##Helper& operator=(Fixture##Name##Helper const&); \ - }; \ - \ - class Test##Fixture##Name : public UnitTest::Test \ - { \ - public: \ - Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ - \ - private: \ - virtual void RunImpl() const; \ - } test##Fixture##Name##Instance; \ - \ - UnitTest::ListAdder adder##Fixture##Name(List, &test##Fixture##Name##Instance, __VA_ARGS__, NULL); \ - \ - void Test##Fixture##Name::RunImpl() const \ - { \ - volatile bool ctorOk = false; \ - UT_TRY({ \ - Fixture##Name##Helper fixtureHelper(m_details); \ - ctorOk = true; \ - UnitTest::ExecuteTest(fixtureHelper, m_details, false); \ - }) \ - UT_CATCH(UnitTest::AssertException, e, { (void)e; }) \ - UT_CATCH(std::exception, e, { \ - UnitTest::MemoryOutStream stream; \ - stream << "Unhandled exception: " << e.what(); \ - UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); \ - }) \ - UT_CATCH_ALL({ \ - if (ctorOk) \ - { \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(m_details, __LINE__), \ - "Unhandled exception while destroying fixture " #Fixture); \ - } \ - else \ - { \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(m_details, __LINE__), \ - "Unhandled exception while constructing fixture " #Fixture); \ - } \ - }) \ - } \ - void Fixture##Name##Helper::RunImpl() -#else -#define TEST_FIXTURE_EX(Fixture, Name, List, ...) \ - class Fixture##Name##Helper : public Fixture \ - { \ - public: \ - explicit Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \ - void RunImpl(); \ - UnitTest::TestDetails const& m_details; \ - \ - private: \ - Fixture##Name##Helper(Fixture##Name##Helper const&); \ - Fixture##Name##Helper& operator=(Fixture##Name##Helper const&); \ - }; \ - \ - class Test##Fixture##Name : public UnitTest::Test \ - { \ - public: \ - Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ - \ - private: \ - virtual void RunImpl() const; \ - } test##Fixture##Name##Instance; \ - \ - UnitTest::ListAdder adder##Fixture##Name(List, &test##Fixture##Name##Instance, ##__VA_ARGS__, NULL); \ - \ - void Test##Fixture##Name::RunImpl() const \ - { \ - volatile bool ctorOk = false; \ - UT_TRY({ \ - Fixture##Name##Helper fixtureHelper(m_details); \ - ctorOk = true; \ - UnitTest::ExecuteTest(fixtureHelper, m_details, false); \ - }) \ - UT_CATCH(UnitTest::AssertException, e, { (void)e; }) \ - UT_CATCH(std::exception, e, { \ - UnitTest::MemoryOutStream stream; \ - stream << "Unhandled exception: " << e.what(); \ - UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText()); \ - }) \ - UT_CATCH_ALL({ \ - if (ctorOk) \ - { \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(m_details, __LINE__), \ - "Unhandled exception while destroying fixture " #Fixture); \ - } \ - else \ - { \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(m_details, __LINE__), \ - "Unhandled exception while constructing fixture " #Fixture); \ - } \ - }) \ - } \ - void Fixture##Name##Helper::RunImpl() -#endif - -#ifdef _WIN32 -#define TEST_FIXTURE(Fixture, Name, ...) TEST_FIXTURE_EX(Fixture, Name, UnitTest::GetTestList(), __VA_ARGS__) -#else -#define TEST_FIXTURE(Fixture, Name, ...) TEST_FIXTURE_EX(Fixture, Name, UnitTest::GetTestList(), ##__VA_ARGS__) -#endif - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestProperties.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestProperties.h @@ -1,85 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TEST_PROPERTIES_H -#define UNITTEST_TEST_PROPERTIES_H - -#include <map> -#include <stdexcept> -#include <string> - -namespace UnitTest -{ -// Simple key value pairs. -class TestProperties -{ -public: - TestProperties() {} - - void Add(const std::string& key, const std::string& value) - { - if (!Has(key)) - { - m_properties[key] = value; - } - else - { - m_properties[key] += ";"; - m_properties[key] += value; - } - } - - bool Has(const std::string& key) const { return m_properties.find(key) != m_properties.end(); } - - const std::string& Get(const std::string& key) const - { - if (!Has(key)) - { - throw std::invalid_argument("Error: property is not found"); - } - return m_properties.find(key)->second; - } - - const std::string& operator[](const std::string& key) const { return Get(key); } - - std::map<std::string, std::string>::const_iterator begin() const { return m_properties.begin(); } - - std::map<std::string, std::string>::const_iterator end() const { return m_properties.end(); } - -private: - std::map<std::string, std::string> m_properties; - TestProperties(const TestProperties&); - TestProperties& operator=(const TestProperties&); -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporter.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporter.cpp @@ -1,40 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -namespace UnitTest -{ -TestReporter::TestReporter() {} - -TestReporter::~TestReporter() {} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporter.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporter.h @@ -1,57 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTREPORTER_H -#define UNITTEST_TESTREPORTER_H - -#include "HelperMacros.h" - -namespace UnitTest -{ -class TestDetails; - -class TestReporter -{ -public: - UNITTEST_LINKAGE TestReporter(); - UNITTEST_LINKAGE virtual ~TestReporter(); - - UNITTEST_LINKAGE virtual void ReportTestStart(TestDetails const& test) = 0; - UNITTEST_LINKAGE virtual void ReportFailure(TestDetails const& test, char const* failure) = 0; - UNITTEST_LINKAGE virtual void ReportTestFinish(TestDetails const& test, bool passed, float secondsElapsed) = 0; - UNITTEST_LINKAGE virtual void ReportSummary(int totalTestCount, - int failedTestCount, - int failureCount, - float secondsElapsed) = 0; -}; - -} // namespace UnitTest -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporterStdout.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporterStdout.cpp @@ -1,145 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include <stdarg.h> -#include <vector> - -// cstdio doesn't pull in namespace std on VC6, so we do it here. -#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200) -namespace std -{ -} -#endif - -namespace UnitTest -{ -// Function to work around outputing to the console when under WinRT. -static void PrintfWrapper(const char* format, ...) -{ - va_list args; - va_start(args, format); - -#ifdef __cplusplus_winrt - const auto bufSize = _vscprintf(format, args) + 1; // add 1 for null termination - std::vector<char> byteArray; - byteArray.resize(bufSize); - vsnprintf_s(&byteArray[0], bufSize, bufSize, format, args); - - DWORD bytesWritten; - HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); - WriteFile(h, &byteArray[0], (DWORD)bufSize, &bytesWritten, NULL); -#else -#ifdef _WIN32 - vfprintf_s(stdout, format, args); -#else - vfprintf(stdout, format, args); -#endif -#endif - - va_end(args); -} - -static void ChangeConsoleTextColorToRed() -{ -#if defined(__cplusplus_winrt) -#elif defined(_WIN32) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0004 | 0x0008); -#else - std::cout << "\033[1;31m"; -#endif -} - -static void ChangeConsoleTextColorToGreen() -{ -#if defined(__cplusplus_winrt) -#elif defined(_WIN32) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0002 | 0x0008); -#else - std::cout << "\033[1;32m"; -#endif -} - -static void ChangeConsoleTextColorToGrey() -{ -#if defined(__cplusplus_winrt) -#elif defined(_WIN32) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN); -#else - std::cout << "\033[0m"; -#endif -} - -void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure) -{ -#if defined(__APPLE__) || defined(__GNUG__) - char const* const errorFormat = "%s:%d: error: Failure in %s: %s FAILED\n"; -#else - char const* const errorFormat = "%s(%d): error: Failure in %s: %s FAILED\n"; -#endif - - ChangeConsoleTextColorToRed(); - PrintfWrapper(errorFormat, details.filename, details.lineNumber, details.testName, failure); - ChangeConsoleTextColorToGrey(); - std::fflush(stdout); -} - -void TestReporterStdout::ReportTestStart(TestDetails const& test) -{ - const char* format = "Starting test case %s:%s...\n"; - PrintfWrapper(format, test.suiteName, test.testName); - std::fflush(stdout); -} - -void TestReporterStdout::ReportTestFinish(TestDetails const& test, bool passed, float) -{ - if (passed) - { - const char* format = "Test case %s:%s "; - PrintfWrapper(format, test.suiteName, test.testName); - ChangeConsoleTextColorToGreen(); - PrintfWrapper("PASSED\n"); - ChangeConsoleTextColorToGrey(); - } - else - { - ChangeConsoleTextColorToRed(); - const char* format = "Test case %s:%s FAILED\n"; - PrintfWrapper(format, test.suiteName, test.testName); - ChangeConsoleTextColorToGrey(); - } - std::fflush(stdout); -} - -void TestReporterStdout::ReportSummary(int const, int const, int const, float) {} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporterStdout.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestReporterStdout.h @@ -1,53 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTREPORTERSTDOUT_H -#define UNITTEST_TESTREPORTERSTDOUT_H - -#include "TestReporter.h" - -namespace UnitTest -{ -class TestReporterStdout : public TestReporter -{ -private: - UNITTEST_LINKAGE virtual void ReportTestStart(TestDetails const& test); - UNITTEST_LINKAGE virtual void ReportFailure(TestDetails const& test, char const* failure); - UNITTEST_LINKAGE virtual void ReportTestFinish(TestDetails const& test, bool passed, float secondsElapsed); - UNITTEST_LINKAGE virtual void ReportSummary(int totalTestCount, - int failedTestCount, - int failureCount, - float secondsElapsed); -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestResults.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestResults.cpp @@ -1,99 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifndef WIN32 -#include "signal.h" -#endif - -namespace UnitTest -{ -TestResults::TestResults(TestReporter* testReporter, bool breakOnError) - : m_testReporter(testReporter) - , m_totalTestCount(0) - , m_failedTestCount(0) - , m_failureCount(0) - , m_currentTestFailed(false) - , m_breakOnError(breakOnError) -{ -} - -void TestResults::OnTestStart(TestDetails const& test) -{ - ++m_totalTestCount; - m_currentTestFailed = false; - if (m_testReporter) m_testReporter->ReportTestStart(test); -} - -#ifdef WIN32 -#define DEBUG_BREAK() __debugbreak() -#else -#define DEBUG_BREAK() raise(SIGTRAP) -#endif - -void TestResults::OnTestFailure(TestDetails const& test, char const* failure) -{ - ++m_failureCount; - if (!m_currentTestFailed) - { - ++m_failedTestCount; - std::string fullTestName(test.suiteName); - fullTestName.append(":"); - fullTestName.append(test.testName); - m_failedTests.push_back(fullTestName); - m_currentTestFailed = true; - } - - if (m_testReporter) - { - m_testReporter->ReportFailure(test, failure); - if (m_breakOnError) - { - DEBUG_BREAK(); - } - } -} - -void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed) -{ - if (m_testReporter) m_testReporter->ReportTestFinish(test, !m_currentTestFailed, secondsElapsed); -} - -int TestResults::GetTotalTestCount() const { return m_totalTestCount; } - -int TestResults::GetFailedTestCount() const { return m_failedTestCount; } - -int TestResults::GetFailureCount() const { return m_failureCount; } - -const std::vector<std::string>& TestResults::GetFailedTests() const { return m_failedTests; } - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestResults.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestResults.h @@ -1,76 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTRESULTS_H -#define UNITTEST_TESTRESULTS_H - -#include "HelperMacros.h" -#include <string> -#include <vector> - -namespace UnitTest -{ -class TestReporter; -class TestDetails; - -class TestResults -{ -public: - UNITTEST_LINKAGE explicit TestResults(TestReporter* reporter = 0, bool breakOnError = false); - - UNITTEST_LINKAGE void OnTestStart(TestDetails const& test); - UNITTEST_LINKAGE void OnTestFailure(TestDetails const& test, char const* failure); - UNITTEST_LINKAGE void OnTestFinish(TestDetails const& test, float secondsElapsed); - - UNITTEST_LINKAGE int GetTotalTestCount() const; - UNITTEST_LINKAGE int GetFailedTestCount() const; - UNITTEST_LINKAGE int GetFailureCount() const; - - UNITTEST_LINKAGE const std::vector<std::string>& GetFailedTests() const; - -private: - TestReporter* m_testReporter; - int m_totalTestCount; - int m_failedTestCount; - int m_failureCount; - - bool m_currentTestFailed; - const bool m_breakOnError; - - std::vector<std::string> m_failedTests; - - TestResults(TestResults const&); - TestResults& operator=(TestResults const&); -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestRunner.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestRunner.cpp @@ -1,199 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "TestRunner.h" - -#include "TestMacros.h" - -#if _MSC_VER == 1600 -#include <agents.h> -#include <functional> -#else -#include <future> -#endif - -#if (defined(ANDROID) || defined(__ANDROID__)) -#include <boost/scope_exit.hpp> -#include <jni.h> -#endif - -#include <cstdlib> - -#if (defined(ANDROID) || defined(__ANDROID__)) -namespace crossplat -{ -extern std::atomic<JavaVM*> JVM; -} -#endif - -namespace UnitTest -{ -TestRunner::TestRunner(TestReporter& reporter, bool breakOnError) - : m_reporter(&reporter), m_result(new TestResults(&reporter, breakOnError)), m_timer(new Timer) -{ - m_timer->Start(); -} - -TestRunner::~TestRunner() -{ - delete m_result; - delete m_timer; -} - -TestResults* TestRunner::GetTestResults() { return m_result; } - -int TestRunner::Finish() const -{ - float const secondsElapsed = static_cast<float>(m_timer->GetTimeInMs() / 1000.0); - m_reporter->ReportSummary( - m_result->GetTotalTestCount(), m_result->GetFailedTestCount(), m_result->GetFailureCount(), secondsElapsed); - - return m_result->GetFailureCount(); -} - -bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) const -{ - using namespace std; - return (suiteName == NULL) || !strcmp(curTest->m_details.suiteName, suiteName); -} - -#if _MSC_VER == 1600 -// std::future and std::thread doesn't exist on Visual Studio 2010 so fall back -// to use agent. -class TestRunnerAgent : public Concurrency::agent -{ -public: - TestRunnerAgent(std::tr1::function<void()> func) : m_func(func) {} - -protected: - void run() - { - Concurrency::Context::Oversubscribe(true); - m_func(); - Concurrency::Context::Oversubscribe(false); - done(); - } - -private: - std::tr1::function<void()> m_func; -}; -#endif - -// Logic to decide the timeout for individual test -// 1. If /testtimeout is specified with testrunner arguments, use that timeout. -// 2. Else, if the test has a Timeout property set, use that timeout. -// 3. If both the above properties are not specified, use the default timeout value. -int TestRunner::GetTestTimeout(Test* const curTest, int const defaultTestTimeInMs) const -{ - std::stringstream timeoutstream; - int timeout = defaultTestTimeInMs; - if (UnitTest::GlobalSettings::Has("testtimeout")) - { - timeoutstream << UnitTest::GlobalSettings::Get("testtimeout"); - timeoutstream >> timeout; - } - else if (curTest->m_properties.Has("Timeout")) - { - timeoutstream << curTest->m_properties.Get("Timeout"); - timeoutstream >> timeout; - } - return timeout; -} - -void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const defaultTestTimeInMs) const -{ - if (curTest->m_isMockTest == false) CurrentTest::SetResults(result); - - int maxTestTimeInMs = GetTestTimeout(curTest, defaultTestTimeInMs); - - Timer testTimer; - testTimer.Start(); - - result->OnTestStart(curTest->m_details); - - if (maxTestTimeInMs > 0) - { - bool timedOut = false; -#if _MSC_VER == 1600 - TestRunnerAgent testRunnerAgent([&]() { curTest->Run(); }); - testRunnerAgent.start(); - try - { - Concurrency::agent::wait(&testRunnerAgent, maxTestTimeInMs); - } - catch (const Concurrency::operation_timed_out&) - { - timedOut = true; - } -#else - // Timed wait requires async execution. - auto testRunnerFuture = std::async(std::launch::async, [&]() { -#if (defined(ANDROID) || defined(__ANDROID__)) - JNIEnv* env = nullptr; - auto result = crossplat::JVM.load()->AttachCurrentThread(&env, nullptr); - if (result != JNI_OK) - { - throw std::runtime_error("Could not attach to JVM"); - } - BOOST_SCOPE_EXIT(void) { crossplat::JVM.load()->DetachCurrentThread(); } - BOOST_SCOPE_EXIT_END -#endif - curTest->Run(); - }); - std::chrono::system_clock::time_point totalTime = - std::chrono::system_clock::now() + std::chrono::milliseconds(maxTestTimeInMs); - if (testRunnerFuture.wait_until(totalTime) == std::future_status::timeout) - { - timedOut = true; - } -#endif - if (timedOut) - { - MemoryOutStream stream; - stream << "Test case timed out and is hung. Aborting all remaining test cases. "; - stream << "Expected under " << maxTestTimeInMs << "ms."; - result->OnTestFailure(curTest->m_details, stream.GetText()); - - abort(); - } - } - else - { - curTest->Run(); - } - - double const testTimeInMs = testTimer.GetTimeInMs(); - result->OnTestFinish(curTest->m_details, static_cast<float>(testTimeInMs / 1000.0)); -} - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestRunner.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestRunner.h @@ -1,107 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTRUNNER_H -#define UNITTEST_TESTRUNNER_H - -#include "CurrentTest.h" -#include "GlobalSettings.h" -#include "Test.h" -#include "TestList.h" - -namespace UnitTest -{ -class TestReporter; -class TestResults; -class Timer; - -struct True -{ - bool operator()(const Test* const) const { return true; } -}; - -class TestRunner -{ -public: - UNITTEST_LINKAGE explicit TestRunner(TestReporter& reporter, bool breakOnError = false); - UNITTEST_LINKAGE ~TestRunner(); - - template<class Predicate> - int RunTestsIf(TestList const& list, const Predicate& predicate, int defaultTestTimeInMs) const - { - return RunTestsIf(list, nullptr, predicate, defaultTestTimeInMs); - } - - template<class Predicate> - int RunTestsIf(TestList const& list, - char const* suiteName, - const Predicate& predicate, - int defaultTestTimeInMs) const - { - Test* curTest = list.GetFirst(); - - while (curTest != 0) - { - if (IsTestInSuite(curTest, suiteName) && predicate(curTest)) - RunTest(m_result, curTest, defaultTestTimeInMs); - - curTest = curTest->m_nextTest; - } - - return Finish(); - } - - int RunTests(TestList const& list, char const* suiteName, int defaultTestTimeInMs) const - { - return RunTestsIf(list, suiteName, True(), defaultTestTimeInMs); - } - int RunTests(TestList const& list, int defaultTestTimeInMs) const - { - return RunTestsIf(list, nullptr, True(), defaultTestTimeInMs); - } - - UNITTEST_LINKAGE TestResults* GetTestResults(); - -private: - TestReporter* m_reporter; - TestResults* m_result; - Timer* m_timer; - - int GetTestTimeout(Test* const curTest, int const defaultTestTimeInMs) const; - - UNITTEST_LINKAGE int Finish() const; - UNITTEST_LINKAGE bool IsTestInSuite(const Test* const curTest, char const* suiteName) const; - UNITTEST_LINKAGE void RunTest(TestResults* const result, Test* const curTest, int const defaultTestTimeInMs) const; -}; - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestSuite.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TestSuite.h @@ -1,40 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TESTSUITE_H -#define UNITTEST_TESTSUITE_H - -namespace UnitTestSuite -{ -inline char const* GetSuiteName() { return "DefaultSuite"; } -} // namespace UnitTestSuite - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TimeHelpers.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/TimeHelpers.h @@ -1,38 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "../config.h" - -#if defined UNITTEST_POSIX -#include "Posix/TimeHelpers.h" -#else -#include "Win32/TimeHelpers.h" -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Win32/TimeHelpers.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Win32/TimeHelpers.cpp @@ -1,69 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -namespace UnitTest -{ -Timer::Timer() : m_threadHandle(::GetCurrentThread()), m_startTime(0) -{ -#if defined(UNITTEST_WIN32) && (_MSC_VER == 1200) // VC6 doesn't have DWORD_PTR - typedef unsigned long DWORD_PTR; -#endif - - DWORD_PTR systemMask; - ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask); - ::SetThreadAffinityMask(m_threadHandle, 1); - ::QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&m_frequency)); - ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask); -} - -void Timer::Start() { m_startTime = GetTime(); } - -double Timer::GetTimeInMs() const -{ - __int64 const elapsedTime = GetTime() - m_startTime; - double const seconds = double(elapsedTime) / double(m_frequency); - return seconds * 1000.0; -} - -__int64 Timer::GetTime() const -{ - LARGE_INTEGER curTime; - ::SetThreadAffinityMask(m_threadHandle, 1); - ::QueryPerformanceCounter(&curTime); - ::SetThreadAffinityMask(m_threadHandle, m_processAffinityMask); - return curTime.QuadPart; -} - -void TimeHelpers::SleepMs(int ms) { ::Sleep(ms); } - -} // namespace UnitTest diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Win32/TimeHelpers.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/Win32/TimeHelpers.h @@ -1,75 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_TIMEHELPERS_H -#define UNITTEST_TIMEHELPERS_H - -#include "../../config.h" -#include "../HelperMacros.h" - -#ifdef UNITTEST_MINGW -#ifndef __int64 -#define __int64 long long -#endif -#endif - -namespace UnitTest -{ -class Timer -{ -public: - UNITTEST_LINKAGE Timer(); - UNITTEST_LINKAGE void Start(); - UNITTEST_LINKAGE double GetTimeInMs() const; - -private: - __int64 GetTime() const; - - void* m_threadHandle; - -#if defined(_WIN64) - unsigned __int64 m_processAffinityMask; -#else - unsigned long m_processAffinityMask; -#endif - - __int64 m_startTime; - __int64 m_frequency; -}; - -namespace TimeHelpers -{ -UNITTEST_LINKAGE void SleepMs(int ms); -} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/XmlTestReporter.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/XmlTestReporter.cpp @@ -1,152 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "XmlTestReporter.h" -#include <iostream> -#include <sstream> - -using std::ostream; -using std::ostringstream; -using std::string; - -namespace -{ -void ReplaceChar(string& str, char c, string const& replacement) -{ - for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1)) - str.replace(pos, 1, replacement); -} - -string XmlEscape(string const& value) -{ - string escaped = value; - - ReplaceChar(escaped, '&', "&"); - ReplaceChar(escaped, '<', "<"); - ReplaceChar(escaped, '>', ">"); - ReplaceChar(escaped, '\'', "'"); - ReplaceChar(escaped, '\"', """); - - return escaped; -} - -string BuildFailureMessage(string const& file, int line, string const& message) -{ - ostringstream failureMessage; - failureMessage << file << "(" << line << ") : " << message; - return failureMessage.str(); -} - -} // namespace - -namespace UnitTest -{ -XmlTestReporter::XmlTestReporter(ostream& ostream) : m_ostream(ostream) {} - -void XmlTestReporter::ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) -{ - AddXmlElement(m_ostream, NULL); - - BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed); - - DeferredTestResultList const& results = GetResults(); - for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i) - { - BeginTest(m_ostream, *i); - - if (i->failed) AddFailure(m_ostream, *i); - - EndTest(m_ostream, *i); - } - - EndResults(m_ostream); -} - -void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding) -{ - os << "<?xml version=\"1.0\""; - - if (encoding != NULL) os << " encoding=\"" << encoding << "\""; - - os << "?>"; -} - -void XmlTestReporter::BeginResults( - std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) -{ - os << "<unittest-results" - << " tests=\"" << totalTestCount << "\"" - << " failedtests=\"" << failedTestCount << "\"" - << " failures=\"" << failureCount << "\"" - << " time=\"" << secondsElapsed << "\"" - << ">"; -} - -void XmlTestReporter::EndResults(std::ostream& os) { os << "</unittest-results>"; } - -void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result) -{ - os << "<test" - << " suite=\"" << result.suiteName << "\"" - << " name=\"" << result.testName << "\"" - << " time=\"" << result.timeElapsed << "\""; -} - -void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result) -{ - if (result.failed) - os << "</test>"; - else - os << "/>"; -} - -void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result) -{ - os << ">"; // close <test> element - - for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin(); it != result.failures.end(); ++it) - { - string const escapedMessage = XmlEscape(std::string(it->failureStr)); - string const message = BuildFailureMessage(result.failureFile, it->lineNumber, escapedMessage); - - os << "<failure" - << " message=\"" << message << "\"" - << "/>"; - } -} - -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/XmlTestReporter.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/XmlTestReporter.h @@ -1,71 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_XMLTESTREPORTER_H -#define UNITTEST_XMLTESTREPORTER_H - -#include "../config.h" -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "DeferredTestReporter.h" -#include <iosfwd> - -namespace UnitTest -{ -class XmlTestReporter : public DeferredTestReporter -{ -public: - explicit UNITTEST_LINKAGE XmlTestReporter(std::ostream& ostream); - - virtual UNITTEST_LINKAGE void ReportSummary(int totalTestCount, - int failedTestCount, - int failureCount, - float secondsElapsed); - -private: - XmlTestReporter(XmlTestReporter const&); - XmlTestReporter& operator=(XmlTestReporter const&); - - void AddXmlElement(std::ostream& os, char const* encoding); - void BeginResults( - std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); - void EndResults(std::ostream& os); - void BeginTest(std::ostream& os, DeferredTestResult const& result); - void AddFailure(std::ostream& os, DeferredTestResult const& result); - void EndTest(std::ostream& os, DeferredTestResult const& result); - - std::ostream& m_ostream; -}; - -} // namespace UnitTest - -#endif -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/stdafx.cpp @@ -1,35 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h"- \ No newline at end of file diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/stdafx.h @@ -1,53 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#pragma once - -#include "../config.h" -#include "AssertException.h" -#include "CurrentTest.h" -#include "DeferredTestReporter.h" -#include "MemoryOutStream.h" -#include "Test.h" -#include "TestDetails.h" -#include "TestList.h" -#include "TestReporter.h" -#include "TestReporterStdout.h" -#include "TestResults.h" -#include "TimeHelpers.h" -#include <cstddef> -#include <cstdio> -#include <cstring> - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include <Windows.h> -#endif- \ No newline at end of file diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/RecordingReporter.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/RecordingReporter.h @@ -1,130 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_RECORDINGREPORTER_H -#define UNITTEST_RECORDINGREPORTER_H - -#include "../TestDetails.h" -#include "../TestReporter.h" -#include <cstring> - -struct RecordingReporter : public UnitTest::TestReporter -{ -private: - enum - { - kMaxStringLength = 256 - }; - -public: - RecordingReporter() - : testRunCount(0) - , testFailedCount(0) - , lastFailedLine(0) - , testFinishedCount(0) - , lastFinishedTestTime(0) - , summaryTotalTestCount(0) - , summaryFailedTestCount(0) - , summaryFailureCount(0) - , summarySecondsElapsed(0) - { - lastStartedSuite[0] = '\0'; - lastStartedTest[0] = '\0'; - lastFailedFile[0] = '\0'; - lastFailedSuite[0] = '\0'; - lastFailedTest[0] = '\0'; - lastFailedMessage[0] = '\0'; - lastFinishedSuite[0] = '\0'; - lastFinishedTest[0] = '\0'; - } - - virtual void ReportTestStart(UnitTest::TestDetails const& test) - { - using namespace std; - - ++testRunCount; - strcpy(lastStartedSuite, test.suiteName); - strcpy(lastStartedTest, test.testName); - } - - virtual void ReportFailure(UnitTest::TestDetails const& test, char const* failure) - { - using namespace std; - - ++testFailedCount; - strcpy(lastFailedFile, test.filename); - lastFailedLine = test.lineNumber; - strcpy(lastFailedSuite, test.suiteName); - strcpy(lastFailedTest, test.testName); - strcpy(lastFailedMessage, failure); - } - - virtual void ReportTestFinish(UnitTest::TestDetails const& test, bool, float testDuration) - { - using namespace std; - - ++testFinishedCount; - strcpy(lastFinishedSuite, test.suiteName); - strcpy(lastFinishedTest, test.testName); - lastFinishedTestTime = testDuration; - } - - virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) - { - summaryTotalTestCount = totalTestCount; - summaryFailedTestCount = failedTestCount; - summaryFailureCount = failureCount; - summarySecondsElapsed = secondsElapsed; - } - - int testRunCount; - char lastStartedSuite[kMaxStringLength]; - char lastStartedTest[kMaxStringLength]; - - int testFailedCount; - char lastFailedFile[kMaxStringLength]; - int lastFailedLine; - char lastFailedSuite[kMaxStringLength]; - char lastFailedTest[kMaxStringLength]; - char lastFailedMessage[kMaxStringLength]; - - int testFinishedCount; - char lastFinishedSuite[kMaxStringLength]; - char lastFinishedTest[kMaxStringLength]; - float lastFinishedTestTime; - - int summaryTotalTestCount; - int summaryFailedTestCount; - int summaryFailureCount; - float summarySecondsElapsed; -}; - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/ScopedCurrentTest.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/ScopedCurrentTest.h @@ -1,65 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTEST_SCOPEDCURRENTTEST_H -#define UNITTEST_SCOPEDCURRENTTEST_H - -#include "../CurrentTest.h" -#include <cstddef> - -class ScopedCurrentTest -{ -public: - ScopedCurrentTest() - : m_oldTestResults(UnitTest::CurrentTest::Results()), m_oldTestDetails(UnitTest::CurrentTest::Details()) - { - } - - explicit ScopedCurrentTest(UnitTest::TestResults& newResults, const UnitTest::TestDetails* newDetails = NULL) - : m_oldTestResults(UnitTest::CurrentTest::Results()), m_oldTestDetails(UnitTest::CurrentTest::Details()) - { - UnitTest::CurrentTest::Results() = &newResults; - - if (newDetails != NULL) UnitTest::CurrentTest::Details() = newDetails; - } - - ~ScopedCurrentTest() - { - UnitTest::CurrentTest::Results() = m_oldTestResults; - UnitTest::CurrentTest::Details() = m_oldTestDetails; - } - -private: - UnitTest::TestResults* m_oldTestResults; - const UnitTest::TestDetails* m_oldTestDetails; -}; - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestAssertHandler.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestAssertHandler.cpp @@ -1,159 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "../AssertException.h" -#include <csetjmp> - -using namespace UnitTest; - -namespace -{ -TEST(CanSetAssertExpected) -{ - Detail::ExpectAssert(true); - CHECK(Detail::AssertExpected()); - - Detail::ExpectAssert(false); - CHECK(!Detail::AssertExpected()); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -TEST(ReportAssertThrowsAssertException) -{ - bool caught = false; - - try - { - TestResults testResults; - TestDetails testDetails("", "", "", 0); - Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); - } - catch (AssertException const&) - { - caught = true; - } - - CHECK(true == caught); -} - -TEST(ReportAssertClearsExpectAssertFlag) -{ - RecordingReporter reporter; - TestResults testResults(&reporter); - TestDetails testDetails("", "", "", 0); - - try - { - Detail::ExpectAssert(true); - Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); - } - catch (AssertException const&) - { - } - - CHECK(Detail::AssertExpected() == false); - CHECK_EQUAL(0, reporter.testFailedCount); -} - -TEST(ReportAssertWritesFailureToResultsAndDetailsWhenAssertIsNotExpected) -{ - const int lineNumber = 12345; - const char* description = "description"; - const char* filename = "filename"; - - RecordingReporter reporter; - TestResults testResults(&reporter); - TestDetails testDetails("", "", "", 0); - - try - { - Detail::ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber); - } - catch (AssertException const&) - { - } - - CHECK_EQUAL(description, reporter.lastFailedMessage); - CHECK_EQUAL(filename, reporter.lastFailedFile); - CHECK_EQUAL(lineNumber, reporter.lastFailedLine); -} - -TEST(ReportAssertReportsNoErrorsWhenAssertIsExpected) -{ - Detail::ExpectAssert(true); - - RecordingReporter reporter; - TestResults testResults(&reporter); - TestDetails testDetails("", "", "", 0); - - try - { - Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0); - } - catch (AssertException const&) - { - } - - CHECK_EQUAL(0, reporter.testFailedCount); -} - -TEST(CheckAssertMacroSetsAssertExpectationToFalseAfterRunning) -{ - Detail::ExpectAssert(true); - CHECK_ASSERT(ReportAssert("", "", 0)); - CHECK(!Detail::AssertExpected()); - Detail::ExpectAssert(false); -} - -#else - -TEST(SetAssertJumpTargetReturnsFalseWhenSettingJumpTarget) { CHECK(UNITTEST_SET_ASSERT_JUMP_TARGET() == false); } - -TEST(JumpToAssertJumpTarget_JumpsToSetPoint_ReturnsTrue) -{ - const volatile bool taken = !!UNITTEST_SET_ASSERT_JUMP_TARGET(); - - volatile bool set = false; - if (taken == false) - { - UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET(); - set = true; - } - - CHECK(set == false); -} - -#endif - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestCheckMacros.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestCheckMacros.cpp @@ -1,550 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -using namespace std; - -namespace -{ -TEST(CheckSucceedsOnTrue) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - - ScopedCurrentTest scopedResults(testResults); - CHECK(true); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckFailsOnFalse) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK(false); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(FailureReportsCorrectTestName) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK(false); - } - - CHECK_EQUAL(m_details.testName, reporter.lastFailedTest); -} - -TEST(CheckFailureIncludesCheckContents) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - const bool yaddayadda = false; - CHECK(yaddayadda); - } - - CHECK(strstr(reporter.lastFailedMessage, "yaddayadda")); -} - -TEST(CheckEqualSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(1, 1); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckEqualFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(1, 2); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckEqualFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails const testDetails("testName", "suiteName", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - CHECK_EQUAL(1, 123); - line = __LINE__; - } - - CHECK_EQUAL("testName", reporter.lastFailedTest); - CHECK_EQUAL("suiteName", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -int g_sideEffect = 0; -int FunctionWithSideEffects() -{ - ++g_sideEffect; - return 1; -} - -TEST(CheckEqualDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(1, FunctionWithSideEffects()); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckEqualDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_EQUAL(2, FunctionWithSideEffects()); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckCloseSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE(1.0f, 1.001f, 0.01f); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckCloseFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE(1.0f, 1.1f, 0.01f); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckCloseFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("test", "suite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - CHECK_CLOSE(1.0f, 1.1f, 0.01f); - line = __LINE__; - } - - CHECK_EQUAL("test", reporter.lastFailedTest); - CHECK_EQUAL("suite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckCloseDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE(1, FunctionWithSideEffects(), 0.1f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckCloseDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - CHECK_CLOSE(2, FunctionWithSideEffects(), 0.1f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArrayCloseSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - const float data[4] = {0, 1, 2, 3}; - CHECK_ARRAY_CLOSE(data, data, 4, 0.01f); - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckArrayCloseFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = {0, 1, 2, 3}; - int const data2[4] = {0, 1, 3, 3}; - CHECK_ARRAY_CLOSE(data1, data2, 4, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArrayCloseFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = {0, 1, 2, 3}; - int const data2[4] = {0, 1, 3, 3}; - CHECK_ARRAY_CLOSE(data1, data2, 4, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); - CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); -} - -TEST(CheckArrayCloseFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("arrayCloseTest", "arrayCloseSuite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - int const data1[4] = {0, 1, 2, 3}; - int const data2[4] = {0, 1, 3, 3}; - CHECK_ARRAY_CLOSE(data1, data2, 4, 0.01f); - line = __LINE__; - } - - CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckArrayCloseFailureIncludesTolerance) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - float const data1[4] = {0, 1, 2, 3}; - float const data2[4] = {0, 1, 3, 3}; - CHECK_ARRAY_CLOSE(data1, data2, 4, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "0.01")); -} - -TEST(CheckArrayEqualSuceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[4] = {0, 1, 2, 3}; - CHECK_ARRAY_EQUAL(data, data, 4); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckArrayEqualFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = {0, 1, 2, 3}; - int const data2[4] = {0, 1, 3, 3}; - CHECK_ARRAY_EQUAL(data1, data2, 4); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArrayEqualFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = {0, 1, 2, 3}; - int const data2[4] = {0, 1, 3, 3}; - CHECK_ARRAY_EQUAL(data1, data2, 4); - } - - CHECK(strstr(reporter.lastFailedMessage, "xpected [ 0 1 2 3 ]")); - CHECK(strstr(reporter.lastFailedMessage, "was [ 0 1 3 3 ]")); -} - -TEST(CheckArrayEqualFailureContainsCorrectInfo) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[4] = {0, 1, 2, 3}; - int const data2[4] = {0, 1, 3, 3}; - CHECK_ARRAY_EQUAL(data1, data2, 4); - line = __LINE__; - } - - CHECK_EQUAL("CheckArrayEqualFailureContainsCorrectInfo", reporter.lastFailedTest); - CHECK_EQUAL(__FILE__, reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -float const* FunctionWithSideEffects2() -{ - ++g_sideEffect; - static float const data[] = {1, 2, 3, 4}; - return data; -} - -TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[] = {0, 1, 2, 3}; - CHECK_ARRAY_CLOSE(data, FunctionWithSideEffects2(), 4, 0.01f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArrayCloseDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[] = {0, 1, 3, 3}; - CHECK_ARRAY_CLOSE(data, FunctionWithSideEffects2(), 4, 0.01f); - } - - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArray2DCloseSucceedsOnEqual) -{ - bool failure = true; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = {{0, 1}, {2, 3}}; - CHECK_ARRAY2D_CLOSE(data, data, 2, 2, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(!failure); -} - -TEST(CheckArray2DCloseFailsOnNotEqual) -{ - bool failure = false; - { - RecordingReporter reporter; - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[2][2] = {{0, 1}, {2, 3}}; - int const data2[2][2] = {{0, 1}, {3, 3}}; - CHECK_ARRAY2D_CLOSE(data1, data2, 2, 2, 0.01f); - - failure = (testResults.GetFailureCount() > 0); - } - - CHECK(failure); -} - -TEST(CheckArray2DCloseFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - int const data1[2][2] = {{0, 1}, {2, 3}}; - int const data2[2][2] = {{0, 1}, {3, 3}}; - - CHECK_ARRAY2D_CLOSE(data1, data2, 2, 2, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "xpected [ [ 0 1 ] [ 2 3 ] ]")); - CHECK(strstr(reporter.lastFailedMessage, "was [ [ 0 1 ] [ 3 3 ] ]")); -} - -TEST(CheckArray2DCloseFailureContainsCorrectDetails) -{ - int line = 0; - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - UnitTest::TestDetails testDetails("array2DCloseTest", "array2DCloseSuite", "filename", -1); - ScopedCurrentTest scopedResults(testResults, &testDetails); - - int const data1[2][2] = {{0, 1}, {2, 3}}; - int const data2[2][2] = {{0, 1}, {3, 3}}; - CHECK_ARRAY2D_CLOSE(data1, data2, 2, 2, 0.01f); - line = __LINE__; - } - - CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(line, reporter.lastFailedLine); -} - -TEST(CheckArray2DCloseFailureIncludesTolerance) -{ - RecordingReporter reporter; - { - UnitTest::TestResults testResults(&reporter); - ScopedCurrentTest scopedResults(testResults); - - float const data1[2][2] = {{0, 1}, {2, 3}}; - float const data2[2][2] = {{0, 1}, {3, 3}}; - CHECK_ARRAY2D_CLOSE(data1, data2, 2, 2, 0.01f); - } - - CHECK(strstr(reporter.lastFailedMessage, "0.01")); -} - -float const* const* FunctionWithSideEffects3() -{ - ++g_sideEffect; - static float const data1[] = {0, 1}; - static float const data2[] = {2, 3}; - static const float* const data[] = {data1, data2}; - return data; -} - -TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenPassing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = {{0, 1}, {2, 3}}; - CHECK_ARRAY2D_CLOSE(data, FunctionWithSideEffects3(), 2, 2, 0.01f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -TEST(CheckArray2DCloseDoesNotHaveSideEffectsWhenFailing) -{ - g_sideEffect = 0; - { - UnitTest::TestResults testResults; - ScopedCurrentTest scopedResults(testResults); - - const float data[2][2] = {{0, 1}, {3, 3}}; - CHECK_ARRAY2D_CLOSE(data, FunctionWithSideEffects3(), 2, 2, 0.01f); - } - CHECK_EQUAL(1, g_sideEffect); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestChecks.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestChecks.cpp @@ -1,300 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -using namespace UnitTest; - -namespace -{ -TEST(CheckEqualWithUnsignedLong) -{ - TestResults results; - unsigned long something = 2; - CHECK_EQUAL(something, something); -} - -TEST(CheckEqualsWithStringsFailsOnDifferentStrings) -{ - char txt1[] = "Hello"; - char txt2[] = "Hallo"; - TestResults results; - CheckEqual(results, "txt1", "txt2", txt1, txt2, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -char txt1[] = "Hello"; // non-const on purpose so no folding of duplicate data -char txt2[] = "Hello"; - -TEST(CheckEqualsWithStringsWorksOnContentsNonConstNonConst) -{ - char const* const p1 = txt1; - char const* const p2 = txt2; - TestResults results; - CheckEqual(results, "p1", "p2", p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsConstConst) -{ - char* const p1 = txt1; - char* const p2 = txt2; - TestResults results; - CheckEqual(results, "p1", "p2", p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsNonConstConst) -{ - char* const p1 = txt1; - char const* const p2 = txt2; - TestResults results; - CheckEqual(results, "p1", "p2", p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsConstNonConst) -{ - char const* const p1 = txt1; - char* const p2 = txt2; - TestResults results; - CheckEqual(results, "p1", "p2", p1, p2, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualsWithStringsWorksOnContentsWithALiteral) -{ - char const* const p1 = txt1; - TestResults results; - CheckEqual(results, "Hello", "p1", "Hello", p1, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckEqualFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - TestResults results(&reporter); - const int something = 2; - CheckEqual(results, "1", "something", 1, something, TestDetails("", "", "", 0)); - - using namespace std; - CHECK(strstr(reporter.lastFailedMessage, "1=1")); - CHECK(strstr(reporter.lastFailedMessage, "something=2")); -} - -TEST(CheckEqualFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("mytest", "mysuite", "file.h", 101); - - CheckEqual(results, "1", "2", 1, 2, details); - - CHECK_EQUAL("mytest", reporter.lastFailedTest); - CHECK_EQUAL("mysuite", reporter.lastFailedSuite); - CHECK_EQUAL("file.h", reporter.lastFailedFile); - CHECK_EQUAL(101, reporter.lastFailedLine); -} - -TEST(CheckCloseTrue) -{ - TestResults results; - CheckClose(results, 3.001f, 3.0f, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckCloseFalse) -{ - TestResults results; - CheckClose(results, 3.12f, 3.0f, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseWithZeroEpsilonWorksForSameNumber) -{ - TestResults results; - CheckClose(results, 0.1f, 0.1f, 0, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckCloseWithNaNFails) -{ - const unsigned int bitpattern = 0xFFFFFFFF; - float nan; - std::memcpy(&nan, &bitpattern, sizeof(bitpattern)); - - TestResults results; - CheckClose(results, 3.0f, nan, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseWithNaNAgainstItselfFails) -{ - const unsigned int bitpattern = 0xFFFFFFFF; - float nan; - std::memcpy(&nan, &bitpattern, sizeof(bitpattern)); - - TestResults results; - CheckClose(results, nan, nan, 0.1f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseFailureIncludesCheckExpectedAndActual) -{ - RecordingReporter reporter; - TestResults results(&reporter); - const float expected = 0.9f; - const float actual = 1.1f; - CheckClose(results, expected, actual, 0.01f, TestDetails("", "", "", 0)); - - using namespace std; - CHECK(strstr(reporter.lastFailedMessage, "xpected 0.9")); - CHECK(strstr(reporter.lastFailedMessage, "was 1.1")); -} - -TEST(CheckCloseFailureIncludesTolerance) -{ - RecordingReporter reporter; - TestResults results(&reporter); - CheckClose(results, 2, 3, 0.01f, TestDetails("", "", "", 0)); - - using namespace std; - CHECK(strstr(reporter.lastFailedMessage, "0.01")); -} - -TEST(CheckCloseFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("mytest", "mysuite", "header.h", 10); - - CheckClose(results, 2, 3, 0.01f, details); - - CHECK_EQUAL("mytest", reporter.lastFailedTest); - CHECK_EQUAL("mysuite", reporter.lastFailedSuite); - CHECK_EQUAL("header.h", reporter.lastFailedFile); - CHECK_EQUAL(10, reporter.lastFailedLine); -} - -TEST(CheckArrayEqualTrue) -{ - TestResults results; - - int const array[3] = {1, 2, 3}; - CheckArrayEqual(results, array, array, 3, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckArrayEqualFalse) -{ - TestResults results; - - int const array1[3] = {1, 2, 3}; - int const array2[3] = {1, 2, 2}; - CheckArrayEqual(results, array1, array2, 3, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckArrayCloseTrue) -{ - TestResults results; - - float const array1[3] = {1.0f, 1.5f, 2.0f}; - float const array2[3] = {1.01f, 1.51f, 2.01f}; - CheckArrayClose(results, array1, array2, 3, 0.02f, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckArrayCloseFalse) -{ - TestResults results; - - float const array1[3] = {1.0f, 1.5f, 2.0f}; - float const array2[3] = {1.01f, 1.51f, 2.01f}; - CheckArrayClose(results, array1, array2, 3, 0.001f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckArrayCloseFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("arrayCloseTest", "arrayCloseSuite", "file", 1337); - - float const array1[3] = {1.0f, 1.5f, 2.0f}; - float const array2[3] = {1.01f, 1.51f, 2.01f}; - CheckArrayClose(results, array1, array2, 3, 0.001f, details); - - CHECK_EQUAL("arrayCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("arrayCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("file", reporter.lastFailedFile); - CHECK_EQUAL(1337, reporter.lastFailedLine); -} - -TEST(CheckArray2DCloseTrue) -{ - TestResults results; - - float const array1[3][3] = {{1.0f, 1.5f, 2.0f}, {2.0f, 2.5f, 3.0f}, {3.0f, 3.5f, 4.0f}}; - float const array2[3][3] = {{1.01f, 1.51f, 2.01f}, {2.01f, 2.51f, 3.01f}, {3.01f, 3.51f, 4.01f}}; - CheckArray2DClose(results, array1, array2, 3, 3, 0.02f, TestDetails("", "", "", 0)); - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(CheckArray2DCloseFalse) -{ - TestResults results; - - float const array1[3][3] = {{1.0f, 1.5f, 2.0f}, {2.0f, 2.5f, 3.0f}, {3.0f, 3.5f, 4.0f}}; - float const array2[3][3] = {{1.01f, 1.51f, 2.01f}, {2.01f, 2.51f, 3.01f}, {3.01f, 3.51f, 4.01f}}; - CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, TestDetails("", "", "", 0)); - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckCloseWithDoublesSucceeds) { CHECK_CLOSE(0.5, 0.5, 0.0001); } - -TEST(CheckArray2DCloseFailureIncludesDetails) -{ - RecordingReporter reporter; - TestResults results(&reporter); - TestDetails const details("array2DCloseTest", "array2DCloseSuite", "file", 1234); - - float const array1[3][3] = {{1.0f, 1.5f, 2.0f}, {2.0f, 2.5f, 3.0f}, {3.0f, 3.5f, 4.0f}}; - float const array2[3][3] = {{1.01f, 1.51f, 2.01f}, {2.01f, 2.51f, 3.01f}, {3.01f, 3.51f, 4.01f}}; - CheckArray2DClose(results, array1, array2, 3, 3, 0.001f, details); - - CHECK_EQUAL("array2DCloseTest", reporter.lastFailedTest); - CHECK_EQUAL("array2DCloseSuite", reporter.lastFailedSuite); - CHECK_EQUAL("file", reporter.lastFailedFile); - CHECK_EQUAL(1234, reporter.lastFailedLine); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestCompositeTestReporter.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestCompositeTestReporter.cpp @@ -1,202 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "../CompositeTestReporter.h" - -using namespace UnitTest; - -namespace -{ -TEST(ZeroReportersByDefault) { CHECK_EQUAL(0, CompositeTestReporter().GetReporterCount()); } - -struct MockReporter : TestReporter -{ - MockReporter() - : testStartCalled(false) - , testStartDetails(NULL) - , failureCalled(false) - , failureDetails(NULL) - , failureStr(NULL) - , testFinishCalled(false) - , testFinishDetails(NULL) - , testFinishSecondsElapsed(-1.0f) - , summaryCalled(false) - , summaryTotalTestCount(-1) - , summaryFailureCount(-1) - , summarySecondsElapsed(-1.0f) - { - } - - virtual void ReportTestStart(TestDetails const& test) - { - testStartCalled = true; - testStartDetails = &test; - } - - virtual void ReportFailure(TestDetails const& test, char const* failure) - { - failureCalled = true; - failureDetails = &test; - failureStr = failure; - } - - virtual void ReportTestFinish(TestDetails const& test, bool, float secondsElapsed) - { - testFinishCalled = true; - testFinishDetails = &test; - testFinishSecondsElapsed = secondsElapsed; - } - - virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) - { - summaryCalled = true; - summaryTotalTestCount = totalTestCount; - summaryFailedTestCount = failedTestCount; - summaryFailureCount = failureCount; - summarySecondsElapsed = secondsElapsed; - } - - bool testStartCalled; - TestDetails const* testStartDetails; - - bool failureCalled; - TestDetails const* failureDetails; - const char* failureStr; - - bool testFinishCalled; - TestDetails const* testFinishDetails; - float testFinishSecondsElapsed; - - bool summaryCalled; - int summaryTotalTestCount; - int summaryFailedTestCount; - int summaryFailureCount; - float summarySecondsElapsed; -}; - -TEST(AddReporter) -{ - MockReporter r; - CompositeTestReporter c; - - CHECK(c.AddReporter(&r)); - CHECK_EQUAL(1, c.GetReporterCount()); -} - -TEST(RemoveReporter) -{ - MockReporter r; - CompositeTestReporter c; - - c.AddReporter(&r); - CHECK(c.RemoveReporter(&r)); - CHECK_EQUAL(0, c.GetReporterCount()); -} - -struct Fixture -{ - Fixture() - { - c.AddReporter(&r0); - c.AddReporter(&r1); - } - - MockReporter r0, r1; - CompositeTestReporter c; -}; - -TEST_FIXTURE(Fixture, ReportTestStartCallsReportTestStartOnAllAggregates) -{ - TestDetails t("", "", "", 0); - c.ReportTestStart(t); - - CHECK(r0.testStartCalled); - CHECK_EQUAL(&t, r0.testStartDetails); - CHECK(r1.testStartCalled); - CHECK_EQUAL(&t, r1.testStartDetails); -} - -TEST_FIXTURE(Fixture, ReportFailureCallsReportFailureOnAllAggregates) -{ - TestDetails t("", "", "", 0); - const char* failStr = "fail"; - c.ReportFailure(t, failStr); - - CHECK(r0.failureCalled); - CHECK_EQUAL(&t, r0.failureDetails); - CHECK_EQUAL(failStr, r0.failureStr); - - CHECK(r1.failureCalled); - CHECK_EQUAL(&t, r1.failureDetails); - CHECK_EQUAL(failStr, r1.failureStr); -} - -TEST_FIXTURE(Fixture, ReportTestFinishCallsReportTestFinishOnAllAggregates) -{ - TestDetails t("", "", "", 0); - const float s = 1.2345f; - c.ReportTestFinish(t, true, s); - - CHECK(r0.testFinishCalled); - CHECK_EQUAL(&t, r0.testFinishDetails); - CHECK_CLOSE(s, r0.testFinishSecondsElapsed, 0.00001f); - - CHECK(r1.testFinishCalled); - CHECK_EQUAL(&t, r1.testFinishDetails); - CHECK_CLOSE(s, r1.testFinishSecondsElapsed, 0.00001f); -} - -TEST_FIXTURE(Fixture, ReportSummaryCallsReportSummaryOnAllAggregates) -{ - TestDetails t("", "", "", 0); - const int testCount = 3; - const int failedTestCount = 4; - const int failureCount = 5; - const float secondsElapsed = 3.14159f; - - c.ReportSummary(testCount, failedTestCount, failureCount, secondsElapsed); - - CHECK(r0.summaryCalled); - CHECK_EQUAL(testCount, r0.summaryTotalTestCount); - CHECK_EQUAL(failedTestCount, r0.summaryFailedTestCount); - CHECK_EQUAL(failureCount, r0.summaryFailureCount); - CHECK_CLOSE(secondsElapsed, r0.summarySecondsElapsed, 0.00001f); - - CHECK(r1.summaryCalled); - CHECK_EQUAL(testCount, r1.summaryTotalTestCount); - CHECK_EQUAL(failedTestCount, r1.summaryFailedTestCount); - CHECK_EQUAL(failureCount, r1.summaryFailureCount); - CHECK_CLOSE(secondsElapsed, r1.summarySecondsElapsed, 0.00001f); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestCurrentTest.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestCurrentTest.cpp @@ -1,66 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -namespace -{ -TEST(CanSetandGetDetails) -{ - bool ok = false; - { - ScopedCurrentTest scopedTest; - - const UnitTest::TestDetails* details = reinterpret_cast<const UnitTest::TestDetails*>(12345); - UnitTest::CurrentTest::Details() = details; - - ok = (UnitTest::CurrentTest::Details() == details); - } - - CHECK(ok); -} - -TEST(CanSetAndGetResults) -{ - bool ok = false; - { - ScopedCurrentTest scopedTest; - - UnitTest::TestResults results; - UnitTest::CurrentTest::Results() = &results; - - ok = (UnitTest::CurrentTest::Results() == &results); - } - - CHECK(ok); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestDeferredTestReporter.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestDeferredTestReporter.cpp @@ -1,148 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "../DeferredTestReporter.h" - -namespace UnitTest -{ -namespace -{ -#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM -MemoryOutStream& operator<<(MemoryOutStream& lhs, const std::string& rhs) -{ - lhs << rhs.c_str(); - return lhs; -} -#endif - -struct MockDeferredTestReporter : public DeferredTestReporter -{ - virtual void ReportSummary(int, int, int, float) {} -}; - -struct DeferredTestReporterFixture -{ - DeferredTestReporterFixture() - : testName("UniqueTestName") - , testSuite("UniqueTestSuite") - , fileName("filename.h") - , lineNumber(12) - , details(testName.c_str(), testSuite.c_str(), fileName.c_str(), lineNumber) - { - } - - MockDeferredTestReporter reporter; - std::string const testName; - std::string const testSuite; - std::string const fileName; - int const lineNumber; - TestDetails const details; -}; - -TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCreatesANewDeferredTest) -{ - reporter.ReportTestStart(details); - CHECK_EQUAL(1, (int)reporter.GetResults().size()); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportTestStartCapturesTestNameAndSuite) -{ - reporter.ReportTestStart(details); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK_EQUAL(testName.c_str(), result.testName); - CHECK_EQUAL(testSuite.c_str(), result.suiteName); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportTestEndCapturesTestTime) -{ - float const elapsed = 123.45f; - reporter.ReportTestStart(details); - reporter.ReportTestFinish(details, true, elapsed); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK_CLOSE(elapsed, result.timeElapsed, 0.0001f); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetails) -{ - char const* failure = "failure"; - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, failure); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK(result.failed == true); - CHECK_EQUAL(fileName.c_str(), result.failureFile); -} - -TEST_FIXTURE(DeferredTestReporterFixture, ReportFailureSavesFailureDetailsForMultipleFailures) -{ - char const* failure1 = "failure 1"; - char const* failure2 = "failure 2"; - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, failure1); - reporter.ReportFailure(details, failure2); - - DeferredTestResult const& result = reporter.GetResults().at(0); - CHECK_EQUAL(2, (int)result.failures.size()); - CHECK_EQUAL(failure1, result.failures[0].failureStr); - CHECK_EQUAL(failure2, result.failures[1].failureStr); -} - -TEST_FIXTURE(DeferredTestReporterFixture, DeferredTestReporterTakesCopyOfFailureMessage) -{ - reporter.ReportTestStart(details); - - char failureMessage[128]; - char const* goodStr = "Real failure message"; - char const* badStr = "Bogus failure message"; - - using namespace std; - - strcpy(failureMessage, goodStr); - reporter.ReportFailure(details, failureMessage); - strcpy(failureMessage, badStr); - - DeferredTestResult const& result = reporter.GetResults().at(0); - DeferredTestFailure const& failure = result.failures.at(0); - CHECK_EQUAL(goodStr, failure.failureStr); -} - -} // namespace -} // namespace UnitTest - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestMemoryOutStream.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestMemoryOutStream.cpp @@ -1,208 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "../MemoryOutStream.h" -#include <climits> -#include <cstdlib> - -using namespace UnitTest; -using namespace std; - -namespace -{ -TEST(DefaultIsEmptyString) -{ - MemoryOutStream const stream; - CHECK(stream.GetText() != 0); - CHECK_EQUAL("", stream.GetText()); -} - -TEST(StreamingTextCopiesCharacters) -{ - MemoryOutStream stream; - stream << "Lalala"; - CHECK_EQUAL("Lalala", stream.GetText()); -} - -TEST(StreamingMultipleTimesConcatenatesResult) -{ - MemoryOutStream stream; - stream << "Bork" - << "To" - << "Fred"; - CHECK_EQUAL("BorkToFred", stream.GetText()); -} - -TEST(StreamingIntWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (int)123; - CHECK_EQUAL("123", stream.GetText()); -} - -TEST(StreamingUnsignedIntWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (unsigned int)123; - CHECK_EQUAL("123", stream.GetText()); -} - -TEST(StreamingLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (long)(-123); - CHECK_EQUAL("-123", stream.GetText()); -} - -TEST(StreamingUnsignedLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (unsigned long)123; - CHECK_EQUAL("123", stream.GetText()); -} - -TEST(StreamingLongLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (long long)(ULONG_MAX)*2; - CHECK_EQUAL("8589934590", stream.GetText()); -} - -TEST(StreamingUnsignedLongLongWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << (unsigned long long)(ULONG_MAX)*2; - CHECK_EQUAL("8589934590", stream.GetText()); -} - -TEST(StreamingFloatWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << 3.1415f; - CHECK(strstr(stream.GetText(), "3.1415")); -} - -TEST(StreamingDoubleWritesCorrectCharacters) -{ - MemoryOutStream stream; - stream << 3.1415; - CHECK(strstr(stream.GetText(), "3.1415")); -} - -TEST(StreamingPointerWritesCorrectCharacters) -{ - MemoryOutStream stream; - int* p = (int*)0x1234; - stream << p; - CHECK(strstr(stream.GetText(), "1234")); -} - -TEST(StreamingSizeTWritesCorrectCharacters) -{ - MemoryOutStream stream; - size_t const s = 53124; - stream << s; - CHECK_EQUAL("53124", stream.GetText()); -} - -TEST(ClearEmptiesMemoryOutStreamContents) -{ - MemoryOutStream stream; - stream << "Hello world"; - stream.Clear(); - CHECK_EQUAL("", stream.GetText()); -} - -#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -TEST(StreamInitialCapacityIsCorrect) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); - CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE, stream.GetCapacity()); -} - -TEST(StreamInitialCapacityIsMultipleOfGrowChunkSize) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE + 1); - CHECK_EQUAL((int)MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity()); -} - -TEST(ExceedingCapacityGrowsBuffer) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); - stream << "012345678901234567890123456789"; - char const* const oldBuffer = stream.GetText(); - stream << "0123456789"; - CHECK(oldBuffer != stream.GetText()); -} - -TEST(ExceedingCapacityGrowsBufferByGrowChunk) -{ - MemoryOutStream stream(MemoryOutStream::GROW_CHUNK_SIZE); - stream << "0123456789012345678901234567890123456789"; - CHECK_EQUAL(MemoryOutStream::GROW_CHUNK_SIZE * 2, stream.GetCapacity()); -} - -TEST(WritingStringLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "0123456789ABCDEF"; - CHECK_EQUAL("0123456789ABCDEF", stream.GetText()); -} - -TEST(WritingIntLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "aaaa" << 123456; - ; - CHECK_EQUAL("aaaa123456", stream.GetText()); -} - -TEST(WritingFloatLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "aaaa" << 123456.0f; - ; - CHECK_EQUAL("aaaa123456.000000f", stream.GetText()); -} - -TEST(WritingSizeTLongerThanCapacityFitsInNewBuffer) -{ - MemoryOutStream stream(8); - stream << "aaaa" << size_t(32145); - CHECK_EQUAL("aaaa32145", stream.GetText()); -} - -#endif - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTest.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTest.cpp @@ -1,145 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -using namespace UnitTest; - -namespace -{ -TEST(PassingTestHasNoFailures) -{ - class PassingTest : public Test - { - public: - PassingTest() : Test("passing") {} - virtual void RunImpl() const { CHECK(true); } - }; - - TestResults results; - { - ScopedCurrentTest scopedResults(results); - PassingTest().Run(); - } - - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(FailingTestHasFailures) -{ - class FailingTest : public Test - { - public: - FailingTest() : Test("failing") {} - virtual void RunImpl() const { CHECK(false); } - }; - - TestResults results; - { - ScopedCurrentTest scopedResults(results); - FailingTest().Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -#ifndef UNITTEST_NO_EXCEPTIONS -TEST(ThrowingTestsAreReportedAsFailures) -{ - class CrashingTest : public Test - { - public: - CrashingTest() : Test("throwing") {} - virtual void RunImpl() const { throw "Blah"; } - }; - - TestResults results; - { - ScopedCurrentTest scopedResult(results); - CrashingTest().Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} -/* -#ifndef UNITTEST_MINGW -TEST(CrashingTestsAreReportedAsFailures) -{ - class CrashingTest : public Test - { - public: - CrashingTest() : Test("crashing") {} - virtual void RunImpl() const - { - reinterpret_cast< void (*)() >(0)(); - } - }; - - TestResults results; - { - ScopedCurrentTest scopedResult(results); - CrashingTest().Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} -#endif -*/ -#endif - -TEST(TestWithUnspecifiedSuiteGetsDefaultSuite) -{ - Test test("test"); - CHECK(test.m_details.suiteName != NULL); - CHECK_EQUAL("DefaultSuite", test.m_details.suiteName); -} - -TEST(TestReflectsSpecifiedSuiteName) -{ - Test test("test", "testSuite"); - CHECK(test.m_details.suiteName != NULL); - CHECK_EQUAL("testSuite", test.m_details.suiteName); -} - -void Fail() { CHECK(false); } - -TEST(OutOfCoreCHECKMacrosCanFailTests) -{ - TestResults results; - { - ScopedCurrentTest scopedResult(results); - Fail(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestList.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestList.cpp @@ -1,79 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -using namespace UnitTest; - -namespace -{ -TEST(TestListIsEmptyByDefault) -{ - TestList list; - CHECK(list.GetFirst() == 0); -} - -TEST(AddingTestSetsHeadToTest) -{ - Test test("test"); - TestList list; - list.Add(&test); - - CHECK(list.GetFirst() == &test); - CHECK(test.m_nextTest == 0); -} - -TEST(AddingSecondTestAddsItToEndOfList) -{ - Test test1("test1"); - Test test2("test2"); - - TestList list; - list.Add(&test1); - list.Add(&test2); - - CHECK(list.GetFirst() == &test1); - CHECK(test1.m_nextTest == &test2); - CHECK(test2.m_nextTest == 0); -} - -TEST(ListAdderAddsTestToList) -{ - TestList list; - - Test test(""); - ListAdder adder(list, &test, nullptr); - - CHECK(list.GetFirst() == &test); - CHECK(test.m_nextTest == 0); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestMacros.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestMacros.cpp @@ -1,201 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -using namespace UnitTest; -using namespace std; - -#ifdef __APPLE__ -extern "C" UnitTest::TestList& UnitTest::GetTestList() -{ - static TestList s_list; - return s_list; -} -#endif - -namespace -{ -TestList list1; -TEST_EX(DummyTest, list1) {} - -TEST(TestsAreAddedToTheListThroughMacro) -{ - CHECK(list1.GetFirst() != 0); - CHECK(list1.GetFirst()->m_nextTest == 0); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -struct ThrowingThingie -{ - ThrowingThingie() : dummy(false) - { - if (!dummy) throw "Oops"; - } - - bool dummy; -}; - -TestList list2; -TEST_FIXTURE_EX(ThrowingThingie, DummyTestName, list2) {} - -TEST(ExceptionsInFixtureAreReportedAsHappeningInTheFixture) -{ - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResults(result); - list2.GetFirst()->Run(); - } - - CHECK(strstr(reporter.lastFailedMessage, "xception")); - CHECK(strstr(reporter.lastFailedMessage, "fixture")); - CHECK(strstr(reporter.lastFailedMessage, "ThrowingThingie")); -} - -#endif - -struct DummyFixture -{ - int x; -}; - -// We're really testing the macros so we just want them to compile and link -SUITE(TestSuite1) -{ - TEST(SimilarlyNamedTestsInDifferentSuitesWork) {} - - TEST_FIXTURE(DummyFixture, SimilarlyNamedFixtureTestsInDifferentSuitesWork) {} -} - -SUITE(TestSuite2) -{ - TEST(SimilarlyNamedTestsInDifferentSuitesWork) {} - - TEST_FIXTURE(DummyFixture, SimilarlyNamedFixtureTestsInDifferentSuitesWork) {} -} - -TestList macroTestList1; -TEST_EX(MacroTestHelper1, macroTestList1) {} - -TEST(TestAddedWithTEST_EXMacroGetsDefaultSuite) -{ - CHECK(macroTestList1.GetFirst() != NULL); - CHECK_EQUAL("MacroTestHelper1", macroTestList1.GetFirst()->m_details.testName); - CHECK_EQUAL("DefaultSuite", macroTestList1.GetFirst()->m_details.suiteName); -} - -TestList macroTestList2; -TEST_FIXTURE_EX(DummyFixture, MacroTestHelper2, macroTestList2) {} - -TEST(TestAddedWithTEST_FIXTURE_EXMacroGetsDefaultSuite) -{ - CHECK(macroTestList2.GetFirst() != NULL); - CHECK_EQUAL("MacroTestHelper2", macroTestList2.GetFirst()->m_details.testName); - CHECK_EQUAL("DefaultSuite", macroTestList2.GetFirst()->m_details.suiteName); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -struct FixtureCtorThrows -{ - FixtureCtorThrows() { throw "exception"; } -}; - -TestList throwingFixtureTestList1; -TEST_FIXTURE_EX(FixtureCtorThrows, FixtureCtorThrowsTestName, throwingFixtureTestList1) {} - -TEST(FixturesWithThrowingCtorsAreFailures) -{ - CHECK(throwingFixtureTestList1.GetFirst() != NULL); - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResult(result); - throwingFixtureTestList1.GetFirst()->Run(); - } - - int const failureCount = result.GetFailedTestCount(); - CHECK_EQUAL(1, failureCount); - CHECK(strstr(reporter.lastFailedMessage, "while constructing fixture")); -} - -const int FailingLine = 123; - -struct FixtureCtorAsserts -{ - FixtureCtorAsserts() { UnitTest::ReportAssert("assert failure", "file", FailingLine); } -}; - -TestList ctorAssertFixtureTestList; -TEST_FIXTURE_EX(FixtureCtorAsserts, CorrectlyReportsAssertFailureInCtor, ctorAssertFixtureTestList) {} - -TEST(CorrectlyReportsFixturesWithCtorsThatAssert) -{ - RecordingReporter reporter; - TestResults result(&reporter); - { - ScopedCurrentTest scopedResults(result); - ctorAssertFixtureTestList.GetFirst()->Run(); - } - - const int failureCount = result.GetFailedTestCount(); - CHECK_EQUAL(1, failureCount); - CHECK_EQUAL(FailingLine, reporter.lastFailedLine); - CHECK(strstr(reporter.lastFailedMessage, "assert failure")); -} - -#endif - -} // namespace - -// We're really testing if it's possible to use the same suite in two files -// to compile and link successfuly (TestTestSuite.cpp has suite with the same name) -// Note: we are outside of the anonymous namespace -SUITE(SameTestSuite) -{ - TEST(DummyTest1) {} -} - -#define CUR_TEST_NAME CurrentTestDetailsContainCurrentTestInfo -#define INNER_STRINGIFY(X) #X -#define STRINGIFY(X) INNER_STRINGIFY(X) - -TEST(CUR_TEST_NAME) -{ - const UnitTest::TestDetails* details = CurrentTest::Details(); - CHECK_EQUAL(STRINGIFY(CUR_TEST_NAME), details->testName); -} - -#undef CUR_TEST_NAME -#undef INNER_STRINGIFY -#undef STRINGIFY diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestResults.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestResults.cpp @@ -1,138 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -using namespace UnitTest; - -namespace -{ -TestDetails const g_testdetails("testname", "suitename", "filename", 123); - -TEST(StartsWithNoTestsRun) -{ - TestResults results; - CHECK_EQUAL(0, results.GetTotalTestCount()); -} - -TEST(RecordsNumbersOfTests) -{ - TestResults results; - results.OnTestStart(g_testdetails); - results.OnTestStart(g_testdetails); - results.OnTestStart(g_testdetails); - CHECK_EQUAL(3, results.GetTotalTestCount()); -} - -TEST(StartsWithNoTestsFailing) -{ - TestResults results; - CHECK_EQUAL(0, results.GetFailureCount()); -} - -TEST(RecordsNumberOfFailures) -{ - TestResults results; - results.OnTestFailure(g_testdetails, ""); - results.OnTestFailure(g_testdetails, ""); - CHECK_EQUAL(2, results.GetFailureCount()); -} - -TEST(RecordsNumberOfFailedTests) -{ - TestResults results; - - results.OnTestStart(g_testdetails); - results.OnTestFailure(g_testdetails, ""); - results.OnTestFinish(g_testdetails, 0); - - results.OnTestStart(g_testdetails); - results.OnTestFailure(g_testdetails, ""); - results.OnTestFailure(g_testdetails, ""); - results.OnTestFailure(g_testdetails, ""); - results.OnTestFinish(g_testdetails, 0); - - CHECK_EQUAL(2, results.GetFailedTestCount()); -} - -TEST(NotifiesReporterOfTestStartWithCorrectInfo) -{ - RecordingReporter reporter; - TestResults results(&reporter); - results.OnTestStart(g_testdetails); - - CHECK_EQUAL(1, reporter.testRunCount); - CHECK_EQUAL("suitename", reporter.lastStartedSuite); - CHECK_EQUAL("testname", reporter.lastStartedTest); -} - -TEST(NotifiesReporterOfTestFailureWithCorrectInfo) -{ - RecordingReporter reporter; - TestResults results(&reporter); - - results.OnTestFailure(g_testdetails, "failurestring"); - CHECK_EQUAL(1, reporter.testFailedCount); - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(123, reporter.lastFailedLine); - CHECK_EQUAL("suitename", reporter.lastFailedSuite); - CHECK_EQUAL("testname", reporter.lastFailedTest); - CHECK_EQUAL("failurestring", reporter.lastFailedMessage); -} - -TEST(NotifiesReporterOfCheckFailureWithCorrectInfo) -{ - RecordingReporter reporter; - TestResults results(&reporter); - - results.OnTestFailure(g_testdetails, "failurestring"); - CHECK_EQUAL(1, reporter.testFailedCount); - - CHECK_EQUAL("filename", reporter.lastFailedFile); - CHECK_EQUAL(123, reporter.lastFailedLine); - CHECK_EQUAL("testname", reporter.lastFailedTest); - CHECK_EQUAL("suitename", reporter.lastFailedSuite); - CHECK_EQUAL("failurestring", reporter.lastFailedMessage); -} - -TEST(NotifiesReporterOfTestEnd) -{ - RecordingReporter reporter; - TestResults results(&reporter); - - results.OnTestFinish(g_testdetails, 0.1234f); - CHECK_EQUAL(1, reporter.testFinishedCount); - CHECK_EQUAL("testname", reporter.lastFinishedTest); - CHECK_EQUAL("suitename", reporter.lastFinishedSuite); - CHECK_CLOSE(0.1234f, reporter.lastFinishedTestTime, 0.0001f); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestRunner.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestRunner.cpp @@ -1,289 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#include "../Test.h" - -using namespace UnitTest; - -namespace -{ -struct TestRunnerFixture -{ - TestRunnerFixture() : runner(reporter) { s_testRunnerFixtureTestResults = runner.GetTestResults(); } - - static TestResults* s_testRunnerFixtureTestResults; - - RecordingReporter reporter; - TestList list; - TestRunner runner; -}; - -TestResults* TestRunnerFixture::s_testRunnerFixtureTestResults = NULL; - -struct MockTest : public Test -{ - MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1) - : Test(testName), success(success_), asserted(assert_), count(count_) - { - m_isMockTest = true; - } - - virtual void RunImpl() const - { - TestResults* testResults = TestRunnerFixture::s_testRunnerFixtureTestResults; - - for (int i = 0; i < count; ++i) - { - if (asserted) - Detail::ReportAssertEx(testResults, &m_details, "desc", "file", 0); - else if (!success) - testResults->OnTestFailure(m_details, "message"); - } - } - - bool const success; - bool const asserted; - int const count; -}; - -TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly) -{ - MockTest test("goodtest", true, false); - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.testRunCount); - CHECK_EQUAL("goodtest", reporter.lastStartedTest); -} - -TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly) -{ - MockTest test("goodtest", true, false); - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.testFinishedCount); - CHECK_EQUAL("goodtest", reporter.lastFinishedTest); -} - -class SlowTest : public Test -{ -public: - SlowTest() : Test("slow", "somesuite", "filename", 123) {} - virtual void RunImpl() const { TimeHelpers::SleepMs(20); } -}; - -TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime) -{ - SlowTest test; - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= 0.050f); -} - -TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun) -{ - CHECK_EQUAL(0, runner.RunTestsIf(list, NULL, True(), 0)); - CHECK_EQUAL(0, reporter.testRunCount); - CHECK_EQUAL(0, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest) -{ - MockTest test1("test", false, false); - list.Add(&test1); - MockTest test2("test", true, false); - list.Add(&test2); - MockTest test3("test", false, false); - list.Add(&test3); - - CHECK_EQUAL(2, runner.RunTestsIf(list, NULL, True(), 0)); - CHECK_EQUAL(2, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing) -{ - MockTest test("test", true, true); - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.testFailedCount); -} - -TEST_FIXTURE(TestRunnerFixture, AssertingTestAbortsAsSoonAsAssertIsHit) -{ - MockTest test("test", false, true, 3); - list.Add(&test); - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(1, reporter.summaryFailureCount); -} - -TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount) -{ - MockTest test1("test", true, false); - MockTest test2("test", true, false); - MockTest test3("test", true, false); - list.Add(&test1); - list.Add(&test2); - list.Add(&test3); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(3, reporter.summaryTotalTestCount); -} - -TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests) -{ - MockTest test1("test", false, false, 2); - MockTest test2("test", true, false); - MockTest test3("test", false, false, 3); - list.Add(&test1); - list.Add(&test2); - list.Add(&test3); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(2, reporter.summaryFailedTestCount); -} - -TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures) -{ - MockTest test1("test", false, false, 2); - MockTest test2("test", true, false); - MockTest test3("test", false, false, 3); - list.Add(&test1); - list.Add(&test2); - list.Add(&test3); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(5, reporter.summaryFailureCount); -} - -TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold) -{ - SlowTest test; - list.Add(&test); - - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(0, reporter.testFailedCount); -} - -struct TestSuiteFixture -{ - TestSuiteFixture() - : test1("TestInDefaultSuite") - , test2("TestInOtherSuite", "OtherSuite") - , test3("SecondTestInDefaultSuite") - , runner(reporter) - { - list.Add(&test1); - list.Add(&test2); - } - - Test test1; - Test test2; - Test test3; - RecordingReporter reporter; - TestList list; - TestRunner runner; -}; - -TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed) -{ - runner.RunTestsIf(list, NULL, True(), 0); - CHECK_EQUAL(2, reporter.summaryTotalTestCount); -} - -TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsOnlySpecifiedSuite) -{ - runner.RunTestsIf(list, "OtherSuite", True(), 0); - CHECK_EQUAL(1, reporter.summaryTotalTestCount); - CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest); -} - -struct RunTestIfNameIs -{ - RunTestIfNameIs(char const* name_) : name(name_) {} - - bool operator()(const Test* const test) const - { - using namespace std; - return (0 == strcmp(test->m_details.testName, name)); - } - - char const* name; -}; - -TEST(TestMockPredicateBehavesCorrectly) -{ - RunTestIfNameIs predicate("pass"); - - Test pass("pass"); - Test fail("fail"); - - CHECK(predicate(&pass)); - CHECK(!predicate(&fail)); -} - -TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate) -{ - Test should_run("goodtest"); - list.Add(&should_run); - - Test should_not_run("badtest"); - list.Add(&should_not_run); - - runner.RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0); - CHECK_EQUAL(1, reporter.testRunCount); - CHECK_EQUAL("goodtest", reporter.lastStartedTest); -} - -TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate) -{ - Test runningTest1("goodtest", "suite"); - Test skippedTest2("goodtest"); - Test skippedTest3("badtest", "suite"); - Test skippedTest4("badtest"); - - list.Add(&runningTest1); - list.Add(&skippedTest2); - list.Add(&skippedTest3); - list.Add(&skippedTest4); - - runner.RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0); - - CHECK_EQUAL(1, reporter.testRunCount); - CHECK_EQUAL("goodtest", reporter.lastStartedTest); - CHECK_EQUAL("suite", reporter.lastStartedSuite); -} - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestSuite.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestTestSuite.cpp @@ -1,40 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -// We're really testing if it's possible to use the same suite in two files -// to compile and link successfuly (TestTestSuite.cpp has suite with the same name) -// Note: we are outside of the anonymous namespace -SUITE(SameTestSuite) -{ - TEST(DummyTest2) {} -} diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestUnitTestPP.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestUnitTestPP.cpp @@ -1,151 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -// These are sample tests that show the different features of the framework - -namespace -{ -TEST(ValidCheckSucceeds) -{ - bool const b = true; - CHECK(b); -} - -TEST(CheckWorksWithPointers) -{ - void* p = (void*)0x100; - CHECK(p); - CHECK(p != 0); -} - -TEST(ValidCheckEqualSucceeds) -{ - int const x = 3; - int const y = 3; - CHECK_EQUAL(x, y); -} - -TEST(CheckEqualWorksWithPointers) -{ - void* p = (void*)0; - CHECK_EQUAL((void*)0, p); -} - -TEST(ValidCheckCloseSucceeds) -{ - CHECK_CLOSE(2.0f, 2.001f, 0.01f); - CHECK_CLOSE(2.001f, 2.0f, 0.01f); -} - -TEST(ArrayCloseSucceeds) -{ - float const a1[] = {1, 2, 3}; - float const a2[] = {1, 2.01f, 3}; - CHECK_ARRAY_CLOSE(a1, a2, 3, 0.1f); -} - -#ifndef UNITTEST_NO_EXCEPTIONS - -TEST(CheckThrowMacroSucceedsOnCorrectException) -{ - struct TestException - { - }; - CHECK_THROW(throw TestException(), TestException); -} - -TEST(CheckAssertSucceeds) { CHECK_ASSERT(UnitTest::ReportAssert("desc", "file", 0)); } - -TEST(CheckThrowMacroFailsOnMissingException) -{ - class NoThrowTest : public UnitTest::Test - { - public: - NoThrowTest() : Test("nothrow") {} - void DontThrow() const {} - - virtual void RunImpl() const { CHECK_THROW(DontThrow(), int); } - }; - - UnitTest::TestResults results; - { - ScopedCurrentTest scopedResults(results); - - NoThrowTest test; - test.Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -TEST(CheckThrowMacroFailsOnWrongException) -{ - class WrongThrowTest : public UnitTest::Test - { - public: - WrongThrowTest() : Test("wrongthrow") {} - virtual void RunImpl() const { CHECK_THROW(throw "oops", int); } - }; - - UnitTest::TestResults results; - { - ScopedCurrentTest scopedResults(results); - - WrongThrowTest test; - test.Run(); - } - - CHECK_EQUAL(1, results.GetFailureCount()); -} - -#endif - -struct SimpleFixture -{ - SimpleFixture() { ++instanceCount; } - ~SimpleFixture() { --instanceCount; } - - static int instanceCount; -}; - -int SimpleFixture::instanceCount = 0; - -TEST_FIXTURE(SimpleFixture, DefaultFixtureCtorIsCalled) { CHECK(SimpleFixture::instanceCount > 0); } - -TEST_FIXTURE(SimpleFixture, OnlyOneFixtureAliveAtATime) { CHECK_EQUAL(1, SimpleFixture::instanceCount); } - -void CheckBool(const bool b) { CHECK(b); } - -TEST(CanCallCHECKOutsideOfTestFunction) { CheckBool(true); } - -} // namespace diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestXmlTestReporter.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/TestXmlTestReporter.cpp @@ -1,207 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#include "stdafx.h" - -#ifndef UNITTEST_NO_DEFERRED_REPORTER - -#include "../XmlTestReporter.h" -#include <sstream> - -using namespace UnitTest; -using std::ostringstream; - -namespace -{ -#ifndef UNITTEST_MEMORYOUTSTREAM_IS_STD_OSTRINGSTREAM - -// Overload to let MemoryOutStream accept std::string -MemoryOutStream& operator<<(MemoryOutStream& s, const std::string& value) -{ - s << value.c_str(); - return s; -} - -#endif - -struct XmlTestReporterFixture -{ - XmlTestReporterFixture() : reporter(output) {} - - ostringstream output; - XmlTestReporter reporter; -}; - -TEST_FIXTURE(XmlTestReporterFixture, MultipleCharactersAreEscaped) -{ - TestDetails const details("TestName", "suite", "filename.h", 4321); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "\"\"\'\'&&<<>>"); - reporter.ReportTestFinish(details, false, 0.1f); - reporter.ReportSummary(1, 2, 3, 0.1f); - - char const* expected = "<?xml version=\"1.0\"?>" - "<unittest-results tests=\"1\" failedtests=\"2\" failures=\"3\" time=\"0.1\">" - "<test suite=\"suite\" name=\"TestName\" time=\"0.1\">" - "<failure message=\"filename.h(4321) : " - """''&&<<>>\"/>" - "</test>" - "</unittest-results>"; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, OutputIsCachedUntilReportSummaryIsCalled) -{ - TestDetails const details("", "", "", 0); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "message"); - reporter.ReportTestFinish(details, false, 1.0F); - CHECK(output.str().empty()); - - reporter.ReportSummary(1, 1, 1, 1.0f); - CHECK(!output.str().empty()); -} - -TEST_FIXTURE(XmlTestReporterFixture, EmptyReportSummaryFormat) -{ - reporter.ReportSummary(0, 0, 0, 0.1f); - - const char* expected = "<?xml version=\"1.0\"?>" - "<unittest-results tests=\"0\" failedtests=\"0\" failures=\"0\" time=\"0.1\">" - "</unittest-results>"; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, SingleSuccessfulTestReportSummaryFormat) -{ - TestDetails const details("TestName", "DefaultSuite", "", 0); - - reporter.ReportTestStart(details); - reporter.ReportSummary(1, 0, 0, 0.1f); - - const char* expected = "<?xml version=\"1.0\"?>" - "<unittest-results tests=\"1\" failedtests=\"0\" failures=\"0\" time=\"0.1\">" - "<test suite=\"DefaultSuite\" name=\"TestName\" time=\"0\"/>" - "</unittest-results>"; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, SingleFailedTestReportSummaryFormat) -{ - TestDetails const details("A Test", "suite", "A File", 4321); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "A Failure"); - reporter.ReportSummary(1, 1, 1, 0.1f); - - const char* expected = "<?xml version=\"1.0\"?>" - "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">" - "<test suite=\"suite\" name=\"A Test\" time=\"0\">" - "<failure message=\"A File(4321) : A Failure\"/>" - "</test>" - "</unittest-results>"; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, FailureMessageIsXMLEscaped) -{ - TestDetails const details("TestName", "suite", "filename.h", 4321); - - reporter.ReportTestStart(details); - reporter.ReportFailure(details, "\"\'&<>"); - reporter.ReportTestFinish(details, false, 0.1f); - reporter.ReportSummary(1, 1, 1, 0.1f); - - char const* expected = "<?xml version=\"1.0\"?>" - "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"1\" time=\"0.1\">" - "<test suite=\"suite\" name=\"TestName\" time=\"0.1\">" - "<failure message=\"filename.h(4321) : "'&<>\"/>" - "</test>" - "</unittest-results>"; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, OneFailureAndOneSuccess) -{ - TestDetails const failedDetails("FailedTest", "suite", "fail.h", 1); - reporter.ReportTestStart(failedDetails); - reporter.ReportFailure(failedDetails, "expected 1 but was 2"); - reporter.ReportTestFinish(failedDetails, false, 0.1f); - - TestDetails const succeededDetails("SucceededTest", "suite", "", 0); - reporter.ReportTestStart(succeededDetails); - reporter.ReportTestFinish(succeededDetails, true, 1.0f); - reporter.ReportSummary(2, 1, 1, 1.1f); - - char const* expected = "<?xml version=\"1.0\"?>" - "<unittest-results tests=\"2\" failedtests=\"1\" failures=\"1\" time=\"1.1\">" - "<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">" - "<failure message=\"fail.h(1) : expected 1 but was 2\"/>" - "</test>" - "<test suite=\"suite\" name=\"SucceededTest\" time=\"1\"/>" - "</unittest-results>"; - - CHECK_EQUAL(expected, output.str()); -} - -TEST_FIXTURE(XmlTestReporterFixture, MultipleFailures) -{ - TestDetails const failedDetails1("FailedTest", "suite", "fail.h", 1); - TestDetails const failedDetails2("FailedTest", "suite", "fail.h", 31); - - reporter.ReportTestStart(failedDetails1); - reporter.ReportFailure(failedDetails1, "expected 1 but was 2"); - reporter.ReportFailure(failedDetails2, "expected one but was two"); - reporter.ReportTestFinish(failedDetails1, false, 0.1f); - - reporter.ReportSummary(1, 1, 2, 1.1f); - - char const* expected = "<?xml version=\"1.0\"?>" - "<unittest-results tests=\"1\" failedtests=\"1\" failures=\"2\" time=\"1.1\">" - "<test suite=\"suite\" name=\"FailedTest\" time=\"0.1\">" - "<failure message=\"fail.h(1) : expected 1 but was 2\"/>" - "<failure message=\"fail.h(31) : expected one but was two\"/>" - "</test>" - "</unittest-results>"; - - CHECK_EQUAL(expected, output.str()); -} - -} // namespace - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/stdafx.cpp @@ -1,35 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h"- \ No newline at end of file diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/src/tests/stdafx.h @@ -1,45 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#pragma once - -#include "../../config.h" -#include "../../unittestpp.h" -#include "../CurrentTest.h" -#include "../ReportAssert.h" -#include "../ReportAssertImpl.h" -#include "../TestMacros.h" -#include "../TestReporter.h" -#include "../TestResults.h" -#include "../TimeHelpers.h" -#include "RecordingReporter.h" -#include "ScopedCurrentTest.h" -#include <cstring>- \ No newline at end of file diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/unittestpp.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/UnitTestpp/unittestpp.h @@ -1,42 +0,0 @@ -/*** - * This file is based on or incorporates material from the UnitTest++ r30 open source project. - * Microsoft is not the original author of this code but has modified it and is licensing the code under - * the MIT License. Microsoft reserves all other rights not expressly granted under the MIT License, - * whether by implication, estoppel or otherwise. - * - * UnitTest++ r30 - * - * Copyright (c) 2006 Noel Llopis and Charles Nicholson - * Portions Copyright (c) Microsoft Corporation - * - * All Rights Reserved. - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ***/ - -#ifndef UNITTESTPP_H -#define UNITTESTPP_H - -#include "config.h" -#include "src/CheckMacros.h" -#include "src/GlobalSettings.h" -#include "src/ReportAssert.h" -#include "src/TestMacros.h" -#include "src/TestRunner.h" - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/CMakeLists.txt @@ -1,18 +0,0 @@ -include_directories(include) - -if(WIN32) - add_definitions(-DCOMMONUTILITIES_EXPORTS) -endif() - -add_library(common_utilities - os_utilities.cpp - ) - -if(NOT BUILD_SHARED_LIBS) - target_compile_definitions(common_utilities INTERFACE -DTEST_UTILITY_API=) -endif() - -target_link_libraries(common_utilities - cpprest - unittestpp -) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/include/common_utilities_public.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/include/common_utilities_public.h @@ -1,24 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * common_utilities.h -- Common definitions for public test utility headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#if !defined(_WIN32) && !defined(__cplusplus_winrt) -#define TEST_UTILITY_API -#endif // !_WIN32 && !__cplusplus_winrt - -#ifndef TEST_UTILITY_API -#ifdef COMMONUTILITIES_EXPORTS -#define TEST_UTILITY_API __declspec(dllexport) -#else // COMMONUTILITIES_EXPORTS -#define TEST_UTILITY_API __declspec(dllimport) -#endif // COMMONUTILITIES_EXPORTS -#endif // TEST_UTILITY_API diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/include/locale_guard.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/include/locale_guard.h @@ -1,34 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Defines an RAII container for setting global locale. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include <locale> - -namespace tests -{ -namespace common -{ -namespace utilities -{ -class locale_guard -{ -public: - locale_guard(std::locale const& loc) { m_prev = std::locale::global(loc); } - ~locale_guard() { std::locale::global(m_prev); } - -private: - std::locale m_prev; - locale_guard(locale_guard const&); - locale_guard& operator=(locale_guard const&); -}; - -} // namespace utilities -} // namespace common -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/include/os_utilities.h b/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/include/os_utilities.h @@ -1,40 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * os_utilities.h - defines an abstraction for common OS functions like Sleep, hiding the underlying platform. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "common_utilities_public.h" -#include "cpprest/details/cpprest_compat.h" - -namespace tests -{ -namespace common -{ -namespace utilities -{ -class os_utilities -{ -public: - static TEST_UTILITY_API void __cdecl sleep(unsigned long ms); - - // Could use std::atomics but VS 2010 doesn't support it yet. - static TEST_UTILITY_API unsigned long __cdecl interlocked_increment(volatile unsigned long* addend); - static TEST_UTILITY_API long __cdecl interlocked_exchange(volatile long* target, long value); - -private: - os_utilities(); - os_utilities(const os_utilities&); - os_utilities& operator=(const os_utilities&); -}; - -} // namespace utilities -} // namespace common -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/os_utilities.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/common/utilities/os_utilities.cpp @@ -1,62 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * os_utilities.cpp - defines an abstraction for common OS functions like Sleep, hiding the underlying platform. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "os_utilities.h" - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#include <SDKDDKVer.h> - -#include <Windows.h> -#else -#include <unistd.h> -#endif - -namespace tests -{ -namespace common -{ -namespace utilities -{ -void os_utilities::sleep(unsigned long ms) -{ -#ifdef WIN32 - Sleep(ms); -#else - usleep(ms * 1000); -#endif -} - -unsigned long os_utilities::interlocked_increment(volatile unsigned long* addend) -{ -#ifdef WIN32 - return InterlockedIncrement(addend); -#elif defined(__GNUC__) - return __sync_add_and_fetch(addend, 1); -#else -#error Need to implement interlocked_increment -#endif -} - -long os_utilities::interlocked_exchange(volatile long* target, long value) -{ -#ifdef WIN32 - return InterlockedExchange(target, value); -#elif defined(__GNUC__) - return __sync_lock_test_and_set(target, value); -#else -#error Need to implement interlocked_exchange -#endif -} - -} // namespace utilities -} // namespace common -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/CMakeLists.txt @@ -1,7 +0,0 @@ -add_subdirectory(http) -add_subdirectory(json) -add_subdirectory(pplx) -add_subdirectory(streams) -add_subdirectory(uri) -add_subdirectory(utils) -add_subdirectory(websockets)- \ No newline at end of file diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/CMakeLists.txt @@ -1,3 +0,0 @@ -add_subdirectory(utilities) -add_subdirectory(client) -add_subdirectory(listener) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/CMakeLists.txt @@ -1,41 +0,0 @@ -set(SOURCES - authentication_tests.cpp - building_request_tests.cpp - client_construction.cpp - compression_tests.cpp - connection_pool_tests.cpp - connections_and_errors.cpp - header_tests.cpp - http_client_fuzz_tests.cpp - http_client_tests.cpp - http_methods_tests.cpp - multiple_requests.cpp - oauth1_tests.cpp - oauth2_tests.cpp - outside_tests.cpp - pipeline_stage_tests.cpp - progress_handler_tests.cpp - proxy_tests.cpp - redirect_tests.cpp - request_helper_tests.cpp - request_stream_tests.cpp - request_uri_tests.cpp - response_extract_tests.cpp - response_stream_tests.cpp - status_code_reason_phrase_tests.cpp - to_string_tests.cpp -) - -add_casablanca_test(httpclient_test SOURCES) -if(TEST_LIBRARY_TARGET_TYPE STREQUAL "OBJECT") - target_include_directories(httpclient_test PRIVATE ../utilities/include) -else() - target_link_libraries(httpclient_test PRIVATE httptest_utilities) -endif() - -configure_pch(httpclient_test stdafx.h stdafx.cpp) - -if(NOT WIN32) - cpprest_find_boost() - target_link_libraries(httpclient_test PRIVATE cpprestsdk_boost_internal) -endif() diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/authentication_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/authentication_tests.cpp @@ -1,725 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for authentication with http_clients. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include <stdexcept> - -#ifdef _WIN32 -#ifdef __cplusplus_winrt -#if !defined(__WRL_NO_DEFAULT_LIB__) -#define __WRL_NO_DEFAULT_LIB__ -#endif -#include <msxml6.h> -#include <wrl.h> -#else -#include <windows.h> - -#include <winhttp.h> -#pragma comment(lib, "winhttp") -#endif -#endif - -#if !defined(_WIN32) -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Winfinite-recursion" -#endif -#include <boost/asio.hpp> -#include <boost/asio/ssl.hpp> -#if defined(__clang__) -#pragma clang diagnostic pop -#endif -#endif - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(authentication_tests) -{ - TEST_FIXTURE(uri_address, auth_no_data, "Ignore:Linux", "89", "Ignore:Apple", "89") - { - pplx::task<void> t, t2; - { - test_http_server::scoped_server scoped(m_uri); - http_client_config client_config; - web::credentials cred(U("some_user"), U("some_password")); // WinHTTP requires non-empty password - client_config.set_credentials(cred); - http_client client(m_uri, client_config); - const method mtd = methods::POST; - - http_request msg(mtd); - - t = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - - // Auth header - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - - // unauthorized - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }); - t2 = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - p_request->reply(200); - }); - - try - { - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - catch (...) - { - VERIFY_ARE_EQUAL(0, 1); - } - } - try - { - t.get(); - } - catch (...) - { - VERIFY_ARE_EQUAL(0, 1); - } - try - { - t2.get(); - } - catch (...) - { - VERIFY_ARE_EQUAL(0, 1); - } - } - -// TFS 648783 -#ifndef __cplusplus_winrt - TEST_FIXTURE(uri_address, proxy_auth_known_contentlength, "Ignore:Linux", "88", "Ignore:Apple", "88") - { - pplx::task<void> t, t2; - { - test_http_server::scoped_server scoped(m_uri); - http_client_config client_config; - web::credentials cred(U("some_user"), U("some_password")); // WinHTTP requires non-empty password - client_config.set_credentials(cred); - http_client client(m_uri, client_config); - const method mtd = methods::POST; - utility::string_t contents(U("Hello World")); - - http_request msg(mtd); - msg.set_body(contents); - - t = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - - // Auth header - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - - // unauthorized - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }); - - t2 = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::POST, U("/"), U("text/plain; charset=utf-8"), contents); - - p_request->reply(200); - }); - - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - try - { - t.get(); - } - catch (...) - { - VERIFY_ARE_EQUAL(0, 1); - } - try - { - t2.get(); - } - catch (...) - { - VERIFY_ARE_EQUAL(0, 1); - } - } -#endif - - TEST_FIXTURE(uri_address, proxy_auth_noseek, "Ignore:Linux", "88", "Ignore:Apple", "88") - { - web::http::uri uri(U("http://localhost:34567/")); - test_http_server::scoped_server scoped(uri); - http_client client( - uri); // In this test, the request cannot be resent, so the username and password are not required - const method mtd = methods::POST; - - auto buf = streams::producer_consumer_buffer<unsigned char>(); - buf.putc('a').get(); - buf.close(std::ios_base::out).get(); - - http_request msg(mtd); - msg.set_body(buf.create_istream(), 1); - - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - - // Auth header - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - - // unauthorized - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }); - - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::Unauthorized); - } - -// Must specify content length with winrt client, so this test case isn't possible. -#ifndef __cplusplus_winrt - TEST_FIXTURE(uri_address, proxy_auth_unknown_contentlength, "Ignore:Linux", "88", "Ignore:Apple", "88") - { - pplx::task<void> t; - { - test_http_server::scoped_server scoped(m_uri); - http_client_config client_config; - web::credentials cred(U("some_user"), U("some_password")); // WinHTTP requires non-empty password - client_config.set_credentials(cred); - http_client client(m_uri, client_config); - const method mtd = methods::POST; - - std::vector<uint8_t> msg_body; - msg_body.push_back('a'); - - http_request msg(mtd); - msg.set_body(streams::container_stream<std::vector<uint8_t>>::open_istream(std::move(msg_body))); - - auto replyFunc = [&](test_request* p_request) { - utility::string_t contents(U("a")); - http_asserts::assert_test_request_equals( - p_request, methods::POST, U("/"), U("application/octet-stream"), contents); - - p_request->reply(200); - }; - - t = scoped.server() - ->next_request() - .then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - - // Auth header - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - - // unauthorized - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }) - .then([&scoped, replyFunc]() { - // Client resent the request - return scoped.server()->next_request().then(replyFunc); - }); - - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - t.get(); - } - - // Accessing a server that returns 401 with an empty user name should not resend the request with an empty password - TEST_FIXTURE(uri_address, empty_username_password) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - auto t = scoped.server()->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("h1")] = U("data1"); - // Auth header - headers[U("WWW-Authenticate")] = U("Basic realm = \"myRealm\""); - // unauthorized - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers, "a"); - }); - - http_response response = client.request(methods::GET).get(); - auto str_body = response.extract_vector().get(); - auto h1 = response.headers()[U("h1")]; - VERIFY_ARE_EQUAL(status_codes::Unauthorized, response.status_code()); - VERIFY_ARE_EQUAL(str_body[0], 'a'); - VERIFY_ARE_EQUAL(h1, U("data1")); - t.get(); - } -#endif - - // Fails on WinRT due to TFS 648278 - // Accessing a server that supports auth, but returns 401, even after the user has provided valid creds - // We're making sure the error is reported properly, and the response data from the second response is received - TEST_FIXTURE(uri_address, error_after_valid_credentials, "Ignore:Linux", "89", "Ignore:Apple", "89") - { - pplx::task<void> t; - { - web::http::uri uri(U("http://localhost:34569/")); - test_http_server::scoped_server scoped(uri); - http_client_config client_config; - web::credentials cred(U("some_user"), U("some_password")); - client_config.set_credentials(cred); - http_client client(uri, client_config); - - auto replyFunc = [&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - // Auth header - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - headers[U("h1")] = U("data2"); - // still unauthorized after the user has resent the request with the credentials - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers, "def"); - }; - - t = scoped.server() - ->next_request() - .then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("h1")] = U("data1"); - // Auth header - headers[U("WWW-Authenticate")] = U("Basic realm = \"myRealm\""); - // unauthorized - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers, "abc"); - }) - .then([&scoped, &replyFunc]() { - // Client resent the request - return scoped.server()->next_request().then(replyFunc); - }) -#ifdef __cplusplus_winrt - .then([&scoped, &replyFunc]() { - // in winrt, client resent the request again - return scoped.server()->next_request().then(replyFunc); - }) -#endif - ; - - http_response response = client.request(methods::GET).get(); - auto str_body = response.extract_vector().get(); - auto h1 = response.headers()[U("h1")]; - VERIFY_ARE_EQUAL(status_codes::Unauthorized, response.status_code()); - VERIFY_ARE_EQUAL(str_body[0], 'd'); - VERIFY_ARE_EQUAL(str_body[1], 'e'); - VERIFY_ARE_EQUAL(str_body[2], 'f'); - VERIFY_ARE_EQUAL(h1, U("data2")); - } - t.get(); - } - - // These tests are disabled since they require a server with authentication running. - // The server portion to use is the C# AuthenticationListener. - - class server_properties - { - public: - server_properties() {} - - // Helper function to retrieve all parameters necessary for setup tests. - void load_parameters() - { - m_uri = uri(utility::conversions::to_string_t(UnitTest::GlobalSettings::Get("Server"))); - if (UnitTest::GlobalSettings::Has("UserName")) - { - m_username = utility::conversions::to_string_t(UnitTest::GlobalSettings::Get("UserName")); - } - if (UnitTest::GlobalSettings::Has("Password")) - { - m_password = utility::conversions::to_string_t(UnitTest::GlobalSettings::Get("Password")); - } - } - - web::http::uri m_uri; - string_t m_username; - string_t m_password; - }; - - // This test should be executed for NTLM, Negotiate, IntegratedWindowsAuth, and Anonymous. - TEST_FIXTURE(server_properties, successful_auth_no_cred, "Requires", "Server") - { - load_parameters(); - - http_client client(m_uri); - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - - TEST_FIXTURE(server_properties, digest_basic_auth_no_cred, "Requires", "Server") - { - load_parameters(); - - http_client client(m_uri); - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::Unauthorized, response.status_code()); - } - - TEST_FIXTURE(server_properties, none_auth_no_cred, "Requires", "Server") - { - load_parameters(); - - http_client client(m_uri); - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::Forbidden, response.status_code()); - } - - // This test should be executed for NTLM, Negotiate, IntegratedWindowsAuth, and Digest. - TEST_FIXTURE(server_properties, unsuccessful_auth_with_basic_cred, "Requires", "Server;UserName;Password") - { - load_parameters(); - - http_client_config config; - config.set_credentials(web::credentials(m_username, m_password)); - - http_client client(m_uri, config); - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::Unauthorized, response.status_code()); - } - - TEST_FIXTURE(server_properties, basic_anonymous_auth_with_basic_cred, "Requires", "Server;UserName;Password") - { - load_parameters(); - - http_client_config config; - config.set_credentials(web::credentials(m_username, m_password)); - http_client client(m_uri, config); - http_request req(methods::GET); - req.headers().add(U("UserName"), m_username); - req.headers().add(U("Password"), m_password); - http_response response = client.request(req).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - - TEST_FIXTURE(server_properties, none_auth_with_cred, "Requires", "Server;UserName;Password") - { - load_parameters(); - - http_client_config config; - config.set_credentials(web::credentials(m_username, m_password)); - http_client client(m_uri, config); - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::Forbidden, response.status_code()); - } - - // This test should be executed for all authentication schemes except None. - TEST_FIXTURE(server_properties, successful_auth_with_domain_cred, "Requires", "Server;UserName;Password") - { - load_parameters(); - - http_client_config config; - config.set_credentials(web::credentials(m_username, m_password)); - http_client client(m_uri, config); - http_request req(methods::GET); - req.headers().add(U("UserName"), m_username); - req.headers().add(U("Password"), m_password); - http_response response = client.request(req).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - -#ifndef __cplusplus_winrt // WinRT implementation doesn't support request buffer caching. - TEST_FIXTURE(server_properties, failed_authentication_resend_request_error, "Requires", "Server;UserName;Password") - { - load_parameters(); - - http_client_config config; - config.set_credentials(web::credentials(m_username, m_password)); - http_client client(m_uri, config); - - const size_t rawDataSize = 8; - - std::vector<unsigned char> data(rawDataSize); - memcpy(&data[0], "raw data", rawDataSize); - - http_request request; - request.set_method(methods::POST); - request.set_body(data); - http_response response = client.request(request).get(); - - VERIFY_ARE_EQUAL(200, response.status_code()); - } -#endif - -#ifdef __cplusplus_winrt - TEST_FIXTURE(uri_address, set_user_options_winrt) - { - test_http_server::scoped_server scoped(m_uri); - scoped.server()->next_request().then([](test_request* p_request) { p_request->reply(status_codes::OK); }); - - http_client_config config; - config.set_nativehandle_options([](native_handle handle) -> void { - auto hr = handle->SetProperty(XHR_PROP_TIMEOUT, 1000); - if (!SUCCEEDED(hr)) throw std::runtime_error("The Test Exception"); - }); - http_client client(m_uri, config); - auto response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(200, response.status_code()); - } -#endif // __cplusplus_winrt - -#ifdef _WIN32 -#if !defined(__cplusplus_winrt) - TEST_FIXTURE(server_properties, set_user_options, "Requires", "Server;UserName;Password") - { - load_parameters(); - - http_client_config config; - config.set_credentials(web::credentials(m_username, m_password)); - - config.set_nativehandle_options([&](native_handle handle) -> void { - DWORD policy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW; - if (!WinHttpSetOption(handle, WINHTTP_OPTION_AUTOLOGON_POLICY, &policy, sizeof(policy))) - { - throw std::runtime_error("The Test Error"); - } - }); - - http_client client(m_uri, config); - - const size_t rawDataSize = 8; - - std::vector<unsigned char> data(rawDataSize); - memcpy(&data[0], "raw data", rawDataSize); - - http_request request; - request.set_method(methods::POST); - request.set_body(data); - - VERIFY_ARE_EQUAL(200, client.request(request).get().status_code()); - } - - TEST_FIXTURE(uri_address, auth_producer_consumer_buffer) - { - auto buf = streams::producer_consumer_buffer<unsigned char>(); - buf.putc('a').get(); - buf.putc('a').get(); - buf.putc('a').get(); - buf.putc('a').get(); - buf.close(std::ios_base::out).get(); - http_request msg(methods::POST); - msg.set_body(buf.create_istream()); - - http_client_config config; - VERIFY_IS_FALSE(config.buffer_request()); - config.set_buffer_request(true); - VERIFY_IS_TRUE(config.buffer_request()); - config.set_credentials(web::credentials(U("USERNAME"), U("PASSWORD"))); - - http_client client(m_uri, config); - - pplx::task<void> t, t2; - test_http_server::scoped_server scoped(m_uri); - - t = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::POST, U("/"), U("application/octet-stream"), U("aaaa")); - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }); - t2 = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::POST, U("/"), U("application/octet-stream"), U("aaaa")); - p_request->reply(200); - }); - - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - scoped.server()->close(); - VERIFY_NO_THROWS(t.get()); - VERIFY_NO_THROWS(t2.get()); - } - - TEST_FIXTURE(uri_address, auth_producer_comsumer_buffer_fail_no_cred) - { - auto buf = streams::producer_consumer_buffer<unsigned char>(); - buf.putc('a').get(); - buf.putc('a').get(); - buf.putc('a').get(); - buf.putc('a').get(); - buf.close(std::ios_base::out).get(); - http_request msg(methods::POST); - msg.set_body(buf.create_istream()); - - http_client client(m_uri); - - pplx::task<void> t; - { - test_http_server::scoped_server scoped(m_uri); - t = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::POST, U("/"), U("application/octet-stream"), U("aaaa")); - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }); - - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::Unauthorized); - } - t.get(); - } - - TEST_FIXTURE(uri_address, auth_producer_comsumer_buffer_fail) - { - auto buf = streams::producer_consumer_buffer<unsigned char>(); - buf.putc('a').get(); - buf.close(std::ios_base::out).get(); - http_request msg(methods::POST); - msg.set_body(buf.create_istream()); - - http_client_config config; - config.set_buffer_request(true); - config.set_credentials(web::credentials(U("USERNAME"), U("PASSWORD"))); - - http_client client(m_uri, config); - pplx::task<void> t; - { - test_http_server::scoped_server scoped(m_uri); - - auto replyFunc = [&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::POST, U("/"), U("application/octet-stream"), U("a")); - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld2\""); - - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }; - - t = scoped.server() - ->next_request() - .then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::POST, U("/"), U("application/octet-stream"), U("a")); - std::map<utility::string_t, utility::string_t> headers; - headers[U("WWW-Authenticate")] = U("Basic realm = \"WallyWorld\""); - - p_request->reply(status_codes::Unauthorized, U("Authentication Failed"), headers); - }) - .then([&scoped, replyFunc]() { return scoped.server()->next_request().then(replyFunc); }); - - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::Unauthorized); - } - VERIFY_NO_THROWS(t.get()); - } -#endif - - TEST_FIXTURE(uri_address, set_user_options_exceptions) - { - test_http_server::scoped_server scoped(m_uri); - http_client_config config; - class TestException; - config.set_nativehandle_options([](native_handle) { throw std::runtime_error("The Test exception"); }); - http_client client(m_uri, config); - VERIFY_THROWS(client.request(methods::GET).get(), std::runtime_error); - } -#endif // _WIN32 - - // Fix for 522831 AV after failed authentication attempt - TEST_FIXTURE(uri_address, failed_authentication_attempt, "Ignore:Linux", "89", "Ignore:Apple", "89") - { - handle_timeout([] { - http_client_config config; - web::credentials cred(U("user"), U("schmuser")); - config.set_credentials(cred); - http_client client(U("https://apis.live.net"), config); - http_response response = client.request(methods::GET, U("V5.0/me/skydrive/files")).get(); - VERIFY_ARE_EQUAL(status_codes::Unauthorized, response.status_code()); - auto v = response.extract_vector().get(); - std::string s(v.begin(), v.end()); - // The resulting data must be non-empty (an error about missing access token) - VERIFY_IS_FALSE(s.empty()); - }); - } - -#if !defined(_WIN32) - - // http_server does not support auth - void auth_test_impl(bool fail) - { - std::string user("user1"), password("user1"); - auto return_code = status_codes::OK; - - if (fail) - { - password = "invalid"; - return_code = status_codes::Unauthorized; - } - - http_client_config client_config; - web::credentials cred(U(user), U(password)); - client_config.set_credentials(cred); - http_client client(U("http://httpbin.org/basic-auth/user1/user1"), client_config); - - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(return_code, response.status_code()); - } - - TEST(auth_no_data) { auth_test_impl(false); } - - TEST(unsuccessful_auth_with_basic_cred) { auth_test_impl(true); } - - TEST_FIXTURE(uri_address, set_user_options_asio_http) - { - test_http_server::scoped_server scoped(m_uri); - scoped.server()->next_request().then([](test_request* p_request) { p_request->reply(status_codes::OK); }); - - http_client_config config; - config.set_nativehandle_options([](native_handle handle) { - boost::asio::ip::tcp::socket* socket = static_cast<boost::asio::ip::tcp::socket*>(handle); - // Socket shouldn't be open yet since no requests have gone out. - VERIFY_ARE_EQUAL(false, socket->is_open()); - }); - http_client client(m_uri, config); - auto response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(200, response.status_code()); - } - - TEST_FIXTURE(uri_address, set_user_options_asio_https) - { - handle_timeout([] { - http_client_config config; - config.set_nativehandle_options([](native_handle handle) { - boost::asio::ssl::stream<boost::asio::ip::tcp::socket&>* streamobj = - static_cast<boost::asio::ssl::stream<boost::asio::ip::tcp::socket&>*>(handle); - const auto& tcpLayer = streamobj->lowest_layer(); - VERIFY_ARE_EQUAL(false, tcpLayer.is_open()); - }); - - http_client client(U("https://apis.live.net"), config); - http_response response = client.request(methods::GET, U("V5.0/me/skydrive/files")).get(); - VERIFY_ARE_EQUAL(status_codes::Unauthorized, response.status_code()); - auto v = response.extract_vector().get(); - // The resulting data must be non-empty (an error about missing access token) - VERIFY_IS_FALSE(v.empty()); - }); - } - -#endif - -} // SUITE(authentication_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/building_request_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/building_request_tests.cpp @@ -1,334 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * building_request_tests.cpp - * - * Tests cases manually building up HTTP requests. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#ifdef _WIN32 -#include <WinError.h> -#endif - -#include <locale_guard.h> - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(building_request_tests) -{ - TEST_FIXTURE(uri_address, simple_values) - { - test_http_server::scoped_server scoped(m_uri); - pplx::task<void> t1, t2; - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // Set a method. - const method method = methods::OPTIONS; - http_request msg(method); - VERIFY_ARE_EQUAL(method, msg.method()); - - // Set a path once. - const utility::string_t custom_path1 = U("/hey/custom/path"); - msg.set_request_uri(custom_path1); - VERIFY_ARE_EQUAL(custom_path1, msg.relative_uri().to_string()); - t1 = p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, custom_path1); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // Set the path twice. - msg = http_request(method); - msg.set_request_uri(custom_path1); - VERIFY_ARE_EQUAL(custom_path1, msg.relative_uri().to_string()); - const utility::string_t custom_path2 = U("/yes/you/there"); - msg.set_request_uri(custom_path2); - VERIFY_ARE_EQUAL(custom_path2, msg.relative_uri().to_string()); - t2 = p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, custom_path2); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - p_server->close(); - try - { - t1.get(); - } - catch (...) - { - VERIFY_ARE_EQUAL(0, 1, "t1 failed"); - } - try - { - t2.get(); - } - catch (...) - { - VERIFY_ARE_EQUAL(0, 2, "t2 failed"); - } - } - - TEST_FIXTURE(uri_address, body_types) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // Body data types. - const method method(U("CUSTOMmethod")); - utility::string_t str_body(U("YES_BASIC_STRING BODY")); - utility::string_t str_move_body(str_body); - std::vector<unsigned char> vector_body; - vector_body.resize(str_body.size() * sizeof(utility::char_t)); - memcpy(&vector_body[0], &str_body[0], str_body.size() * sizeof(utility::char_t)); - std::vector<unsigned char> vector_move_body(vector_body); - utility::string_t custom_content = U("YESNOW!"); - - // vector - no content type. - http_request msg(method); - msg.set_body(std::move(vector_move_body)); - VERIFY_ARE_EQUAL(U("application/octet-stream"), msg.headers()[U("Content-Type")]); - p_server->next_request().then([&](test_request* p_request) { - auto received = p_request->m_body; - auto sent = vector_body; - VERIFY_IS_TRUE(received == sent); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // vector - with content type. - msg = http_request(method); - vector_move_body = vector_body; - msg.headers().add(U("Content-Type"), custom_content); - msg.set_body(std::move(vector_move_body)); - VERIFY_ARE_EQUAL(custom_content, msg.headers()[U("Content-Type")]); - p_server->next_request().then([&](test_request* p_request) { - auto received = p_request->m_body; - auto sent = vector_body; - VERIFY_IS_TRUE(received == sent); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // string - no content type. - msg = http_request(method); - msg.set_body(std::move(str_move_body)); - VERIFY_ARE_EQUAL(U("text/plain; charset=utf-8"), msg.headers()[U("Content-Type")]); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, method, U("/"), U("text/plain; charset=utf-8"), str_body); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // string - with content type. - msg = http_request(method); - str_move_body = str_body; - msg.headers().add(U("Content-Type"), custom_content); - msg.set_body(std::move(str_move_body)); - VERIFY_ARE_EQUAL(custom_content, msg.headers()[U("Content-Type")]); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, U("/"), custom_content, str_body); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - TEST(set_body_string_with_charset) - { - http_request request; - VERIFY_THROWS(request.set_body(::utility::conversions::to_utf16string("body_data"), - ::utility::conversions::to_utf16string("text/plain;charset=utf-16")), - std::invalid_argument); - } - - TEST_FIXTURE(uri_address, empty_bodies) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // Body data. - std::string empty_str; - std::vector<unsigned char> vector_body; - utility::string_t str_body; - utility::string_t wstr_body; - - // empty vector. - const method method(methods::PUT); - http_request msg(method); - msg.set_body(std::move(vector_body)); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, U("/"), U("application/octet-stream")); - VERIFY_ARE_EQUAL(0u, p_request->m_body.size()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // empty string. - msg = http_request(method); - msg.set_body(std::move(str_body)); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, U("/"), U("text/plain; charset=utf-8")); - VERIFY_ARE_EQUAL(0u, p_request->m_body.size()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // empty wstring. - msg = http_request(method); - msg.set_body(std::move(wstr_body)); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, U("/"), U("text/plain; charset=utf-8")); - VERIFY_ARE_EQUAL(0u, p_request->m_body.size()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, set_body) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const method mtd = methods::POST; - utility::string_t data(U("YOU KNOW~!!!!!")); - utility::string_t content_type = U("text/plain; charset=utf-8"); - - // without content type - http_request msg(mtd); - msg.set_body(data); - VERIFY_ARE_EQUAL(content_type, msg.headers()[U("Content-Type")]); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/"), content_type, data); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // with content type - content_type = U("YESYES"); -#ifdef _UTF16_STRINGS - const utility::string_t expected_content_type = U("YESYES; charset=utf-8"); -#else - const utility::string_t expected_content_type = U("YESYES"); -#endif - msg = http_request(mtd); - msg.set_body(data, content_type); - VERIFY_ARE_EQUAL(expected_content_type, msg.headers()[U("Content-Type")]); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/"), expected_content_type, data); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, set_body_with_charset) - { - http_request msg(methods::PUT); - msg.set_body("datadatadata", "text/plain;charset=us-ascii"); - VERIFY_THROWS(msg.set_body(::utility::conversions::to_utf16string("datadatadata"), - ::utility::conversions::to_utf16string("text/plain;charset=us-ascii")), - std::invalid_argument); - } - - TEST_FIXTURE(uri_address, set_content_length_locale, "Ignore:Android", "Locale unsupported on Android") - { - std::locale changedLocale; - try - { -#ifdef _WIN32 - changedLocale = std::locale("fr-FR"); -#else - changedLocale = std::locale("fr_FR.UTF-8"); -#endif - } - catch (const std::exception&) - { - // Silently pass if locale isn't installed on the machine. - return; - } - - tests::common::utilities::locale_guard loc(changedLocale); - - http_request req(methods::PUT); - req.headers().set_content_length(1000); - VERIFY_ARE_EQUAL(U("1000"), req.headers()[web::http::header_names::content_length]); // fr_RF would have 1 000 - } - - TEST_FIXTURE(uri_address, set_port_locale, "Ignore:Android", "Locale unsupported on Android") - { - std::locale changedLocale; - try - { -#ifdef _WIN32 - changedLocale = std::locale("fr-FR"); -#else - changedLocale = std::locale("fr_FR.UTF-8"); -#endif - } - catch (const std::exception&) - { - // Silently pass if locale isn't installed on machine. - return; - } - tests::common::utilities::locale_guard loc(changedLocale); - - test_http_server::scoped_server scoped(m_uri); - pplx::task<void> t; - http_client client(m_uri); - - utility::string_t data(U("STRING data 1000")); - t = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/"), U("text/plain; charset=utf-8"), data); - p_request->reply(200); - }); - - http_request msg(methods::PUT); - msg.set_body(data); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - scoped.server()->close(); - t.get(); - } - - TEST_FIXTURE(uri_address, reuse_request) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - http_request msg(methods::GET); - for (int i = 0; i < 3; ++i) - { - p_server->next_request().then([](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::GET, U("/")); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - } -} - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/client_construction.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/client_construction.cpp @@ -1,227 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * client_construction.cpp - * - * Tests cases for covering creating http_clients. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include <fstream> - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(client_construction) -{ - // Tests using different types of strings to construct an http_client. - TEST_FIXTURE(uri_address, string_types) - { - // The goal of this test case is to make sure we can compile, - // if the URI class doesn't have the proper constructors it won't. - // So we don't need to actually do a request. - http_client c1(U("http://localhost:4567/")); - http_client c3(utility::string_t(U("http://localhost:4567/"))); - } - - // Tests different variations on specifying the URI in http_client constructor. - TEST_FIXTURE(uri_address, different_uris) - { - const utility::string_t paths[] = {U(""), U("/"), U("/toplevel/nested"), U("/toplevel/nested/")}; - const utility::string_t expected_paths[] = {U("/"), U("/"), U("/toplevel/nested"), U("/toplevel/nested/")}; - const size_t num_paths = sizeof(paths) / sizeof(paths[0]); - for (size_t i = 0; i < num_paths; ++i) - { - uri address(U("http://localhost:55678") + paths[i]); - test_http_server::scoped_server scoped(address); - http_client client(address); - test_connection(scoped.server(), &client, expected_paths[i]); - } - } - - // Helper function verifies that when constructing an http_client with given - // URI std::invalid_argument is thrown. - static void verify_client_invalid_argument(const uri& address) - { - try - { - http_client client(address); - VERIFY_IS_TRUE(false); - } - catch (std::invalid_argument&) - { - // expected - } - } - - TEST_FIXTURE(uri_address, client_construction_error_cases) - { - uri address(U("nothttp://localhost:34567/")); - - // Invalid scheme. - verify_client_invalid_argument(address); - - // empty host. - address = uri(U("http://:34567/")); - verify_client_invalid_argument(address); - } - - TEST_FIXTURE(uri_address, client_construction_no_scheme) - { - uri address(U("//localhost:34568/p/g")); - test_http_server::scoped_server scoped(m_uri); - - http_client client(address); - test_connection(scoped.server(), &client, U("/p/g")); - } - - TEST_FIXTURE(uri_address, copy_assignment) - { - test_http_server::scoped_server scoped(m_uri); - - // copy constructor - http_client original(m_uri); - http_client new_client(original); - test_connection(scoped.server(), &new_client, U("/")); - test_connection(scoped.server(), &original, U("/")); - - // assignment - http_client new_client2(U("http://bad:-1")); - new_client2 = original; - test_connection(scoped.server(), &new_client2, U("/")); - test_connection(scoped.server(), &original, U("/")); - } - - TEST_FIXTURE(uri_address, move_not_init) - { - test_http_server::scoped_server scoped(m_uri); - - // move constructor - http_client original(m_uri); - http_client new_client = std::move(original); - test_connection(scoped.server(), &new_client, U("/")); - - // move assignment - original = http_client(m_uri); - test_connection(scoped.server(), &original, U("/")); - } - - TEST_FIXTURE(uri_address, move_init) - { - test_http_server::scoped_server scoped(m_uri); - - // move constructor - http_client original(m_uri); - test_connection(scoped.server(), &original, U("/")); - http_client new_client = std::move(original); - test_connection(scoped.server(), &new_client, U("/")); - - // move assignment - original = http_client(m_uri); - test_connection(scoped.server(), &original, U("/")); - } - - // Verify that we can read the config from the http_client - TEST_FIXTURE(uri_address, get_client_config) - { - test_http_server::scoped_server scoped(m_uri); - - http_client_config config; - - VERIFY_ARE_EQUAL(config.chunksize(), 64 * 1024); - config.set_chunksize(1024); - VERIFY_ARE_EQUAL(config.chunksize(), 1024); - - utility::seconds timeout(100); - config.set_timeout(timeout); - http_client client(m_uri, config); - - const http_client_config& config2 = client.client_config(); - VERIFY_ARE_EQUAL(config2.timeout().count(), timeout.count()); - std::chrono::milliseconds milli_timeout = config2.timeout(); - VERIFY_ARE_EQUAL(milli_timeout.count(), std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()); - auto micro_timeout = config.timeout<std::chrono::microseconds>(); - VERIFY_ARE_EQUAL(micro_timeout.count(), std::chrono::duration_cast<std::chrono::microseconds>(timeout).count()); - - VERIFY_ARE_EQUAL(config2.chunksize(), 1024); - } - - // Verify that we can get the baseuri from http_client constructors - TEST_FIXTURE(uri_address, BaseURI_test) - { - http_client baseclient1(m_uri); - VERIFY_ARE_EQUAL(baseclient1.base_uri(), m_uri); - - http_client_config config; - http_client baseclient2(m_uri, config); - VERIFY_ARE_EQUAL(baseclient2.base_uri(), m_uri); - } - -#if !defined(_WIN32) && !defined(__cplusplus_winrt) || defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) - - // Verify that the callback of sslcontext is called for HTTPS - TEST_FIXTURE(uri_address, ssl_context_callback_https) - { - http_client_config config; - bool called = false; - - config.set_ssl_context_callback([&called](boost::asio::ssl::context& ctx) { called = true; }); - - http_client client(U("https://www.google.com/"), config); - - try - { - client.request(methods::GET, U("/")).get(); - } - catch (...) - { - } - - VERIFY_IS_TRUE(called, "The sslcontext options is not called for HTTPS protocol"); - } - - // Verify that the callback of sslcontext is not called for HTTP - TEST_FIXTURE(uri_address, ssl_context_callback_http) - { - http_client_config config; - bool called = false; - - config.set_ssl_context_callback([&called](boost::asio::ssl::context& ctx) { called = true; }); - - http_client client(U("http://www.google.com/"), config); - - try - { - client.request(methods::GET, U("/")).get(); - } - catch (...) - { - } - - VERIFY_IS_FALSE(called, "The sslcontext options is called for HTTP protocol"); - } - -#endif - -} // SUITE(client_construction) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/compression_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/compression_tests.cpp @@ -1,1356 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * compression_tests.cpp - * - * Tests cases, including client/server, for the web::http::compression namespace. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/details/http_helpers.h" -#include "cpprest/version.h" -#include <fstream> - -#ifndef __cplusplus_winrt -#include "cpprest/http_listener.h" -#endif - -using namespace web; -using namespace utility; -using namespace web::http; -using namespace web::http::client; -using namespace web::http::compression; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(compression_tests) -{ - // A fake "pass-through" compressor/decompressor for testing - class fake_provider : public compress_provider, public decompress_provider - { - public: - static const utility::string_t FAKE; - - fake_provider(size_t size = static_cast<size_t>(-1)) : _size(size), _so_far(0), _done(false) {} - - virtual const utility::string_t& algorithm() const { return FAKE; } - - virtual size_t decompress(const uint8_t* input, - size_t input_size, - uint8_t* output, - size_t output_size, - operation_hint hint, - size_t& input_bytes_processed, - bool& done) - { - size_t bytes; - - if (_done) - { - input_bytes_processed = 0; - done = true; - return 0; - } - if (_size == static_cast<size_t>(-1) || input_size > _size - _so_far) - { - std::stringstream ss; - ss << "Fake decompress - invalid data " << input_size << ", " << output_size << " with " << _so_far - << " / " << _size; - throw std::runtime_error(std::move(ss.str())); - } - bytes = (std::min)(input_size, output_size); - if (bytes) - { - memcpy(output, input, bytes); - } - _so_far += bytes; - _done = (_so_far == _size); - done = _done; - input_bytes_processed = bytes; - return input_bytes_processed; - } - - virtual pplx::task<operation_result> decompress( - const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) - { - operation_result r; - - try - { - r.output_bytes_produced = - decompress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); - } - catch (...) - { - pplx::task_completion_event<operation_result> ev; - ev.set_exception(std::current_exception()); - return pplx::create_task(ev); - } - - return pplx::task_from_result<operation_result>(r); - } - - virtual size_t compress(const uint8_t* input, - size_t input_size, - uint8_t* output, - size_t output_size, - operation_hint hint, - size_t& input_bytes_processed, - bool& done) - { - size_t bytes; - - if (_done) - { - input_bytes_processed = 0; - done = true; - return 0; - } - if (_size == static_cast<size_t>(-1) || input_size > _size - _so_far) - { - std::stringstream ss; - ss << "Fake compress - invalid data " << input_size << ", " << output_size << " with " << _so_far - << " / " << _size; - throw std::runtime_error(std::move(ss.str())); - } - bytes = (std::min)(input_size, output_size); - if (bytes) - { - memcpy(output, input, bytes); - } - _so_far += bytes; - _done = (hint == operation_hint::is_last && _so_far == _size); - done = _done; - input_bytes_processed = bytes; - return input_bytes_processed; - } - - virtual pplx::task<operation_result> compress( - const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) - { - operation_result r; - - try - { - r.output_bytes_produced = - compress(input, input_size, output, output_size, hint, r.input_bytes_processed, r.done); - } - catch (...) - { - pplx::task_completion_event<operation_result> ev; - ev.set_exception(std::current_exception()); - return pplx::create_task(ev); - } - - return pplx::task_from_result<operation_result>(r); - } - - virtual void reset() - { - _done = false; - _so_far = 0; - } - - private: - size_t _size; - size_t _so_far; - bool _done; - }; - - const utility::string_t fake_provider::FAKE = _XPLATSTR("fake"); - - void compress_and_decompress(std::unique_ptr<compress_provider> compressor, - std::unique_ptr<decompress_provider> decompressor, - const size_t buffer_size, - const size_t chunk_size, - bool compressible) - { - std::vector<uint8_t> input_buffer; - size_t i; - - VERIFY_ARE_EQUAL(compressor->algorithm(), decompressor->algorithm()); - - input_buffer.reserve(buffer_size); - for (i = 0; i < buffer_size; ++i) - { - uint8_t element; - if (compressible) - { - element = static_cast<uint8_t>('a' + i % 26); - } - else - { - element = static_cast<uint8_t>(std::rand()); - } - - input_buffer.push_back(element); - } - - // compress in chunks - std::vector<size_t> chunk_sizes; - std::vector<uint8_t> cmp_buffer(buffer_size); - size_t cmpsize = buffer_size; - size_t csize = 0; - operation_result r = {}; - operation_hint hint = operation_hint::has_more; - for (i = 0; i < buffer_size || csize == cmpsize || !r.done; i += r.input_bytes_processed) - { - if (i == buffer_size) - { - // the entire input buffer has been consumed by the compressor - hint = operation_hint::is_last; - } - if (csize == cmpsize) - { - // extend the output buffer if there may be more compressed bytes to retrieve - cmpsize += (std::min)(chunk_size, (size_t)200); - cmp_buffer.resize(cmpsize); - } - r = compressor - ->compress(input_buffer.data() + i, - (std::min)(chunk_size, buffer_size - i), - cmp_buffer.data() + csize, - (std::min)(chunk_size, cmpsize - csize), - hint) - .get(); - VERIFY_IS_TRUE(r.input_bytes_processed == (std::min)(chunk_size, buffer_size - i) || - r.output_bytes_produced == (std::min)(chunk_size, cmpsize - csize)); - VERIFY_IS_TRUE(hint == operation_hint::is_last || !r.done); - chunk_sizes.push_back(r.output_bytes_produced); - csize += r.output_bytes_produced; - } - VERIFY_ARE_EQUAL(r.done, true); - - // once more with no input or output, to assure no error and done - r = compressor->compress(NULL, 0, NULL, 0, operation_hint::is_last).get(); - VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); - VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); - VERIFY_ARE_EQUAL(r.done, true); - - cmp_buffer.resize(csize); // actual - - // decompress in as-compressed chunks - std::vector<uint8_t> dcmp_buffer(buffer_size); - size_t dsize = 0; - size_t nn = 0; - for (std::vector<size_t>::iterator it = chunk_sizes.begin(); it != chunk_sizes.end(); ++it) - { - if (*it) - { - auto hint = operation_hint::has_more; - if (it == chunk_sizes.begin()) - { - hint = operation_hint::is_last; - } - - r = decompressor - ->decompress(cmp_buffer.data() + nn, - *it, - dcmp_buffer.data() + dsize, - (std::min)(chunk_size, buffer_size - dsize), - hint) - .get(); - nn += *it; - dsize += r.output_bytes_produced; - } - } - VERIFY_ARE_EQUAL(csize, nn); - VERIFY_ARE_EQUAL(dsize, buffer_size); - VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); - VERIFY_IS_TRUE(r.done); - - // decompress again in fixed-size chunks - nn = 0; - dsize = 0; - decompressor->reset(); - memset(dcmp_buffer.data(), 0, dcmp_buffer.size()); - do - { - size_t n = (std::min)(chunk_size, csize - nn); - do - { - r = decompressor - ->decompress(cmp_buffer.data() + nn, - n, - dcmp_buffer.data() + dsize, - (std::min)(chunk_size, buffer_size - dsize), - operation_hint::has_more) - .get(); - dsize += r.output_bytes_produced; - nn += r.input_bytes_processed; - n -= r.input_bytes_processed; - } while (n); - } while (nn < csize || !r.done); - VERIFY_ARE_EQUAL(csize, nn); - VERIFY_ARE_EQUAL(dsize, buffer_size); - VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); - VERIFY_IS_TRUE(r.done); - - // once more with no input, to assure no error and done - r = decompressor->decompress(NULL, 0, NULL, 0, operation_hint::has_more).get(); - VERIFY_ARE_EQUAL(r.input_bytes_processed, 0); - VERIFY_ARE_EQUAL(r.output_bytes_produced, 0); - VERIFY_IS_TRUE(r.done); - - // decompress all at once - decompressor->reset(); - memset(dcmp_buffer.data(), 0, dcmp_buffer.size()); - r = decompressor - ->decompress(cmp_buffer.data(), csize, dcmp_buffer.data(), dcmp_buffer.size(), operation_hint::is_last) - .get(); - VERIFY_ARE_EQUAL(r.output_bytes_produced, buffer_size); - VERIFY_ARE_EQUAL(input_buffer, dcmp_buffer); - - if (decompressor->algorithm() != fake_provider::FAKE) - { - // invalid decompress buffer, first and subsequent tries - cmp_buffer[0] = ~cmp_buffer[1]; - decompressor->reset(); - for (i = 0; i < 2; i++) - { - nn = 0; - try - { - r = decompressor - ->decompress(cmp_buffer.data(), - csize, - dcmp_buffer.data(), - dcmp_buffer.size(), - operation_hint::is_last) - .get(); - VERIFY_IS_FALSE(r.done && r.output_bytes_produced == buffer_size); - } - catch (std::runtime_error) - { - } - } - } - } - - void compress_test(std::shared_ptr<compress_factory> cfactory, std::shared_ptr<decompress_factory> dfactory) - { - size_t tuples[][2] = {{3, 1024}, - {7999, 8192}, - {8192, 8192}, - {16001, 8192}, - {16384, 8192}, - {140000, 65536}, - {256 * 1024, 65536}, - {256 * 1024, 256 * 1024}, - {263456, 256 * 1024}}; - - for (int i = 0; i < sizeof(tuples) / sizeof(tuples[0]); i++) - { - for (int j = 0; j < 2; j++) - { - if (!cfactory) - { - auto size = tuples[i][0]; - compress_and_decompress(utility::details::make_unique<fake_provider>(size), - utility::details::make_unique<fake_provider>(size), - size, - tuples[i][1], - !!j); - } - else - { - compress_and_decompress( - cfactory->make_compressor(), dfactory->make_decompressor(), tuples[i][0], tuples[i][1], !!j); - } - } - } - } - - TEST_FIXTURE(uri_address, compress_and_decompress_fake) - { - compress_test(nullptr, nullptr); // FAKE - } - - TEST_FIXTURE(uri_address, compress_and_decompress_gzip) - { - if (builtin::algorithm::supported(builtin::algorithm::GZIP)) - { - compress_test(builtin::get_compress_factory(builtin::algorithm::GZIP), - builtin::get_decompress_factory(builtin::algorithm::GZIP)); - } - } - - TEST_FIXTURE(uri_address, compress_and_decompress_deflate) - { - if (builtin::algorithm::supported(builtin::algorithm::DEFLATE)) - { - compress_test(builtin::get_compress_factory(builtin::algorithm::DEFLATE), - builtin::get_decompress_factory(builtin::algorithm::DEFLATE)); - } - } - - TEST_FIXTURE(uri_address, compress_and_decompress_brotli) - { - if (builtin::algorithm::supported(builtin::algorithm::BROTLI)) - { - compress_test(builtin::get_compress_factory(builtin::algorithm::BROTLI), - builtin::get_decompress_factory(builtin::algorithm::BROTLI)); - } - } - - TEST_FIXTURE(uri_address, compress_headers) - { - const utility::string_t _NONE = _XPLATSTR("none"); - - std::unique_ptr<compress_provider> c; - std::unique_ptr<decompress_provider> d; - - std::shared_ptr<compress_factory> fcf = - make_compress_factory(fake_provider::FAKE, []() -> std::unique_ptr<compress_provider> { - return utility::details::make_unique<fake_provider>(); - }); - std::vector<std::shared_ptr<compress_factory>> fcv; - fcv.push_back(fcf); - std::shared_ptr<decompress_factory> fdf = - make_decompress_factory(fake_provider::FAKE, 800, []() -> std::unique_ptr<decompress_provider> { - return utility::details::make_unique<fake_provider>(); - }); - std::vector<std::shared_ptr<decompress_factory>> fdv; - fdv.push_back(fdf); - - std::shared_ptr<compress_factory> ncf = - make_compress_factory(_NONE, []() -> std::unique_ptr<compress_provider> { - return utility::details::make_unique<fake_provider>(); - }); - std::vector<std::shared_ptr<compress_factory>> ncv; - ncv.push_back(ncf); - std::shared_ptr<decompress_factory> ndf = - make_decompress_factory(_NONE, 800, []() -> std::unique_ptr<decompress_provider> { - return utility::details::make_unique<fake_provider>(); - }); - std::vector<std::shared_ptr<decompress_factory>> ndv; - ndv.push_back(ndf); - - // Supported algorithms - VERIFY_ARE_EQUAL(builtin::supported(), builtin::algorithm::supported(builtin::algorithm::GZIP)); - VERIFY_ARE_EQUAL(builtin::supported(), builtin::algorithm::supported(builtin::algorithm::DEFLATE)); - if (builtin::algorithm::supported(builtin::algorithm::BROTLI)) - { - VERIFY_IS_TRUE(builtin::supported()); - } - VERIFY_IS_FALSE(builtin::algorithm::supported(_XPLATSTR(""))); - VERIFY_IS_FALSE(builtin::algorithm::supported(_XPLATSTR("foo"))); - - // Strings that double as both Transfer-Encoding and TE - std::vector<utility::string_t> encodings = {_XPLATSTR("gzip"), - _XPLATSTR("gZip "), - _XPLATSTR(" GZIP"), - _XPLATSTR(" gzip "), - _XPLATSTR(" gzip , chunked "), - _XPLATSTR(" gZip , chunked "), - _XPLATSTR("GZIP,chunked")}; - - // Similar, but geared to match a non-built-in algorithm - std::vector<utility::string_t> fake = {_XPLATSTR("fake"), - _XPLATSTR("faKe "), - _XPLATSTR(" FAKE"), - _XPLATSTR(" fake "), - _XPLATSTR(" fake , chunked "), - _XPLATSTR(" faKe , chunked "), - _XPLATSTR("FAKE,chunked")}; - - std::vector<utility::string_t> invalid = {_XPLATSTR(","), - _XPLATSTR(",gzip"), - _XPLATSTR("gzip,"), - _XPLATSTR(",gzip, chunked"), - _XPLATSTR(" ,gzip, chunked"), - _XPLATSTR("gzip, chunked,"), - _XPLATSTR("gzip, chunked, "), - _XPLATSTR("gzip,, chunked"), - _XPLATSTR("gzip , , chunked"), - _XPLATSTR("foo")}; - - std::vector<utility::string_t> invalid_tes = { - _XPLATSTR("deflate;q=0.5, gzip;q=2"), - _XPLATSTR("deflate;q=1.5, gzip;q=1"), - }; - - std::vector<utility::string_t> empty = {_XPLATSTR(""), _XPLATSTR(" ")}; - - // Repeat for Transfer-Encoding (which also covers part of TE) and Content-Encoding (which also covers all of - // Accept-Encoding) - for (int transfer = 0; transfer < 2; transfer++) - { - compression::details::header_types ctype = - transfer ? compression::details::header_types::te : compression::details::header_types::accept_encoding; - compression::details::header_types dtype = transfer ? compression::details::header_types::transfer_encoding - : compression::details::header_types::content_encoding; - - // No compression - Transfer-Encoding - d = compression::details::get_decompressor_from_header( - _XPLATSTR(" chunked "), compression::details::header_types::transfer_encoding); - VERIFY_IS_FALSE((bool)d); - - utility::string_t gzip(builtin::algorithm::GZIP); - for (auto encoding = encodings.begin(); encoding != encodings.end(); encoding++) - { - bool has_comma = false; - - has_comma = encoding->find(_XPLATSTR(",")) != utility::string_t::npos; - - // Built-in only - c = compression::details::get_compressor_from_header(*encoding, ctype); - VERIFY_ARE_EQUAL((bool)c, builtin::supported()); - if (c) - { - VERIFY_ARE_EQUAL(c->algorithm(), gzip); - } - - try - { - d = compression::details::get_decompressor_from_header(*encoding, dtype); - VERIFY_ARE_EQUAL((bool)d, builtin::supported()); - if (d) - { - VERIFY_ARE_EQUAL(d->algorithm(), gzip); - } - } - catch (http_exception) - { - VERIFY_IS_TRUE(transfer == !has_comma); - } - } - - for (auto encoding = fake.begin(); encoding != fake.end(); encoding++) - { - bool has_comma = false; - - has_comma = encoding->find(_XPLATSTR(",")) != utility::string_t::npos; - - // Supplied compressor/decompressor - c = compression::details::get_compressor_from_header(*encoding, ctype, fcv); - VERIFY_IS_TRUE((bool)c); - VERIFY_IS_TRUE(c->algorithm() == fcf->algorithm()); - - try - { - d = compression::details::get_decompressor_from_header(*encoding, dtype, fdv); - VERIFY_IS_TRUE((bool)d); - VERIFY_IS_TRUE(d->algorithm() == fdf->algorithm()); - } - catch (http_exception) - { - VERIFY_IS_TRUE(transfer == !has_comma); - } - - // No matching compressor - c = compression::details::get_compressor_from_header(*encoding, ctype, ncv); - VERIFY_IS_FALSE((bool)c); - - try - { - d = compression::details::get_decompressor_from_header(*encoding, dtype, ndv); - VERIFY_IS_FALSE(true); - } - catch (http_exception) - { - } - } - - // Negative tests - invalid headers, no matching algorithm, etc. - for (auto encoding = invalid.begin(); encoding != invalid.end(); encoding++) - { - try - { - c = compression::details::get_compressor_from_header(*encoding, ctype); - VERIFY_IS_TRUE(encoding->find(_XPLATSTR(",")) == utility::string_t::npos); - VERIFY_IS_FALSE((bool)c); - } - catch (http_exception) - { - } - - try - { - d = compression::details::get_decompressor_from_header(*encoding, dtype); - VERIFY_IS_TRUE(!builtin::supported() && encoding->find(_XPLATSTR(",")) == utility::string_t::npos); - VERIFY_IS_FALSE((bool)d); - } - catch (http_exception) - { - } - } - - // Negative tests - empty headers - for (auto encoding = empty.begin(); encoding != empty.end(); encoding++) - { - c = compression::details::get_compressor_from_header(*encoding, ctype); - VERIFY_IS_FALSE((bool)c); - - try - { - d = compression::details::get_decompressor_from_header(*encoding, dtype); - VERIFY_IS_FALSE(true); - } - catch (http_exception) - { - } - } - - // Negative tests - invalid rankings - for (auto te = invalid_tes.begin(); te != invalid_tes.end(); te++) - { - try - { - c = compression::details::get_compressor_from_header(*te, ctype); - VERIFY_IS_FALSE(true); - } - catch (http_exception) - { - } - } - - utility::string_t builtin; - std::vector<std::shared_ptr<decompress_factory>> dv; - - // Builtins - builtin = compression::details::build_supported_header(ctype); - if (transfer) - { - VERIFY_ARE_EQUAL(!builtin.empty(), builtin::supported()); - } - else - { - VERIFY_IS_FALSE(builtin.empty()); - } - - // Null decompressor - effectively forces no compression algorithms - dv.push_back(std::shared_ptr<decompress_factory>()); - builtin = compression::details::build_supported_header(ctype, dv); - VERIFY_ARE_EQUAL(transfer != 0, builtin.empty()); - dv.pop_back(); - - if (builtin::supported()) - { - dv.push_back(builtin::get_decompress_factory(builtin::algorithm::GZIP)); - builtin = compression::details::build_supported_header(ctype, dv); // --> "gzip;q=1.0" - VERIFY_IS_FALSE(builtin.empty()); - } - else - { - builtin = _XPLATSTR("gzip;q=1.0"); - } - - // TE- and/or Accept-Encoding-specific test cases, regenerated for each pass - std::vector<utility::string_t> tes = { - builtin, - _XPLATSTR(" deflate;q=0.777 ,foo;q=0,gzip;q=0.9, bar;q=1.0, xxx;q=1 "), - _XPLATSTR("gzip ; q=1, deflate;q=0.5"), - _XPLATSTR("gzip;q=1.0, deflate;q=0.5"), - _XPLATSTR("deflate;q=0.5, gzip;q=1"), - _XPLATSTR("gzip,deflate;q=0.7"), - _XPLATSTR("trailers,gzip,deflate;q=0.7")}; - - for (int fake = 0; fake < 2; fake++) - { - if (fake) - { - // Switch built-in vs. supplied results the second time around - for (auto& te : tes) - { - te.replace(te.find(builtin::algorithm::GZIP), gzip.size(), fake_provider::FAKE); - if (te.find(builtin::algorithm::DEFLATE) != utility::string_t::npos) - { - te.replace(te.find(builtin::algorithm::DEFLATE), - utility::string_t(builtin::algorithm::DEFLATE).size(), - _NONE); - } - } - } - - for (auto te = tes.begin(); te != tes.end(); te++) - { - // Built-in only - c = compression::details::get_compressor_from_header(*te, ctype); - if (c) - { - VERIFY_IS_TRUE(builtin::supported()); - VERIFY_IS_FALSE(fake != 0); - VERIFY_ARE_EQUAL(c->algorithm(), gzip); - } - else - { - VERIFY_IS_TRUE(fake != 0 || !builtin::supported()); - } - - // Supplied compressor - both matching and non-matching - c = compression::details::get_compressor_from_header(*te, ctype, fcv); - VERIFY_ARE_EQUAL(c != 0, fake != 0); - if (c) - { - VERIFY_ARE_EQUAL(c->algorithm(), fake_provider::FAKE); - } - } - } - } - } - - template<typename _CharType> - class my_rawptr_buffer : public concurrency::streams::rawptr_buffer<_CharType> - { - public: - my_rawptr_buffer(const _CharType* data, size_t size) - : concurrency::streams::rawptr_buffer<_CharType>(data, size) - { - } - - // No acquire(), to force non-acquire compression client codepaths - virtual bool acquire(_Out_ _CharType*& ptr, _Out_ size_t& count) - { - (void)ptr; - (void)count; - return false; - } - - virtual void release(_Out_writes_(count) _CharType* ptr, _In_ size_t count) - { - (void)ptr; - (void)count; - } - - static concurrency::streams::basic_istream<_CharType> open_istream(const _CharType* data, size_t size) - { - return concurrency::streams::basic_istream<_CharType>( - concurrency::streams::streambuf<_CharType>(std::make_shared<my_rawptr_buffer<_CharType>>(data, size))); - } - }; - - TEST_FIXTURE(uri_address, compress_client_server) - { - bool processed; - bool skip_transfer_put = false; - int transfer; - - size_t buffer_sizes[] = {0, 1, 3, 4, 4096, 65536, 100000, 157890}; - - std::vector<std::shared_ptr<decompress_factory>> dfactories; - std::vector<std::shared_ptr<compress_factory>> cfactories; - -#if defined(_WIN32) && !defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) - // Run a quick test to see if we're dealing with older/broken winhttp for compressed transfer encoding - { - test_http_server* p_server = nullptr; - std::unique_ptr<test_http_server::scoped_server> scoped = - std::move(utility::details::make_unique<test_http_server::scoped_server>(m_uri)); - scoped->server()->next_request().then([&skip_transfer_put](pplx::task<test_request*> op) { - try - { - op.get()->reply(static_cast<unsigned short>(status_codes::OK)); - } - catch (std::runtime_error) - { - // The test server throws if it's destructed with outstanding tasks, - // which will happen if winhttp responds 501 without informing us - VERIFY_IS_TRUE(skip_transfer_put); - } - }); - - http_client client(m_uri); - http_request msg(methods::PUT); - msg.set_compressor(utility::details::make_unique<fake_provider>(0)); - msg.set_body(concurrency::streams::rawptr_stream<uint8_t>::open_istream((const uint8_t*)nullptr, 0)); - http_response rsp = client.request(msg).get(); - rsp.content_ready().wait(); - if (rsp.status_code() == status_codes::NotImplemented) - { - skip_transfer_put = true; - } - else - { - VERIFY_IS_TRUE(rsp.status_code() == status_codes::OK); - } - } -#endif // _WIN32 - - auto extra_size = [](size_t bufsz) -> size_t { return (std::max)(static_cast<size_t>(128), bufsz / 1000); }; - - // Test decompression both explicitly through the test server and implicitly through the listener; - // this is the top-level loop in order to avoid thrashing the listeners more than necessary - for (int real = 0; real < 2; real++) - { - web::http::experimental::listener::http_listener listener; - std::unique_ptr<test_http_server::scoped_server> scoped; - test_http_server* p_server = nullptr; - std::vector<uint8_t> v; - size_t buffer_size; - - // Start the listener, and configure callbacks if necessary - if (real) - { - listener = std::move(web::http::experimental::listener::http_listener(m_uri)); - listener.open().wait(); - listener.support(methods::PUT, [&v, &dfactories, &processed](http_request request) { - utility::string_t encoding; - http_response rsp; - - if (request.headers().match(web::http::header_names::transfer_encoding, encoding) || - request.headers().match(web::http::header_names::content_encoding, encoding)) - { - if (encoding.find(fake_provider::FAKE) != utility::string_t::npos) - { - // This one won't be found by the server in the default set... - rsp._get_impl()->set_decompress_factories(dfactories); - } - } - processed = true; - rsp.set_status_code(status_codes::OK); - request.reply(rsp); - }); - listener.support( - methods::GET, - [&v, &buffer_size, &cfactories, &processed, &transfer, &extra_size](http_request request) { - utility::string_t encoding; - http_response rsp; - bool done; - - if (transfer) - { -#if defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) - // Compression happens in the listener itself - done = request.headers().match(web::http::header_names::te, encoding); - VERIFY_IS_TRUE(done); - if (encoding.find(fake_provider::FAKE) != utility::string_t::npos) - { - // This one won't be found in the server's default set... - rsp._get_impl()->set_compressor( - utility::details::make_unique<fake_provider>(buffer_size)); - } -#endif // _WIN32 - rsp.set_body( - concurrency::streams::rawptr_stream<uint8_t>::open_istream(v.data(), v.size())); - } - else - { - std::unique_ptr<compress_provider> c; - std::vector<uint8_t> pre; - size_t used; - - done = request.headers().match(web::http::header_names::accept_encoding, encoding); - VERIFY_IS_TRUE(done); - pre.resize(v.size() + extra_size(buffer_size)); - c = compression::details::get_compressor_from_header( - encoding, compression::details::header_types::accept_encoding, cfactories); - VERIFY_IS_TRUE((bool)c); - auto got = c->compress( - v.data(), v.size(), pre.data(), pre.size(), operation_hint::is_last, used, done); - VERIFY_IS_TRUE(used == v.size()); - VERIFY_IS_TRUE(done); - - // Add a single pre-compressed stream, since Content-Encoding requires Content-Length - pre.resize(got); - rsp.headers().add(header_names::content_encoding, c->algorithm()); - rsp.set_body( - concurrency::streams::container_stream<std::vector<uint8_t>>::open_istream(pre)); - } - processed = true; - rsp.set_status_code(status_codes::OK); - request.reply(rsp); - }); - } - else - { - scoped = std::move(utility::details::make_unique<test_http_server::scoped_server>(m_uri)); - p_server = scoped->server(); - } - - // Test various buffer sizes - for (int sz = 0; sz < sizeof(buffer_sizes) / sizeof(buffer_sizes[0]); sz++) - { - std::vector<utility::string_t> algorithms; - std::map<utility::string_t, std::shared_ptr<decompress_factory>> dmap; - std::map<utility::string_t, std::shared_ptr<compress_factory>> cmap; - - buffer_size = buffer_sizes[sz]; - - dfactories.clear(); - cfactories.clear(); - - // Re-build the sets of compress and decompress factories, to account for the buffer size in our "fake" - // ones - if (builtin::algorithm::supported(builtin::algorithm::GZIP)) - { - algorithms.push_back(builtin::algorithm::GZIP); - dmap[builtin::algorithm::GZIP] = builtin::get_decompress_factory(builtin::algorithm::GZIP); - cmap[builtin::algorithm::GZIP] = builtin::get_compress_factory(builtin::algorithm::GZIP); - dfactories.push_back(dmap[builtin::algorithm::GZIP]); - cfactories.push_back(cmap[builtin::algorithm::GZIP]); - } - if (builtin::algorithm::supported(builtin::algorithm::DEFLATE)) - { - algorithms.push_back(builtin::algorithm::DEFLATE); - dmap[builtin::algorithm::DEFLATE] = builtin::get_decompress_factory(builtin::algorithm::DEFLATE); - cmap[builtin::algorithm::DEFLATE] = builtin::get_compress_factory(builtin::algorithm::DEFLATE); - dfactories.push_back(dmap[builtin::algorithm::DEFLATE]); - cfactories.push_back(cmap[builtin::algorithm::DEFLATE]); - } - if (builtin::algorithm::supported(builtin::algorithm::BROTLI)) - { - algorithms.push_back(builtin::algorithm::BROTLI); - dmap[builtin::algorithm::BROTLI] = builtin::get_decompress_factory(builtin::algorithm::BROTLI); - cmap[builtin::algorithm::BROTLI] = - make_compress_factory(builtin::algorithm::BROTLI, []() -> std::unique_ptr<compress_provider> { - // Use a memory-constrained Brotli instance in some cases for code coverage - return builtin::make_brotli_compressor(10, 11, 0, 16, 0, 0); - }); - dfactories.push_back(dmap[builtin::algorithm::BROTLI]); - cfactories.push_back(builtin::get_compress_factory(builtin::algorithm::BROTLI)); - } - algorithms.push_back(fake_provider::FAKE); - dmap[fake_provider::FAKE] = make_decompress_factory( - fake_provider::FAKE, 1000, [buffer_size]() -> std::unique_ptr<decompress_provider> { - return utility::details::make_unique<fake_provider>(buffer_size); - }); - cmap[fake_provider::FAKE] = - make_compress_factory(fake_provider::FAKE, [buffer_size]() -> std::unique_ptr<compress_provider> { - return utility::details::make_unique<fake_provider>(buffer_size); - }); - dfactories.push_back(dmap[fake_provider::FAKE]); - cfactories.push_back(cmap[fake_provider::FAKE]); - - v.resize(buffer_size); - - // Test compressible (net shrinking) and non-compressible (net growing) buffers - for (int compressible = 0; compressible < 2; compressible++) - { - for (size_t x = 0; x < buffer_size; x++) - { - if (compressible) - { - v[x] = static_cast<uint8_t>('a' + x % 26); - } - else - { - v[x] = static_cast<uint8_t>(std::rand()); - } - } - - // Test both Transfer-Encoding and Content-Encoding - for (transfer = 0; transfer < 2; transfer++) - { - web::http::client::http_client_config config; - config.set_request_compressed_response(!transfer); - http_client client(m_uri, config); - - // Test supported compression algorithms - for (auto& algorithm : algorithms) - { - // Test both GET and PUT - for (int put = 0; put < 2; put++) - { - if (transfer && put && skip_transfer_put) - { - continue; - } - - processed = false; - - if (put) - { - std::vector<concurrency::streams::istream> streams; - std::vector<uint8_t> pre; - - if (transfer) - { - // Add a pair of non-compressed streams for Transfer-Encoding, one with and one - // without acquire/release support - streams.emplace_back(concurrency::streams::rawptr_stream<uint8_t>::open_istream( - (const uint8_t*)v.data(), v.size())); - streams.emplace_back( - my_rawptr_buffer<uint8_t>::open_istream(v.data(), v.size())); - } - else - { - bool done; - size_t used; - pre.resize(v.size() + extra_size(buffer_size)); - - auto c = builtin::make_compressor(algorithm); - if (algorithm == fake_provider::FAKE) - { - VERIFY_IS_FALSE((bool)c); - c = utility::details::make_unique<fake_provider>(buffer_size); - } - VERIFY_IS_TRUE((bool)c); - auto got = c->compress(v.data(), - v.size(), - pre.data(), - pre.size(), - operation_hint::is_last, - used, - done); - VERIFY_ARE_EQUAL(used, v.size()); - VERIFY_IS_TRUE(done); - - // Add a single pre-compressed stream, since Content-Encoding requires - // Content-Length - streams.emplace_back(concurrency::streams::rawptr_stream<uint8_t>::open_istream( - pre.data(), got)); - } - - for (auto& stream : streams) - { - http_request msg(methods::PUT); - - processed = false; - - msg.set_body(stream); - if (transfer) - { - if (real) - { - bool boo = msg.set_compressor(algorithm); - VERIFY_ARE_EQUAL(boo, algorithm != fake_provider::FAKE); - if (algorithm == fake_provider::FAKE) - { - msg.set_compressor( - utility::details::make_unique<fake_provider>(buffer_size)); - } - } - else - { - msg.set_compressor(cmap[algorithm]->make_compressor()); - } - } - else - { - msg.headers().add(header_names::content_encoding, algorithm); - } - - if (!real) - { - // We implement the decompression path in the server, to prove that valid, - // compressed data is sent - p_server->next_request().then([&](test_request* p_request) { - std::unique_ptr<decompress_provider> d; - std::vector<uint8_t> vv; - utility::string_t header; - size_t used; - size_t got; - bool done; - - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/")); - - if (transfer) - { - VERIFY_IS_FALSE(p_request->match_header( - header_names::content_encoding, header)); - done = p_request->match_header(header_names::transfer_encoding, - header); - VERIFY_IS_TRUE(done); - d = compression::details::get_decompressor_from_header( - header, - compression::details::header_types::transfer_encoding, - dfactories); - } - else - { - done = p_request->match_header(header_names::transfer_encoding, - header); - if (done) - { - VERIFY_IS_TRUE( - utility::details::str_iequal(_XPLATSTR("chunked"), header)); - } - done = - p_request->match_header(header_names::content_encoding, header); - VERIFY_IS_TRUE(done); - d = compression::details::get_decompressor_from_header( - header, - compression::details::header_types::content_encoding, - dfactories); - } -#if defined(_WIN32) && !defined(__cplusplus_winrt) && !defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) - VERIFY_IS_TRUE((bool)d); -#else // _WIN32 - VERIFY_ARE_NOT_EQUAL((bool)d, !!transfer); -#endif // _WIN32 - - vv.resize(buffer_size + extra_size(buffer_size)); - if (d) - { - got = d->decompress(p_request->m_body.data(), - p_request->m_body.size(), - vv.data(), - vv.size(), - operation_hint::is_last, - used, - done); - VERIFY_ARE_EQUAL(used, p_request->m_body.size()); - VERIFY_IS_TRUE(done); - } - else - { - std::copy(v.begin(), v.end(), vv.begin()); - got = v.size(); - } - VERIFY_ARE_EQUAL(buffer_size, got); - vv.resize(buffer_size); - VERIFY_ARE_EQUAL(v, vv); - processed = true; - - p_request->reply(static_cast<unsigned short>(status_codes::OK)); - }); - } - - // Send the request - http_response rsp = client.request(msg).get(); - VERIFY_ARE_EQUAL(rsp.status_code(), status_codes::OK); - rsp.content_ready().wait(); - stream.close().wait(); - VERIFY_IS_TRUE(processed); - } - } - else - { - std::vector<uint8_t> vv; - concurrency::streams::ostream stream = - concurrency::streams::rawptr_stream<uint8_t>::open_ostream(vv.data(), - buffer_size); - http_request msg(methods::GET); - - std::vector<std::shared_ptr<decompress_factory>> df = {dmap[algorithm]}; - msg.set_decompress_factories(df); - - vv.resize(buffer_size + extra_size(buffer_size)); // extra to ensure no overflow - - concurrency::streams::rawptr_buffer<uint8_t> buf( - vv.data(), vv.size(), std::ios::out); - - if (!real) - { - p_server->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - std::unique_ptr<compress_provider> c; - utility::string_t header; - std::vector<uint8_t> cmp; - size_t used; - size_t extra = 0; - size_t skip = 0; - size_t got; - bool done; - - std::string ext = ";x=y"; - std::string trailer = "a=b\r\nx=y\r\n"; - - http_asserts::assert_test_request_equals(p_request, methods::GET, U("/")); - - if (transfer) - { - // On Windows, someone along the way adds "Accept-Encoding: peerdist", - // so we can't unconditionally assert that Accept-Encoding is not - // present - done = p_request->match_header(header_names::accept_encoding, header); - VERIFY_IS_TRUE(!done || - header.find(algorithm) == utility::string_t::npos); - done = p_request->match_header(header_names::te, header); - if (done) - { - c = compression::details::get_compressor_from_header( - header, compression::details::header_types::te, cfactories); - } - - // Account for space for the chunk header and delimiters, plus a chunk - // extension and a chunked trailer part - extra = 2 * web::http::details::chunked_encoding:: - additional_encoding_space + - ext.size() + trailer.size(); - skip = web::http::details::chunked_encoding::data_offset + ext.size(); - } - else - { - VERIFY_IS_FALSE(p_request->match_header(header_names::te, header)); - done = p_request->match_header(header_names::accept_encoding, header); - VERIFY_IS_TRUE(done); - c = compression::details::get_compressor_from_header( - header, - compression::details::header_types::accept_encoding, - cfactories); - } -#if !defined __cplusplus_winrt - VERIFY_IS_TRUE((bool)c); -#else // __cplusplus_winrt - VERIFY_ARE_NOT_EQUAL((bool)c, !!transfer); -#endif // __cplusplus_winrt - cmp.resize(extra + buffer_size + extra_size(buffer_size)); - if (c) - { - got = c->compress(v.data(), - v.size(), - cmp.data() + skip, - cmp.size() - extra, - operation_hint::is_last, - used, - done); - VERIFY_ARE_EQUAL(used, v.size()); - VERIFY_IS_TRUE(done); - } - else - { - memcpy(cmp.data() + skip, v.data(), v.size()); - got = v.size(); - } - if (transfer) - { - // Add delimiters for the first (and only) data chunk, plus the final - // 0-length chunk, and hack in a dummy chunk extension and a dummy - // trailer part. Note that we put *two* "0\r\n" in here in the 0-length - // case... and none of the parsers complain. - size_t total = - got + - web::http::details::chunked_encoding::additional_encoding_space + - ext.size(); - _ASSERTE(ext.size() >= 2); - if (got > ext.size() - 1) - { - cmp[total - 2] = - cmp[got + web::http::details::chunked_encoding::data_offset]; - } - if (got > ext.size() - 2) - { - cmp[total - 1] = - cmp[got + web::http::details::chunked_encoding::data_offset + - 1]; - } - size_t offset = - web::http::details::chunked_encoding::add_chunked_delimiters( - cmp.data(), total, got); - size_t offset2 = - web::http::details::chunked_encoding::add_chunked_delimiters( - cmp.data() + total - 7, - web::http::details::chunked_encoding::additional_encoding_space, - 0); - _ASSERTE( - offset2 == 7 && - web::http::details::chunked_encoding::additional_encoding_space - - 7 == - 5); - memcpy(cmp.data() + web::http::details::chunked_encoding::data_offset - - 2, - ext.data(), - ext.size()); - cmp[web::http::details::chunked_encoding::data_offset + ext.size() - - 2] = '\r'; - cmp[web::http::details::chunked_encoding::data_offset + ext.size() - - 1] = '\n'; - if (got > ext.size() - 1) - { - cmp[got + web::http::details::chunked_encoding::data_offset] = - cmp[total - 2]; - } - if (got > ext.size() - 2) - { - cmp[got + web::http::details::chunked_encoding::data_offset + 1] = - cmp[total - 1]; - } - cmp[total - 2] = '\r'; - cmp[total - 1] = '\n'; - memcpy(cmp.data() + total + 3, trailer.data(), trailer.size()); - cmp[total + trailer.size() + 3] = '\r'; - cmp[total + trailer.size() + 4] = '\n'; - cmp.erase(cmp.begin(), cmp.begin() + offset); - cmp.resize( - ext.size() + got + trailer.size() + - web::http::details::chunked_encoding::additional_encoding_space - - offset + 5); - if (c) - { - headers[header_names::transfer_encoding] = - c->algorithm() + _XPLATSTR(", chunked"); - } - else - { - headers[header_names::transfer_encoding] = _XPLATSTR("chunked"); - } - } - else - { - cmp.resize(got); - headers[header_names::content_encoding] = c->algorithm(); - } - processed = true; - - if (cmp.size()) - { - p_request->reply(static_cast<unsigned short>(status_codes::OK), - utility::string_t(), - headers, - cmp); - } - else - { - p_request->reply(static_cast<unsigned short>(status_codes::OK), - utility::string_t(), - headers); - } - }); - } - - // Common send and response processing code - http_response rsp = client.request(msg).get(); - VERIFY_ARE_EQUAL(rsp.status_code(), status_codes::OK); - VERIFY_NO_THROWS(rsp.content_ready().wait()); - - if (transfer) - { - VERIFY_IS_TRUE(rsp.headers().has(header_names::transfer_encoding)); - VERIFY_IS_FALSE(rsp.headers().has(header_names::content_encoding)); - } - else - { - utility::string_t header; - - VERIFY_IS_TRUE(rsp.headers().has(header_names::content_encoding)); - bool boo = rsp.headers().match(header_names::transfer_encoding, header); - if (boo) - { - VERIFY_IS_TRUE(utility::details::str_iequal(_XPLATSTR("chunked"), header)); - } - } - - size_t offset = 0; - VERIFY_NO_THROWS(offset = rsp.body().read_to_end(buf).get()); - VERIFY_ARE_EQUAL(offset, buffer_size); - VERIFY_ARE_EQUAL(offset, static_cast<size_t>(buf.getpos(std::ios::out))); - vv.resize(buffer_size); - VERIFY_ARE_EQUAL(v, vv); - buf.close(std::ios_base::out).wait(); - stream.close().wait(); - } - VERIFY_IS_TRUE(processed); - } - } - } - } - } - if (real) - { - listener.close().wait(); - } - } - } -} // SUITE(request_helper_tests) -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/connection_pool_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/connection_pool_tests.cpp @@ -1,50 +0,0 @@ -#include "stdafx.h" - -#include "../../../src/http/common/connection_pool_helpers.h" -#include <memory> - -using namespace web::http::client::details; - -SUITE(connection_pooling) -{ - TEST(empty_returns_nullptr) - { - connection_pool_stack<int> connectionStack; - VERIFY_ARE_EQUAL(connectionStack.try_acquire(), std::shared_ptr<int> {}); - } - - static int noisyCount = 0; - struct noisy - { - noisy() = delete; - noisy(int) { ++noisyCount; } - noisy(const noisy&) = delete; - noisy(noisy&&) { ++noisyCount; } - noisy& operator=(const noisy&) = delete; - noisy& operator=(noisy&&) = delete; - ~noisy() { --noisyCount; } - }; - - TEST(cycled_connections_survive) - { - connection_pool_stack<noisy> connectionStack; - VERIFY_ARE_EQUAL(0, noisyCount); - connectionStack.release(std::make_shared<noisy>(42)); - connectionStack.release(std::make_shared<noisy>(42)); - connectionStack.release(std::make_shared<noisy>(42)); - VERIFY_ARE_EQUAL(3, noisyCount); - VERIFY_IS_TRUE(connectionStack.free_stale_connections()); - auto tmp = connectionStack.try_acquire(); - VERIFY_ARE_NOT_EQUAL(tmp, std::shared_ptr<noisy> {}); - connectionStack.release(std::move(tmp)); - VERIFY_ARE_EQUAL(tmp, std::shared_ptr<noisy> {}); - tmp = connectionStack.try_acquire(); - VERIFY_ARE_NOT_EQUAL(tmp, std::shared_ptr<noisy> {}); - connectionStack.release(std::move(tmp)); - VERIFY_IS_TRUE(connectionStack.free_stale_connections()); - VERIFY_ARE_EQUAL(1, noisyCount); - VERIFY_IS_FALSE(connectionStack.free_stale_connections()); - VERIFY_ARE_EQUAL(0, noisyCount); - VERIFY_IS_FALSE(connectionStack.free_stale_connections()); - } -}; diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/connections_and_errors.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/connections_and_errors.cpp @@ -1,448 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for covering issues dealing with http_client lifetime, underlying TCP connections, and general connection - *errors. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#ifndef __cplusplus_winrt -#include "cpprest/http_listener.h" -#endif - -#include <chrono> -#include <thread> - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -// Test implementation for pending_requests_after_client. -static void pending_requests_after_client_impl(const uri& address) -{ - std::vector<pplx::task<void>> completed_requests; - { - test_http_server::scoped_server scoped(address); - const method mtd = methods::GET; - - const size_t num_requests = 10; - - std::vector<pplx::task<test_request*>> requests = scoped.server()->next_requests(num_requests); - std::vector<pplx::task<http_response>> responses; - { - http_client client(address); - - // send requests. - for (size_t i = 0; i < num_requests; ++i) - { - responses.push_back(client.request(mtd)); - } - } - - // send responses. - for (size_t i = 0; i < num_requests; ++i) - { - completed_requests.push_back(requests[i].then([&](test_request* request) { - http_asserts::assert_test_request_equals(request, mtd, U("/")); - VERIFY_ARE_EQUAL(0u, request->reply(status_codes::OK)); - })); - } - - // verify responses. - for (size_t i = 0; i < num_requests; ++i) - { - try - { - http_asserts::assert_response_equals(responses[i].get(), status_codes::OK); - } - catch (...) - { - VERIFY_IS_TRUE(false); - } - } - } - for (auto&& req : completed_requests) - req.get(); -} - -SUITE(connections_and_errors) -{ - // Tests requests still outstanding after the http_client has been destroyed. - TEST_FIXTURE(uri_address, pending_requests_after_client) { pending_requests_after_client_impl(m_uri); } - - TEST_FIXTURE(uri_address, server_doesnt_exist) - { - http_client_config config; - config.set_timeout(std::chrono::seconds(1)); - http_client client(m_uri, config); - VERIFY_THROWS(client.request(methods::GET).wait(), web::http::http_exception); - } - - TEST_FIXTURE(uri_address, open_failure) - { - http_client client(U("http://localhost323:-1")); - - // This API should not throw. The exception should be surfaced - // during task.wait/get - auto t = client.request(methods::GET); - VERIFY_THROWS(t.wait(), web::http::http_exception); - } - - TEST_FIXTURE(uri_address, server_close_without_responding) - { - http_client_config config; - config.set_timeout(utility::seconds(1)); - - http_client client(m_uri, config); - test_http_server::scoped_server server(m_uri); - auto t = server.server()->next_request(); - - // Send request. - auto response = client.request(methods::PUT); - - // Wait for request - VERIFY_NO_THROWS(t.get()); - - // Close server connection. - server.server()->close(); - - VERIFY_THROWS_HTTP_ERROR_CODE(response.wait(), std::errc::connection_aborted); - - // Try sending another request. - VERIFY_THROWS(client.request(methods::GET).wait(), web::http::http_exception); - } - - TEST_FIXTURE(uri_address, request_timeout) - { - test_http_server::scoped_server scoped(m_uri); - auto t = scoped.server()->next_request(); - http_client_config config; - config.set_timeout(utility::seconds(1)); - - http_client client(m_uri, config); - auto responseTask = client.request(methods::GET); - -#ifdef __APPLE__ - // CodePlex 295 - VERIFY_THROWS(responseTask.get(), http_exception); -#else - VERIFY_THROWS_HTTP_ERROR_CODE(responseTask.get(), std::errc::timed_out); -#endif - t.get(); - } - - TEST_FIXTURE(uri_address, request_timeout_microsecond) - { - pplx::task<test_request*> t; - { - test_http_server::scoped_server scoped(m_uri); - t = scoped.server()->next_request(); - http_client_config config; - config.set_timeout(std::chrono::microseconds(900)); - - http_client client(m_uri, config); - auto responseTask = client.request(methods::GET); -#ifdef __APPLE__ - // CodePlex 295 - VERIFY_THROWS(responseTask.get(), http_exception); -#else - VERIFY_THROWS_HTTP_ERROR_CODE(responseTask.get(), std::errc::timed_out); -#endif - } - try - { - t.get(); - } - catch (...) - { - } - } - - TEST_FIXTURE(uri_address, invalid_method) - { - web::http::uri uri(U("http://www.bing.com/")); - http_client client(uri); - string_t invalid_chars = U("\a\b\f\v\n\r\t\x20\x7f"); - - for (auto iter = invalid_chars.begin(); iter < invalid_chars.end(); iter++) - { - string_t method = U("my method"); - method[2] = *iter; - VERIFY_THROWS(client.request(method).get(), http_exception); - } - } - - // This test sends an SSL request to a non-SSL server and should fail on handshaking - TEST_FIXTURE(uri_address, handshake_fail) - { - web::http::uri ssl_uri(U("https://localhost:34568/")); - - test_http_server::scoped_server scoped(m_uri); - - http_client client(ssl_uri); - auto request = client.request(methods::GET); - - VERIFY_THROWS(request.get(), http_exception); - } - -#if !defined(__cplusplus_winrt) - TEST_FIXTURE(uri_address, content_ready_timeout) - { - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - - streams::producer_consumer_buffer<uint8_t> buf; - - listener.support([buf](http_request request) { - http_response response(200); - response.set_body(streams::istream(buf), U("text/plain")); - response.headers().add(header_names::connection, U("close")); - request.reply(response); - }); - - { - http_client_config config; - config.set_timeout(utility::seconds(1)); - http_client client(m_uri, config); - http_request msg(methods::GET); - http_response rsp = client.request(msg).get(); - - // The response body should timeout and we should receive an exception - VERIFY_THROWS_HTTP_ERROR_CODE(rsp.content_ready().wait(), std::errc::timed_out); - } - - buf.close(std::ios_base::out).wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, stream_timeout) - { - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - - streams::producer_consumer_buffer<uint8_t> buf; - - listener.support([buf](http_request request) { - http_response response(200); - response.set_body(streams::istream(buf), U("text/plain")); - response.headers().add(header_names::connection, U("close")); - request.reply(response); - }); - - { - http_client_config config; - config.set_timeout(utility::seconds(1)); - http_client client(m_uri, config); - http_request msg(methods::GET); - http_response rsp = client.request(msg).get(); - - // The response body should timeout and we should receive an exception - auto readTask = rsp.body().read_to_end(streams::producer_consumer_buffer<uint8_t>()); - VERIFY_THROWS_HTTP_ERROR_CODE(readTask.wait(), std::errc::timed_out); - } - - buf.close(std::ios_base::out).wait(); - listener.close().wait(); - } -#endif - - TEST_FIXTURE(uri_address, cancel_before_request) - { - test_http_server::scoped_server scoped(m_uri); - http_client c(m_uri); - pplx::cancellation_token_source source; - source.cancel(); - - auto responseTask = c.request(methods::PUT, U("/"), source.get_token()); - VERIFY_THROWS_HTTP_ERROR_CODE(responseTask.get(), std::errc::operation_canceled); - } - -// This test can't be implemented with our test server so isn't available on WinRT. -#ifndef __cplusplus_winrt - TEST_FIXTURE(uri_address, cancel_after_headers) - { - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - http_client c(m_uri); - pplx::cancellation_token_source source; - pplx::extensibility::event_t ev; - - listener.support([&](http_request request) { - streams::producer_consumer_buffer<uint8_t> buf; - http_response response(200); - response.set_body(streams::istream(buf), U("text/plain")); - request.reply(response); - ev.wait(); - buf.putc('a').wait(); - buf.putc('b').wait(); - buf.putc('c').wait(); - buf.putc('d').wait(); - buf.close(std::ios::out).wait(); - }); - - auto responseTask = c.request(methods::GET, source.get_token()); - http_response response = responseTask.get(); - source.cancel(); - ev.set(); - - VERIFY_THROWS_HTTP_ERROR_CODE(response.extract_string().get(), std::errc::operation_canceled); - - // Codeplex 328. -#if !defined(_WIN32) - tests::common::utilities::os_utilities::sleep(1000); -#endif - - listener.close().wait(); - } -#endif - - TEST_FIXTURE(uri_address, cancel_after_body) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client c(m_uri); - pplx::cancellation_token_source source; - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain; charset=utf-8"); - std::string bodyData("Hello"); - - p_server->next_request().then( - [&](test_request* r) { VERIFY_ARE_EQUAL(0u, r->reply(status_codes::OK, U("OK"), headers, bodyData)); }); - - auto response = c.request(methods::PUT, U("/"), U("data"), source.get_token()).get(); - VERIFY_ARE_EQUAL(utility::conversions::to_string_t(bodyData), response.extract_string().get()); - source.cancel(); - response.content_ready().wait(); - } - - TEST_FIXTURE(uri_address, cancel_with_error) - { - http_client c(m_uri); - pplx::task<http_response> responseTask; - { - test_http_server::scoped_server server(m_uri); - pplx::cancellation_token_source source; - - const auto r = server.server()->next_request(); - responseTask = c.request(methods::GET, U("/"), source.get_token()); - r.wait(); - source.cancel(); - } - - // All errors after cancellation are ignored. - VERIFY_THROWS_HTTP_ERROR_CODE(responseTask.get(), std::errc::operation_canceled); - } - - TEST_FIXTURE(uri_address, cancel_while_uploading_data) - { - test_http_server::scoped_server scoped(m_uri); - http_client c(m_uri); - pplx::cancellation_token_source source; - - auto buf = streams::producer_consumer_buffer<uint8_t>(); - buf.putc('A').wait(); - auto responseTask = c.request(methods::PUT, U("/"), buf.create_istream(), 2, source.get_token()); - source.cancel(); - buf.putc('B').wait(); - buf.close(std::ios::out).wait(); - VERIFY_THROWS_HTTP_ERROR_CODE(responseTask.get(), std::errc::operation_canceled); - } - -// This test can't be implemented with our test server since it doesn't stream data so isn't avaliable on WinRT. -#ifndef __cplusplus_winrt - TEST_FIXTURE(uri_address, cancel_while_downloading_data) - { - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - http_client c(m_uri); - pplx::cancellation_token_source source; - - pplx::extensibility::event_t ev; - pplx::extensibility::event_t ev2; - - listener.support([&](http_request request) { - streams::producer_consumer_buffer<uint8_t> buf; - http_response response(200); - response.set_body(streams::istream(buf), U("text/plain")); - request.reply(response); - buf.putc('a').wait(); - buf.putc('b').wait(); - ev.set(); - ev2.wait(); - buf.putc('c').wait(); - buf.putc('d').wait(); - buf.close(std::ios::out).wait(); - }); - - auto response = c.request(methods::GET, source.get_token()).get(); - ev.wait(); - source.cancel(); - ev2.set(); - - VERIFY_THROWS_HTTP_ERROR_CODE(response.extract_string().get(), std::errc::operation_canceled); - - // Codeplex 328. -#if !defined(_WIN32) - tests::common::utilities::os_utilities::sleep(1000); -#endif - - listener.close().wait(); - } -#endif - - // Try to connect to a server on a closed port and cancel the operation. - TEST_FIXTURE(uri_address, cancel_bad_port) - { - // http_client_asio had a bug where, when canceled, it would cancel only the - // current connection but then go and try the next address from the list of - // resolved addresses, i.e., it wouldn't actually cancel as long as there - // are more addresses to try. Consequently, it would not report the task as - // being canceled. This was easiest to observe when trying to connect to a - // server that does not respond on a certain port, otherwise the timing - // might be tricky. - - // We need to connect to a URI for which there are multiple addresses - // associated (i.e., multiple A records). - web::http::uri uri(U("https://microsoft.com:442/")); - - // Send request. - http_client_config config; - config.set_timeout(std::chrono::milliseconds(1000)); - http_client c(uri, config); - web::http::http_request r; - auto cts = pplx::cancellation_token_source(); - auto ct = cts.get_token(); - auto t = c.request(r, ct); - - // Make sure that the client already finished resolving before canceling, - // otherwise the bug might not be triggered. - std::this_thread::sleep_for(std::chrono::milliseconds(400)); - cts.cancel(); - - VERIFY_THROWS_HTTP_ERROR_CODE(t.get(), std::errc::operation_canceled); - } - -} // SUITE(connections_and_errors) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/header_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/header_tests.cpp @@ -1,405 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for http_headers. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "cpprest/details/http_helpers.h" - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(outside_tests) -{ - TEST_FIXTURE(uri_address, request_headers) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - http_request msg(methods::POST); - -#ifndef __cplusplus_winrt - // The WinRT-based HTTP stack does not support headers that have no - // value, which means that there is no point in making this particular - // header test, it is an unsupported feature on WinRT. - msg.headers().add(U("HEHE"), U("")); -#endif - - msg.headers().add(U("MyHeader"), U("hehe;blach")); - msg.headers().add(U("Yo1"), U("You, Too")); - msg.headers().add(U("Yo2"), U("You2")); - msg.headers().add(U("Yo3"), U("You3")); - msg.headers().add(U("Yo4"), U("You4")); - msg.headers().add(U("Yo5"), U("You5")); - msg.headers().add(U("Yo6"), U("You6")); - msg.headers().add(U("Yo7"), U("You7")); - msg.headers().add(U("Yo8"), U("You8")); - msg.headers().add(U("Yo9"), U("You9")); - msg.headers().add(U("Yo10"), U("You10")); - msg.headers().add(U("Yo11"), U("You11")); - msg.headers().add(U("Accept"), U("text/plain")); - VERIFY_ARE_EQUAL(U("You5"), msg.headers()[U("Yo5")]); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - http_asserts::assert_test_request_contains_headers(p_request, msg.headers()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, field_name_casing) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const method mtd = methods::GET; - const utility::string_t field_name1 = U("CustomHeader"); - const utility::string_t field_name2 = U("CUSTOMHEADER"); - const utility::string_t field_name3 = U("CuSTomHEAdeR"); - const utility::string_t value1 = U("value1"); - const utility::string_t value2 = U("value2"); - const utility::string_t value3 = U("value3"); - - http_request msg(mtd); - msg.headers()[field_name1] = value1; - msg.headers()[field_name2].append(U(", ") + value2); - msg.headers()[field_name3].append(U(", ") + value3); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[field_name1] = value1 + U(", ") + value2 + U(", ") + value3; - http_asserts::assert_test_request_contains_headers(p_request, expected_headers); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, field_name_duplicate) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const method mtd = methods::GET; - const utility::string_t field_name1 = U("CUSTOMHEADER"); - const utility::string_t value1 = U("value1"); - const utility::string_t value2 = U("value2"); - - http_request msg(mtd); - msg.headers().add(field_name1, value1); - msg.headers().add(field_name1, value2); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[field_name1] = value1 + U(", ") + value2; - http_asserts::assert_test_request_contains_headers(p_request, expected_headers); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, field_name_no_multivalue_allowed) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const method mtd = methods::GET; - - http_request msg(mtd); - - msg.headers().set_content_type(web::http::details::mime_types::text_plain); - msg.headers().set_content_type(web::http::details::mime_types::application_json); - - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[U("Content-Type")] = web::http::details::mime_types::application_json; - http_asserts::assert_test_request_contains_headers(p_request, expected_headers); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - TEST_FIXTURE(uri_address, copy_move) - { - // copy constructor - http_headers h1; - h1.add(U("key1"), U("key2")); - http_headers h2(h1); - http_asserts::assert_http_headers_equals(h1, h2); - - // move constructor - http_headers h3(std::move(h1)); - VERIFY_ARE_EQUAL(1u, h3.size()); - VERIFY_ARE_EQUAL(U("key2"), h3[U("key1")]); - - // assignment operator - h1 = h3; - VERIFY_ARE_EQUAL(1u, h1.size()); - VERIFY_ARE_EQUAL(U("key2"), h1[U("key1")]); - http_asserts::assert_http_headers_equals(h1, h3); - - // move assignment operator - h1 = http_headers(); - h1 = std::move(h2); - VERIFY_ARE_EQUAL(1u, h1.size()); - VERIFY_ARE_EQUAL(U("key2"), h1[U("key1")]); - } - - TEST_FIXTURE(uri_address, match_types) - { - // wchar - http_headers h1; - h1[U("key1")] = U("string"); - utility::char_t buf[12]; - VERIFY_IS_TRUE(h1.match(U("key1"), buf)); - VERIFY_ARE_EQUAL(U("string"), utility::string_t(buf)); - - // utility::string_t - utility::string_t wstr; - VERIFY_IS_TRUE(h1.match(U("key1"), wstr)); - VERIFY_ARE_EQUAL(U("string"), wstr); - - // int - h1[U("key2")] = U("22"); - int i; - VERIFY_IS_TRUE(h1.match(U("key2"), i)); - VERIFY_ARE_EQUAL(22, i); - - // unsigned long - unsigned long l; - VERIFY_IS_TRUE(h1.match(U("key2"), l)); - VERIFY_ARE_EQUAL(22ul, l); - } - - TEST_FIXTURE(uri_address, match_edge_cases) - { - // match with empty string - http_headers h; - h[U("here")] = U(""); - utility::string_t value(U("k")); - VERIFY_IS_TRUE(h.match(U("HeRE"), value)); - VERIFY_ARE_EQUAL(U(""), value); - - // match with string containing spaces - h.add(U("blah"), U("spaces ss")); - VERIFY_IS_TRUE(h.match(U("blah"), value)); - VERIFY_ARE_EQUAL(U("spaces ss"), value); - - // match failing - value = utility::string_t(); - VERIFY_IS_FALSE(h.match(U("hahah"), value)); - VERIFY_ARE_EQUAL(U(""), value); - } - - TEST_FIXTURE(uri_address, headers_find) - { - // Find when empty. - http_headers h; - VERIFY_ARE_EQUAL(h.end(), h.find(U("key1"))); - - // Find that exists. - h[U("key1")] = U("yes"); - VERIFY_ARE_EQUAL(U("yes"), h.find(U("key1"))->second); - - // Find that doesn't exist. - VERIFY_ARE_EQUAL(h.end(), h.find(U("key2"))); - } - - TEST_FIXTURE(uri_address, headers_add) - { - // Add multiple - http_headers h; - h.add(U("key1"), 22); - h.add(U("key2"), U("str2")); - VERIFY_ARE_EQUAL(U("22"), h[U("key1")]); - VERIFY_ARE_EQUAL(U("str2"), h[U("key2")]); - - // Add one that already exists - h.add(U("key2"), U("str3")); - VERIFY_ARE_EQUAL(U("str2, str3"), h[U("key2")]); - - // Add with different case - h.add(U("KEY2"), U("str4")); - VERIFY_ARE_EQUAL(U("str2, str3, str4"), h[U("keY2")]); - - // Add with spaces in string - h.add(U("key3"), U("value with spaces")); - VERIFY_ARE_EQUAL(U("value with spaces"), h[U("key3")]); - } - - TEST_FIXTURE(uri_address, headers_iterators) - { - // begin when empty - http_headers h; - VERIFY_ARE_EQUAL(h.begin(), h.end()); - - // with some values. - h.add(U("key1"), U("value1")); - h.add(U("key2"), U("value2")); - h.add(U("key3"), U("value3")); - http_headers::const_iterator iter = h.begin(); - VERIFY_ARE_EQUAL(U("value1"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("value2"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("value3"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(h.end(), iter); - } - - TEST_FIXTURE(uri_address, headers_foreach) - { - // begin when empty - http_headers h; - VERIFY_ARE_EQUAL(h.begin(), h.end()); - - // with some values. - h.add(U("key1"), U("value")); - h.add(U("key2"), U("value")); - h.add(U("key3"), U("value")); - - std::for_each(std::begin(h), std::end(h), [=](http_headers::const_reference kv) { - VERIFY_ARE_EQUAL(U("value"), kv.second); - }); - - std::for_each( - std::begin(h), std::end(h), [=](http_headers::reference kv) { VERIFY_ARE_EQUAL(U("value"), kv.second); }); - } - - TEST_FIXTURE(uri_address, response_headers) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - std::map<utility::string_t, utility::string_t> headers; - headers[U("H1")] = U(""); - headers[U("H2")] = U("hah"); - headers[U("H3")] = U("es"); - headers[U("H4")] = U("es;kjr"); - headers[U("H5")] = U("asb"); - headers[U("H6")] = U("abc"); - headers[U("H7")] = U("eds"); - headers[U("H8")] = U("blue"); - headers[U("H9")] = U("sd"); - headers[U("H10")] = U("res"); - test_server_utilities::verify_request( - &client, methods::GET, U("/"), scoped.server(), status_codes::OK, headers); - } - - TEST_FIXTURE(uri_address, cache_control_header) - { - http_headers headers; - VERIFY_ARE_EQUAL(headers.cache_control(), U("")); - const utility::string_t value(U("custom value")); - headers.set_cache_control(value); - VERIFY_ARE_EQUAL(headers.cache_control(), value); - utility::string_t foundValue; - VERIFY_IS_TRUE(headers.match(header_names::cache_control, foundValue)); - VERIFY_ARE_EQUAL(value, foundValue); - } - - TEST_FIXTURE(uri_address, content_length_header) - { - http_headers headers; - VERIFY_ARE_EQUAL(headers.content_length(), 0); - const size_t value = 44; - headers.set_content_length(value); - VERIFY_ARE_EQUAL(headers.content_length(), value); - size_t foundValue; - VERIFY_IS_TRUE(headers.match(header_names::content_length, foundValue)); - VERIFY_ARE_EQUAL(value, foundValue); - } - - TEST_FIXTURE(uri_address, date_header) - { - http_headers headers; - VERIFY_ARE_EQUAL(headers.date(), U("")); - const utility::datetime value(utility::datetime::utc_now()); - headers.set_date(value); - VERIFY_ARE_EQUAL(headers.date(), value.to_string()); - utility::string_t foundValue; - VERIFY_IS_TRUE(headers.match(header_names::date, foundValue)); - VERIFY_ARE_EQUAL(value.to_string(), foundValue); - } - - TEST_FIXTURE(uri_address, parsing_content_type_redundantsemicolon_json) - { - test_http_server::scoped_server scoped(m_uri); - web::json::value body = web::json::value::string(U("Json body")); - - scoped.server()->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = U("application/json; charset=utf-8;;;;"); - p_request->reply(200, U("OK"), headers, utility::conversions::to_utf8string(body.serialize())); - }); - - http_client client(m_uri); - auto resp = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(resp.extract_json().get().serialize(), body.serialize()); - } - - TEST_FIXTURE(uri_address, parsing_content_type_redundantsemicolon_string) - { - test_http_server::scoped_server scoped(m_uri); - std::string body("Body"); - scoped.server()->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = U("text/plain; charset = UTF-8;;;; "); - p_request->reply(200, U("OK"), headers, body); - }); - - http_client client(m_uri); - auto resp = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(resp.extract_string().get(), utility::conversions::to_string_t(body)); - } - - TEST_FIXTURE(uri_address, overwrite_http_header) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // Test default case of cpprestsdk setting host header as host:port - auto& host = m_uri.host(); - int port = m_uri.port(); - utility::string_t expected_default_header = host + U(":") + utility::conversions::details::to_string_t(port); - http_request default_host_headers_request(methods::GET); - scoped.server()->next_request().then([&](test_request* p_request) { - auto headers = p_request->m_headers; - VERIFY_ARE_EQUAL(expected_default_header, headers[header_names::host]); - p_request->reply(200); - }); - - client.request(default_host_headers_request).get(); - -#ifndef __cplusplus_winrt - // Test case where we overwrite the host header - http_request overwritten_host_headers_request(methods::GET); - overwritten_host_headers_request.headers().add(U("Host"), host); - scoped.server()->next_request().then([&](test_request* p_request) { - auto headers = p_request->m_headers; - VERIFY_ARE_EQUAL(host, headers[header_names::host]); - p_request->reply(200); - }); - client.request(overwritten_host_headers_request).get(); -#endif - } -} // SUITE(header_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_client_fuzz_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_client_fuzz_tests.cpp @@ -1,102 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * http_client_fuzz_tests.cpp - * - * Tests cases for fuzzing http_client (headers). - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::client; -using namespace concurrency; -using namespace concurrency::streams; -using namespace utility; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(http_client_fuzz_tests) -{ - class fuzz_uri_address - { - public: - // Ensure that your traffic goes to port 8877 on the machine where NetFuzz is running - // Netfuzz sets an HTTP proxy at that location which your client must talk to - fuzz_uri_address() : m_uri(U("http://localhost:8877/")) {} - web::http::uri m_uri; - }; - - TEST_FIXTURE(fuzz_uri_address, fuzz_header_basic, "Ignore", "Manual") - { - http_client client(m_uri); - method requestMethod = methods::GET; - http_request msg(requestMethod); - - try - { - auto response = client.request(msg).get(); - printf("Response code:%d\n", response.status_code()); - auto response2 = response.content_ready().get(); - printf("Response2 code:%d\n", response2.status_code()); - } - catch (http_exception& e) - { - printf("Exception:%s\n", e.what()); - } - } - - TEST_FIXTURE(fuzz_uri_address, fuzz_request_headers, "Ignore", "Manual") - { - http_client client(m_uri); - http_request msg(methods::POST); - -#ifndef __cplusplus_winrt - // The WinRT-based HTTP stack does not support headers that have no - // value, which means that there is no point in making this particular - // header test, it is an unsupported feature on WinRT. - msg.headers().add(U("HEHE"), U("")); -#endif - - msg.headers().add(U("MyHeader"), U("hehe;blach")); - msg.headers().add(U("Yo1"), U("You, Too")); - msg.headers().add(U("Yo2"), U("You2")); - msg.headers().add(U("Yo3"), U("You3")); - msg.headers().add(U("Yo4"), U("You4")); - msg.headers().add(U("Yo5"), U("You5")); - msg.headers().add(U("Yo6"), U("You6")); - msg.headers().add(U("Yo7"), U("You7")); - msg.headers().add(U("Yo8"), U("You8")); - msg.headers().add(U("Yo9"), U("You9")); - msg.headers().add(U("Yo10"), U("You10")); - msg.headers().add(U("Yo11"), U("You11")); - msg.headers().add(U("Accept"), U("text/plain")); - VERIFY_ARE_EQUAL(U("You5"), msg.headers()[U("Yo5")]); - try - { - auto response = client.request(msg).get(); - printf("Response code:%d\n", response.status_code()); - } - catch (http_exception& e) - { - printf("Exception:%s\n", e.what()); - } - } -} // SUITE(http_client_fuzz_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_client_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_client_tests.cpp @@ -1,55 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * http_client_tests.cpp - * - * Common definitions and helper functions for http_client test cases. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -void test_connection(test_http_server* p_server, http_client* p_client, const utility::string_t& path) -{ - p_server->next_request().then([path](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::GET, path); - VERIFY_ARE_EQUAL(0u, p_request->reply(200)); - }); - http_asserts::assert_response_equals(p_client->request(methods::GET).get(), status_codes::OK); -} - -// Helper function send a simple request to test the connection. -// Take in the path to request and what path should be received in the server. -void test_connection(test_http_server* p_server, - http_client* p_client, - const utility::string_t& request_path, - const utility::string_t& expected_path) -{ - p_server->next_request().then([expected_path](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::GET, expected_path); - VERIFY_ARE_EQUAL(0u, p_request->reply(200)); - }); - http_asserts::assert_response_equals(p_client->request(methods::GET, request_path).get(), status_codes::OK); -} - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_client_tests.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_client_tests.h @@ -1,51 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * http_client_tests.h - * - * Common declarations and helper functions for http_client test cases. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/http_client.h" -#include "http_test_utilities.h" -#include "unittestpp.h" - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -class uri_address -{ -public: - uri_address() : m_uri(U("http://localhost:34568/")) {} - web::http::uri m_uri; -}; - -// Helper function to send a simple request to a server to test -// the connection. -void test_connection(tests::functional::http::utilities::test_http_server* p_server, - web::http::client::http_client* p_client, - const utility::string_t& path); - -// Helper function send a simple request to test the connection. -// Take in the path to request and what path should be received in the server. -void test_connection(tests::functional::http::utilities::test_http_server* p_server, - web::http::client::http_client* p_client, - const utility::string_t& request_path, - const utility::string_t& expected_path); - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_methods_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/http_methods_tests.cpp @@ -1,104 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for HTTP methods. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(http_methods_tests) -{ - // Tests the defined methods and custom methods. - TEST_FIXTURE(uri_address, http_methods) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // Don't include 'CONNECT' it has a special meaning. - utility::string_t send_methods[] = {methods::GET, - U("GET"), - methods::DEL, - methods::HEAD, -#ifdef _WIN32 // - this is never passed to the listener with http_listener - methods::OPTIONS, -#endif - methods::POST, - methods::PUT, - methods::PATCH, -#ifndef __cplusplus_winrt -#ifdef _WIN32 // - ditto - methods::TRCE, -#endif -#endif - - U("CUstomMETHOD")}; - utility::string_t recv_methods[] = {U("GET"), - U("GET"), - U("DELETE"), - U("HEAD"), -#ifdef _WIN32 - U("OPTIONS"), -#endif - U("POST"), - U("PUT"), - U("PATCH"), -#ifndef __cplusplus_winrt -#ifdef _WIN32 - U("TRACE"), -#endif -#endif - - U("CUstomMETHOD")}; - const size_t num_methods = sizeof(send_methods) / sizeof(send_methods[0]); - - for (int i = 0; i < num_methods; ++i) - { - p_server->next_request().then([i, &recv_methods](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, recv_methods[i], U("/")); - VERIFY_ARE_EQUAL(0u, p_request->reply(200)); - }); - http_asserts::assert_response_equals(client.request(send_methods[i]).get(), status_codes::OK); - } - } - -#ifdef __cplusplus_winrt - TEST_FIXTURE(uri_address, http_trace_fails_on_winrt) - { - http_client client(m_uri); - VERIFY_THROWS(client.request(methods::TRCE).get(), http_exception); - } -#endif - - TEST(http_request_empty_method) { VERIFY_THROWS(http_request(U("")), std::invalid_argument); } - - TEST_FIXTURE(uri_address, empty_method) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - VERIFY_THROWS(client.request(U("")), std::invalid_argument); - } -} - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/multiple_requests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/multiple_requests.cpp @@ -1,153 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for multiple requests and responses from an http_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; -using namespace utility::conversions; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -// Helper function to initialize an array of strings to contain 1 MB data. -static void initialize_data(std::string* data_arrays, const size_t count) -{ - // 10k - std::string data; - for (int j = 0; j < 1024 * 10; ++j) - { - data.push_back('A' + (j % 26)); - } - - for (size_t i = 0; i < count; ++i) - { - data_arrays[i] = data; - data_arrays[i].push_back('a' + (char)i); - } -} - -SUITE(multiple_requests) -{ - TEST_FIXTURE(uri_address, requests_with_data) - { - test_http_server::scoped_server scoped(m_uri); - http_client_config config; - http_client client(m_uri, config); - - const size_t num_requests = 20; - std::string request_body; - initialize_data(&request_body, 1); - const method method = methods::PUT; - const web::http::status_code code = status_codes::OK; - - std::vector<pplx::task<test_request*>> reqs; - // response to requests - for (size_t i = 0; i < num_requests; ++i) - { - reqs.push_back(scoped.server()->next_request()); - } - - // send requests - std::vector<pplx::task<http_response>> responses; - for (size_t i = 0; i < num_requests; ++i) - { - http_request msg(method); - msg.set_body(request_body); - responses.push_back(client.request(msg)); - } - - for (auto&& requestTask : reqs) - { - auto request = requestTask.get(); - http_asserts::assert_test_request_equals( - request, method, U("/"), U("text/plain"), to_string_t(request_body)); - VERIFY_ARE_EQUAL(0u, request->reply(code)); - } - - // wait for requests. - for (size_t i = 0; i < num_requests; ++i) - { - try - { - http_asserts::assert_response_equals(responses[i].get(), code); - } - catch (...) - { - VERIFY_ARE_EQUAL(1, 0); - } - } - } - - // Tests multiple requests with responses containing data. - TEST_FIXTURE(uri_address, responses_with_data) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - const size_t num_requests = 20; - std::string request_body; - initialize_data(&request_body, 1); - const method method = methods::PUT; - const web::http::status_code code = status_codes::OK; - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - - // response to requests - auto requestTasks = scoped.server()->next_requests(num_requests); - - // send requests - std::vector<pplx::task<http_response>> responses; - for (size_t i = 0; i < num_requests; ++i) - { - responses.push_back(client.request(method)); - } - - // response to requests - for (size_t i = 0; i < num_requests; ++i) - { - test_request* request = requestTasks[i].get(); - http_asserts::assert_test_request_equals(request, method, U("/")); - VERIFY_ARE_EQUAL(0u, request->reply(code, U(""), headers, request_body)); - } - - // wait for requests. - for (size_t i = 0; i < num_requests; ++i) - { - try - { - http_response rsp = responses[i].get(); - http_asserts::assert_response_equals(rsp, code, headers); - VERIFY_ARE_EQUAL(to_string_t(request_body), rsp.extract_string().get()); - } - catch (...) - { - VERIFY_ARE_EQUAL(1, 0); - } - } - } - -} // SUITE(multiple_requests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/oauth1_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/oauth1_tests.cpp @@ -1,324 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Test cases for oauth1. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "cpprest/details/http_helpers.h" - -using namespace web; -using namespace web::http; -using namespace web::http::client; -using namespace web::http::details; -using namespace web::http::oauth1::experimental; -using namespace web::http::oauth1::details; -using namespace utility; -using namespace concurrency; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(oauth1_tests) -{ - struct oauth1_test_config - { - oauth1_test_config() - : m_server_uri(U("http://localhost:17778/")) - , m_test_token(U("test_token"), U("test_token_secret")) - , m_oauth1_config(U("test_key"), - U("test_secret"), - m_server_uri, - m_server_uri, - m_server_uri, - m_server_uri, - oauth1_methods::hmac_sha1) - , m_oauth1_handler(std::shared_ptr<oauth1_config>(new oauth1_config(m_oauth1_config))) - { - } - - const utility::string_t m_server_uri; - const oauth1_token m_test_token; - - oauth1_config m_oauth1_config; - oauth1_handler m_oauth1_handler; - }; - - struct oauth1_token_setup : public oauth1_test_config - { - oauth1_token_setup() { m_oauth1_config.set_token(m_test_token); } - }; - - struct oauth1_server_setup : public oauth1_test_config - { - oauth1_server_setup() : m_server(m_server_uri) {} - - test_http_server::scoped_server m_server; - }; - -#define TEST_ACCESSOR(value_, name_) \ - t.set_##name_(value_); \ - VERIFY_ARE_EQUAL(value_, t.name_()); - - TEST(oauth1_token_accessors) - { - oauth1_token t(U(""), U("")); - TEST_ACCESSOR(U("a%123"), access_token) - TEST_ACCESSOR(U("b%20456"), secret) - - const auto key1 = U("abc"); - const auto value1 = U("123"); - const auto key2 = U("xyz"); - const auto value2 = U("456"); - t.set_additional_parameter(key1, value1); - t.set_additional_parameter(U("xyz"), U("456")); - const auto& parameters = t.additional_parameters(); - VERIFY_ARE_EQUAL(parameters.at(key1), value1); - VERIFY_ARE_EQUAL(parameters.at(key2), value2); - t.clear_additional_parameters(); - VERIFY_ARE_EQUAL(0, t.additional_parameters().size()); - } - - TEST(oauth1_config_accessors) - { - oauth1_config t(U(""), U(""), U(""), U(""), U(""), U(""), oauth1_methods::hmac_sha1); - TEST_ACCESSOR(U("Test123"), consumer_key) - TEST_ACCESSOR(U("bar456"), consumer_secret) - TEST_ACCESSOR(U("file:///123?123=a&1="), temp_endpoint) - TEST_ACCESSOR(U("x:yxw#0"), auth_endpoint) - TEST_ACCESSOR(U("baz:"), token_endpoint) - TEST_ACCESSOR(U("/xyzzy=2"), callback_uri) - TEST_ACCESSOR(oauth1_methods::plaintext, method) - TEST_ACCESSOR(U("wally.world x"), realm) - - const auto key1 = U("abc"); - const auto value1 = U("123"); - const auto key2 = U("xyz"); - const auto value2 = U("456"); - t.add_parameter(key1, value1); - t.add_parameter(U("xyz"), U("456")); - const auto parameters = t.parameters(); - VERIFY_ARE_EQUAL(parameters.at(key1), value1); - VERIFY_ARE_EQUAL(parameters.at(key2), value2); - t.clear_parameters(); - VERIFY_ARE_EQUAL(0, t.parameters().size()); - t.set_parameters(parameters); - const auto parameters2 = t.parameters(); - VERIFY_ARE_EQUAL(parameters2.at(key1), value1); - VERIFY_ARE_EQUAL(parameters2.at(key2), value2); - } - -#undef TEST_ACCESSOR - - // clang-format off - TEST_FIXTURE(oauth1_token_setup, oauth1_signature_base_string) - { - // Basic base string generation. - { - http_request r; - r.set_method(methods::POST); - r.set_request_uri(U("http://example.com:80/request?a=b&c=d")); // Port set to avoid default. - - auto state = m_oauth1_config._generate_auth_state(); - state.set_timestamp(U("12345678")); - state.set_nonce(U("ABCDEFGH")); - - utility::string_t base_string = m_oauth1_config._build_signature_base_string(r, state); - utility::string_t correct_base_string( - U("POST&http%3A%2F%2Fexample.com%2Frequest&a%3Db%26c%3Dd%26oauth_consumer_key%3Dtest_key%26oauth_nonce%") - U("3DABCDEFGH%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D12345678%26oauth_token%3Dtest_") - U("token%26oauth_version%3D1.0")); - VERIFY_ARE_EQUAL(correct_base_string, base_string); - } - - // Added "extra_param" and proper parameter normalization. - { - http_request r; - r.set_method(methods::POST); - r.set_request_uri(U("http://example.com:80/request?a=b&c=d")); - - auto state = m_oauth1_config._generate_auth_state(U("oauth_test"), U("xyzzy")); - state.set_timestamp(U("12345678")); - state.set_nonce(U("ABCDEFGH")); - - utility::string_t base_string = m_oauth1_config._build_signature_base_string(r, state); - utility::string_t correct_base_string( - U("POST&http%3A%2F%2Fexample.com%2Frequest&a%3Db%26c%3Dd%26oauth_consumer_key%3Dtest_key%26oauth_nonce%") - U("3DABCDEFGH%26oauth_signature_method%3DHMAC-SHA1%26oauth_test%3Dxyzzy%26oauth_timestamp%3D12345678%") - U("26oauth_token%3Dtest_token%26oauth_version%3D1.0")); - VERIFY_ARE_EQUAL(correct_base_string, base_string); - } - - // Use application/x-www-form-urlencoded with parameters in body - { - http_request r(methods::POST); - r.set_request_uri(U("http://example.com:80/request?a=b&c=d")); // Port set to avoid default. - r.set_body("MyVariableOne=ValueOne&MyVariableTwo=ValueTwo", "application/x-www-form-urlencoded"); - - auto state = m_oauth1_config._generate_auth_state(); - state.set_timestamp(U("12345678")); - state.set_nonce(U("ABCDEFGH")); - - utility::string_t base_string = m_oauth1_config._build_signature_base_string(r, state); - utility::string_t correct_base_string( - U("POST&http%3A%2F%2Fexample.com%2Frequest&a%3Db%26c%3Dd%26MyVariableOne%3DValueOne%26%26MyVariableTwo%") - U("3DValueTwo%26oauth_consumer_key%3Dtest_key%26oauth_nonce%3DABCDEFGH%26oauth_signature_method%3DHMAC-") - U("SHA1%26oauth_timestamp%3D12345678%26oauth_token%3Dtest_token%26oauth_version%3D1.0")); - } - } - - TEST_FIXTURE(oauth1_token_setup, oauth1_hmac_sha1_method) - { - http_request r; - r.set_method(methods::POST); - r.set_request_uri(U("http://example.com:80/request?a=b&c=d")); // Port set to avoid default. - - auto state = m_oauth1_config._generate_auth_state(); - state.set_timestamp(U("12345678")); - state.set_nonce(U("ABCDEFGH")); - - utility::string_t signature = m_oauth1_config._build_hmac_sha1_signature(r, state); - - utility::string_t correct_signature(U("iUq3VlP39UNXoJHXlKjgSTmjEs8=")); - VERIFY_ARE_EQUAL(correct_signature, signature); - } - - TEST_FIXTURE(oauth1_token_setup, oauth1_plaintext_method) - { - utility::string_t signature(m_oauth1_config._build_plaintext_signature()); - utility::string_t correct_signature(U("test_secret&test_token_secret")); - VERIFY_ARE_EQUAL(correct_signature, signature); - } - - TEST_FIXTURE(oauth1_server_setup, oauth1_hmac_sha1_request) - { - m_oauth1_config.set_token(m_test_token); - m_oauth1_config.set_method(oauth1_methods::hmac_sha1); - - http_client_config client_config; - client_config.set_oauth1(m_oauth1_config); - http_client client(m_server_uri, client_config); - - m_server.server()->next_request().then([](test_request* request) { - const utility::string_t header_authorization(request->m_headers[header_names::authorization]); - const utility::string_t prefix( - U("OAuth oauth_version=\"1.0\", oauth_consumer_key=\"test_key\", oauth_token=\"test_token\", ") - U("oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"")); - VERIFY_ARE_EQUAL(0, header_authorization.find(prefix)); - request->reply(status_codes::OK); - }); - - VERIFY_IS_TRUE(m_oauth1_config.token().is_valid_access_token()); - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - - TEST_FIXTURE(oauth1_server_setup, oauth1_plaintext_request) - { - m_oauth1_config.set_token(m_test_token); - m_oauth1_config.set_method(oauth1_methods::plaintext); - - http_client_config client_config; - client_config.set_oauth1(m_oauth1_config); - http_client client(m_server_uri, client_config); - - m_server.server()->next_request().then([](test_request* request) { - const utility::string_t header_authorization(request->m_headers[header_names::authorization]); - const utility::string_t prefix( - U("OAuth oauth_version=\"1.0\", oauth_consumer_key=\"test_key\", oauth_token=\"test_token\", ") - U("oauth_signature_method=\"PLAINTEXT\", oauth_timestamp=\"")); - VERIFY_ARE_EQUAL(0, header_authorization.find(prefix)); - request->reply(status_codes::OK); - }); - - VERIFY_IS_TRUE(m_oauth1_config.token().is_valid_access_token()); - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - - TEST_FIXTURE(oauth1_server_setup, oauth1_build_authorization_uri) - { - m_server.server()->next_request().then([](test_request* request) { - const utility::string_t header_authorization(request->m_headers[header_names::authorization]); - - // Verify prefix, and without 'oauth_token'. - const utility::string_t prefix(U("OAuth oauth_version=\"1.0\", oauth_consumer_key=\"test_key\", ") - U("oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"")); - VERIFY_ARE_EQUAL(0, header_authorization.find(prefix)); - - // Verify suffix with proper 'oauth_callback'. - const utility::string_t suffix(U(", oauth_callback=\"http%3A%2F%2Flocalhost%3A17778%2F\"")); - VERIFY_IS_TRUE(std::equal(suffix.rbegin(), suffix.rend(), header_authorization.rbegin())); - - // Reply with temporary token and secret. - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_x_www_form_urlencoded; - request->reply(status_codes::OK, - U(""), - headers, - "oauth_token=testbar&oauth_token_secret=xyzzy&oauth_callback_confirmed=true"); - }); - - VERIFY_IS_FALSE(m_oauth1_config.token().is_valid_access_token()); - utility::string_t auth_uri = m_oauth1_config.build_authorization_uri().get(); - VERIFY_ARE_EQUAL(auth_uri, U("http://localhost:17778/?oauth_token=testbar")); - VERIFY_IS_FALSE(m_oauth1_config.token().is_valid_access_token()); - } - - // NOTE: This test also covers token_from_verifier(). - TEST_FIXTURE(oauth1_server_setup, oauth1_token_from_redirected_uri) - { - m_server.server()->next_request().then([](test_request* request) { - const utility::string_t header_authorization(request->m_headers[header_names::authorization]); - - // Verify temporary token prefix. - const utility::string_t prefix( - U("OAuth oauth_version=\"1.0\", oauth_consumer_key=\"test_key\", oauth_token=\"xyzzy\", ") - U("oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"")); - VERIFY_ARE_EQUAL(0, header_authorization.find(prefix)); - - // Verify suffix with 'oauth_verifier'. - const utility::string_t suffix(U(", oauth_verifier=\"simsalabim\"")); - VERIFY_IS_TRUE(std::equal(suffix.rbegin(), suffix.rend(), header_authorization.rbegin())); - - // Verify we have 'oauth_nonce' and 'oauth_signature'. - VERIFY_ARE_NOT_EQUAL(utility::string_t::npos, header_authorization.find(U("oauth_nonce"))); - VERIFY_ARE_NOT_EQUAL(utility::string_t::npos, header_authorization.find(U("oauth_signature"))); - - // Reply with access token and secret. - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_x_www_form_urlencoded; - request->reply(status_codes::OK, U(""), headers, "oauth_token=test&oauth_token_secret=bar"); - }); - - m_oauth1_config.set_token(oauth1_token(U("xyzzy"), U(""))); // Simulate temporary token. - - const web::http::uri redirected_uri(U("http://localhost:17778/?oauth_token=xyzzy&oauth_verifier=simsalabim")); - m_oauth1_config.token_from_redirected_uri(redirected_uri).wait(); - - VERIFY_IS_TRUE(m_oauth1_config.token().is_valid_access_token()); - VERIFY_ARE_EQUAL(m_oauth1_config.token().access_token(), U("test")); - VERIFY_ARE_EQUAL(m_oauth1_config.token().secret(), U("bar")); - } - - // clang-format on - -} // SUITE(oauth1_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/oauth2_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/oauth2_tests.cpp @@ -1,396 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Test cases for oauth2. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "cpprest/details/http_helpers.h" - -using namespace web; -using namespace web::http; -using namespace web::http::client; -using namespace web::http::details; -using namespace web::http::oauth2::experimental; -using namespace utility; -using namespace concurrency; - -using namespace tests::functional::http::utilities; -extern utility::string_t _to_base64(const unsigned char* ptr, size_t size); - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -static std::vector<unsigned char> to_body_data(utility::string_t str) -{ - const std::string utf8(conversions::to_utf8string(std::move(str))); - return std::vector<unsigned char>(utf8.data(), utf8.data() + utf8.size()); -} - -static bool is_application_x_www_form_urlencoded(test_request* request) -{ - const auto content_type(request->m_headers[header_names::content_type]); - return (0 == content_type.find(mime_types::application_x_www_form_urlencoded)); -} - -static utility::string_t get_request_user_agent(test_request* request) -{ - if (request->m_headers.find(header_names::user_agent) != request->m_headers.end()) - { - return request->m_headers[header_names::user_agent]; - } - - return utility::string_t(); -} - -SUITE(oauth2_tests) -{ - struct oauth2_test_setup - { - oauth2_test_setup() - : m_uri(U("http://localhost:16743/")) - , m_oauth2_config(U("123ABC"), U("456DEF"), U("https://test1"), m_uri.to_string(), U("https://bar")) - , m_scoped(m_uri) - { - } - - web::http::uri m_uri; - oauth2_config m_oauth2_config; - test_http_server::scoped_server m_scoped; - }; - -#define TEST_ACCESSOR(value_, name_) \ - t.set_##name_(value_); \ - VERIFY_ARE_EQUAL(value_, t.name_()); - - TEST(oauth2_token_accessors) - { - oauth2_token t; - TEST_ACCESSOR(U("b%20456"), access_token) - TEST_ACCESSOR(U("a%123"), refresh_token) - TEST_ACCESSOR(U("b%20456"), token_type) - TEST_ACCESSOR(U("ad.ww xyz"), scope) - TEST_ACCESSOR(0, expires_in) - TEST_ACCESSOR(123, expires_in) - } - - TEST(oauth2_config_accessors) - { - oauth2_config t(U(""), U(""), U(""), U(""), U("")); - TEST_ACCESSOR(U("ABC123abc"), client_key) - TEST_ACCESSOR(U("123abcABC"), client_secret) - TEST_ACCESSOR(U("x:/t/a?q=c&a#3"), auth_endpoint) - TEST_ACCESSOR(U("y:///?a=21#1=2"), token_endpoint) - TEST_ACCESSOR(U("z://?=#"), redirect_uri) - TEST_ACCESSOR(U("xyzw=stuv"), scope) - TEST_ACCESSOR(U("1234567890"), state) - TEST_ACCESSOR(U("keyx"), access_token_key) - TEST_ACCESSOR(true, implicit_grant) - TEST_ACCESSOR(false, implicit_grant) - TEST_ACCESSOR(true, bearer_auth) - TEST_ACCESSOR(false, bearer_auth) - TEST_ACCESSOR(true, http_basic_auth) - TEST_ACCESSOR(false, http_basic_auth) - } - -#undef TEST_ACCESSOR - - TEST(oauth2_build_authorization_uri) - { - oauth2_config config(U(""), U(""), U(""), U(""), U("")); - config.set_state(U("xyzzy")); - config.set_implicit_grant(false); - - // Empty authorization URI. - { - VERIFY_ARE_EQUAL(U("/?response_type=code&client_id=&redirect_uri=&state=xyzzy"), - config.build_authorization_uri(false)); - } - - // Authorization URI with scope parameter. - { - config.set_scope(U("testing_123")); - VERIFY_ARE_EQUAL(U("/?response_type=code&client_id=&redirect_uri=&state=xyzzy&scope=testing_123"), - config.build_authorization_uri(false)); - } - - // Full authorization URI with scope. - { - config.set_client_key(U("4567abcd")); - config.set_auth_endpoint(U("https://test1")); - config.set_redirect_uri(U("http://localhost:8080")); - VERIFY_ARE_EQUAL(U("https://test1/?response_type=code&client_id=4567abcd&redirect_uri=http://") - U("localhost:8080&state=xyzzy&scope=testing_123"), - config.build_authorization_uri(false)); - } - - // Verify again with implicit grant. - { - config.set_implicit_grant(true); - VERIFY_ARE_EQUAL(U("https://test1/?response_type=token&client_id=4567abcd&redirect_uri=http://") - U("localhost:8080&state=xyzzy&scope=testing_123"), - config.build_authorization_uri(false)); - } - - // Verify that a new state() will be generated. - { - const uri auth_uri(config.build_authorization_uri(true)); - auto params = uri::split_query(auth_uri.query()); - VERIFY_ARE_NOT_EQUAL(params[U("state")], U("xyzzy")); - } - } - - TEST_FIXTURE(oauth2_test_setup, oauth2_token_from_code) - { - VERIFY_IS_FALSE(m_oauth2_config.is_enabled()); - - m_oauth2_config.set_user_agent(U("test_user_agent")); - - // Fetch using HTTP Basic authentication. - { - m_scoped.server()->next_request().then([](test_request* request) { - VERIFY_ARE_EQUAL(request->m_method, methods::POST); - - VERIFY_IS_TRUE(is_application_x_www_form_urlencoded(request)); - - VERIFY_ARE_EQUAL(U("Basic MTIzQUJDOjQ1NkRFRg=="), request->m_headers[header_names::authorization]); - - VERIFY_ARE_EQUAL( - to_body_data(U("grant_type=authorization_code&code=789GHI&redirect_uri=https%3A%2F%2Fbar")), - request->m_body); - - VERIFY_ARE_EQUAL(U("test_user_agent"), get_request_user_agent(request)); - - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_json; - request->reply( - status_codes::OK, U(""), headers, "{\"access_token\":\"xyzzy123\",\"token_type\":\"bearer\"}"); - }); - - m_oauth2_config.token_from_code(U("789GHI")).wait(); - VERIFY_ARE_EQUAL(U("xyzzy123"), m_oauth2_config.token().access_token()); - VERIFY_IS_TRUE(m_oauth2_config.is_enabled()); - } - - // Fetch using client key & secret in request body (x-www-form-urlencoded). - { - m_scoped.server()->next_request().then([](test_request* request) { - VERIFY_IS_TRUE(is_application_x_www_form_urlencoded(request)); - - VERIFY_ARE_EQUAL(U(""), request->m_headers[header_names::authorization]); - - VERIFY_ARE_EQUAL(to_body_data(U("grant_type=authorization_code&code=789GHI&redirect_uri=https%3A%2F%") - U("2Fbar&client_id=123ABC&client_secret=456DEF")), - request->m_body); - - VERIFY_ARE_EQUAL(U("test_user_agent"), get_request_user_agent(request)); - - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_json; - request->reply( - status_codes::OK, U(""), headers, "{\"access_token\":\"xyzzy123\",\"token_type\":\"bearer\"}"); - }); - - m_oauth2_config.set_token(oauth2_token()); // Clear token. - VERIFY_IS_FALSE(m_oauth2_config.is_enabled()); - - m_oauth2_config.set_http_basic_auth(false); - m_oauth2_config.token_from_code(U("789GHI")).wait(); - - VERIFY_ARE_EQUAL(U("xyzzy123"), m_oauth2_config.token().access_token()); - VERIFY_IS_TRUE(m_oauth2_config.is_enabled()); - } - } - - TEST_FIXTURE(oauth2_test_setup, oauth2_token_from_redirected_uri) - { - // Authorization code grant. - { - m_scoped.server()->next_request().then([](test_request* request) { - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_json; - request->reply( - status_codes::OK, U(""), headers, "{\"access_token\":\"test1\",\"token_type\":\"bearer\"}"); - }); - - m_oauth2_config.set_implicit_grant(false); - m_oauth2_config.set_state(U("xyzzy")); - - const web::http::uri redirected_uri(m_uri.to_string() + U("?code=sesame&state=xyzzy")); - m_oauth2_config.token_from_redirected_uri(redirected_uri).wait(); - - VERIFY_IS_TRUE(m_oauth2_config.token().is_valid_access_token()); - VERIFY_ARE_EQUAL(m_oauth2_config.token().access_token(), U("test1")); - } - - // Implicit grant. - { - m_oauth2_config.set_implicit_grant(true); - const web::http::uri redirected_uri(m_uri.to_string() + U("#access_token=abcd1234&state=xyzzy")); - m_oauth2_config.token_from_redirected_uri(redirected_uri).wait(); - - VERIFY_IS_TRUE(m_oauth2_config.token().is_valid_access_token()); - VERIFY_ARE_EQUAL(m_oauth2_config.token().access_token(), U("abcd1234")); - } - } - - TEST_FIXTURE(oauth2_test_setup, oauth2_token_from_refresh) - { - oauth2_token token(U("accessing")); - token.set_refresh_token(U("refreshing")); - m_oauth2_config.set_token(token); - VERIFY_IS_TRUE(m_oauth2_config.is_enabled()); - - // Verify token refresh without scope. - m_scoped.server()->next_request().then([](test_request* request) { - VERIFY_ARE_EQUAL(request->m_method, methods::POST); - - VERIFY_IS_TRUE(is_application_x_www_form_urlencoded(request)); - - VERIFY_ARE_EQUAL(U("Basic MTIzQUJDOjQ1NkRFRg=="), request->m_headers[header_names::authorization]); - - VERIFY_ARE_EQUAL(to_body_data(U("grant_type=refresh_token&refresh_token=refreshing")), request->m_body); - - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_json; - request->reply(status_codes::OK, - U(""), - headers, - "{\"access_token\":\"ABBA\",\"refresh_token\":\"BAZ\",\"token_type\":\"bearer\"}"); - }); - - m_oauth2_config.token_from_refresh().wait(); - VERIFY_ARE_EQUAL(U("ABBA"), m_oauth2_config.token().access_token()); - VERIFY_ARE_EQUAL(U("BAZ"), m_oauth2_config.token().refresh_token()); - - // Verify chaining refresh tokens and refresh with scope. - m_scoped.server()->next_request().then([](test_request* request) { - VERIFY_IS_TRUE(is_application_x_www_form_urlencoded(request)); - - VERIFY_ARE_EQUAL(to_body_data(U("grant_type=refresh_token&refresh_token=BAZ&scope=xyzzy")), - request->m_body); - - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_json; - request->reply(status_codes::OK, U(""), headers, "{\"access_token\":\"done\",\"token_type\":\"bearer\"}"); - }); - - m_oauth2_config.set_scope(U("xyzzy")); - m_oauth2_config.token_from_refresh().wait(); - VERIFY_ARE_EQUAL(U("done"), m_oauth2_config.token().access_token()); - } - - TEST_FIXTURE(oauth2_test_setup, oauth2_bearer_token) - { - m_oauth2_config.set_token(oauth2_token(U("12345678"))); - http_client_config config; - - // Default, bearer token in "Authorization" header (bearer_auth() == true) - { - config.set_oauth2(m_oauth2_config); - - http_client client(m_uri, config); - m_scoped.server()->next_request().then([](test_request* request) { - VERIFY_ARE_EQUAL(U("Bearer 12345678"), request->m_headers[header_names::authorization]); - VERIFY_ARE_EQUAL(U("/"), request->m_path); - request->reply(status_codes::OK); - }); - - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - - // Bearer token in query, default access token key (bearer_auth() == false) - { - m_oauth2_config.set_bearer_auth(false); - config.set_oauth2(m_oauth2_config); - - http_client client(m_uri, config); - m_scoped.server()->next_request().then([](test_request* request) { - VERIFY_ARE_EQUAL(U(""), request->m_headers[header_names::authorization]); - VERIFY_ARE_EQUAL(U("/?access_token=12345678"), request->m_path); - request->reply(status_codes::OK); - }); - - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - - // Bearer token in query, updated token, custom access token key (bearer_auth() == false) - { - m_oauth2_config.set_bearer_auth(false); - m_oauth2_config.set_access_token_key(U("open")); - m_oauth2_config.set_token(oauth2_token(U("Sesame"))); - config.set_oauth2(m_oauth2_config); - - http_client client(m_uri, config); - m_scoped.server()->next_request().then([](test_request* request) { - VERIFY_ARE_EQUAL(U(""), request->m_headers[header_names::authorization]); - VERIFY_ARE_EQUAL(U("/?open=Sesame"), request->m_path); - request->reply(status_codes::OK); - }); - - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - } - - TEST_FIXTURE(oauth2_test_setup, oauth2_token_parsing) - { - VERIFY_IS_FALSE(m_oauth2_config.is_enabled()); - - // Verify reply JSON 'access_token', 'refresh_token', 'expires_in' and 'scope'. - { - m_scoped.server()->next_request().then([](test_request* request) { - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_json; - request->reply(status_codes::OK, - U(""), - headers, - "{\"access_token\":\"123\",\"refresh_token\":\"ABC\",\"token_type\":\"bearer\"," - "\"expires_in\":12345678,\"scope\":\"baz\"}"); - }); - - m_oauth2_config.token_from_code(U("")).wait(); - VERIFY_ARE_EQUAL(U("123"), m_oauth2_config.token().access_token()); - VERIFY_ARE_EQUAL(U("ABC"), m_oauth2_config.token().refresh_token()); - VERIFY_ARE_EQUAL(12345678, m_oauth2_config.token().expires_in()); - VERIFY_ARE_EQUAL(U("baz"), m_oauth2_config.token().scope()); - VERIFY_IS_TRUE(m_oauth2_config.is_enabled()); - } - - // Verify undefined 'expires_in' and 'scope'. - { - m_scoped.server()->next_request().then([](test_request* request) { - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = mime_types::application_json; - request->reply( - status_codes::OK, U(""), headers, "{\"access_token\":\"123\",\"token_type\":\"bearer\"}"); - }); - - const utility::string_t test_scope(U("wally world")); - m_oauth2_config.set_scope(test_scope); - - m_oauth2_config.token_from_code(U("")).wait(); - VERIFY_ARE_EQUAL(oauth2_token::undefined_expiration, m_oauth2_config.token().expires_in()); - VERIFY_ARE_EQUAL(test_scope, m_oauth2_config.token().scope()); - } - } - -} // SUITE(oauth2_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/outside_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/outside_tests.cpp @@ -1,293 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for using http_clients to outside websites. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" -#if defined(_MSC_VER) && !defined(__cplusplus_winrt) -#define WIN32_LEAN_AND_MEAN -#include <Windows.h> - -#include <winhttp.h> -#pragma comment(lib, "winhttp") -#endif -#include "cpprest/details/http_helpers.h" -#include "cpprest/rawptrstream.h" -#include "os_utilities.h" -#include <stdexcept> - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(outside_tests) -{ - TEST_FIXTURE(uri_address, outside_cnn_dot_com) - { - handle_timeout([] { - // http://www.cnn.com redirects users from countries outside of the US to the "http://edition.cnn.com/" drop - // location - http_client client(U("http://edition.cnn.com")); - - // CNN's main page doesn't use chunked transfer encoding. - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - - // CNN's other pages do use chunked transfer encoding. - response = client.request(methods::GET, U("us")).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - }); - } - - TEST_FIXTURE(uri_address, outside_wikipedia_compressed_http_response) - { - if (web::http::compression::builtin::supported() == false) - { - // On platforms which do not support compressed http, nothing to check. - return; - } - http_client_config config; - config.set_request_compressed_response(true); - - http_client client(U("https://en.wikipedia.org/wiki/HTTP_compression"), config); - http_request httpRequest(methods::GET); - - http_response response = client.request(httpRequest).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - - auto s = response.extract_utf8string().get(); - VERIFY_IS_FALSE(s.empty()); - - utility::string_t encoding; - VERIFY_IS_TRUE(response.headers().match(web::http::header_names::content_encoding, encoding)); - - VERIFY_ARE_EQUAL(encoding, U("gzip")); - } - - TEST_FIXTURE(uri_address, outside_google_dot_com) - { - // Use code.google.com instead of www.google.com, which redirects - http_client client(U("http://code.google.com")); - http_request request(methods::GET); - for (int i = 0; i < 2; ++i) - { - http_response response = client.request(request).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } - } - - TEST_FIXTURE(uri_address, multiple_https_requests) - { - handle_timeout([&] { - // Use code.google.com instead of www.google.com, which redirects - http_client client(U("https://code.google.com")); - - http_response response; - for (int i = 0; i < 5; ++i) - { - response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - } - }); - } - -#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) && !CPPREST_FORCE_PPLX - TEST_FIXTURE(uri_address, multiple_https_requests_sync_scheduler) - { - struct sync_scheduler : public scheduler_interface - { - public: - virtual void schedule(TaskProc_t function, PVOID context) override { function(context); } - }; - - // Save the current ambient scheduler - const auto scheduler = get_cpprestsdk_ambient_scheduler(); - - // Change the ambient scheduler to one that schedules synchronously - static std::shared_ptr<scheduler_interface> syncScheduler = std::make_shared<sync_scheduler>(); - set_cpprestsdk_ambient_scheduler(syncScheduler); - - handle_timeout([&] { - // Use code.google.com instead of www.google.com, which redirects - http_client client(U("https://code.google.com")); - - http_response response; - for (int i = 0; i < 5; ++i) - { - response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - } - }); - - // Revert to the original scheduler - set_cpprestsdk_ambient_scheduler(scheduler); - } -#endif - - TEST_FIXTURE(uri_address, reading_google_stream) - { - handle_timeout([&] { - // Use code.google.com instead of www.google.com, which redirects - http_client simpleclient(U("http://code.google.com")); - utility::string_t path = m_uri.query(); - http_response response = simpleclient.request(::http::methods::GET).get(); - - uint8_t chars[71]; - memset(chars, 0, sizeof(chars)); - - streams::rawptr_buffer<uint8_t> temp(chars, sizeof(chars)); - - VERIFY_ARE_EQUAL(response.body().read(temp, 70).get(), 70); - // Uncomment the following line to output the chars. - // std::cout << chars << '\n'; - VERIFY_ARE_EQUAL(strcmp((const char*)chars, - "<html>\n <head>\n <meta name=\"google-site-verification\" content=\"4zc"), - 0); - }); - } - - TEST_FIXTURE(uri_address, no_transfer_encoding_content_length) - { - handle_timeout([] { - http_client client(U("http://ws.audioscrobbler.com/2.0/") U( - "?method=artist.gettoptracks&artist=cher&api_key=6fcd59047568e89b1615975081258990&format=json")); - - client.request(methods::GET) - .then([](http_response response) { - VERIFY_ARE_EQUAL(response.status_code(), status_codes::OK); - VERIFY_IS_FALSE(response.headers().has(header_names::content_length) && - response.headers().has(header_names::transfer_encoding)); - return response.extract_string(); - }) - .then([](string_t result) { - // Verify that the body size isn't empty. - VERIFY_IS_TRUE(result.size() > 0); - }) - .wait(); - }); - } - - // Note additional sites for testing can be found at: - // https://badssl.com/ - // https://www.ssllabs.com/ssltest/ - // http://www.internetsociety.org/deploy360/resources/dane-test-sites/ - // https://onlinessl.netlock.hu/# - static void test_failed_ssl_cert(const uri& base_uri) - { - handle_timeout([&base_uri] { - http_client client(base_uri); - auto requestTask = client.request(methods::GET); - VERIFY_THROWS(requestTask.get(), http_exception); - }); - } - -#if !defined(__cplusplus_winrt) - static void test_ignored_ssl_cert(const uri& base_uri) - { - handle_timeout([&base_uri] { - http_client_config config; - config.set_validate_certificates(false); - http_client client(base_uri, config); - auto response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - }); - } -#endif // !defined(__cplusplus_winrt) - - TEST(server_selfsigned_cert) { test_failed_ssl_cert(U("https://self-signed.badssl.com/")); } - -#if !defined(__cplusplus_winrt) - TEST(server_selfsigned_cert_ignored) { test_ignored_ssl_cert(U("https://self-signed.badssl.com/")); } -#endif // !defined(__cplusplus_winrt) - - TEST(server_hostname_mismatch) { test_failed_ssl_cert(U("https://wrong.host.badssl.com/")); } - -#if !defined(__cplusplus_winrt) && !defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL) - TEST(server_hostname_host_override) - { - handle_timeout([] { - http_client client(U("https://wrong.host.badssl.com/")); - http_request req(methods::GET); - req.headers().add(U("Host"), U("badssl.com")); - auto response = client.request(req).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - }); - } - - TEST(server_hostname_mismatch_ignored) { test_ignored_ssl_cert(U("https://wrong.host.badssl.com/")); } - - TEST(server_hostname_host_override_after_upgrade) - { - http_client client(U("http://198.35.26.96/")); - http_request req(methods::GET); - req.headers().add(U("Host"), U("en.wikipedia.org")); - auto response = client.request(req).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - } -#endif // !defined(__cplusplus_winrt) && !defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL) - - TEST(server_cert_expired) { test_failed_ssl_cert(U("https://expired.badssl.com/")); } - -#if !defined(__cplusplus_winrt) - TEST(server_cert_expired_ignored) { test_ignored_ssl_cert(U("https://expired.badssl.com/")); } -#endif // !defined(__cplusplus_winrt) - - TEST(server_cert_revoked, "Ignore:Android", "229", "Ignore:Apple", "229", "Ignore:Linux", "229") - { - test_failed_ssl_cert(U("https://revoked.badssl.com/")); - } - -#if !defined(__cplusplus_winrt) - TEST(server_cert_revoked_ignored) { test_ignored_ssl_cert(U("https://revoked.badssl.com/")); } -#endif // !defined(__cplusplus_winrt) - - TEST(server_cert_untrusted) { test_failed_ssl_cert(U("https://untrusted-root.badssl.com/")); } - -#if !defined(__cplusplus_winrt) - TEST(server_cert_untrusted_ignored) { test_ignored_ssl_cert(U("https://untrusted-root.badssl.com/")); } -#endif // !defined(__cplusplus_winrt) - -#if !defined(__cplusplus_winrt) - TEST(ignore_server_cert_invalid, "Ignore:Android", "229", "Ignore:Apple", "229", "Ignore:Linux", "229") - { - handle_timeout([] { - http_client_config config; - config.set_validate_certificates(false); - config.set_timeout(std::chrono::seconds(1)); - http_client client(U("https://expired.badssl.com/"), config); - - auto request = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, request.status_code()); - }); - } -#endif // !defined(__cplusplus_winrt) -} // SUITE(outside_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/pipeline_stage_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/pipeline_stage_tests.cpp @@ -1,260 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * pipeline_stage_tests.cpp - * - * Tests cases using pipeline stages on an http_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(pipeline_stage_tests) -{ - TEST_FIXTURE(uri_address, http_counting_methods) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - - size_t count = 0; - - auto response_counter = [&count](pplx::task<http_response> r_task) -> pplx::task<http_response> { - ++count; - return r_task; - }; - auto request_counter = - [&count, response_counter](http_request request, - std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response> { - ++count; - return next_stage->propagate(request).then(response_counter); - }; - - http_client client(m_uri); - client.add_handler(request_counter); - - // Don't include 'CONNECT' it has a special meaning. - utility::string_t send_methods[] = {methods::GET, - U("GET"), - methods::DEL, - methods::HEAD, -#ifdef _WIN32 // this is never passed to the listener - methods::OPTIONS, -#endif - methods::POST, - methods::PUT, - methods::PATCH, - U("CUstomMETHOD")}; - utility::string_t recv_methods[] = {U("GET"), - U("GET"), - U("DELETE"), - U("HEAD"), -#ifdef _WIN32 - U("OPTIONS"), -#endif - U("POST"), - U("PUT"), - U("PATCH"), - U("CUstomMETHOD")}; - const size_t num_methods = sizeof(send_methods) / sizeof(send_methods[0]); - - for (int i = 0; i < num_methods; ++i) - { - p_server->next_request().then([i, &recv_methods](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, recv_methods[i], U("/")); - VERIFY_ARE_EQUAL(0u, p_request->reply(200)); - }); - http_asserts::assert_response_equals(client.request(send_methods[i]).get(), status_codes::OK); - } - - VERIFY_ARE_EQUAL(num_methods * 2, count); - } - - TEST_FIXTURE(uri_address, http_short_circuit) - { - size_t count = 0; - - auto request_counter = [&count](http_request request, - std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response> { - ++count; - request.reply(status_codes::Forbidden); - return request.get_response(); - }; - - http_client client(m_uri); - client.add_handler(request_counter); - - // Don't include 'CONNECT' it has a special meaning. - utility::string_t send_methods[] = {methods::GET, - U("GET"), - methods::DEL, - methods::HEAD, - methods::OPTIONS, - methods::POST, - methods::PUT, - methods::PATCH, - U("CUstomMETHOD")}; - const size_t num_methods = sizeof(send_methods) / sizeof(send_methods[0]); - - for (int i = 0; i < num_methods; ++i) - { - http_asserts::assert_response_equals(client.request(send_methods[i]).get(), status_codes::Forbidden); - } - - VERIFY_ARE_EQUAL(num_methods, count); - } - - TEST_FIXTURE(uri_address, http_short_circuit_multiple) - { - size_t count = 0; - - auto reply_stage = [](http_request request, - std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response> { - request.reply(status_codes::Forbidden); - return request.get_response(); - }; - - auto count_stage = [&count](http_request request, - std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response> { - count++; - return next_stage->propagate(request); - }; - - http_client client(m_uri); - client.add_handler(count_stage); - client.add_handler(count_stage); - client.add_handler(reply_stage); - - // Don't include 'CONNECT' it has a special meaning. - utility::string_t send_methods[] = {methods::GET, - U("GET"), - methods::DEL, - methods::HEAD, - methods::OPTIONS, - methods::POST, - methods::PUT, - methods::PATCH, - U("CUstomMETHOD")}; - const size_t num_methods = sizeof(send_methods) / sizeof(send_methods[0]); - - for (int i = 0; i < num_methods; ++i) - { - http_asserts::assert_response_equals(client.request(send_methods[i]).get(), status_codes::Forbidden); - } - - VERIFY_ARE_EQUAL(num_methods * 2, count); - } - - TEST_FIXTURE(uri_address, http_short_circuit_no_count) - { - size_t count = 0; - - auto reply_stage = [](http_request request, - std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response> { - request.reply(status_codes::Forbidden); - return request.get_response(); - }; - - auto count_stage = [&count](http_request request, - std::shared_ptr<http_pipeline_stage> next_stage) -> pplx::task<http_response> { - count++; - return next_stage->propagate(request); - }; - - // The counting is prevented from happening, because the short-circuit come before the count. - http_client client(m_uri); - client.add_handler(reply_stage); - client.add_handler(count_stage); - - // Don't include 'CONNECT' it has a special meaning. - utility::string_t send_methods[] = {methods::GET, - U("GET"), - methods::DEL, - methods::HEAD, - methods::OPTIONS, - methods::POST, - methods::PUT, - methods::PATCH, - U("CUstomMETHOD")}; - const size_t num_methods = sizeof(send_methods) / sizeof(send_methods[0]); - - for (int i = 0; i < num_methods; ++i) - { - http_asserts::assert_response_equals(client.request(send_methods[i]).get(), status_codes::Forbidden); - } - - VERIFY_ARE_EQUAL(0u, count); - } - - /// <summary> - /// Pipeline stage used for pipeline_stage_inspect_response. - /// </summary> - class modify_count_responses_stage : public http_pipeline_stage - { - public: - modify_count_responses_stage() : m_Count(0) {} - - virtual pplx::task<http_response> propagate(http_request request) - { - request.headers().set_content_type(U("modified content type")); - - auto currentStage = this->shared_from_this(); - return next_stage()->propagate(request).then([currentStage](http_response response) -> http_response { - int prevCount = 0; - response.headers().match(U("My Header"), prevCount); - utility::stringstream_t data; - data << prevCount + ++std::dynamic_pointer_cast<modify_count_responses_stage>(currentStage)->m_Count; - response.headers().add(U("My Header"), data.str()); - return response; - }); - } - - private: - int m_Count; - }; - - TEST_FIXTURE(uri_address, pipeline_stage_inspect_response) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - scoped.server()->next_request().then([](test_request* request) { - http_asserts::assert_test_request_equals(request, methods::GET, U("/"), U("modified content type")); - request->reply(status_codes::OK); - }); - - // Put in nested scope so we lose the reference on the shared pointer. - { - std::shared_ptr<http_pipeline_stage> countStage = std::make_shared<modify_count_responses_stage>(); - client.add_handler(countStage); - std::shared_ptr<http_pipeline_stage> countStage2 = std::make_shared<modify_count_responses_stage>(); - client.add_handler(countStage2); - } - - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - VERIFY_ARE_EQUAL(U("1, 2"), response.headers()[U("My Header")]); - } - -} // SUITE(pipeline_stage_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/progress_handler_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/progress_handler_tests.cpp @@ -1,402 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases manually building up HTTP requests with progress handlers. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#ifdef _WIN32 -#include <WinError.h> -#endif - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(progress_handler_tests) -{ - TEST_FIXTURE(uri_address, set_progress_handler_no_bodies) - { - http_client_config config; - config.set_chunksize(512); - - http_client client(m_uri, config); - const method mtd = methods::GET; - utility::size64_t upsize = 4711u, downsize = 4711u; - int calls = 0; - - http_request msg(mtd); - msg.set_progress_handler([&](message_direction::direction direction, utility::size64_t so_far) { - calls += 1; - if (direction == message_direction::upload) - upsize = so_far; - else - downsize = so_far; - }); - - test_http_server::scoped_server scoped(m_uri); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - std::map<utility::string_t, utility::string_t> headers; - p_request->reply(200, utility::string_t(U("OK")), headers); - }); - - auto response = client.request(msg).get(); - http_asserts::assert_response_equals(response, status_codes::OK); - - VERIFY_ARE_EQUAL(0, upsize); - - response.content_ready().wait(); - - VERIFY_ARE_EQUAL(0, downsize); - VERIFY_ARE_EQUAL(2, calls); - } - - TEST_FIXTURE(uri_address, set_progress_handler_upload) - { - http_client_config config; - config.set_chunksize(512); - - http_client client(m_uri, config); - const method mtd = methods::POST; - utility::string_t data; - utility::string_t content_type = U("text/plain; charset=utf-8"); - - const size_t repeats = 5500; - for (size_t i = 0; i < repeats; ++i) - data.append(U("abcdefghihklmnopqrstuvwxyz")); - - utility::size64_t upsize = 4711u, downsize = 4711u; - int calls = 0; - - http_request msg(mtd); - msg.set_progress_handler([&](message_direction::direction direction, utility::size64_t so_far) { - calls += 1; - if (direction == message_direction::upload) - upsize = so_far; - else - downsize = so_far; - }); - - msg.set_body(data); - - test_http_server::scoped_server scoped(m_uri); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/"), content_type, data); - std::map<utility::string_t, utility::string_t> headers; - p_request->reply(200, utility::string_t(U("OK")), headers); - }); - - auto response = client.request(msg).get(); - http_asserts::assert_response_equals(response, status_codes::OK); - - VERIFY_ARE_EQUAL(26u * repeats, upsize); - - response.content_ready().wait(); - - VERIFY_ARE_EQUAL(0, downsize); - // We don't have very precise control over how much of a message is transferred - // in each chunk being sent or received, so we can't make an exact comparison here. - VERIFY_IS_TRUE(calls >= 3); - } - - TEST_FIXTURE(uri_address, set_progress_handler_download) - { - http_client_config config; - config.set_chunksize(512); - - http_client client(m_uri, config); - const method mtd = methods::GET; - - utility::size64_t upsize = 4711u, downsize = 4711u; - int calls = 0; - - http_request msg(mtd); - msg.set_progress_handler([&](message_direction::direction direction, utility::size64_t so_far) { - calls += 1; - if (direction == message_direction::upload) - upsize = so_far; - else - downsize = so_far; - }); - - const size_t repeats = 6000; - - test_http_server::scoped_server scoped(m_uri); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/")); - std::string resp_data; - for (size_t i = 0; i < repeats; ++i) - resp_data.append("abcdefghihklmnopqrstuvwxyz"); - - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - p_request->reply(200, utility::string_t(U("OK")), headers, resp_data); - }); - - auto response = client.request(msg).get(); - http_asserts::assert_response_equals(response, status_codes::OK); - - VERIFY_ARE_EQUAL(0, upsize); - - response.content_ready().wait(); - - VERIFY_ARE_EQUAL(26u * repeats, downsize); - // We don't have very precise control over how much of a message is transferred - // in each chunk being sent or received, so we can't make an exact comparison here. - VERIFY_IS_TRUE(calls > 4); - } - - TEST_FIXTURE(uri_address, set_progress_handler_upload_and_download) - { - http_client_config config; - config.set_chunksize(512); - - http_client client(m_uri, config); - const method mtd = methods::POST; - utility::string_t data; - utility::string_t content_type = U("text/plain; charset=utf-8"); - - const size_t repeats = 5500; - for (size_t i = 0; i < repeats; ++i) - data.append(U("abcdefghihklmnopqrstuvwxyz")); - - utility::size64_t upsize = 4711u, downsize = 4711u; - int calls = 0; - - http_request msg(mtd); - msg.set_progress_handler([&](message_direction::direction direction, utility::size64_t so_far) { - calls += 1; - if (direction == message_direction::upload) - upsize = so_far; - else - downsize = so_far; - }); - - msg.set_body(data); - - test_http_server::scoped_server scoped(m_uri); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, mtd, U("/"), content_type, data); - std::string resp_data; - for (size_t i = 0; i < repeats * 2; ++i) - resp_data.append("abcdefghihklmnopqrstuvwxyz"); - - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - p_request->reply(200, utility::string_t(U("OK")), headers, resp_data); - }); - - auto response = client.request(msg).get(); - http_asserts::assert_response_equals(response, status_codes::OK); - - VERIFY_ARE_EQUAL(26u * repeats, upsize); - - response.content_ready().wait(); - - VERIFY_ARE_EQUAL(26u * repeats * 2, downsize); - // We don't have very precise control over how much of a message is transferred - // in each chunk being sent or received, so we can't make an exact comparison here. - VERIFY_IS_TRUE(calls > 4); - } - - TEST_FIXTURE(uri_address, set_progress_handler_open_failure) - { - http_client client(U("http://localhost323:-1")); - - const method mtd = methods::POST; - utility::string_t data; - utility::string_t content_type = U("text/plain; charset=utf-8"); - - const size_t repeats = 5500; - for (size_t i = 0; i < repeats; ++i) - data.append(U("abcdefghihklmnopqrstuvwxyz")); - - utility::size64_t upsize = 4711u, downsize = 4711u; - int calls = 0; - - http_request msg(mtd); - // We should never see this handler called. - msg.set_progress_handler([&](message_direction::direction direction, utility::size64_t so_far) { - calls += 1; - if (direction == message_direction::upload) - upsize = so_far; - else - downsize = so_far; - }); - - msg.set_body(data); - - auto response = client.request(msg); - VERIFY_THROWS(response.get(), web::http::http_exception); - VERIFY_ARE_EQUAL(4711u, upsize); - VERIFY_ARE_EQUAL(4711u, downsize); - VERIFY_ARE_EQUAL(0, calls); - } - - TEST_FIXTURE(uri_address, set_progress_handler_request_timeout) - { - test_http_server::scoped_server scoped(m_uri); - http_client_config config; - config.set_chunksize(512); - config.set_timeout(utility::seconds(1)); - - http_client client(m_uri, config); - - const method mtd = methods::POST; - utility::string_t data; - utility::string_t content_type = U("text/plain; charset=utf-8"); - - const size_t repeats = 5500; - for (size_t i = 0; i < repeats; ++i) - data.append(U("abcdefghihklmnopqrstuvwxyz")); - - utility::size64_t upsize = 4711u, downsize = 4711u; - int calls = 0; - - http_request msg(mtd); - // We should never see this handler called for download, but for upload should still happen, since - // there's a server (just not a very responsive one) and we're sending data to it. - msg.set_progress_handler([&](message_direction::direction direction, utility::size64_t so_far) { - calls += 1; - if (direction == message_direction::upload) - upsize = so_far; - else - downsize = so_far; - }); - - msg.set_body(data); - auto t = scoped.server()->next_request(); - auto response = client.request(msg); - -#ifdef __APPLE__ - // CodePlex 295 - VERIFY_THROWS(response.get(), http_exception); -#else - VERIFY_THROWS_HTTP_ERROR_CODE(response.get(), std::errc::timed_out); -#endif - VERIFY_ARE_EQUAL(26u * repeats, upsize); - VERIFY_ARE_EQUAL(4711u, downsize); - // We don't have very precise control over how much of the message is transferred - // before the exception occurs, so we can't make an exact comparison here. - VERIFY_IS_TRUE(calls >= 2); - t.get(); - } - - TEST_FIXTURE(uri_address, upload_nobody_exception) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - http_request msg(methods::GET); - - auto t = scoped.server()->next_request().then( - [&](test_request* p_request) { p_request->reply(200, utility::string_t(U("OK"))); }); - - msg.set_progress_handler([](message_direction::direction, utility::size64_t) { - // First all is for data upload completion - throw std::invalid_argument("fake error"); - }); - - VERIFY_THROWS(client.request(msg).get(), std::invalid_argument); - - t.get(); - } - - TEST_FIXTURE(uri_address, download_nobody_exception) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - http_request msg(methods::GET); - - scoped.server()->next_request().then( - [&](test_request* p_request) { p_request->reply(200, utility::string_t(U("OK"))); }); - - int numCalls = 0; - msg.set_progress_handler([&](message_direction::direction, utility::size64_t) { - if (++numCalls == 2) - { - // second is for data download - throw std::invalid_argument("fake error"); - } - }); - - VERIFY_THROWS(client.request(msg).get().content_ready().get(), std::invalid_argument); - } - - TEST_FIXTURE(uri_address, data_upload_exception) - { - http_client client(m_uri); - http_request msg(methods::PUT); - msg.set_body(U("A")); - - msg.set_progress_handler( - [&](message_direction::direction, utility::size64_t) { throw std::invalid_argument("fake error"); }); - - pplx::task<test_request*> t; - { - test_http_server::scoped_server scoped(m_uri); - t = scoped.server()->next_request(); - VERIFY_THROWS(client.request(msg).get(), std::invalid_argument); - } - try - { - t.get(); - } - catch (const std::runtime_error&) - { /* It is ok if the request does not complete before the server is shutdown */ - } - } - - TEST_FIXTURE(uri_address, data_download_exception, "Ignore:Windows", "395") - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - http_request msg(methods::GET); - - auto t = scoped.server()->next_request().then([&](test_request* p_request) { - std::string resp_data("abc"); - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - p_request->reply(200, utility::string_t(U("OK")), headers, resp_data); - }); - - int numCalls = 0; - msg.set_progress_handler([&](message_direction::direction, utility::size64_t) { - if (++numCalls == 2) - { - // 2rd is for data download - throw std::invalid_argument("fake error"); - } - }); - - try - { - handle_timeout([&] { client.request(msg).get().content_ready().get(); }); - } - catch (std::invalid_argument const&) - { - // Expected. - } - t.get(); - } -} - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/proxy_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/proxy_tests.cpp @@ -1,222 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * proxy_tests.cpp - * - * Tests cases for using proxies with http_clients. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -// In order to run this test, replace this proxy uri with one that you have access to. -static const auto proxy_uri = U("http://netproxy.redmond.corp.microsoft.com"); - -SUITE(proxy_tests) -{ - TEST_FIXTURE(uri_address, web_proxy_uri) - { - uri u(proxy_uri); - - web_proxy uri_proxy(u); - VERIFY_IS_TRUE(uri_proxy.is_specified()); - VERIFY_IS_FALSE(uri_proxy.is_disabled()); - VERIFY_IS_FALSE(uri_proxy.is_auto_discovery()); - VERIFY_IS_FALSE(uri_proxy.is_default()); - VERIFY_ARE_EQUAL(u, uri_proxy.address()); - } - - TEST_FIXTURE(uri_address, web_proxy_disabled) - { - web_proxy disabled_proxy(web_proxy::disabled); - VERIFY_IS_FALSE(disabled_proxy.is_specified()); - VERIFY_IS_TRUE(disabled_proxy.is_disabled()); - VERIFY_IS_FALSE(disabled_proxy.is_auto_discovery()); - VERIFY_IS_FALSE(disabled_proxy.is_default()); - } - - TEST_FIXTURE(uri_address, web_proxy_discover) - { - web_proxy discover_proxy(web_proxy::use_auto_discovery); - VERIFY_IS_FALSE(discover_proxy.is_specified()); - VERIFY_IS_FALSE(discover_proxy.is_disabled()); - VERIFY_IS_TRUE(discover_proxy.is_auto_discovery()); - VERIFY_IS_FALSE(discover_proxy.is_default()); - } - - TEST_FIXTURE(uri_address, web_proxy_default) - { - web_proxy default_proxy(web_proxy::use_default); - VERIFY_IS_FALSE(default_proxy.is_specified()); - VERIFY_IS_FALSE(default_proxy.is_disabled()); - VERIFY_IS_FALSE(default_proxy.is_auto_discovery()); - VERIFY_IS_TRUE(default_proxy.is_default()); - } - - TEST_FIXTURE(uri_address, web_proxy_default_construct) - { - web_proxy default_proxy_2; - VERIFY_IS_FALSE(default_proxy_2.is_specified()); - VERIFY_IS_FALSE(default_proxy_2.is_disabled()); - VERIFY_IS_FALSE(default_proxy_2.is_auto_discovery()); - VERIFY_IS_TRUE(default_proxy_2.is_default()); - } - - TEST_FIXTURE(uri_address, http_client_config_set_proxy) - { - http_client_config hconfig; - VERIFY_IS_TRUE(hconfig.proxy().is_default()); - - uri u = U("http://x"); - - hconfig.set_proxy(web_proxy(u)); - VERIFY_ARE_EQUAL(u, hconfig.proxy().address()); - } - -#ifndef __cplusplus_winrt - // IXHR2 does not allow the proxy settings to be changed - TEST_FIXTURE(uri_address, auto_discovery_proxy) - { - test_http_server::scoped_server scoped(m_uri); - auto t = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/"), U("text/plain"), U("this is a test")); - p_request->reply(status_codes::OK); - }); - http_client_config config; - config.set_proxy(web_proxy::use_auto_discovery); - - http_client client(m_uri, config); - http_asserts::assert_response_equals(client.request(methods::PUT, U("/"), U("this is a test")).get(), - status_codes::OK); - - t.get(); - } - - TEST_FIXTURE(uri_address, disabled_proxy) - { - test_http_server::scoped_server scoped(m_uri); - auto t = scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/"), U("text/plain"), U("sample data")); - p_request->reply(status_codes::OK); - }); - - http_client_config config; - config.set_proxy(web_proxy::disabled); - - http_client client(m_uri, config); - http_asserts::assert_response_equals(client.request(methods::PUT, U("/"), U("sample data")).get(), - status_codes::OK); - - t.get(); - } - -#endif // __cplusplus_winrt - -#ifdef __cplusplus_winrt - TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) - { - http_client_config config; - config.set_proxy(web_proxy::use_auto_discovery); - http_client client(m_uri, config); - - VERIFY_THROWS(client.request(methods::GET, U("/")).get(), http_exception); - } -#endif - -#ifndef __cplusplus_winrt - // Can't specify a proxy with WinRT implementation. - TEST_FIXTURE(uri_address, - http_proxy_with_credentials, - "Ignore:Linux", - "Github 53", - "Ignore:Apple", - "Github 53", - "Ignore:Android", - "Github 53", - "Ignore:IOS", - "Github 53", - "Ignore", - "Manual") - { - web_proxy proxy(proxy_uri); - web::credentials cred(U("artur"), U("fred")); // relax, this is not my real password - proxy.set_credentials(cred); - - http_client_config config; - config.set_proxy(proxy); - - // Access to this server will succeed because the first request will not be challenged and hence - // my bogus credentials will not be supplied. - http_client client(U("http://www.microsoft.com"), config); - - try - { - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - } - catch (web::http::http_exception const& e) - { - if (e.error_code().value() == 12007) - { - // The above "netproxy.redmond.corp.microsoft.com" is an internal site not generally accessible. - // This will cause a failure to resolve the URL. - // This is ok. - return; - } - throw; - } - } - - TEST_FIXTURE(uri_address, http_proxy, "Ignore", "Manual") - { - http_client_config config; - config.set_proxy(web_proxy(proxy_uri)); - - http_client client(U("http://httpbin.org"), config); - - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - } - - TEST_FIXTURE(uri_address, https_proxy, "Ignore", "Manual") - { - http_client_config config; - config.set_proxy(web_proxy(proxy_uri)); - - http_client client(U("https://httpbin.org"), config); - - http_response response = client.request(methods::GET).get(); - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - response.content_ready().wait(); - } - -#endif - -} // SUITE(proxy_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/redirect_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/redirect_tests.cpp @@ -1,342 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for multiple requests and responses from an http_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" -#ifdef _WIN32 -#include <Windows.h> -#include <VersionHelpers.h> -#endif // _WIN32 - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -#if defined(_WIN32) && !defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) -#define USING_WINHTTP 1 -#else -#define USING_WINHTTP 0 -#endif - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -pplx::task<void> next_reply_assert( - test_http_server* p_server, - const method& method, - const utility::string_t& path, - status_code code = status_codes::OK, - const utility::string_t& location = U("")) -{ - return p_server->next_request().then([=](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, path); - size_t content_length; - VERIFY_ARE_EQUAL(methods::POST == method, - p_request->match_header(header_names::content_length, content_length)); - - std::map<utility::string_t, utility::string_t> headers; - if (!location.empty()) - { - headers[header_names::location] = location; - } - - // web::http::details::get_default_reason_phrase is internal :-/ - p_request->reply(code, {}, headers); - }); -} - -pplx::task<void> next_reply_assert( - test_http_server* p_server, - const utility::string_t& path, - status_code code = status_codes::OK, - const utility::string_t& location = U("")) -{ - return next_reply_assert(p_server, methods::GET, path, code, location); -} - -SUITE(redirect_tests) -{ - TEST_FIXTURE(uri_address, follows_multiple_redirects_by_default) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::MovedPermanently, U("/moved-here"))); - replies.push_back(next_reply_assert(p_server, U("/moved-here"), status_codes::TemporaryRedirect, U("/moved-there"))); - replies.push_back(next_reply_assert(p_server, U("/moved-there"), status_codes::Found, U("/found-elsewhere"))); - replies.push_back(next_reply_assert(p_server, U("/found-elsewhere"))); - - http_client_config config; - http_client client(m_uri, config); - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::OK) - ); - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST_FIXTURE(uri_address, follows_retrieval_redirect) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, methods::POST, U("/"), status_codes::SeeOther, U("/see-here"))); - replies.push_back(next_reply_assert(p_server, methods::GET, U("/see-here"))); - - http_client_config config; - http_client client(m_uri, config); - - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::POST, U(""), U("body")).get(), status_codes::OK); - ); - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST_FIXTURE(uri_address, obeys_max_redirects) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::MovedPermanently, U("/moved-here"))); - replies.push_back(next_reply_assert(p_server, U("/moved-here"), status_codes::TemporaryRedirect, U("/moved-there"))); - replies.push_back(next_reply_assert(p_server, U("/moved-there"), status_codes::Found, U("/found-elsewhere"))); - - http_client_config config; - config.set_max_redirects(2); - http_client client(m_uri, config); - - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::Found) - ); - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST_FIXTURE(uri_address, can_disable_redirects) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::MovedPermanently, U("/moved-here"))); - - http_client_config config; - config.set_max_redirects(0); - http_client client(m_uri, config); - - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::MovedPermanently) - ); - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST(does_not_follow_https_to_http_by_default) - { - handle_timeout([] { - http_client_config config; - http_client client(U("https://http.badssl.com/"), config); - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::MovedPermanently) - ); - }); - } - - TEST(can_follow_https_to_http) - { - handle_timeout([] { - http_client_config config; - config.set_https_to_http_redirects(true); - http_client client(U("https://http.badssl.com/"), config); - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::OK) - ); - }); - } - - TEST_FIXTURE(uri_address, follows_permanent_redirect) - { -#if USING_WINHTTP - // note that 308 Permanent Redirect is only supported by WinHTTP from Windows 10 - if (!IsWindows10OrGreater()) { - return; - } -#endif // USING_WINHTTP - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::PermanentRedirect, U("/moved-here"))); - replies.push_back(next_reply_assert(p_server, U("/moved-here"))); - - http_client_config config; - http_client client(m_uri, config); - - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::OK) - ); - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST_FIXTURE(uri_address, may_throw_if_no_location) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::MovedPermanently)); - - http_client_config config; - http_client client(m_uri, config); - - // implementation-specific behaviour -#if USING_WINHTTP - VERIFY_THROWS( - client.request(methods::GET).get(), - http_exception - ); -#else - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::MovedPermanently) - ); -#endif - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST_FIXTURE(uri_address, should_not_follow_cyclic_redirect) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::TemporaryRedirect, U("/briefly-here"))); - replies.push_back(next_reply_assert(p_server, U("/briefly-here"), status_codes::MovedPermanently, U("/"))); -#if USING_WINHTTP - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::NotFound)); -#endif - - http_client_config config; - http_client client(m_uri, config); - - // implementation-specific behaviour -#if USING_WINHTTP - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::NotFound) - ); -#else // ^^^ USING_WINHTTP / !USING_WINHTTP vvv - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::MovedPermanently) - ); -#endif // USING_WINHTTP - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST_FIXTURE(uri_address, may_follow_unchanged_redirect) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, methods::POST, U("/"), status_codes::TemporaryRedirect, U("/retry-here"))); -#if USING_WINHTTP - replies.push_back(next_reply_assert(p_server, methods::POST, U("/retry-here"))); -#endif - - http_client_config config; - http_client client(m_uri, config); - - // implementation-specific behaviour -#if USING_WINHTTP - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::POST, U(""), U("body")).get(), status_codes::OK) - ); -#else // ^^^ USING_WINHTTP / !USING_WINHTTP vvv - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::POST, U(""), U("body")).get(), status_codes::TemporaryRedirect) - ); -#endif // USING_WINHTTP - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - - TEST_FIXTURE(uri_address, may_not_follow_manual_redirect) - { - test_http_server::scoped_server scoped(m_uri); - auto p_server = scoped.server(); - - std::vector<pplx::task<void>> replies; - replies.push_back(next_reply_assert(p_server, U("/"), status_codes::MultipleChoices, U("/prefer-here"))); -#if USING_WINHTTP - replies.push_back(next_reply_assert(p_server, U("/prefer-here"))); -#endif - - http_client_config config; - http_client client(m_uri, config); - - // implementation-specific behaviour -#if USING_WINHTTP - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::OK) - ); -#else // ^^^ USING_WINHTTP / !USING_WINHTTP vvv - VERIFY_NO_THROWS( - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::MultipleChoices) - ); -#endif // USING_WINHTTP - p_server->close(); - for (auto& reply : replies) - { - VERIFY_NO_THROWS(reply.get()); - } - } - -} // SUITE(redirect_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/request_helper_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/request_helper_tests.cpp @@ -1,277 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * request_helper_tests.cpp - * - * Tests cases for the convenience helper functions for making requests on http_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "cpprest/details/http_helpers.h" -#include "cpprest/version.h" -#include <fstream> - -using namespace web; -using namespace utility; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(request_helper_tests) -{ - TEST_FIXTURE(uri_address, do_not_fail_on_content_encoding_when_not_requested) - { - test_http_server::scoped_server scoped(m_uri); - auto& server = *scoped.server(); - http_client client(m_uri); - - server.next_request().then([](test_request* p_request) { - p_request->reply(200, U("OK"), {{header_names::content_encoding, U("chunked")}}); - }); - - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, fail_on_content_encoding_if_unsupported) - { - if (web::http::compression::builtin::supported()) - { - test_http_server::scoped_server scoped(m_uri); - auto& server = *scoped.server(); - http_client_config config; - config.set_request_compressed_response(true); - http_client client(m_uri, config); - - server.next_request().then([](test_request* p_request) { - p_request->reply(200, U("OK"), {{header_names::content_encoding, U("unsupported-algorithm")}}); - }); - - VERIFY_THROWS(client.request(methods::GET).get(), web::http::http_exception); - } - } - - TEST_FIXTURE(uri_address, send_accept_encoding) - { - if (web::http::compression::builtin::supported()) - { - test_http_server::scoped_server scoped(m_uri); - auto& server = *scoped.server(); - http_client_config config; - config.set_request_compressed_response(true); - http_client client(m_uri, config); - - std::atomic<bool> found_accept_encoding(false); - - server.next_request().then([&found_accept_encoding](test_request* p_request) { - found_accept_encoding = - p_request->m_headers.find(header_names::accept_encoding) != p_request->m_headers.end(); - p_request->reply(200, U("OK")); - }); - - client.request(methods::GET).get(); - - VERIFY_IS_TRUE(found_accept_encoding); - } - } - - TEST_FIXTURE(uri_address, do_not_send_accept_encoding) - { - test_http_server::scoped_server scoped(m_uri); - auto& server = *scoped.server(); - http_client client(m_uri); - - std::atomic<bool> found_accept_encoding(true); - - server.next_request().then([&found_accept_encoding](test_request* p_request) { - utility::string_t header; - - // On Windows, someone along the way (not us!) adds "Accept-Encoding: peerdist" - found_accept_encoding = - p_request->match_header(header_names::accept_encoding, header) && header != _XPLATSTR("peerdist"); - p_request->reply(200, U("OK")); - }); - - client.request(methods::GET).get(); - - VERIFY_IS_FALSE(found_accept_encoding); - } - - TEST_FIXTURE(uri_address, non_rvalue_bodies) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // Without content type. - utility::string_t send_body = U("YES NOW SEND THE TROOPS!"); - p_server->next_request().then([&send_body](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/"), U("text/plain; charset=utf-8"), send_body); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(methods::PUT, U(""), send_body).get(), status_codes::OK); - - // With content type. - utility::string_t content_type = U("custom_content"); - test_server_utilities::verify_request( - &client, methods::PUT, U("/"), content_type, send_body, p_server, status_codes::OK, U("OK")); - - // Empty body type - send_body.clear(); - content_type = U("haha_type"); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::PUT, U("/"), content_type); - VERIFY_ARE_EQUAL(0u, p_request->m_body.size()); - VERIFY_ARE_EQUAL(0u, p_request->reply(status_codes::OK, U("OK"))); - }); - http_asserts::assert_response_equals( - client.request(methods::PUT, U("/"), send_body, content_type).get(), status_codes::OK, U("OK")); - } - - TEST_FIXTURE(uri_address, rvalue_bodies) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // Without content type. - utility::string_t send_body = U("YES NOW SEND THE TROOPS!"); - utility::string_t move_body = send_body; - p_server->next_request().then([&send_body](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/"), U("text/plain; charset=utf-8"), send_body); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(methods::PUT, U(""), std::move(move_body)).get(), - status_codes::OK); - - // With content type. - utility::string_t content_type = U("custom_content"); - move_body = send_body; - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::PUT, U("/"), content_type, send_body); - p_request->reply(200); - }); - http_asserts::assert_response_equals( - client.request(methods::PUT, U(""), std::move(move_body), content_type).get(), status_codes::OK); - - // Empty body. - content_type = U("haha_type"); - send_body.clear(); - move_body = send_body; - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::PUT, U("/"), content_type); - VERIFY_ARE_EQUAL(0u, p_request->m_body.size()); - p_request->reply(200); - }); - http_asserts::assert_response_equals( - client.request(methods::PUT, U(""), std::move(move_body), content_type).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, json_bodies) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // JSON bool value. - json::value bool_value = json::value::boolean(true); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/"), U("application/json"), bool_value.serialize()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(methods::PUT, U("/"), bool_value).get(), status_codes::OK); - - // JSON null value. - json::value null_value = json::value::null(); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals( - p_request, methods::PUT, U("/"), U("application/json"), null_value.serialize()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(methods::PUT, U(""), null_value).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, non_rvalue_2k_body) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - std::string body; - for (int i = 0; i < 2048; ++i) - { - body.append(1, (char)('A' + (i % 26))); - } - test_server_utilities::verify_request(&client, - methods::PUT, - U("/"), - U("text/plain"), - ::utility::conversions::to_string_t(body), - p_server, - status_codes::OK, - U("OK")); - } - - TEST_FIXTURE(uri_address, default_user_agent) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - p_server->next_request().then([&](test_request* p_request) { - utility::stringstream_t stream; - stream << _XPLATSTR("cpprestsdk/") << CPPREST_VERSION_MAJOR << _XPLATSTR(".") << CPPREST_VERSION_MINOR - << _XPLATSTR(".") << CPPREST_VERSION_REVISION; - utility::string_t foundHeader; - p_request->match_header(U("User-Agent"), foundHeader); - VERIFY_ARE_EQUAL(stream.str(), foundHeader); - - p_request->reply(200); - }); - - http_asserts::assert_response_equals(client.request(methods::GET).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, overwrite_user_agent) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - utility::string_t customUserAgent(U("MyAgent")); - p_server->next_request().then([&](test_request* p_request) { - utility::string_t foundHeader; - p_request->match_header(U("User-Agent"), foundHeader); - VERIFY_ARE_EQUAL(customUserAgent, foundHeader); - - p_request->reply(200); - }); - - http_request request(methods::GET); - request.headers()[U("User-Agent")] = customUserAgent; - http_asserts::assert_response_equals(client.request(request).get(), status_codes::OK); - } - -} // SUITE(request_helper_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/request_stream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/request_stream_tests.cpp @@ -1,455 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases covering using streams with HTTP request with http_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -utility::string_t get_full_name(const utility::string_t& name) -{ -#if defined(__cplusplus_winrt) - // On WinRT, we must compensate for the fact that we will be accessing files in the - // Documents folder - auto file = pplx::create_task(KnownFolders::DocumentsLibrary->CreateFileAsync( - ref new Platform::String(name.c_str()), CreationCollisionOption::ReplaceExisting)) - .get(); - return file->Path->Data(); -#else - return name; -#endif -} - -template<typename _CharType> -pplx::task<streams::streambuf<_CharType>> OPEN_R(const utility::string_t& name) -{ -#if !defined(__cplusplus_winrt) - return streams::file_buffer<_CharType>::open(name, std::ios_base::in); -#else - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))).get(); - - return streams::file_buffer<_CharType>::open(file, std::ios_base::in); -#endif -} - -SUITE(request_stream_tests) -{ - // Used to prepare data for stream tests - void fill_file(const utility::string_t& name, size_t repetitions = 1) - { - std::fstream stream(get_full_name(name), std::ios_base::out | std::ios_base::trunc); - - for (size_t i = 0; i < repetitions; i++) - stream << "abcdefghijklmnopqrstuvwxyz"; - } - - void fill_buffer(streams::streambuf<uint8_t> rbuf, size_t repetitions = 1) - { - const char* text = "abcdefghijklmnopqrstuvwxyz"; - size_t len = strlen(text); - for (size_t i = 0; i < repetitions; i++) - rbuf.putn_nocopy((const uint8_t*)text, len); - } - -#if defined(__cplusplus_winrt) - TEST_FIXTURE(uri_address, ixhr2_transfer_encoding) - { - // Transfer encoding chunked is not supported. Not specifying the - // content length should cause an exception from the task. Verify - // that there is no unobserved exception - - http_client client(m_uri); - - auto buf = streams::producer_consumer_buffer<uint8_t>(); - buf.putc(22).wait(); - buf.close(std::ios_base::out).wait(); - - http_request reqG(methods::PUT); - reqG.set_body(buf.create_istream()); - VERIFY_THROWS(client.request(reqG).get(), http_exception); - - VERIFY_THROWS(client.request(methods::POST, U(""), buf.create_istream(), 1).get(), http_exception); - } -#endif - - TEST_FIXTURE(uri_address, set_body_stream_1) - { - utility::string_t fname = U("set_body_stream_1.txt"); - fill_file(fname); - - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - auto stream = OPEN_R<uint8_t>(fname).get(); - http_request msg(methods::POST); - msg.set_body(stream); -#if defined(__cplusplus_winrt) - msg.headers().set_content_length(26); -#endif - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - VERIFY_ARE_EQUAL(26u, p_request->m_body.size()); - std::string str_body(std::begin(p_request->m_body), std::end(p_request->m_body)); - VERIFY_ARE_EQUAL(U("abcdefghijklmnopqrstuvwxyz"), ::utility::conversions::to_string_t(str_body)); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - stream.close().wait(); - } - - TEST_FIXTURE(uri_address, set_body_stream_2) - { - utility::string_t fname = U("set_body_stream_2.txt"); - fill_file(fname); - - http_client_config config; - config.set_chunksize(16 * 1024); - - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri, config); - - auto stream = OPEN_R<uint8_t>(fname).get(); - http_request msg(methods::POST); - msg.set_body(stream); -#if defined(__cplusplus_winrt) - msg.headers().set_content_length(26); -#endif - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - VERIFY_ARE_EQUAL(26u, p_request->m_body.size()); - std::string str_body(std::begin(p_request->m_body), std::end(p_request->m_body)); - VERIFY_ARE_EQUAL(U("abcdefghijklmnopqrstuvwxyz"), ::utility::conversions::to_string_t(str_body)); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - stream.close().wait(); - } - - // Implementation for request with stream test case. - static void stream_request_impl( - const uri& address, bool withContentLength, size_t chunksize, utility::string_t fname) - { - fill_file(fname); - //(withContentLength); - http_client_config config; - config.set_chunksize(chunksize); - - test_http_server::scoped_server scoped(address); - test_http_server* p_server = scoped.server(); - http_client client(address, config); - - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - VERIFY_ARE_EQUAL(26u, p_request->m_body.size()); - std::string str_body(std::begin(p_request->m_body), std::end(p_request->m_body)); - VERIFY_ARE_EQUAL(U("abcdefghijklmnopqrstuvwxyz"), ::utility::conversions::to_string_t(str_body)); - p_request->reply(200); - }); - - auto stream = OPEN_R<uint8_t>(fname).get(); - - if (withContentLength) - { - http_asserts::assert_response_equals( - client.request(methods::POST, U(""), stream, 26, U("text/plain")).get(), status_codes::OK); - } - else - { -#if defined __cplusplus_winrt - http_asserts::assert_response_equals( - client.request(methods::POST, U(""), stream, 26, U("text/plain")).get(), status_codes::OK); -#else - http_asserts::assert_response_equals(client.request(methods::POST, U(""), stream, U("text/plain")).get(), - status_codes::OK); -#endif - } - - stream.close().wait(); - } - -#if !defined(__cplusplus_winrt) - TEST_FIXTURE(uri_address, without_content_length_1) - { - stream_request_impl(m_uri, false, 64 * 1024, U("without_content_length_1.txt")); - } - - TEST_FIXTURE(uri_address, without_content_length_2) - { - stream_request_impl(m_uri, false, 1024, U("without_content_length_2.txt")); - } -#endif - - TEST_FIXTURE(uri_address, with_content_length_1) - { - stream_request_impl(m_uri, true, 64 * 1024, U("with_content_length_1.txt")); - } - - TEST_FIXTURE(uri_address, producer_consumer_buffer_with_content_length) - { - streams::producer_consumer_buffer<uint8_t> rbuf; - fill_buffer(rbuf); - rbuf.close(std::ios_base::out); - - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - http_request msg(methods::POST); - msg.set_body(streams::istream(rbuf)); - msg.headers().set_content_length(26); - - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - VERIFY_ARE_EQUAL(26u, p_request->m_body.size()); - std::string str_body(std::begin(p_request->m_body), std::end(p_request->m_body)); - VERIFY_ARE_EQUAL(U("abcdefghijklmnopqrstuvwxyz"), ::utility::conversions::to_string_t(str_body)); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, stream_partial_from_start) - { - utility::string_t fname = U("stream_partial_from_start.txt"); - fill_file(fname, 200); - - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - http_request msg(methods::POST); - auto stream = OPEN_R<uint8_t>(fname).get().create_istream(); - msg.set_body(stream); - msg.headers().set_content_length(4500); - - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - VERIFY_ARE_EQUAL(4500u, p_request->m_body.size()); - std::string str_body(std::begin(p_request->m_body), std::end(p_request->m_body)); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // We should only have read the first 4500 bytes. - auto length = stream.seek(0, std::ios_base::cur); - VERIFY_ARE_EQUAL((size_t)length, (size_t)4500); - - stream.close().get(); - } - - TEST_FIXTURE(uri_address, stream_partial_from_middle) - { - utility::string_t fname = U("stream_partial_from_middle.txt"); - fill_file(fname, 100); - - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - http_request msg(methods::POST); - auto stream = OPEN_R<uint8_t>(fname).get().create_istream(); - msg.set_body(stream); - msg.headers().set_content_length(13); - - stream.seek(13, std::ios_base::cur); - - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::POST, U("/")); - VERIFY_ARE_EQUAL(13u, p_request->m_body.size()); - std::string str_body(std::begin(p_request->m_body), std::end(p_request->m_body)); - VERIFY_ARE_EQUAL(str_body, "nopqrstuvwxyz"); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // We should only have read the first 26 bytes. - auto length = stream.seek(0, std::ios_base::cur); - VERIFY_ARE_EQUAL((int)length, 26); - - stream.close().get(); - } - - class test_exception : public std::exception - { - public: - test_exception() {} - }; - -// Ignore on WinRT CodePlex 144 -#if !defined(__cplusplus_winrt) - TEST_FIXTURE(uri_address, set_body_stream_exception) - { - test_http_server::scoped_server scoped(m_uri); - scoped.server(); - http_client client(m_uri); - - streams::producer_consumer_buffer<uint8_t> buf; - const char* data = "abcdefghijklmnopqrstuvwxyz"; - buf.putn_nocopy(reinterpret_cast<const uint8_t*>(data), 26).wait(); - - http_request msg(methods::POST); - msg.set_body(buf.create_istream()); - msg.headers().set_content_length(26); - - buf.close(std::ios::in, std::make_exception_ptr(test_exception())).wait(); - - VERIFY_THROWS(client.request(msg).get(), test_exception); - - // Codeplex 328. -#if !defined(_WIN32) - tests::common::utilities::os_utilities::sleep(1000); -#endif - } -#endif - -// These tests aren't possible on WinRT because they don't -// specify a Content-Length. -#if !defined(__cplusplus_winrt) - TEST_FIXTURE(uri_address, stream_close_early) - { - http_client client(m_uri); - test_http_server::scoped_server scoped(m_uri); - scoped.server()->next_request().then([](test_request* request) { request->reply(status_codes::OK); }); - - // Make request. - streams::producer_consumer_buffer<uint8_t> buf; - auto responseTask = client.request(methods::PUT, U(""), buf.create_istream()); - - // Write a bit of data then close the stream early. - unsigned char data[5] = {'1', '2', '3', '4', '5'}; - buf.putn_nocopy(&data[0], 5).wait(); - - buf.close(std::ios::out).wait(); - - // Verify that the task completes successfully - http_asserts::assert_response_equals(responseTask.get(), status_codes::OK); - } - - TEST_FIXTURE(uri_address, stream_close_early_with_exception) - { - http_client client(m_uri); - test_http_server::scoped_server scoped(m_uri); - - // Make request. - streams::producer_consumer_buffer<uint8_t> buf; - auto responseTask = client.request(methods::PUT, U(""), buf.create_istream()); - - // Write a bit of data then close the stream early. - unsigned char data[5] = {'1', '2', '3', '4', '5'}; - buf.putn_nocopy(&data[0], 5).wait(); - - buf.close(std::ios::out, std::make_exception_ptr(test_exception())).wait(); - - // Verify that the responseTask throws the exception set when closing the stream - VERIFY_THROWS(responseTask.get(), test_exception); - - // Codeplex 328. -#if !defined(_WIN32) - tests::common::utilities::os_utilities::sleep(1000); -#endif - } -#endif - - // Ignore on WinRT only CodePlex 144 -#if !defined(__cplusplus_winrt) - TEST_FIXTURE(uri_address, stream_close_early_with_exception_and_contentlength) - { - http_client client(m_uri); - test_http_server::scoped_server scoped(m_uri); - - // Make request. - streams::producer_consumer_buffer<uint8_t> buf; - auto responseTask = client.request(methods::PUT, U(""), buf.create_istream(), 10); - - // Write a bit of data then close the stream early. - unsigned char data[5] = {'1', '2', '3', '4', '5'}; - buf.putn_nocopy(&data[0], 5).wait(); - - buf.close(std::ios::out, std::make_exception_ptr(test_exception())).wait(); - - // Verify that the responseTask throws the exception set when closing the stream - VERIFY_THROWS(responseTask.get(), test_exception); - - // Codeplex 328. -#if !defined(_WIN32) - tests::common::utilities::os_utilities::sleep(1000); -#endif - } -#endif - -// Ignore on WinRT only CodePlex 144 -#if !defined(__cplusplus_winrt) - TEST_FIXTURE(uri_address, stream_close_early_with_contentlength, "Ignore:Apple", "328") - { - http_client client(m_uri); - test_http_server::scoped_server scoped(m_uri); - - // Make request. - streams::producer_consumer_buffer<uint8_t> buf; - auto responseTask = client.request(methods::PUT, U(""), buf.create_istream(), 10); - - // Write a bit of data then close the stream early. - unsigned char data[5] = {'1', '2', '3', '4', '5'}; - buf.putn_nocopy(&data[0], 5).wait(); - - buf.close(std::ios::out).wait(); - - // Verify that the responseTask throws the exception set when closing the stream - VERIFY_THROWS(responseTask.get(), http_exception); - - // Codeplex 328. -#if !defined(_WIN32) - tests::common::utilities::os_utilities::sleep(1000); -#endif - } -#endif - - TEST_FIXTURE(uri_address, get_with_body_nono) - { - http_client client(m_uri); - - streams::producer_consumer_buffer<uint8_t> buf; - - http_request reqG(methods::GET); - reqG.set_body(buf.create_istream()); - VERIFY_THROWS(client.request(reqG).get(), http_exception); - - http_request reqH(methods::HEAD); - reqH.set_body(buf.create_istream()); - VERIFY_THROWS(client.request(reqH).get(), http_exception); - } - -} // SUITE(request_stream_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/request_uri_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/request_uri_tests.cpp @@ -1,176 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * request_uri_tests.cpp - * - * Tests cases covering various kinds of request URIs with http_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(request_uri_tests) -{ - // Tests path specified in requests with non-empty base path in client constructor. - TEST_FIXTURE(uri_address, path_non_empty_ctor) - { - uri address(U("http://localhost:45678/base_path/")); - - // Path not starting with '/'. - { - test_http_server::scoped_server scoped(address); - http_client client(address); - test_connection(scoped.server(), &client, U("next_level"), U("/base_path/next_level")); - } - - // Path starting with '/'. - { - test_http_server::scoped_server scoped(address); - http_client client(address); - test_connection(scoped.server(), &client, U("/next_level"), U("/base_path/next_level")); - } - } - - // Tests path specified in requests with empty base path in client constructor. - TEST_FIXTURE(uri_address, path_empty_ctor) - { - uri address(U("http://localhost:45678")); - - // NON empty path. - { - test_http_server::scoped_server scoped(address); - http_client client(address); - test_connection(scoped.server(), &client, U("next_level"), U("/next_level")); - } - - // Request path of '*' - { - test_http_server::scoped_server scoped(address); - http_client client(address); - test_connection(scoped.server(), &client, U("*"), U("/*")); - } - - // Empty base of '/' with request path starting with '/'. - address = uri(U("http://localhost:45678/")); - { - test_http_server::scoped_server scoped(address); - http_client client(address); - test_connection(scoped.server(), &client, U("/hehehe"), U("/hehehe")); - } - } - - TEST_FIXTURE(uri_address, with_query_fragment) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // query - test_connection(scoped.server(), &client, U("/hehehe?key1=value2&"), U("/hehehe?key1=value2&")); - - // fragment - - // WinRT implementation percent encodes the '#'. - utility::string_t expected_value = U("/heheh?key1=value2#fragment"); -#if defined(__cplusplus_winrt) || defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL) - expected_value = percent_encode_pound(expected_value); -#endif - - test_connection(scoped.server(), &client, U("/heheh?key1=value2#fragment"), expected_value); - } - - TEST_FIXTURE(uri_address, uri_encoding) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - // try with encoding string. - http_request msg(methods::GET); - msg.set_request_uri(U("/path1!!alreadyencoded")); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::GET, U("/path1!!alreadyencoded")); - http_asserts::assert_test_request_contains_headers(p_request, msg.headers()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - // verify encoding actual happens with plain. - msg = http_request(methods::GET); - msg.set_request_uri(web::http::uri::encode_uri(U("/path1 /encode"))); - VERIFY_ARE_EQUAL(U("/path1%20/encode"), msg.relative_uri().to_string()); - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, methods::GET, U("/path1%20/encode")); - http_asserts::assert_test_request_contains_headers(p_request, msg.headers()); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - } - - // Tests combining case URI query/fragments with relative URI query/fragments. - TEST_FIXTURE(uri_address, append_query_fragment) - { - // Try with query. - const utility::string_t base_uri_with_query = - web::http::uri_builder(m_uri).append(U("/path1?key1=value1")).to_string(); - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(base_uri_with_query); - - p_server->next_request().then([&](test_request* p_request) { - // WinRT implementation percent encodes the '#'. - utility::string_t expected_value = U("/path1?key1=value1&key2=value2#frag"); -#if defined(__cplusplus_winrt) || defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL) - expected_value = percent_encode_pound(expected_value); -#endif - http_asserts::assert_test_request_equals(p_request, methods::GET, expected_value); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(methods::GET, U("?key2=value2#frag")).get(), - status_codes::OK); - } - - // Try with fragment. - const utility::string_t base_uri_with_frag(m_uri.to_string() + U("path1#fragment")); - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(base_uri_with_frag); - - p_server->next_request().then([&](test_request* p_request) { - // WinRT implementation percent encodes the '#'. - utility::string_t expected_value = U("/path1/path2?key2=value2#fragmentfg2"); -#if defined(__cplusplus_winrt) || defined(CPPREST_FORCE_HTTP_CLIENT_WINHTTPPAL) - expected_value = percent_encode_pound(expected_value); -#endif - http_asserts::assert_test_request_equals(p_request, methods::GET, expected_value); - p_request->reply(200); - }); - http_asserts::assert_response_equals(client.request(methods::GET, U("path2?key2=value2#fg2")).get(), - status_codes::OK); - } - } - -} // SUITE(request_uri_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/response_extract_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/response_extract_tests.cpp @@ -1,546 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * response_extract_tests.cpp - * - * Tests cases covering extract functions on HTTP response. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#ifndef __cplusplus_winrt -#include "cpprest/http_listener.h" -#endif - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace utility::conversions; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(response_extract_tests) -{ - // Helper function to send a request and response with given values. - template<typename CharType> - static http_response send_request_response(test_http_server * p_server, - http_client * p_client, - const utility::string_t& content_type, - const std::basic_string<CharType>& data) - { - const method method = methods::GET; - const ::http::status_code code = status_codes::OK; - std::map<utility::string_t, utility::string_t> headers; - if (!content_type.empty()) - { - headers[U("Content-Type")] = content_type; - } - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, U("/")); - VERIFY_ARE_EQUAL(0u, p_request->reply(code, U(""), headers, data)); - }); - http_response rsp = p_client->request(method).get(); - http_asserts::assert_response_equals(rsp, code, headers); - return rsp; - } - - utf16string switch_endian_ness(const utf16string& src_str) - { - utf16string dest_str; - dest_str.resize(src_str.size()); - unsigned char* src = (unsigned char*)&src_str[0]; - unsigned char* dest = (unsigned char*)&dest_str[0]; - for (size_t i = 0; i < dest_str.size() * 2; i += 2) - { - dest[i] = src[i + 1]; - dest[i + 1] = src[i]; - } - return dest_str; - } - - TEST_FIXTURE(uri_address, extract_string) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // default encoding (Latin1) - std::string data("YOU KNOW ITITITITI"); - http_response rsp = send_request_response(scoped.server(), &client, U("text/plain"), data); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // us-ascii - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset= us-AscIi"), data); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // Latin1 - rsp = send_request_response(scoped.server(), &client, U("text/plain;charset=iso-8859-1"), data); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // utf-8 - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset = UTF-8"), data); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // "utf-8" - quoted charset - rsp = send_request_response(scoped.server(), &client, U("text/plain;charset=\"utf-8\""), data); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // no content length - rsp = send_request_response(scoped.server(), &client, U(""), utility::string_t()); - auto str = rsp.to_string(); - // If there is no Content-Type in the response, make sure it won't throw when we ask for string - if (str.find(U("Content-Type")) == std::string::npos) - { - VERIFY_ARE_EQUAL(utility::string_t(U("")), rsp.extract_string().get()); - } - - // utf-16le - data = "YES NOW, HERHEHE****"; - utf16string wdata(utf8_to_utf16(data)); - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16le"), wdata); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // utf-16be - wdata = switch_endian_ness(wdata); - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16be"), wdata); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // utf-16 no BOM (utf-16be) - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdata); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // utf-16 big endian BOM. - wdata.insert(wdata.begin(), ('\0')); - unsigned char* start = (unsigned char*)&wdata[0]; - start[0] = 0xFE; - start[1] = 0xFF; - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdata); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - - // utf-16 little endian BOM. - wdata = utf8_to_utf16("YOU KNOW THIS **********KICKS"); - data = utf16_to_utf8(wdata); - wdata.insert(wdata.begin(), '\0'); - start = (unsigned char*)&wdata[0]; - start[0] = 0xFF; - start[1] = 0xFE; - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdata); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string().get()); - } - - TEST_FIXTURE(uri_address, extract_utf8string) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // default encoding (Latin1) - std::string data("YOU KNOW ITITITITI"); - http_response rsp = send_request_response(scoped.server(), &client, U("text/plain"), data); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // us-ascii - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset= us-AscIi"), data); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // Latin1 - rsp = send_request_response(scoped.server(), &client, U("text/plain;charset=iso-8859-1"), data); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // utf-8 - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset = UTF-8"), data); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // "utf-8" - quoted charset - rsp = send_request_response(scoped.server(), &client, U("text/plain;charset=\"utf-8\""), data); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // no content length - rsp = send_request_response(scoped.server(), &client, U(""), utility::string_t()); - auto str = rsp.to_string(); - // If there is no Content-Type in the response, make sure it won't throw when we ask for string - if (str.find(U("Content-Type")) == std::string::npos) - { - VERIFY_ARE_EQUAL("", rsp.extract_utf8string().get()); - } - - // utf-16le - data = "YES NOW, HERHEHE****"; - utf16string wdata(utf8_to_utf16(data)); - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16le"), wdata); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // utf-16be - wdata = switch_endian_ness(wdata); - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16be"), wdata); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // utf-16 no BOM (utf-16be) - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdata); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // utf-16 big endian BOM. - wdata.insert(wdata.begin(), ('\0')); - unsigned char* start = (unsigned char*)&wdata[0]; - start[0] = 0xFE; - start[1] = 0xFF; - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdata); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - - // utf-16 little endian BOM. - wdata = utf8_to_utf16("YOU KNOW THIS **********KICKS"); - data = utf16_to_utf8(wdata); - wdata.insert(wdata.begin(), '\0'); - start = (unsigned char*)&wdata[0]; - start[0] = 0xFF; - start[1] = 0xFE; - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdata); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string().get()); - } - - TEST_FIXTURE(uri_address, extract_utf16string) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // default encoding (Latin1) - std::string data("YOU KNOW ITITITITI"); - utf16string wdata(utf8_to_utf16(data)); - http_response rsp = send_request_response(scoped.server(), &client, U("text/plain"), data); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // us-ascii - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset= us-AscIi"), data); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // Latin1 - rsp = send_request_response(scoped.server(), &client, U("text/plain;charset=iso-8859-1"), data); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // utf-8 - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset = UTF-8"), data); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // "utf-8" - quoted charset - rsp = send_request_response(scoped.server(), &client, U("text/plain;charset=\"utf-8\""), data); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // no content length - rsp = send_request_response(scoped.server(), &client, U(""), utility::string_t()); - auto str = rsp.to_string(); - // If there is no Content-Type in the response, make sure it won't throw when we ask for string - if (str.find(U("Content-Type")) == std::string::npos) - { - VERIFY_ARE_EQUAL(utf16string(), rsp.extract_utf16string().get()); - } - - // utf-16le - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16le"), wdata); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // utf-16be - auto wdatabe = switch_endian_ness(wdata); - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16be"), wdatabe); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // utf-16 no BOM (utf-16be) - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdatabe); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // utf-16 big endian BOM. - wdatabe.insert(wdatabe.begin(), ('\0')); - unsigned char* start = (unsigned char*)&wdatabe[0]; - start[0] = 0xFE; - start[1] = 0xFF; - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdatabe); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - - // utf-16 little endian BOM. - auto wdatale = wdata; - wdatale.insert(wdatale.begin(), '\0'); - start = (unsigned char*)&wdatale[0]; - start[0] = 0xFF; - start[1] = 0xFE; - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), wdatale); - VERIFY_ARE_EQUAL(wdata, rsp.extract_utf16string().get()); - } - - TEST_FIXTURE(uri_address, extract_string_force) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - std::string data("YOU KNOW ITITITITI"); - http_response rsp = send_request_response(scoped.server(), &client, U("bad unknown charset"), data); - VERIFY_ARE_EQUAL(to_string_t(data), rsp.extract_string(true).get()); - rsp = send_request_response(scoped.server(), &client, U("bad unknown charset"), data); - VERIFY_ARE_EQUAL(data, rsp.extract_utf8string(true).get()); - rsp = send_request_response(scoped.server(), &client, U("bad unknown charset"), data); - VERIFY_ARE_EQUAL(to_utf16string(data), rsp.extract_utf16string(true).get()); - } - - TEST_FIXTURE(uri_address, extract_string_incorrect) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // with non matching content type. - const std::string data("YOU KNOW ITITITITI"); - http_response rsp = send_request_response(scoped.server(), &client, U("non_text"), data); - VERIFY_THROWS(rsp.extract_string().get(), http_exception); - - // with unknown charset - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=uis-ascii"), data); - VERIFY_THROWS(rsp.extract_string().get(), http_exception); - } - -#ifndef __cplusplus_winrt - TEST_FIXTURE(uri_address, extract_empty_string) - { - web::http::experimental::listener::http_listener listener(m_uri); - http_client client(m_uri); - listener.support([](http_request msg) { - auto ResponseStreamBuf = streams::producer_consumer_buffer<uint8_t>(); - ResponseStreamBuf.close(std::ios_base::out).wait(); - http_response response(status_codes::OK); - response.set_body(ResponseStreamBuf.create_istream(), U("text/plain")); - response.headers().add(header_names::connection, U("close")); - msg.reply(response).wait(); - }); - - listener.open().wait(); - - auto response = client.request(methods::GET).get(); - auto data = response.extract_string().get(); - - VERIFY_ARE_EQUAL(0, data.size()); - listener.close().wait(); - } -#endif - - TEST_FIXTURE(uri_address, extract_json) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // default encoding (Latin1) - json::value data = json::value::string(U("JSON string object")); - http_response rsp = - send_request_response(scoped.server(), &client, U("application/json"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - // us-ascii - rsp = send_request_response( - scoped.server(), &client, U("application/json; charset= us-AscIi"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - // Latin1 - rsp = send_request_response( - scoped.server(), &client, U("application/json;charset=iso-8859-1"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - // utf-8 - rsp = send_request_response( - scoped.server(), &client, U("application/json; charset = UTF-8"), to_utf8string((data.serialize()))); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - rsp = send_request_response(scoped.server(), &client, U(""), utility::string_t()); - auto str = rsp.to_string(); - // If there is no Content-Type in the response, make sure it won't throw when we ask for json - if (str.find(U("Content-Type")) == std::string::npos) - { - VERIFY_ARE_EQUAL(utility::string_t(U("null")), rsp.extract_json().get().serialize()); - } - -#ifdef _WIN32 - // utf-16le - auto utf16str = data.serialize(); - rsp = send_request_response(scoped.server(), &client, U("application/json; charset=utf-16le"), utf16str); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - // utf-16be - utf16string modified_data = data.serialize(); - modified_data = switch_endian_ness(modified_data); - rsp = send_request_response(scoped.server(), &client, U("application/json; charset=utf-16be"), modified_data); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - // utf-16 no BOM (utf-16be) - rsp = send_request_response(scoped.server(), &client, U("application/json; charset=utf-16"), modified_data); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - // utf-16 big endian BOM. - modified_data.insert(modified_data.begin(), U('\0')); - unsigned char* start = (unsigned char*)&modified_data[0]; - start[0] = 0xFE; - start[1] = 0xFF; - rsp = send_request_response(scoped.server(), &client, U("application/json; charset=utf-16"), modified_data); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - - // utf-16 little endian BOM. - modified_data = data.serialize(); - modified_data.insert(modified_data.begin(), U('\0')); - start = (unsigned char*)&modified_data[0]; - start[0] = 0xFF; - start[1] = 0xFE; - rsp = send_request_response(scoped.server(), &client, U("application/json; charset=utf-16"), modified_data); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); -#endif - - // unofficial JSON MIME types - rsp = send_request_response(scoped.server(), &client, U("text/json"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - rsp = send_request_response(scoped.server(), &client, U("text/x-json"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - rsp = send_request_response(scoped.server(), &client, U("text/javascript"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - rsp = send_request_response(scoped.server(), &client, U("text/x-javascript"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - rsp = send_request_response( - scoped.server(), &client, U("application/javascript"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - rsp = send_request_response( - scoped.server(), &client, U("application/x-javascript"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json().get().serialize()); - } - - TEST_FIXTURE(uri_address, extract_json_force) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - json::value data = json::value::string(U("JSON string object")); - http_response rsp = - send_request_response(scoped.server(), &client, U("bad charset"), to_utf8string(data.serialize())); - VERIFY_ARE_EQUAL(data.serialize(), rsp.extract_json(true).get().serialize()); - } - - TEST_FIXTURE(uri_address, extract_json_incorrect) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // with non matching content type. - json::value json_data = json::value::string(U("JSON string object")); - http_response rsp = send_request_response(scoped.server(), &client, U("bad guy"), json_data.serialize()); - VERIFY_THROWS(rsp.extract_json().get(), http_exception); - - // with unknown charset. - rsp = send_request_response( - scoped.server(), &client, U("application/json; charset=us-askjhcii"), json_data.serialize()); - VERIFY_THROWS(rsp.extract_json().get(), http_exception); - } - - TEST_FIXTURE(uri_address, set_stream_try_extract_json) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - http_request request(methods::GET); - streams::ostream responseStream = streams::bytestream::open_ostream<std::vector<uint8_t>>(); - request.set_response_stream(responseStream); - scoped.server()->next_request().then([](test_request* req) { - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = U("application/json"); - req->reply(status_codes::OK, U("OK"), headers, U("{true}")); - }); - - http_response response = client.request(request).get(); - VERIFY_THROWS(response.extract_json().get(), http_exception); - } - - TEST_FIXTURE(uri_address, extract_vector) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // textual content type - with unknown charset - std::string data("YOU KNOW ITITITITI"); - std::vector<unsigned char> vector_data; - std::for_each(data.begin(), data.end(), [&](char ch) { vector_data.push_back((unsigned char)ch); }); - http_response rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=unknown"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - - // textual type with us-ascii - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset= us-AscIi"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - - // textual type with Latin1 - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=iso-8859-1"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - - // textual type with utf-8 - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-8"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - - // textual type with utf-16le - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16LE"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - - // textual type with utf-16be - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=UTF-16be"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - - // textual type with utf-16 - rsp = send_request_response(scoped.server(), &client, U("text/plain; charset=utf-16"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - - // non textual content type - rsp = send_request_response(scoped.server(), &client, U("blah; charset=utf-16"), data); - VERIFY_ARE_EQUAL(vector_data, rsp.extract_vector().get()); - } - - TEST_FIXTURE(uri_address, set_stream_try_extract_vector) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - http_request request(methods::GET); - streams::ostream responseStream = streams::bytestream::open_ostream<std::vector<uint8_t>>(); - request.set_response_stream(responseStream); - scoped.server()->next_request().then([](test_request* req) { - std::map<utility::string_t, utility::string_t> headers; - headers[header_names::content_type] = U("text/plain"); - req->reply(status_codes::OK, U("OK"), headers, U("data")); - }); - - http_response response = client.request(request).get(); - VERIFY_THROWS(response.extract_vector().get(), http_exception); - } - - TEST_FIXTURE(uri_address, head_response) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - const method method = methods::HEAD; - const ::http::status_code code = status_codes::OK; - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - headers[U("Content-Length")] = U("100"); - scoped.server()->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, U("/")); - VERIFY_ARE_EQUAL(0u, p_request->reply(code, U(""), headers)); - }); - http_response rsp = client.request(method).get(); - VERIFY_ARE_EQUAL(0u, rsp.body().streambuf().in_avail()); - } - -} // SUITE(response_extract_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/response_stream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/response_stream_tests.cpp @@ -1,500 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * response_stream_tests.cpp - * - * Tests cases for covering receiving various responses as a stream with http_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -#ifndef __cplusplus_winrt -#include "cpprest/http_listener.h" -#endif - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -template<typename _CharType> -pplx::task<streams::streambuf<_CharType>> OPENSTR_R(const utility::string_t& name) -{ -#if !defined(__cplusplus_winrt) - return streams::file_buffer<_CharType>::open(name, std::ios_base::in); -#else - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))).get(); - - return streams::file_buffer<_CharType>::open(file, std::ios_base::in); -#endif -} - -template<typename _CharType> -pplx::task<Concurrency::streams::basic_ostream<_CharType>> OPENSTR_W(const utility::string_t& name, - std::ios_base::openmode mode = std::ios_base::out) -{ -#if !defined(__cplusplus_winrt) - return Concurrency::streams::file_stream<_CharType>::open_ostream(name, mode); -#else - auto file = pplx::create_task(KnownFolders::DocumentsLibrary->CreateFileAsync( - ref new Platform::String(name.c_str()), CreationCollisionOption::ReplaceExisting)) - .get(); - - return Concurrency::streams::file_stream<_CharType>::open_ostream(file, mode); -#endif -} -SUITE(response_stream_tests) -{ - TEST_FIXTURE(uri_address, set_response_stream_producer_consumer_buffer) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - p_server->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - p_request->reply(200, U(""), headers, "This is just a bit of a string"); - }); - - streams::producer_consumer_buffer<uint8_t> rwbuf; - auto ostr = streams::ostream(rwbuf); - - http_request msg(methods::GET); - msg.set_response_stream(ostr); - http_response rsp = client.request(msg).get(); - - rsp.content_ready().get(); - VERIFY_ARE_EQUAL(rwbuf.in_avail(), 30u); - - VERIFY_THROWS(rsp.extract_string().get(), http_exception); - - char chars[128]; - memset(chars, 0, sizeof(chars)); - - rwbuf.getn((unsigned char*)chars, rwbuf.in_avail()).get(); - VERIFY_ARE_EQUAL(0, strcmp("This is just a bit of a string", chars)); - } - - TEST_FIXTURE(uri_address, set_response_stream_container_buffer) - { - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - p_server->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - p_request->reply(200, U(""), headers, "This is just a bit of a string"); - }); - - { - streams::container_buffer<std::vector<uint8_t>> buf; - - http_request msg(methods::GET); - msg.set_response_stream(buf.create_ostream()); - http_response rsp = client.request(msg).get(); - - rsp.content_ready().get(); - VERIFY_ARE_EQUAL(buf.collection().size(), 30); - - char bufStr[31]; - memset(bufStr, 0, sizeof(bufStr)); - memcpy(&bufStr[0], &(buf.collection())[0], 30); - VERIFY_ARE_EQUAL(bufStr, "This is just a bit of a string"); - - VERIFY_THROWS(rsp.extract_string().get(), http_exception); - } - } - - TEST_FIXTURE(uri_address, response_stream_file_stream) - { - std::string message = "A world without string is chaos."; - - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - http_client client(m_uri); - - p_server->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - p_request->reply(200, U(""), headers, message); - }); - - { - auto fstream = OPENSTR_W<uint8_t>(U("response_stream.txt")).get(); - - // Write the response into the file - http_request msg(methods::GET); - msg.set_response_stream(fstream); - http_response rsp = client.request(msg).get(); - - rsp.content_ready().get(); - VERIFY_IS_TRUE(fstream.streambuf().is_open()); - fstream.close().get(); - - char chars[128]; - memset(chars, 0, sizeof(chars)); - - streams::rawptr_buffer<uint8_t> buffer(reinterpret_cast<uint8_t*>(chars), sizeof(chars)); - - streams::basic_istream<uint8_t> fistream = OPENSTR_R<uint8_t>(U("response_stream.txt")).get(); - VERIFY_ARE_EQUAL(message.length(), fistream.read_line(buffer).get()); - VERIFY_ARE_EQUAL(message, std::string(chars)); - fistream.close().get(); - } - } - - TEST_FIXTURE(uri_address, response_stream_file_stream_close_early) - { - // The test needs to be a little different between desktop and WinRT. - // In the latter case, the server will not see a message, and so the - // test will hang. In order to prevent that from happening, we will - // not have a server listening on WinRT. -#if !defined(__cplusplus_winrt) - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - - p_server->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - p_request->reply(200, U(""), headers, "A world without string is chaos."); - }); -#endif - - auto fstream = OPENSTR_W<uint8_t>(U("response_stream_file_stream_close_early.txt")).get(); - - http_client client(m_uri); - - http_request msg(methods::GET); - msg.set_response_stream(fstream); - fstream.close(std::make_exception_ptr(std::exception())).wait(); - - http_response resp; - - VERIFY_THROWS((resp = client.request(msg).get(), resp.content_ready().get()), std::exception); - } - - TEST_FIXTURE(uri_address, response_stream_large_file_stream) - { - // Send a 100 KB data in the response body, the server will send this in multiple chunks - // This data will get sent with content-length - const size_t workload_size = 100 * 1024; - utility::string_t fname(U("response_stream_large_file_stream.txt")); - std::string responseData; - responseData.resize(workload_size, 'a'); - - test_http_server::scoped_server scoped(m_uri); - test_http_server* p_server = scoped.server(); - - http_client client(m_uri); - - p_server->next_request().then([&](test_request* p_request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = U("text/plain"); - - p_request->reply(200, U(""), headers, responseData); - }); - - { - auto fstream = OPENSTR_W<uint8_t>(fname).get(); - - http_request msg(methods::GET); - msg.set_response_stream(fstream); - http_response rsp = client.request(msg).get(); - - rsp.content_ready().get(); - VERIFY_IS_TRUE(fstream.streambuf().is_open()); - fstream.close().get(); - - std::string rsp_string; - rsp_string.resize(workload_size, 0); - streams::rawptr_buffer<char> buffer(&rsp_string[0], rsp_string.size()); - streams::basic_istream<char> fistream = OPENSTR_R<char>(fname).get(); - - VERIFY_ARE_EQUAL(fistream.read_to_end(buffer).get(), workload_size); - VERIFY_ARE_EQUAL(rsp_string, responseData); - fistream.close().get(); - } - } - -#if !defined(__cplusplus_winrt) - - template<typename CharType> - class basic_throws_buffer : public streams::details::streambuf_state_manager<CharType> - { - public: - basic_throws_buffer() : streams::details::streambuf_state_manager<CharType>(std::ios_base::out) {} - - typedef typename streams::details::basic_streambuf<CharType>::int_type int_type; - typedef typename streams::details::basic_streambuf<CharType>::pos_type pos_type; - typedef typename streams::details::basic_streambuf<CharType>::off_type off_type; - - bool can_seek() const override { return true; } - bool has_size() const override { return false; } - size_t buffer_size(std::ios_base::openmode) const override { return 0; } - void set_buffer_size(size_t, std::ios_base::openmode) override {} - size_t in_avail() const override { return 0; } - pos_type getpos(std::ios_base::openmode) const override { return 0; } - pos_type seekpos(pos_type, std::ios_base::openmode) override { return 0; } - pos_type seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode) override { return 0; } - bool acquire(_Out_writes_(count) CharType*&, _In_ size_t&) override { return false; } - void release(_Out_writes_(count) CharType*, _In_ size_t) override {} - - protected: - pplx::task<int_type> _putc(CharType) override { throw std::runtime_error("error"); } - pplx::task<size_t> _putn(const CharType*, size_t) override { throw std::runtime_error("error"); } - pplx::task<int_type> _bumpc() override { throw std::runtime_error("error"); } - int_type _sbumpc() override { throw std::runtime_error("error"); } - pplx::task<int_type> _getc() override { throw std::runtime_error("error"); } - int_type _sgetc() override { throw std::runtime_error("error"); } - pplx::task<int_type> _nextc() override { throw std::runtime_error("error"); } - pplx::task<int_type> _ungetc() override { throw std::runtime_error("error"); } - pplx::task<size_t> _getn(_Out_writes_(count) CharType*, _In_ size_t) override - { - throw std::runtime_error("error"); - } - size_t _scopy(_Out_writes_(count) CharType*, _In_ size_t) override { throw std::runtime_error("error"); } - pplx::task<bool> _sync() override { throw std::runtime_error("error"); } - CharType* _alloc(size_t) override { throw std::runtime_error("error"); } - void _commit(size_t) override { throw std::runtime_error("error"); } - - pplx::task<void> _close_write() override - { - return pplx::task_from_exception<void>(std::invalid_argument("test")); - } - }; - - template<typename CharType> - class close_throws_buffer : public streams::streambuf<CharType> - { - public: - close_throws_buffer() - : streams::streambuf<CharType>( - std::shared_ptr<basic_throws_buffer<CharType>>(new basic_throws_buffer<CharType>())) - { - } - }; - - // Tests if an exception occurs and close throws an exception that the close - // one is ignored and doesn't bring down the process. - TEST_FIXTURE(uri_address, response_stream_close_throws_with_exception) - { - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - - streams::producer_consumer_buffer<uint8_t> buf; - - listener.support([buf](http_request request) { - http_response response(200); - response.set_body(streams::istream(buf), U("text/plain")); - response.headers().add(header_names::connection, U("close")); - request.reply(response); - }); - - http_client_config config; - config.set_timeout(utility::seconds(1)); - http_client client(m_uri, config); - - close_throws_buffer<uint8_t> responseBody; - http_request msg(methods::GET); - msg.set_response_stream(responseBody.create_ostream()); - http_response rsp = client.request(msg).get(); - VERIFY_THROWS(rsp.content_ready().get(), http_exception); - - buf.close(std::ios_base::out).wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, content_ready) - { - http_client client(m_uri); - std::string responseData("Hello world"); - - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - listener.support([responseData](http_request request) { - streams::producer_consumer_buffer<uint8_t> buf; - http_response response(200); - response.set_body(buf.create_istream(), U("text/plain")); - response.headers().add(header_names::connection, U("close")); - - request.reply(response); - - VERIFY_ARE_EQUAL(buf.putn_nocopy((const uint8_t*)responseData.data(), responseData.size()).get(), - responseData.size()); - buf.close(std::ios_base::out).get(); - }); - - { - http_request msg(methods::GET); - http_response rsp = client.request(msg).get().content_ready().get(); - - auto extract_string_task = rsp.extract_string(); - VERIFY_ARE_EQUAL(extract_string_task.get(), ::utility::conversions::to_string_t(responseData)); - rsp.content_ready().wait(); - } - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, xfer_chunked_with_length) - { - http_client client(m_uri); - utility::string_t responseData(U("Hello world")); - - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - listener.support([responseData](http_request request) { - http_response response(200); - - // This sets the content_length - response.set_body(responseData); - - // overwrite content_length to 0 - response.headers().add(header_names::content_length, 0); - - // add chunked transfer encoding - response.headers().add(header_names::transfer_encoding, U("chunked")); - - // add connection=close header, connection SHOULD NOT be considered persistent' after the current - // request/response is complete - response.headers().add(header_names::connection, U("close")); - - // respond - request.reply(response); - }); - - { - http_request msg(methods::GET); - http_response rsp = client.request(msg).get(); - - auto rsp_string = rsp.extract_string().get(); - VERIFY_ARE_EQUAL(rsp_string, responseData); - } - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, get_resp_stream) - { - http_client client(m_uri); - std::string responseData("Hello world"); - - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - listener.support([responseData](http_request request) { - streams::producer_consumer_buffer<uint8_t> buf; - - http_response response(200); - response.set_body(buf.create_istream(), U("text/plain")); - response.headers().add(header_names::connection, U("close")); - request.reply(response); - - VERIFY_ARE_EQUAL(buf.putn_nocopy((const uint8_t*)responseData.data(), responseData.size()).get(), - responseData.size()); - buf.close(std::ios_base::out).get(); - }); - - { - http_request msg(methods::GET); - http_response rsp = client.request(msg).get(); - - streams::stringstreambuf data; - - auto t = rsp.body().read_to_delim(data, (uint8_t)(' ')); - - t.then([&data](size_t size) { - VERIFY_ARE_EQUAL(size, 5); - auto s = data.collection(); - VERIFY_ARE_EQUAL(s, std::string("Hello")); - }) - .wait(); - rsp.content_ready().wait(); - } - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, xfer_chunked_multiple_chunks) - { - // With chunked transfer-encoding, send 2 chunks of different sizes in the response - http_client client(m_uri); - - // Send two chunks, note: second chunk is bigger than the first. - std::string firstChunk("abcdefghijklmnopqrst"); - std::string secondChunk("abcdefghijklmnopqrstuvwxyz"); - - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - listener.support([firstChunk, secondChunk](http_request request) { - streams::producer_consumer_buffer<uint8_t> buf; - - http_response response(200); - response.set_body(buf.create_istream(), U("text/plain")); - response.headers().add(header_names::connection, U("close")); - request.reply(response); - - VERIFY_ARE_EQUAL(buf.putn_nocopy((const uint8_t*)firstChunk.data(), firstChunk.size()).get(), - firstChunk.size()); - buf.sync().get(); - VERIFY_ARE_EQUAL(buf.putn_nocopy((const uint8_t*)secondChunk.data(), secondChunk.size()).get(), - secondChunk.size()); - buf.close(std::ios_base::out).get(); - }); - - { - utility::string_t fname(U("xfer_chunked_multiple_chunks.txt")); - auto fstream = OPENSTR_W<uint8_t>(fname).get(); - - http_request msg(methods::GET); - msg.set_response_stream(fstream); - http_response rsp = client.request(msg).get(); - - rsp.content_ready().wait(); - VERIFY_IS_TRUE(fstream.streambuf().is_open()); - fstream.close().get(); - - std::string rsp_string; - size_t workload_size = firstChunk.size() + secondChunk.size(); - rsp_string.resize(workload_size, 0); - streams::rawptr_buffer<uint8_t> buffer(reinterpret_cast<uint8_t*>(&rsp_string[0]), rsp_string.size()); - streams::basic_istream<uint8_t> fistream = OPENSTR_R<uint8_t>(fname).get(); - - VERIFY_ARE_EQUAL(fistream.read_to_end(buffer).get(), workload_size); - VERIFY_ARE_EQUAL(rsp_string, firstChunk + secondChunk); - fistream.close().get(); - } - - listener.close().wait(); - } - -#endif - -} // SUITE(responses) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/status_code_reason_phrase_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/status_code_reason_phrase_tests.cpp @@ -1,54 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * status_code_reason_phrase_tests.cpp - * - * Tests cases for covering HTTP status codes and reason phrases. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(status_code_reason_phrase_tests) -{ - TEST_FIXTURE(uri_address, status_code) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - // custom status code. - test_server_utilities::verify_request(&client, methods::GET, U("/"), scoped.server(), 666); - } - - TEST_FIXTURE(uri_address, reason_phrase) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - - test_server_utilities::verify_request( - &client, methods::GET, U("/"), scoped.server(), status_codes::OK, U("Reasons!!")); - } - -} // SUITE(status_code_reason_phrase_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/stdafx.cpp @@ -1,14 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" - -#if WIN32 -__declspec(dllexport) int httpclient_test_generate_lib = 0; -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/stdafx.h @@ -1,24 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/containerstream.h" -#include "cpprest/filestream.h" -#include "cpprest/http_client.h" -#include "cpprest/producerconsumerstream.h" -#include "cpprest/rawptrstream.h" -#include "http_client_tests.h" -#include "http_test_utilities.h" -#include "os_utilities.h" -#include "timeout_handler.h" -#include "unittestpp.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/timeout_handler.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/timeout_handler.h @@ -1,57 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Simple utility for handling timeouts with http client test cases. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/http_client.h" - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -// helper function to check if failure is due to timeout. -inline bool is_timeout(const std::string& msg) -{ - if (msg.find("The operation timed out") != std::string::npos /* WinHTTP */ || - msg.find("The operation was timed out") != std::string::npos /* IXmlHttpRequest2 */) - { - return true; - } - return false; -} - -template<typename Func> -void handle_timeout(const Func& f) -{ - try - { - f(); - } - catch (const web::http::http_exception& e) - { - if (is_timeout(e.what())) - { - // Since this test depends on an outside server sometimes it sporadically can fail due to timeouts - // especially on our build machines. - return; - } - throw; - } -} - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/to_string_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/client/to_string_tests.cpp @@ -1,133 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for to_string APIs on HTTP request and responses. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; -using namespace web::http; -using namespace web::http::client; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace client -{ -SUITE(to_string_tests) -{ - TEST_FIXTURE(uri_address, request_to_string_without_body) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const method mtd = methods::GET; - const utility::string_t path = U("/pathbaby/"); - const utility::string_t content_type = U("text/plain; charset= utf-8"); - - // to_string - http_request msg(mtd); - msg.set_request_uri(path); - msg.headers()[U("Content-Type")] = content_type; - - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[U("Content-Type")] = content_type; - http_asserts::assert_request_string_equals(msg.to_string(), mtd, path, U("HTTP/1.1"), expected_headers, U("")); - } - - TEST_FIXTURE(uri_address, request_to_string_with_body) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const method mtd = methods::POST; - const utility::string_t path = U("/path baby/"); - const utility::string_t content_type = U("text/plain;charset=utf-8"); - const utility::string_t body = U("YES THIS IS THE MSG BODY!!!!!"); - - // to_string - http_request msg(mtd); - msg.set_request_uri(uri::encode_uri(path, uri::components::path)); - msg.headers()[U("Content-Type")] = content_type; - msg.set_body(body); - - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[U("Content-Type")] = content_type; - expected_headers[U("Content-Length")] = U("29"); - http_asserts::assert_request_string_equals( - msg.to_string(), mtd, U("/path%20baby/"), U("HTTP/1.1"), expected_headers, body); - } - - TEST_FIXTURE(uri_address, response_to_string_without_body) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const web::http::status_code code = status_codes::OK; - const utility::string_t reason = U("OK YEAH!"); - const utility::string_t content_type = U("not; charset= utf-8"); - - // to_string - scoped.server()->next_request().then([&](test_request* request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = content_type; - request->reply(code, reason, headers); - }); - http_response rsp = client.request(methods::GET).get(); - - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[U("Content-Length")] = U("0"); - expected_headers[U("Content-Type")] = content_type; - http_asserts::assert_response_string_equals( - rsp.to_string(), U("HTTP/1.1"), code, U("OK"), expected_headers, U("")); - -#ifdef _WIN32 - // Don't verify the values of each of these headers, but make sure they exist. - if (!rsp.headers().has(U("Date")) || !rsp.headers().has(U("Cache-Control")) || !rsp.headers().has(U("Server"))) - { - CHECK(false); - } -#endif - } - - TEST_FIXTURE(uri_address, response_to_string_with_body) - { - test_http_server::scoped_server scoped(m_uri); - http_client client(m_uri); - const ::http::status_code code = status_codes::OK; - const utility::string_t reason = U("OK YEAH!"); - const std::string data = "HERE IS THE RESPONSE body!"; - const utility::string_t content_type = U("text/yeah;charset=utf-8"); - - // to_string - scoped.server()->next_request().then([&](test_request* request) { - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = content_type; - request->reply(code, reason, headers, data); - }); - - http_response rsp = client.request(methods::GET).get(); - rsp.content_ready().wait(); - - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[U("Content-Length")] = U("26"); - expected_headers[U("Content-Type")] = content_type; - http_asserts::assert_response_string_equals( - rsp.to_string(), U("HTTP/1.1"), code, U("OK"), expected_headers, ::utility::conversions::to_string_t(data)); - } - -} // SUITE(to_string_tests) - -} // namespace client -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/CMakeLists.txt @@ -1,26 +0,0 @@ -if(NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) - set (SOURCES - building_response_tests.cpp - connections_and_errors.cpp - header_tests.cpp - listener_construction_tests.cpp - reply_helper_tests.cpp - request_extract_tests.cpp - request_handler_tests.cpp - request_relative_uri_tests.cpp - request_stream_tests.cpp - requests_tests.cpp - response_stream_tests.cpp - status_code_reason_phrase_tests.cpp - to_string_tests.cpp - ) - - add_casablanca_test(httplistener_test SOURCES) - if(TEST_LIBRARY_TARGET_TYPE STREQUAL "OBJECT") - target_include_directories(httplistener_test PRIVATE ../utilities/include) - else() - target_link_libraries(httplistener_test PRIVATE httptest_utilities) - endif() - - configure_pch(httplistener_test stdafx.h stdafx.cpp) -endif() diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/building_response_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/building_response_tests.cpp @@ -1,154 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * building_response_tests.cpp - * - * Tests cases for manually building up HTTP responses with http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(building_response_tests) -{ - TEST_FIXTURE(uri_address, set_body_with_content_type) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - http_response response(status_codes::OK); - response.set_body(U("test string"), U("text")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { -#ifdef _UTF16_STRINGS - const ::utility::string_t expectedContentType(U("text; charset=utf-8")); -#else - const ::utility::string_t expectedContentType(U("text")); -#endif - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, expectedContentType, U("test string")); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, set_body_without_content_type) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([&](http_request request) { - http_response response(status_codes::OK); - response.set_body(U("test string")); - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("text/plain; charset=utf-8"), U("test string")); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, set_body_string) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - http_response response(status_codes::OK); - utility::string_t data(U("test data")); - response.set_body(std::move(data)); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("text/plain; charset=utf-8"), U("test data")); - }) - .wait(); - - listener.close().wait(); - } - - TEST(set_body_string_with_charset) - { - http_response response; - VERIFY_THROWS(response.set_body(::utility::conversions::to_utf16string("body_data"), - ::utility::conversions::to_utf16string("text/plain;charset=utf-16")), - std::invalid_argument); - } - - TEST_FIXTURE(uri_address, set_body_vector) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - http_response response(status_codes::OK); - std::vector<unsigned char> v_body; - v_body.push_back('A'); - v_body.push_back('B'); - v_body.push_back('C'); - response.set_body(std::move(v_body)); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("application/octet-stream"), U("ABC")); - }) - .wait(); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/connections_and_errors.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/connections_and_errors.cpp @@ -1,420 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * connections_and_errors.cpp - * - * Tests cases the underlying connections and error cases with the connection using then http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include <cpprest/http_client.h> - -// For single_core test case. -#if defined(_WIN32) && _MSC_VER < 1900 -#include <concrt.h> -#endif - -using namespace utility; -using namespace web; -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(connections_and_errors) -{ - TEST_FIXTURE(uri_address, close_listener_race, "Ignore", "825350") - { - ::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - - listener.support([](http_request) { - // Let the connection timeout - }); - - // close() racing with a new connection - auto closeTask = pplx::create_task([&listener]() { listener.close().wait(); }); - - auto clientTask = pplx::create_task([this] { - ::http::client::http_client_config config; - config.set_timeout(utility::seconds(1)); - ::http::client::http_client client(m_uri, config); - - try - { - // Depending on timing this might not succeed. The - // exception will be caught and ignored below - auto rsp = client.request(methods::GET).get(); - - // The response body should timeout and we should recieve an exception - rsp.content_ready().wait(); - - // If we reach here then it is an error - VERIFY_IS_FALSE(true); - } - catch (std::exception) - { - } - }); - - (closeTask && clientTask).wait(); - } - - // Note: Run with admin privileges to listen on default port. - // This test will fail with "Access denied: attempting to add Address.." exception if it is not run as admin. - TEST(default_port_close, "Ignore", "Manual") - { - uri address(U("http://localhost/portnotspecified")); - http_listener listener(address); - - try - { - listener.open().wait(); - } - catch (const http_exception& ex) - { - VERIFY_IS_FALSE(true, ex.what()); - return; - } - - // Verify close does not throw an exception while listening on default port - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, send_response_later) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - std::vector<http_request> requests; - pplx::extensibility::event_t request_event; - listener.support([&](http_request r) { - requests.push_back(r); - request_event.set(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - request_event.wait(); - requests[0].reply(status_codes::OK, "HEHEHE").wait(); - requests.clear(); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("text/plain; charset=utf-8"), U("HEHEHE")); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, save_request_reply) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - http_request request; - pplx::extensibility::event_t request_event; - listener.support([&](http_request r) { - request = r; - request_event.set(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - request_event.wait(); - request.reply(status_codes::OK).wait(); - - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - listener.close().wait(); - } - -#if defined(_WIN32) && _MSC_VER < 1900 - TEST_FIXTURE(uri_address, single_core_request) - { - // Fake having a scheduler with only 1 core. - concurrency::CurrentScheduler::Create( - concurrency::SchedulerPolicy(2, 1, Concurrency::MinConcurrency, 1, Concurrency::MaxConcurrency)); - - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([](http_request request) { request.reply(status_codes::OK).get(); }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - - // Don't wait on the task otherwise it could inline allowing other tasks to run on the scheduler. - std::atomic_flag responseEvent = ATOMIC_FLAG_INIT; - responseEvent.test_and_set(); - p_client->next_response().then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - responseEvent.clear(); - }); - while (responseEvent.test_and_set()) - { - } - - listener.close().wait(); - - concurrency::CurrentScheduler::Detach(); - } -#endif - - TEST_FIXTURE(uri_address, save_request_response) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - http_request request; - pplx::extensibility::event_t request_event; - listener.support([&](http_request r) { - request = r; - request_event.set(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - request_event.wait(); - http_response response(status_codes::OK); - request.reply(response).wait(); - - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, reply_twice) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([](http_request request) { - request.reply(status_codes::OK); - VERIFY_THROWS(request.reply(status_codes::Accepted).get(), http_exception); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - // This test case is manual becuase it requires to be run under and account without admin access. - TEST(default_port_admin_access, "Ignore", "Manual") - { - uri address(U("http://localhost/")); - http_listener listener(address); - VERIFY_THROWS(listener.open().wait(), http_exception); - } - - TEST_FIXTURE(uri_address, try_port_already_in_use, "Ignore:Linux", "Bug 879077", "Ignore:Apple", "Bug 879077") - { - test_http_server::scoped_server scoped(m_uri); - http_listener listener(m_uri); - VERIFY_THROWS(listener.open().wait(), http_exception); - } - - TEST_FIXTURE(uri_address, reply_after_starting_close, "Ignore", "901808") - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([&](http_request request) { - // Start closing the listener and then send reply. - listener.close(); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path"))); - - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - } - - static void close_stream_early_with_length_impl(const uri& u, bool useException) - { - http_listener listener(u); - listener.open().wait(); - listener.support([=](http_request request) { - concurrency::streams::producer_consumer_buffer<unsigned char> body; - concurrency::streams::istream instream = body.create_istream(); - body.putc('A').wait(); - body.putc('B').wait(); - auto responseTask = request.reply(status_codes::OK, instream, 4); - - if (useException) - { - body.close(std::ios::out, std::make_exception_ptr(std::invalid_argument("test exception"))).wait(); - VERIFY_THROWS(responseTask.get(), std::invalid_argument); - } - else - { - body.close(std::ios::out).wait(); - VERIFY_THROWS(responseTask.get(), http_exception); - } - }); - - web::http::client::http_client client(u); - client.request(methods::GET, U("/path")) - .then([](http_response response) -> pplx::task<std::vector<unsigned char>> { - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - return response.extract_vector(); - }) - .then( - [=](pplx::task<std::vector<unsigned char>> bodyTask) { VERIFY_THROWS(bodyTask.get(), http_exception); }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, close_stream_early_with_length) - { - close_stream_early_with_length_impl(m_uri, true); - close_stream_early_with_length_impl(m_uri, false); - } - - static void close_stream_early_impl(const uri& u, bool useException) - { - http_listener listener(u); - listener.open().wait(); - listener.support([=](http_request request) { - concurrency::streams::producer_consumer_buffer<unsigned char> body; - concurrency::streams::istream instream = body.create_istream(); - body.putc('A').wait(); - body.putc('B').wait(); - auto responseTask = request.reply(status_codes::OK, instream); - - if (useException) - { - body.close(std::ios::out, std::make_exception_ptr(std::invalid_argument("test exception"))).wait(); - VERIFY_THROWS(responseTask.get(), std::invalid_argument); - } - else - { - body.close(std::ios::out).wait(); - responseTask.get(); - } - }); - - web::http::client::http_client client(u); - client.request(methods::GET, U("/path")) - .then([](http_response response) -> pplx::task<std::vector<unsigned char>> { - VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); - return response.extract_vector(); - }) - .then([=](pplx::task<std::vector<unsigned char>> bodyTask) { - if (useException) - { - VERIFY_THROWS(bodyTask.get(), http_exception); - } - else - { - std::vector<unsigned char> body = bodyTask.get(); - VERIFY_ARE_EQUAL(2, body.size()); - VERIFY_ARE_EQUAL('A', body[0]); - VERIFY_ARE_EQUAL('B', body[1]); - } - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, close_stream_with_exception) - { - close_stream_early_impl(m_uri, true); - close_stream_early_impl(m_uri, false); - } - - // Helper function to verify http_exception and return the error code value. - template<typename Func> - int verify_http_exception(Func f) - { - int errorCode = 0; - try - { - f(); - VERIFY_IS_TRUE(false); - } - catch (const http_exception& e) - { - errorCode = e.error_code().value(); - } - return errorCode; - } - - TEST_FIXTURE(uri_address, - request_content_ready_timeout, - "Ignore:Linux", - "Unsuitable until 813276", - "Ignore:Apple", - "Unsuitable until 813276") - { -#if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) - throw std::runtime_error( - "Unsuitable until 813276 -- http_listener on ASIO does not support timeouts nor chunk sizes"); -#endif - http_listener_config config; - config.set_timeout(utility::seconds(1)); - http_listener listener(m_uri, config); - pplx::extensibility::event_t timedOutEvent; - listener.support([&](http_request req) { - const int e1 = verify_http_exception([=]() { req.content_ready().wait(); }); - const int e2 = verify_http_exception([=]() { req.body().read().wait(); }); - const int e3 = verify_http_exception([=]() { req.reply(status_codes::OK).wait(); }); - VERIFY_ARE_EQUAL(e1, e2); - VERIFY_ARE_EQUAL(e2, e3); - timedOutEvent.set(); - }); - listener.open().wait(); - - // Using our production http_client here because it - // allows separation of sending headers and body. - ::web::http::client::http_client client(m_uri); - concurrency::streams::producer_consumer_buffer<unsigned char> body; - auto responseTask = client.request(methods::PUT, U(""), body.create_istream()); - timedOutEvent.wait(); - body.close().wait(); - VERIFY_THROWS(responseTask.get(), http_exception); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/header_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/header_tests.cpp @@ -1,227 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * header_tests.cpp - * - * Tests cases for using HTTP requests/response headers with http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(header_tests) -{ - TEST_FIXTURE(uri_address, request_headers) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - const utility::string_t mtd = methods::GET; - std::map<utility::string_t, utility::string_t> headers; - - // single header value. - headers[U("Header1")] = U("Value1"); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, mtd, U("/"), headers); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(mtd, U(""), headers)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // empty header value. - headers.clear(); - headers[U("Key1")] = U(""); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, mtd, U("/"), headers); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(mtd, U(""), headers)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // 10 headers. - headers.clear(); - headers[U("MyHeader")] = U("hehe;blach"); - headers[U("Yo1")] = U("You, Too"); - headers[U("Yo2")] = U("You2"); - headers[U("Yo3")] = U("You3"); - headers[U("Yo4")] = U("You4"); - headers[U("Yo5")] = U("You5"); - headers[U("Yo6")] = U("You6"); - headers[U("Yo7")] = U("You7"); - headers[U("Yo8")] = U("You8"); - headers[U("Yo9")] = U("You9"); - headers[U("Yo10")] = U("You10"); - headers[U("Yo11")] = U("You11"); - headers[U("Accept")] = U("text/plain"); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, mtd, U("/"), headers); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(mtd, U(""), headers)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // several headers different casings. - headers.clear(); - headers[U("CUSTOMHEADER")] = U("value1"); - headers[U("customHEADER")] = U("value2"); - headers[U("CUSTOMheaDER")] = U("value3"); - listener.support([&](http_request request) { - std::map<utility::string_t, utility::string_t> h; - h[U("CUSTOMHEADER")] = U("value1, value3, value2"); - http_asserts::assert_request_equals(request, mtd, U("/"), h); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(mtd, U(""), headers)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, request_known_headers) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - const utility::string_t mtd = methods::GET; - std::map<utility::string_t, utility::string_t> headers; - - // "Date" was being incorrectly mapped to "Data" - // see https://github.com/microsoft/cpprestsdk/issues/1208 - headers[U("Date")] = U("Mon, 29 Jul 2019 12:32:57 GMT"); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, mtd, U("/"), headers); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(mtd, U(""), headers)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, response_headers) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // No http_request/response classes can be around for close to complete. - { - // header with empty value - http_response response(status_codes::OK); - response.headers()[U("Key1")] = U(""); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK, response.headers()); - }) - .wait(); - - // 10 headers - response = http_response(status_codes::Accepted); - response.headers()[U("MyHeader")] = U("hehe;blach"); - response.headers()[U("Yo1")] = U("You, Too"); - response.headers()[U("Yo2")] = U("You2"); - response.headers()[U("Yo3")] = U("You3"); - response.headers()[U("Yo4")] = U("You4"); - response.headers()[U("Yo5")] = U("You5"); - response.headers()[U("Yo6")] = U("You6"); - response.headers()[U("Yo7")] = U("You7"); - response.headers()[U("Yo8")] = U("You8"); - response.headers()[U("Yo9")] = U("You9"); - response.headers()[U("Yo10")] = U("You10"); - response.headers()[U("Yo11")] = U("You11"); - response.headers()[U("Accept")] = U("text/plain"); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Accepted, response.headers()); - }) - .wait(); - - // several headers in different casings - response = http_response(status_codes::BadGateway); - response.headers().add(U("Key1"), U("value1")); - response.headers()[U("KEY1")] += U("value2"); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::BadGateway, response.headers()); - }) - .wait(); - - // duplicate headers fields - response = http_response(status_codes::BadGateway); - response.headers().add(U("Key1"), U("value1")); - response.headers().add(U("Key1"), U("value2")); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::BadGateway, response.headers()); - }) - .wait(); - } - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/http_listener_tests.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/http_listener_tests.h @@ -1,49 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * http_listener_tests.h - * - * Common declarations and helper functions for http_listener test cases. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/http_listener.h" - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -class uri_address -{ -public: - uri_address() : m_uri(U("http://localhost:34567/")), m_secure_uri(U("https://localhost:8443/")) - { - if (!s_dummy_listener) - s_dummy_listener = - std::make_shared<web::http::experimental::listener::http_listener>(U("http://localhost:30000/")); - } - - // By introducing an additional listener, we can avoid having to close the - // server after each unit test. - - static std::shared_ptr<web::http::experimental::listener::http_listener> s_dummy_listener; - web::http::uri m_uri; - web::http::uri m_secure_uri; -}; - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/listener_construction_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/listener_construction_tests.cpp @@ -1,576 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * listener_construction_tests.cpp - * - * Tests cases for covering creating http_listeners in various ways. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(listener_construction_tests) -{ - TEST_FIXTURE(uri_address, default_constructor) - { - // Test that the default ctor works. - http_listener listener; - - VERIFY_IS_TRUE(listener.uri().is_empty()); - VERIFY_THROWS(listener.open().wait(), std::invalid_argument); - } - - TEST_FIXTURE(uri_address, move_operations) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // move constructor - http_listener listener2 = std::move(listener); - listener2.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, U("PUT"), U("/")); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(U("PUT"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // move assignment - listener = std::move(listener2); - listener.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, U("PUT"), U("/")); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(U("PUT"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, various_uris) - { - http_listener listener(web::http::uri_builder(m_uri).append_path(U("path1")).to_uri()); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Path that matches exactly - listener.support([](http_request request) { - http_asserts::assert_request_equals(request, U("GET"), U("")); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // Path that matches but is more specific. - listener.support([](http_request request) { - http_asserts::assert_request_equals(request, U("GET"), U("/path2")); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1/path2"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // Try a request with a path that doesn't match. - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path3/path2"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NotFound); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, uri_routing) - { - http_listener listener1(web::http::uri_builder(m_uri).append_path(U("path1")).to_uri()); - http_listener listener2(web::http::uri_builder(m_uri).append_path(U("path2")).to_uri()); - http_listener listener3(web::http::uri_builder(m_uri).append_path(U("path1/path2")).to_uri()); - - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Path that matches exactly - listener1.support([](http_request request) { request.reply(status_codes::OK); }); - listener1.open().wait(); - - listener2.support([](http_request request) { request.reply(status_codes::Created); }); - listener2.open().wait(); - - listener3.support([](http_request request) { request.reply(status_codes::Accepted); }); - listener3.open().wait(); - - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path2"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Created); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1/path2"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Accepted); - }) - .wait(); - - // Try a request with a path that doesn't match. - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path3/path2"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NotFound); - }) - .wait(); - - listener1.close().wait(); - listener2.close().wait(); - listener3.close().wait(); - } - - TEST_FIXTURE(uri_address, uri_error_cases) - { - // non HTTP scheme - VERIFY_THROWS(http_listener(U("ftp://localhost:456/")), std::invalid_argument); - - // empty HTTP host - VERIFY_THROWS(http_listener(U("http://:456/")), std::invalid_argument); - - // try specifying a query - VERIFY_THROWS(http_listener(U("http://localhost:45678/path?key1=value")), std::invalid_argument); - - // try specifing a fragment - VERIFY_THROWS(http_listener(U("http://localhost:4563/path?key1=value#frag")), std::invalid_argument); - } - - TEST_FIXTURE(uri_address, create_listener_get) - { - http_listener listener(m_uri); - - listener.support(methods::GET, [](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - request.reply(status_codes::OK); - }); - - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::MethodNotAllowed); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, create_listener_get_put) - { - http_listener listener(m_uri); - - listener.support(methods::GET, [](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - request.reply(status_codes::OK); - }); - - listener.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, methods::PUT, U("/")); - request.reply(status_codes::OK); - }); - - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::MethodNotAllowed); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, create_listener_get_put_post) - { - http_listener listener(m_uri); - - listener.support(methods::GET, [](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - request.reply(status_codes::OK); - }); - - listener.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, methods::PUT, U("/")); - request.reply(status_codes::OK); - }); - - listener.support(methods::POST, [](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(status_codes::OK); - }); - - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::DEL, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::MethodNotAllowed); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, create_listener_get_put_post_delete) - { - http_listener listener(m_uri); - - listener.support(methods::GET, [](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - request.reply(status_codes::OK); - }); - - listener.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, methods::PUT, U("/")); - request.reply(status_codes::OK); - }); - - listener.support(methods::POST, [](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(status_codes::OK); - }); - - listener.support(methods::DEL, [](http_request request) { - http_asserts::assert_request_equals(request, methods::DEL, U("/")); - request.reply(status_codes::OK); - }); - - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::DEL, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::HEAD, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::MethodNotAllowed); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, get_listener_config) - { - // Verify default configuration. - { - http_listener listener(m_uri); - VERIFY_ARE_EQUAL(utility::seconds(120), listener.configuration().timeout()); - listener.open().wait(); - listener.close().wait(); - } - - // Verify specified config values. - { - http_listener_config config; - utility::seconds t(1); - config.set_timeout(t); - http_listener listener(m_uri, config); - listener.open().wait(); - listener.close().wait(); - VERIFY_ARE_EQUAL(t, listener.configuration().timeout()); - } - } - - TEST_FIXTURE(uri_address, listener_config_creation) - { - // copy constructor - { - http_listener_config config; - config.set_timeout(utility::seconds(2)); - http_listener_config copy(config); - VERIFY_ARE_EQUAL(utility::seconds(2), copy.timeout()); - } - - // move constructor - { - http_listener_config config; - config.set_timeout(utility::seconds(2)); - http_listener_config ctorMove(std::move(config)); - VERIFY_ARE_EQUAL(utility::seconds(2), ctorMove.timeout()); - } - - // assignment - { - http_listener_config config; - config.set_timeout(utility::seconds(2)); - http_listener_config assign; - assign = config; - VERIFY_ARE_EQUAL(utility::seconds(2), assign.timeout()); - } - - // move assignment - { - http_listener_config config; - config.set_timeout(utility::seconds(2)); - http_listener_config assignMove; - assignMove = std::move(config); - VERIFY_ARE_EQUAL(utility::seconds(2), assignMove.timeout()); - } - } - -#if !defined(_WIN32) && !defined(__cplusplus_winrt) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) - - TEST_FIXTURE(uri_address, create_https_listener_get, "Ignore", "github 209") - { - const char* self_signed_cert = R"( ------BEGIN CERTIFICATE----- -MIIDlzCCAn+gAwIBAgIJAP9ZV+1X94UjMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNV -BAYTAkNOMQswCQYDVQQIDAJTSDELMAkGA1UEBwwCU0gxEjAQBgNVBAoMCU1JQ1JP -U09GVDERMA8GA1UECwwISFBDLVBBQ0sxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0x -NTA4MTkwOTA0MjhaFw00MzAxMDMwOTA0MjhaMGIxCzAJBgNVBAYTAkNOMQswCQYD -VQQIDAJTSDELMAkGA1UEBwwCU0gxEjAQBgNVBAoMCU1JQ1JPU09GVDERMA8GA1UE -CwwISFBDLVBBQ0sxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBALLv7AAPa+4wYpa+3tqc9HIHhh8kv/MpV2Dm+oKG27iH -zOugMNAPqLzMAaWCzDRyw27I+jPS3pzAAu6rQ0v2H6XNrie1YEEV27j1WOUS9iFy -vcf6Y+ywUKXvFlN/VM/ZFz9Z8U3jc7Y6unIyoUs8UdX/RRITspb2m7SUxlmLJ+4c -qiLrHwstNB2NHIZN72oc8DaS5eBqBdT9h6NO62RSBTrAlR7Vk9eU/5trYkd5+PoC -pispvU+7Fe24uVerGgU6Yoyd7DMj+3BpbG3g/VkOlGhgH0DNtbKu3v/XOmnzdZn6 -dzoOoGFNpG1NeH2Xv0vnvEZP6WG4h/TFSafBJMONNnMCAwEAAaNQME4wHQYDVR0O -BBYEFO1mAjAmLk1J0iT93xfczAE5mxgzMB8GA1UdIwQYMBaAFO1mAjAmLk1J0iT9 -3xfczAE5mxgzMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAFB8AACf -5O+sPe3PZ8IPgwZb+BCXdoXc2rngR/gOaYO019TZyNLuHRzW9FtplzW25IbQ9Jnc -b+jmY2Ill7Zf3TX4OhHEwscJ1G2LBaqZfQlwSbYJmCzvRNSzSbF3RigNQD5Qhdph -vVBdvVGTZnVeatjTOFKUyfhcXf4DMb6eMfaU6il/VJCSMW0j3hYNQjPm3V/PLxnG -fd9T4hpCUd8MK2XG4RqJAzh6x/6v0fc6mRHBS5+qTWYSDGFwITrU1pP2L9qFegpm -aNAom7bdENU8uivd+vrLnG2fKvFSssjVfaXpFLKAICfTJY9A3/CWnZ1AcbE5El7A -adctopihoUrlAb0= ------END CERTIFICATE----- - )"; - const char* private_key = R"( ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCy7+wAD2vuMGKW -vt7anPRyB4YfJL/zKVdg5vqChtu4h8zroDDQD6i8zAGlgsw0csNuyPoz0t6cwALu -q0NL9h+lza4ntWBBFdu49VjlEvYhcr3H+mPssFCl7xZTf1TP2Rc/WfFN43O2Orpy -MqFLPFHV/0USE7KW9pu0lMZZiyfuHKoi6x8LLTQdjRyGTe9qHPA2kuXgagXU/Yej -TutkUgU6wJUe1ZPXlP+ba2JHefj6AqYrKb1PuxXtuLlXqxoFOmKMnewzI/twaWxt -4P1ZDpRoYB9AzbWyrt7/1zpp83WZ+nc6DqBhTaRtTXh9l79L57xGT+lhuIf0xUmn -wSTDjTZzAgMBAAECggEAenzd8lScL1qTwlk6ODAE7SHVX/BKLWv5Um4KwdsLAVCE -qC7p+yMdANAtuFzG6Ig+29Fb5KnOlUKjPzmhQZhjpZ4cPzZbg3IxDHV2uqi2L8NZ -wlDWoik3q770a4fYSMd0sHsjQYwXo4CkLJQX8WaDJpgtcehl8g0yHPVSqe0mEkoL -dxdqaZnxprchscxefWaGaysIxEO+V+ZOBaPNf4i8PmBKoMNczWZbLcdKhRL7aLeW -ngPQp1xSWYoN8fPoonpL2qTSop3Nsc2INpwGcYPAj3vxdasC3+DZ8JEJI2AmxpVB -13BLkd3nDzOwimZIlu9Fv+NMJ1vb9XdC249ZOqo68QKBgQDigkws1W429nqDtEtQ -Dr5ebHTdP4gZlNt6vWx5obGLCMBAzoyubfNCCBTCYsCPj8hXxNfiPArPFFkIgEx9 -+w0n7BlaYL6SD2xD4q+YzA1/j4Loakxc7N9z8Cyu+/YHifvLhzwqgFnkLfFnVq9N -TF8TatHUYcrbcpawJLz0wr/cnQKBgQDKPAYNTzqPLOOBaE4DfnJNn2zctGU8G5Xp -0L/ED8O1t9AjjV2xVO8PDPNDZAxMzgnIbWeU9iWRSLbr7NloXElKh/QlITjAbSXe -HsUruq1SmDgiaUhEtDaaJ1SqSZZWY2BZqNXMdILOCgvZGnOyyBR2U49zuNaRHyhm -kmZMdIIKTwKBgQDezAk/hEQfvfuuNpZpzcbEu+uLgKVPfFMSfOYJEdnAB0CLvl80 -Z6QBzE8XEOmVjHkkk9NBjYuYOsyEhyY2OM2s+hfKBSUOKCt27q+IHRYd5bx+/afV -M41rzc8141ISAlBw1rmAmLVSszojSmmuH7PZNpXkULineCPuaISQQEtWJQKBgQDD -laVsvdEuowUsJEo+ys2VELhiAv1dUnh79u1fmrd2SV085P1WAYRqE+Y4qMvUg/em -JVjmEeBnT+HI7fmdGpOvRyjxt92BDI5w8WVTU2lI1fqEHTpNZ9Te5WbWgfCpf9ax -H74VzCCtT74Bq7l1kFdp0IqOKpcpJu8VtETHcG5LtQKBgQC4Tx7El1Xb4hsI4dvE -h43j3KBb3evlz6vaqgz0BArahYAz2UkkOYDSOPs4K6aOxxXjO0BjqQqCx/tCPcU5 -AvLsTlswO+wDLXM1DoKxzFBZL5o8927niqW+vZpzyGc1uPmC1MG7+MDKdZsR+e+9 -XzJTD4slrGSJrcpLt/g/Jqqdjg== ------END PRIVATE KEY----- - )"; - - auto body = utility::string_t {U("body content")}; - http_headers all_headers; - all_headers.add(U("Accept"), U("text/plain")); - all_headers.add(U("Accept-Charset"), U("utf-8")); - all_headers.add(U("Accept-Encoding"), U("gzip, deflate")); - all_headers.add(U("Accept-Language"), U("en-US")); - all_headers.add(U("Accept-Datetime"), U("Thu, 31 May 2007 20:35:00 GMT")); - all_headers.add(U("Authorization"), U("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==")); - all_headers.add(U("Cache-Control"), U("no-cache")); - all_headers.add(U("Cookie"), U("$Version=1; Skin=new;")); - all_headers.add(U("Content-Length"), body.size()); - all_headers.add(U("Content-MD5"), U("Q2hlY2sgSW50ZWdyaXR5IQ==")); - all_headers.add(U("Content-Type"), U("application/x-www-form-urlencoded")); - all_headers.add(U("Date"), U("Tue, 15 Nov 1994 08:12:31 GMT")); - all_headers.add(U("Expect"), U("100-continue")); - all_headers.add(U("Forwarded"), - U("for=192.0.2.60;proto=http;by=203.0.113.43Forwarded: for=192.0.2.43, for=198.51.100.17")); - all_headers.add(U("From"), U("user@example.com")); - all_headers.add(U("Host"), U("en.wikipedia.org")); - all_headers.add(U("If-Match"), U("\"737060cd8c284d8af7ad3082f209582d\"")); - all_headers.add(U("If-Modified-Since"), U("Sat, 29 Oct 1994 19:43:31 GMT")); - all_headers.add(U("If-None-Match"), U("\"737060cd8c284d8af7ad3082f209582d\"")); - all_headers.add(U("If-Range"), U("\"737060cd8c284d8af7ad3082f209582d\"")); - all_headers.add(U("If-Unmodified-Since"), U("Sat, 29 Oct 1994 19:43:31 GMT")); - all_headers.add(U("Max-Forwards"), U("10")); - all_headers.add(U("Origin"), U("http://www.example-social-network.com")); - all_headers.add(U("Pragma"), U("no-cache")); - all_headers.add(U("Proxy-Authorization"), U("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==")); - all_headers.add(U("Range"), U("bytes=500-999")); - all_headers.add(U("Referer"), U("http://en.wikipedia.org/wiki/Main_Page")); - all_headers.add(U("TE"), U("trailers, deflate")); - all_headers.add(U("User-Agent"), U("Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0")); - all_headers.add(U("Upgrade"), U("HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11")); - all_headers.add(U("Via"), U("1.0 fred, 1.1 example.com (Apache/1.1)")); - all_headers.add(U("Warning"), U("199 Miscellaneous warning")); - - boost::asio::const_buffer cert(self_signed_cert, std::strlen(self_signed_cert)); - boost::asio::const_buffer key(private_key, std::strlen(private_key)); - - http_listener_config server_config; - server_config.set_ssl_context_callback([&](boost::asio::ssl::context& ctx) { - ctx.set_options(boost::asio::ssl::context::default_workarounds); - ctx.use_certificate_chain(cert); - ctx.use_private_key(key, boost::asio::ssl::context::pem); - }); - - http_listener listener(m_secure_uri, server_config); - - listener.support(methods::GET, [&](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - - for (auto&& h : all_headers) - { - VERIFY_IS_TRUE(request.headers().has(h.first)); - VERIFY_ARE_EQUAL(h.second, request.headers().find(h.first)->second); - } - - VERIFY_ARE_EQUAL(body, request.extract_string(true).get()); - - request.reply(status_codes::OK); - }); - - listener.open().wait(); - - client::http_client_config client_config; -#if !defined(_WIN32) && !defined(__cplusplus_winrt) || defined(CPPREST_FORCE_HTTP_CLIENT_ASIO) - client_config.set_ssl_context_callback( - [&](boost::asio::ssl::context& ctx) { ctx.add_certificate_authority(cert); }); -#else - // in this build configuration, with WinHTTP-based http_client, this test will fail unless the self-signed - // cert is added to the Windows certificate store (or certificate validation is disabled in client_config) -#endif - client::http_client client(m_secure_uri, client_config); - http_request msg(methods::GET); - msg.set_request_uri(U("/")); - - msg.headers() = all_headers; - msg.set_body(body); - - http_asserts::assert_response_equals(client.request(msg).get(), status_codes::OK); - - listener.close().wait(); - } -#endif -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/reply_helper_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/reply_helper_tests.cpp @@ -1,104 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * reply_helper_tests.cpp - * - * Tests cases covering the reply helper functions on HTTP response. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace utility; -using namespace web; -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(reply_helper_tests) -{ - TEST_FIXTURE(uri_address, json) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support( - [](http_request request) { request.reply(status_codes::OK, json::value::parse(U("true"))).wait(); }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("application/json"), U("true")); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, string) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support([](http_request request) { - std::string body("test str"); - request.reply(status_codes::OK, body).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("text/plain; charset=utf-8"), U("test str")); - }) - .wait(); - - // content type and string body - listener.support([](http_request request) { - utility::string_t s(U("test str")); - request.reply(status_codes::OK, s, U("custom content")).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("custom content"), U("test str")); - }) - .wait(); - - // content type and rvalue reference string body - listener.support( - [](http_request request) { request.reply(status_codes::OK, "test str", "text/plain").wait(); }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK, U("text/plain"), U("test str")); - }) - .wait(); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_extract_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_extract_tests.cpp @@ -1,192 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * request_extract_tests.cpp - * - * Tests cases for covering calling extract_ overloads on HTTP request. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace utility; -using namespace web; -using namespace web::http; -using namespace web::http::experimental::listener; -using namespace utility::conversions; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(request_extract_tests) -{ - TEST_FIXTURE(uri_address, extract_string) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - std::string data("HEHEHE"); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, U("PUT"), U("/"), to_string_t(data)); - VERIFY_ARE_EQUAL(U("text/plain"), request.headers().content_type()); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U(""), U("text/plain"), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, extract_string_force) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - std::string data("HEHEHE"); - - listener.support([&](http_request request) { - VERIFY_ARE_EQUAL(to_string_t(data), request.extract_string(true).get()); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U(""), U("unknown charset"), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, extract_json) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - json::value j(true); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, U("PUT"), U("/")); - VERIFY_ARE_EQUAL(U("application/json"), request.headers().content_type()); - const json::value j_found = request.extract_json().get(); - VERIFY_ARE_EQUAL(j.serialize(), j_found.serialize()); - request.reply(status_codes::OK); - }); - std::string data = to_utf8string(j.serialize()); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U(""), U("application/json"), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, extract_json_force) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - json::value j(true); - listener.support([&](http_request request) { - const json::value j_found = request.extract_json(true).get(); - VERIFY_ARE_EQUAL(j.serialize(), j_found.serialize()); - request.reply(status_codes::OK); - }); - std::string data = to_utf8string(j.serialize()); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U(""), U("unknown charset"), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, empty_vector) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - std::string data(""); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, U("PUT"), U("/")); - VERIFY_ARE_EQUAL(U("text/plain"), request.headers().content_type()); - std::vector<unsigned char> vec = request.extract_vector().get(); - VERIFY_ARE_EQUAL(vec.size(), 0); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U(""), U("text/plain"), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, extract_vector) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - std::string data("HEHEHE"); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, U("PUT"), U("/")); - VERIFY_ARE_EQUAL(U("text/plain"), request.headers().content_type()); - std::vector<unsigned char> vec = request.extract_vector().get(); - VERIFY_ARE_EQUAL(vec.size(), data.size()); - VERIFY_ARE_EQUAL('H', vec[0]); - VERIFY_ARE_EQUAL('E', vec[1]); - VERIFY_ARE_EQUAL('H', vec[2]); - VERIFY_ARE_EQUAL('E', vec[3]); - VERIFY_ARE_EQUAL('H', vec[4]); - VERIFY_ARE_EQUAL('E', vec[5]); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U(""), U("text/plain"), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_handler_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_handler_tests.cpp @@ -1,557 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases for covering the http_listener class itself. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -std::shared_ptr<web::http::experimental::listener::http_listener> uri_address::s_dummy_listener; - -SUITE(request_handler_tests) -{ - TEST_FIXTURE(uri_address, support) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support(U("CUSTOM"), [](http_request request) { - http_asserts::assert_request_equals(request, U("CUSTOM"), U("/")); - request.reply(status_codes::OK); - }); - listener.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, methods::PUT, U("/")); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(methods::DEL, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::MethodNotAllowed); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(U("CUSTOM"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // Add one with a different case. - listener.support(U("CUSToM"), [](http_request request) { - http_asserts::assert_request_equals(request, U("CUSToM"), U("/")); - request.reply(status_codes::Gone); - }); - VERIFY_ARE_EQUAL(0, p_client->request(U("CUSToM"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Gone); - }) - .wait(); - - // Add a general handler - listener.support([](http_request request) { - http_asserts::assert_request_equals(request, U("CuSToM"), U("/")); - request.reply(status_codes::Created); - }); - VERIFY_ARE_EQUAL(0, p_client->request(U("CUSToM"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Gone); - }) - .wait(); - VERIFY_ARE_EQUAL(0, p_client->request(U("CuSToM"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Created); - }) - .wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, exceptions_in_handler) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // throw exception - listener.support(methods::GET, [](http_request request) { - http_asserts::assert_request_equals(request, U("GET"), U("/")); - throw std::runtime_error(""); - }); - VERIFY_ARE_EQUAL(0, p_client->request(U("GET"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::InternalError); - }) - .wait(); - - // throw exception, after replying first - listener.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, U("PUT"), U("/")); - request.reply(status_codes::OK); - throw 55; - }); - VERIFY_ARE_EQUAL(0, p_client->request(U("PUT"), U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, handle_options) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - listener.support(methods::GET, [](http_request) {}); - listener.support(methods::PUT, [](http_request) {}); - VERIFY_ARE_EQUAL(0, p_client->request(methods::OPTIONS, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - VERIFY_ARE_EQUAL(U("GET, PUT"), p_response->m_headers[U("Allow")]); - }) - .wait(); - - // try overridding the default OPTIONS handler - listener.support(methods::OPTIONS, [](http_request request) { - http_asserts::assert_request_equals(request, methods::OPTIONS, U("/")); - request.reply(status_codes::NoContent); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::OPTIONS, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NoContent); - }) - .wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, handle_trace) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - VERIFY_ARE_EQUAL(0, p_client->request(methods::TRCE, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - std::string utf8_response; - utf8_response.assign(p_response->m_data.begin(), p_response->m_data.end()); -#ifdef _WIN32 - VERIFY_ARE_EQUAL("TRACE / HTTP/1.1\r\nConnection: Keep-Alive\r\nHost: localhost:34567\r\nUser-Agent: " - "test_http_client\r\n\r\n", - utf8_response); -#else - VERIFY_ARE_EQUAL( - "TRACE / HTTP/1.1\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\nContent-Type: text/plain; " - "charset=utf-8\r\nHost: localhost:34567\r\nUser-Agent: test_http_client\r\n\r\n", - utf8_response); -#endif - }) - .wait(); - - // try overridding the default OPTIONS handler - listener.support(methods::TRCE, [](http_request request) { - http_asserts::assert_request_equals(request, methods::TRCE, U("/")); - request.reply(status_codes::NoContent); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::TRCE, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NoContent); - }) - .wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, async_request_handler) - { - http_listener listener(m_uri); - pplx::extensibility::event_t e; - listener.support([&e](http_request request) { - e.set(); - request.reply(status_codes::OK).wait(); - }); - listener.open().wait(); - - client::http_client client(m_uri); - auto buf = streams::producer_consumer_buffer<uint8_t>(); - pplx::task<http_response> response = - client.request(methods::PUT, U("/"), buf.create_istream(), U("text/plain")); - - e.wait(); - buf.close(std::ios_base::out).wait(); - response.wait(); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, multiple_listeners) - { - http_listener listener1(U("http://localhost:45678/path1")); - http_listener listener2(U("http://localhost:45678/path1/path2")); - http_listener listener3(U("http://localhost:45678/path3")); - listener1.open().wait(); - listener2.open().wait(); - listener3.open().wait(); - - test_http_client::scoped_client client(U("http://localhost:45678")); - test_http_client* p_client = client.client(); - - // send a request to the first listener - listener1.support(methods::GET, [](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - request.reply(status_codes::NoContent); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NoContent); - }) - .wait(); - - // send a request to the second listener - listener2.support(methods::PUT, [](http_request request) { - http_asserts::assert_request_equals(request, methods::PUT, U("/path4")); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U("/path1/path2/path4"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // send a request to the third listener - listener3.support(methods::POST, [](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(status_codes::Created); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U("/path3"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Created); - }) - .wait(); - - // Remove the second listener and send a request again. - listener2.close().wait(); - listener1.support(methods::GET, [](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/path2/path4")); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1/path2/path4"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener3.close().wait(); - listener1.close().wait(); - } - - TEST_FIXTURE(uri_address, unregister_while_processing) - { - http_listener listener1(U("http://localhost:45679/path1")); - http_listener listener2(U("http://localhost:45679/path1/path2")); - listener1.open().wait(); - listener2.open().wait(); - - test_http_client::scoped_client client1(U("http://localhost:45679")); - test_http_client* p_client1 = client1.client(); - test_http_client::scoped_client client2(U("http://localhost:45679")); - test_http_client* p_client2 = client2.client(); - - // first listener is used to wait until a request comes into the second - // and then will try to close the second. - pplx::extensibility::event_t secondRequest; - listener1.support(methods::GET, [&](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - secondRequest.wait(); - listener2.close().wait(); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client1->request(methods::GET, U("/path1"))); - listener2.support(methods::GET, [&](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - secondRequest.set(); - os_utilities::sleep(200); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client2->request(methods::GET, U("/path1/path2/"))); - p_client1->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - p_client2->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - listener1.close().wait(); - } - - TEST_FIXTURE(uri_address, multiple_requests) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - test_http_client::scoped_client client2(m_uri); - test_http_client* p_client2 = client2.client(); - test_http_client::scoped_client client3(m_uri); - test_http_client* p_client3 = client3.client(); - - volatile unsigned long requestCount = 0; - listener.support(methods::GET, [&](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/path1")); - os_utilities::interlocked_increment(&requestCount); - while (requestCount != 3) - { - os_utilities::sleep(1); - } - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1"))); - VERIFY_ARE_EQUAL(0, p_client2->request(methods::GET, U("/path1"))); - VERIFY_ARE_EQUAL(0, p_client3->request(methods::GET, U("/path1"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - p_client2->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - p_client3->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, multiple_clients_multiple_requests) - { - http_listener listener(m_uri); - listener.open().wait(); - const size_t NUM_CLIENTS = 10; - std::vector<std::unique_ptr<test_http_client>> clients; - for (size_t i = 0; i < NUM_CLIENTS; ++i) - { - std::unique_ptr<test_http_client> client(new test_http_client(m_uri)); - VERIFY_ARE_EQUAL(0, client->open()); - clients.push_back(std::move(client)); - } - - listener.support(methods::GET, [&](http_request request) { - http_asserts::assert_request_equals(request, methods::GET, U("/")); - request.reply(status_codes::OK); - }); - for (size_t j = 0; j < 10; ++j) - { - std::vector<pplx::task<void>> requests; - for (size_t i = 0; i < NUM_CLIENTS; ++i) - { - VERIFY_ARE_EQUAL(0, clients[i]->request(methods::GET, U("/"))); - requests.push_back(clients[i]->next_response().then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - })); - } - pplx::when_all(requests.begin(), requests.end()).wait(); - } - - for (size_t i = 0; i < NUM_CLIENTS; ++i) - { - VERIFY_ARE_EQUAL(0, clients[i]->close()); - } - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, test_leaks) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // pick a large number to see leaks easier - const size_t nbytes = 1024 * 1000; - - listener.support(methods::PUT, [&](http_request message) { - while (message.body().streambuf().in_avail() < nbytes) - ; - - utility::string_t request = U("unknown"); - auto it = message.headers().find(U("ClientID")); - if (it != message.headers().end()) - { - message.reply(status_codes::OK, U("Unknown command")); - } - else - { - message.reply(status_codes::OK, U("ClientID missing")); - } - }); - - const int N = 1; // use large number of iterations to test for leaks - for (int i = 0; i < N; ++i) - { - std::map<utility::string_t, utility::string_t> headers; - headers[U("ClientID")] = U("123"); - headers[U("Request")] = U("Upload"); - headers[U("ImgNr")] = U("1"); - - // this help recognizing the leaked memory in the CRT/VLD dump - std::string data; - for (int j = 0; j < nbytes; j++) - data.push_back('a' + (j % 26)); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U("/path1"), headers, data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - } - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, http_version) - { - // formatting should succeed - VERIFY_IS_TRUE("HTTP/0.9" == http_versions::HTTP_0_9.to_utf8string()); - VERIFY_IS_TRUE("HTTP/1.0" == http_versions::HTTP_1_0.to_utf8string()); - VERIFY_IS_TRUE("HTTP/1.1" == http_versions::HTTP_1_1.to_utf8string()); - VERIFY_IS_TRUE("HTTP/12.3" == (http_version {12, 3}).to_utf8string()); - // parsing should succeed - VERIFY_IS_TRUE(http_version::from_string("HTTP/0.9") == http_versions::HTTP_0_9); - VERIFY_IS_TRUE(http_version::from_string("HTTP/1.0") == http_versions::HTTP_1_0); - VERIFY_IS_TRUE(http_version::from_string("HTTP/1.1") == http_versions::HTTP_1_1); - VERIFY_IS_TRUE((http_version::from_string("HTTP/12.3") == http_version {12, 3})); - // parsing should fail - http_version unknown = {0, 0}; - VERIFY_IS_TRUE(http_version::from_string("http/12.3") == unknown); - VERIFY_IS_TRUE(http_version::from_string("HTTP/12.3foo") == unknown); - VERIFY_IS_TRUE(http_version::from_string("HTTP/12.") == unknown); - VERIFY_IS_TRUE(http_version::from_string("HTTP/12") == unknown); - VERIFY_IS_TRUE(http_version::from_string("HTTP/.3") == unknown); - VERIFY_IS_TRUE(http_version::from_string("HTTP/") == unknown); - VERIFY_IS_TRUE(http_version::from_string("HTTP") == unknown); - VERIFY_IS_TRUE(http_version::from_string("HTTP") == unknown); - VERIFY_IS_TRUE(http_version::from_string("foo") == unknown); - VERIFY_IS_TRUE(http_version::from_string("") == unknown); - - http_listener listener(U("http://localhost:45678/path1")); - listener.open().wait(); - - test_http_client::scoped_client client(U("http://localhost:45678")); - test_http_client* p_client = client.client(); - - volatile unsigned long requestCount = 0; - - listener.support(methods::GET, [&requestCount](http_request request) { - const auto& httpVersion = request.http_version(); - - // All clients currently use HTTP/1.1 - VERIFY_IS_TRUE(httpVersion == http_versions::HTTP_1_1); - - os_utilities::interlocked_increment(&requestCount); - request.reply(status_codes::NoContent); - }); - - // Send a request to the listener - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1"))); - - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NoContent); - }) - .wait(); - - VERIFY_IS_TRUE(requestCount >= 1); - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, remote_address) - { - http_listener listener(U("http://localhost:45678/path1")); - listener.open().wait(); - - test_http_client::scoped_client client(U("http://localhost:45678")); - test_http_client* p_client = client.client(); - - volatile unsigned long requestCount = 0; - - listener.support(methods::GET, [&requestCount](http_request request) { - const string_t& remoteAddr = request.remote_address(); - const string_t& localhost4 = string_t(U("127.0.0.1")); - const string_t& localhost6 = string_t(U("::1")); - - // We can't guarantee that the host has both IPv4 and IPv6 available, so check for either IP - VERIFY_IS_TRUE((remoteAddr == localhost4) || (remoteAddr == localhost6)); - - os_utilities::interlocked_increment(&requestCount); - request.reply(status_codes::NoContent); - }); - - // Send a request to the listener - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/path1"))); - - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NoContent); - }) - .wait(); - - VERIFY_IS_TRUE(requestCount >= 1); - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_relative_uri_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_relative_uri_tests.cpp @@ -1,144 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * request_relative_uri_tests.cpp - * - * Tests cases the combinations of base uri and relative uri with incoming requests to the http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(request_relative_uri_tests) -{ - TEST_FIXTURE(uri_address, empty_base_uri) - { - // listen on empty, request /path1/path2 - http_listener listener(m_uri); - listener.open().wait(); - test_http_client client(m_uri); - VERIFY_ARE_EQUAL(0, client.open()); - listener.support([](http_request request) { - VERIFY_ARE_EQUAL(U("/path1/path2"), request.request_uri().path()); - VERIFY_ARE_EQUAL(U("/path1/path2"), request.relative_uri().to_string()); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, client.request(methods::GET, U("/path1/path2"))); - client.next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, client.close()); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, nested_paths) - { - // listen on /path1, request /path1/path2 - http_listener listener(web::http::uri_builder(m_uri).append_path(U("/path1")).to_uri()); - listener.open().wait(); - test_http_client client(m_uri); - VERIFY_ARE_EQUAL(0, client.open()); - listener.support([](http_request request) { - VERIFY_ARE_EQUAL(U("/path1/path2"), request.request_uri().path()); - VERIFY_ARE_EQUAL(U("/path2"), request.relative_uri().to_string()); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, client.request(methods::GET, U("/path1/path2"))); - client.next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, client.close()); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, nested_paths_encoding) - { - // listen on /path1%20/path2%20, request /path1%20/path2%20/path%203 - http_listener listener(web::http::uri_builder(m_uri).append_path(U("/path1%20/path2%20")).to_uri()); - listener.open().wait(); - test_http_client client(m_uri); - VERIFY_ARE_EQUAL(0, client.open()); - listener.support([](http_request request) { - VERIFY_ARE_EQUAL(U("/path1%20/path2%20/path3%20"), request.request_uri().path()); - VERIFY_ARE_EQUAL(U("/path3 "), web::http::uri::decode(request.relative_uri().to_string())); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, client.request(methods::GET, U("/path1%20/path2%20/path3%20"))); - client.next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - VERIFY_ARE_EQUAL(0, client.close()); - - listener.close().wait(); - } - - TEST(listener_uri_empty_path) - { - uri address(U("http://localhost:45678")); - http_listener listener(address); - listener.open().wait(); - test_http_client::scoped_client client(address); - test_http_client* p_client = client.client(); - - listener.support([](http_request request) { request.reply(status_codes::OK); }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST(listener_invalid_encoded_uri) - { - uri address(U("http://localhost:45678")); - http_listener listener(address); - listener.open().wait(); - test_http_client::scoped_client client(address); - test_http_client* p_client = client.client(); - - listener.support([](http_request request) { request.reply(status_codes::OK); }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("/%invalid/uri"))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::BadRequest); - }) - .wait(); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_stream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/request_stream_tests.cpp @@ -1,103 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * request_stream_tests.cpp - * - * Tests cases for streaming HTTP requests with http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(request_stream_tests) -{ - TEST_FIXTURE(uri_address, large_body) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - std::string data_piece("abcdefghijklmnopqrstuvwxyz"); - std::string send_data; - // 26 * 160 is greater than 4k which is the chunk size. - for (int i = 0; i < 160; ++i) - { - send_data.append(data_piece); - } - size_t length = send_data.size(); - - listener.support([&](http_request request) { - auto stream = request.body(); - streams::stringstreambuf strbuf; - - VERIFY_ARE_EQUAL(stream.read_to_end(strbuf).get(), length); - VERIFY_ARE_EQUAL(strbuf.collection(), send_data); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U(""), U("text/plain"), send_data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, test_chunked_transfer) - { - const size_t num_bytes = 1024 * 1024 * 10; - http_listener listener(m_uri); - listener.support([num_bytes](http_request request) { request.reply(status_codes::OK); }); - listener.open().wait(); - - ::http::client::http_client client(m_uri); - auto buf = streams::producer_consumer_buffer<uint8_t>(); - pplx::task<http_response> response = - client.request(methods::PUT, U("/"), buf.create_istream(), U("text/plain")); - - const size_t four_mb = 1024 * 1024 * 4; - std::vector<uint8_t> buffer; - buffer.resize(num_bytes); - memset(&buffer[0], (int)'A', num_bytes); - size_t start = 0, end; - while (start < num_bytes) - { - end = start + four_mb < num_bytes ? four_mb : num_bytes - start; - size_t num_written = buf.putn_nocopy(&buffer[start], end).get(); - start += num_written; - } - buf.close(std::ios_base::out).wait(); - - response.wait(); - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/requests_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/requests_tests.cpp @@ -1,278 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * requests_tests.cpp - * - * Tests cases for covering sending various requests to http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include <cpprest/http_client.h> - -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(requests_tests) -{ - TEST_FIXTURE(uri_address, http_methods) - { - http_listener listener(m_uri); - - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Don't include 'CONNECT' it has a special meaning. - utility::string_t send_methods[] = {methods::GET, - U("GET"), - methods::DEL, - methods::HEAD, - U("HeAd"), - methods::POST, - methods::PUT, - U("CUstomMETHOD")}; - utility::string_t recv_methods[] = { - U("GET"), U("GET"), U("DELETE"), U("HEAD"), U("HEAD"), U("POST"), U("PUT"), U("CUstomMETHOD")}; - const size_t num_methods = sizeof(send_methods) / sizeof(send_methods[0]); - - utility::string_t actual_method; - listener.support([&](http_request request) { - actual_method = request.method(); - request.reply(status_codes::OK).wait(); - }); - - for (int i = 0; i < num_methods; ++i) - { - pplx::extensibility::event_t ev; - VERIFY_ARE_EQUAL(0, p_client->request(send_methods[i], U(""))); - p_client->next_response() - .then([&ev](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - ev.set(); - }) - .wait(); - VERIFY_ARE_EQUAL(recv_methods[i], actual_method); - ev.wait(); - } - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, http_body_and_body_size) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // request with no body - listener.support([](http_request request) { - http_asserts::assert_request_equals(request, U("GET"), U("/")); - VERIFY_ARE_EQUAL(0, request.body().streambuf().in_avail()); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U(""))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // request with body size explicitly 0 - listener.support([](http_request request) { - http_asserts::assert_request_equals(request, U("GET"), U("/")); - VERIFY_ARE_EQUAL(0, request.body().streambuf().in_avail()); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U(""), "")); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - // request with body data - std::string data("HEHE"); - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, U("GET"), U("/")); - - auto stream = request.body(); - VERIFY_IS_TRUE(stream.is_valid()); - auto buf = stream.streambuf(); - VERIFY_IS_TRUE(buf); - - request.content_ready().wait(); - - VERIFY_ARE_EQUAL(data.size(), buf.in_avail()); - VERIFY_ARE_EQUAL('H', (char)buf.sbumpc()); - VERIFY_ARE_EQUAL('E', (char)buf.sbumpc()); - VERIFY_ARE_EQUAL('H', (char)buf.sbumpc()); - VERIFY_ARE_EQUAL('E', (char)buf.sbumpc()); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U(""), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, large_body) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - std::string data_piece("abcdefghijklmnopqrstuvwxyz"); - std::string send_data; - // 26 * 160 is greater than 4k which is the chunk size. - for (int i = 0; i < 160; ++i) - { - send_data.append(data_piece); - } - listener.support([&](http_request request) { - std::string recv_data = utility::conversions::to_utf8string(request.extract_string().get()); - VERIFY_ARE_EQUAL(send_data, recv_data); - request.reply(status_codes::OK); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U(""), U("text/plain"), send_data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, response_order) - { - http_listener listener(m_uri); - listener.open().wait(); - - client::http_client_config config; - // our product client would be able to pipe multiple requests on one connection - client::http_client client(m_uri, config); - - const int num_requests = 50; - - listener.support([](http_request request) { - auto str = request.extract_string().get(); - // intentionally break order - if (str == U("0")) tests::common::utilities::os_utilities::sleep(500); - request.reply(status_codes::OK, str); - }); - - std::vector<pplx::task<web::http::http_response>> responses; - - for (int i = 0; i < num_requests; ++i) - { - utility::ostringstream_t ss; - ss << i; - responses.push_back(client.request(web::http::methods::PUT, U(""), ss.str())); - } - - // wait for requests. - for (size_t i = 0; i < num_requests; ++i) - { - utility::ostringstream_t ss; - ss << i; - auto response = responses[i].get(); - - // verify the requests and responses are still match - VERIFY_ARE_EQUAL(response.status_code(), status_codes::OK); - VERIFY_ARE_EQUAL(response.extract_string().get(), ss.str()); - } - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, uri_encoding, "Ignore", "Codeplex 201") - { - http_listener listener(m_uri); - listener.open().wait(); - client::http_client client(m_uri); - utility::string_t encoded_uri; - - listener.support([&](http_request request) { - VERIFY_ARE_EQUAL(encoded_uri, request.relative_uri().to_string()); - request.reply(status_codes::OK); - }); - - // Wrap in try catch to print out more information to help with a sporadic failure. - try - { - encoded_uri = uri::encode_uri(U("/path 1/path 2")); // Path component contains encoded characters - client.request(methods::GET, encoded_uri).wait(); - encoded_uri = uri::encode_uri( - U("/test?Text=J'ai besoin de trouver un personnage")); // Query string contains encoded characters - client.request(methods::GET, encoded_uri).wait(); - encoded_uri = uri::encode_uri(U("/path 1/path 2#fragment1")); // URI has path and fragment components - client.request(methods::GET, encoded_uri).wait(); - encoded_uri = uri::encode_uri( - U("/path 1/path 2?key1=val1 val2#fragment1")); // URI has path, query and fragment components - client.request(methods::GET, encoded_uri).wait(); - } - catch (const http_exception& e) - { - std::cout << "http_exception caught" << std::endl - << "what():" << e.what() << std::endl - << "error_code msg:" << e.error_code().message() << std::endl - << "error_code value:" << e.error_code().value() << std::endl; - VERIFY_IS_TRUE(false); - } - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, https_listener, "Ignore", "Manual") - { - // Requires a certificate for execution. - // Here are instructions for creating a self signed cert. Full instructions can be located here: - // http://blogs.msdn.com/b/haoxu/archive/2009/04/30/one-time-set-up-for-wwsapi-security-examples.aspx - // From an elevated admin prompt: - // 1. MakeCert.exe -ss Root -sr LocalMachine -n "CN=Fake-Test-CA" -cy authority -r -sk "CAKeyContainer" - // 2. MakeCert.exe -ss My -sr LocalMachine -n "CN=localhost" -sky exchange -is Root -ir LocalMachine -in - // Fake-Test-CA -sk "ServerKeyContainer" - // 3. Find corresponding SHA-1 hash with CertUtil.exe -store My localhost - // 4. Netsh.exe http add sslcert ipport=0.0.0.0:8443 appid={00112233-4455-6677-8899-AABBCCDDEEFF} - // certhash=<40CharacterThumbprintWithNoSpaces> - - http_listener listener(m_secure_uri); - listener.open().wait(); - client::http_client client(m_secure_uri); - - listener.support([&](http_request request) { request.reply(status_codes::OK); }); - - http_asserts::assert_response_equals(client.request(methods::GET, U("")).get(), status_codes::OK); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/response_stream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/response_stream_tests.cpp @@ -1,316 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * response_stream_tests.cpp - * - * Tests cases for streaming with HTTP response with http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "cpprest/rawptrstream.h" - -using namespace web; -using namespace utility; -using namespace concurrency; -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(response_stream_tests) -{ - // Used to prepare data for read tests - void fill_file(const utility::string_t& name, size_t repetitions = 1) - { - std::fstream stream(name, std::ios_base::out | std::ios_base::trunc); - - for (size_t i = 0; i < repetitions; i++) - stream << "abcdefghijklmnopqrstuvwxyz"; - } - - TEST_FIXTURE(uri_address, set_body_stream_small) - { - utility::string_t fname = U("set_response_stream_small.txt"); - fill_file(fname); - - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Try sending data straight from a file. - http_response response(status_codes::OK); - - auto stream = streams::file_stream<uint8_t>::open_istream(fname).get(); - response.set_body(stream); - - auto length = stream.seek(0, std::ios_base::end); - stream.seek(0); - - response.headers().set_content_type(U("text/plain; charset=utf-8")); - response.headers().set_content_length((size_t)length); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals( - p_response, status_codes::OK, U("text/plain; charset=utf-8"), U("abcdefghijklmnopqrstuvwxyz")); - }) - .wait(); - - stream.close().get(); - } - - TEST_FIXTURE(uri_address, set_body_stream_large) - { - utility::string_t fname = U("set_response_stream_large.txt"); - fill_file(fname, 200); - - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Try sending data straight from a file. - http_response response(status_codes::OK); - - auto stream = streams::file_stream<uint8_t>::open_istream(fname).get(); - response.set_body(stream); - - auto length = stream.seek(0, std::ios_base::end); - stream.seek(0); - - response.headers().set_content_type(U("text/plain; charset=utf-8")); - response.headers().set_content_length((size_t)length); - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - VERIFY_ARE_EQUAL((size_t)length, p_response->m_data.size()); - }) - .wait(); - - stream.close().get(); - } - - TEST_FIXTURE(uri_address, set_body_stream_partial) - { - utility::string_t fname = U("set_response_stream_partial.txt"); - fill_file(fname, 200); - - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Try sending data straight from a file. - http_response response(status_codes::OK); - - auto stream = streams::file_stream<uint8_t>::open_istream(fname).get(); - response.set_body(stream); - - response.headers().set_content_type(U("text/plain; charset=utf-8")); - response.headers().set_content_length(4500); - - // We shouldn't be sending more than the content-length. - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - VERIFY_ARE_EQUAL(4500, p_response->m_data.size()); - }) - .wait(); - - // We should only have read the first 4500 bytes. - auto length = stream.seek(0, std::ios_base::cur); - VERIFY_ARE_EQUAL((size_t)length, (size_t)4500); - - stream.close().get(); - } - - TEST_FIXTURE(uri_address, set_body_filestream_chunked) - { - utility::string_t fname = U("set_response_stream_chunked.txt"); - fill_file(fname, 200); - - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Try sending data straight from a file. - http_response response(status_codes::OK); - - auto stream = streams::file_stream<uint8_t>::open_istream(fname).get(); - response.set_body(stream); - - auto length = stream.seek(0, std::ios_base::end); - stream.seek(0); - - response.headers().set_content_type(U("text/plain; charset=utf-8")); - // Not setting the content length forces "transfer-encoding: chunked" - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - VERIFY_ARE_EQUAL((size_t)length, p_response->m_data.size()); - }) - .wait(); - - stream.close().get(); - } - - TEST_FIXTURE(uri_address, set_body_memorystream_chunked) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // Try sending data straight from a file. - http_response response(status_codes::OK); - - std::string text1 = "This is a test"; - size_t length = text1.size(); - - response.headers().set_content_type(U("text/plain; charset=utf-8")); - // Not setting the content length forces "transfer-encoding: chunked" - - listener.support([&](http_request request) { - http_asserts::assert_request_equals(request, methods::POST, U("/")); - - streams::producer_consumer_buffer<char> rwbuf; - - streams::basic_istream<uint8_t> stream(rwbuf); - response.set_body(stream); - - auto rep = request.reply(response); - - os_utilities::sleep(100); - - rwbuf.putn_nocopy(&text1[0], length).wait(); - rwbuf.putn_nocopy(&text1[0], length).wait(); - rwbuf.sync().wait(); - rwbuf.putn_nocopy(&text1[0], length).wait(); - rwbuf.close(std::ios_base::out).wait(); - - rep.wait(); - }); - - VERIFY_ARE_EQUAL(0u, p_client->request(methods::POST, U(""))); - p_client->next_response() - .then([&](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - VERIFY_ARE_EQUAL((size_t)length * 3, p_response->m_data.size()); - }) - .wait(); - } - - TEST_FIXTURE(uri_address, reply_transfer_encoding_4k) - { - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - - streams::container_buffer<std::vector<uint8_t>> buf; - - // Write 4K - the exact internal chunk size - unsigned char ptr[4 * 1024] = {'a', 'b', 'c'}; - VERIFY_ARE_EQUAL(buf.putn_nocopy(ptr, sizeof(ptr)).get(), sizeof(ptr)); - - listener.support([&buf](http_request request) { - // Ensure that it is transfer-encoded - auto collection = buf.collection(); - streams::container_buffer<std::vector<uint8_t>> buf2(std::move(collection), std::ios_base::in); - request.reply(200, streams::istream(buf2), U("text/plain")); - buf.close(std::ios_base::out); - }); - - { - ::http::client::http_client client(m_uri); - http_request msg(methods::GET); - - // Wait for headers - auto resp = client.request(msg).get(); - - // Wait for data - resp.content_ready().wait(); - - // Now verify that we've got the right data - auto s = resp.extract_string().get(); - VERIFY_ARE_EQUAL(s.c_str(), U("abc")); - } - listener.close().wait(); - } - - // Fails sporadically, Codeplex #158 - TEST_FIXTURE(uri_address, reply_chunked_4k, "Ignore", "Codeplex 158") - { - web::http::experimental::listener::http_listener listener(m_uri); - listener.open().wait(); - - streams::producer_consumer_buffer<uint8_t> buf; - - // Write 4K - the exact internal chunk size - unsigned char ptr[4 * 1024]; - VERIFY_ARE_EQUAL(buf.putn_nocopy(ptr, sizeof(ptr)).get(), sizeof(ptr)); - buf.close(std::ios_base::out); - - listener.support([&buf](http_request request) { - // Ensure that it is transfer-encoded - request.reply(200, streams::istream(buf), 4096, U("text/plain")); - }); - - { - ::http::client::http_client client(m_uri); - http_request msg(methods::GET); - - // Wait for headers - auto resp = client.request(msg).get(); - - // Wait for data - resp.content_ready().wait(); - } - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/status_code_reason_phrase_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/status_code_reason_phrase_tests.cpp @@ -1,107 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * status_code_reason_phrase_tests.cpp - * - * Tests cases for using HTTP status codes and reason phrases with http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(status_code_reason_phrase_tests) -{ - TEST_FIXTURE(uri_address, status_codes) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // known status code - listener.support([&](http_request request) { request.reply(status_codes::Conflict).wait(); }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::PUT, U(""))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::Conflict); - }) - .wait(); - - // user defined status code - listener.support([&](http_request request) { request.reply(867).wait(); }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::PUT, U(""))); - p_client->next_response() - .then([](test_response* p_response) { http_asserts::assert_test_response_equals(p_response, 867); }) - .wait(); - - listener.close().wait(); - } - - TEST_FIXTURE(uri_address, reason_phrase) - { - http_listener listener(m_uri); - listener.open().wait(); - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // standard status code, no reason phrase - listener.support([](http_request request) { request.reply(status_codes::NotModified).wait(); }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::PUT, U(""))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NotModified); - VERIFY_ARE_EQUAL(U("Not Modified"), p_response->m_reason_phrase); - }) - .wait(); - - // standard status code, with reason phrase - listener.support([](http_request request) { - http_response response(status_codes::NotModified); - response.set_reason_phrase(U("Custom")); - request.reply(response).wait(); - }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::PUT, U(""))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::NotModified); - VERIFY_ARE_EQUAL(U("Custom"), p_response->m_reason_phrase); - }) - .wait(); - - // non standard status code, no reason phrase - listener.support([](http_request request) { request.reply(987); }); - VERIFY_ARE_EQUAL(0u, p_client->request(methods::PUT, U(""))); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, 987); - VERIFY_ARE_EQUAL(U(""), p_response->m_reason_phrase); - }) - .wait(); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/stdafx.cpp @@ -1,8 +0,0 @@ -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" - -#if WIN32 -__declspec(dllexport) int httplistener_test_generate_lib = 0; -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/stdafx.h @@ -1,27 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * stdafx.h - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/filestream.h" -#include "cpprest/http_client.h" -#include "cpprest/http_listener.h" -#include "cpprest/producerconsumerstream.h" -#include "http_listener_tests.h" -#include "http_test_utilities.h" -#include "os_utilities.h" -#include "unittestpp.h" -#include <fstream> diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/to_string_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/listener/to_string_tests.cpp @@ -1,84 +0,0 @@ -/*** - * ==++== - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * - * ==--== - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * to_string_tests.cpp - * - * Tests cases for to_string on HTTP requests/responses with http_listener. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web::http; -using namespace web::http::experimental::listener; - -using namespace tests::common::utilities; -using namespace tests::functional::http::utilities; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace listener -{ -SUITE(to_string_tests) -{ - TEST_FIXTURE(uri_address, response_to_string) - { - // to string - http_response resp(status_codes::PartialContent); - resp.set_body(U("data")); - VERIFY_ARE_EQUAL(U("HTTP/1.1 206 Partial Content\r\nContent-Length: 4\r\nContent-Type: text/plain; ") - U("charset=utf-8\r\n\r\ndata"), - resp.to_string()); - } - - TEST_FIXTURE(uri_address, request_to_string) - { - http_listener listener(m_uri); - listener.open().wait(); - - test_http_client::scoped_client client(m_uri); - test_http_client* p_client = client.client(); - - // to_string - std::string data("hehehe"); - listener.support([&](http_request request) { - std::map<utility::string_t, utility::string_t> expected_headers; - expected_headers[U("Connection")] = U("Keep-Alive"); - expected_headers[U("Content-Length")] = U("6"); - expected_headers[U("Content-Type")] = U("text/plain"); - expected_headers[U("Host")] = U("localhost:34567"); - expected_headers[U("User-Agent")] = U("test_http_client"); - - // maybe to_string() should wait for the request to complete? - // in the mean time... - request.content_ready().wait(); - - http_asserts::assert_request_string_equals( - request.to_string(), U("GET"), U("/pa%20th1"), U("HTTP/1.1"), expected_headers, U("hehehe")); - request.reply(status_codes::OK).wait(); - }); - VERIFY_ARE_EQUAL(0, p_client->request(methods::GET, U("pa%20th1"), U("text/plain"), data)); - p_client->next_response() - .then([](test_response* p_response) { - http_asserts::assert_test_response_equals(p_response, status_codes::OK); - }) - .wait(); - - listener.close().wait(); - } -} - -} // namespace listener -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/CMakeLists.txt @@ -1,20 +0,0 @@ -set(SOURCES - http_asserts.cpp - test_http_client.cpp - test_http_server.cpp - test_server_utilities.cpp -) - -add_library(httptest_utilities ${SOURCES}) -if(WIN32) - target_compile_definitions(httptest_utilities PRIVATE -DHTTPTESTUTILITY_EXPORTS) -endif() -target_include_directories(httptest_utilities PUBLIC include) -target_link_libraries(httptest_utilities PUBLIC - cpprest - unittestpp - common_utilities -) -if(WINDOWS_STORE) - target_compile_options(httptest_utilities PRIVATE /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP) -endif() diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/http_asserts.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/http_asserts.cpp @@ -1,312 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * http_asserts.cpp - Utility class to help verify assertions about http requests and responses. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -using namespace web; -using namespace utility; -using namespace utility::conversions; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -utility::string_t percent_encode_pound(utility::string_t str) -{ - size_t index; - while ((index = str.find_first_of(U("#"))) != str.npos) - { - str.insert(index, U("%23")); - str.erase(index + 3, 1); - } - return str; -} - -// Helper function to verify all given headers are present. -template<typename T1, typename T2> -static void verify_headers(const T1& expected, const T2& actual) -{ - for (auto iter = expected.begin(); iter != expected.end(); ++iter) - { - VERIFY_ARE_EQUAL(iter->second, actual.find(iter->first)->second); - } -} - -void http_asserts::assert_request_equals(::http::http_request request, - const ::http::method& mtd, - const utility::string_t& relative_path) -{ - VERIFY_ARE_EQUAL(mtd, request.method()); - if (relative_path == U("")) - { - VERIFY_ARE_EQUAL(U("/"), request.relative_uri().to_string()); - } - else - { - VERIFY_ARE_EQUAL(relative_path, request.relative_uri().to_string()); - } -} - -void http_asserts::assert_request_equals(::http::http_request request, - const ::http::method& mtd, - const utility::string_t& relative_uri, - const std::map<utility::string_t, utility::string_t>& headers) -{ - assert_request_equals(request, mtd, relative_uri); - verify_headers(headers, request.headers()); -} - -void http_asserts::assert_request_equals(::http::http_request request, - const ::http::method& mtd, - const utility::string_t& relative_path, - const utility::string_t& body) -{ - assert_request_equals(request, mtd, relative_path); - auto request_data = request.extract_string().get(); - VERIFY_ARE_EQUAL(body, request_data); -} - -void http_asserts::assert_response_equals(::http::http_response response, const ::http::status_code& code) -{ - VERIFY_ARE_EQUAL(response.status_code(), code); -} - -void http_asserts::assert_response_equals(::http::http_response response, - const ::http::status_code& code, - const utility::string_t& reason) -{ - VERIFY_ARE_EQUAL(code, response.status_code()); - VERIFY_ARE_EQUAL(reason, response.reason_phrase()); -} - -void http_asserts::assert_response_equals(::http::http_response response, - const ::http::status_code& code, - const std::map<utility::string_t, utility::string_t>& headers) -{ - VERIFY_ARE_EQUAL(code, response.status_code()); - verify_headers(headers, response.headers()); -} - -void http_asserts::assert_http_headers_equals(const ::http::http_headers& actual, const ::http::http_headers& expected) -{ - verify_headers(actual, expected); -} - -void http_asserts::assert_test_request_equals(const test_request* const p_request, - const ::http::method& mtd, - const utility::string_t& path) -{ - VERIFY_ARE_EQUAL(mtd, p_request->m_method); - VERIFY_ARE_EQUAL(path, p_request->m_path); -} - -void http_asserts::assert_test_request_equals(const test_request* const p_request, - const ::http::method& mtd, - const utility::string_t& path, - const utility::string_t& content_type) -{ - VERIFY_ARE_EQUAL(mtd, p_request->m_method); - VERIFY_ARE_EQUAL(path, p_request->m_path); - - // verify that content-type key exists in the header and the value matches the one provided - auto iter = p_request->m_headers.find(U("Content-Type")); - if (content_type.empty()) - { - VERIFY_ARE_EQUAL(iter, p_request->m_headers.end()); - } - else - { - VERIFY_IS_TRUE(iter != p_request->m_headers.end()); - VERIFY_ARE_EQUAL(iter->second.find(content_type), 0); - } -} - -void http_asserts::assert_test_request_contains_headers(const test_request* const p_request, - const ::http::http_headers& headers) -{ - verify_headers(headers, p_request->m_headers); -} - -void http_asserts::assert_test_request_contains_headers(const test_request* const p_request, - const std::map<utility::string_t, utility::string_t>& headers) -{ - verify_headers(headers, p_request->m_headers); -} - -// Helper function to parse HTTP headers from a stringstream. -static std::map<utility::string_t, utility::string_t> parse_headers(utility::istringstream_t& ss) -{ - // Keep parsing until CRLF is encountered. - std::map<utility::string_t, utility::string_t> headers; - utility::string_t header_line; - while (getline(ss, header_line).good()) - { - const size_t colon_index = header_line.find(U(":")); - const utility::string_t header_name = header_line.substr(0, colon_index); - utility::string_t header_value = header_line.substr(colon_index + 1); - tests::functional::http::utilities::trim_whitespace(header_value); - headers[header_name] = header_value; - - char c1 = (char)ss.get(), c2 = (char)ss.get(); - if (c1 == '\r' && c2 == '\n') - { - break; - } - ss.unget(); - ss.unget(); - } - return headers; -} - -void http_asserts::assert_request_string_equals(const utility::string_t& request, - const ::http::method& mtd, - const utility::string_t& path, - const utility::string_t& version, - const std::map<utility::string_t, utility::string_t>& headers, - const utility::string_t& body) -{ - utility::istringstream_t ss(request); - - // Parse request line. - utility::string_t actual_method, actual_path, actual_version; - ss >> actual_method >> actual_path >> actual_version; - - // Parse headers. - utility::string_t temp; - getline(ss, temp); - std::map<utility::string_t, utility::string_t> actual_headers = parse_headers(ss); - - // Parse in any message body - utility::string_t actual_body = ss.str().substr((size_t)ss.tellg()); - - VERIFY_ARE_EQUAL(mtd, actual_method); - VERIFY_ARE_EQUAL(path, actual_path); - VERIFY_ARE_EQUAL(version, actual_version); - verify_headers(headers, actual_headers); - VERIFY_ARE_EQUAL(body, actual_body); -} - -void http_asserts::assert_response_string_equals(const utility::string_t& response, - const utility::string_t& version, - const ::http::status_code& code, - const utility::string_t& phrase, - const std::map<utility::string_t, utility::string_t>& headers, - const utility::string_t& body) -{ - utility::istringstream_t ss(response); - - // Parse response line. - utility::string_t actual_version, actual_phrase; - ::http::status_code actual_code; - ss >> actual_version >> actual_code >> actual_phrase; - - // Parse headers. - utility::string_t temp; - getline(ss, temp); - std::map<utility::string_t, utility::string_t> actual_headers = parse_headers(ss); - - // Prase in any message body. - utility::string_t actual_body = ss.str().substr((size_t)ss.tellg()); - - VERIFY_ARE_EQUAL(version, actual_version); - VERIFY_ARE_EQUAL(code, actual_code); - VERIFY_ARE_EQUAL(phrase, actual_phrase); - verify_headers(headers, actual_headers); - VERIFY_ARE_EQUAL(body, actual_body); -} - -void http_asserts::assert_test_request_equals(const test_request* const p_request, - const ::http::method& mtd, - const utility::string_t& path, - const utility::string_t& content_type, - const utility::string_t& body) -{ - assert_test_request_equals(p_request, mtd, path, content_type); - // Textual response is always sent as UTF-8, hence the converison to string_t - std::string s((char*)&p_request->m_body[0], p_request->m_body.size()); - utility::string_t extracted_body = to_string_t(s); - - VERIFY_ARE_EQUAL(body, extracted_body); -} - -void http_asserts::assert_test_response_equals(const test_response* const p_response, const ::http::status_code& code) -{ - VERIFY_ARE_EQUAL(code, p_response->m_status_code); -} - -void http_asserts::assert_test_response_equals(const test_response* const p_response, - const ::http::status_code& code, - const std::map<utility::string_t, utility::string_t>& headers) -{ - VERIFY_ARE_EQUAL(code, p_response->m_status_code); - verify_headers(headers, p_response->m_headers); -} - -void http_asserts::assert_test_response_equals(const test_response* const p_response, - const ::http::status_code& code, - const ::http::http_headers& headers) -{ - VERIFY_ARE_EQUAL(code, p_response->m_status_code); - verify_headers(headers, p_response->m_headers); -} - -void http_asserts::assert_test_response_equals(test_response* p_response, - const ::http::status_code& code, - const utility::string_t& content_type) -{ - VERIFY_ARE_EQUAL(code, p_response->m_status_code); - utility::string_t found_content; - p_response->match_header(U("Content-Type"), found_content); - VERIFY_ARE_EQUAL(content_type, found_content); -} - -void http_asserts::assert_test_response_equals(test_response* p_response, - const ::http::status_code& code, - const utility::string_t& content_type, - const utility::string_t data) -{ - VERIFY_ARE_EQUAL(code, p_response->m_status_code); - utility::string_t found_content; - p_response->match_header(U("Content-Type"), found_content); - VERIFY_ARE_EQUAL(found_content.find(content_type), 0); - - // Beware: what kind of string this is? <-- stringhack until we tighten up wide/narrow string business - utility::string_t extracted_body; - if (p_response->m_data.size() == 0) - { - extracted_body = U(""); - } - else - { - auto actualRawData = (char*)&p_response->m_data[0]; - if (p_response->m_data.size() > 1 && *(actualRawData + 1) == '\0') - { - // We have more than one byte of data, but it's null-terminated at byte 1. - // Therefore, this is a wide string - extracted_body.assign((utility::char_t*)actualRawData, p_response->m_data.size() / sizeof(utility::char_t)); - } - else - { - std::string s(actualRawData, p_response->m_data.size()); - extracted_body = to_string_t(s); - } - } - - VERIFY_ARE_EQUAL(data, extracted_body); -} - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/http_asserts.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/http_asserts.h @@ -1,238 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * http_asserts.h - Utility class to help verify assertions about http requests and responses. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "http_test_utilities_public.h" -#include "test_http_client.h" -#include "test_http_server.h" - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -template<class Char> -void trim_whitespace(std::basic_string<Char>& str) -{ - size_t index; - // trim left whitespace - for (index = 0; index < str.size() && isspace(str[index]); ++index) - ; - str.erase(0, index); - // trim right whitespace - for (index = str.size(); index > 0 && isspace(str[index - 1]); --index) - ; - str.erase(index); -} - -/// <summary> -/// Helper function to do percent encoding of just the '#' character, when running under WinRT. -/// The WinRT http client implementation performs percent encoding on the '#'. -/// </summary> -TEST_UTILITY_API utility::string_t __cdecl percent_encode_pound(utility::string_t str); - -/// <summary> -/// Static class containing various http request and response asserts. -/// </summary> -class http_asserts -{ -public: - /// <summary> - /// Asserts that the specified request is equal to given arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_request_equals(web::http::http_request request, - const web::http::method& mtd, - const utility::string_t& relative_uri); - - TEST_UTILITY_API static void __cdecl assert_request_equals( - web::http::http_request request, - const web::http::method& mtd, - const utility::string_t& relative_uri, - const std::map<utility::string_t, utility::string_t>& headers); - - TEST_UTILITY_API static void __cdecl assert_request_equals(web::http::http_request request, - const web::http::method& mtd, - const utility::string_t& relative_uri, - const utility::string_t& body); - - /// <summary> - /// Asserts that the specified response is equal to given arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_response_equals(web::http::http_response response, - const web::http::status_code& code); - - TEST_UTILITY_API static void __cdecl assert_response_equals(web::http::http_response response, - const web::http::status_code& code, - const utility::string_t& reason); - - TEST_UTILITY_API static void __cdecl assert_response_equals( - web::http::http_response response, - const web::http::status_code& code, - const std::map<utility::string_t, utility::string_t>& headers); - - /// <summary> - /// Asserts the given http_headers contains the given values. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_http_headers_equals(const web::http::http_headers& actual, - const web::http::http_headers& expected); - - /// <summary> - /// Asserts the specified test_request is equal to its arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_test_request_equals(const test_request* const p_request, - const web::http::method& mtd, - const utility::string_t& path); - - /// <summary> - /// Asserts the specified test_request is equal to its arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_test_request_equals(const test_request* const p_request, - const web::http::method& mtd, - const utility::string_t& path, - const utility::string_t& content_type); - - /// <summary> - /// Asserts the specified test_request is equal to its arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_test_request_contains_headers(const test_request* const p_request, - const web::http::http_headers& headers); - - /// <summary> - /// Asserts the specified test_request is equal to its arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_test_request_contains_headers( - const test_request* const p_request, const std::map<utility::string_t, utility::string_t>& headers); - - /// <summary> - /// Asserts the given HTTP request string is equal to its arguments. - /// NOTE: this function only makes sure the specified headers exist, not that they are the only ones. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_request_string_equals( - const utility::string_t& request, - const web::http::method& mtd, - const utility::string_t& path, - const utility::string_t& version, - const std::map<utility::string_t, utility::string_t>& headers, - const utility::string_t& body); - - /// <summary> - /// Asserts the given HTTP response string is equal to its arguments. - /// NOTE: this function only makes sure the specified headers exist, not that they are the only ones. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_response_string_equals( - const utility::string_t& response, - const utility::string_t& version, - const web::http::status_code& code, - const utility::string_t& phrase, - const std::map<utility::string_t, utility::string_t>& headers, - const utility::string_t& body); - - /// <summary> - /// Asserts the specified test_request is equal to its arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_test_request_equals(const test_request* const p_request, - const web::http::method& mtd, - const utility::string_t& path, - const utility::string_t& content_type, - const utility::string_t& body); - - /// <summary> - /// Asserts the specified test_response is equal to its arguments. - /// </summary> - TEST_UTILITY_API static void __cdecl assert_test_response_equals(const test_response* const p_response, - const web::http::status_code& code); - - TEST_UTILITY_API static void __cdecl assert_test_response_equals( - const test_response* const p_response, - const web::http::status_code& code, - const std::map<utility::string_t, utility::string_t>& headers); - - TEST_UTILITY_API static void __cdecl assert_test_response_equals(const test_response* const p_response, - const web::http::status_code& code, - const web::http::http_headers& headers); - - TEST_UTILITY_API static void __cdecl assert_test_response_equals(test_response* p_response, - const web::http::status_code& code, - const utility::string_t& content_type); - - TEST_UTILITY_API static void __cdecl assert_test_response_equals(test_response* p_response, - const web::http::status_code& code, - const utility::string_t& content_type, - const utility::string_t data); - -private: - http_asserts() {} - ~http_asserts() {} -}; - -#if defined(_WIN32) -#if _MSC_VER >= 1900 -#include <winapifamily.h> -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -// For IXMLHttpRequest with Windows 10, the error codes don't directly compare equal anymore. -// Relax verification for now. -#define HTTP_ERROR_CHECK_IMPL(__code) -#else -#define HTTP_ERROR_CHECK_IMPL(__code) \ - if (__code != _exc.error_code()) \ - { \ - VERIFY_IS_TRUE(false, "Unexpected error code encountered."); \ - } -#endif -#else -// The reason we can't directly compare with the given std::errc code is because -// on Windows the STL implementation of error categories are NOT unique across -// dll boundaries, until VS2015. -#define HTTP_ERROR_CHECK_IMPL(__code) \ - VERIFY_ARE_EQUAL(static_cast<int>(__code), _exc.error_code().default_error_condition().value()); -#endif -#else -#define HTTP_ERROR_CHECK_IMPL(__code) VERIFY_ARE_EQUAL(_exc.error_code(), __code, "Unexpected error code encountered.") -#endif - -// Helper function to verify http_exception is thrown with correct error code -#define VERIFY_THROWS_HTTP_ERROR_CODE(__expression, __code) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - try \ - { \ - __expression; \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \ - "Expected exception: \"web::http::http_exception\" not thrown"); \ - } \ - catch (const web::http::http_exception& _exc) \ - { \ - VERIFY_IS_TRUE(std::string(_exc.what()).size() > 0); \ - HTTP_ERROR_CHECK_IMPL(__code); \ - } \ - catch (const std::exception& _exc) \ - { \ - std::string _msg("(" #__expression ") threw exception: "); \ - _msg.append(_exc.what()); \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), _msg.c_str()); \ - } \ - catch (...) \ - { \ - std::string _msg("(" #__expression ") threw exception: <...>"); \ - UnitTest::CurrentTest::Results()->OnTestFailure( \ - UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), _msg.c_str()); \ - } \ - UNITTEST_MULTILINE_MACRO_END - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/http_test_utilities.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/http_test_utilities.h @@ -1,18 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * httpt_test_utilities.h -- This is the "one-stop-shop" header for including http test dependencies - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "http_asserts.h" -#include "http_test_utilities_public.h" -#include "test_http_client.h" -#include "test_http_server.h" -#include "test_server_utilities.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/http_test_utilities_public.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/http_test_utilities_public.h @@ -1,24 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * http_test_utilities_public.h -- Common definitions for public http test utility headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#if !defined(_WIN32) && !defined(__cplusplus_winrt) -#define TEST_UTILITY_API -#endif // !_WIN32 && !__cplusplus_winrt - -#ifndef TEST_UTILITY_API -#ifdef HTTPTESTUTILITY_EXPORTS -#define TEST_UTILITY_API __declspec(dllexport) -#else // HTTPTESTUTILITIES_EXPORTS -#define TEST_UTILITY_API __declspec(dllimport) -#endif // HTTPTESTUTILITIES_EXPORTS -#endif // TEST_UTILITY_API diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/test_http_client.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/test_http_client.h @@ -1,151 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * test_http_client.h -- Defines a test client to handle requests and sending responses. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/uri.h" -#include "http_test_utilities_public.h" -#include <map> -#include <unittestpp.h> -#include <vector> - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -class _test_http_client; - -/// <summary> -/// Structure for storing information about an HTTP response. -/// <summary> -class test_response -{ -public: - test_response(_test_http_client* client) : m_client(client) {} - - // API to check if a specific header exists and get it. - template<typename T> - bool match_header(const utility::string_t& header_name, T& header_value) - { - auto iter = m_headers.find(header_name); - - if (iter != m_headers.end()) - { - utility::istringstream_t iss(iter->second); - iss >> header_value; - if (iss.fail() || !iss.eof()) - { - return false; - } - return true; - } - else - { - return false; - } - } - - bool match_header(const utility::string_t& header_name, utility::string_t& header_value) - { - auto iter = m_headers.find(header_name); - if (iter != m_headers.end()) - { - header_value = m_headers[header_name]; - return true; - } - return false; - } - - // Response data. - unsigned short m_status_code; - utility::string_t m_reason_phrase; - std::map<utility::string_t, utility::string_t> m_headers; - std::vector<unsigned char> m_data; - - friend class _test_http_client; - _test_http_client* m_client; -}; - -/// <summary> -/// Basic HTTP client for testing. Supports sending multiple requests. -/// -/// NOTE: this HTTP client is not concurrency safe. I.e. only one thread at a time should use it. -/// </summary> -class test_http_client -{ -public: - TEST_UTILITY_API test_http_client(const web::http::uri& uri); - TEST_UTILITY_API ~test_http_client(); - TEST_UTILITY_API test_http_client(test_http_client&& other); - TEST_UTILITY_API test_http_client& operator=(test_http_client&& other); - - // APIs to open and close requests. - TEST_UTILITY_API unsigned long open(); - TEST_UTILITY_API unsigned long close(); - - // APIs to send requests. - TEST_UTILITY_API unsigned long request(const utility::string_t& method, const utility::string_t& path); - TEST_UTILITY_API unsigned long request(const utility::string_t& method, - const utility::string_t& path, - const std::map<utility::string_t, utility::string_t>& headers); - TEST_UTILITY_API unsigned long request(const utility::string_t& method, - const utility::string_t& path, - const std::string& data); - TEST_UTILITY_API unsigned long request(const utility::string_t& method, - const utility::string_t& path, - const utility::string_t& content_type, - const std::string& data); - TEST_UTILITY_API unsigned long request(const utility::string_t& method, - const utility::string_t& path, - const std::map<utility::string_t, utility::string_t>& headers, - const std::string& data); - - // APIs to receive responses. - TEST_UTILITY_API test_response* wait_for_response(); - TEST_UTILITY_API pplx::task<test_response*> next_response(); - TEST_UTILITY_API std::vector<test_response*> wait_for_responses(const size_t count); - TEST_UTILITY_API std::vector<pplx::task<test_response*>> next_responses(const size_t count); - - // RAII pattern for test_http_client. - class scoped_client - { - public: - scoped_client(const web::http::uri& uri) - { - m_p_client = new test_http_client(uri); - VERIFY_ARE_EQUAL(0u, m_p_client->open()); - } - ~scoped_client() - { - VERIFY_ARE_EQUAL(0u, m_p_client->close()); - delete m_p_client; - } - test_http_client* client() { return m_p_client; } - - private: - test_http_client* m_p_client; - }; - -private: - test_http_client& operator=(const test_http_client&); - test_http_client(const test_http_client&); - - std::unique_ptr<_test_http_client> m_impl; -}; - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/test_http_server.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/test_http_server.h @@ -1,141 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * test_http_server.h -- Defines a test server to handle requests and sending responses. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/uri.h" -#include "http_test_utilities_public.h" -#include "unittestpp.h" -#include <map> -#include <sstream> - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -/// <summary> -/// Actual implementation of test_http_server is in this class. -/// This wrapping is done to hide the fact we are using Windows HTTP Server APIs -/// from users of this test library. -/// </summary> -class _test_http_server; - -/// <summary> -/// Structure for storing HTTP request information and responding to requests. -/// </summary> -class test_request -{ - friend class _test_http_server; - -public: - test_request(unsigned long long reqid, _test_http_server* p_server) : m_request_id(reqid), m_p_server(p_server) {} - - // APIs to send responses. - unsigned long reply(const unsigned short status_code, - const utility::string_t& reason_phrase = U(""), - const std::map<utility::string_t, utility::string_t>& headers = - std::map<utility::string_t, utility::string_t>(), - const utf8string& data = "") - { - return reply_impl(status_code, reason_phrase, headers, (void*)&data[0], data.size() * sizeof(utf8char)); - } - - unsigned long reply(const unsigned short status_code, - const utility::string_t& reason_phrase, - const std::map<utility::string_t, utility::string_t>& headers, - const std::vector<uint8_t>& data) - { - return reply_impl(status_code, reason_phrase, headers, (void*)&data[0], data.size()); - } - - unsigned long reply(const unsigned short status_code, - const utility::string_t& reason_phrase, - const std::map<utility::string_t, utility::string_t>& headers, - const utf16string& data) - { - return reply_impl(status_code, reason_phrase, headers, (void*)&data[0], data.size() * sizeof(utf16char)); - } - - // API to check if a specific header exists and get it. - template<typename T> - bool match_header(const utility::string_t& header_name, T& header_value) - { - auto iter = m_headers.find(header_name); - if (iter == m_headers.end()) - { - return false; - } - - return web::http::details::bind_impl(iter->second, header_value) || iter->second.empty(); - } - - // Request data. - utility::string_t m_method; - utility::string_t m_path; - std::map<utility::string_t, utility::string_t> m_headers; - std::vector<unsigned char> m_body; - -private: - // This is the HTTP Server API Request Id, we don't want to bring in the header file. - unsigned long long m_request_id; - _test_http_server* m_p_server; - - // Helper to send replies. - TEST_UTILITY_API unsigned long reply_impl(const unsigned short status_code, - const utility::string_t& reason_phrase, - const std::map<utility::string_t, utility::string_t>& headers, - void* data, - size_t data_length); -}; - -/// <summary> -/// Basic HTTP server for testing. Supports waiting and collecting together requests. -/// -/// NOTE: this HTTP server is not concurrency safe. I.e. only one thread at a time should use it. -/// </summary> -class test_http_server -{ -public: - TEST_UTILITY_API test_http_server(const web::http::uri& uri); - TEST_UTILITY_API ~test_http_server(); - - // APIs to receive requests. - TEST_UTILITY_API pplx::task<test_request*> next_request(); - TEST_UTILITY_API std::vector<pplx::task<test_request*>> next_requests(const size_t count); - - // Enable early close - TEST_UTILITY_API void close(); - - // RAII pattern for test_http_server. - class scoped_server; - -private: - std::unique_ptr<_test_http_server> m_p_impl; -}; - -class test_http_server::scoped_server -{ -public: - scoped_server(const web::http::uri& uri) : m_p_server(uri) {} - test_http_server* server() { return &m_p_server; } - -private: - test_http_server m_p_server; -}; - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/test_server_utilities.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/include/test_server_utilities.h @@ -1,67 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * test_server_utilities.h - Utility class to send and verify requests and responses working with the http_test_server. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/http_client.h" -#include "http_test_utilities_public.h" -#include "test_http_server.h" - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -class test_server_utilities -{ -public: - /// <summary> - /// Sends request with specified values using given http_client and verifies - /// they are properly received by the test server. - /// </summary> - TEST_UTILITY_API static void __cdecl verify_request(web::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - test_http_server* p_server, - unsigned short code); - - TEST_UTILITY_API static void __cdecl verify_request(web::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - test_http_server* p_server, - unsigned short code, - const utility::string_t& reason); - - TEST_UTILITY_API static void __cdecl verify_request(web::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - const utility::string_t& request_content_type, - const utility::string_t& request_data, - test_http_server* p_server, - unsigned short code, - const utility::string_t& reason); - - TEST_UTILITY_API static void __cdecl verify_request( - web::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - test_http_server* p_server, - unsigned short code, - const std::map<utility::string_t, utility::string_t>& response_headers); -}; - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/stdafx.cpp @@ -1,10 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/stdafx.h @@ -1,26 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> - -#include <Windows.h> -#endif - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/http_client.h" -#include "cpprest/http_msg.h" -#include "cpprest/uri.h" -#include "include/http_asserts.h" -#include "unittestpp.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/test_http_client.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/test_http_client.cpp @@ -1,537 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Defines a test client to handle requests and sending responses. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "test_http_client.h" - -#include "cpprest/details/http_helpers.h" -#include "cpprest/uri.h" -#ifdef _WIN32 -#include <winhttp.h> -#pragma comment(lib, "winhttp.lib") -#pragma warning(push) -#pragma warning(disable : 4457) -#include <agents.h> -#pragma warning(pop) -#endif - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -// Flatten the http_headers into a name:value pairs separated by a carriage return and line feed. -utility::string_t flatten_http_headers(const std::map<utility::string_t, utility::string_t>& headers) -{ - utility::string_t flattened_headers; - for (auto iter = headers.begin(); iter != headers.end(); ++iter) - { - utility::string_t temp((*iter).first + U(":") + (*iter).second + U("\r\n")); - flattened_headers.append(utility::string_t(temp.begin(), temp.end())); - } - return flattened_headers; -} - -#ifdef _WIN32 - -// Helper function to query for the size of header values. -static void query_header_length(HINTERNET request_handle, DWORD header, DWORD& length) -{ - WinHttpQueryHeaders(request_handle, - header, - WINHTTP_HEADER_NAME_BY_INDEX, - WINHTTP_NO_OUTPUT_BUFFER, - &length, - WINHTTP_NO_HEADER_INDEX); -} - -// Helper function to get the status code from a WinHTTP response. -static void parse_status_code(HINTERNET request_handle, unsigned short& code) -{ - DWORD length = 0; - query_header_length(request_handle, WINHTTP_QUERY_STATUS_CODE, length); - utility::string_t buffer; - buffer.resize(length); - WinHttpQueryHeaders(request_handle, - WINHTTP_QUERY_STATUS_CODE, - WINHTTP_HEADER_NAME_BY_INDEX, - &buffer[0], - &length, - WINHTTP_NO_HEADER_INDEX); - code = (unsigned short)_wtoi(buffer.c_str()); -} - -// Helper function to trim leading and trailing null characters from a string. -static void trim_nulls(utility::string_t& str) -{ - size_t index; - for (index = 0; index < str.size() && str[index] == 0; ++index) - ; - str.erase(0, index); - index; - for (index = str.size(); index > 0 && str[index - 1] == 0; --index) - ; - str.erase(index); -} - -// Helper function to get the reason phrase from a WinHTTP response. -static void parse_reason_phrase(HINTERNET request_handle, utility::string_t& phrase) -{ - DWORD length = 0; - query_header_length(request_handle, WINHTTP_QUERY_STATUS_TEXT, length); - phrase.resize(length); - WinHttpQueryHeaders(request_handle, - WINHTTP_QUERY_STATUS_TEXT, - WINHTTP_HEADER_NAME_BY_INDEX, - &phrase[0], - &length, - WINHTTP_NO_HEADER_INDEX); - // WinHTTP reports back the wrong length, trim any null characters. - trim_nulls(phrase); -} - -/// <summary> -/// Parses a string containing Http headers. -/// </summary> -static void parse_winhttp_headers(HINTERNET request_handle, utf16char* headersStr, test_response* p_response) -{ - // Status code and reason phrase. - parse_status_code(request_handle, p_response->m_status_code); - parse_reason_phrase(request_handle, p_response->m_reason_phrase); - - utf16char* context = nullptr; - utf16char* line = wcstok_s(headersStr, U("\r\n"), &context); - while (line != nullptr) - { - const utility::string_t header_line(line); - const size_t colonIndex = header_line.find_first_of(U(":")); - if (colonIndex != utility::string_t::npos) - { - utility::string_t key = header_line.substr(0, colonIndex); - utility::string_t value = header_line.substr(colonIndex + 1, header_line.length() - colonIndex - 1); - tests::functional::http::utilities::trim_whitespace(key); - tests::functional::http::utilities::trim_whitespace(value); - p_response->m_headers[key] = value; - } - line = wcstok_s(nullptr, U("\r\n"), &context); - } -} - -class _test_http_client -{ -public: - _test_http_client(const utility::string_t& uri) : m_uri(uri), m_hSession(nullptr), m_hConnection(nullptr) {} - - unsigned long open() - { - // Open session. - m_hSession = WinHttpOpen(U("test_http_client"), - WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, - WINHTTP_NO_PROXY_NAME, - WINHTTP_NO_PROXY_BYPASS, - WINHTTP_FLAG_ASYNC); - if (!m_hSession) - { - return GetLastError(); - } - - // Set timeouts. - int multiplier = 10; - if (!WinHttpSetTimeouts( - m_hSession, 60000 * multiplier, 60000 * multiplier, 30000 * multiplier, 30000 * multiplier)) - { - return GetLastError(); - } - - // Set max connection to use per server to 1. - DWORD maxConnections = 1; - if (!WinHttpSetOption(m_hSession, WINHTTP_OPTION_MAX_CONNS_PER_SERVER, &maxConnections, sizeof(maxConnections))) - { - return GetLastError(); - } - - // Register asynchronous callback. - if (WINHTTP_INVALID_STATUS_CALLBACK == - WinHttpSetStatusCallback( - m_hSession, &_test_http_client::completion_callback, WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS, 0)) - { - return GetLastError(); - } - - // Open connection. - ::http::uri u(m_uri); - unsigned int port = u.is_port_default() ? INTERNET_DEFAULT_PORT : u.port(); - m_hConnection = WinHttpConnect(m_hSession, u.host().c_str(), (INTERNET_PORT)port, 0); - if (m_hConnection == nullptr) - { - return GetLastError(); - } - return 0; - } - - unsigned long close() - { - // Release memory for each request. - std::for_each( - m_responses_memory.begin(), m_responses_memory.end(), [](test_response* p_response) { delete p_response; }); - - if (m_hConnection != nullptr) - { - if (WinHttpCloseHandle(m_hConnection) == NULL) - { - return GetLastError(); - } - } - - if (m_hSession != nullptr) - { - // Unregister the callback. - if (!WinHttpSetStatusCallback(m_hSession, NULL, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL)) - { - return GetLastError(); - } - - if (WinHttpCloseHandle(m_hSession) == NULL) - { - return GetLastError(); - } - } - return 0; - } - - unsigned long request(const utility::string_t& method, - const utility::string_t& path, - const std::map<utility::string_t, utility::string_t> headers, - void* data, - size_t data_length) - { - HINTERNET request_handle = WinHttpOpenRequest( - m_hConnection, method.c_str(), path.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); - if (request_handle == nullptr) - { - return GetLastError(); - } - - // Add headers. - if (!headers.empty()) - { - utility::string_t flattened_headers = flatten_http_headers(headers); - if (!WinHttpAddRequestHeaders(request_handle, - flattened_headers.c_str(), - (DWORD)flattened_headers.length(), - WINHTTP_ADDREQ_FLAG_ADD)) - { - return GetLastError(); - } - } - - if (!WinHttpSendRequest(request_handle, - WINHTTP_NO_ADDITIONAL_HEADERS, - 0, - data, - (DWORD)data_length, - (DWORD)data_length, - (DWORD_PTR) new test_response(this))) - { - return GetLastError(); - } - return 0; - } - - test_response* wait_for_response() { return wait_for_responses(1)[0]; } - - pplx::task<test_response*> next_response() - { - return pplx::create_task([this]() -> test_response* { return wait_for_response(); }); - } - - std::vector<test_response*> wait_for_responses(const size_t count) - { - std::vector<test_response*> m_test_responses; - for (size_t i = 0; i < count; ++i) - { - m_test_responses.push_back(Concurrency::receive(m_responses)); - } - return m_test_responses; - } - - std::vector<pplx::task<test_response*>> next_responses(const size_t count) - { - std::vector<pplx::task_completion_event<test_response*>> events; - std::vector<pplx::task<test_response*>> responses; - for (size_t i = 0; i < count; ++i) - { - events.push_back(pplx::task_completion_event<test_response*>()); - responses.push_back(pplx::create_task(events[i])); - } - pplx::create_task([this, count, events]() { - for (size_t i = 0; i < count; ++i) - { - events[i].set(wait_for_response()); - } - }); - return responses; - } - -private: - // WinHTTP callback. - static void CALLBACK - completion_callback(HINTERNET hRequestHandle, DWORD_PTR context, DWORD statusCode, void* statusInfo, DWORD) - { - test_response* p_response = reinterpret_cast<test_response*>(context); - if (p_response != nullptr) - { - if (statusCode == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR) - { - WINHTTP_ASYNC_RESULT* pStatusInfo = static_cast<WINHTTP_ASYNC_RESULT*>(statusInfo); - pStatusInfo; - throw std::exception("Error in WinHTTP callback"); - } - else if (statusCode == WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE) - { - if (!WinHttpReceiveResponse(hRequestHandle, NULL)) - { - throw std::exception("Error receiving response"); - } - } - else if (statusCode == WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE) - { - DWORD headers_length; - WinHttpQueryHeaders(hRequestHandle, - WINHTTP_QUERY_RAW_HEADERS_CRLF, - WINHTTP_HEADER_NAME_BY_INDEX, - WINHTTP_NO_OUTPUT_BUFFER, - &headers_length, - WINHTTP_NO_HEADER_INDEX); - - // Now allocate buffer for headers and query for them. - std::vector<unsigned char> header_raw_buffer; - header_raw_buffer.resize(headers_length); - utf16char* header_buffer = reinterpret_cast<utf16char*>(&header_raw_buffer[0]); - if (!WinHttpQueryHeaders(hRequestHandle, - WINHTTP_QUERY_RAW_HEADERS_CRLF, - WINHTTP_HEADER_NAME_BY_INDEX, - header_buffer, - &headers_length, - WINHTTP_NO_HEADER_INDEX)) - { - throw std::exception("Error querying for headers"); - } - parse_winhttp_headers(hRequestHandle, header_buffer, p_response); - - // Check to see if the response has a body or not. - if (!WinHttpQueryDataAvailable(hRequestHandle, nullptr)) - { - throw std::exception("Error reading response body"); - } - } - else if (statusCode == WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE) - { - DWORD num_bytes = *(PDWORD)statusInfo; - - if (num_bytes > 0) - { - size_t current_size = p_response->m_data.size(); - p_response->m_data.resize(current_size + (size_t)num_bytes); - - // Actual WinHTTP call to read in body. - if (!WinHttpReadData(hRequestHandle, &p_response->m_data[current_size], (DWORD)num_bytes, NULL)) - { - throw std::exception("Error reading response body"); - } - } - else - { - WinHttpCloseHandle(hRequestHandle); - p_response->m_client->m_responses_memory.push_back(p_response); - Concurrency::asend(p_response->m_client->m_responses, p_response); - } - } - else if (statusCode == WINHTTP_CALLBACK_STATUS_READ_COMPLETE) - { - if (!WinHttpQueryDataAvailable(hRequestHandle, nullptr)) - { - throw std::exception("Error reading response body"); - } - } - } - } - - Concurrency::unbounded_buffer<test_response*> m_responses; - - // Used to store all requests to simplify memory management. - std::vector<test_response*> m_responses_memory; - - const utility::string_t m_uri; - HINTERNET m_hSession; - HINTERNET m_hConnection; -}; -#else -class _test_http_client -{ -private: - const web::http::uri m_uri; - typename web::http::client::http_client m_client; - std::vector<pplx::task<web::http::http_response>> m_responses; - std::vector<test_response*> m_test_responses; - -public: - _test_http_client(utility::string_t uri) : m_uri(web::http::uri::encode_uri(uri)), m_client(m_uri.authority()) {} - - unsigned long open() { return 0; } - unsigned long close() { return 0; } - - unsigned long request(const utility::string_t& method, - const utility::string_t& path, - const std::map<utility::string_t, utility::string_t>& headers, - void* data, - size_t data_length) - { - auto localHeaders = headers; - localHeaders["User-Agent"] = "test_http_client"; - web::http::http_request request; - request.set_method(method); - request.set_request_uri(web::http::uri_builder(m_uri).append_path(path).to_uri()); - auto& hDest = request.headers(); - for (auto it = localHeaders.begin(); it != localHeaders.end(); ++it) - { - auto& currentValue = hDest[it->first]; - if (currentValue.empty()) - currentValue = it->second; - else - currentValue = currentValue + U(", ") + it->second; - } - request.set_body(utility::string_t(reinterpret_cast<const char*>(data), data_length)); - - m_responses.push_back(m_client.request(request)); - return 0; - } - - test_response* wait_for_response() { return wait_for_responses(1)[0]; } - - pplx::task<test_response*> next_response() - { - return pplx::create_task([this]() -> test_response* { return wait_for_response(); }); - } - - std::vector<test_response*> wait_for_responses(const size_t count) - { - if (count > m_responses.size()) throw std::logic_error("count too big"); - - std::vector<test_response*> m_test_responses; - for (size_t i = 0; i < count; ++i) - { - auto response = m_responses[0].get(); - - auto tr = new test_response(this); - tr->m_status_code = response.status_code(); - tr->m_reason_phrase = response.reason_phrase(); - for (auto it = response.headers().begin(); it != response.headers().end(); ++it) - { - tr->m_headers[it->first] = it->second; - } - tr->m_data = response.extract_vector().get(); - - m_test_responses.push_back(tr); - m_responses.erase(m_responses.begin()); - } - return m_test_responses; - } - - std::vector<pplx::task<test_response*>> next_responses(const size_t count) - { - std::vector<pplx::task<test_response*>> result; - for (size_t i = 0; i < count; ++i) - { - result.push_back(next_response()); - } - return result; - } -}; -#endif - -test_http_client::test_http_client(const web::http::uri& uri) -{ - m_impl = std::unique_ptr<_test_http_client>(new _test_http_client(uri.to_string())); -} - -test_http_client::~test_http_client() {} - -test_http_client::test_http_client(test_http_client&& other) : m_impl(std::move(other.m_impl)) {} - -test_http_client& test_http_client::operator=(test_http_client&& other) -{ - if (this != &other) - { - this->m_impl = std::move(other.m_impl); - } - return *this; -} - -unsigned long test_http_client::open() { return m_impl->open(); } -unsigned long test_http_client::close() { return m_impl->close(); } - -unsigned long test_http_client::request(const utility::string_t& method, const utility::string_t& path) -{ - return request(method, path, std::map<utility::string_t, utility::string_t>()); -} -unsigned long test_http_client::request(const utility::string_t& method, - const utility::string_t& path, - const std::map<utility::string_t, utility::string_t>& headers) -{ - return request(method, path, headers, std::string()); -} -unsigned long test_http_client::request(const utility::string_t& method, - const utility::string_t& path, - const std::string& data) -{ - return request(method, path, std::map<utility::string_t, utility::string_t>(), data); -} -unsigned long test_http_client::request(const utility::string_t& method, - const utility::string_t& path, - const utility::string_t& content_type, - const std::string& data) -{ - std::map<utility::string_t, utility::string_t> headers; - headers[U("Content-Type")] = content_type; - return request(method, path, headers, data); -} - -unsigned long test_http_client::request(const utility::string_t& method, - const utility::string_t& path, - const std::map<utility::string_t, utility::string_t>& headers, - const std::string& data) -{ - return m_impl->request(method, path, headers, (void*)&data[0], data.size()); -} - -test_response* test_http_client::wait_for_response() { return m_impl->wait_for_response(); } -pplx::task<test_response*> test_http_client::next_response() { return m_impl->next_response(); } -std::vector<test_response*> test_http_client::wait_for_responses(const size_t count) -{ - return m_impl->wait_for_responses(count); -} -std::vector<pplx::task<test_response*>> test_http_client::next_responses(const size_t count) -{ - return m_impl->next_responses(count); -} - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/test_http_server.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/test_http_server.cpp @@ -1,602 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Defines a test server to handle requests and sending responses. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -#ifdef _WIN32 -#include <http.h> -#pragma comment(lib, "httpapi.lib") -#pragma warning(push) -#pragma warning(disable : 4457) -#include <agents.h> -#pragma warning(pop) -#else -#include "cpprest/http_listener.h" -#endif -#include "cpprest/uri.h" -#include "test_http_server.h" -#include <algorithm> -#include <mutex> -#include <os_utilities.h> -#include <thread> - -using namespace web; -using namespace utility; -using namespace utility::conversions; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -struct test_server_queue -{ - std::mutex m_lock; - std::deque<pplx::task_completion_event<test_request*>> m_requests; - std::vector<std::unique_ptr<test_request>> m_requests_memory; - - void close() - { - std::lock_guard<std::mutex> lk(m_lock); - for (auto&& tce : m_requests) - tce.set_exception(std::runtime_error("test_http_server closed.")); - } - - ~test_server_queue() { close(); } - - void on_request(std::unique_ptr<test_request> req) - { - std::lock_guard<std::mutex> lk(m_lock); - VERIFY_IS_FALSE(m_requests.empty(), "There are no pending calls to next_request."); - if (m_requests.empty()) return; - auto tce = std::move(m_requests.front()); - m_requests.pop_front(); - m_requests_memory.push_back(std::move(req)); - tce.set(m_requests_memory.back().get()); - } - - pplx::task<test_request*> next_request() - { - pplx::task_completion_event<test_request*> tce; - std::lock_guard<std::mutex> lock(m_lock); - m_requests.push_back(tce); - return pplx::create_task(tce); - } -}; - -#if defined(_WIN32) -// Helper function to parse verb from Windows HTTP Server API. -static utility::string_t parse_verb(const HTTP_REQUEST* p_http_request) -{ - utility::string_t method; - std::string temp; - switch (p_http_request->Verb) - { - case HttpVerbGET: method = U("GET"); break; - case HttpVerbPOST: method = U("POST"); break; - case HttpVerbPUT: method = U("PUT"); break; - case HttpVerbDELETE: method = U("DELETE"); break; - case HttpVerbHEAD: method = U("HEAD"); break; - case HttpVerbOPTIONS: method = U("OPTIONS"); break; - case HttpVerbTRACE: method = U("TRACE"); break; - case HttpVerbCONNECT: method = U("CONNECT"); break; - case HttpVerbUnknown: temp = p_http_request->pUnknownVerb; method = utility::string_t(temp.begin(), temp.end()); - default: break; - } - return method; -} - -/// <summary> -/// String values for all HTTP Server API HTTP_REQUEST_HEADERS known headers. -/// NOTE: the order here is important it is from the _HTTP_HEADER_ID enum. -/// </summary> -static utility::string_t HttpServerAPIRequestKnownHeaders[] = -{ - U("Cache-Control"), - U("Connection"), - U("Date"), - U("Keep-Alive"), - U("Pragma"), - U("Trailer"), - U("Transfer-Encoding"), - U("Upgrade"), - U("Via"), - U("Warning"), - U("Allow"), - U("Content-Length"), - U("Content-Type"), - U("Content-Encoding"), - U("Content-Language"), - U("Content-Location"), - U("Content-MD5"), - U("Content-Range"), - U("Expires"), - U("Last-Modified"), - U("Accept"), - U("Accept-Charset"), - U("Accept-Encoding"), - U("Accept-Language"), - U("Authorization"), - U("Cookie"), - U("Expect"), - U("From"), - U("Host"), - U("If-Match"), - U("If-Modified-Since"), - U("If-None-Match"), - U("If-Range"), - U("If-Unmodified-Since"), - U("Max-Forwards"), - U("Proxy-Authorization"), - U("Referer"), - U("Range"), - U("TE"), - U("Translate"), - U("User-Agent") -}; - -static utility::string_t char_to_wstring(const char* src) -{ - if (src == nullptr) - { - return utility::string_t(); - } - std::string temp(src); - return utility::string_t(temp.begin(), temp.end()); -} - -static std::map<utility::string_t, utility::string_t> parse_http_headers(const HTTP_REQUEST_HEADERS& headers) -{ - std::map<utility::string_t, utility::string_t> headers_map; - for (USHORT i = 0; i < headers.UnknownHeaderCount; ++i) - { - headers_map[char_to_wstring(headers.pUnknownHeaders[i].pName)] = - char_to_wstring(headers.pUnknownHeaders[i].pRawValue); - } - for (int i = 0; i < HttpHeaderMaximum; ++i) - { - if (headers.KnownHeaders[i].RawValueLength != 0) - { - headers_map[HttpServerAPIRequestKnownHeaders[i]] = char_to_wstring(headers.KnownHeaders[i].pRawValue); - } - } - return headers_map; -} - -struct ConcRTOversubscribe -{ - ConcRTOversubscribe() - { -#if _MSC_VER >= 1800 - concurrency::Context::Oversubscribe(true); -#endif - } - ~ConcRTOversubscribe() - { -#if _MSC_VER >= 1800 - concurrency::Context::Oversubscribe(false); -#endif - } -}; - -class _test_http_server -{ - inline bool is_error_code(ULONG error_code) - { - return error_code == ERROR_OPERATION_ABORTED || error_code == ERROR_CONNECTION_INVALID || - error_code == ERROR_NETNAME_DELETED || m_closing == 1; - } - -public: - _test_http_server(const web::uri& uri) : m_uri(uri), m_session(0), m_url_group(0), m_request_queue(nullptr) - { - // Open server session. - HTTPAPI_VERSION httpApiVersion = HTTPAPI_VERSION_2; - HttpInitialize(httpApiVersion, HTTP_INITIALIZE_SERVER, NULL); - ULONG error_code = HttpCreateServerSession(httpApiVersion, &m_session, 0); - if (error_code) - { - throw std::runtime_error("error code: " + std::to_string(error_code)); - } - - // Create Url group. - error_code = HttpCreateUrlGroup(m_session, &m_url_group, 0); - if (error_code) - { - throw std::runtime_error("error code: " + std::to_string(error_code)); - } - - // Create request queue. - error_code = HttpCreateRequestQueue(httpApiVersion, U("test_http_server"), NULL, NULL, &m_request_queue); - if (error_code) - { - throw std::runtime_error("error code: " + std::to_string(error_code)); - } - - // Windows HTTP Server API will not accept a uri with an empty path, it must have a '/'. - auto host_uri = uri.to_string(); - if (uri.is_path_empty() && host_uri[host_uri.length() - 1] != '/' && uri.query().empty() && - uri.fragment().empty()) - { - host_uri.append(U("/")); - } - - // Add Url. - error_code = HttpAddUrlToUrlGroup(m_url_group, host_uri.c_str(), (HTTP_URL_CONTEXT)this, 0); - if (error_code) - { - throw std::runtime_error("error code: " + std::to_string(error_code)); - } - - // Associate Url group with request queue. - HTTP_BINDING_INFO bindingInfo; - bindingInfo.RequestQueueHandle = m_request_queue; - bindingInfo.Flags.Present = 1; - error_code = - HttpSetUrlGroupProperty(m_url_group, HttpServerBindingProperty, &bindingInfo, sizeof(HTTP_BINDING_INFO)); - if (error_code) - { - throw std::runtime_error("error code: " + std::to_string(error_code)); - } - - // Launch listener thread - m_thread = std::thread( - [](_test_http_server* self) { - for (;;) - { - auto req = self->sync_get_request(); - if (req == nullptr) break; - - self->m_queue.on_request(std::move(req)); - } - }, - this); - } - - ~_test_http_server() - { - close(); - - m_thread.join(); - - HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); - } - - std::unique_ptr<test_request> sync_get_request() - { - ConcRTOversubscribe osubs; // Oversubscription for long running ConcRT tasks - const ULONG buffer_length = 1024 * 4; - char buffer[buffer_length]; - ULONG bytes_received = 0; - HTTP_REQUEST* p_http_request = (HTTP_REQUEST*)buffer; - - // Read in everything except the body. - ULONG error_code2 = - HttpReceiveHttpRequest(m_request_queue, HTTP_NULL_ID, 0, p_http_request, buffer_length, &bytes_received, 0); - if (error_code2 != 0) - { - return nullptr; - } - - // Now create request structure. - auto p_test_request = std::unique_ptr<test_request>(new test_request(p_http_request->RequestId, this)); - p_test_request->m_path = utf8_to_utf16(p_http_request->pRawUrl); - p_test_request->m_method = parse_verb(p_http_request); - p_test_request->m_headers = parse_http_headers(p_http_request->Headers); - - // Read in request body. - ULONG content_length; - const bool has_content_length = p_test_request->match_header(U("Content-Length"), content_length); - if (has_content_length && content_length > 0) - { - p_test_request->m_body.resize(content_length); - auto result = HttpReceiveRequestEntityBody(m_request_queue, - p_http_request->RequestId, - HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER, - &p_test_request->m_body[0], - content_length, - &bytes_received, - NULL); - if (result != 0) return nullptr; - } - - utility::string_t transfer_encoding; - const bool has_transfer_encoding = p_test_request->match_header(U("Transfer-Encoding"), transfer_encoding); - if (has_transfer_encoding && transfer_encoding.find(U("chunked")) != std::string::npos) - { - content_length = 0; - char buf[4096]; - auto result = HttpReceiveRequestEntityBody(m_request_queue, - p_http_request->RequestId, - HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER, - (LPVOID)buf, - 4096, - &bytes_received, - NULL); - - while (result == NO_ERROR) - { - content_length += bytes_received; - p_test_request->m_body.resize(content_length); - memcpy(&p_test_request->m_body[content_length - bytes_received], buf, bytes_received); - - result = HttpReceiveRequestEntityBody(m_request_queue, - p_http_request->RequestId, - HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER, - (LPVOID)buf, - 4096, - &bytes_received, - NULL); - } - - if (is_error_code(result)) - return nullptr; - else - VERIFY_ARE_EQUAL(ERROR_HANDLE_EOF, result); - } - - return p_test_request; - } - - unsigned long close() - { - m_closing = 1; - - // Windows HTTP Server API will not accept a uri with an empty path, it must have a '/'. - utility::string_t host_uri = m_uri.to_string(); - if (m_uri.is_path_empty() && host_uri[host_uri.length() - 1] != '/' && m_uri.query().empty() && - m_uri.fragment().empty()) - { - host_uri.append(U("/")); - } - - // Remove Url. - ULONG error_code = HttpRemoveUrlFromUrlGroup(m_url_group, host_uri.c_str(), 0); - if (error_code) - { - return error_code; - } - - // Stop request queue. - error_code = HttpShutdownRequestQueue(m_request_queue); - if (error_code) - { - return error_code; - } - - // Close all resources. - HttpCloseRequestQueue(m_request_queue); - HttpCloseUrlGroup(m_url_group); - HttpCloseServerSession(m_session); - - m_queue.close(); - - return 0; - } - - unsigned long send_reply(const unsigned long long request_id, - const unsigned short status_code, - const utility::string_t& reason_phrase, - const std::map<utility::string_t, utility::string_t>& headers, - void* data, - size_t data_length) - { - ConcRTOversubscribe osubs; // Oversubscription for long running ConcRT tasks - HTTP_RESPONSE response; - ZeroMemory(&response, sizeof(HTTP_RESPONSE)); - response.StatusCode = status_code; -#pragma warning(suppress: 4244) // intentionally narrow wchar_t -> char - std::string reason(reason_phrase.begin(), reason_phrase.end()); - response.pReason = reason.c_str(); - response.ReasonLength = (USHORT)reason.length(); - - // Add headers. - std::vector<std::string> headers_buffer; - response.Headers.UnknownHeaderCount = (USHORT)headers.size() + 1; - response.Headers.pUnknownHeaders = new HTTP_UNKNOWN_HEADER[headers.size() + 1]; - headers_buffer.resize(headers.size() * 2 + 2); - - // Add the no cache header. - headers_buffer[0] = "Cache-Control"; - headers_buffer[1] = "no-cache"; - response.Headers.pUnknownHeaders[0].NameLength = (USHORT)headers_buffer[0].size(); - response.Headers.pUnknownHeaders[0].pName = headers_buffer[0].c_str(); - response.Headers.pUnknownHeaders[0].RawValueLength = (USHORT)headers_buffer[1].size(); - response.Headers.pUnknownHeaders[0].pRawValue = headers_buffer[1].c_str(); - - // Add all other headers. - if (!headers.empty()) - { - int headerIndex = 1; - for (auto iter = headers.begin(); iter != headers.end(); ++iter, ++headerIndex) - { - headers_buffer[headerIndex * 2] = utf16_to_utf8(iter->first); - headers_buffer[headerIndex * 2 + 1] = utf16_to_utf8(iter->second); - - // TFS 624150 -#pragma warning(push) -#pragma warning(disable : 6386) - response.Headers.pUnknownHeaders[headerIndex].NameLength = - (USHORT)headers_buffer[headerIndex * 2].size(); -#pragma warning(pop) - - response.Headers.pUnknownHeaders[headerIndex].pName = headers_buffer[headerIndex * 2].c_str(); - response.Headers.pUnknownHeaders[headerIndex].RawValueLength = - (USHORT)headers_buffer[headerIndex * 2 + 1].size(); - response.Headers.pUnknownHeaders[headerIndex].pRawValue = headers_buffer[headerIndex * 2 + 1].c_str(); - } - } - - // Add body. - response.EntityChunkCount = 0; - HTTP_DATA_CHUNK dataChunk; - if (data_length != 0) - { - response.EntityChunkCount = 1; - dataChunk.DataChunkType = HttpDataChunkFromMemory; - dataChunk.FromMemory.pBuffer = (void*)data; - dataChunk.FromMemory.BufferLength = (ULONG)data_length; - response.pEntityChunks = &dataChunk; - } - - // Synchronously sending the request. - unsigned long error_code = HttpSendHttpResponse(m_request_queue, - request_id, - HTTP_SEND_RESPONSE_FLAG_DISCONNECT, - &response, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - - // Free memory needed for headers. - if (response.Headers.UnknownHeaderCount != 0) - { - delete[] response.Headers.pUnknownHeaders; - } - - return error_code; - } - -public: - test_server_queue m_queue; - -private: - std::atomic<int> m_closing = 0; - - web::uri m_uri; - HTTP_SERVER_SESSION_ID m_session; - HTTP_URL_GROUP_ID m_url_group; - HANDLE m_request_queue; - - std::thread m_thread; -}; -#else -class _test_http_server -{ -public: - test_server_queue m_queue; - -private: - web::http::experimental::listener::http_listener m_listener; - - std::atomic<unsigned long> m_last_request_id; - - std::mutex m_response_lock; - std::unordered_map<unsigned long long, web::http::http_request> m_responding_requests; - -public: - _test_http_server(const web::uri& uri) : m_listener(uri), m_last_request_id(0) - { - auto handler = [this](web::http::http_request result) -> void { - auto tr = std::unique_ptr<test_request>(new test_request(this->m_last_request_id++, this)); - tr->m_method = result.method(); - tr->m_path = result.request_uri().resource().to_string(); - if (tr->m_path.empty()) tr->m_path = U("/"); - - for (auto it = result.headers().begin(); it != result.headers().end(); ++it) - tr->m_headers[it->first] = it->second; - - tr->m_body = result.extract_vector().get(); - - { - std::lock_guard<std::mutex> lock(m_response_lock); - m_responding_requests[tr->m_request_id] = result; - } - - m_queue.on_request(std::move(tr)); - }; - m_listener.support(handler); - m_listener.support(web::http::methods::OPTIONS, handler); - m_listener.support(web::http::methods::TRCE, handler); - - m_listener.open().wait(); - } - - ~_test_http_server() { close(); } - - void close() - { - m_listener.close().wait(); - m_queue.close(); - } - - unsigned long send_reply(unsigned long long request_id, - const unsigned short status_code, - const utility::string_t& reason_phrase, - const std::map<utility::string_t, utility::string_t>& headers, - void* data, - size_t data_length) - { - web::http::http_request request; - { - std::lock_guard<std::mutex> lock(m_response_lock); - auto it = m_responding_requests.find(request_id); - if (it == m_responding_requests.end()) throw std::runtime_error("no such request awaiting response"); - request = it->second; - m_responding_requests.erase(it); - } - - web::http::http_response response; - response.set_status_code(status_code); - response.set_reason_phrase(reason_phrase); - - for (auto it = headers.begin(); it != headers.end(); ++it) - response.headers().add(it->first, it->second); - - unsigned char* data_bytes = reinterpret_cast<unsigned char*>(data); - std::vector<unsigned char> body_data(data_bytes, data_bytes + data_length); - response.set_body(std::move(body_data)); - - request.reply(response).get(); - - return 0; - } -}; -#endif - -unsigned long test_request::reply_impl(const unsigned short status_code, - const utility::string_t& reason_phrase, - const std::map<utility::string_t, utility::string_t>& headers, - void* data, - size_t data_length) -{ - return m_p_server->send_reply(m_request_id, status_code, reason_phrase, headers, data, data_length); -} - -test_http_server::test_http_server(const web::http::uri& uri) -{ - m_p_impl = std::unique_ptr<_test_http_server>(new _test_http_server(uri)); -} - -test_http_server::~test_http_server() {} - -pplx::task<test_request*> test_http_server::next_request() { return m_p_impl->m_queue.next_request(); } - -std::vector<pplx::task<test_request*>> test_http_server::next_requests(const size_t count) -{ - std::vector<pplx::task<test_request*>> ret; - ret.reserve(count); - for (size_t x = 0; x < count; ++x) - ret.push_back(next_request()); - return ret; -} - -void test_http_server::close() { m_p_impl->close(); } - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/test_server_utilities.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/http/utilities/test_server_utilities.cpp @@ -1,90 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * test_server_utilities.h - Utility class to send and verify requests and responses working with the http_test_server. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include "test_server_utilities.h" - -#include "http_asserts.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace http -{ -namespace utilities -{ -void test_server_utilities::verify_request(::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - test_http_server* p_server, - unsigned short code) -{ - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, path); - VERIFY_ARE_EQUAL(0, p_request->reply(code)); - }); - http_asserts::assert_response_equals(p_client->request(method, path).get(), code); -} - -void test_server_utilities::verify_request(::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - test_http_server* p_server, - unsigned short code, - const utility::string_t& reason) -{ - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, path); - VERIFY_ARE_EQUAL(0, p_request->reply(code, reason)); - }); - http_asserts::assert_response_equals(p_client->request(method, path).get(), code, reason); -} - -void test_server_utilities::verify_request(::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - const utility::string_t& request_content_type, - const utility::string_t& request_data, - test_http_server* p_server, - unsigned short code, - const utility::string_t& reason) -{ - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, path, request_content_type, request_data); - VERIFY_ARE_EQUAL(0, p_request->reply(code, reason)); - }); - http_asserts::assert_response_equals( - p_client->request(method, path, request_data, request_content_type).get(), code, reason); -} - -void test_server_utilities::verify_request(::http::client::http_client* p_client, - const utility::string_t& method, - const utility::string_t& path, - test_http_server* p_server, - unsigned short code, - const std::map<utility::string_t, utility::string_t>& response_headers) -{ - p_server->next_request().then([&](test_request* p_request) { - http_asserts::assert_test_request_equals(p_request, method, path); - VERIFY_ARE_EQUAL(0, p_request->reply(code, U(""), response_headers)); - }); - http_asserts::assert_response_equals(p_client->request(method, path).get(), code, response_headers); -} - -} // namespace utilities -} // namespace http -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/CMakeLists.txt @@ -1,17 +0,0 @@ -set(SOURCES - construction_tests.cpp - negative_parsing_tests.cpp - parsing_tests.cpp - to_as_and_operators_tests.cpp - iterator_tests.cpp - json_numbers_tests.cpp -) -if(NOT WINDOWS_STORE AND NOT WINDOWS_PHONE) - list(APPEND SOURCES fuzz_tests.cpp) -endif() - -add_casablanca_test(json_test SOURCES) -if(UNIX AND NOT APPLE) - cpprest_find_boost() - target_link_libraries(json_test PRIVATE cpprestsdk_boost_internal) -endif() diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/construction_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/construction_tests.cpp @@ -1,501 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * construction_tests.cpp - * - * Tests creating JSON values. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/json.h" -#include "unittestpp.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace json_tests -{ -SUITE(construction_tests) -{ -#if defined(__cplusplus_winrt) - - TEST(winrt_platform_string) - { - Platform::String ^ platformStr = "Hello!"; - json::value jstr = json::value::string(platformStr->Data()); - CHECK(jstr.is_string()); - CHECK_EQUAL(jstr.serialize(), U("\"Hello!\"")); - } - -#endif - - TEST(assignment_op) - { - json::value arr = json::value::array(); - arr[0] = json::value(true); - - json::value ass_copy = arr; - VERIFY_IS_TRUE(ass_copy.is_array()); - VERIFY_ARE_EQUAL(U("true"), ass_copy[0].serialize()); - ass_copy[1] = json::value(false); - VERIFY_ARE_EQUAL(U("false"), ass_copy[1].serialize()); - VERIFY_ARE_EQUAL(U("null"), arr[1].serialize()); - } - - TEST(copy_ctor_array) - { - json::value arr = json::value::array(); - arr[0] = json::value(true); - - json::value copy(arr); - VERIFY_IS_TRUE(copy.is_array()); - VERIFY_ARE_EQUAL(U("true"), copy[0].serialize()); - copy[1] = json::value(false); - VERIFY_ARE_EQUAL(U("false"), copy[1].serialize()); - VERIFY_ARE_EQUAL(U("null"), arr[1].serialize()); - } - - TEST(copy_ctor_object) - { - json::value obj = json::value::object(); - utility::string_t keyName(U("key")); - obj[keyName] = json::value(false); - - // Copy object that has values added. - json::value copy(obj); - VERIFY_IS_TRUE(copy.is_object()); - VERIFY_ARE_EQUAL(U("false"), copy[keyName].serialize()); - obj[keyName] = json::value(true); - VERIFY_ARE_EQUAL(U("false"), copy[keyName].serialize()); - VERIFY_ARE_EQUAL(U("true"), obj[keyName].serialize()); - - // Copy object that parses with value, but none additional added. - obj = json::value::parse(U("{\"key\": true}")); - json::value copy2(obj); - VERIFY_IS_TRUE(copy2.is_object()); - obj[keyName] = json::value(false); - VERIFY_IS_TRUE(copy2.size() == 1); - VERIFY_ARE_EQUAL(U("false"), obj[keyName].serialize()); - VERIFY_ARE_EQUAL(U("true"), copy2[keyName].serialize()); - } - - TEST(copy_ctor_string) - { - utility::string_t strValue(U("teststr")); - json::value str = json::value::string(strValue); - - json::value copy(str); - VERIFY_IS_TRUE(copy.is_string()); - VERIFY_ARE_EQUAL(strValue, copy.as_string()); - str = json::value::string(U("teststr2")); - VERIFY_ARE_EQUAL(strValue, copy.as_string()); - VERIFY_ARE_EQUAL(U("teststr2"), str.as_string()); - } - - TEST(copy_ctor_with_escaped) - { - auto str = json::value::parse(U("\"\\n\"")); - VERIFY_ARE_EQUAL(U("\n"), str.as_string()); - - auto copy = str; - VERIFY_ARE_EQUAL(U("\n"), copy.as_string()); - } - - TEST(move_ctor) - { - json::value obj; - obj[U("A")] = json::value(true); - - json::value moved(std::move(obj)); - VERIFY_IS_TRUE(moved.is_object()); - VERIFY_ARE_EQUAL(U("true"), moved[U("A")].serialize()); - moved[U("B")] = json::value(false); - VERIFY_ARE_EQUAL(U("false"), moved[U("B")].serialize()); - } - - TEST(move_assignment_op) - { - json::value obj; - obj[U("A")] = json::value(true); - - json::value moved; - moved = std::move(obj); - VERIFY_IS_TRUE(moved.is_object()); - VERIFY_ARE_EQUAL(U("true"), moved[U("A")].serialize()); - moved[U("B")] = json::value(false); - VERIFY_ARE_EQUAL(U("false"), moved[U("B")].serialize()); - } - - TEST(constructor_overloads) - { - json::value v0; - json::value v1(17); - json::value v2(3.1415); - json::value v3(true); - const utility::char_t* p4 = U("Hello!"); - json::value v4(p4); - - json::value v5(U("Hello Again!")); - json::value v6(U("YES YOU KNOW IT")); - json::value v7(U("HERE ID IS")); - - const utility::char_t* p9 = U("Hello not-escaped!"); - json::value v8(p9, true); - json::value v9(p9, false); - - VERIFY_ARE_EQUAL(v0.type(), json::value::Null); - VERIFY_IS_TRUE(v0.is_null()); - VERIFY_ARE_EQUAL(v1.type(), json::value::Number); - VERIFY_IS_TRUE(v1.is_number()); - VERIFY_IS_TRUE(v1.is_integer()); - VERIFY_IS_FALSE(v1.is_double()); - VERIFY_ARE_EQUAL(v2.type(), json::value::Number); - VERIFY_IS_TRUE(v2.is_number()); - VERIFY_IS_TRUE(v2.is_double()); - VERIFY_IS_FALSE(v2.is_integer()); - VERIFY_ARE_EQUAL(v3.type(), json::value::Boolean); - VERIFY_IS_TRUE(v3.is_boolean()); - VERIFY_ARE_EQUAL(v4.type(), json::value::String); - VERIFY_IS_TRUE(v4.is_string()); - VERIFY_ARE_EQUAL(v5.type(), json::value::String); - VERIFY_IS_TRUE(v5.is_string()); - VERIFY_ARE_EQUAL(v6.type(), json::value::String); - VERIFY_IS_TRUE(v6.is_string()); - VERIFY_ARE_EQUAL(v7.type(), json::value::String); - VERIFY_IS_TRUE(v7.is_string()); - VERIFY_ARE_EQUAL(v8.type(), json::value::String); - VERIFY_IS_TRUE(v8.is_string()); - VERIFY_ARE_EQUAL(v9.type(), json::value::String); - VERIFY_IS_TRUE(v9.is_string()); - } - - TEST(factory_overloads) - { - json::value v0 = json::value::null(); - json::value v1 = json::value::number(17); - json::value v2 = json::value::number(3.1415); - json::value v3 = json::value::boolean(true); - json::value v4 = json::value::string(U("Hello!")); - json::value v5 = json::value::string(U("Hello Again!")); - json::value v6 = json::value::string(U("Hello!")); - json::value v7 = json::value::string(U("Hello Again!")); - json::value v8 = json::value::string(U("Hello not-escaped!"), true); - json::value v9 = json::value::string(U("Hello not-escaped!"), false); - json::value v10 = json::value::object(); - json::value v11 = json::value::array(); - - VERIFY_ARE_EQUAL(v0.type(), json::value::Null); - VERIFY_ARE_EQUAL(v1.type(), json::value::Number); - VERIFY_ARE_EQUAL(v2.type(), json::value::Number); - VERIFY_ARE_EQUAL(v3.type(), json::value::Boolean); - VERIFY_ARE_EQUAL(v4.type(), json::value::String); - VERIFY_ARE_EQUAL(v5.type(), json::value::String); - VERIFY_ARE_EQUAL(v6.type(), json::value::String); - VERIFY_ARE_EQUAL(v7.type(), json::value::String); - VERIFY_ARE_EQUAL(v8.type(), json::value::String); - VERIFY_ARE_EQUAL(v9.type(), json::value::String); - VERIFY_ARE_EQUAL(v10.type(), json::value::Object); - VERIFY_IS_TRUE(v10.is_object()); - VERIFY_ARE_EQUAL(v11.type(), json::value::Array); - VERIFY_IS_TRUE(v11.is_array()); - } - - TEST(object_construction) - { - // Factory which takes a vector. - std::vector<std::pair<string_t, json::value>> f; - f.push_back(std::make_pair(U("abc"), json::value(true))); - f.push_back(std::make_pair(U("xyz"), json::value(44))); - json::value obj = json::value::object(f); - - VERIFY_ARE_EQUAL(f.size(), obj.size()); - - obj[U("abc")] = json::value::string(U("str")); - obj[U("123")] = json::value(false); - - VERIFY_ARE_NOT_EQUAL(f.size(), obj.size()); - VERIFY_ARE_EQUAL(json::value::string(U("str")).serialize(), obj[U("abc")].serialize()); - VERIFY_ARE_EQUAL(json::value(false).serialize(), obj[U("123")].serialize()); - - // Tests constructing empty and adding. - auto val1 = json::value::object(); - val1[U("A")] = 44; - val1[U("hahah")] = json::value(true); - VERIFY_ARE_EQUAL(2u, val1.size()); - VERIFY_ARE_EQUAL(U("44"), val1[U("A")].serialize()); - VERIFY_ARE_EQUAL(U("true"), val1[U("hahah")].serialize()); - - // Construct as null value, then turn into object. - json::value val2; - VERIFY_IS_TRUE(val2.is_null()); - val2[U("A")] = 44; - val2[U("hahah")] = json::value(true); - VERIFY_ARE_EQUAL(2u, val2.size()); - VERIFY_ARE_EQUAL(U("44"), val2[U("A")].serialize()); - VERIFY_ARE_EQUAL(U("true"), val2[U("hahah")].serialize()); - } - - TEST(object_construction_keep_order) - { - std::vector<std::pair<string_t, json::value>> f; - f.push_back(std::make_pair(U("x"), json::value(0))); - f.push_back(std::make_pair(U("a"), json::value(1))); - - auto obj1 = json::value::object(f, /*keep_order==*/true); - VERIFY_ARE_EQUAL(obj1.as_object().begin()->first, U("x")); - - auto obj2 = json::value::object(f, /*keep_order==*/false); - VERIFY_ARE_EQUAL(obj2.as_object().begin()->first, U("a")); - } - - TEST(object_construction_from_null_keep_order) - { - struct restore - { - ~restore() { json::keep_object_element_order(false); } - } _; - - json::keep_object_element_order(true); - - auto val1 = json::value::null(); - val1[U("B")] = 1; - val1[U("A")] = 1; - VERIFY_ARE_EQUAL(val1.as_object().begin()->first, U("B")); - - json::keep_object_element_order(false); - - auto val2 = json::value::null(); - val2[U("B")] = 1; - val2[U("A")] = 1; - VERIFY_ARE_EQUAL(val2.as_object().begin()->first, U("A")); - } - - TEST(array_construction) - { - // Constructor which takes a vector. - std::vector<json::value> e; - e.push_back(json::value(false)); - e.push_back(json::value::string(U("hehe"))); - json::value arr = json::value::array(e); - VERIFY_ARE_EQUAL(e.size(), arr.size()); - VERIFY_ARE_EQUAL(U("false"), arr[0].serialize()); - arr[3] = json::value(22); - VERIFY_ARE_NOT_EQUAL(e.size(), arr.size()); - VERIFY_ARE_EQUAL(U("22"), arr[3].serialize()); - - // Test empty factory and adding. - auto arr2 = json::value::array(); - arr2[1] = json::value(false); - arr2[0] = json::value::object(); - arr2[0][U("A")] = json::value::string(U("HE")); - VERIFY_ARE_EQUAL(2u, arr2.size()); - VERIFY_ARE_EQUAL(U("false"), arr2[1].serialize()); - VERIFY_ARE_EQUAL(U("\"HE\""), arr2[0][U("A")].serialize()); - - // Construct as null value and then add elements. - json::value arr3; - VERIFY_IS_TRUE(arr3.is_null()); - arr3[1] = json::value(false); - // Element [0] should already behave as an object. - arr3[0][U("A")] = json::value::string(U("HE")); - VERIFY_ARE_EQUAL(2u, arr3.size()); - VERIFY_ARE_EQUAL(U("false"), arr3[1].serialize()); - VERIFY_ARE_EQUAL(U("\"HE\""), arr3[0][U("A")].serialize()); - - // Test factory which takes a size. - auto arr4 = json::value::array(2); - VERIFY_IS_TRUE(arr4[0].is_null()); - VERIFY_IS_TRUE(arr4[1].is_null()); - arr4[2] = json::value(true); - arr4[0] = json::value(false); - VERIFY_ARE_EQUAL(U("false"), arr4[0].serialize()); - VERIFY_ARE_EQUAL(U("true"), arr4[2].serialize()); - } - - TEST(array_test) - { - json::value arr = json::value::array(); - const json::value& carr = arr; - arr[0] = json::value(3.14); - arr[1] = json::value(true); - arr[2] = json::value("Yes"); - int count; - json::array& array = arr.as_array(); - const json::array& carray = arr.as_array(); - - VERIFY_THROWS(array.at(4), json::json_exception); - VERIFY_THROWS(carray.at(5), json::json_exception); - VERIFY_THROWS(arr.at(6), json::json_exception); - VERIFY_THROWS(carr.at(7), json::json_exception); - - // The begin and end iterators on non-const instances - count = 0; - for (auto iter = array.begin(); iter != array.end(); ++iter) - { - VERIFY_IS_TRUE((*iter) == array[count]); - VERIFY_IS_TRUE((*iter) == array.at(count)); - VERIFY_IS_TRUE((*iter) == carray.at(count)); - count++; - } - VERIFY_ARE_EQUAL(array.size(), count); - - count = 0; - for (auto iter = array.cbegin(); iter != array.cend(); ++iter) - { - VERIFY_IS_TRUE((*iter) == array[count]); - VERIFY_IS_TRUE((*iter) == array.at(count)); - count++; - } - VERIFY_ARE_EQUAL(array.size(), count); - - count = 0; - for (auto iter = array.rbegin(); iter != array.rend(); ++iter) - { - VERIFY_IS_TRUE((*iter) == array[array.size() - 1 - count]); - VERIFY_IS_TRUE((*iter) == array.at(array.size() - 1 - count)); - VERIFY_IS_TRUE((*iter) == carray.at(array.size() - 1 - count)); - count++; - } - VERIFY_ARE_EQUAL(array.size(), count); - - count = 0; - for (auto iter = array.crbegin(); iter != array.crend(); ++iter) - { - VERIFY_IS_TRUE((*iter) == array[array.size() - 1 - count]); - VERIFY_IS_TRUE((*iter) == arr[array.size() - 1 - count]); - VERIFY_IS_TRUE((*iter) == array.at(array.size() - 1 - count)); - VERIFY_IS_TRUE((*iter) == arr.at(array.size() - 1 - count)); - count++; - } - VERIFY_ARE_EQUAL(array.size(), count); - - // The begin and end iterators on const instances - count = 0; - for (auto iter = carray.begin(); iter != carray.end(); ++iter) - { - VERIFY_IS_TRUE((*iter) == carray.at(count)); - VERIFY_IS_TRUE((*iter) == carr.at(count)); - count++; - } - VERIFY_ARE_EQUAL(array.size(), count); - - count = 0; - for (auto iter = carray.rbegin(); iter != carray.rend(); ++iter) - { - VERIFY_IS_TRUE((*iter) == carray.at(array.size() - 1 - count)); - VERIFY_IS_TRUE((*iter) == carr.at(array.size() - 1 - count)); - count++; - } - VERIFY_ARE_EQUAL(array.size(), count); - } - - TEST(object_test) - { - json::value obj = json::value::object(); - const json::value& cobj = obj; - json::object& object = obj.as_object(); - const json::object& cobject = obj.as_object(); - - VERIFY_IS_TRUE(object.empty()); - - obj[U("name")] = json::value(U("John")); - obj[U("surname")] = json::value(U("Smith")); - obj[U("height")] = json::value(5.9); - obj[U("vegetarian")] = json::value(true); - int count; - - // Test at() - VERIFY_ARE_EQUAL(U("John"), obj.at(U("name")).as_string()); - VERIFY_ARE_EQUAL(U("John"), cobj.at(U("name")).as_string()); - VERIFY_ARE_EQUAL(U("Smith"), object.at(U("surname")).as_string()); - VERIFY_ARE_EQUAL(U("Smith"), cobject.at(U("surname")).as_string()); - VERIFY_THROWS(obj.at(U("wrong key")), json::json_exception); - VERIFY_THROWS(cobj.at(U("wrong key")), json::json_exception); - - // Test find() - { - auto iter = object.find(U("height")); - VERIFY_ARE_NOT_EQUAL(object.end(), iter); - VERIFY_IS_TRUE(iter->second.is_number()); - VERIFY_ARE_EQUAL(5.9, iter->second.as_number().to_double()); - VERIFY_ARE_EQUAL(object.end(), object.find(U("wrong_key"))); - } - - // Test find() const - auto citer = cobject.find(U("height")); - VERIFY_ARE_NOT_EQUAL(cobject.end(), citer); - VERIFY_IS_TRUE(citer->second.is_number()); - VERIFY_ARE_EQUAL(5.9, citer->second.as_number().to_double()); - VERIFY_ARE_EQUAL(cobject.end(), cobject.find(U("wrong_key"))); - - VERIFY_IS_FALSE(object.empty()); - - // The begin and end iterators on non-const instances - count = 0; - for (auto iter = object.begin(); iter != object.end(); ++iter) - { - VERIFY_ARE_EQUAL(object[iter->first], iter->second); - count++; - } - VERIFY_ARE_EQUAL(object.size(), count); - - count = 0; - for (auto iter = object.rbegin(); iter != object.rend(); ++iter) - { - VERIFY_ARE_EQUAL(object[iter->first], iter->second); - count++; - } - VERIFY_ARE_EQUAL(object.size(), count); - - count = 0; - for (auto iter = object.cbegin(); iter != object.cend(); ++iter) - { - VERIFY_ARE_EQUAL(object[iter->first], iter->second); - count++; - } - VERIFY_ARE_EQUAL(object.size(), count); - - count = 0; - for (auto iter = object.crbegin(); iter != object.crend(); ++iter) - { - VERIFY_ARE_EQUAL(object[iter->first], iter->second); - count++; - } - VERIFY_ARE_EQUAL(object.size(), count); - - // The begin and end iterators on const instances - count = 0; - for (auto iter = cobject.begin(); iter != cobject.end(); ++iter) - { - VERIFY_ARE_EQUAL(cobject.find(iter->first)->second, iter->second); - count++; - } - VERIFY_ARE_EQUAL(cobject.size(), count); - - count = 0; - for (auto iter = cobject.rbegin(); iter != cobject.rend(); ++iter) - { - VERIFY_ARE_EQUAL(cobject.find(iter->first)->second, iter->second); - count++; - } - VERIFY_ARE_EQUAL(cobject.size(), count); - } - - TEST(github_asan_989) - { - ::web::json::value::parse(_XPLATSTR(R"([ { "k1" : "v" }, { "k2" : "v" }, { "k3" : "v" }, { "k4" : "v" } ])")); - } - -} // SUITE(construction_tests) - -} // namespace json_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/fuzz_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/fuzz_tests.cpp @@ -1,83 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * fuzz_tests.cpp - * - * Fuzz tests for the JSON library. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/json.h" -#include "cpprest/containerstream.h" -#include "cpprest/filestream.h" -#include "unittestpp.h" - -using namespace web; - -namespace tests -{ -namespace functional -{ -namespace json_tests -{ -#ifdef _WIN32 - -SUITE(json_fuzz_tests) -{ - std::string get_fuzzed_file_path() - { - std::string ipfile; - - if (UnitTest::GlobalSettings::Has("fuzzedinputfile")) - { - ipfile = UnitTest::GlobalSettings::Get("fuzzedinputfile"); - } - - return ipfile; - } - - TEST(fuzz_json_parser, "Requires", "fuzzedinputfile") - { - std::wstring ipfile = utility::conversions::to_utf16string(get_fuzzed_file_path()); - if (true == ipfile.empty()) - { - VERIFY_IS_TRUE(false, "Input file is empty"); - return; - } - - auto fs = Concurrency::streams::file_stream<uint8_t>::open_istream(ipfile).get(); - concurrency::streams::container_buffer<std::string> cbuf; - fs.read_to_end(cbuf).get(); - fs.close().get(); - auto json_str = cbuf.collection(); - - // Look for UTF-8 BOM - if ((uint8_t)json_str[0] != 0xEF || (uint8_t)json_str[1] != 0xBB || (uint8_t)json_str[2] != 0xBF) - { - VERIFY_IS_TRUE(false, "Input file encoding is not UTF-8. Test will not parse the file."); - return; - } - - auto utf16_json_str = utility::conversions::utf8_to_utf16(json_str); - // UTF8 to UTF16 conversion will retain the BOM, remove it. - if (utf16_json_str.front() == 0xFEFF) utf16_json_str.erase(0, 1); - - try - { - json::value::parse(std::move(utf16_json_str)); - std::cout << "Input file parsed successfully."; - } - catch (const json::json_exception& ex) - { - std::cout << "json exception:" << ex.what(); - } - } -} - -#endif -} // namespace json_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/iterator_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/iterator_tests.cpp @@ -1,308 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * iterator_tests.cpp - * - * Tests iterating over JSON values - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/json.h" -#include "unittestpp.h" -#include <algorithm> - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace json_tests -{ -SUITE(iterator_tests) -{ - void validate_array_and_object_throw(json::value value) - { - VERIFY_THROWS(value.as_array(), web::json::json_exception); - VERIFY_THROWS(value.as_object(), web::json::json_exception); - } - - TEST(non_composites_member_preincrement) - { - validate_array_and_object_throw(json::value::null()); - validate_array_and_object_throw(json::value::number(17)); - validate_array_and_object_throw(json::value::boolean(true)); - validate_array_and_object_throw(json::value::string(U("Hello!"))); - } - - TEST(objects_constructed) - { - json::value val1; - val1[U("a")] = 44; - val1[U("b")] = json::value(true); - val1[U("c")] = json::value(false); - - VERIFY_ARE_EQUAL(3, val1.size()); - - size_t count = 0; - for (auto iter = std::begin(val1.as_object()); iter != std::end(val1.as_object()); ++iter) - { - auto key = iter->first; - auto& value = iter->second; - switch (count) - { - case 0: - VERIFY_ARE_EQUAL(U("a"), key); - VERIFY_IS_TRUE(value.is_number()); - break; - case 1: - VERIFY_ARE_EQUAL(U("b"), key); - VERIFY_IS_TRUE(value.is_boolean()); - break; - case 2: - VERIFY_ARE_EQUAL(U("c"), key); - VERIFY_IS_TRUE(value.is_boolean()); - break; - } - count++; - } - VERIFY_ARE_EQUAL(3, count); - } - - TEST(objects_parsed) - { - json::value val1 = json::value::parse(U("{\"a\": 44, \"b\": true, \"c\": false}")); - - VERIFY_ARE_EQUAL(3, val1.size()); - - size_t count = 0; - for (auto iter = std::begin(val1.as_object()); iter != std::end(val1.as_object()); ++iter) - { - auto key = iter->first; - auto& value = iter->second; - switch (count) - { - default: VERIFY_IS_TRUE(value.is_null()); break; - case 0: - VERIFY_ARE_EQUAL(U("a"), key); - VERIFY_IS_TRUE(value.is_number()); - VERIFY_ARE_EQUAL(44, value.as_integer()); - break; - case 1: - VERIFY_ARE_EQUAL(U("b"), key); - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_TRUE(value.as_bool()); - break; - case 2: - VERIFY_ARE_EQUAL(U("c"), key); - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_FALSE(value.as_bool()); - break; - } - count++; - } - VERIFY_ARE_EQUAL(3, count); - } - - TEST(objects_reverse) - { - json::value val1 = json::value::parse(U("{\"a\": 44, \"b\": true, \"c\": false}")); - - VERIFY_ARE_EQUAL(3, val1.size()); - VERIFY_ARE_EQUAL(3, val1.as_object().size()); - - size_t count = 0; - for (auto iter = val1.as_object().rbegin(); iter != val1.as_object().rend(); ++iter) - { - auto key = iter->first; - auto& value = iter->second; - switch (count) - { - case 2: - VERIFY_ARE_EQUAL(U("a"), key); - VERIFY_IS_TRUE(value.is_number()); - VERIFY_ARE_EQUAL(44, value.as_integer()); - break; - case 1: - VERIFY_ARE_EQUAL(U("b"), key); - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_TRUE(value.as_bool()); - break; - case 0: - VERIFY_ARE_EQUAL(U("c"), key); - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_FALSE(value.as_bool()); - break; - } - count++; - } - VERIFY_ARE_EQUAL(3, count); - } - - TEST(arrays_constructed) - { - json::value val1; - val1[0] = 44; - val1[2] = json::value(true); - val1[5] = json::value(true); - - VERIFY_ARE_EQUAL(6, val1.size()); - - size_t count = 0; - for (auto value : val1.as_array()) - { - switch (count) - { - case 0: - VERIFY_IS_TRUE(value.is_number()); - VERIFY_ARE_EQUAL(44, value.as_integer()); - break; - case 2: - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_TRUE(value.as_bool()); - break; - case 5: - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_TRUE(value.as_bool()); - break; - } - count++; - } - VERIFY_ARE_EQUAL(6, count); - } - - TEST(arrays_parsed) - { - json::value val1 = json::value::parse(U("[44, true, false]")); - - VERIFY_ARE_EQUAL(3, val1.size()); - - size_t count = 0; - for (auto& value : val1.as_array()) - { - switch (count) - { - case 0: - VERIFY_IS_TRUE(value.is_number()); - VERIFY_ARE_EQUAL(44, value.as_integer()); - break; - case 1: - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_TRUE(value.as_bool()); - break; - case 2: - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_FALSE(value.as_bool()); - break; - } - count++; - } - VERIFY_ARE_EQUAL(3, count); - } - - TEST(arrays_reversed) - { - json::value val1 = json::value::parse(U("[44, true, false]")); - - VERIFY_ARE_EQUAL(3, val1.size()); - - size_t count = 0; - for (auto iter = val1.as_array().rbegin(); iter != val1.as_array().rend(); ++iter) - { - auto value = *iter; - switch (count) - { - case 2: - VERIFY_IS_TRUE(value.is_number()); - VERIFY_ARE_EQUAL(44, value.as_integer()); - break; - case 1: - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_TRUE(value.as_bool()); - break; - case 0: - VERIFY_IS_TRUE(value.is_boolean()); - VERIFY_IS_FALSE(value.as_bool()); - break; - } - count++; - } - VERIFY_ARE_EQUAL(3, count); - } - - TEST(comparison) - { - json::value val1; - val1[U("a")] = 44; - val1[U("b")] = json::value(true); - val1[U("c")] = json::value(false); - - auto first = std::begin(val1.as_object()); - auto f = first; - auto f_1 = first++; - auto f_2 = ++first; - - VERIFY_ARE_EQUAL(f, f_1); - VERIFY_ARE_NOT_EQUAL(f_1, f_2); - } - - TEST(std_algorithms) - { - { - // for_each - size_t count = 0; - json::value v_array = json::value::parse(U("[44, true, false]")); - std::for_each(std::begin(v_array.as_array()), - std::end(v_array.as_array()), - [&](json::array::iterator::value_type) { count++; }); - VERIFY_ARE_EQUAL(3, count); - } - { - // find_if - json::value v_array = json::value::parse(U("[44, true, false]")); - auto _where = std::find_if(std::begin(v_array.as_array()), - std::end(v_array.as_array()), - [&](json::array::iterator::value_type value) { return value.is_boolean(); }); - - VERIFY_ARE_NOT_EQUAL(_where, std::end(v_array.as_array())); - - VERIFY_ARE_EQUAL(_where->as_bool(), true); - } - { - // copy_if - json::value v_array = json::value::parse(U("[44, true, false]")); - std::vector<json::array::iterator::value_type> v_target(v_array.size()); - auto _where = std::copy_if(std::begin(v_array.as_array()), - std::end(v_array.as_array()), - std::begin(v_target), - [&](json::array::iterator::value_type value) { return value.is_boolean(); }); - VERIFY_ARE_EQUAL(2, _where - std::begin(v_target)); - VERIFY_IS_FALSE(v_array.as_array().begin()[1].is_number()); - } - { - // transform - json::value v_array = json::value::parse(U("[44, true, false]")); - std::vector<json::value> v_target(v_array.size()); - std::transform(std::begin(v_array.as_array()), - std::end(v_array.as_array()), - std::begin(v_target), - [&](json::array::iterator::value_type) -> json::value { return json::value::number(17); }); - - VERIFY_ARE_EQUAL(3, v_target.size()); - - for (auto iter = std::begin(v_target); iter != std::end(v_target); ++iter) - { - VERIFY_IS_FALSE(iter->is_null()); - } - } - } -} - -} // namespace json_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/json_numbers_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/json_numbers_tests.cpp @@ -1,324 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * json_numbers_tests.cpp - * - * Tests parsing numbers and json::number class - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/json.h" -#include "unittestpp.h" -#include <clocale> -#include <iomanip> - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace json_tests -{ -SUITE(json_numbers_tests) -{ - TEST(numbers) - { - json::value num = json::value::parse(U("-22")); - VERIFY_ARE_EQUAL(-22, num.as_double()); - VERIFY_ARE_EQUAL(-22, num.as_integer()); - - num = json::value::parse(U("-1.45E2")); - VERIFY_IS_TRUE(num.is_number()); - - num = json::value::parse(U("-1.45E+1")); - VERIFY_IS_TRUE(num.is_number()); - - num = json::value::parse(U("-1.45E-10")); - VERIFY_IS_TRUE(num.is_number()); - - num = json::value::parse(U("1e01")); - VERIFY_IS_TRUE(num.is_number()); - } - - // Test both positive and negative number - void test_int64(int64_t number) - { - stringstream_t ss; - ss << number; - json::value num = json::value::parse(ss); - VERIFY_ARE_EQUAL(number, num.as_number().to_int64()); - VERIFY_IS_TRUE(num.is_integer()); - num = json::value::number(number); - VERIFY_ARE_EQUAL(number, num.as_number().to_int64()); - VERIFY_IS_TRUE(num.is_integer()); - - // Check that the number is convertible to signed int64 - VERIFY_IS_TRUE(num.as_number().is_int64()); - - // Check for other integral conversions - VERIFY_ARE_EQUAL(number >= INT_MIN && number <= INT_MAX, num.as_number().is_int32()); - VERIFY_ARE_EQUAL(number >= 0 && number <= UINT_MAX, num.as_number().is_uint32()); - VERIFY_ARE_EQUAL(number >= 0, num.as_number().is_uint64()); - } - - TEST(parse_int64) - { - // Negative limits - test_int64(int64_t(LLONG_MIN)); - test_int64(int64_t(LLONG_MIN) + 1); - test_int64(int64_t(INT_MIN) - 1); - test_int64(int64_t(INT_MIN)); - test_int64(int64_t(INT_MIN) + 1); - - // Around zero - test_int64(int64_t(-1)); - test_int64(int64_t(0)); - test_int64(int64_t(1)); - - // Positive limits - test_int64(int64_t(INT_MAX)); - test_int64(int64_t(INT_MAX) + 1); - test_int64(int64_t(UINT_MAX)); - test_int64(int64_t(UINT_MAX) + 1); - - // Outside 32-bits limits - test_int64(int64_t(INT_MAX) * 13 + 5); // a number out of the int32 range - test_int64(uint64_t(LLONG_MAX / 2)); - } - - void test_int64(uint64_t number) - { - stringstream_t ss; - ss << number; - json::value num = json::value::parse(ss); - VERIFY_ARE_EQUAL(number, num.as_number().to_uint64()); - VERIFY_IS_TRUE(num.is_integer()); - num = json::value::number(number); - VERIFY_ARE_EQUAL(number, num.as_number().to_uint64()); - VERIFY_IS_TRUE(num.is_integer()); - - // Check that the number is convertible to unsigned int64 - VERIFY_IS_TRUE(num.as_number().is_uint64()); - - // Check for other integral conversions - VERIFY_ARE_EQUAL(number <= INT_MAX, num.as_number().is_int32()); - VERIFY_ARE_EQUAL(number <= UINT_MAX, num.as_number().is_uint32()); - VERIFY_ARE_EQUAL(number <= LLONG_MAX, num.as_number().is_int64()); - } - - TEST(parse_uint64) - { - test_int64(int64_t(0)); - test_int64(int64_t(1)); - - test_int64(uint64_t(LLONG_MAX) - 1); - test_int64(uint64_t(LLONG_MAX)); - test_int64(uint64_t(LLONG_MAX) + 1); - test_int64(uint64_t(ULLONG_MAX)); - test_int64(uint64_t(ULLONG_MAX) - 1); - } - - const int DOUBLE_DIGITS = - std::numeric_limits<double>::digits10 + - 7; // 7 = length of "1." and "e+123" which is the begining and the end of the double representation - - void test_double(double number, string_t str_rep) - { - stringstream_t ss; - ss << str_rep; - - json::value num = json::value::parse(ss); - VERIFY_ARE_EQUAL(number, num.as_double()); - VERIFY_ARE_EQUAL(number, num.as_number().to_double()); - - // If the number is within integral types limit and not decimal, it should be stored as one of the integral - // types - VERIFY_ARE_EQUAL(number > LLONG_MIN && number < ULLONG_MAX && number == floor(number), num.is_integer()); - - // If it is outside the range, these methods should return false. - // Note that at this point there is no guarantee that the number was stored as double. - - if (number < INT_MIN || number > INT_MAX || number != floor(number)) - VERIFY_IS_FALSE(num.as_number().is_int32()); - - if (number < 0 || number > UINT_MAX || number != floor(number)) VERIFY_IS_FALSE(num.as_number().is_uint32()); - - if (number < LLONG_MIN || number > LLONG_MAX || number != floor(number)) - VERIFY_IS_FALSE(num.as_number().is_int64()); - - if (number < 0 || number > ULLONG_MAX || number != floor(number)) VERIFY_IS_FALSE(num.as_number().is_uint64()); - } - - void test_double(double d) - { - ::std::basic_stringstream<string_t::value_type> ss; - ss << ::std::setprecision(DOUBLE_DIGITS); - ss << d; - test_double(d, ss.str()); - } - - TEST(parsing_doubles_into_longs) - { - test_double(2.0); - test_double(pow(2.0, 10.0)); - test_double(pow(2.0, 20.0)); - test_double(pow(2.0, 60.0)); - test_double(pow(2.0, 63.0)); - } - - TEST(parsing_doubles) - { - test_double(3.14); - test_double(-9.81); - - // Note: this should not parse to a ullong because of rounding - test_double(static_cast<double>(ULLONG_MAX)); - - test_double(0 - static_cast<double>(ULLONG_MAX)); - test_double(static_cast<double>(ULLONG_MAX) + - (2 << (64 - 52))); // the lowest number that will be represented as double due to overflowing - // unsigned int64 (52bits fraction in double-precision) - test_double(0 - pow(2.0, 63.0) * 1.5); // between 0-ULLONG_MAX and LLONGMIN - } - - TEST(parsing_doubles_setlocale, - "Ignore:Android", - "Locale not supported on Android", - "Ignore:Linux", - "Fails due to double conversion issues", - "Ignore:Apple", - "Fails due to double conversion issues") - { - // JSON uses the C locale always and should therefore not be impacted by the process locale -#ifdef _WIN32 - std::string changedLocale("fr-FR"); -#else - std::string changedLocale("fr_FR.UTF-8"); -#endif - - // If locale isn't installed on system just silently pass. - if (setlocale(LC_ALL, changedLocale.c_str()) != nullptr) - { - test_double(1.91563); - test_double(2.0e93); - setlocale(LC_ALL, "C"); - } - } - - TEST(parsing_very_large_doubles) - { - test_double(pow(2.0, 64.0)); - test_double(pow(2.0, 70.0)); - test_double(pow(2.0, 80.0)); - test_double(pow(2.0, 120.0)); - test_double(pow(2.0, 240.0)); - test_double(pow(2.0, 300.0)); - } - - TEST(parsing_very_small_doubles) - { - test_double(2.34e-308); - test_double(1e-308); - } - - void test_integral(int number) - { - stringstream_t ss; - ss << number; - json::value num = json::value::parse(ss); - VERIFY_IS_TRUE(num.as_number().is_int32()); - VERIFY_IS_TRUE(num.as_number().is_uint32()); - VERIFY_IS_TRUE(num.as_number().is_int64()); - VERIFY_IS_TRUE(num.as_number().is_uint64()); - - VERIFY_ARE_EQUAL(number, num.as_number().to_int32()); - VERIFY_ARE_EQUAL(number, num.as_number().to_uint32()); - VERIFY_ARE_EQUAL(number, num.as_number().to_int64()); - VERIFY_ARE_EQUAL(number, num.as_number().to_uint64()); - } - - TEST(parsing_integral_types) - { - test_integral(0); - test_integral(1); - test_integral(INT_MAX / 2); - test_integral(INT_MAX); - } - - TEST(int_double_limits) - { - utility::stringstream_t stream(utility::stringstream_t::in | utility::stringstream_t::out); - utility::stringstream_t oracleStream(utility::stringstream_t::in | utility::stringstream_t::out); - - // unsigned int64 max - oracleStream.precision(std::numeric_limits<uint64_t>::digits10 + 2); - oracleStream << (std::numeric_limits<uint64_t>::max)(); - json::value iMax((std::numeric_limits<uint64_t>::max)()); - VERIFY_ARE_EQUAL(oracleStream.str(), iMax.serialize()); - iMax.serialize(stream); - VERIFY_ARE_EQUAL(oracleStream.str(), stream.str()); - - // signed int64 min - stream.str(U("")); - oracleStream.str(U("")); - oracleStream.clear(); - oracleStream << (std::numeric_limits<int64_t>::min)(); - json::value iMin((std::numeric_limits<int64_t>::min)()); - VERIFY_ARE_EQUAL(oracleStream.str(), iMin.serialize()); - iMin.serialize(stream); - VERIFY_ARE_EQUAL(oracleStream.str(), stream.str()); - - // double max - stream.str(U("")); - oracleStream.str(U("")); - oracleStream.precision(std::numeric_limits<double>::digits10 + 2); - oracleStream << (std::numeric_limits<double>::max)(); - json::value dMax((std::numeric_limits<double>::max)()); - VERIFY_ARE_EQUAL(oracleStream.str(), dMax.serialize()); - dMax.serialize(stream); - VERIFY_ARE_EQUAL(oracleStream.str(), stream.str()); - - // double min - stream.str(U("")); - oracleStream.str(U("")); - oracleStream << (std::numeric_limits<double>::min)(); - json::value dMin((std::numeric_limits<double>::min)()); - VERIFY_ARE_EQUAL(oracleStream.str(), dMin.serialize()); - dMin.serialize(stream); - VERIFY_ARE_EQUAL(oracleStream.str(), stream.str()); - } - - TEST(compare_numbers) - { - // Make sure these are equal - VERIFY_ARE_EQUAL(json::value(3.14), json::value::parse(U("3.14"))); - VERIFY_ARE_EQUAL(json::value(uint64_t(1234)), json::value::parse(U("1234"))); - VERIFY_ARE_EQUAL(json::value(uint32_t(10)), json::value::parse(U("10"))); - - // These two are to verify that explicitly stated signed int was stored as unsigned int as we store all - // non-negative numbers as unsigned int - VERIFY_ARE_EQUAL(json::value(int32_t(10)), json::value::parse(U("10"))); - VERIFY_ARE_EQUAL(json::value(int64_t(1234)), json::value::parse(U("1234"))); - - // These numbers would be equal if converted to double first. That is how we compared them before we had int64 - // support. - VERIFY_ARE_NOT_EQUAL(json::value(int64_t(LLONG_MIN)), json::value(int64_t(LLONG_MIN + 1))); - VERIFY_ARE_NOT_EQUAL(json::value(uint64_t(ULLONG_MAX)), json::value(uint64_t(ULLONG_MAX - 1))); - - // Checking boundary condition - zero - VERIFY_ARE_EQUAL(json::value(int32_t(0)), json::value::parse(U("-0"))); - VERIFY_ARE_EQUAL(json::value(int64_t(0)), json::value::parse(U("-0"))); - VERIFY_ARE_EQUAL(json::value::parse(U("0")), json::value::parse(U("-0"))); - } - -} // SUITE(json_numbers_tests) - -} // namespace json_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/negative_parsing_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/negative_parsing_tests.cpp @@ -1,185 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * negative_parsing_tests.cpp - * - * Negative tests for JSON parsing. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/json.h" -#include "unittestpp.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace json_tests -{ -template<typename T> -void verify_json_throws(T& parseString) -{ - std::error_code ec; - VERIFY_THROWS(json::value::parse(parseString), json::json_exception); - auto value = json::value::parse(parseString, ec); - VERIFY_IS_TRUE(ec.value() > 0); - VERIFY_IS_TRUE(value.is_null()); -} - -SUITE(negative_parsing_tests) -{ - TEST(string_t) - { - verify_json_throws(U("\"\\k\"")); - verify_json_throws(U("\" \" \"")); - verify_json_throws(U("\"\\u23A\"")); - verify_json_throws(U("\"\\uXY1A\"")); - verify_json_throws(U("\"asdf")); - verify_json_throws(U("\\asdf")); - verify_json_throws(U("\"\"\"\"")); - - // '\', '"', and control characters must be escaped (0x1F and below). - verify_json_throws(U("\"\\\"")); - verify_json_throws(U("\"")); - utility::string_t str(U("\"")); - str.append(1, 0x1F); - str.append(U("\"")); - verify_json_throws(str); - } - - TEST(numbers) - { - verify_json_throws(U("-")); - verify_json_throws(U("-.")); - verify_json_throws(U("-e1")); - verify_json_throws(U("-1e")); - verify_json_throws(U("+1.1")); - verify_json_throws(U("1.1 E")); - verify_json_throws(U("1.1E-")); - verify_json_throws(U("1.1E.1")); - verify_json_throws(U("1.1E1.1")); - verify_json_throws(U("001.1")); - verify_json_throws(U("-.100")); - verify_json_throws(U("-.001")); - verify_json_throws(U(".1")); - verify_json_throws(U("0.1.1")); - } - - // TFS 535589 - void parse_help(utility::string_t str) - { - utility::stringstream_t ss1; - ss1 << str; - verify_json_throws(ss1); - } - - TEST(objects) - { - verify_json_throws(U("}")); - parse_help(U("{")); - parse_help(U("{ 1, 10 }")); - parse_help(U("{ : }")); - parse_help(U("{ \"}")); - verify_json_throws(U("{")); - verify_json_throws(U("{ 1")); - verify_json_throws(U("{ \"}")); - verify_json_throws(U("{\"2\":")); - verify_json_throws(U("{\"2\":}")); - verify_json_throws(U("{\"2\": true")); - verify_json_throws(U("{\"2\": true false")); - verify_json_throws(U("{\"2\": true :false")); - verify_json_throws(U("{\"2\": false,}")); - } - - TEST(arrays) - { - verify_json_throws(U("]")); - verify_json_throws(U("[")); - verify_json_throws(U("[ 1")); - verify_json_throws(U("[ 1,")); - verify_json_throws(U("[ 1,]")); - verify_json_throws(U("[ 1 2]")); - verify_json_throws(U("[ \"1\" : 2]")); - parse_help(U("[,]")); - parse_help(U("[ \"]")); - parse_help(U("[\"2\", false,]")); - } - - TEST(literals_not_lower_case) - { - verify_json_throws(U("NULL")); - verify_json_throws(U("FAlse")); - verify_json_throws(U("TRue")); - } - - TEST(incomplete_literals) - { - verify_json_throws(U("nul")); - verify_json_throws(U("fal")); - verify_json_throws(U("tru")); - } - - // TFS#501321 - TEST(exception_string) - { - utility::string_t json_ip_str = U(""); - verify_json_throws(json_ip_str); - } - - TEST(boundary_chars) - { - utility::string_t str(U("\"")); - str.append(1, 0x1F); - str.append(U("\"")); - parse_help(str); - } - - TEST(stream_left_over_chars) - { - std::stringbuf buf; - buf.sputn("[false]false", 12); - std::istream stream(&buf); - verify_json_throws(stream); - } - -// Test using Windows only API. -#ifdef _WIN32 - TEST(wstream_left_over_chars) - { - std::wstringbuf buf; - buf.sputn(L"[false]false", 12); - std::wistream stream(&buf); - verify_json_throws(stream); - } -#endif - - void garbage_impl(wchar_t ch) - { - utility::string_t ss(U("{\"a\" : 10, \"b\":")); - - std::random_device rd; - std::mt19937 eng(rd()); - std::uniform_int_distribution<unsigned int> dist(0, ch); - - for (int i = 0; i < 2500; i++) - ss.push_back(static_cast<char_t>(dist(eng))); - - verify_json_throws(ss); - } - - TEST(garbage_1) { garbage_impl(0x7F); } - - TEST(garbage_2) { garbage_impl(0xFF); } - - TEST(garbage_3) { garbage_impl(0xFFFF); } -} - -} // namespace json_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/parsing_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/parsing_tests.cpp @@ -1,943 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests for JSON parsing. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/json.h" -#include "unittestpp.h" -#include <array> -#include <iomanip> - -#if defined(_WIN32) || defined(__APPLE__) -#include <regex> -#elif (defined(ANDROID) || defined(__ANDROID__)) -#else -// GCC 4.8 doesn't support regex very well, fall back to Boost. Revist in GCC 4.9. -#include <boost/regex.hpp> -#endif - -using namespace web; -using namespace utility; -using namespace utility::conversions; - -static utility::string_t youtubeJson = _XPLATSTR( -R"delimeter({ - "kind": "youtube#playlistItemListResponse", - "etag": "\"Fznwjl6JEQdo1MGvHOGaz_YanRU/ranGcWzseanYs9xZ0NXAq24qK-w\"", - "pageInfo": { - "totalResults": 3, - "resultsPerPage": 5 - }, - "items": [ - { - "kind": "youtube#playlistItem", - "etag": "\"Fznwjl6JEQdo1MGvHOGaz_YanRU/phfRXORDKFrYjeJGWbI8MbIk08A\"", - "id": "VVVGMWhNVVZ3bHJ2bFZNalVHT1pFeGdnLm12RERIeEJyd1U4", - "snippet": { - "publishedAt": "2013-05-24T22:03:10.000Z", - "channelId": "UCF1hMUVwlrvlVMjUGOZExgg", - "title": "C++ REST SDK (\"Casablanca\")", - "description": "This library is a Microsoft effort to support cloud-based client-server communication in native code using a modern asynchronous C++ API design.", - "thumbnails": { - "default": { - "url": "https://i.ytimg.com/vi/mvDDHxBrwU8/default.jpg", - "width": 120, - "height": 90 - }, - "medium": { - "url": "https://i.ytimg.com/vi/mvDDHxBrwU8/mqdefault.jpg", - "width": 320, - "height": 180 - }, - "high": { - "url": "https://i.ytimg.com/vi/mvDDHxBrwU8/hqdefault.jpg", - "width": 480, - "height": 360 - }, - "standard": { - "url": "https://i.ytimg.com/vi/mvDDHxBrwU8/sddefault.jpg", - "width": 640, - "height": 480 - }, - "maxres": { - "url": "https://i.ytimg.com/vi/mvDDHxBrwU8/maxresdefault.jpg", - "width": 1280, - "height": 720 - } - }, - "channelTitle": "casablancacore", - "playlistId": "UUF1hMUVwlrvlVMjUGOZExgg", - "position": 0, - "resourceId": { - "kind": "youtube#video", - "videoId": "mvDDHxBrwU8" - } - } - }, - { - "kind": "youtube#playlistItem", - "etag": "\"Fznwjl6JEQdo1MGvHOGaz_YanRU/J65jYO0AIlbIqd4JpVigajlhVnE\"", - "id": "VVVGMWhNVVZ3bHJ2bFZNalVHT1pFeGdnLmlFVU9fdDhFYW5r", - "snippet": { - "publishedAt": "2013-05-07T18:47:24.000Z", - "channelId": "UCF1hMUVwlrvlVMjUGOZExgg", - "title": "C++ REST SDK", - "description": "A brief introduction to the C++ REST SDK. This video goes over high level concepts and features of the library. \n\nFor more information visit: http://casablanca.codeplex.com\nFor more information on PPL tasks visit: http://msdn.microsoft.com/en-us/library/dd492418.aspx", - "thumbnails": { - "default": { - "url": "https://i.ytimg.com/vi/iEUO_t8Eank/default.jpg", - "width": 120, - "height": 90 - }, - "medium": { - "url": "https://i.ytimg.com/vi/iEUO_t8Eank/mqdefault.jpg", - "width": 320, - "height": 180 - }, - "high": { - "url": "https://i.ytimg.com/vi/iEUO_t8Eank/hqdefault.jpg", - "width": 480, - "height": 360 - }, - "standard": { - "url": "https://i.ytimg.com/vi/iEUO_t8Eank/sddefault.jpg", - "width": 640, - "height": 480 - } - }, - "channelTitle": "casablancacore", - "playlistId": "UUF1hMUVwlrvlVMjUGOZExgg", - "position": 1, - "resourceId": { - "kind": "youtube#video", - "videoId": "iEUO_t8Eank" - } - } - }, - { - "kind": "youtube#playlistItem", - "etag": "\"Fznwjl6JEQdo1MGvHOGaz_YanRU/XMpuK2N4-LOhDWtgCG8nBw7eNl8\"", - "id": "VVVGMWhNVVZ3bHJ2bFZNalVHT1pFeGdnLk41cnlJN3U5RVFB", - "snippet": { - "publishedAt": "2013-05-02T21:24:56.000Z", - "channelId": "UCF1hMUVwlrvlVMjUGOZExgg", - "title": "bunny", - "description": "", - "thumbnails": { - "default": { - "url": "https://i.ytimg.com/vi/N5ryI7u9EQA/default.jpg", - "width": 120, - "height": 90 - }, - "medium": { - "url": "https://i.ytimg.com/vi/N5ryI7u9EQA/mqdefault.jpg", - "width": 320, - "height": 180 - }, - "high": { - "url": "https://i.ytimg.com/vi/N5ryI7u9EQA/hqdefault.jpg", - "width": 480, - "height": 360 - }, - "standard": { - "url": "https://i.ytimg.com/vi/N5ryI7u9EQA/sddefault.jpg", - "width": 640, - "height": 480 - } - }, - "channelTitle": "casablancacore", - "playlistId": "UUF1hMUVwlrvlVMjUGOZExgg", - "position": 2, - "resourceId": { - "kind": "youtube#video", - "videoId": "N5ryI7u9EQA" - } - } - } - ] -})delimeter" -); - -namespace tests -{ -namespace functional -{ -namespace json_tests -{ -inline bool verify_parsing_error_msg(const std::string& str) -{ -#if defined(_WIN32) || defined(__APPLE__) - auto spattern = "^\\* Line \\d+, Column \\d+ Syntax error: .+"; - static std::regex pattern(spattern); - return std::regex_match(str, pattern, std::regex_constants::match_flag_type::match_not_null); -#elif (defined(ANDROID) || defined(__ANDROID__)) - return str.find("Syntax error: ") != std::string::npos; -#else - auto spattern = "^\\* Line \\d+, Column \\d+ Syntax error: .+"; - static boost::regex pattern(spattern); - return boost::regex_match(str, pattern, boost::regex_constants::match_flag_type::match_not_null); -#endif -} - -#if defined(_MSC_VER) -#pragma warning(disable : 4127) // const expression -#endif -#define VERIFY_PARSING_THROW(target) \ - do \ - { \ - try \ - { \ - target; \ - VERIFY_IS_TRUE(false); \ - } \ - catch (const json::json_exception& e) \ - { \ - VERIFY_IS_TRUE(verify_parsing_error_msg(e.what())); \ - } \ - catch (...) \ - { \ - VERIFY_IS_TRUE(false); \ - } \ - } while (false) - -SUITE(parsing_tests) -{ - TEST(stringstream_t) - { - utility::stringstream_t ss0; - ss0 << U("null"); - json::value v0 = json::value::parse(ss0); - - utility::stringstream_t ss1; - ss1 << U("17"); - json::value v1 = json::value::parse(ss1); - - utility::stringstream_t ss2; - ss2 << U("3.1415"); - json::value v2 = json::value::parse(ss2); - - utility::stringstream_t ss3; - ss3 << U("true"); - json::value v3 = json::value::parse(ss3); - - utility::stringstream_t ss4; - ss4 << U("\"Hello!\""); - json::value v4 = json::value::parse(ss4); - - utility::stringstream_t ss8; - ss8 << U("{ \"a\" : 10 }"); - json::value v8 = json::value::parse(ss8); - - utility::stringstream_t ss9; - ss9 << U("[1,2,3,true]"); - json::value v9 = json::value::parse(ss9); - - VERIFY_ARE_EQUAL(v1.type(), json::value::Number); - VERIFY_ARE_EQUAL(v2.type(), json::value::Number); - VERIFY_ARE_EQUAL(v3.type(), json::value::Boolean); - VERIFY_ARE_EQUAL(v4.type(), json::value::String); - VERIFY_ARE_EQUAL(v8.type(), json::value::Object); - VERIFY_ARE_EQUAL(v9.type(), json::value::Array); - } - - TEST(whitespace_failure) { VERIFY_PARSING_THROW(json::value::parse(U(" "))); } - - static const std::array<char, 4> whitespace_chars = {{0x20, 0x09, 0x0A, 0x0D}}; - - TEST(whitespace_array) - { - // Try all the whitespace characters before/after all the structural characters - // whitespace characters according to RFC4627: space, horizontal tab, line feed or new line, carriage return - // structural characters: [{]}:, - - // [,] - for (auto ch : whitespace_chars) - { - utility::string_t input; - input.append(2, ch); - input.append(U("[")); - input.append(2, ch); - input.append(U("1")); - input.append(1, ch); - input.append(U(",")); - input.append(4, ch); - input.append(U("2")); - input.append(1, ch); - input.append(U("]")); - input.append(2, ch); - json::value val = json::value::parse(input); - VERIFY_IS_TRUE(val.is_array()); - VERIFY_ARE_EQUAL(U("1"), val[0].serialize()); - VERIFY_ARE_EQUAL(U("2"), val[1].serialize()); - } - } - - TEST(whitespace_object) - { - // {:} - for (auto ch : whitespace_chars) - { - utility::string_t input; - input.append(2, ch); - input.append(U("{")); - input.append(2, ch); - input.append(U("\"1\"")); - input.append(1, ch); - input.append(U(":")); - input.append(4, ch); - input.append(U("2")); - input.append(1, ch); - input.append(U("}")); - input.append(2, ch); - json::value val = json::value::parse(input); - VERIFY_IS_TRUE(val.is_object()); - VERIFY_ARE_EQUAL(U("2"), val[U("1")].serialize()); - } - } - - TEST(string_t) - { - json::value str = json::value::parse(U("\"\\\"\"")); - VERIFY_ARE_EQUAL(U("\""), str.as_string()); - - str = json::value::parse(U("\"\"")); - VERIFY_ARE_EQUAL(U(""), str.as_string()); - - str = json::value::parse(U("\"\\\"ds\"")); - VERIFY_ARE_EQUAL(U("\"ds"), str.as_string()); - - str = json::value::parse(U("\"\\\"\\\"\"")); - VERIFY_ARE_EQUAL(U("\"\""), str.as_string()); - - // two character escapes - str = json::value::parse(U("\"\\\\\"")); - VERIFY_ARE_EQUAL(U("\\"), str.as_string()); - - str = json::value::parse(U("\"\\/\"")); - VERIFY_ARE_EQUAL(U("/"), str.as_string()); - - str = json::value::parse(U("\"\\b\"")); - VERIFY_ARE_EQUAL(U("\b"), str.as_string()); - - str = json::value::parse(U("\"\\f\"")); - VERIFY_ARE_EQUAL(U("\f"), str.as_string()); - - str = json::value::parse(U("\"\\n\"")); - VERIFY_ARE_EQUAL(U("\n"), str.as_string()); - - str = json::value::parse(U("\"\\r\"")); - VERIFY_ARE_EQUAL(U("\r"), str.as_string()); - - str = json::value::parse(U("\"\\t\"")); - VERIFY_ARE_EQUAL(U("\t"), str.as_string()); - } - - TEST(escaped_unicode_string) - { - auto str = json::value::parse(U("\"\\u0041\"")); - VERIFY_ARE_EQUAL(U("A"), str.as_string()); - - str = json::value::parse(U("\"\\u004B\"")); - VERIFY_ARE_EQUAL(U("K"), str.as_string()); - - str = json::value::parse(U("\"\\u20AC\"")); - // Euro sign as a hexadecimal UTF-8 - const auto euro = to_string_t("\xE2\x82\xAC"); - VERIFY_ARE_EQUAL(euro, str.as_string()); - - // UTF-16 character with surrogate pair - str = json::value::parse(U("\"\\ud83d\\ude00\"")); - // Grinning Face emoji as a hexadecimal UTF-8 - const auto emoji = to_string_t("\xF0\x9F\x98\x80"); - VERIFY_ARE_EQUAL(emoji, str.as_string()); - - VERIFY_PARSING_THROW(json::value::parse(U("\"\\u0klB\""))); - } - - TEST(escaping_control_characters) - { - std::vector<int> chars; - for (int i = 0; i <= 0x1F; ++i) - { - chars.push_back(i); - } - chars.push_back(0x5C); // backslash '\' - chars.push_back(0x22); // quotation '"' - - for (int i : chars) - { - utility::stringstream_t ss; - ss << U("\"\\u") << std::uppercase << std::setfill(U('0')) << std::setw(4) << std::hex << i << U("\""); - const auto& str = ss.str(); - auto expectedStr = str; - if (i == 0x08) - { - expectedStr = U("\"\\b\""); - } - else if (i == 0x09) - { - expectedStr = U("\"\\t\""); - } - else if (i == 0x0A) - { - expectedStr = U("\"\\n\""); - } - else if (i == 0x0C) - { - expectedStr = U("\"\\f\""); - } - else if (i == 0x0D) - { - expectedStr = U("\"\\r\""); - } - else if (i == 0x5C) - { - expectedStr = U("\"\\\\\""); - } - else if (i == 0x22) - { - expectedStr = U("\"\\\"\""); - } - - // Try constructing a json string value directly. - utility::string_t schar; - schar.push_back(static_cast<utility::string_t::value_type>(i)); - const auto& sv = json::value::string(schar); - VERIFY_ARE_EQUAL(expectedStr, sv.serialize()); - - // Try parsing a string - const auto& v = json::value::parse(str); - VERIFY_IS_TRUE(v.is_string()); - VERIFY_ARE_EQUAL(expectedStr, v.serialize()); - - // Try parsing a stringstream. - const auto& ssv = json::value::parse(ss); - VERIFY_ARE_EQUAL(expectedStr, ssv.serialize()); - } - } - - TEST(comments_string) - { - // Nothing but a comment - VERIFY_PARSING_THROW(json::value::parse(U(" /* There's nothing but a comment here */ "))); - VERIFY_PARSING_THROW(json::value::parse(U(" // There's nothing but a comment here\n"))); - - // Some invalid comments - VERIFY_PARSING_THROW(json::value::parse(U(" -22 /*/"))); - VERIFY_PARSING_THROW(json::value::parse(U(" -22 /* /* nested */ */"))); - - // Correctly placed comments - json::value num1 = json::value::parse(U("-22 // This is a trailing comment\n")); - VERIFY_ARE_EQUAL(-22, num1.as_double()); - num1 = json::value::parse(U(" -22 /* This is a trailing comment with a // nested\n comment */")); - VERIFY_ARE_EQUAL(-22, num1.as_double()); - json::value num2 = json::value::parse(U("// This is a leading comment\n -22")); - VERIFY_ARE_EQUAL(-22, num2.as_double()); - json::value num3 = json::value::parse(U("-22 /* This is a trailing comment */")); - VERIFY_ARE_EQUAL(-22, num3.as_double()); - json::value num4 = json::value::parse(U("/* This is a leading comment */ -22")); - VERIFY_ARE_EQUAL(-22, num4.as_double()); - json::value num5 = json::value::parse(U("-22 /***/")); - VERIFY_ARE_EQUAL(-22, num5.as_double()); - - json::value obj1 = json::value::parse(U("{// A comment in the middle of an empty object\n}")); - VERIFY_IS_TRUE(obj1.is_object()); - VERIFY_ARE_EQUAL(0u, obj1.size()); - json::value obj2 = json::value::parse(U("{/* A comment in the middle of an empty object */}")); - VERIFY_IS_TRUE(obj2.is_object()); - VERIFY_ARE_EQUAL(0u, obj2.size()); - json::value obj3 = json::value::parse(U("{ \"test\" : // A comment in the middle of a non-empty object\n 2}")); - VERIFY_IS_TRUE(obj3.is_object()); - VERIFY_ARE_EQUAL(1u, obj3.size()); - json::value obj4 = json::value::parse(U("{ \"test\" : /* A comment in the middle of a non-empty object */ 2}")); - VERIFY_IS_TRUE(obj4.is_object()); - VERIFY_ARE_EQUAL(1u, obj4.size()); - - json::value arr1 = json::value::parse(U("[// A comment in the middle of an empty array\n]")); - VERIFY_IS_TRUE(arr1.is_array()); - VERIFY_ARE_EQUAL(0u, arr1.size()); - json::value arr2 = json::value::parse(U("[/* A comment in the middle of an empty array */]")); - VERIFY_IS_TRUE(arr2.is_array()); - VERIFY_ARE_EQUAL(0u, arr2.size()); - json::value arr3 = json::value::parse(U("[ 1, // A comment in the middle of a non-array\n 2]")); - VERIFY_IS_TRUE(arr3.is_array()); - VERIFY_ARE_EQUAL(2u, arr3.size()); - json::value arr4 = json::value::parse(U("[ 1, /* A comment in the middle of a non-empty array */ 2]")); - VERIFY_IS_TRUE(arr4.is_array()); - VERIFY_ARE_EQUAL(2u, arr4.size()); - } - - TEST(comments_stream) - { - // Nothing but a comment - { - std::basic_stringstream<utility::char_t> stream; - stream << U(" /* There's nothing but a comment here */ "); - VERIFY_PARSING_THROW(json::value::parse(stream)); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U(" // There's nothing but a comment here\n "); - VERIFY_PARSING_THROW(json::value::parse(stream)); - } - - // Some invalid comments - { - std::basic_stringstream<utility::char_t> stream; - stream << U(" -22 /*/"); - VERIFY_PARSING_THROW(json::value::parse(stream)); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U(" -22 /* /* nested */ */"); - VERIFY_PARSING_THROW(json::value::parse(stream)); - } - - // Correctly placed comments - { - std::basic_stringstream<utility::char_t> stream; - stream << U("-22 // This is a trailing comment\n"); - json::value num1 = json::value::parse(stream); - VERIFY_ARE_EQUAL(-22, num1.as_double()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U(" -22 /* This is a trailing comment with a // nested\n comment */"); - json::value num1 = json::value::parse(stream); - VERIFY_ARE_EQUAL(-22, num1.as_double()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("// This is a leading comment\n -22"); - json::value num2 = json::value::parse(stream); - VERIFY_ARE_EQUAL(-22, num2.as_double()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("-22 /* This is a trailing comment */"); - json::value num3 = json::value::parse(stream); - VERIFY_ARE_EQUAL(-22, num3.as_double()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("/* This is a leading comment */ -22"); - json::value num4 = json::value::parse(stream); - VERIFY_ARE_EQUAL(-22, num4.as_double()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("-22 /***/"); - json::value num4 = json::value::parse(stream); - VERIFY_ARE_EQUAL(-22, num4.as_double()); - } - - { - std::basic_stringstream<utility::char_t> stream; - stream << U("{// A comment in the middle of an empty object\n}"); - json::value obj1 = json::value::parse(stream); - VERIFY_IS_TRUE(obj1.is_object()); - VERIFY_ARE_EQUAL(0u, obj1.size()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("{/* A comment in the middle of an empty object */}"); - json::value obj2 = json::value::parse(stream); - VERIFY_IS_TRUE(obj2.is_object()); - VERIFY_ARE_EQUAL(0u, obj2.size()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("{ \"test1\" : // A comment in the middle of a non-empty object\n 2}"); - json::value obj3 = json::value::parse(stream); - VERIFY_IS_TRUE(obj3.is_object()); - VERIFY_ARE_EQUAL(1u, obj3.size()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("{ \"test1\" : /* A comment in the middle of a non-empty object */ 2}"); - json::value obj4 = json::value::parse(stream); - VERIFY_IS_TRUE(obj4.is_object()); - VERIFY_ARE_EQUAL(1u, obj4.size()); - } - - { - std::basic_stringstream<utility::char_t> stream; - stream << U("[// A comment in the middle of an empty array\n]"); - json::value arr1 = json::value::parse(stream); - VERIFY_IS_TRUE(arr1.is_array()); - VERIFY_ARE_EQUAL(0u, arr1.size()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("[/* A comment in the middle of an empty array */]"); - json::value arr2 = json::value::parse(stream); - VERIFY_IS_TRUE(arr2.is_array()); - VERIFY_ARE_EQUAL(0u, arr2.size()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("[ 1, // A comment in the middle of a non-array\n 2]"); - json::value arr3 = json::value::parse(stream); - VERIFY_IS_TRUE(arr3.is_array()); - VERIFY_ARE_EQUAL(2u, arr3.size()); - } - { - std::basic_stringstream<utility::char_t> stream; - stream << U("[ 1, /* A comment in the middle of a non-empty array */ 2]"); - json::value arr4 = json::value::parse(stream); - VERIFY_IS_TRUE(arr4.is_array()); - VERIFY_ARE_EQUAL(2u, arr4.size()); - } - } - - TEST(empty_object_array) - { - json::value obj = json::value::parse(U("{}")); - VERIFY_IS_TRUE(obj.is_object()); - VERIFY_ARE_EQUAL(0u, obj.size()); - - json::value arr = json::value::parse(U("[]")); - VERIFY_IS_TRUE(arr.is_array()); - VERIFY_ARE_EQUAL(0u, arr.size()); - } - - TEST(bug_object_field_key_no_value) - { - VERIFY_PARSING_THROW(json::value::parse(U("{\"meow\"}"))); - VERIFY_PARSING_THROW(json::value::parse(U("{\"meow\": 42, \"purr\": 57, \"hiss\"}"))); - } - - TEST(bug_416116) - { - json::value data2 = json::value::parse(U("\"δοκιμή\"")); - auto s = data2.serialize(); - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4566) -#endif - VERIFY_ARE_EQUAL(s, U("\"δοκιμή\"")); -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - } - - TEST(byte_ptr_parsing_array) - { - char s[] = "[ \"test1\",true]"; - json::value v = json::value::parse(s); - std::stringstream ss; - ss << s; - json::value vv = json::value::parse(ss); - VERIFY_ARE_EQUAL(v, vv); - - auto s2 = v.serialize(); - VERIFY_ARE_EQUAL(s2, U("[\"test1\",true]")); - - std::stringstream os; - vv.serialize(os); - VERIFY_ARE_EQUAL(s2, to_string_t(os.str())); - } - - TEST(byte_ptr_parsing_object) - { - char s[] = "{\"test1\":true }"; - json::value v = json::value::parse(s); - std::stringstream ss; - ss << s; - json::value vv = json::value::parse(ss); - VERIFY_ARE_EQUAL(v, vv); - - auto s2 = v.serialize(); - VERIFY_ARE_EQUAL(s2, U("{\"test1\":true}")); - - std::stringstream os; - vv.serialize(os); - VERIFY_ARE_EQUAL(s2, to_string_t(os.str())); - } - - TEST(Japanese) - { - utility::string_t ws = U("\"こんにちは\""); - std::string s = to_utf8string(ws); - json::value v = json::value::parse(s); - - std::stringstream ss; - ss << s; - json::value vv = json::value::parse(ss); - VERIFY_ARE_EQUAL(v, vv); - - auto s2 = v.serialize(); - VERIFY_ARE_EQUAL(s2, ws); - - std::stringstream os; - vv.serialize(os); - VERIFY_ARE_EQUAL(s2, to_string_t(os.str())); - } - - TEST(Russian) - { - utility::string_t ws = U("{\"results\":[{\"id\":272655310,\"name\":\"Андрей Ив´анов\"}]}"); - json::value v1 = json::value::parse(ws); - auto s2 = v1.serialize(); - - VERIFY_ARE_EQUAL(s2, ws); - - std::string s = to_utf8string(ws); - - std::stringstream ss; - ss << s; - json::value v2 = json::value::parse(ss); - auto s3 = v2.serialize(); - - VERIFY_ARE_EQUAL(s3, ws); - } - - utility::string_t make_deep_json_string(size_t depth) - { - utility::string_t strval; - for (size_t i = 0; i < depth; ++i) - { - strval += U("{ \"a\" : 10, \"b\" : "); - } - strval += U("20"); - for (size_t i = 0; i < depth; ++i) - { - strval += U("}"); - } - return strval; - } - - TEST(deeply_nested) - { -#if defined(__APPLE__) - size_t safeDepth = 32; - size_t overDepth = 33; -#else - size_t safeDepth = 128; - size_t overDepth = 129; -#endif - - // This should parse without issues: - auto strGood = make_deep_json_string(safeDepth); - json::value::parse(strGood); - - // But this one should throw: - auto strBad = make_deep_json_string(overDepth); - VERIFY_PARSING_THROW(json::value::parse(strBad)); - } - - static bool compare_pairs(const std::pair<utility::string_t, json::value>& p1, - const std::pair<utility::string_t, json::value>& p2) - { - return p1.first < p2.first; - } - - TEST(unsorted_object_parsing) - { - utility::stringstream_t ss; - ss << U("{\"z\":2, \"a\":1}"); - json::value v = json::value::parse(ss); - auto& obj = v.as_object(); - - VERIFY_ARE_NOT_EQUAL(obj.find(U("a")), obj.end()); - VERIFY_ARE_NOT_EQUAL(obj.find(U("z")), obj.end()); - VERIFY_ARE_EQUAL(obj[U("a")], 1); - VERIFY_ARE_EQUAL(obj[U("z")], 2); - VERIFY_ARE_EQUAL(obj.size(), 2); - - VERIFY_IS_TRUE(::std::is_sorted(obj.begin(), obj.end(), compare_pairs)); - } - - TEST(keep_order_while_parsing) - { - utility::stringstream_t ss; - ss << U("{\"k\":3, \"j\":2, \"i\":1}"); - - json::keep_object_element_order(true); - struct restore - { - ~restore() { json::keep_object_element_order(false); } - } _; - - json::value v = json::value::parse(ss); - auto& obj = v.as_object(); - - // Make sure collection stays unsorted: - auto b = obj.begin(); - VERIFY_ARE_EQUAL(b[0].first, U("k")); - VERIFY_ARE_EQUAL(b[1].first, U("j")); - VERIFY_ARE_EQUAL(b[2].first, U("i")); - - // Make sure lookup still works: - auto val_i = obj[U("i")]; - VERIFY_ARE_EQUAL(val_i.as_integer(), 1); - - auto val_j = obj[U("j")]; - VERIFY_ARE_EQUAL(val_j.as_integer(), 2); - - // Make sure 'a' goes to the back of the collection, and - // can be looked up - obj[U("a")] = 4; - b = obj.begin(); - VERIFY_ARE_EQUAL(b[3].first, U("a")); - VERIFY_ARE_EQUAL(obj[U("a")].as_integer(), 4); - } - - TEST(non_default_locale, "Ignore:Android", "Locale unsupported on Android") - { - std::string originalLocale = setlocale(LC_ALL, nullptr); -#ifdef _WIN32 - std::string changedLocale("fr-FR"); -#else - std::string changedLocale("fr_FR.utf8"); -#endif - - // If locale isn't installed on system just silently pass. - if (setlocale(LC_ALL, changedLocale.c_str()) != nullptr) - { - // string serialize - utility::string_t str(U("[true,false,-1.55,5,null,{\"abc\":5555}]")); - json::value v = json::value::parse(str); - VERIFY_ARE_EQUAL(changedLocale, setlocale(LC_ALL, nullptr)); - VERIFY_ARE_EQUAL(str, v.serialize()); - VERIFY_ARE_EQUAL(changedLocale, setlocale(LC_ALL, nullptr)); - - setlocale(LC_ALL, originalLocale.c_str()); - setlocale(LC_NUMERIC, changedLocale.c_str()); - - // cpprestsdk stream serialize - utility::stringstream_t stream; - stream << v; - utility::string_t serializedStr; - stream >> serializedStr; - VERIFY_ARE_EQUAL(str, serializedStr); - - // std stream serialize - std::stringstream stdStream; - v.serialize(stdStream); - std::string stdStr; - stdStream >> stdStr; - VERIFY_ARE_EQUAL(str, utility::conversions::to_string_t(stdStr)); - - setlocale(LC_ALL, originalLocale.c_str()); - } - } - - template<typename T> - void error_code_helper(T & jsonData) - { - std::error_code err; - auto parsedObject = web::json::value::parse(jsonData, err); - VERIFY_IS_TRUE(err.value() == 0); - VERIFY_IS_TRUE(!parsedObject.is_null()); - } - - TEST(parse_overload_success) - { - std::error_code err; - utility::string_t valueStr(U("\"JSONString\"")); - utility::string_t arrStr(U("[true,false,-1.55,5,null,{\"abc\":5555}]")); - utility::string_t objStr(U("{\"k\":3, \"j\":2, \"i\":1}")); - - error_code_helper(valueStr); - error_code_helper(arrStr); - error_code_helper(objStr); - - utility::stringstream_t valueStringStream; - utility::stringstream_t arrayStringStream; - utility::stringstream_t objStringStream; - - valueStringStream << valueStr; - arrayStringStream << arrStr; - objStringStream << objStr; - - error_code_helper(valueStringStream); - error_code_helper(arrayStringStream); - error_code_helper(objStringStream); - -#ifdef _WIN32 - std::wstringbuf buf; - - buf.sputn(valueStr.c_str(), valueStr.size()); - std::wistream valStream(&buf); - error_code_helper(valStream); - - buf.sputn(arrStr.c_str(), arrStr.size()); - std::wistream arrStream(&buf); - error_code_helper(arrStream); - - buf.sputn(objStr.c_str(), objStr.size()); - std::wistream objStream(&buf); - error_code_helper(objStream); -#endif - } - - TEST(parse_overload_failed) - { - std::error_code err, streamErr, iStreamErr; - utility::string_t str(U("JSONString")); - utility::string_t arrStr(U("[true, false")); - json::value parsedObject = json::value::parse(str, err); - - VERIFY_IS_TRUE(err.value() > 0); - VERIFY_IS_TRUE(parsedObject.is_null()); - - utility::stringstream_t stream; - stream << str; - - parsedObject = json::value::parse(arrStr, streamErr); - VERIFY_IS_TRUE(streamErr.value() > 0); - VERIFY_IS_TRUE(parsedObject.is_null()); - -#ifdef _WIN32 - std::wstringbuf buf; - buf.sputn(str.c_str(), str.size()); - std::wistream iStream(&buf); - parsedObject = json::value::parse(str, iStreamErr); - VERIFY_IS_TRUE(iStreamErr.value() > 0); - VERIFY_IS_TRUE(parsedObject.is_null()); -#endif - } - - TEST(youtube_api) - { - auto v = json::value::parse(youtubeJson); - int count = 0; - auto& obj = v.as_object(); - - VERIFY_ARE_NOT_EQUAL(obj.find(U("pageInfo")), obj.end()); - VERIFY_ARE_NOT_EQUAL(obj.find(U("items")), obj.end()); - - auto& items = obj[U("items")]; - - for (auto iter = items.as_array().cbegin(); iter != items.as_array().cend(); ++iter) - { - const auto& item = *iter; - auto iSnippet = item.as_object().find(U("snippet")); - if (iSnippet == item.as_object().end()) - { - throw std::runtime_error("snippet key not found"); - } - auto iTitle = iSnippet->second.as_object().find(U("title")); - if (iTitle == iSnippet->second.as_object().end()) - { - throw std::runtime_error("title key not found"); - } - auto name = iTitle->second.serialize(); - count++; - } - VERIFY_ARE_EQUAL(3, count); // Update this accordingly, if the number of items changes - } - -} // SUITE(parsing_tests) - -} // namespace json_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/to_as_and_operators_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/json/to_as_and_operators_tests.cpp @@ -1,515 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests for to_*, as_*, and operators on JSON values. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/json.h" -#include "unittestpp.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace json_tests -{ -SUITE(to_as_and_operators_tests) -{ - TEST(to_string) - { - utility::stringstream_t stream(utility::stringstream_t::in | utility::stringstream_t::out); - - // null - json::value n; - VERIFY_ARE_EQUAL(U("null"), n.serialize()); - n.serialize(stream); - VERIFY_ARE_EQUAL(U("null"), stream.str()); - - // bool - true - stream.str(U("")); - json::value b(true); - VERIFY_ARE_EQUAL(U("true"), b.serialize()); - b.serialize(stream); - VERIFY_ARE_EQUAL(U("true"), stream.str()); - - // bool - false - stream.str(U("")); - json::value b2(false); - VERIFY_ARE_EQUAL(U("false"), b2.serialize()); - b2.serialize(stream); - VERIFY_ARE_EQUAL(U("false"), stream.str()); - - // number - int - stream.str(U("")); - json::value num(44); - VERIFY_ARE_EQUAL(U("44"), num.serialize()); - num.serialize(stream); - VERIFY_ARE_EQUAL(U("44"), stream.str()); - - // number - double - stream.str(U("")); - json::value dNum(11.5); - VERIFY_ARE_EQUAL(U("11.5"), dNum.serialize()); - dNum.serialize(stream); - VERIFY_ARE_EQUAL(U("11.5"), stream.str()); - - // string - stream.str(U("")); - json::value string = json::value::string(U("hehehe")); - VERIFY_ARE_EQUAL(U("\"hehehe\""), string.serialize()); - string.serialize(stream); - VERIFY_ARE_EQUAL(U("\"hehehe\""), stream.str()); - - // object - with values created from parsing - stream.str(U("")); - const utility::string_t strValue1(U("{ \"key\" : true }")); - const utility::string_t strValue2(U("{\"key\":true}")); - json::value obj1 = json::value::parse(strValue1); - VERIFY_ARE_EQUAL(strValue2, obj1.serialize()); - json::value obj2 = json::value::parse(strValue2); - VERIFY_ARE_EQUAL(strValue2, obj2.serialize()); - obj1.serialize(stream); - VERIFY_ARE_EQUAL(strValue2, stream.str()); - - // object - with values added - stream.str(U("")); - json::value obj3 = json::value::object(); - obj3[U("key")] = json::value(true); - VERIFY_ARE_EQUAL(strValue2, obj3.serialize()); - obj3.serialize(stream); - VERIFY_ARE_EQUAL(strValue2, stream.str()); - - // array - stream.str(U("")); - json::value arr = json::value::array(); - arr[0] = json::value::string(U("Here")); - arr[1] = json::value(true); - VERIFY_ARE_EQUAL(U("[\"Here\",true]"), arr.serialize()); - VERIFY_ARE_EQUAL(U("[\"Here\",true]"), arr.serialize()); - arr.serialize(stream); - VERIFY_ARE_EQUAL(U("[\"Here\",true]"), stream.str()); - } - - TEST(empty_arrays_objects) - { - // array - auto arr = json::value::parse(U("[ ]")); - VERIFY_ARE_EQUAL(U("[]"), arr.serialize()); - - // object - auto obj = json::value::parse(U("{ }")); - VERIFY_ARE_EQUAL(U("{}"), obj.serialize()); - } - - void verify_escaped_chars(const utility::string_t& str1, const utility::string_t& str2) - { - json::value j1 = json::value::string(str1); - VERIFY_ARE_EQUAL(str2, j1.serialize()); - } - - void verify_unescaped_chars(const utility::string_t& str1, const utility::string_t& str2) - { - json::value j1 = json::value::string(str1, false); - VERIFY_ARE_EQUAL(str2, j1.serialize()); - } - - TEST(to_string_escaped_chars) - { - verify_escaped_chars(U(" \" "), U("\" \\\" \"")); - verify_escaped_chars(U(" \b "), U("\" \\b \"")); - verify_escaped_chars(U(" \f "), U("\" \\f \"")); - verify_escaped_chars(U(" \n "), U("\" \\n \"")); - verify_escaped_chars(U(" \r "), U("\" \\r \"")); - verify_escaped_chars(U(" \t "), U("\" \\t \"")); - - json::value obj = json::value::object(); - obj[U(" \t ")] = json::value::string(U(" \b ")); - - json::value arr = json::value::array(); - arr[0] = json::value::string(U(" \f ")); - - VERIFY_ARE_EQUAL(U("{\" \\t \":\" \\b \"}"), obj.serialize()); - VERIFY_ARE_EQUAL(U("[\" \\f \"]"), arr.serialize()); - - utility::string_t str(U("{\"hello\":\" \\\"here's looking at you kid\\\" \\r \"}")); - json::value obj2 = json::value::parse(str); - - VERIFY_ARE_EQUAL(str, obj2.serialize()); - } - - TEST(to_string_unescaped_chars) - { - verify_unescaped_chars(U(" \" "), U("\" \" \"")); - verify_unescaped_chars(U(" \b "), U("\" \b \"")); - verify_unescaped_chars(U(" \f "), U("\" \f \"")); - verify_unescaped_chars(U(" \n "), U("\" \n \"")); - verify_unescaped_chars(U(" \r "), U("\" \r \"")); - verify_unescaped_chars(U(" \t "), U("\" \t \"")); - - json::value obj = json::value::object(); - obj[U(" \t ")] = json::value::string(U(" \b "), false); - - json::value arr = json::value::array(); - arr[0] = json::value::string(U(" \f "), false); - - VERIFY_ARE_EQUAL(U("{\" \\t \":\" \b \"}"), obj.serialize()); - VERIFY_ARE_EQUAL(U("[\" \f \"]"), arr.serialize()); - } - - TEST(as_string) - { - json::value b(false); - VERIFY_THROWS(b.as_string(), json::json_exception); - VERIFY_THROWS(b.as_string(), json::json_exception); - - utility::string_t data(U("HERE IS A STRING")); - utility::string_t wdata(data.begin(), data.end()); - json::value str = json::value::string(data); - VERIFY_ARE_EQUAL(data, str.as_string()); - VERIFY_ARE_EQUAL(wdata, str.as_string()); - } - - TEST(as_copy_constructor) - { - auto arr = json::value::array(); - arr[0] = json::value::number(44); - arr[1] = json::value::string(U("abc")); - json::array arrCopy = arr.as_array(); - VERIFY_ARE_EQUAL(2, arrCopy.size()); - VERIFY_ARE_EQUAL(2, arr.size()); - VERIFY_ARE_EQUAL(44, arrCopy[0].as_integer()); - VERIFY_ARE_EQUAL(U("abc"), arrCopy[1].as_string()); - VERIFY_ARE_EQUAL(44, arr[0].as_integer()); - VERIFY_ARE_EQUAL(U("abc"), arr[1].as_string()); - - auto obj = json::value::object(); - obj[U("abc")] = json::value::number(123); - json::object objCopy = obj.as_object(); - VERIFY_ARE_EQUAL(1, objCopy.size()); - VERIFY_ARE_EQUAL(1, obj.size()); - VERIFY_ARE_EQUAL(123, objCopy[U("abc")].as_integer()); - VERIFY_ARE_EQUAL(123, obj[U("abc")].as_integer()); - - auto num = json::value::number(44); - json::number numCopy = num.as_number(); - VERIFY_ARE_EQUAL(44, num.as_integer()); - VERIFY_ARE_EQUAL(44, numCopy.to_int32()); - } - - TEST(as_bool_as_double_as_string) - { - utility::stringstream_t ss1; - ss1 << U("17"); - json::value v1 = json::value::parse(ss1); - - utility::stringstream_t ss2; - ss2 << U("3.1415"); - json::value v2 = json::value::parse(ss2); - - utility::stringstream_t ss3; - ss3 << U("true"); - json::value v3 = json::value::parse(ss3); - - utility::stringstream_t ss4; - ss4 << U("\"Hello!\""); - json::value v4 = json::value::parse(ss4); - - utility::stringstream_t ss8; - ss8 << U("{ \"a\" : 10, \"b\" : 4711.17, \"c\" : false }"); - json::value v8 = json::value::parse(ss8); - - utility::stringstream_t ss9; - ss9 << U("[1,2,3,true]"); - json::value v9 = json::value::parse(ss9); - - VERIFY_ARE_EQUAL(v1.as_double(), 17); - VERIFY_ARE_EQUAL(v2.as_double(), 3.1415); - VERIFY_IS_TRUE(v3.as_bool()); - VERIFY_ARE_EQUAL(v4.as_string(), U("Hello!")); - VERIFY_ARE_EQUAL(v4.as_string(), U("Hello!")); - - VERIFY_ARE_EQUAL(v8[U("a")].as_double(), 10); - VERIFY_ARE_EQUAL(v8[U("b")].as_double(), 4711.17); - VERIFY_ARE_EQUAL(v8[U("a")].as_integer(), 10); - VERIFY_IS_FALSE(v8[U("c")].as_bool()); - - VERIFY_ARE_EQUAL(v9[0].as_double(), 1); - VERIFY_ARE_EQUAL(v9[1].as_double(), 2); - VERIFY_ARE_EQUAL(v9[2].as_double(), 3); - VERIFY_IS_TRUE(v9[3].as_bool()); - } - - TEST(to_stream_operator) - { - utility::string_t str(U("\"JSON STRING\"")); - json::value value = json::value::parse(str); - utility::stringstream_t stream; - stream << value; - VERIFY_ARE_EQUAL(str, stream.str()); - } - - TEST(from_stream_operator) - { - utility::string_t str(U("\"JSON STRING!\"")); - utility::stringstream_t stream; - stream << str; - json::value value; - stream >> value; - VERIFY_IS_TRUE(value.is_string()); - VERIFY_ARE_EQUAL(str, value.serialize()); - } - - TEST(negative_is_tests) - { - json::value b(true); - json::value str(U("string")); - json::value d(22.5); - json::value n; - json::value a = json::value::array(2); - json::value o = json::value::object(); - - VERIFY_IS_FALSE(b.is_number()); - VERIFY_IS_FALSE(str.is_boolean()); - VERIFY_IS_FALSE(d.is_string()); - VERIFY_IS_FALSE(a.is_object()); - VERIFY_IS_FALSE(o.is_array()); - VERIFY_IS_FALSE(n.is_string()); - VERIFY_IS_FALSE(str.is_null()); - } - - TEST(negative_index_operator_boolean) - { - json::value v = json::value::boolean(true); - - VERIFY_THROWS(v[0], json::json_exception); - VERIFY_THROWS(v[U("H")], json::json_exception); - VERIFY_THROWS(v[U("A")], json::json_exception); - } - - TEST(negative_get_field_object) - { - json::value v; - - v[U("a")] = json::value::number(1); - VERIFY_IS_TRUE(v.is_object()); - VERIFY_ARE_EQUAL(v[U("a")].as_integer(), 1); - VERIFY_IS_TRUE(v[U("b")].is_null()); - VERIFY_THROWS(v[0], json::json_exception); - } - - TEST(negative_get_element_array) - { - json::value v; - - v[0] = json::value::number(1); - VERIFY_ARE_EQUAL(v[0].as_integer(), 1); - VERIFY_IS_TRUE(v[1].is_null()); - VERIFY_THROWS(v[U("a")], json::json_exception); - } - - TEST(has_field_object) - { - json::value v1; - - v1[U("a")] = json::value::number(1); - v1[U("b")] = json::value::boolean(true); - v1[U("c")] = json::value::string(U("a string")); - v1[U("d")] = json::value::array({}); - json::value sub_field; - sub_field[U("x")] = json::value::number(1); - v1[U("e")] = sub_field; - - VERIFY_IS_TRUE(v1.has_field(U("a"))); - VERIFY_IS_TRUE(v1.has_field(U("b"))); - VERIFY_IS_TRUE(v1.has_field(U("c"))); - VERIFY_IS_TRUE(v1.has_field(U("d"))); - VERIFY_IS_TRUE(v1.has_field(U("e"))); - VERIFY_IS_FALSE(v1.has_field(U("f"))); - - VERIFY_IS_TRUE(v1.has_number_field(U("a"))); - VERIFY_IS_TRUE(v1.has_integer_field(U("a"))); - VERIFY_IS_FALSE(v1.has_double_field(U("a"))); - VERIFY_IS_FALSE(v1.has_boolean_field(U("a"))); - VERIFY_IS_FALSE(v1.has_string_field(U("a"))); - VERIFY_IS_FALSE(v1.has_array_field(U("a"))); - VERIFY_IS_FALSE(v1.has_object_field(U("a"))); - - VERIFY_IS_TRUE(v1.has_boolean_field(U("b"))); - VERIFY_IS_FALSE(v1.has_number_field(U("b"))); - VERIFY_IS_FALSE(v1.has_integer_field(U("b"))); - VERIFY_IS_FALSE(v1.has_double_field(U("b"))); - VERIFY_IS_FALSE(v1.has_string_field(U("b"))); - VERIFY_IS_FALSE(v1.has_array_field(U("b"))); - VERIFY_IS_FALSE(v1.has_object_field(U("b"))); - - VERIFY_IS_TRUE(v1.has_string_field(U("c"))); - VERIFY_IS_FALSE(v1.has_boolean_field(U("c"))); - VERIFY_IS_FALSE(v1.has_number_field(U("c"))); - VERIFY_IS_FALSE(v1.has_integer_field(U("c"))); - VERIFY_IS_FALSE(v1.has_double_field(U("c"))); - VERIFY_IS_FALSE(v1.has_array_field(U("c"))); - VERIFY_IS_FALSE(v1.has_object_field(U("c"))); - - VERIFY_IS_TRUE(v1.has_array_field(U("d"))); - VERIFY_IS_FALSE(v1.has_string_field(U("d"))); - VERIFY_IS_FALSE(v1.has_boolean_field(U("d"))); - VERIFY_IS_FALSE(v1.has_number_field(U("d"))); - VERIFY_IS_FALSE(v1.has_integer_field(U("d"))); - VERIFY_IS_FALSE(v1.has_double_field(U("d"))); - VERIFY_IS_FALSE(v1.has_object_field(U("d"))); - - VERIFY_IS_TRUE(v1.has_object_field(U("e"))); - VERIFY_IS_FALSE(v1.has_array_field(U("e"))); - VERIFY_IS_FALSE(v1.has_string_field(U("e"))); - VERIFY_IS_FALSE(v1.has_boolean_field(U("e"))); - VERIFY_IS_FALSE(v1.has_number_field(U("e"))); - VERIFY_IS_FALSE(v1.has_integer_field(U("e"))); - VERIFY_IS_FALSE(v1.has_double_field(U("e"))); - - json::value v2; - - v2[0] = json::value::number(1); - VERIFY_IS_FALSE(v2.has_field(U("0"))); - VERIFY_IS_FALSE(v2.has_field(U("b"))); - } - - TEST(negative_as_tests) - { - json::value b(true); - VERIFY_THROWS(b.as_double(), json::json_exception); - VERIFY_THROWS(b.as_integer(), json::json_exception); - VERIFY_THROWS(b.as_string(), json::json_exception); - - json::value str = json::value::string(U("string")); - VERIFY_THROWS(str.as_double(), json::json_exception); - VERIFY_THROWS(str.as_bool(), json::json_exception); - VERIFY_THROWS(str.as_integer(), json::json_exception); - - json::value d(2.0f); - VERIFY_THROWS(d.as_string(), json::json_exception); - VERIFY_THROWS(d.as_bool(), json::json_exception); - - json::value i(11); - VERIFY_THROWS(i.as_bool(), json::json_exception); - VERIFY_THROWS(i.as_string(), json::json_exception); - } - - TEST(erase_array_index) - { - json::value a = json::value::array(4); - a[0] = json::value(1); - a[1] = json::value(2); - a[2] = json::value(3); - a[3] = json::value(4); - - a.erase(1); - VERIFY_ARE_EQUAL(3, a.size()); - VERIFY_ARE_EQUAL(1, a[0].as_integer()); - VERIFY_ARE_EQUAL(3, a[1].as_integer()); - VERIFY_ARE_EQUAL(4, a[2].as_integer()); - a.as_array().erase(2); - VERIFY_ARE_EQUAL(2, a.size()); - VERIFY_ARE_EQUAL(1, a[0].as_integer()); - VERIFY_ARE_EQUAL(3, a[1].as_integer()); - } - - TEST(erase_array_iter) - { - json::value a = json::value::array(3); - a[0] = json::value(1); - a[1] = json::value(2); - a[2] = json::value(3); - - auto iter = a.as_array().begin() + 1; - auto afterLoc = a.as_array().erase(iter); - VERIFY_ARE_EQUAL(3, afterLoc->as_integer()); - VERIFY_ARE_EQUAL(2, a.size()); - VERIFY_ARE_EQUAL(1, a[0].as_integer()); - VERIFY_ARE_EQUAL(3, a[1].as_integer()); - - iter = a.as_array().begin() + 1; - afterLoc = a.as_array().erase(iter); - VERIFY_ARE_EQUAL(a.as_array().end(), afterLoc); - VERIFY_ARE_EQUAL(1, a.size()); - VERIFY_ARE_EQUAL(1, a[0].as_integer()); - } - - TEST(erase_object_key) - { - auto o = json::value::object(); - o[U("a")] = json::value(1); - o[U("b")] = json::value(2); - o[U("c")] = json::value(3); - o[U("d")] = json::value(4); - - o.erase(U("a")); - VERIFY_ARE_EQUAL(3, o.size()); - VERIFY_ARE_EQUAL(2, o[U("b")].as_integer()); - VERIFY_ARE_EQUAL(3, o[U("c")].as_integer()); - VERIFY_ARE_EQUAL(4, o[U("d")].as_integer()); - - o.as_object().erase(U("d")); - VERIFY_ARE_EQUAL(2, o.size()); - VERIFY_ARE_EQUAL(2, o[U("b")].as_integer()); - VERIFY_ARE_EQUAL(3, o[U("c")].as_integer()); - } - - TEST(erase_object_iter) - { - auto o = json::value::object(); - o[U("a")] = json::value(1); - o[U("b")] = json::value(2); - o[U("c")] = json::value(3); - o[U("d")] = json::value(4); - - auto iter = o.as_object().begin() + 1; - auto afterLoc = o.as_object().erase(iter); - VERIFY_ARE_EQUAL(3, o.size()); - VERIFY_ARE_EQUAL(3, afterLoc->second.as_integer()); - VERIFY_ARE_EQUAL(1, o[U("a")].as_integer()); - VERIFY_ARE_EQUAL(3, o[U("c")].as_integer()); - VERIFY_ARE_EQUAL(4, o[U("d")].as_integer()); - - iter = o.as_object().begin() + 2; - afterLoc = o.as_object().erase(iter); - VERIFY_ARE_EQUAL(2, o.size()); - VERIFY_ARE_EQUAL(o.as_object().end(), afterLoc); - VERIFY_ARE_EQUAL(1, o[U("a")].as_integer()); - VERIFY_ARE_EQUAL(3, o[U("c")].as_integer()); - } - - TEST(floating_number_serialize) - { - // This number will have the longest serializaton possible (lenght of the string): - // Sign, exponent, decimal comma, longest mantisa and exponent make so. - auto value = json::value(-3.123456789012345678901234567890E-123); - - // #digits + 2 to avoid loss + 1 for the sign + 1 for decimal point + 5 for exponent (e+xxx) - const auto len = std::numeric_limits<double>::digits10 + 9; - - // Check narrow string implementation - std::stringstream ss; - value.serialize(ss); - VERIFY_ARE_EQUAL(len, ss.str().length()); - -#ifdef _WIN32 - // Check wide string implementation - std::basic_stringstream<wchar_t> wss; - value.serialize(wss); - VERIFY_ARE_EQUAL(len, wss.str().length()); -#endif - } - -} // SUITE(to_as_and_operators_tests) - -} // namespace json_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/Resource.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/Resource.h @@ -1,17 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by header_test.rc -// - -#define IDS_APP_TITLE 103 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/header_test.rc b/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/header_test.rc Binary files differ. diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/header_test1.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/header_test1.cpp @@ -1,62 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests to include headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -// Include ATL headers before casablanca headers -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit - -#ifndef VC_EXTRALEAN -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#endif - -// These MFC headers are not code analysis clean. -#pragma warning(push) -#pragma warning(disable : 6387) -#include <afx.h> -#include <afxext.h> // MFC extensions -#include <afxwin.h> // MFC core and standard components -#ifndef _AFX_NO_OLE_SUPPORT -#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls -#endif -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include <afxcmn.h> // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT -#pragma warning(pop) - -#include <iostream> -// Windows Header Files: -#include <windows.h> - -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit - -#include "cpprest/http_client.h" -#include "unittestpp.h" -#include <atlbase.h> -#include <atlstr.h> - -namespace tests -{ -namespace functional -{ -namespace misc -{ -namespace atl_headers -{ -SUITE(header_test1) -{ - TEST(HeaderTest) { web::http::client::http_client client(U("http://www.cnn.com")); } - -} // SUITE(header_test1) - -} // namespace atl_headers -} // namespace misc -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/header_test2.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/misc/atl_headers/header_test2.cpp @@ -1,63 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests to include headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#include "cpprest/http_client.h" - -// Include ATL headers after casablanca headers -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit - -#ifndef VC_EXTRALEAN -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#endif - -// These MFC headers are not code analysis clean. -#pragma warning(push) -#pragma warning(disable : 6387) -#include <afx.h> -#include <afxext.h> // MFC extensions -#include <afxwin.h> // MFC core and standard components -#ifndef _AFX_NO_OLE_SUPPORT -#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls -#endif -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include <afxcmn.h> // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT -#pragma warning(pop) - -#include <iostream> -// Windows Header Files: -#include <windows.h> - -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit - -#include "unittestpp.h" -#include <atlbase.h> -#include <atlstr.h> - -namespace tests -{ -namespace functional -{ -namespace misc -{ -namespace atl_headers -{ -SUITE(header_test2) -{ - TEST(HeaderTest) { web::http::client::http_client client(U("http://www.cnn.com")); } - -} // SUITE(header_test2) - -} // namespace atl_headers -} // namespace misc -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/CMakeLists.txt @@ -1 +0,0 @@ -add_subdirectory(pplx_test) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/CMakeLists.txt @@ -1,9 +0,0 @@ -set(SOURCES - pplx_op_test.cpp - pplx_task_options.cpp - pplxtask_tests.cpp -) - -add_casablanca_test(pplx_test SOURCES) - -configure_pch(pplx_test stdafx.h stdafx.cpp) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/pplx_op_test.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/pplx_op_test.cpp @@ -1,361 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for PPLX operations. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -pplx::details::atomic_long s_flag; - -#if defined(_MSC_VER) - -class pplx_dflt_scheduler : public pplx::scheduler_interface -{ - struct _Scheduler_Param - { - pplx::TaskProc_t m_proc; - void* m_param; - - _Scheduler_Param(pplx::TaskProc_t proc, void* param) : m_proc(proc), m_param(param) {} - }; - - static void CALLBACK DefaultWorkCallbackTest(PTP_CALLBACK_INSTANCE, PVOID pContext, PTP_WORK) - { - auto schedulerParam = std::unique_ptr<_Scheduler_Param>(static_cast<_Scheduler_Param*>(pContext)); - - schedulerParam->m_proc(schedulerParam->m_param); - } - - virtual void schedule(pplx::TaskProc_t proc, void* param) - { - pplx::details::atomic_increment(s_flag); - auto schedulerParam = std::unique_ptr<_Scheduler_Param>(new _Scheduler_Param(proc, param)); - auto work = CreateThreadpoolWork(DefaultWorkCallbackTest, schedulerParam.get(), NULL); - - if (work == nullptr) - { - throw utility::details::create_system_error(GetLastError()); - } - - SubmitThreadpoolWork(work); - CloseThreadpoolWork(work); - schedulerParam.release(); - } -}; - -#else -class pplx_dflt_scheduler : public pplx::scheduler_interface -{ - std::unique_ptr<crossplat::threadpool> m_pool; - - virtual void schedule(pplx::TaskProc_t proc, void* param) - { - pplx::details::atomic_increment(s_flag); - m_pool->service().post([=]() -> void { proc(param); }); - } - -public: - pplx_dflt_scheduler() : m_pool(crossplat::threadpool::construct(4)) {} -}; -#endif - -namespace tests -{ -namespace functional -{ -namespace pplx_tests -{ -SUITE(pplx_op_tests) -{ - TEST(task_from_value) - { - auto val = pplx::task_from_result<int>(17); - - VERIFY_ARE_EQUAL(val.get(), 17); - } - - TEST(task_from_value_with_continuation) - { - auto val = pplx::task_from_result<int>(17); - - int v = 0; - - auto t = val.then([&](int x) { v = x; }); - t.wait(); - - VERIFY_ARE_EQUAL(v, 17); - } - - TEST(create_task) - { - auto val = pplx::create_task([]() { return 17; }); - - VERIFY_ARE_EQUAL(val.get(), 17); - } - - TEST(create_task_with_continuation) - { - auto val = pplx::create_task([]() { return 17; }); - - int v = 0; - - auto t = val.then([&](int x) { v = x; }); - t.wait(); - - VERIFY_ARE_EQUAL(v, 17); - } - - TEST(task_from_event) - { - pplx::task_completion_event<int> tce; - auto val = pplx::create_task(tce); - tce.set(17); - - VERIFY_ARE_EQUAL(val.get(), 17); - } - - TEST(task_from_event_with_continuation) - { - pplx::task_completion_event<int> tce; - auto val = pplx::create_task(tce); - - int v = 0; - - auto t = val.then([&](int x) { v = x; }); - - tce.set(17); - t.wait(); - - VERIFY_ARE_EQUAL(v, 17); - } - - TEST(task_from_event_is_done) - { - pplx::task_completion_event<long> tce; - auto val = pplx::create_task(tce); - - pplx::details::atomic_long v(0); - - auto t = val.then([&](long x) { pplx::details::atomic_exchange(v, x); }); - - // The task should not have started yet. - bool isDone = t.is_done(); - VERIFY_ARE_EQUAL(isDone, false); - - // Start the task - tce.set(17); - - // Wait for the lambda to finish running - while (!t.is_done()) - { - // Yield. - } - - // Verify that the lambda did run - VERIFY_ARE_EQUAL(v, 17); - - // Wait for the task. - t.wait(); - - VERIFY_ARE_EQUAL(v, 17); - } - - TEST(task_from_event_with_exception) - { - pplx::task_completion_event<long> tce; - auto val = pplx::create_task(tce); - - pplx::details::atomic_long v(0); - - auto t = val.then([&](long x) { pplx::details::atomic_exchange(v, x); }); - - // Start the task - tce.set_exception(pplx::invalid_operation()); - - // Wait for the lambda to finish running - while (!t.is_done()) - { - // Yield. - } - - // Verify that the lambda did run - VERIFY_ARE_EQUAL(v, 0); - - // Wait for the task. - try - { - t.wait(); - } - catch (pplx::invalid_operation) - { - } - catch (std::exception_ptr) - { - v = 1; - } - - VERIFY_ARE_EQUAL(v, 0); - } - - TEST(schedule_task_hold_then_release) - { - pplx::details::atomic_long flag(0); - - pplx::task<void> t1([&flag]() { - while (flag == 0) - ; - }); - - pplx::details::atomic_exchange(flag, 1L); - t1.wait(); - } - - // TFS # 521911 - TEST(schedule_two_tasks) - { - pplx_dflt_scheduler sched; - pplx::details::atomic_exchange(s_flag, 0L); - - auto nowork = []() {}; - - auto defaultTask = pplx::create_task(nowork); - defaultTask.wait(); - VERIFY_ARE_EQUAL(s_flag, 0); - - pplx::task_completion_event<void> tce; - auto t = pplx::create_task(tce, sched); - - // 2 continuations to be scheduled on the scheduler. - // Note that task "t" is not scheduled. - auto t1 = t.then(nowork).then(nowork); - - tce.set(); - t1.wait(); - - VERIFY_ARE_EQUAL(s_flag, 2); - } - - TEST(task_throws_exception) - { - pplx::extensibility::event_t ev; - bool caught = false; - - // Ensure that exceptions thrown from user lambda - // are indeed propagated and do not escape out of - // the task. - auto t1 = pplx::create_task([&ev]() { - ev.set(); - throw std::logic_error("Should not escape"); - }); - - auto t2 = t1.then([]() { VERIFY_IS_TRUE(false); }); - - // Ensure that we do not inline the work on this thread - ev.wait(); - - try - { - t2.wait(); - } - catch (std::exception&) - { - caught = true; - } - - VERIFY_IS_TRUE(caught); - } - - pplx::task<int> make_unwrapped_task() - { - pplx::task<int> t1([]() { return 10; }); - - return pplx::task<int>([t1]() { return t1; }); - } - - TEST(unwrap_task) - { - pplx::task<int> t = make_unwrapped_task(); - int n = t.get(); - VERIFY_ARE_EQUAL(n, 10); - } - - TEST(task_from_event_with_tb_continuation) - { - volatile long flag = 0; - - pplx::task_completion_event<int> tce; - auto val = pplx::create_task(tce).then([=, &flag](pplx::task<int> op) -> short { - flag = 1; - return (short)op.get(); - }); - - tce.set(17); - - VERIFY_ARE_EQUAL(val.get(), 17); - VERIFY_ARE_EQUAL(flag, 1); - } - - class fcc_370010 - { - public: - fcc_370010(pplx::task_completion_event<bool> op) : m_op(op) {} - - virtual void on_closed(bool result) - { - m_op.set(result); -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" -#endif - delete this; -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - } - - private: - pplx::task_completion_event<bool> m_op; - }; - - TEST(BugRepro370010) - { - auto result_tce = pplx::task_completion_event<bool>(); - - auto f = new fcc_370010(result_tce); - - pplx::task<void> dummy([f]() { f->on_closed(true); }); - - auto result = pplx::task<bool>(result_tce); - - VERIFY_IS_TRUE(result.get()); - } - - TEST(event_set_reset_timeout, "Ignore", "785846") - { - pplx::extensibility::event_t ev; - - ev.set(); - - // Wait should succeed as the event was set above - VERIFY_IS_TRUE(ev.wait(0) == 0); - - // wait should succeed as this is manual reset - VERIFY_IS_TRUE(ev.wait(0) == 0); - - ev.reset(); - - // wait should fail as the event is reset (not set) - VERIFY_IS_TRUE(ev.wait(0) == pplx::extensibility::event_t::timeout_infinite); - } - -} // SUITE(pplx_op_tests) - -} // namespace pplx_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/pplx_task_options.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/pplx_task_options.cpp @@ -1,447 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for PPLX task options. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) && !CPPREST_FORCE_PPLX -// Dev12 doesn't have an in-box ambient scheduler, since all tasks execute on ConcRT. -// Therefore, we need to provide one. A scheduler that directly executes a functor given to it is -// a simple and valid implementation of a PPL scheduler -class direct_executor : public pplx::scheduler_interface -{ -public: - virtual void schedule(concurrency::TaskProc_t proc, _In_ void* param) { proc(param); } -}; - -static std::shared_ptr<pplx::scheduler_interface> g_executor; -std::shared_ptr<pplx::scheduler_interface> __cdecl get_scheduler() -{ - if (!g_executor) - { - g_executor = std::make_shared<direct_executor>(); - } - - return g_executor; -} -#else -std::shared_ptr<pplx::scheduler_interface> __cdecl get_scheduler() { return pplx::get_ambient_scheduler(); } -#endif - -class TaskOptionsTestScheduler : public pplx::scheduler_interface -{ -public: - TaskOptionsTestScheduler() : m_numTasks(0), m_scheduler(get_scheduler()) {} - - virtual void schedule(pplx::TaskProc_t proc, void* param) - { - pplx::details::atomic_increment(m_numTasks); - m_scheduler->schedule(proc, param); - } - - long get_num_tasks() { return m_numTasks; } - -private: - pplx::details::atomic_long m_numTasks; - pplx::scheduler_ptr m_scheduler; - - TaskOptionsTestScheduler(const TaskOptionsTestScheduler&); - TaskOptionsTestScheduler& operator=(const TaskOptionsTestScheduler&); -}; - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4512) -#endif -class CheckLifetimeScheduler : public pplx::scheduler_interface -{ -public: - CheckLifetimeScheduler(pplx::extensibility::event_t& ev) : m_event(ev), m_numTasks(0) {} - - ~CheckLifetimeScheduler() { m_event.set(); } - - virtual void schedule(pplx::TaskProc_t proc, void* param) - { - pplx::details::atomic_increment(m_numTasks); - get_scheduler()->schedule(proc, param); - } - - long get_num_tasks() { return m_numTasks; } - - pplx::extensibility::event_t& m_event; - pplx::details::atomic_long m_numTasks; -}; -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -namespace tests -{ -namespace functional -{ -namespace PPLX -{ -SUITE(pplx_task_options_tests) -{ - TEST(voidtask_schedoption_test) - { - TaskOptionsTestScheduler sched; - long n = 0; - - auto t1 = pplx::create_task([&n]() { n++; }, sched); // run on sched - t1.wait(); - - VERIFY_ARE_EQUAL(sched.get_num_tasks(), n); - } - - TEST(task_schedoption_test) - { - TaskOptionsTestScheduler sched; - long n = 0; - - auto t1 = pplx::create_task( - [&n]() -> int { - n++; - return 1; - }, - sched); // run on sched - t1.wait(); - - VERIFY_ARE_EQUAL(sched.get_num_tasks(), n); - } - - TEST(then_nooptions_test) - { - TaskOptionsTestScheduler sched; - long n = 0; - - auto t1 = pplx::create_task([&n]() { n++; }, sched); - t1.then([&n]() { n++; }) // inherit sched - .then([&n]() { n++; }) - .wait(); - - VERIFY_ARE_EQUAL(sched.get_num_tasks(), n); - } - - TEST(then_multiple_schedulers_test1) - { - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - auto emptyFunc = []() {}; - - auto t1 = pplx::create_task(emptyFunc, sched1); // sched1 - t1.then(emptyFunc, sched2).wait(); // sched2 - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), 1); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(then_multiple_schedulers_test2) - { - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - auto emptyFunc = []() {}; - - auto t1 = pplx::create_task(emptyFunc, sched1); - t1.then(emptyFunc, sched2) - .then(emptyFunc) // inherit sched2 - .wait(); - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), 1); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 2); - } - - TEST(opand_nooptions_test) - { - TaskOptionsTestScheduler sched; - - auto t1 = pplx::create_task([]() {}, sched); - auto t2 = pplx::create_task([]() {}, sched); - - auto t3 = t1 && t2; // Does not run on the scheduler - it should run inline - t3.then([]() {}, sched).wait(); // run on sched - - VERIFY_ARE_EQUAL(sched.get_num_tasks(), 3); - } - - TEST(whenall_nooptions_test) - { - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - std::vector<pplx::task<void>> taskVect; - const int n = 10; - for (int i = 0; i < n; i++) - { - taskVect.push_back(pplx::create_task([]() {}, sched1)); - } - - auto t3 = - pplx::when_all(begin(taskVect), end(taskVect)); // Does not run on the scheduler - it should run inline - t3.then([]() {}, sched2).wait(); // run on sched2 - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), n); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(whenall_options_test1) - { - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - std::vector<pplx::task<void>> taskVect; - const int n = 10; - for (int i = 0; i < n; i++) - { - taskVect.push_back(pplx::create_task([]() {}, sched1)); - } - - auto t3 = pplx::when_all( - begin(taskVect), end(taskVect), sched2); // Does not run on the scheduler - it should run inline - t3.then([]() {}).wait(); // run on sched2 (inherits from the when_all task - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), n); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(whenall_options_test2) - { - // Same as the above test but use task<int> to instatinate those templates - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - std::vector<pplx::task<int>> taskVect; - const int n = 10; - for (int i = 0; i < n; i++) - { - taskVect.push_back(pplx::create_task([i]() -> int { return i; }, sched1)); - } - - auto t3 = pplx::when_all( - begin(taskVect), end(taskVect), sched2); // Does not run on the scheduler - it should run inline - t3.then([](std::vector<int>) {}).wait(); // run on sched2 (inherits from the when_all task - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), n); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(whenall_options_test3) - { - // Same as the above test but use multiple when_all - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - std::vector<pplx::task<int>> taskVect; - const int n = 10; - for (int i = 0; i < n; i++) - { - taskVect.push_back(pplx::create_task([i]() -> int { return i; }, sched1)); - } - - auto t2 = pplx::create_task([]() -> int { return 0; }, sched1); - - auto t3 = pplx::when_all( - begin(taskVect), end(taskVect), sched2); // Does not run on the scheduler - it should run inline - - auto t4 = t2 && t3; - t4.then([](std::vector<int>) {}) - .wait(); // run on default scheduler as the operator && breaks the chain of inheritance - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), n + 1); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 0); - } - - TEST(opor_nooptions_test) - { - TaskOptionsTestScheduler sched; - - auto t1 = pplx::create_task([]() {}, sched); - auto t2 = pplx::create_task([]() {}, sched); - - auto t3 = t1 || t2; // Runs inline - t3.then([]() {}, sched).wait(); - - VERIFY_ARE_EQUAL(sched.get_num_tasks(), 3); - } - - TEST(whenany_nooptions_test) - { - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - std::vector<pplx::task<void>> taskVect; - const int n = 10; - for (int i = 0; i < n; i++) - { - taskVect.push_back(pplx::create_task([]() {}, sched1)); - } - - auto t3 = - pplx::when_any(begin(taskVect), end(taskVect)); // Does not run on the scheduler - it should run inline - t3.then([](size_t) {}, sched2).wait(); // run on sched2 - - // Do a whenall to wait for all the tasks - pplx::when_all(begin(taskVect), end(taskVect)).wait(); - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), n); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(whenany_options_test1) - { - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - std::vector<pplx::task<void>> taskVect; - const int n = 10; - for (int i = 0; i < n; i++) - { - taskVect.push_back(pplx::create_task([]() {}, sched1)); - } - - auto t3 = pplx::when_any( - begin(taskVect), end(taskVect), sched2); // Does not run on the scheduler - it should run inline - t3.then([](size_t) {}).wait(); // run on sched2 (inherits from the when_all task - - // Do a whenall to wait for all the tasks - pplx::when_all(begin(taskVect), end(taskVect)).wait(); - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), n); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(whenany_options_test2) - { - // Same as whenany_options_test1 except that we instantiate a different set of template functions - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - std::vector<pplx::task<int>> taskVect; - const int n = 10; - for (int i = 0; i < n; i++) - { - taskVect.push_back(pplx::create_task([]() -> int { return 0; }, sched1)); - } - - auto t3 = pplx::when_any( - begin(taskVect), end(taskVect), sched2); // Does not run on the scheduler - it should run inline - t3.then([](std::pair<int, size_t>) {}).wait(); // run on sched2 (inherits from the when_all task - - // Do a whenall to wait for all the tasks - pplx::when_all(begin(taskVect), end(taskVect)).wait(); - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), n); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(tce_nooptions_test) - { - TaskOptionsTestScheduler sched; - TaskOptionsTestScheduler sched1; - TaskOptionsTestScheduler sched2; - - pplx::task_completion_event<void> tce; - auto t1 = pplx::create_task(tce, sched1); - auto t2 = pplx::create_task(tce, sched2); - - tce.set(); - t1.wait(); - t2.wait(); - - // There is nothing to execute - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), 0); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 0); - - auto emptyFunc = []() {}; - - auto t3 = t1.then(emptyFunc); - auto t4 = t2.then(emptyFunc); - - t3.wait(); - t4.wait(); - - VERIFY_ARE_EQUAL(sched1.get_num_tasks(), 1); - VERIFY_ARE_EQUAL(sched2.get_num_tasks(), 1); - } - - TEST(fromresult_options_test) - { - TaskOptionsTestScheduler sched; - - int value = 10; - auto t1 = pplx::task_from_result(value); - t1.wait(); - VERIFY_ARE_EQUAL(sched.get_num_tasks(), 0); - - t1.then([](int i) -> int { return i; }, sched).wait(); - VERIFY_ARE_EQUAL(sched.get_num_tasks(), 1); - } - - TEST(scheduler_lifetime) - { - pplx::extensibility::event_t ev; - { - auto sched = std::make_shared<CheckLifetimeScheduler>(ev); - - pplx::create_task([]() {}, sched) // runs on sched (1) - .then([]() {}) // runs on sched (2) - .wait(); - - VERIFY_ARE_EQUAL(sched->get_num_tasks(), 2); - } - - ev.wait(); - } - - TEST(scheduler_lifetime_mixed) - { - pplx::extensibility::event_t ev; - auto t = pplx::create_task([]() {}); // use default scheduler - { - auto sched = std::make_shared<CheckLifetimeScheduler>(ev); - - t.then([]() {}, sched) // (1) - .then([]() {}) // (2) - .wait(); - - VERIFY_ARE_EQUAL(sched->get_num_tasks(), 2); - } - - ev.wait(); - } - - TEST(scheduler_lifetime_nested) - { - pplx::extensibility::event_t ev; - auto t = pplx::create_task([]() {}); // use default scheduler - { - auto sched = std::make_shared<CheckLifetimeScheduler>(ev); - - t.then([]() {}, sched) // custom scheduler (1) - .then( - [sched]() { - // We are on the default scheduler - pplx::create_task([]() {}, sched); // run on custom scheduler (2) - }, - t.scheduler()) - .wait(); - - VERIFY_ARE_EQUAL(sched->get_num_tasks(), 2); - } - - ev.wait(); - } - -} // SUITE(pplx_task_options_tests) -} // namespace PPLX -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/pplxtask_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/pplxtask_tests.cpp @@ -1,1898 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for PPLX operations - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -using namespace ::pplx; -using namespace ::tests::common::utilities; - -namespace tests -{ -namespace functional -{ -namespace PPLX -{ -static void IsTrue(bool condition, const wchar_t*, ...) { VERIFY_IS_TRUE(condition); } - -static void IsFalse(bool condition, ...) { VERIFY_IS_TRUE(condition == false); } - -static void LogFailure(const wchar_t* msg, ...) -{ - wprintf(L"%s", msg); - VERIFY_IS_TRUE(false); -} - -namespace helpers -{ -static int FibSerial(int n) -{ - if (n < 2) return n; - - return FibSerial(n - 1) + FibSerial(n - 2); -} - -static void DoRandomParallelWork() -{ - int param = (rand() % 8) + 20; - // Calculate fib in serial - volatile int val = FibSerial(param); - val; -} - -template<typename _EX, typename _T> -bool VerifyException(task<_T>& task) -{ - bool gotException = true; - bool wrongException = false; - - try - { - task.get(); - gotException = false; - } - catch (const _EX&) - { - } - catch (...) - { - wrongException = true; - } - - return (gotException && !wrongException); -} - -template<typename _T> -bool VerifyNoException(task<_T>& task) -{ - try - { - task.get(); - } - catch (...) - { - return false; - } - return true; -} - -template<typename _T> -bool VerifyCanceled(task<_T>& task) -{ - try - { - task.get(); - } - catch (task_canceled&) - { - return true; - } - catch (...) - { - return false; - } - return false; -} - -template<typename _T> -void ObserveException(task<_T>& task) -{ - try - { - task.get(); - } - catch (...) - { - } -} - -template<typename Iter> -void ObserveAllExceptions(Iter begin, Iter end) -{ - typedef typename std::iterator_traits<Iter>::value_type::result_type TaskType; - for (auto it = begin; it != end; ++it) - { - ObserveException(*it); - } -} -} // namespace helpers - -SUITE(pplxtask_tests) -{ - TEST(TestCancellationTokenRegression) - { - for (int i = 0; i < 500; i++) - { - task_completion_event<void> tce; - task<void> starter(tce); - - cancellation_token_source ct; - - task<int> t1 = starter.then([]() -> int { return 47; }, ct.get_token()); - - task<int> t2([]() -> int { return 82; }); - - task<int> t3([]() -> int { return 147; }); - - auto t4 = (t1 && t2 && t3).then([=](std::vector<int> vec) -> int { return vec[0] + vec[1] + vec[3]; }); - - ct.cancel(); - - tce.set(); - // this should not hang - task_status t4Status = t4.wait(); - IsTrue(t4Status == canceled, - L"operator && did not properly cancel. Expected: %d, Actual: %d", - canceled, - t4Status); - } - } - TEST(TestTasks_basic) - { - { - task<int> t1([]() -> int { return 47; }); - - auto t2 = t1.then([=](int i) -> float { - IsTrue(i == 47, - L"Continuation did not recieve the correct value from ancestor. Expected: 47, Actual: %d", - i); - return (float)i / 2; - }); - - float t2Result = t2.get(); - IsTrue(t2Result == 23.5, - L"Continuation task did not produce the correct result. Expected: 23.5, Actual: %f", - t2Result); - - task_status t2Status = t2.wait(); - IsTrue(t2Status == completed, - L"Continuation task was not in completed state. Expected: %d, Actual: %d", - completed, - t2Status); - - task<int> t3([]() -> int { return 0; }); - - IsTrue(t1 == t1, L"task operator== resulted false on equivalent tasks"); - IsFalse(t1 != t1, L"task operator!= resulted true on equivalent tasks"); - IsFalse(t1 == t3, L"task operator== resulted true on different tasks"); - IsTrue(t1 != t3, L"task operator!= resulted false on different tasks"); - - t3.wait(); - } - } - - TEST(TestTasks_default_construction) - { - // Test that default constructed task<T> properly throw exceptions - { - task<int> t1; - - try - { - t1.wait(); - LogFailure(L"t1.wait() should have thrown an exception"); - } - catch (invalid_operation) - { - } - - try - { - t1.get(); - LogFailure(L"t1.get() should have thrown an exception"); - } - catch (invalid_operation) - { - } - - try - { - t1.then([](int i) { return i; }); - - LogFailure(L"t1.then() should have thrown an exception"); - } - catch (invalid_operation) - { - } - } - } - - TEST(TestTasks_void_tasks) - { - // Test void tasks - { - int value = 0; - task<void> t1([&value]() { value = 147; }); - - auto t2 = t1.then([&]() { - IsTrue(value == 147, - L"void continuation did not recieve the correct value from ancestor. Expected: 147, Actual: %d", - value); - value++; - }); - - IsTrue(t2.wait() == completed, L"void task was not in completed state."); - - IsTrue(value == 148, L"void tasks did not properly execute. Expected: 148, Actual: %d", value); - - task<void> t3([]() {}); - - IsTrue(t1 == t1, L"task operator== resulted false on equivalent tasks"); - IsFalse(t1 != t1, L"task operator!= resulted true on equivalent tasks"); - IsFalse(t1 == t3, L"task operator== resulted true on different tasks"); - IsTrue(t1 != t3, L"task operator!= resulted false on different tasks"); - } - } - - TEST(TestTasks_void_tasks_default_construction) - { - // Test that default constructed task<void> properly throw exceptions - { - task<void> t1; - - try - { - t1.wait(); - LogFailure(L"t1.wait() should have thrown an exception"); - } - catch (invalid_operation) - { - } - - try - { - t1.get(); - LogFailure(L"t1.get() should have thrown an exception"); - } - catch (invalid_operation) - { - } - - try - { - t1.then([]() {}); - LogFailure(L"t1.contiue_with() should have thrown an exception"); - } - catch (invalid_operation) - { - } - } - } - - TEST(TestTasks_movable_then) - { -#ifndef _MSC_VER - // create movable only type - struct A - { - A() = default; - A(A&&) = default; - A& operator=(A&&) = default; - - // explicitly delete copy functions - A(const A&) = delete; - A& operator=(const A&) = delete; - - char operator()(int) { return 'c'; } - } a; - - task<int> task = create_task([] { return 2; }); - auto f = task.then(std::move(a)); - - IsTrue(f.get() == 'c', L".then should be able to work with movable functors"); -#endif // _MSC_VER - } - - TEST(TestTasks_constant_this) - { -#ifdef _MSC_VER -#if _MSC_VER < 1700 - // Dev10 compiler gives an error => .then(func) where func = int! -#else - { - // Test constant 'this' pointer in member functions then(), wait() and get(), - // so that they can be used in Lambda. - task<int> t1([]() -> int { return 0; }); - - auto func = [t1]() -> int { - t1.then([](int last) -> int { return last; }); - t1.wait(); - return t1.get(); - }; - - IsTrue(func() == 0, L"Tasks should be able to used inside a Lambda."); - } -#endif // _MSC_VER < 1700 -#endif // _MSC_VER - } - - TEST(TestTasks_fire_and_forget) - { - // Test Fire-and-forget behavior - extensibility::event_t evt; - bool flag = false; - { - task<int> t1([&flag, &evt]() -> int { - flag = true; - evt.set(); - return 0; - }); - } - - evt.wait(); - IsTrue(flag == true, L"Fire-and-forget task did not properly execute."); - } - TEST(TestTasks_create_task) - { - // test create task - task<int> t1 = create_task([]() -> int { return 4; }); - IsTrue(t1.get() == 4, L"create_task for simple task did not properly execute."); - IsTrue(create_task(t1).get() == 4, L"create_task from a task task did not properly execute."); - task<void> t2 = create_task([]() {}); - task<int> t3 = create_task([]() -> task<int> { return create_task([]() -> int { return 4; }); }); - IsTrue(t3.get() == 4, L"create_task for task unwrapping did not properly execute."); - } - - TEST(TestTaskCompletionEvents_basic) - { - task_completion_event<int> tce; - task<int> completion(tce); - auto completion2 = create_task(tce); - - task<void> setEvent([=]() { tce.set(50); }); - - int result = completion.get(); - IsTrue(result == 50, L"Task Completion Event did not get the right result. Expected: 50, Actual: %d", result); - IsTrue(completion2.get() == 50, - L"create_task didn't construct correct task for task_completion_event, Expected: 50, Actual: %d", - result); - } - - TEST(TestTaskCompletionEvents_basic2) - { - task_completion_event<void> tce; - task<void> completion(tce); - auto completion2 = create_task(tce); - - task<void> setEvent([=]() { tce.set(); }); - - // this should not hang, because of the set of tce - completion.wait(); - completion2.wait(); - } - - TEST(TestTaskCompletionEvents_set_exception_basic) - { - task_completion_event<void> tce; - task<void> t(tce); - tce.set_exception(42); - - t.then([=](task<void> p) { - try - { - p.get(); - IsTrue(false, L"Exception not propagated to task t when calling set_exception."); - } - catch (int n) - { - IsTrue(n == 42, L"%ws:%u:bad exception value", __FILE__, __LINE__); - } - }) - .wait(); - } - - TEST(TestTaskCompletionEvents_set_exception_multiple) - { - task_completion_event<void> tce; - task<void> t(tce); - tce.set_exception(42); - - t.then([=](task<void> p) { - try - { - p.get(); - IsTrue(false, L"Exception not propagated to task t's first continuation when calling set_exception."); - } - catch (int n) - { - IsTrue(n == 42, L"%ws:%u:bad exception value", __FILE__, __LINE__); - } - }) - .wait(); - - t.then([=](task<void> p) { - try - { - p.get(); - IsTrue(false, L"Exception not propagated to task t's second continuation when calling set_exception."); - } - catch (int n) - { - IsTrue(n == 42, L"%ws:%u:bad exception value", __FILE__, __LINE__); - } - }) - .wait(); - } - - TEST(TestTaskCompletionEvents_set_exception_struct) - { -#if defined(_MSC_VER) && _MSC_VER < 1700 - // The Dev10 compiler hits an ICE with this code -#else - struct s - { - }; - - task_completion_event<void> tce; - task<void> t(tce); - tce.set_exception(s()); - t.then([=](task<void> p) { - try - { - p.get(); - IsTrue(false, L"Exception not caught."); - } - catch (s) - { - // Do nothing - } - catch (...) - { - IsTrue(false, L"%ws:%u:not the right exception", __FILE__, __LINE__); - } - }) - .wait(); -#endif // _MSC_VER < 1700 - } - - TEST(TestTaskCompletionEvents_multiple_tasks) - { - task_completion_event<void> tce; - task<void> t1(tce); - task<void> t2(tce); - tce.set_exception(1); - - t1.then([=](task<void> p) { - try - { - p.get(); - IsTrue(false, L"An exception was not thrown when calling t1.get(). An exception was expected."); - } - catch (int ex) - { - IsTrue(ex == 1, L"%ws:%u:wrong exception value", __FILE__, __LINE__); - } - catch (...) - { - IsTrue(false, L"%ws:%u:not the right exception", __FILE__, __LINE__); - } - }); - - t2.then([=](task<void> p) { - try - { - p.get(); - IsTrue(false, L"An exception was not thrown when calling t2.get(). An exception was expected."); - } - catch (int ex) - { - IsTrue(ex == 1, L"%ws:%u:wrong exception value", __FILE__, __LINE__); - } - catch (...) - { - IsTrue(false, L"%ws:%u:not the right exception", __FILE__, __LINE__); - } - }); - } - - TEST(TestTaskCompletionEvents_set_exception_after_set) - { - task_completion_event<int> tce; - task<int> t(tce); - tce.set(1); - auto result = tce.set_exception(std::current_exception()); - IsFalse(result, L"set_exception must return false, but did not"); - t.then([=](task<int> p) { - try - { - int n = p.get(); - IsTrue(n == 1, L"Value not properly propagated to continuation"); - } - catch (...) - { - IsTrue(false, L"An exception was unexpectedly thrown in the continuation task"); - } - }) - .wait(); - } - - TEST(TestTaskCompletionEvents_set_exception_after_set2) - { - task_completion_event<int> tce; - task<int> t(tce); - tce.set_exception(1); - auto result = tce.set_exception(2); - IsFalse(result, L"set_exception must return false, but did not"); - t.then([=](task<int> p) { - try - { - p.get(); - IsTrue(false, L"%ws:%u:expected exception not thrown", __FILE__, __LINE__); - } - catch (int n) - { - IsTrue(n == 1, L"%ws:%u:unexpected exception payload", __FILE__, __LINE__); - } - }) - .wait(); - } - - TEST(TestTaskCompletionEvents_set_after_set_exception) - { - task_completion_event<int> tce; - task<int> t(tce); - tce.set_exception(42); - tce.set(1); // should be no-op - t.then([=](task<int> p) { - try - { - p.get(); - IsTrue(false, L"Exception should have been thrown here."); - } - catch (int e) - { - IsTrue(e == 42, L"%ws:%u:not the right exception value", __FILE__, __LINE__); - } - catch (...) - { - IsTrue(false, L"%ws:%u:not the right exception", __FILE__, __LINE__); - } - }) - .wait(); - } - - TEST(TestTaskOperators_and_or) - { - task<int> t1([]() -> int { return 47; }); - - task<int> t2([]() -> int { return 82; }); - - auto t3 = (t1 && t2).then([=](std::vector<int> vec) -> int { - IsTrue(vec.size() == 2, - L"operator&& did not produce a correct vector size. Expected: 2, Actual: %d", - vec.size()); - IsTrue(vec[0] == 47, L"operator&& did not produce a correct vector[0]. Expected: 47, Actual: %d", vec[0]); - IsTrue(vec[1] == 82, L"operator&& did not produce a correct vector[1]. Expected: 82, Actual: %d", vec[1]); - return vec[0] + vec[1]; - }); - - int t3Result = t3.get(); - IsTrue(t3Result == 129, - L"operator&& task did not produce the correct result. Expected: 129, Actual: %d", - t3Result); - } - - TEST(TestTaskOperators_and_or2) - { - task<int> t1([]() -> int { return 47; }); - - task<int> t2([]() -> int { return 82; }); - - task<int> t3([]() -> int { return 147; }); - - task<int> t4([]() -> int { return 192; }); - - auto t5 = (t1 && t2 && t3 && t4).then([=](std::vector<int> vec) -> int { - IsTrue(vec.size() == 4, - L"operator&& did not produce a correct vector size. Expected: 4, Actual: %d", - vec.size()); - IsTrue(vec[0] == 47, L"operator&& did not produce a correct vector[0]. Expected: 47, Actual: %d", vec[0]); - IsTrue(vec[1] == 82, L"operator&& did not produce a correct vector[1]. Expected: 82, Actual: %d", vec[1]); - IsTrue(vec[2] == 147, L"operator&& did not produce a correct vector[2]. Expected: 147, Actual: %d", vec[2]); - IsTrue(vec[3] == 192, L"operator&& did not produce a correct vector[3]. Expected: 192, Actual: %d", vec[3]); - int count = 0; - for (unsigned i = 0; i < vec.size(); i++) - count += vec[i]; - return count; - }); - - int t5Result = t5.get(); - IsTrue(t5Result == 468, - L"operator&& task did not produce the correct result. Expected: 468, Actual: %d", - t5Result); - } - - TEST(TestTaskOperators_and_or3) - { - task<int> t1([]() -> int { return 47; }); - - task<int> t2([]() -> int { return 82; }); - - task<int> t3([]() -> int { return 147; }); - - task<int> t4([]() -> int { return 192; }); - - auto t5 = ((t1 && t2) && (t3 && t4)).then([=](std::vector<int> vec) -> int { - IsTrue(vec.size() == 4, - L"operator&& did not produce a correct vector size. Expected: 4, Actual: %d", - vec.size()); - IsTrue(vec[0] == 47, L"operator&& did not produce a correct vector[0]. Expected: 47, Actual: %d", vec[0]); - IsTrue(vec[1] == 82, L"operator&& did not produce a correct vector[1]. Expected: 82, Actual: %d", vec[1]); - IsTrue(vec[2] == 147, L"operator&& did not produce a correct vector[2]. Expected: 147, Actual: %d", vec[2]); - IsTrue(vec[3] == 192, L"operator&& did not produce a correct vector[3]. Expected: 192, Actual: %d", vec[3]); - int count = 0; - for (unsigned i = 0; i < vec.size(); i++) - count += vec[i]; - return count; - }); - - int t5Result = t5.get(); - IsTrue(t5Result == 468, - L"operator&& task did not produce the correct result. Expected: 468, Actual: %d", - t5Result); - } - - TEST(TestTaskOperators_and_or4) - { - extensibility::event_t evt; - - task<int> t1([&evt]() -> int { - evt.wait(); - return 47; - }); - - task<int> t2([]() -> int { return 82; }); - - auto t3 = (t1 || t2).then([=](int p) -> int { - IsTrue(p == 82, L"operator|| did not get the right result. Expected: 82, Actual: %d", p); - return p; - }); - - t3.wait(); - - evt.set(); - t1.wait(); - } - - TEST(TestTaskOperators_and_or5) - { - extensibility::event_t evt; - - task<int> t1([&evt]() -> int { - evt.wait(); - return 47; - }); - - task<int> t2([&evt]() -> int { - evt.wait(); - return 82; - }); - - task<int> t3([]() -> int { return 147; }); - - task<int> t4([&evt]() -> int { - evt.wait(); - return 192; - }); - - auto t5 = (t1 || t2 || t3 || t4).then([=](int result) -> int { - IsTrue(result == 147, L"operator|| did not produce a correct result. Expected: 147, Actual: %d", result); - return result; - }); - - t5.wait(); - - evt.set(); - t1.wait(); - t2.wait(); - t4.wait(); - } - - TEST(TestTaskOperators_and_or_sequence) - { - // testing ( t1 && t2 ) || t3, operator&& finishes first - extensibility::event_t evt; - - task<int> t1([]() -> int { return 47; }); - - task<int> t2([]() -> int { return 82; }); - - task<int> t3([&evt]() -> int { - evt.wait(); - return 147; - }); - - auto t4 = ((t1 && t2) || t3).then([=](std::vector<int> vec) -> int { - IsTrue(vec.size() == 2, - L"(t1 && t2) || t3 did not produce a correct vector size. Expected: 2, Actual: %d", - vec.size()); - IsTrue(vec[0] == 47, - L"(t1 && t2) || t3 did not produce a correct vector[0]. Expected: 47, Actual: %d", - vec[0]); - IsTrue(vec[1] == 82, - L"(t1 && t2) || t3 did not produce a correct vector[1]. Expected: 82, Actual: %d", - vec[1]); - return vec[0] + vec[1]; - }); - - int t4Result = t4.get(); - IsTrue(t4.get() == 129, - L"(t1 && t2) || t3 task did not produce the correct result. Expected: 129, Actual: %d", - t4Result); - - evt.set(); - t3.wait(); - } - - TEST(TestTaskOperators_and_or_sequence2) - { - // testing ( t1 && t2 ) || t3, operator|| finishes first - extensibility::event_t evt; - - task<int> t1([&evt]() -> int { - evt.wait(); - return 47; - }); - - task<int> t2([&evt]() -> int { - evt.wait(); - return 82; - }); - - task<int> t3([]() -> int { return 147; }); - - auto t4 = ((t1 && t2) || t3).then([=](std::vector<int> vec) -> int { - IsTrue(vec.size() == 1, - L"(t1 && t2) || t3 did not produce a correct vector size. Expected: 1, Actual: %d", - vec.size()); - IsTrue(vec[0] == 147, - L"(t1 && t2) || t3 did not produce a correct vector[0]. Expected: 147, Actual: %d", - vec[0]); - return vec[0]; - }); - - int t4Result = t4.get(); - IsTrue(t4.get() == 147, - L"(t1 && t2) || t3 task did not produce the correct result. Expected: 147, Actual: %d", - t4Result); - - evt.set(); - t1.wait(); - t2.wait(); - } - - TEST(TestTaskOperators_and_or_sequence3) - { - // testing t1 && (t2 || t3) - extensibility::event_t evt; - - task<int> t1([]() -> int { return 47; }); - - task<int> t2([&evt]() -> int { - evt.wait(); - return 82; - }); - - task<int> t3([]() -> int { return 147; }); - - auto t4 = (t1 && (t2 || t3)).then([=](std::vector<int> vec) -> int { - IsTrue(vec.size() == 2, - L"t1 && (t2 || t3) did not produce a correct vector size. Expected: 2, Actual: %d", - vec.size()); - IsTrue(vec[0] == 47, - L"t1 && (t2 || t3) did not produce a correct vector[0]. Expected: 47, Actual: %d", - vec[0]); - IsTrue(vec[1] == 147, - L"t1 && (t2 || t3) did not produce a correct vector[1]. Expected: 147, Actual: %d", - vec[1]); - return vec[0] + vec[1]; - }); - - int t4Result = t4.get(); - IsTrue(t4.get() == 194, - L"t1 && (t2 || t3) task did not produce the correct result. Expected: 194 Actual: %d", - t4Result); - - evt.set(); - t2.wait(); - } - - TEST(TestTaskOperators_cancellation) - { - task_completion_event<void> tce; - task<void> starter(tce); - - cancellation_token_source ct; - - task<int> t1 = starter.then([]() -> int { return 47; }, ct.get_token()); - - task<int> t2([]() -> int { return 82; }); - - task<int> t3([]() -> int { return 147; }); - - auto t4 = (t1 && t2 && t3).then([=](std::vector<int> vec) -> int { return vec[0] + vec[1] + vec[3]; }); - - ct.cancel(); - - tce.set(); - // this should not hang - task_status t4Status = t4.wait(); - IsTrue( - t4Status == canceled, L"operator && did not properly cancel. Expected: %d, Actual: %d", canceled, t4Status); - } - - TEST(TestTaskOperators_cancellation_and) - { - task_completion_event<void> tce; - task<void> starter(tce); - - cancellation_token_source ct; - - task<void> t1 = starter.then([]() -> void {}, ct.get_token()); - - task<void> t2([]() -> void {}); - - task<void> t3([]() -> void {}); - - auto t4 = (t1 && t2 && t3).then([=]() {}); - - ct.cancel(); - - tce.set(); - // this should not hang - task_status t4Status = t4.wait(); - IsTrue( - t4Status == canceled, L"operator && did not properly cancel. Expected: %d, Actual: %d", canceled, t4Status); - } - - TEST(TestTaskOperators_cancellation_or) - { - task_completion_event<void> tce; - task<void> starter(tce); - - cancellation_token_source ct1; - cancellation_token_source ct2; - cancellation_token_source ct3; - - task<int> t1 = starter.then([]() -> int { return 47; }, ct1.get_token()); - - task<int> t2 = starter.then([]() -> int { return 82; }, ct2.get_token()); - - task<int> t3 = starter.then([]() -> int { return 147; }, ct3.get_token()); - - auto t4 = (t1 || t2 || t3).then([=](int result) -> int { return result; }); - - ct1.cancel(); - ct2.cancel(); - ct3.cancel(); - - tce.set(); - // this should not hang - task_status t4Status = t4.wait(); - IsTrue( - t4Status == canceled, L"operator || did not properly cancel. Expected: %d, Actual: %d", canceled, t4Status); - } - TEST(TestTaskOperators_cancellation_or2) - { - task_completion_event<void> tce; - task<void> starter(tce); - - cancellation_token_source ct1; - cancellation_token_source ct2; - cancellation_token_source ct3; - - task<void> t1 = starter.then([]() -> void {}, ct1.get_token()); - - task<void> t2 = starter.then([]() -> void {}, ct2.get_token()); - - task<void> t3 = starter.then([]() -> void {}, ct3.get_token()); - - auto t4 = (t1 || t2 || t3).then([=]() {}); - - ct1.cancel(); - ct2.cancel(); - ct3.cancel(); - - tce.set(); - // this should not hang - task_status t4Status = t4.wait(); - IsTrue( - t4Status == canceled, L"operator || did not properly cancel. Expected: %d, Actual: %d", canceled, t4Status); - } - - TEST(TestTaskOperators_cancellation_complex) - { - extensibility::event_t evt1, evt2; - pplx::details::atomic_long n(0); - - cancellation_token_source ct; - - task<void> t1( - [&n, &evt1, &evt2]() { - pplx::details::atomic_add(n, 1L); // this should execute - evt2.set(); - evt1.wait(); - }, - ct.get_token()); - - task<void> t2 = t1.then([&n]() { - pplx::details::atomic_add(n, 10L); // this should NOT execute - }); - - task<void> t3 = t1.then([&n]() { - pplx::details::atomic_add(n, 100L); // this should NOT execute - }); - - task<void> t4 = t1.then([&n](task<void> taskResult) { - pplx::details::atomic_add(n, 1000L); // this should execute - }); - - task<void> t5 = t1.then([&n](task<void> taskResult) { - try - { - taskResult.get(); - pplx::details::atomic_add(n, 10000L); // this should execute - } - catch (task_canceled&) - { - pplx::details::atomic_add(n, 100000L); // this should NOT execute - } - }); - - evt2.wait(); - ct.cancel(); - evt1.set(); - - IsTrue((t2 && t3).wait() == canceled, L"(t1 && t2) was not canceled"); - IsTrue((t2 || t3 || t4 || t5).wait() == completed, L"(t2 || t3 || t4 || t5) did not complete"); - IsTrue((t4 && t5).wait() == completed, L"(t4 && t5) did not complete"); - - try - { - t1.get(); - } - catch (task_canceled&) - { - LogFailure(L"get() on canceled task t1 should not throw a task_canceled exception."); - } - - try - { - t2.get(); - LogFailure(L"get() on canceled task t2 should throw a task_canceled exception."); - } - catch (task_canceled&) - { - } - - try - { - t3.get(); - LogFailure(L"get() on canceled task t3 should throw a task_canceled exception."); - } - catch (task_canceled&) - { - } - - try - { - t4.get(); - t5.get(); - } - catch (...) - { - LogFailure(L"get() on completed tasks threw an exception."); - } - IsTrue( - n == 11001L, - L"The right result was not obtained from the sequence of tasks that executed. Expected: 11001, Actual: %d", - static_cast<long>(n)); - } - - TEST(TestTaskOperators_cancellation_exception) - { - extensibility::event_t evt1, evt2; - pplx::details::atomic_long n(0); - - cancellation_token_source ct; - - task<void> t1( - [&n, &evt1, &evt2]() { - evt2.set(); - evt1.wait(); - }, - ct.get_token()); - - task<void> t2([&n]() { throw 42; }); - - for (int i = 0; i < 5; ++i) - { - try - { - t2.get(); - LogFailure(L"Exception was not received from t2.get()"); - } - catch (int x) - { - IsTrue(x == 42, L"Incorrect integer was thrown from t2.get(). Expected: 42, Actual: %d", x); - } - catch (task_canceled&) - { - LogFailure(L"task_canceled was thrown from t2.get() when an integer was expected"); - } - } - - for (int i = 0; i < 5; ++i) - { - try - { - t2.wait(); - LogFailure(L"Exception was not received from t2.wait()"); - } - catch (int x) - { - IsTrue(x == 42, L"Incorrect integer was thrown from t2.wait(). Expected: 42, Actual: %d", x); - } - catch (task_canceled&) - { - LogFailure(L"task_canceled was thrown from t2.wait() when an integer was expected"); - } - } - - task<void> t3 = t1.then([&n]() { - pplx::details::atomic_add(n, 1L); // this should NOT execute, - }); - - task<void> t4 = t1.then([&n](task<void> taskResult) { - pplx::details::atomic_add(n, 10L); // this should execute - }); - - task<void> t5 = t2.then([&n]() { - pplx::details::atomic_add(n, 100L); // this should NOT execute - }); - - task<void> t6 = t2.then([&n](task<void> taskResult) { - pplx::details::atomic_add(n, 1000L); // this should execute - taskResult.get(); // should throw 42 - pplx::details::atomic_add(n, 10000L); // this should NOT execute - }); - - task<void> t7 = t2.then([&n, this](task<void> taskResult) { - try - { - taskResult.get(); - pplx::details::atomic_add(n, 100000L); // this should NOT execute - } - catch (int x) - { - IsTrue( - x == 42, - L"Incorrect integer exception was received in t7 from taskresult.get(). Expected: 42, Actual: %d", - x); - pplx::details::atomic_add(n, 1000000L); // this should execute - } - catch (task_canceled) - { - LogFailure(L"task_canceled was thrown by taskResult.get() in t7"); - } - catch (...) - { - LogFailure(L"A random exception was thrown by taskResult.get() in t7"); - } - - throw 96; - }); - - task<void> t8 = (t6 || t7).then([&n, this](task<void> taskResult) { - try - { - taskResult.get(); - pplx::details::atomic_add(n, 1000000L); // this should NOT execute - } - catch (int x) - { - IsTrue((x == 42 || x == 96), - L"Incorrect integer exception was received in t7 from taskresult.get(). Expected: 42 or 96, " - L"Actual: %d", - x); - pplx::details::atomic_add(n, 100000000L); // this should execute - } - catch (task_canceled) - { - LogFailure(L"(t6 || t7) was canceled without an exception"); - } - catch (...) - { - LogFailure(L"(t6 || t7) was canceled with an unexpected exception"); - } - }); - - // Cancel t1 now that t2 is guaranteed canceled with an exception - evt2.wait(); - ct.cancel(); - evt1.set(); - - try - { - task_status status = (t1 && t2).wait(); - IsTrue((status == canceled), - L"(t1 && t2).wait() did not return canceled. Expected: %d, Actual %d", - canceled, - status); - } - catch (int x) - { - IsTrue(x == 42, - L"Incorrect integer exception was received from (t1 && t2).wait(). Expected: 42, Actual: %d", - x); - } - - try - { - task_status status = t3.wait(); - IsTrue((status == canceled), - L"t3.wait() did not returned canceled. Expected: %d, Actual %d", - canceled, - status); - } - catch (task_canceled&) - { - LogFailure(L"t3.wait() threw task_canceled instead of returning canceled"); - } - catch (...) - { - LogFailure(L"t3.wait() threw an unexpected exception"); - } - - try - { - task_status status = t4.wait(); - IsTrue((status == completed), - L"t4.wait() did not returned completed. Expected: %d, Actual %d", - completed, - status); - } - catch (...) - { - LogFailure(L"t4.wait() threw an unexpected exception"); - } - - try - { - t5.wait(); - LogFailure(L"t5.wait() did not throw an exception"); - } - catch (int x) - { - IsTrue(x == 42, L"Incorrect integer exception was received from t5.wait(). Expected: 42, Actual: %d", x); - } - - // Observe the exceptions from t5, t6 and t7 - helpers::ObserveException(t5); - helpers::ObserveException(t6); - helpers::ObserveException(t7); - - try - { - (t1 || t6).get(); - LogFailure(L"(t1 || t6).get() should throw an exception."); - } - catch (task_canceled&) - { - LogFailure(L"(t1 || t6).get() threw task_canceled when an int was expected."); - } - catch (int x) - { - IsTrue( - (x == 42 || x == 96), - L"Incorrect integer exception was received from (t1 || t6 || t7).get(). Expected: 42 or 96, Actual: %d", - x); - } - - t8.wait(); - - IsTrue(n == 101001010L, - L"The right result was not obtained from the sequence of tasks that executed. Expected 101001010, " - L"actual %d", - 101001010, - static_cast<long>(n)); - } - - TEST(TestTaskOperators_when_all_cancellation) - { - // A task that participates in a 'when all' operation is canceled and then throws an exception. Verify that - // value and task based continuations of the when all task see the exception. - extensibility::event_t evt1, evt2; - - cancellation_token_source ct; - - task<void> t1( - [&evt1, &evt2]() { - evt2.set(); - evt1.wait(); - os_utilities::sleep(100); - throw 42; - }, - ct.get_token()); - - task<void> t2([]() { helpers::DoRandomParallelWork(); }); - - task<void> t3([]() { helpers::DoRandomParallelWork(); }); - - task<void> whenAllTask = t1 && t2 && t3; - - task<void> t4 = whenAllTask.then([this](task<void> t) { - IsFalse(helpers::VerifyCanceled(t), L"%ws:%u:t should be canceled by token", __FILE__, __LINE__); - IsTrue(helpers::VerifyException<int>(t), L"%ws:%u:exception from t is unexpected", __FILE__, __LINE__); - }); - - task<void> t5 = - whenAllTask.then([this]() { LogFailure(L"%ws:%u:t5 was unexpectedly executed", __FILE__, __LINE__); }); - - evt2.wait(); - ct.cancel(); - evt1.set(); - - IsFalse(helpers::VerifyCanceled(t5), L"%ws:%u:t5 should be canceled", __FILE__, __LINE__); - } - - TEST(TestTaskOperators_when_all_cancellation_sequence) - { - // A task that participates in a 'when all' operation throws an exception, but a continuation of the when all - // task is canceled before this point. Ensure that continuation does not get the exception but others do. - extensibility::event_t evt1, evt2; - - cancellation_token_source ct; - - task<void> t1([&evt1, &evt2]() { - evt2.set(); - evt1.wait(); - os_utilities::sleep(100); - throw 42; - }); - - task<void> t2([]() { helpers::DoRandomParallelWork(); }); - - task<void> t3([]() { helpers::DoRandomParallelWork(); }); - - task<void> whenAllTask = t1 && t2 && t3; - - task<void> t4 = whenAllTask.then([this](task<void> t) { - IsFalse(helpers::VerifyCanceled(t), L"%ws:%u:t was unexpectedly canceled", __FILE__, __LINE__); - IsTrue(helpers::VerifyException<int>(t), - L"%ws:%u:Did not receive the correct exception from t", - __FILE__, - __LINE__); - }); - - task<void> t5 = - whenAllTask.then([this]() { LogFailure(L"%ws:%u:t5 was unexpectedly executed", __FILE__, __LINE__); }); - - task<void> t6 = whenAllTask.then( - [this](task<void> t) { - IsTrue(helpers::VerifyCanceled(t), L"%ws:%u:t was not canceled as expected", __FILE__, __LINE__); - }, - ct.get_token()); - - evt2.wait(); - ct.cancel(); - evt1.set(); - - IsTrue(helpers::VerifyException<int>(t5), - L"%ws:%u:Did not receive the correct exception from t5", - __FILE__, - __LINE__); - } - - TEST(TestTaskOperators_and_cancellation_multiple_tokens) - // - // operator&& with differing tokens: - // - { - cancellation_token_source ct1; - cancellation_token_source ct2; - cancellation_token_source ct3; - cancellation_token_source ct4; - - task<int> t1([]() -> int { return 42; }, ct1.get_token()); - - task<int> t2([]() -> int { return 77; }, ct2.get_token()); - - task<int> t3([]() -> int { return 92; }, ct3.get_token()); - - task<int> t4([]() -> int { return 147; }, ct4.get_token()); - - auto t5 = t1 && t2 && t3 && t4; - - extensibility::event_t ev1, ev2; - - auto t6 = t5.then([&ev1, &ev2](std::vector<int> iVec) -> int { - ev2.set(); - ev1.wait(); - return iVec[0] + iVec[1] + iVec[2] + iVec[3]; - }); - - auto t7 = t6.then([](int val) -> int { return val; }); - - ev2.wait(); - ct3.cancel(); - ev1.set(); - t6.wait(); - t7.wait(); - - bool caughtCanceled = false; - - try - { - t7.get(); - } - catch (task_canceled&) - { - caughtCanceled = true; - } - - IsTrue(caughtCanceled, L"Cancellation token was not joined/inherited on operator&&"); - } - - struct TestException1 - { - }; - - struct TestException2 - { - }; - - // CodePlex 292 - static int ThrowFunc() { throw 42; } - - TEST(TestContinuationsWithTask1) - { - int n2 = 0; - - task<int> t([&]() -> int { return 10; }); - - t.then([&](task<int> ti) { n2 = ti.get(); }).wait(); - - VERIFY_IS_TRUE(n2 == 10); - } - - TEST(TestContinuationsWithTask2) - { - int n = 0; - - task<void> tt1([]() {}); - auto tt2 = tt1.then([&]() -> task<void> { - task<void> tt3([&]() { n = 1; }); - return tt3; - }); - - tt2.get(); - VERIFY_IS_TRUE(n == 1); - - task<void> tt4 = tt2.then([&]() -> task<void> { - task<void> tt5([&]() { n = 2; }); - return tt5; - }); - tt4.get(); - VERIFY_IS_TRUE(n == 2); - } - - TEST(TestContinuationsWithTask3) - { - bool gotException = true; - int n2 = 0; - task<int> t(ThrowFunc); - t.then([&](task<int> ti) { - try - { - ti.get(); - gotException = false; - } - catch (int) - { - n2 = 20; - } - }) - .wait(); - - VERIFY_IS_TRUE(gotException); - VERIFY_IS_TRUE(n2 == 20); - } - - TEST(TestContinuationsWithTask4) - { - int n2 = 0; - - task<int> t([&]() -> int { return 10; }); - - t.then([&](int n) -> task<int> { - task<int> t2([n]() -> int { return n + 10; }); - return t2; - }) - .then([&](int n) { n2 = n; }) - .wait(); - - VERIFY_IS_TRUE(n2 == 20); - } - - TEST(TestContinuationsWithTask5) - { - int n2 = 0; - - task<int> t([&]() -> int { return 10; }); - - t.then([&](task<int> tn) -> task<int> { - int n = tn.get(); - task<int> t2([n]() -> int { return n + 10; }); - return t2; - }) - .then([&](task<int> n) { n2 = n.get(); }) - .wait(); - - VERIFY_IS_TRUE(n2 == 20); - } - - TEST(TestContinuationsWithTask6) - { - pplx::details::atomic_long hit(0); - auto* hitptr = &hit; - task<int> t([]() { return 10; }); - - auto ot = t.then([hitptr](int n) -> task<int> { - auto hitptr1 = hitptr; - task<int> it([n, hitptr1]() -> int { - os_utilities::sleep(100); - pplx::details::atomic_exchange(*hitptr1, 1L); - return n * 2; - }); - - return it; - }); - - int value = ot.get(); - VERIFY_IS_TRUE(value == 20 && hit != 0); - } - - TEST(TestContinuationsWithTask7) - { - volatile long hit = 0; - volatile long* hitptr = &hit; - - task<int> t([]() { return 10; }); - - auto ot = t.then([hitptr](int n) -> task<int> { - task<int> it([n, hitptr]() -> int { throw TestException1(); }); - - return it; - }); - - VERIFY_IS_TRUE(helpers::VerifyException<TestException1>(ot)); - } - - TEST(TestContinuationsWithTask8) - { - volatile long hit = 0; - volatile long* hitptr = &hit; - - task<int> t([]() { return 10; }); - - auto ot = t.then([hitptr](int n) -> task<int> { - volatile long* hitptr1 = hitptr; - task<int> it([n, hitptr1]() -> int { - os_utilities::sleep(100); - os_utilities::interlocked_exchange(hitptr1, 1); - - // This test is needed to disable an optimizer dead-code check that - // winds up generating errors in VS 2010. - if (n == 10) throw TestException2(); - - return n * 3; - }); - - return it; - }); - - VERIFY_IS_TRUE(helpers::VerifyException<TestException2>(ot), - "(7) Inner task exception not propagated out of outer .get()"); - VERIFY_IS_TRUE(hit != 0, "(7) Expected inner task hit marker to be set!"); - } - - TEST(TestContinuationsWithTask9) - { - volatile long hit = 0; - volatile long* hitptr = &hit; - extensibility::event_t e; - task<int> it; - - task<int> t([]() { return 10; }); - - auto ot = t.then([hitptr, &it, &e](int n) -> task<int> { - volatile long* hitptr1 = hitptr; - it = task<int>([hitptr1, n]() -> int { - os_utilities::interlocked_exchange(hitptr1, 1); - // This test is needed to disable an optimizer dead-code check that - // winds up generating errors in VS 2010. - if (n == 10) throw TestException1(); - return n * 5; - }); - - e.set(); - os_utilities::sleep(100); - // This test is needed to disable an optimizer dead-code check that - // winds up generating errors in VS 2010. - if (n == 10) throw TestException2(); - return it; - }); - - e.wait(); - - VERIFY_IS_TRUE(helpers::VerifyException<TestException2>(ot), - "(8) Outer task exception not propagated when inner task also throws"); - VERIFY_IS_TRUE(helpers::VerifyException<TestException1>(it), - "(8) Inner task exception not explicitly propgated on pass out / get"); - VERIFY_IS_TRUE(hit != 0, "(8) Inner hit marker expected!"); - } - - TEST(TestContinuationsWithTask10) - { - volatile long hit = 0; - - task<int> t([]() { return 10; }); - - auto ot = t.then([&](int n) -> task<int> { - task<int> it([&, n]() -> int { - os_utilities::sleep(100); - // This test is needed to disable an optimizer dead-code check that - // winds up generating errors in VS 2010. - if (n == 10) throw TestException1(); - return n * 6; - }); - return it; - }); - - auto otc = ot.then([&](task<int> itp) { - os_utilities::interlocked_exchange(&hit, 1); - VERIFY_IS_TRUE(helpers::VerifyException<TestException1>(itp), - "(9) Outer task exception handling continuation did not get plumbed inner exception"); - }); - - VERIFY_IS_TRUE(helpers::VerifyException<TestException1>(ot), - "(9) Inner task exception not propagated correctly"); - helpers::ObserveException(otc); - VERIFY_IS_TRUE(hit != 0, "(9) Outer task exception handling continuation did not run!"); - } - - TEST(TestUnwrappingCtors) - { - int res; - { - // take task<int> in the ctor - - task<int> ti([]() -> int { return 1; }); - - // Must unwrap: - task<int> t1(ti); - res = t1.get(); - VERIFY_IS_TRUE(res == 1, "unexpected value in TestUnwrappingCtors, location 1"); - } - - { - // take lambda returning task<int> in the ctor - - // Must NOT unwrap: - task<task<int>> t1([]() -> task<int> { - task<int> ti([]() -> int { return 1; }); - return ti; - }); - res = t1.get().get(); - VERIFY_IS_TRUE(res == 1, "unexpected value in TestUnwrappingCtors, location 2"); - - // Must unwrap: - task<int> t2([]() -> task<int> { - task<int> ti([]() -> int { return 2; }); - return ti; - }); - res = t2.get(); - VERIFY_IS_TRUE(res == 2, "unexpected value in TestUnwrappingCtors, location 3"); - - res = t2.then([](int n) { return n + 1; }).get(); - VERIFY_IS_TRUE(res == 3, "unexpected value in TestUnwrappingCtors, location 4"); - } - - { - int executed = 0; - // take task<void> in the ctor - task<void> ti([&]() { executed = 1; }); - - // Must unwrap: - task<void> t1(ti); - t1.wait(); - VERIFY_IS_TRUE(executed == 1, "unexpected value in TestUnwrappingCtors, location 5"); - } - - { - // take lambda returning task<void> in the ctor - - int executed = 0; - int* executedPtr = &executed; - - // Must NOT unwrap: - task<task<void>> t1([executedPtr]() -> task<void> { - auto executedPtr1 = executedPtr; - task<void> ti([executedPtr1]() { *executedPtr1 = 1; }); - return ti; - }); - t1.get().get(); - VERIFY_IS_TRUE(executed == 1, "unexpected value in TestUnwrappingCtors, location 6"); - - task<void> t2([]() {}); - // Must unwrap: - task<void> t3 = t2.then([executedPtr]() -> task<void> { - auto executedPtr1 = executedPtr; - task<void> ti([executedPtr1]() { *executedPtr1 = 2; }); - return ti; - }); - - t3.wait(); - VERIFY_IS_TRUE(executed == 2, "unexpected value in TestUnwrappingCtors, location 7"); - - // Must unwrap: - task<void> t4([executedPtr]() -> task<void> { - auto executedPtr1 = executedPtr; - task<void> ti([executedPtr1]() { *executedPtr1 = 3; }); - return ti; - }); - t4.wait(); - VERIFY_IS_TRUE(executed == 3, "unexpected value in TestUnwrappingCtors, location 8"); - - t4.then([&]() { executed++; }).wait(); - VERIFY_IS_TRUE(executed == 4, "unexpected value in TestUnwrappingCtors, location 9"); - } - - { - res = create_task([]() -> task<int> { return create_task([]() -> int { return 1; }); }).get(); - VERIFY_IS_TRUE(res == 1, "unexpected value in TestUnwrappingCtors, create_task, location 1"); - - create_task([]() -> task<void> { return create_task([]() {}); }).wait(); - } - - { - // BUG TFS: 344954 - cancellation_token_source cts, cts2; - cts.cancel(); // Commenting this line out makes the program work! - // Create a task that is always cancelled - auto falseTask = create_task([]() {}, cts.get_token()); - cancellation_token ct2 = cts2.get_token(); - create_task( - [falseTask]() { - // Task unwrapping! - // This should not crash - return falseTask; - }, - ct2) - .then([this, falseTask, ct2](task<void> t) -> task<void> { - VERIFY_IS_TRUE(t.wait() == canceled, - "unexpected value in TestUnwrappingCtors, cancellation token, location 1"); - VERIFY_IS_TRUE(!ct2.is_canceled(), - "unexpected value in TestUnwrappingCtors, cancellation token, location 2"); - // again, unwrapping in continuation - // this should not crash - return falseTask; - }) - .then([this] { - VERIFY_IS_TRUE(false, "unexpected path in TestUnwrappingCtors, cancellation token, location 3"); - }); - } - } - - TEST(TestNestedTasks) - { - { - task<int> rootTask([]() -> int { return 234; }); - - task<task<int>> resultTask = rootTask.then([](int value) -> task<task<int>> { - return task<task<int>>([=]() -> task<int> { - auto val1 = value; - return task<int>([=]() -> int { return val1 + 22; }); - }); - }); - - int n = resultTask.get().get(); - VERIFY_IS_TRUE(n == 256, "TestNestedTasks_1"); - } - - { - // Same for void task - int flag = 1; - int* flagptr = &flag; - task<void> rootTask([&]() { flag++; }); - - task<task<void>> resultTask = rootTask.then([flagptr]() -> task<task<void>> { - auto flag1 = flagptr; - return task<task<void>>([flag1]() -> task<void> { - auto flag2 = flag1; - return task<void>([flag2]() { ++(flag2[0]); }); - }); - }); - - resultTask.get().wait(); - VERIFY_IS_TRUE(flag == 3, "TestNestedTasks_2"); - } - - { - task<int> rootTask([]() -> int { return 234; }); - - task<task<task<int>>> resultTask = rootTask.then([](int value) -> task<task<task<int>>> { - return task<task<task<int>>>([=]() -> task<task<int>> { - auto v1 = value; - return task<task<int>>([=]() -> task<int> { - auto v2 = v1; - return task<int>([=]() -> int { return v2 + 22; }); - }); - }); - }); - - int n = resultTask.get().get().get(); - VERIFY_IS_TRUE(n == 256, "TestNestedTasks_3"); - } - - { - task<void> nestedTask; - task<void> unwrap([&]() -> task<void> { - nestedTask = task<void>([]() { cancel_current_task(); }); - return nestedTask; - }); - task_status st = unwrap.wait(); - VERIFY_IS_TRUE(st == canceled, "TestNestedTasks_4"); - st = nestedTask.wait(); - VERIFY_IS_TRUE(st == canceled, "TestNestedTasks_5 "); - } - } - - template<typename Function> - task<void> async_for(int start, int step, int end, Function func) - { - if (start < end) - { - return func(start).then([=]() -> task<void> { return async_for(start + step, step, end, func); }); - } - else - { - return task<void>([] {}); - } - } - - TEST(TestInlineChunker) - { - const int numiter = 1000; - volatile int sum = 0; - async_for(0, - 1, - numiter, - [&](int) -> task<void> { - sum++; - return create_task([]() {}); - }) - .wait(); - - VERIFY_IS_TRUE(sum == numiter, "TestInlineChunker: async_for did not return correct result."); - } - -#if defined(_WIN32) && (_MSC_VER >= 1700) && (_MSC_VER < 1800) - - TEST(PPL_Conversions_basic) - { - pplx::task<int> t1([] { return 1; }); - concurrency::task<int> t2 = pplx::pplx_task_to_concurrency_task(t1); - int n = t2.get(); - VERIFY_ARE_EQUAL(n, 1); - - pplx::task<int> t3 = pplx::concurrency_task_to_pplx_task(t2); - int n2 = t3.get(); - VERIFY_ARE_EQUAL(n2, 1); - } - - TEST(PPL_Conversions_Nested) - { - pplx::task<int> t1([] { return 12; }); - pplx::task<int> t2 = pplx::concurrency_task_to_pplx_task(pplx::pplx_task_to_concurrency_task( - pplx::concurrency_task_to_pplx_task(pplx::pplx_task_to_concurrency_task(t1)))); - int n = t2.get(); - VERIFY_ARE_EQUAL(n, 12); - } - - TEST(PPL_Conversions_Exceptions) - { - pplx::task<int> t1(ThrowFunc); - concurrency::task<int> t2 = pplx::pplx_task_to_concurrency_task(t1); - try - { - t2.get(); - VERIFY_IS_TRUE(false); - } - catch (int m) - { - VERIFY_ARE_EQUAL(m, 42); - } - - pplx::task<int> t3 = pplx::concurrency_task_to_pplx_task(t2); - try - { - t3.get(); - VERIFY_IS_TRUE(false); - } - catch (int m) - { - VERIFY_ARE_EQUAL(m, 42); - } - } - - TEST(PPL_Conversions_Basic_void) - { - pplx::task<void> t1([] {}); - concurrency::task<void> t2 = pplx::pplx_task_to_concurrency_task(t1); - t2.get(); - - pplx::task<void> t3 = pplx::concurrency_task_to_pplx_task(t2); - t3.get(); - } - - TEST(PPL_Conversions_Exceptions_void) - { - pplx::task<void> t1([]() { throw 3; }); - concurrency::task<void> t2 = pplx::pplx_task_to_concurrency_task(t1); - try - { - t2.get(); - VERIFY_IS_TRUE(false); - } - catch (int m) - { - VERIFY_ARE_EQUAL(m, 3); - } - - pplx::task<void> t3 = pplx::concurrency_task_to_pplx_task(t2); - try - { - t3.get(); - VERIFY_IS_TRUE(false); - } - catch (int m) - { - VERIFY_ARE_EQUAL(m, 3); - } - } - -#endif - -} // SUITE(pplxtask_tests) - -} // namespace PPLX -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/stdafx.cpp @@ -1,14 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" - -#if WIN32 -__declspec(dllexport) int pplx_test_generate_lib = 0; -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/pplx/pplx_test/stdafx.h @@ -1,33 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#ifdef _WIN32 -#include <Windows.h> -#endif - -#include "pplx/pplxtasks.h" -#include <fstream> -#include <memory> -#include <stdio.h> -#include <time.h> -#include <vector> - -#if defined(_WIN32) -#include "pplx/pplxconv.h" -#else -#include "pplx/threadpool.h" -#endif - -#include "cpprest/asyncrt_utils.h" -#include "os_utilities.h" -#include "unittestpp.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/CMakeLists.txt @@ -1,27 +0,0 @@ -set(SOURCES - fstreambuf_tests.cpp - istream_tests.cpp - memstream_tests.cpp - ostream_tests.cpp - stdstream_tests.cpp -) -if(WINDOWS_STORE OR WINDOWS_PHONE) - list(APPEND SOURCES winrt_interop_tests.cpp) -else() - list(APPEND SOURCES fuzz_tests.cpp) - if(WIN32) - list(APPEND SOURCES CppSparseFile.cpp) - endif() -endif() - -add_casablanca_test(streams_test SOURCES) -if(NOT WIN32 OR CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") - cpprest_find_boost() - if(NOT TEST_LIBRARY_TARGET_TYPE STREQUAL "OBJECT") - target_link_libraries(streams_test PRIVATE cpprestsdk_boost_internal) - else() - target_include_directories(streams_test PRIVATE $<TARGET_PROPERTY:cpprestsdk_boost_internal,INTERFACE_INCLUDE_DIRECTORIES>) - endif() -endif() - -configure_pch(streams_test stdafx.h stdafx.cpp) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/CppSparseFile.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/CppSparseFile.cpp @@ -1,227 +0,0 @@ -/****************************** Module Header ******************************\ -* Module Name: CppSparseFile.cpp -* Project: CppSparseFile -* URL: http://code.msdn.microsoft.com/windowsapps/CppSparseFile-7f28156b -* Copyright (c) Microsoft Corporation. -* -* CppSparseFile demonstrates the common operations on sparse files. A sparse -* file is a type of computer file that attempts to use file system space more -* efficiently when blocks allocated to the file are mostly empty. This is -* achieved by writing brief information (metadata) representing the empty -* blocks to disk instead of the actual "empty" space which makes up the -* block, using less disk space. You can find in this example the creation of -* sparse file, the detection of sparse attribute, the retrieval of sparse -* file size, and the query of sparse file layout. -* -* This source is subject to the Microsoft Public License. -* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL. -* All other rights reserved. -* -* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, -* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -\***************************************************************************/ - -#pragma region Includes -#include "stdafx.h" - -#include "CppSparseFile.h" -#pragma endregion - -/*! - * VolumeSupportsSparseFiles determines if the volume supports sparse streams. - * - * \param lpRootPathName - * Volume root path e.g. C:\ - */ -BOOL VolumeSupportsSparseFiles(LPCTSTR lpRootPathName) -{ - DWORD dwVolFlags; - GetVolumeInformation(lpRootPathName, NULL, MAX_PATH, NULL, NULL, &dwVolFlags, NULL, MAX_PATH); - - return (dwVolFlags & FILE_SUPPORTS_SPARSE_FILES) ? TRUE : FALSE; -} - -/*! - * IsSparseFile determines if a file is sparse. - * - * \param lpFileName - * File name - */ -BOOL IsSparseFile(LPCTSTR lpFileName) -{ - // Open the file for read - HANDLE hFile = CreateFile(lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) return FALSE; - - // Get file information - BY_HANDLE_FILE_INFORMATION bhfi; - GetFileInformationByHandle(hFile, &bhfi); - CloseHandle(hFile); - - return (bhfi.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) ? TRUE : FALSE; -} - -/*! - * Get sparse file sizes. - * - * \param lpFileName - * File name - * - * \see - * http://msdn.microsoft.com/en-us/library/aa365276.aspx - */ -BOOL GetSparseFileSize(LPCTSTR lpFileName) -{ - // Retrieves the size of the specified file, in bytes. The size includes - // both allocated ranges and sparse ranges. - HANDLE hFile = CreateFile(lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) return FALSE; - LARGE_INTEGER liSparseFileSize; - GetFileSizeEx(hFile, &liSparseFileSize); - - // Retrieves the file's actual size on disk, in bytes. The size does not - // include the sparse ranges. - LARGE_INTEGER liSparseFileCompressedSize; - liSparseFileCompressedSize.LowPart = - GetCompressedFileSize(lpFileName, (LPDWORD)&liSparseFileCompressedSize.HighPart); - - // Print the result - wprintf(L"\nFile total size: %I64uKB\nActual size on disk: %I64uKB\n", - liSparseFileSize.QuadPart / 1024, - liSparseFileCompressedSize.QuadPart / 1024); - - CloseHandle(hFile); - return TRUE; -} - -/*! - * Create a sparse file. - * - * \param lpFileName - * The name of the sparse file - */ -HANDLE CreateSparseFile(LPCTSTR lpFileName) -{ - // Create a normal file - HANDLE hSparseFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hSparseFile == INVALID_HANDLE_VALUE) return hSparseFile; - - // Use the DeviceIoControl function with the FSCTL_SET_SPARSE control - // code to mark the file as sparse. If you don't mark the file as sparse, - // the FSCTL_SET_ZERO_DATA control code will actually write zero bytes to - // the file instead of marking the region as sparse zero area. - DWORD dwTemp; - DeviceIoControl(hSparseFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwTemp, NULL); - - return hSparseFile; -} - -/*! - * Converting a file region to A sparse zero area. - * - * \param hSparseFile - * Handle of the sparse file - * - * \param start - * Start address of the sparse zero area - * - * \param size - * Size of the sparse zero block. The minimum sparse size is 64KB. - * - * \remarks - * Note that SetSparseRange does not perform actual file I/O, and unlike the - * WriteFile function, it does not move the current file I/O pointer or sets - * the end-of-file pointer. That is, if you want to place a sparse zero block - * in the end of the file, you must move the file pointer accordingly using - * the FileStream.Seek function, otherwise DeviceIoControl will have no effect - */ -void SetSparseRange(HANDLE hSparseFile, LONGLONG start, LONGLONG size) -{ - // Specify the starting and the ending address (not the size) of the - // sparse zero block - FILE_ZERO_DATA_INFORMATION fzdi; - fzdi.FileOffset.QuadPart = start; - fzdi.BeyondFinalZero.QuadPart = start + size; - - // Mark the range as sparse zero block - DWORD dwTemp; - DeviceIoControl(hSparseFile, FSCTL_SET_ZERO_DATA, &fzdi, sizeof(fzdi), NULL, 0, &dwTemp, NULL); -} - -/*! - * Query the sparse file layout. - * - * \param lpFileName - * File name - */ -BOOL GetSparseRanges(LPCTSTR lpFileName) -{ - // Open the file for read - HANDLE hFile = CreateFile(lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) return FALSE; - - LARGE_INTEGER liFileSize; - GetFileSizeEx(hFile, &liFileSize); - - // Range to be examined (the whole file) - FILE_ALLOCATED_RANGE_BUFFER queryRange; - queryRange.FileOffset.QuadPart = 0; - queryRange.Length = liFileSize; - - // Allocated areas info - FILE_ALLOCATED_RANGE_BUFFER allocRanges[1024]; - - DWORD nbytes; - BOOL fFinished; - _putws(L"\nAllocated ranges in the file:"); - do - { - fFinished = DeviceIoControl(hFile, - FSCTL_QUERY_ALLOCATED_RANGES, - &queryRange, - sizeof(queryRange), - allocRanges, - sizeof(allocRanges), - &nbytes, - NULL); - - if (!fFinished) - { - DWORD dwError = GetLastError(); - - // ERROR_MORE_DATA is the only error that is normal - if (dwError != ERROR_MORE_DATA) - { - wprintf(L"DeviceIoControl failed w/err 0x%08lx\n", dwError); - CloseHandle(hFile); - return FALSE; - } - } - - // Calculate the number of records returned - DWORD dwAllocRangeCount = nbytes / sizeof(FILE_ALLOCATED_RANGE_BUFFER); - - // Print each allocated range - for (DWORD i = 0; i < dwAllocRangeCount; i++) - { - wprintf(L"allocated range: [%I64u] [%I64u]\n", - allocRanges[i].FileOffset.QuadPart, - allocRanges[i].Length.QuadPart); - } - - // Set starting address and size for the next query - if (!fFinished && dwAllocRangeCount > 0) - { - queryRange.FileOffset.QuadPart = allocRanges[dwAllocRangeCount - 1].FileOffset.QuadPart + - allocRanges[dwAllocRangeCount - 1].Length.QuadPart; - - queryRange.Length.QuadPart = liFileSize.QuadPart - queryRange.FileOffset.QuadPart; - } - - } while (!fFinished); - - CloseHandle(hFile); - return TRUE; -} diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/CppSparseFile.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/CppSparseFile.h @@ -1,82 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * CppSparseFile.h : defines various apis for creation and access of sparse files under windows - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma region Includes -#include <assert.h> -#include <stdio.h> -#include <tchar.h> - -#include <windows.h> -#pragma endregion - -/*! - * VolumeSupportsSparseFiles determines if the volume supports sparse streams. - * - * \param lpRootPathName - * Volume root path e.g. C:\ - */ -BOOL VolumeSupportsSparseFiles(LPCTSTR lpRootPathName); - -/*! - * IsSparseFile determines if a file is sparse. - * - * \param lpFileName - * File name - */ -BOOL IsSparseFile(LPCTSTR lpFileName); - -/*! - * Get sparse file sizes. - * - * \param lpFileName - * File name - * - * \see - * http://msdn.microsoft.com/en-us/library/aa365276.aspx - */ -BOOL GetSparseFileSize(LPCTSTR lpFileName); - -/*! - * Create a sparse file. - * - * \param lpFileName - * The name of the sparse file - */ -HANDLE CreateSparseFile(LPCTSTR lpFileName); - -/*! - * Converting a file region to A sparse zero area. - * - * \param hSparseFile - * Handle of the sparse file - * - * \param start - * Start address of the sparse zero area - * - * \param size - * Size of the sparse zero block. The minimum sparse size is 64KB. - * - * \remarks - * Note that SetSparseRange does not perform actual file I/O, and unlike the - * WriteFile function, it does not move the current file I/O pointer or sets - * the end-of-file pointer. That is, if you want to place a sparse zero block - * in the end of the file, you must move the file pointer accordingly using - * the FileStream.Seek function, otherwise DeviceIoControl will have no effect - */ -void SetSparseRange(HANDLE hSparseFile, LONGLONG start, LONGLONG size); - -/*! - * Query the sparse file layout. - * - * \param lpFileName - * File name - */ -BOOL GetSparseRanges(LPCTSTR lpFileName); diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/fstreambuf_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/fstreambuf_tests.cpp @@ -1,1065 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for async file stream buffer operations. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -#ifdef _WIN32 -#include "CppSparseFile.h" -#endif - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -#ifdef _WIN32 -#define DEFAULT_PROT (int)std::ios_base::_Openprot -#else -#define DEFAULT_PROT 0 -#define _SH_DENYRW 0x20 -#endif - -namespace tests -{ -namespace functional -{ -namespace streams -{ -using namespace utility; -using namespace ::pplx; - -// Used to prepare data for read tests - -utility::string_t get_full_name(const utility::string_t& name); - -void fill_file(const utility::string_t& name, size_t repetitions = 1); -#ifdef _WIN32 -void fill_file_w(const utility::string_t& name, size_t repetitions = 1); -#endif - -// -// The following two functions will help mask the differences between non-WinRT environments and -// WinRT: on the latter, a file path is typically not used to open files. Rather, a UI element is used -// to get a 'StorageFile' reference and you go from there. However, to test the library properly, -// we need to get a StorageFile reference somehow, and one way to do that is to create all the files -// used in testing in the Documents folder. -// -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4100) // Because of '_Prot' in WinRT builds. -#endif -template<typename _CharType> -pplx::task<concurrency::streams::streambuf<_CharType>> OPEN(const utility::string_t& name, - std::ios::ios_base::openmode mode, - int _Prot = DEFAULT_PROT) -{ -#if !defined(__cplusplus_winrt) - return concurrency::streams::file_buffer<_CharType>::open(name, mode, _Prot); -#else - try - { - if ((mode & std::ios::out)) - { - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->CreateFileAsync( - ref new Platform::String(name.c_str()), CreationCollisionOption::ReplaceExisting)) - .get(); - - return concurrency::streams::file_buffer<_CharType>::open(file, mode); - } - else - { - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))) - .get(); - - return concurrency::streams::file_buffer<_CharType>::open(file, mode); - } - } - catch (Platform::Exception ^ exc) - { - // The create_system_error API expects a WIN32 error code NOT an HRESULT. - if (exc->HResult == 0x80070002) - { - throw utility::details::create_system_error(ERROR_FILE_NOT_FOUND); - } - else - { - // Some other unexpected error code was encountered, fail immediately. - // Throw statement is still included after because compiler warns about not - // all paths returning a value. - VERIFY_IS_TRUE(false); - throw utility::details::create_system_error(exc->HResult); - } - } -#endif -} - -template<typename _CharType> -pplx::task<concurrency::streams::streambuf<_CharType>> OPEN_W(const utility::string_t& name, int _Prot = DEFAULT_PROT) -{ - return OPEN<_CharType>(name, std::ios_base::out | std::ios_base::trunc, _Prot); -} - -template<typename _CharType> -pplx::task<concurrency::streams::streambuf<_CharType>> OPEN_R(const utility::string_t& name, int _Prot = DEFAULT_PROT) -{ - return OPEN<_CharType>(name, std::ios_base::in, _Prot); -} - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -SUITE(file_buffer_tests) -{ - TEST(OpenCloseTest1) - { - // Test using single-byte strings - auto open = OPEN_W<char>(U("OpenCloseTest1.txt")); - - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - VERIFY_IS_TRUE(stream.is_open()); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(OpenForReadDoesntCreateFile1) - { - utility::string_t fname = U("OpenForReadDoesntCreateFile1.txt"); - - VERIFY_THROWS_SYSTEM_ERROR(OPEN_R<char>(fname).get(), std::errc::no_such_file_or_directory); - - std::ifstream is; - VERIFY_IS_NULL(is.rdbuf()->open(fname.c_str(), std::ios::in)); - } - - TEST(OpenForReadDoesntCreateFile2) - { - utility::string_t fname = U("OpenForReadDoesntCreateFile2.txt"); - - VERIFY_THROWS_SYSTEM_ERROR(OPEN<char>(fname, std::ios_base::in | std::ios_base::binary).get(), - std::errc::no_such_file_or_directory); - - std::ifstream is; - VERIFY_IS_NULL(is.rdbuf()->open(fname.c_str(), std::ios::in | std::ios_base::binary)); - } - - TEST(WriteSingleCharTest1) - { - auto open = OPEN_W<char>(U("WriteSingleCharTest1.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - VERIFY_IS_TRUE(stream.is_open()); - - bool elements_equal = true; - for (uint8_t ch = 'a'; ch <= 'z'; ch++) - { - elements_equal = elements_equal && (ch == stream.putc(ch).get()); - } - - VERIFY_IS_TRUE(elements_equal); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - VERIFY_IS_FALSE(stream.is_open()); - } -#ifdef _WIN32 - TEST(WriteSingleCharTest1w) - { - auto open = OPEN_W<wchar_t>(U("WriteSingleCharTest1w.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - VERIFY_IS_TRUE(stream.is_open()); - - bool elements_equal = true; - for (wchar_t ch = L'a'; ch <= L'z'; ch++) - { - elements_equal = elements_equal && (ch == stream.putc(ch).get()); - } - - VERIFY_IS_TRUE(elements_equal); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - VERIFY_IS_FALSE(stream.is_open()); - } -#endif - - TEST(WriteBufferTest1) - { - auto open = OPEN_W<char>(U("WriteBufferTest1.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - VERIFY_IS_TRUE(stream.is_open()); - - std::vector<char> vect; - - for (uint8_t ch = 'a'; ch <= 'z'; ch++) - { - vect.push_back(ch); - } - - VERIFY_ARE_EQUAL(stream.putn_nocopy(&vect[0], vect.size()).get(), vect.size()); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - VERIFY_IS_FALSE(stream.is_open()); - } -#ifdef _WIN32 - TEST(WriteBufferTest1w) - { - auto open = OPEN_W<wchar_t>(U("WriteBufferTest1w.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - VERIFY_IS_TRUE(stream.is_open()); - - std::vector<wchar_t> vect; - - for (wchar_t ch = L'a'; ch <= L'z'; ch++) - { - vect.push_back(ch); - } - - VERIFY_ARE_EQUAL(stream.putn_nocopy(&vect[0], vect.size()).get(), vect.size()); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - VERIFY_IS_FALSE(stream.is_open()); - } -#endif - - TEST(WriteBufferAndSyncTest1) - { - auto open = OPEN_W<char>(U("WriteBufferAndSyncTest1.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - VERIFY_IS_TRUE(stream.is_open()); - - std::vector<char> vect; - - for (uint8_t ch = 'a'; ch <= 'z'; ch++) - { - vect.push_back(ch); - } - - auto write = stream.putn_nocopy(&vect[0], vect.size()); - - stream.sync().get(); - - VERIFY_ARE_EQUAL(write.get(), vect.size()); - VERIFY_IS_TRUE(write.is_done()); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(ReadSingleChar_bumpc1) - { - utility::string_t fname = U("ReadSingleChar_bumpc1.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - uint8_t buf[10]; - memset(buf, 0, sizeof(buf)); - - for (int i = 0; i < sizeof(buf); i++) - { - buf[i] = (uint8_t)stream.bumpc().get(); - VERIFY_ARE_EQUAL(buf[i], 'a' + i); - } - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(SequentialReadWrite) - { - utility::string_t fname = U("SequentialReadWrite.txt"); - - auto ostreamBuf = OPEN_W<char>(fname).get(); - - VERIFY_IS_TRUE(ostreamBuf.is_open()); - - for (int i = 0; i < 1000; i++) - { - ostreamBuf.putc(i % 26 + 'a'); - ostreamBuf.putn_nocopy("ABCDEFGHIJ", 10); - } - ostreamBuf.close().wait(); - VERIFY_IS_FALSE(ostreamBuf.is_open()); - - auto istreamBuf = OPEN_R<char>(fname).get(); - std::vector<pplx::task<void>> t; - - for (int k = 0; k < 2; k++) - { - for (int i = 0; i < 1000; i++) - { - t.push_back(istreamBuf.getc().then([i, this](char c) { VERIFY_ARE_EQUAL(i % 26 + 'a', c); })); - t.push_back(istreamBuf.bumpc().then([i, this](char c) { VERIFY_ARE_EQUAL(i % 26 + 'a', c); })); - char* buffer = new char[11]; - t.push_back(istreamBuf.getn(buffer, 10).then([=](size_t n) { - VERIFY_ARE_EQUAL(10u, n); - VERIFY_ARE_EQUAL(std::string("ABCDEFGHIJ"), std::string(buffer, 10)); - delete[] buffer; - })); - } - istreamBuf.seekpos(0, std::ios::in); - } - istreamBuf.close().wait(); - VERIFY_IS_FALSE(istreamBuf.is_open()); - for (size_t i = 0; i < t.size(); i++) - t[i].wait(); - } - -#ifdef _WIN32 - TEST(ReadSingleChar_bumpcw) - { - utility::string_t fname = U("ReadSingleChar_bumpcw.txt"); - fill_file_w(fname); - - auto stream = OPEN_R<wchar_t>(fname).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - wchar_t buf[10]; - memset(buf, 0, sizeof(buf)); - - for (int i = 0; i < 10; i++) - { - buf[i] = stream.bumpc().get(); - VERIFY_ARE_EQUAL(buf[i], L'a' + i); - } - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } -#endif - - TEST(ReadSingleChar_bumpc2) - { - // Test that seeking works. - utility::string_t fname = U("ReadSingleChar_bumpc2.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - stream.seekpos(3, std::ios_base::in); - - uint8_t buf[10]; - memset(buf, 0, sizeof(buf)); - - for (int i = 0; i < sizeof(buf); i++) - { - buf[i] = (uint8_t)stream.bumpc().get(); - VERIFY_ARE_EQUAL(buf[i], 'd' + i); - } - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(filestream_length) - { - utility::string_t fname = U("ReadSingleChar_bumpc3.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname, _SH_DENYRW).get(); - stream.set_buffer_size(512); - - VERIFY_IS_TRUE(stream.is_open()); - - test_stream_length(stream.create_istream(), 26); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(ReadSingleChar_bumpc3) - { - // Test that seeking works. - utility::string_t fname = U("ReadSingleChar_bumpc3.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname, _SH_DENYRW).get(); - stream.set_buffer_size(512); - - VERIFY_IS_TRUE(stream.is_open()); - - stream.seekpos(2, std::ios_base::in); - - // Read a character asynchronously to get the buffer primed. - stream.bumpc().get(); - - auto ras = concurrency::streams::char_traits<char>::requires_async(); - - for (int i = 3; i < 26; i++) - { - auto c = (uint8_t)stream.sbumpc(); - if (c != ras) - { - VERIFY_ARE_EQUAL(c, 'a' + i); - } - } - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(ReadSingleChar_nextc) - { - utility::string_t fname = U("ReadSingleChar_nextc.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - uint8_t buf[10]; - memset(buf, 0, sizeof(buf)); - - for (int i = 0; i < sizeof(buf); i++) - { - buf[i] = (uint8_t)stream.nextc().get(); - VERIFY_ARE_EQUAL(buf[i], 'b' + i); - } - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } -#ifdef _WIN32 - TEST(ReadSingleChar_nextcw) - { - utility::string_t fname = U("ReadSingleChar_nextcw.txt"); - fill_file_w(fname); - - auto stream = OPEN_R<wchar_t>(fname).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - wchar_t buf[10]; - memset(buf, 0, sizeof(buf)); - - for (int i = 0; i < 10; i++) - { - buf[i] = stream.nextc().get(); - VERIFY_ARE_EQUAL(buf[i], L'b' + i); - } - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } -#endif - - TEST(ReadSingleChar_ungetc) - { - // Test that seeking works. - utility::string_t fname = U("ReadSingleChar_ungetc.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - stream.seekpos(13, std::ios_base::in); - - uint8_t buf[10]; - memset(buf, 0, sizeof(buf)); - - for (int i = 0; i < sizeof(buf); i++) - { - buf[i] = (uint8_t)stream.ungetc().get(); - VERIFY_ARE_EQUAL(buf[i], 'm' - i); - } - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(ReadSingleChar_getc1) - { - utility::string_t fname = U("ReadSingleChar_getc1.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname, _SH_DENYRW).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - uint8_t ch0 = (uint8_t)stream.getc().get(); - uint8_t ch1 = (uint8_t)stream.getc().get(); - - VERIFY_ARE_EQUAL(ch0, ch1); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(ReadSingleChar_getc2) - { - utility::string_t fname = U("ReadSingleChar_getc2.txt"); - fill_file(fname); - - auto stream = OPEN_R<char>(fname, _SH_DENYRW).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - stream.seekpos(13, std::ios_base::in); - - uint8_t ch0 = (uint8_t)stream.getc().get(); - uint8_t ch1 = (uint8_t)stream.sgetc(); - - VERIFY_ARE_EQUAL(ch0, ch1); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - -#ifdef _WIN32 - TEST(ReadSingleChar_getc1w) - { - utility::string_t fname = U("ReadSingleChar_getc1w.txt"); - fill_file_w(fname); - - auto stream = OPEN_R<wchar_t>(fname, _SH_DENYRW).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - wchar_t ch0 = stream.getc().get(); - wchar_t ch1 = stream.getc().get(); - - VERIFY_ARE_EQUAL(ch0, ch1); - VERIFY_ARE_EQUAL(ch0, L'a'); - - stream.seekpos(15, std::ios_base::in); - - ch0 = stream.getc().get(); - ch1 = stream.getc().get(); - - VERIFY_ARE_EQUAL(ch0, ch1); - VERIFY_ARE_EQUAL(ch0, L'p'); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(ReadSingleChar_getc2w) - { - utility::string_t fname = U("ReadSingleChar_getc2w.txt"); - fill_file_w(fname); - - auto stream = OPEN_R<wchar_t>(fname, _SH_DENYRW).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - stream.seekpos(13, std::ios_base::in); - - wchar_t ch0 = stream.getc().get(); - wchar_t ch1 = stream.getc().get(); - - VERIFY_ARE_EQUAL(ch0, ch1); - VERIFY_ARE_EQUAL(ch0, L'n'); - - stream.seekpos(5, std::ios_base::in); - - ch0 = stream.getc().get(); - ch1 = stream.getc().get(); - - VERIFY_ARE_EQUAL(ch0, ch1); - VERIFY_ARE_EQUAL(ch0, L'f'); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } -#endif - - TEST(ReadBuffer1) - { - // Test that seeking works. - utility::string_t fname = U("ReadBuffer1.txt"); - fill_file(fname); - - // In order to get the implementation to buffer reads, we have to open the file - // with protection against sharing. - auto stream = OPEN_R<char>(fname, _SH_DENYRW).get(); - stream.set_buffer_size(512); - - VERIFY_IS_TRUE(stream.is_open()); - - char buf[10]; - memset(buf, 0, sizeof(buf)); - - auto read = stream.getn(buf, sizeof(buf)).then([=](pplx::task<size_t> op) -> size_t { return op.get(); }); - - VERIFY_ARE_EQUAL(sizeof(buf), read.get()); - - bool elements_equal = true; - - for (int i = 0; i < sizeof(buf); i++) - { - elements_equal = elements_equal && (buf[i] == 'a' + i); - } - - VERIFY_IS_TRUE(elements_equal); - - stream.seekpos(3, std::ios_base::in); - - memset(buf, 0, sizeof(buf)); - - read = stream.getn(buf, sizeof(buf)).then([=](pplx::task<size_t> op) -> size_t { return op.get(); }); - - VERIFY_ARE_EQUAL(sizeof(buf), read.get()); - - elements_equal = true; - - for (int i = 0; i < sizeof(buf); i++) - { - elements_equal = elements_equal && (buf[i] == 'd' + i); - } - - VERIFY_IS_TRUE(elements_equal); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - -#ifdef _WIN32 - TEST(ReadBuffer1w) - { - // Test that seeking works. - utility::string_t fname = U("ReadBuffer1w.txt"); - fill_file_w(fname); - - // In order to get the implementation to buffer reads, we have to open the file - // with protection against sharing. - auto stream = OPEN_R<wchar_t>(fname, _SH_DENYRW).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - wchar_t buf[10]; - memset(buf, 0, sizeof(buf)); - - auto read = stream.getn(buf, 10).then([=](pplx::task<size_t> op) -> size_t { return op.get(); }); - - VERIFY_ARE_EQUAL(10u, read.get()); - - bool elements_equal = true; - - for (int i = 0; i < 10; i++) - { - elements_equal = elements_equal && (buf[i] == L'a' + i); - } - - VERIFY_IS_TRUE(elements_equal); - - stream.seekpos(3, std::ios_base::in); - - memset(buf, 0, sizeof(buf)); - - read = stream.getn(buf, 10).then([=](pplx::task<size_t> op) -> size_t { return op.get(); }); - - VERIFY_ARE_EQUAL(10u, read.get()); - - elements_equal = true; - - for (int i = 0; i < 10; i++) - { - elements_equal = elements_equal && (buf[i] == L'd' + i); - } - - VERIFY_IS_TRUE(elements_equal); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } -#endif - - TEST(ReadBuffer2) - { - // Test that seeking works when the file is larger than the internal buffer size. - utility::string_t fname = U("ReadBuffer2.txt"); - fill_file(fname, 30); - - // In order to get the implementation to buffer reads, we have to open the file - // with protection against sharing. - auto stream = OPEN_R<char>(fname, _SH_DENYRW).get(); - - VERIFY_IS_TRUE(stream.is_open()); - - char buf[10]; - memset(buf, 0, sizeof(buf)); - - auto read = stream.getn(buf, sizeof(buf)).then([=](pplx::task<size_t> op) -> size_t { return op.get(); }); - - VERIFY_ARE_EQUAL(sizeof(buf), read.get()); - - bool elements_equal = true; - - for (int i = 0; i < sizeof(buf); i++) - { - elements_equal = elements_equal && (buf[i] == 'a' + i); - } - - VERIFY_IS_TRUE(elements_equal); - - // Test that we can seek to a position near the end of the initial buffer, - // read a chunk spanning the end of the buffer, and get a correct outcome. - - stream.seekpos(505, std::ios_base::in); - - memset(buf, 0, sizeof(buf)); - - read = stream.getn(buf, sizeof(buf)).then([=](pplx::task<size_t> op) -> size_t { return op.get(); }); - - VERIFY_ARE_EQUAL(sizeof(buf), read.get()); - - elements_equal = true; - - for (int i = 0; i < sizeof(buf); i++) - { - elements_equal = elements_equal && (buf[i] == 'l' + i); - } - - VERIFY_IS_TRUE(elements_equal); - - stream.close().get(); - - VERIFY_IS_FALSE(stream.is_open()); - } - - TEST(SeekEnd1) - { - utility::string_t fname = U("SeekEnd1.txt"); - fill_file(fname, 30); - - // In order to get the implementation to buffer reads, we have to open the file - // with protection against sharing. - auto stream = OPEN_R<char>(fname).get(); - - auto pos = stream.seekoff(0, std::ios_base::end, std::ios_base::in); - - VERIFY_ARE_EQUAL(30 * 26, pos); - } - - TEST(IsEOFTest) - { - utility::string_t fname = U("IsEOFTest.txt"); - fill_file(fname, 30); - - auto stream = OPEN_R<char>(fname).get(); - VERIFY_IS_FALSE(stream.is_eof()); - stream.getc().wait(); - VERIFY_IS_FALSE(stream.is_eof()); - stream.seekoff(0, std::ios_base::end, std::ios_base::in); - VERIFY_IS_FALSE(stream.is_eof()); - stream.getc().wait(); - VERIFY_IS_TRUE(stream.is_eof()); - stream.seekoff(0, std::ios_base::beg, std::ios_base::in); - VERIFY_IS_TRUE(stream.is_eof()); - stream.getc().wait(); - VERIFY_IS_FALSE(stream.is_eof()); - } - - TEST(CloseWithException) - { - struct MyException - { - }; - auto streambuf = OPEN_W<char>(U("CloseExceptionTest.txt")).get(); - streambuf.close(std::ios::out, std::make_exception_ptr(MyException())).wait(); - VERIFY_THROWS(streambuf.putn_nocopy("this is good", 10).get(), MyException); - VERIFY_THROWS(streambuf.putc('c').get(), MyException); - - streambuf = OPEN_R<char>(U("CloseExceptionTest.txt")).get(); - streambuf.close(std::ios::in, std::make_exception_ptr(MyException())).wait(); - char buf[100]; - VERIFY_THROWS(streambuf.getn(buf, 100).get(), MyException); - VERIFY_THROWS(streambuf.getc().get(), MyException); - } - - TEST(inout_regression_test) - { - std::string data = "abcdefghijklmn"; - concurrency::streams::streambuf<char> file_buf = - OPEN<char>(U("inout_regression_test.txt"), std::ios_base::in | std::ios_base::out).get(); - file_buf.putn_nocopy(&data[0], data.size()).get(); - - file_buf.bumpc().get(); // reads 'a' - - char readdata[256]; - memset(&readdata[0], '\0', 256); - - file_buf.seekoff(0, std::ios::beg, std::ios::in); - auto data_read = file_buf.getn(&readdata[0], 3).get(); // reads 'bcd'. File contains the org string though!!! - - memset(&readdata[0], '\0', 256); - - file_buf.seekoff(0, std::ios::beg, std::ios::in); - data_read = file_buf.getn(&readdata[0], 3).get(); // reads 'efg'. File contains org string 'abcdef..'. - - file_buf.close().wait(); - } - - TEST(seek_read_regression_test) - { - utility::string_t fname = U("seek_read_regression_test.txt"); - fill_file(fname, 100); - - char readdata[256]; - - auto istream = OPEN_R<char>(fname, _SH_DENYRW).get().create_istream(); - istream.streambuf().set_buffer_size(128); - - { - istream.seek(50, std::ios_base::beg); - concurrency::streams::rawptr_buffer<char> block(readdata, sizeof(readdata)); - istream.read(block, 50).get(); - } - - { - istream.seek(256, std::ios_base::beg); - concurrency::streams::rawptr_buffer<char> block(readdata, sizeof(readdata)); - istream.read(block, 256).get(); - } - - istream.close().get(); - } - - TEST(file_size) - { - utility::string_t fname = U("file_size.txt"); - fill_file(fname, 100); - auto istream = OPEN_R<char>(fname).get(); - VERIFY_IS_TRUE(istream.has_size()); - VERIFY_ARE_EQUAL(istream.size(), 2600); - } - -#ifdef _WIN32 - TEST(file_size_w) - { - utility::string_t fname = U("file_size_w.txt"); - fill_file_w(fname, 100); - auto istream = OPEN_R<wchar_t>(fname).get(); - VERIFY_IS_TRUE(istream.has_size()); - VERIFY_ARE_EQUAL(istream.size(), 2600); - } - - TEST(file_with_one_byte_size) - { - // Create a file with one byte. - concurrency::streams::streambuf<char> file_buf = OPEN<char>(U("one_byte_file.txt"), std::ios_base::out).get(); - file_buf.putc('a').wait(); - file_buf.close().wait(); - - // Try to read from file with a 2 byte character. - concurrency::streams::basic_istream<wchar_t> inFile(OPEN<wchar_t>(U("one_byte_file.txt"), std::ios::in).get()); - concurrency::streams::container_buffer<std::wstring> buffer; - VERIFY_ARE_EQUAL(inFile.read(buffer, 1).get(), 0); - VERIFY_IS_TRUE(inFile.is_eof()); - } -#endif - -#if defined(_WIN32) && (!defined(__cplusplus_winrt)) && defined(_WIN64) - // since casablanca does not use sparse file apis we're not doing the reverse test (write one byte at 4Gb and verify - // with std apis) because the file created would be too big - TEST(read_one_byte_at_4G) - { - // Create a file with one byte. - string_t filename = U("read_one_byte_at_4G.txt"); - // create a sparse file with sparse file apis - auto handle = CreateSparseFile(filename.c_str()); - VERIFY_ARE_NOT_EQUAL(handle, INVALID_HANDLE_VALUE); - - // write 1 byte - auto data = 'a'; - - DWORD dwBytesWritten; - LARGE_INTEGER i; - i.QuadPart = 0x100000000; - - SetFilePointerEx(handle, i /*4GB*/, NULL, FILE_END); - WriteFile(handle, &data, 1, &dwBytesWritten, NULL); - - CloseHandle(handle); - - // read the file with casablanca streams - concurrency::streams::streambuf<char> file_buf = OPEN<char>(filename, std::ios_base::in).get(); - file_buf.seekoff(4 * 1024 * 1024 * 1024ll, ::std::ios_base::beg, ::std::ios_base::in); - - int aCharacter = file_buf.getc().get(); - file_buf.close().wait(); - - VERIFY_ARE_EQUAL(aCharacter, data); - } -#endif - -#if !defined(_WIN32) && defined(__x86_64__) - - struct TidyStream - { - string_t _fileName; - concurrency::streams::streambuf<char> _stream; - - TidyStream(string_t filename) - { - _fileName = filename; - _stream = OPEN<char>(filename, std::ios_base::out | ::std::ios_base::in).get(); - } - - ~TidyStream() - { - _stream.close().wait(); - std::remove(_fileName.c_str()); - } - }; - - TEST(write_one_byte_at_4G) - { - // write using casablanca streams - concurrency::streams::streambuf<char>::off_type pos = 4 * 1024 * 1024 * 1024ll; - - string_t filename = U("write_one_byte_at_4G.txt"); - TidyStream file_buf(filename); - file_buf._stream.seekoff(pos, ::std::ios_base::beg, ::std::ios_base::out); - file_buf._stream.putc('a').wait(); - file_buf._stream.sync().get(); - - // verify with std streams - std::fstream stream(get_full_name(filename), std::ios_base::in); - stream.seekg(pos); - char c; - stream >> c; - stream.close(); - VERIFY_ARE_EQUAL(c, 'a'); - } - - TEST(read_one_byte_at_4G) - { - // write with std stream - concurrency::streams::streambuf<char>::off_type pos = 4 * 1024 * 1024 * 1024ll; - // Create a file with one byte. - string_t filename = U("read_one_byte_at_4G.txt"); - - std::fstream stream(get_full_name(filename), std::ios_base::out); - stream.seekg(pos); - stream << 'a'; - stream.close(); - - // verify with casablanca streams - TidyStream file_buf(filename); - file_buf._stream.seekoff(pos, ::std::ios_base::beg, ::std::ios_base::in); - int aCharacter = file_buf._stream.getc().get(); - - VERIFY_ARE_EQUAL(aCharacter, 'a'); - } - -#endif - - TEST(alloc_acquire_not_supported) - { - concurrency::streams::streambuf<char> file_buf = - OPEN<char>(U("alloc_not_supported.txt"), std::ios::out | std::ios::in).get(); - VERIFY_IS_TRUE(file_buf.alloc(1) == nullptr); - char* temp; - size_t size; - VERIFY_IS_FALSE(file_buf.acquire(temp, size)); - } - - TEST(read_alloc_acquire_not_supported) - { - auto file_buf1 = OPEN<char>(U("read_acquire_not_supported1.txt"), std::ios::out | std::ios::in).get(); - auto file_buf2 = OPEN<char>(U("read_acquire_not_supported2.txt"), std::ios::out | std::ios::in).get(); - - concurrency::streams::stringstreambuf data_buf("A"); - file_buf1.create_ostream().write(data_buf, 1).wait(); - file_buf1.sync().wait(); - file_buf2.create_ostream().write(file_buf1, 1).wait(); - file_buf2.sync().wait(); - - file_buf2.create_istream().read(file_buf1, 1).wait(); - file_buf1.sync().wait(); - file_buf1.seekpos(0, std::ios::in); - data_buf = concurrency::streams::stringstreambuf(); - file_buf1.create_istream().read(data_buf, 2).wait(); - const auto& data = data_buf.collection(); - VERIFY_ARE_EQUAL(data[0], 'A'); - VERIFY_ARE_EQUAL(data[1], 'A'); - - file_buf1.close().wait(); - file_buf2.close().wait(); - } - - TEST(winrt_filestream_close) - { - std::string str("test data"); - auto t = OPEN_W<uint8_t>(U("file.txt")).then([this, str](concurrency::streams::ostream stream) { - concurrency::streams::container_buffer<std::string> rbuf(str); - concurrency::streams::istream is(rbuf); - size_t size = 0; - is.read(stream.streambuf(), 1).wait(); - while (!is.is_eof()) - { - is.read(stream.streambuf(), 1).wait(); - size += 1; - } - - return stream.flush().then([size, stream]() { - stream.close(); - return size; - }); - }); - - VERIFY_ARE_EQUAL(t.get(), str.length()); - } -} // SUITE(file_buffer_tests) - -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/fuzz_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/fuzz_tests.cpp @@ -1,116 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Fuzzing tests for streams read operations that involve parsing of data. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -using namespace concurrency::streams; - -namespace tests -{ -namespace functional -{ -namespace streams -{ -using namespace utility; -using namespace ::pplx; - -SUITE(streams_fuzz_tests) -{ - std::string get_fuzzed_file_path(std::string requires_str) - { - std::string ipfile; - - if (UnitTest::GlobalSettings::Has(requires_str)) - { - ipfile = UnitTest::GlobalSettings::Get(requires_str); - } - - return ipfile; - } - - concurrency::streams::basic_istream<char> get_input_stream(std::string requires_str) - { - utility::string_t ipfile = utility::conversions::to_string_t(get_fuzzed_file_path(requires_str)); - concurrency::streams::basic_istream<char> ifs; - - if (true == ipfile.empty()) - { - VERIFY_IS_TRUE(false, "Input file is empty"); - return ifs; - } - - ifs = concurrency::streams::file_stream<char>::open_istream(ipfile, std::ios::in).get(); - - // Look for UTF-8 BOM - if (ifs.read().get() != 0xEF || ifs.read().get() != 0xBB || ifs.read().get() != 0xBF) - { - VERIFY_IS_TRUE(false, "Input file encoding is not UTF-8. Test will not parse the file."); - ifs.close().get(); - } - return ifs; - } - - TEST(fuzz_read_line, "Requires", "fuzz_read_line_ipfile", "Timeout", "600000") - { - auto ifs = get_input_stream("fuzz_read_line_ipfile"); - if (!ifs.is_valid() || !ifs.is_open()) return; - - size_t num_lines = 0; - while (false == ifs.is_eof()) - { - container_buffer<std::vector<uint8_t>> buf; - ifs.read_line(buf).get(); - num_lines++; - } - ifs.close().get(); - std::wcout << U("Number of lines read:") << num_lines; - } - - template<class T> - void extract(const basic_istream<char>& ifs) - { - try - { - ifs.extract<T>().get(); - } - catch (std::exception) - { - } - return; - } - - TEST(fuzz_extract, "Requires", "fuzz_extract_ipfile", "Timeout", "600000") - { - auto ifs = get_input_stream("fuzz_extract_ipfile"); - if (!ifs.is_valid() || !ifs.is_open()) return; - - int num_lines = 0; - while (false == ifs.is_eof()) - { - extract<std::string>(ifs); - extract<std::string>(ifs); - extract<unsigned int>(ifs); - extract<uint64_t>(ifs); - extract<bool>(ifs); - extract<std::string>(ifs); - extract<int>(ifs); - container_buffer<std::vector<uint8_t>> buf; - ifs.read_line(buf).get(); - num_lines++; - } - ifs.close().get(); - std::wcout << L"Number of lines read:" << num_lines << std::endl; - } - -} // SUITE(streams_fuzz_tests) - -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/istream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/istream_tests.cpp @@ -1,1574 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for async input stream operations. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -#include "unittestpp.h" -#include <float.h> - -#ifdef max -#undef max -#endif - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -#ifdef _WIN32 -#define DEFAULT_PROT (int)std::ios_base::_Openprot -#else -#define DEFAULT_PROT 0 -#endif - -namespace tests -{ -namespace functional -{ -namespace streams -{ -using namespace ::pplx; -using namespace utility; -using namespace concurrency::streams; - -// Used to prepare data for file-stream read tests - -utility::string_t get_full_name(const utility::string_t& name) -{ -#if defined(__cplusplus_winrt) - // On WinRT, we must compensate for the fact that we will be accessing files in the - // Documents folder - auto file = pplx::create_task(KnownFolders::DocumentsLibrary->CreateFileAsync( - ref new Platform::String(name.c_str()), CreationCollisionOption::ReplaceExisting)) - .get(); - return file->Path->Data(); -#else - return name; -#endif -} - -void fill_file(const utility::string_t& name, size_t repetitions = 1) -{ - std::fstream stream(get_full_name(name), std::ios_base::out | std::ios_base::trunc); - - for (size_t i = 0; i < repetitions; i++) - stream << "abcdefghijklmnopqrstuvwxyz"; -} - -void fill_file_with_lines(const utility::string_t& name, const std::string& end, size_t repetitions = 1) -{ - std::fstream stream(get_full_name(name), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary); - - for (size_t i = 0; i < repetitions; i++) - stream << "abcdefghijklmnopqrstuvwxyz" << end; -} - -#ifdef _WIN32 - -// Disabling warning in test because we check for nullptr. -#pragma warning(push) -#pragma warning(disable : 6387) -void fill_file_w(const utility::string_t& name, size_t repetitions = 1) -{ - FILE* stream = nullptr; - _wfopen_s(&stream, get_full_name(name).c_str(), L"w"); - if (stream == nullptr) - { - VERIFY_IS_TRUE(false, "FILE pointer is null"); - } - - for (size_t i = 0; i < repetitions; i++) - for (wchar_t ch = L'a'; ch <= L'z'; ++ch) - fwrite(&ch, sizeof(wchar_t), 1, stream); - - fclose(stream); -} -#pragma warning(pop) - -#endif - -// -// The following functions will help mask the differences between non-WinRT environments and -// WinRT: on the latter, a file path is typically not used to open files. Rather, a UI element is used -// to get a 'StorageFile' reference and you go from there. However, to test the library properly, -// we need to get a StorageFile reference somehow, and one way to do that is to create all the files -// used in testing in the Documents folder. -// -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4100) // Because of '_Prot' in WinRT builds. -#endif -template<typename _CharType> -pplx::task<streams::streambuf<_CharType>> OPEN_R(const utility::string_t& name, int _Prot = DEFAULT_PROT) -{ -#if !defined(__cplusplus_winrt) - return streams::file_buffer<_CharType>::open(name, std::ios_base::in, _Prot); -#else - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))).get(); - - return streams::file_buffer<_CharType>::open(file, std::ios_base::in); -#endif -} -#if defined(_MSC_VER) -#pragma warning(pop) -#endif -SUITE(istream_tests) -{ - // Tests using memory stream buffers. - TEST(stream_read_1) - { - producer_consumer_buffer<char> rbuf; - - VERIFY_ARE_EQUAL(26u, rbuf.putn_nocopy("abcdefghijklmnopqrstuvwxyz", 26).get()); - - istream stream(rbuf); - - VERIFY_IS_FALSE(stream.can_seek()); - - for (char c = 'a'; c <= 'z'; c++) - { - char ch = (char)stream.read().get(); - VERIFY_ARE_EQUAL(c, ch); - } - - stream.close().get(); - } - - TEST(fstream_read_1) - { - utility::string_t fname = U("fstream_read_1.txt"); - fill_file(fname); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - VERIFY_IS_TRUE(stream.is_open()); - - for (char c = 'a'; c <= 'z'; c++) - { - char ch = (char)stream.read().get(); - VERIFY_ARE_EQUAL(c, ch); - } - - stream.close().get(); - } - - TEST(stream_read_1_fail) - { - producer_consumer_buffer<char> rbuf; - - VERIFY_ARE_EQUAL(26u, rbuf.putn_nocopy("abcdefghijklmnopqrstuvwxyz", 26).get()); - - istream stream(rbuf); - rbuf.close(std::ios_base::in).get(); - - VERIFY_THROWS(stream.read().get(), std::runtime_error); - // Closing again should not throw. - stream.close().wait(); - } - - TEST(stream_read_2) - { - producer_consumer_buffer<char> rbuf; - - VERIFY_ARE_EQUAL(26u, rbuf.putn_nocopy("abcdefghijklmnopqrstuvwxyz", 26).get()); - - istream stream(rbuf); - - uint8_t buffer[128]; - streams::rawptr_buffer<uint8_t> tbuf(buffer, 128); - - VERIFY_ARE_EQUAL(26u, stream.read(tbuf, 26).get()); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - rbuf.close(std::ios_base::out).get(); - - VERIFY_ARE_EQUAL(0u, stream.read(tbuf, 26).get()); - - stream.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(fstream_read_2) - { - utility::string_t fname = U("fstream_read_2.txt"); - fill_file(fname); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - char buffer[128]; - streams::rawptr_buffer<char> tbuf(buffer, 128); - - VERIFY_ARE_EQUAL(26u, stream.read(tbuf, 26).get()); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - VERIFY_ARE_EQUAL(0u, stream.read(tbuf, 26).get()); - - stream.close().get(); - } - - TEST(stream_read_3) - { - producer_consumer_buffer<char> rbuf; - - // There's no newline int the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - rbuf.close(std::ios_base::out).get(); - - istream stream(rbuf); - - uint8_t buffer[128]; - streams::rawptr_buffer<uint8_t> tbuf(buffer, 128); - - VERIFY_ARE_EQUAL(52u, stream.read(tbuf, sizeof(buffer)).get()); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'A', buffer[i + 26]); - } - - stream.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(stream_read_3_fail) - { - producer_consumer_buffer<char> rbuf; - - // There's no newline int the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - rbuf.close(std::ios_base::out).get(); - - istream stream(rbuf); - - uint8_t buffer[128]; - streams::rawptr_buffer<uint8_t> tbuf(buffer, 128); - tbuf.close(std::ios_base::out).get(); - - VERIFY_THROWS(stream.read(tbuf, sizeof(buffer)).get(), std::runtime_error); - - stream.close().get(); - } - - TEST(stream_read_4) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> stream = rbuf; - - VERIFY_ARE_EQUAL(52u, stream.read_to_delim(trg, '\n').get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(52u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'A', buffer[i + 26]); - } - - stream.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(fstream_read_4) - { - producer_consumer_buffer<uint8_t> trg; - - utility::string_t fname = U("fstream_read_4.txt"); - fill_file(fname, 2); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - VERIFY_ARE_EQUAL(52u, stream.read_to_delim(trg, '\n').get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(52u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i + 26]); - } - - stream.close().get(); - } - - TEST(stream_read_4_fail) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> stream = rbuf; - - trg.close(std::ios::out).get(); - - VERIFY_THROWS(stream.read_to_delim(trg, '\n').get(), std::runtime_error); - - stream.close().get(); - } - - TEST(stream_read_5) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's one newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\n\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - - istream stream(rbuf); - - VERIFY_IS_FALSE(stream.is_eof()); - VERIFY_ARE_EQUAL(26u, stream.read_to_delim(trg, '\n').get()); - VERIFY_IS_FALSE(stream.is_eof()); - VERIFY_ARE_EQUAL(0u, stream.read_to_delim(trg, '\n').get()); - VERIFY_IS_FALSE(stream.is_eof()); - VERIFY_ARE_EQUAL('A', (char)rbuf.getc().get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(26u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - stream.close().get(); - } - - TEST(fstream_read_5) - { - producer_consumer_buffer<uint8_t> trg; - - utility::string_t fname = U("fstream_read_5.txt"); - fill_file_with_lines(fname, "\n", 2); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - VERIFY_ARE_EQUAL(26u, stream.read_to_delim(trg, '\n').get()); - VERIFY_ARE_EQUAL('a', (char)stream.read().get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(26u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - stream.close().get(); - } - - TEST(stream_readline_1) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's one newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - - istream stream(rbuf); - - VERIFY_ARE_EQUAL(26u, stream.read_line(trg).get()); - VERIFY_ARE_EQUAL('A', (char)rbuf.getc().get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(26u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - stream.close().get(); - } - - TEST(stream_readline_1_fail) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's one newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - - istream stream(rbuf); - - trg.close(std::ios_base::out).get(); - - VERIFY_THROWS(stream.read_line(trg).get(), std::runtime_error); - - stream.close().get(); - } - - TEST(stream_readline_2) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's one newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\r\n\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - - istream stream(rbuf); - - VERIFY_IS_FALSE(stream.is_eof()); - VERIFY_ARE_EQUAL(26u, stream.read_line(trg).get()); - VERIFY_IS_FALSE(stream.is_eof()); - VERIFY_ARE_EQUAL(0u, stream.read_line(trg).get()); - VERIFY_IS_FALSE(stream.is_eof()); - VERIFY_ARE_EQUAL('A', (char)rbuf.getc().get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(26u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - stream.close().get(); - } - - TEST(fstream_readline_1) - { - producer_consumer_buffer<uint8_t> trg; - - utility::string_t fname = U("fstream_readline_1.txt"); - fill_file_with_lines(fname, "\n", 2); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - VERIFY_ARE_EQUAL(26u, stream.read_line(trg).get()); - VERIFY_ARE_EQUAL('a', (char)stream.read().get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(26u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - stream.close().get(); - } - - TEST(fstream_readline_2) - { - producer_consumer_buffer<uint8_t> trg; - - utility::string_t fname = U("fstream_readline_2.txt"); - fill_file_with_lines(fname, "\r\n", 2); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - VERIFY_ARE_EQUAL(26u, stream.read_line(trg).get()); - VERIFY_ARE_EQUAL('a', (char)stream.read().get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(26u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - stream.close().get(); - } - - TEST(stream_read_6) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - rbuf.close(std::ios_base::out).get(); - - istream stream(rbuf); - - VERIFY_ARE_EQUAL(52u, stream.read_to_delim(trg, '|').get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(52u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'A', buffer[i + 26]); - } - - stream.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(stream_read_7) - { - producer_consumer_buffer<char> rbuf; - producer_consumer_buffer<uint8_t> trg; - - // There's one delimiter in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz|ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - - istream stream(rbuf); - - VERIFY_ARE_EQUAL(26u, stream.read_to_delim(trg, '|').get()); - VERIFY_ARE_EQUAL('A', (char)rbuf.getc().get()); - - uint8_t buffer[128]; - VERIFY_ARE_EQUAL(26u, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - stream.close().get(); - } - - TEST(stream_read_to_end_1) - { - // Create a really large (200KB) stream and read into a stream buffer. - // It should not take a long time to do this test. - - producer_consumer_buffer<char> rbuf; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - for (int i = 0; i < 4096; ++i) - { - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - } - - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> stream = rbuf; - - streams::stringstreambuf sbuf; - auto& target = sbuf.collection(); - - VERIFY_ARE_EQUAL(len * 4096, stream.read_to_end(sbuf).get()); - VERIFY_ARE_EQUAL(len * 4096, target.size()); - - stream.close().get(); - sbuf.close().get(); - } - - TEST(stream_read_to_end_1_fail) - { - producer_consumer_buffer<char> rbuf; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - for (int i = 0; i < 4096; ++i) - { - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - } - - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> stream = rbuf; - - streams::stringstreambuf sbuf; - sbuf.close(std::ios_base::out).get(); - - VERIFY_THROWS(stream.read_to_end(sbuf).get(), std::runtime_error); - - stream.close().get(); - // This should not throw - sbuf.close().wait(); - } - - TEST(fstream_read_to_end_1) - { - // Create a really large (100KB) stream and read into a stream buffer. - // It should not take a long time to do this test. - - utility::string_t fname = U("fstream_read_to_end_1.txt"); - fill_file(fname, 4096); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - streams::stringstreambuf sbuf; - VERIFY_IS_FALSE(stream.is_eof()); - auto& target = sbuf.collection(); - - VERIFY_ARE_EQUAL(26 * 4096, stream.read_to_end(sbuf).get()); - VERIFY_ARE_EQUAL(26 * 4096, target.size()); - VERIFY_IS_TRUE(stream.is_eof()); - - stream.close().get(); - sbuf.close().get(); - } - - TEST(fstream_read_to_end_2) - { - // Read a file to end with is_eof tests. - utility::string_t fname = U("fstream_read_to_end_2.txt"); - fill_file(fname); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - streams::stringstreambuf sbuf; - int c; - while (c = stream.read().get(), !stream.is_eof()) - sbuf.putc(static_cast<char>(c)).get(); - auto& target = sbuf.collection(); - VERIFY_ARE_EQUAL(26, target.size()); - VERIFY_IS_TRUE(stream.is_eof()); - - stream.close().get(); - sbuf.close().get(); - } - - TEST(fstream_read_to_end_3) - { - // Async Read a file to end with is_eof tests. - utility::string_t fname = U("fstream_read_to_end_3.txt"); - fill_file(fname, 1); - - streams::basic_istream<char> stream = OPEN_R<char>(fname).get().create_istream(); - - streams::stringstreambuf sbuf; - // workaround VC10 's bug. - auto lambda2 = [](int) { return true; }; - auto lambda1 = [sbuf, stream, lambda2](int val) mutable -> pplx::task<bool> { - if (!stream.is_eof()) - return sbuf.putc(static_cast<char>(val)).then(lambda2); - else - return pplx::task_from_result(false); - }; - pplx::details::_do_while([=]() -> pplx::task<bool> { return stream.read().then(lambda1); }).wait(); - - auto& target = sbuf.collection(); - VERIFY_ARE_EQUAL(26, target.size()); - VERIFY_IS_TRUE(stream.is_eof()); - - stream.close().get(); - sbuf.close().get(); - } - - TEST(stream_read_to_delim_flush) - { - producer_consumer_buffer<char> rbuf; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz|ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> stream = rbuf; - - producer_consumer_buffer<char> sbuf; - - char chars[128]; - - VERIFY_ARE_EQUAL(26u, stream.read_to_delim(sbuf, '|').get()); - // The read_to_delim() should have flushed, so we should be getting what's there, - // less than we asked for. - VERIFY_ARE_EQUAL(26u, sbuf.getn(chars, 100).get()); - - stream.close().get(); - sbuf.close().get(); - } - - TEST(stream_read_line_flush) - { - producer_consumer_buffer<char> rbuf; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> stream = rbuf; - - producer_consumer_buffer<char> sbuf; - - char chars[128]; - - VERIFY_ARE_EQUAL(26u, stream.read_line(sbuf).get()); - // The read_line() should have flushed, so we should be getting what's there, - // less than we asked for. - VERIFY_ARE_EQUAL(26u, sbuf.getn(chars, 100).get()); - - stream.close().get(); - sbuf.close().get(); - } - - TEST(stream_read_to_end_flush) - { - producer_consumer_buffer<char> rbuf; - streams::basic_istream<char> stream = rbuf; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - size_t len = strlen(text); - - VERIFY_ARE_EQUAL(len, rbuf.putn_nocopy(text, len).get()); - - rbuf.close(std::ios_base::out).get(); - - producer_consumer_buffer<char> sbuf; - - char chars[128]; - - VERIFY_ARE_EQUAL(len, stream.read_to_end(sbuf).get()); - // The read_to_end() should have flushed, so we should be getting what's there, - // less than we asked for. - VERIFY_ARE_EQUAL(len, sbuf.getn(chars, len * 2).get()); - - stream.close().get(); - sbuf.close().get(); - } - - TEST(istream_extract_string) - { - producer_consumer_buffer<char> rbuf; - const char* text = " abc defgsf "; - - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> is = rbuf; - std::string str1 = is.extract<std::string>().get(); - std::string str2 = is.extract<std::string>().get(); - - VERIFY_ARE_EQUAL(str1, "abc"); - VERIFY_ARE_EQUAL(str2, "defgsf"); - } -#ifdef _WIN32 // On Linux, this becomes the exact copy of istream_extract_string1, hence disabled - TEST(istream_extract_wstring_1) - { - producer_consumer_buffer<char> rbuf; - const char* text = " abc defgsf "; - - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> is = rbuf; - utility::string_t str1 = is.extract<utility::string_t>().get(); - utility::string_t str2 = is.extract<utility::string_t>().get(); - - VERIFY_ARE_EQUAL(str1, L"abc"); - VERIFY_ARE_EQUAL(str2, L"defgsf"); - } - - TEST(istream_extract_wstring_2) // On Linux, this becomes the exact copy of istream_extract_string2, hence disabled - { - producer_consumer_buffer<signed char> rbuf; - const char* text = " abc defgsf "; - - size_t len = strlen(text); - rbuf.putn_nocopy((const signed char*)text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> is = rbuf; - utility::string_t str1 = is.extract<utility::string_t>().get(); - utility::string_t str2 = is.extract<utility::string_t>().get(); - - VERIFY_ARE_EQUAL(str1, L"abc"); - VERIFY_ARE_EQUAL(str2, L"defgsf"); - } - - TEST(istream_extract_wstring_3) - { - producer_consumer_buffer<unsigned char> rbuf; - const char* text = " abc defgsf "; - - size_t len = strlen(text); - rbuf.putn_nocopy((const unsigned char*)text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> is = rbuf; - utility::string_t str1 = is.extract<utility::string_t>().get(); - utility::string_t str2 = is.extract<utility::string_t>().get(); - - VERIFY_ARE_EQUAL(str1, L"abc"); - VERIFY_ARE_EQUAL(str2, L"defgsf"); - } - -#endif - - TEST(istream_extract_int64) - { - producer_consumer_buffer<char> rbuf; - const char* text = "1024 -17134711"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<char> is = rbuf; - int64_t i1 = is.extract<int64_t>().get(); - int64_t i2 = is.extract<int64_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, -17134711); - } - - TEST(istream_extract_uint64) - { - producer_consumer_buffer<char> rbuf; - const char* text = "1024 12000000000"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::istream is(rbuf); - uint64_t i1 = is.extract<uint64_t>().get(); - uint64_t i2 = is.extract<uint64_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, (uint64_t)12000000000); - } -#ifdef _WIN32 - TEST(istream_extract_int64w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"1024 -17134711"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - int64_t i1 = is.extract<int64_t>().get(); - int64_t i2 = is.extract<int64_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, -17134711); - } - - TEST(istream_extract_uint64w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"1024 12000000000"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - uint64_t i1 = is.extract<uint64_t>().get(); - uint64_t i2 = is.extract<uint64_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, (uint64_t)12000000000); - } -#endif - - TEST(istream_extract_int32) - { - producer_consumer_buffer<char> rbuf; - const char* text = "1024 -17134711 12000000000"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::istream is(rbuf); - int32_t i1 = is.extract<int32_t>().get(); - int32_t i2 = is.extract<int32_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, -17134711); - VERIFY_THROWS(is.extract<int32_t>().get(), std::range_error); - } - - TEST(istream_extract_uint32) - { - producer_consumer_buffer<char> rbuf; - const char* text = "1024 3000000000 12000000000"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::istream is(rbuf); - uint32_t i1 = is.extract<uint32_t>().get(); - uint32_t i2 = is.extract<uint32_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024u); - VERIFY_ARE_EQUAL(i2, (uint32_t)3000000000); - VERIFY_THROWS(is.extract<uint32_t>().get(), std::range_error); - } -#ifdef _WIN32 - TEST(istream_extract_int32w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"1024 -17134711 12000000000"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - int32_t i1 = is.extract<int32_t>().get(); - int32_t i2 = is.extract<int32_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, -17134711); - VERIFY_THROWS(is.extract<int32_t>().get(), std::range_error); - } - - TEST(istream_extract_uint32w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"1024 3000000000 12000000000"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - uint32_t i1 = is.extract<uint32_t>().get(); - uint32_t i2 = is.extract<uint32_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024u); - VERIFY_ARE_EQUAL(i2, 3000000000u); - VERIFY_THROWS(is.extract<uint32_t>().get(), std::range_error); - } -#endif - - TEST(istream_extract_int16) - { - producer_consumer_buffer<char> rbuf; - const char* text = "1024 -4711 100000"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::istream is(rbuf); - int16_t i1 = is.extract<int16_t>().get(); - int16_t i2 = is.extract<int16_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, -4711); - VERIFY_THROWS(is.extract<int16_t>().get(), std::range_error); - } - - TEST(istream_extract_uint16) - { - producer_consumer_buffer<char> rbuf; - const char* text = "1024 50000 100000"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::istream is(rbuf); - uint16_t i1 = is.extract<uint16_t>().get(); - uint16_t i2 = is.extract<uint16_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, 50000); - VERIFY_THROWS(is.extract<uint16_t>().get(), std::range_error); - } - -#ifdef _WIN32 - TEST(istream_extract_int16w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"1024 -4711 100000"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - int16_t i1 = is.extract<int16_t>().get(); - int16_t i2 = is.extract<int16_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, -4711); - VERIFY_THROWS(is.extract<int16_t>().get(), std::range_error); - } - - TEST(istream_extract_uint16w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"1024 50000 100000"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - uint16_t i1 = is.extract<uint16_t>().get(); - uint16_t i2 = is.extract<uint16_t>().get(); - - VERIFY_ARE_EQUAL(i1, 1024); - VERIFY_ARE_EQUAL(i2, 50000); - VERIFY_THROWS(is.extract<uint16_t>().get(), std::range_error); - } -#endif - - TEST(istream_extract_int8) - { - producer_consumer_buffer<char> rbuf; - const char* text = "0 -125 512"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<unsigned char> is(rbuf); - int8_t i1 = is.extract<int8_t>().get(); - int8_t i2 = is.extract<int8_t>().get(); - - VERIFY_ARE_EQUAL(i1, '0'); - VERIFY_ARE_EQUAL(i2, '-'); - } - - TEST(istream_extract_uint8) - { - producer_consumer_buffer<char> rbuf; - const char* text = "0 150 512"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::basic_istream<unsigned char> is(rbuf); - uint8_t i1 = is.extract<uint8_t>().get(); - uint8_t i2 = is.extract<uint8_t>().get(); - - VERIFY_ARE_EQUAL(i1, '0'); - VERIFY_ARE_EQUAL(i2, '1'); - } - -#ifdef _WIN32 - TEST(istream_extract_int8w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"0 -125 512"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - int8_t i1 = is.extract<int8_t>().get(); - int8_t i2 = is.extract<int8_t>().get(); - - VERIFY_ARE_EQUAL(i1, '0'); - VERIFY_ARE_EQUAL(i2, '-'); - } - - TEST(istream_extract_uint8w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L"0 150 512"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - uint8_t i1 = is.extract<uint8_t>().get(); - uint8_t i2 = is.extract<uint8_t>().get(); - - VERIFY_ARE_EQUAL(i1, '0'); - VERIFY_ARE_EQUAL(i2, '1'); - } -#endif - - TEST(istream_extract_bool) - { - producer_consumer_buffer<char> rbuf; - const char* text = " true false NOT_OK"; - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::istream is(rbuf); - bool i1 = is.extract<bool>().get(); - bool i2 = is.extract<bool>().get(); - - VERIFY_IS_TRUE(i1); - VERIFY_IS_FALSE(i2); - VERIFY_THROWS(is.extract<bool>().get(), std::runtime_error); - } - - TEST(istream_extract_bool_from_number) - { - producer_consumer_buffer<char> rbuf; - const char* text = " 1 0 NOT_OK"; - - size_t len = strlen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::istream is(rbuf); - bool i1 = is.extract<bool>().get(); - bool i2 = is.extract<bool>().get(); - - VERIFY_IS_TRUE(i1); - VERIFY_IS_FALSE(i2); - // Make sure parsing consumes just the right amount of characters. - VERIFY_ARE_EQUAL(7u, rbuf.in_avail()); - VERIFY_THROWS(is.extract<bool>().get(), std::runtime_error); - } - -#ifdef _WIN32 - TEST(istream_extract_bool_w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L" true false NOT_OK"; - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - bool i1 = is.extract<bool>().get(); - bool i2 = is.extract<bool>().get(); - - VERIFY_IS_TRUE(i1); - VERIFY_IS_FALSE(i2); - VERIFY_THROWS(is.extract<bool>().get(), std::runtime_error); - } - - TEST(istream_extract_bool_from_number_w) - { - producer_consumer_buffer<wchar_t> rbuf; - const wchar_t* text = L" 1 0 NOT_OK"; - - size_t len = wcslen(text); - rbuf.putn_nocopy(text, len).wait(); - rbuf.close(std::ios_base::out).get(); - - streams::wistream is(rbuf); - bool i1 = is.extract<bool>().get(); - bool i2 = is.extract<bool>().get(); - - VERIFY_IS_TRUE(i1); - VERIFY_IS_FALSE(i2); - // Make sure parsing consumes just the right amount of characters. - VERIFY_ARE_EQUAL(7u, rbuf.in_avail()); - VERIFY_THROWS(is.extract<bool>().get(), std::runtime_error); - } - -#endif - - template<typename _CharType, typename _LongType> - void istream_extract_long_impl(streambuf<_CharType> buf) - { - basic_istream<_CharType> is(buf); - const _LongType v1 = is.template extract<_LongType>().get(); - const _LongType v2 = is.template extract<_LongType>().get(); - - VERIFY_ARE_EQUAL(123, v1); - VERIFY_ARE_EQUAL(-567, v2); - VERIFY_THROWS(is.template extract<_LongType>().get(), std::runtime_error); - } - - TEST(istream_extract_long) - { - istream_extract_long_impl<char, long>( - container_buffer<std::string>("123 -567 120000000000000000000000000000000000000000000000")); -#ifdef _WIN32 - istream_extract_long_impl<wchar_t, long>(container_buffer<std::wstring>(L"123 -567 12000000000")); -#endif - } - - template<typename _CharType, typename _LongType> - void istream_extract_unsigned_long_impl(streambuf<_CharType> buf) - { - basic_istream<_CharType> is(buf); - const _LongType v1 = is.template extract<_LongType>().get(); - const _LongType v2 = is.template extract<_LongType>().get(); - - VERIFY_ARE_EQUAL(876, v1); - VERIFY_ARE_EQUAL(3, v2); - VERIFY_THROWS(is.template extract<_LongType>().get(), std::runtime_error); - } - - TEST(istream_extract_unsigned_long) - { - istream_extract_unsigned_long_impl<char, unsigned long>(container_buffer<std::string>("876 3 -44")); -#ifdef _WIN32 - istream_extract_unsigned_long_impl<wchar_t, unsigned long>(container_buffer<std::wstring>(L"876 3 -44")); -#endif - } - - TEST(istream_extract_long_long) - { - istream_extract_long_impl<char, long long>(container_buffer<std::string>("123 -567 92233720368547758078")); -#ifdef _WIN32 - istream_extract_long_impl<wchar_t, long long>(container_buffer<std::wstring>(L"123 -567 92233720368547758078")); -#endif - } - - TEST(istream_extract_unsigned_long_long) - { - istream_extract_unsigned_long_impl<char, unsigned long long>(container_buffer<std::string>("876 3 -44")); -#ifdef _WIN32 - istream_extract_unsigned_long_impl<wchar_t, unsigned long long>(container_buffer<std::wstring>(L"876 3 -44")); -#endif - } - - template<typename T> - void compare_floating(T expected, T actual, T relativeDiff) - { - // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - if (expected != actual) - { - const auto diff = fabs(expected - actual); - const auto absExpected = fabs(expected); - const auto absActual = fabs(actual); - const auto largest = absExpected > absActual ? absExpected : absActual; - if (diff > largest * relativeDiff) - { - VERIFY_IS_TRUE(false); - } - } - } - void compare_double(double expected, double actual) { compare_floating(expected, actual, DBL_EPSILON); } - void compare_float(float expected, float actual) { compare_floating(expected, actual, FLT_EPSILON); } - - TEST(extract_floating_point) - { - std::string test_string; - test_string.append(" 9.81E05 3.14"); - test_string.append(" 2.71.5"); // two numbers merged after comma - test_string.append(" 6E+4.5"); // two numbers merged in exponent - test_string.append(" 6E-4.5"); // two numbers merged in exponent - test_string.append(" 3.14 -10 +42.0 -1234.567 .01 +0 -0"); -#ifndef __APPLE__ - test_string.append(" 12345678901234567890123456789012345678901234567890"); // a big number -#endif - test_string.append(" 9.81E05 6.0221413e+23 1.6e-14"); // numbers with exponent - test_string.append(" 6."); // a number ending with a dot - - std::stringstream std_istream; - std_istream << test_string; - - producer_consumer_buffer<uint8_t> buff, bufd; - auto ostream_float = buff.create_ostream(); - auto istream_float = buff.create_istream(); - auto ostream_double = bufd.create_ostream(); - auto istream_double = bufd.create_istream(); - - ostream_float.print(test_string); - ostream_double.print(test_string); - ostream_float.close().wait(); - ostream_double.close().wait(); - - do - { - double expected = 0; - std_istream >> expected; - - const auto actual = istream_double.extract<double>().get(); - compare_double(expected, actual); - - if (actual <= (std::numeric_limits<float>::max)()) - compare_float(float(expected), istream_float.extract<float>().get()); - else - VERIFY_THROWS(istream_float.extract<float>().get(), std::exception); - - // Checking positive and negative zero's by dividing 1 with it. They should result in positive and negative - // infinity. - if (expected == 0) VERIFY_ARE_EQUAL(1 / expected, 1 / actual); - } while (!std_istream.eof()); - } - - TEST(extract_floating_point_with_exceptions) - { - std::vector<std::pair<std::string, std::string>> tests; - tests.push_back(std::pair<std::string, std::string>("a", "Invalid character 'a'")); - tests.push_back(std::pair<std::string, std::string>("x", "Invalid character 'x'")); - tests.push_back(std::pair<std::string, std::string>("e", "Invalid character 'e'")); - tests.push_back(std::pair<std::string, std::string>("E", "Invalid character 'E'")); - tests.push_back(std::pair<std::string, std::string>("6.022e+t", "Invalid character 't' in exponent")); - tests.push_back(std::pair<std::string, std::string>("9.81e-.", "Invalid character '.' in exponent")); - tests.push_back(std::pair<std::string, std::string>("9.81e-", "Incomplete exponent")); - tests.push_back(std::pair<std::string, std::string>("1.2e+", "Incomplete exponent")); - tests.push_back(std::pair<std::string, std::string>("10E+-23", "The exponent sign already set")); - tests.push_back(std::pair<std::string, std::string>("15E-+45", "The exponent sign already set")); - tests.push_back(std::pair<std::string, std::string>("5.34e", "Incomplete exponent")); - tests.push_back(std::pair<std::string, std::string>("2E+308", "The value is too big")); - tests.push_back(std::pair<std::string, std::string>("-2E+308", "The value is too big")); - tests.push_back(std::pair<std::string, std::string>("1E-324", "The value is too small")); - tests.push_back(std::pair<std::string, std::string>("-1E-324", "The value is too small")); - - for (auto iter = tests.begin(); iter != tests.end(); iter++) - { - std::stringstream std_istream; - std_istream << iter->first; - VERIFY_IS_TRUE(std_istream.good()); - double x; - std_istream >> x; - VERIFY_IS_FALSE(std_istream.good()); - - producer_consumer_buffer<uint8_t> buf; - auto stream = buf.create_ostream(); - auto istream_double = buf.create_istream(); - - stream.print(iter->first); - stream.close().wait(); - - try - { - istream_double.extract<double>().get(); - VERIFY_IS_TRUE(false, "No exception has been thrown"); - } - catch (const std::exception& exc) - { - VERIFY_ARE_EQUAL(std::string(exc.what()), iter->second); - } - catch (...) - { - VERIFY_IS_TRUE(false, "A wrong exception has been thrown"); - } - } - } - - TEST(streambuf_read_delim) - { - producer_consumer_buffer<uint8_t> rbuf; - std::string s("Hello World"); // there are 2 spaces here - - streams::stringstreambuf data; - - streams::istream is(rbuf); - - auto t = is.read_to_delim(data, ' ') - .then([&data, is](size_t size) -> pplx::task<size_t> { - std::string r("Hello"); - VERIFY_ARE_EQUAL(size, r.size()); - VERIFY_IS_FALSE(is.is_eof()); - - auto& s2 = data.collection(); - VERIFY_ARE_EQUAL(s2, r); - return is.read_to_delim(data, ' '); - }) - .then([&data, is](size_t size) -> pplx::task<size_t> { - VERIFY_ARE_EQUAL(size, 0); - VERIFY_IS_FALSE(is.is_eof()); - return is.read_to_delim(data, ' '); - }) - .then([&data, is](size_t size) -> void { - VERIFY_ARE_EQUAL(size, 5); - VERIFY_IS_TRUE(is.is_eof()); - }); - rbuf.putn_nocopy((uint8_t*)s.data(), s.size()).wait(); - rbuf.close(std::ios_base::out).get(); - t.wait(); - } - - TEST(uninitialized_stream) - { - streams::basic_ostream<uint8_t> test_ostream; - streams::basic_istream<uint8_t> test_istream; - - VERIFY_IS_FALSE(test_ostream.is_valid()); - VERIFY_IS_FALSE(test_istream.is_valid()); - - VERIFY_THROWS(test_istream.read(), std::logic_error); - VERIFY_THROWS(test_ostream.flush(), std::logic_error); - - test_istream.close().wait(); - test_ostream.close().wait(); - } - - TEST(uninitialized_streambuf) - { - streams::streambuf<uint8_t> strbuf; - - // The bool operator shall not throw - VERIFY_IS_TRUE(!strbuf); - - // All operations should throw - uint8_t* ptr = nullptr; - size_t count = 0; - - VERIFY_THROWS(strbuf.acquire(ptr, count), std::invalid_argument); - VERIFY_THROWS(strbuf.release(ptr, count), std::invalid_argument); - - VERIFY_THROWS(strbuf.alloc(count), std::invalid_argument); - VERIFY_THROWS(strbuf.commit(count), std::invalid_argument); - - VERIFY_THROWS(strbuf.can_read(), std::invalid_argument); - VERIFY_THROWS(strbuf.can_write(), std::invalid_argument); - VERIFY_THROWS(strbuf.can_seek(), std::invalid_argument); - - VERIFY_THROWS(strbuf.is_eof(), std::invalid_argument); - VERIFY_THROWS(strbuf.is_open(), std::invalid_argument); - - VERIFY_THROWS(strbuf.in_avail(), std::invalid_argument); - VERIFY_THROWS(strbuf.get_base(), std::invalid_argument); - - VERIFY_THROWS(strbuf.putc('a').get(), std::invalid_argument); - VERIFY_THROWS(strbuf.putn_nocopy(ptr, count).get(), std::invalid_argument); - VERIFY_THROWS(strbuf.sync().get(), std::invalid_argument); - - VERIFY_THROWS(strbuf.getc().get(), std::invalid_argument); - VERIFY_THROWS(strbuf.ungetc().get(), std::invalid_argument); - VERIFY_THROWS(strbuf.bumpc().get(), std::invalid_argument); - VERIFY_THROWS(strbuf.nextc().get(), std::invalid_argument); - VERIFY_THROWS(strbuf.getn(ptr, count).get(), std::invalid_argument); - - VERIFY_THROWS(strbuf.close().get(), std::invalid_argument); - - // The destructor shall not throw - } - - TEST(create_istream_from_output_only) - { - container_buffer<std::string> sourceBuf; - VERIFY_THROWS(sourceBuf.create_istream(), std::runtime_error); - } - - TEST(extract_close_with_exception) - { - container_buffer<std::string> sourceBuf(std::ios::in); - auto inStream = sourceBuf.create_istream(); - inStream.close(std::make_exception_ptr(std::invalid_argument("test exception"))).wait(); - auto extractTask = inStream.extract<std::string>(); - VERIFY_THROWS(extractTask.get(), std::invalid_argument); - } - - TEST(streambuf_close_with_exception_read) - { - container_buffer<std::string> sourceBuf("test data string"); - sourceBuf.close(std::ios::in, std::make_exception_ptr(std::invalid_argument("custom exception"))); - - const size_t size = 4; - char targetBuf[size]; - auto t = sourceBuf.getn(targetBuf, size); - VERIFY_THROWS(t.get(), std::invalid_argument); - } - - TEST(stream_close_with_exception_read) - { - container_buffer<std::string> sourceBuf("test data string"); - auto inStream = sourceBuf.create_istream(); - inStream.close(std::make_exception_ptr(std::invalid_argument("custom exception"))); - - container_buffer<std::string> targetBuf; - auto t1 = inStream.read(targetBuf, 4); - VERIFY_THROWS(t1.get(), std::invalid_argument); - VERIFY_THROWS(inStream.streambuf().sbumpc(), std::invalid_argument); - VERIFY_THROWS(inStream.streambuf().sgetc(), std::invalid_argument); - } - - TEST(istream_input_after_close) - { - container_buffer<std::string> sourceBuf("test data"); - auto inStream = sourceBuf.create_istream(); - inStream.close().wait(); - - container_buffer<std::string> targetBuf; - VERIFY_THROWS(inStream.peek().get(), std::runtime_error); - VERIFY_THROWS(inStream.read(targetBuf, 1).get(), std::runtime_error); - VERIFY_THROWS(inStream.read_line(targetBuf).get(), std::runtime_error); - VERIFY_THROWS(inStream.read_to_delim(targetBuf, '-').get(), std::runtime_error); - VERIFY_THROWS(inStream.read_to_end(targetBuf).get(), std::runtime_error); - VERIFY_THROWS(inStream.seek(0), std::runtime_error); - VERIFY_THROWS(inStream.seek(1, std::ios::beg), std::runtime_error); - VERIFY_THROWS(inStream.tell(), std::runtime_error); - VERIFY_THROWS(inStream.extract<std::string>().get(), std::runtime_error); - } - - TEST(extract_from_empty_stream) - { - container_buffer<std::string> sourceBuf(std::ios::in); - auto inStream = sourceBuf.create_istream(); - - VERIFY_THROWS(inStream.extract<int64_t>().get(), std::range_error); - VERIFY_THROWS(inStream.extract<char>().get(), std::runtime_error); - VERIFY_THROWS(inStream.extract<unsigned char>().get(), std::runtime_error); - VERIFY_THROWS(inStream.extract<signed char>().get(), std::runtime_error); - VERIFY_THROWS(inStream.extract<bool>().get(), std::runtime_error); - - const std::string strValue = inStream.extract<std::string>().get(); - VERIFY_ARE_EQUAL("", strValue); -#ifdef _WIN32 - const std::wstring wstrValue = inStream.extract<std::wstring>().get(); - VERIFY_ARE_EQUAL(L"", wstrValue); -#endif - } - - TEST(seek_after_eof) - { - container_buffer<std::string> sourceBuf(std::ios::in); - VERIFY_ARE_EQUAL(basic_istream<char>::traits::eof(), sourceBuf.seekoff(1, std::ios::cur, std::ios::in)); - } - -} // SUITE(istream_tests) - -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/memstream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/memstream_tests.cpp @@ -1,2535 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for async memory stream buffer operations. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" -#if defined(__cplusplus_winrt) -#include <wrl.h> -#endif -#ifdef _WIN32 - -#include <Windows.h> -#endif - -namespace tests -{ -namespace functional -{ -namespace streams -{ -using namespace ::pplx; -using namespace utility; -using namespace concurrency::streams; - -template<class StreamBufferType> -void streambuf_putc(StreamBufferType& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - - std::basic_string<typename StreamBufferType::char_type> s; - s.push_back((typename StreamBufferType::char_type)0); - s.push_back((typename StreamBufferType::char_type)1); - s.push_back((typename StreamBufferType::char_type)2); - s.push_back((typename StreamBufferType::char_type)3); - - // Verify putc synchronously - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[0], wbuf.putc(s[0]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[1], wbuf.putc(s[1]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[2], wbuf.putc(s[2]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[3], wbuf.putc(s[3]).get()); - - VERIFY_ARE_EQUAL(s.size(), wbuf.in_avail()); - - // Verify putc async - size_t count = 10; - auto seg2 = [&count](typename StreamBufferType::int_type) { return (--count > 0); }; - auto seg1 = [&s, &wbuf, seg2]() { return wbuf.putc(s[0]).then(seg2); }; - pplx::details::_do_while(seg1).wait(); - - VERIFY_ARE_EQUAL(s.size() + 10, wbuf.in_avail()); - - VERIFY_IS_TRUE(wbuf.close().get()); - VERIFY_IS_FALSE(wbuf.can_write()); - - // verify putc after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), wbuf.putc(s[0]).get()); -} - -template<class CharType> -void streambuf_putc(concurrency::streams::rawptr_buffer<CharType>& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - typedef concurrency::streams::rawptr_buffer<CharType> StreamBufferType; - - std::basic_string<CharType> s; - s.push_back((CharType)0); - s.push_back((CharType)1); - s.push_back((CharType)2); - s.push_back((CharType)3); - - // Verify putc synchronously - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[0], wbuf.putc(s[0]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[1], wbuf.putc(s[1]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[2], wbuf.putc(s[2]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[3], wbuf.putc(s[3]).get()); - - VERIFY_ARE_EQUAL(s.size(), wbuf.block().size()); - - // Verify putc async - size_t count = 10; - auto seg2 = [&count](typename StreamBufferType::int_type) { return (--count > 0); }; - auto seg1 = [&s, &wbuf, seg2]() { return wbuf.putc(s[0]).then(seg2); }; - pplx::details::_do_while(seg1).wait(); - - VERIFY_ARE_EQUAL(s.size() + 10, wbuf.block().size()); - - VERIFY_IS_TRUE(wbuf.close().get()); - VERIFY_IS_FALSE(wbuf.can_write()); - - // verify putc after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), wbuf.putc(s[0]).get()); -} - -template<class CollectionType> -void streambuf_putc(concurrency::streams::container_buffer<CollectionType>& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - typedef concurrency::streams::container_buffer<CollectionType> StreamBufferType; - typedef typename concurrency::streams::container_buffer<CollectionType>::char_type CharType; - - std::basic_string<CharType> s; - s.push_back((CharType)0); - s.push_back((CharType)1); - s.push_back((CharType)2); - s.push_back((CharType)3); - - // Verify putc synchronously - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[0], wbuf.putc(s[0]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[1], wbuf.putc(s[1]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[2], wbuf.putc(s[2]).get()); - VERIFY_ARE_EQUAL((typename StreamBufferType::int_type)s[3], wbuf.putc(s[3]).get()); - - VERIFY_ARE_EQUAL(s.size(), wbuf.collection().size()); - - // Verify putc async - size_t count = 10; - auto seg2 = [&count](typename StreamBufferType::int_type) { return (--count > 0); }; - auto seg1 = [&s, &wbuf, seg2]() { return wbuf.putc(s[0]).then(seg2); }; - pplx::details::_do_while(seg1).wait(); - - VERIFY_ARE_EQUAL(s.size() + 10, wbuf.collection().size()); - - wbuf.close().get(); - VERIFY_IS_FALSE(wbuf.can_write()); - - // verify putc after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), wbuf.putc(s[0]).get()); -} - -template<class StreamBufferType> -void streambuf_putn(StreamBufferType& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - - std::basic_string<typename StreamBufferType::char_type> s; - s.push_back((typename StreamBufferType::char_type)0); - s.push_back((typename StreamBufferType::char_type)1); - s.push_back((typename StreamBufferType::char_type)2); - s.push_back((typename StreamBufferType::char_type)3); - - VERIFY_ARE_EQUAL(s.size(), wbuf.putn_nocopy(s.data(), s.size()).get()); - VERIFY_ARE_EQUAL(s.size() * 1, wbuf.in_avail()); - - VERIFY_ARE_EQUAL(s.size(), wbuf.putn_nocopy(s.data(), s.size()).get()); - VERIFY_ARE_EQUAL(s.size() * 2, wbuf.in_avail()); - - int count = 10; - auto seg2 = [&count](size_t) { return (--count > 0); }; - auto seg1 = [&s, &wbuf, seg2]() { return wbuf.putn_nocopy(s.data(), s.size()).then(seg2); }; - pplx::details::_do_while(seg1).wait(); - VERIFY_ARE_EQUAL(s.size() * 12, wbuf.in_avail()); - - wbuf.close().get(); - VERIFY_IS_FALSE(wbuf.can_write()); - - // verify putn after close - VERIFY_ARE_EQUAL(0, wbuf.putn_nocopy(s.data(), s.size()).get()); -} - -template<class CharType> -void streambuf_putn(concurrency::streams::rawptr_buffer<CharType>& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - - typedef concurrency::streams::rawptr_buffer<CharType> StreamBufferType; - - std::basic_string<CharType> s; - s.push_back((CharType)0); - s.push_back((CharType)1); - s.push_back((CharType)2); - s.push_back((CharType)3); - - VERIFY_ARE_EQUAL(s.size(), wbuf.putn_nocopy(s.data(), s.size()).get()); - - VERIFY_ARE_EQUAL(s.size(), wbuf.putn_nocopy(s.data(), s.size()).get()); - - int count = 10; - auto seg2 = [&count](size_t) { return (--count > 0); }; - auto seg1 = [&s, &wbuf, seg2]() { return wbuf.putn_nocopy(s.data(), s.size()).then(seg2); }; - pplx::details::_do_while(seg1).wait(); - - wbuf.close().get(); - VERIFY_IS_FALSE(wbuf.can_write()); - - // verify putn after close - VERIFY_ARE_EQUAL(0, wbuf.putn_nocopy(s.data(), s.size()).get()); -} - -template<class CollectionType> -void streambuf_putn(concurrency::streams::container_buffer<CollectionType>& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - typedef concurrency::streams::container_buffer<CollectionType> StreamBufferType; - typedef typename concurrency::streams::container_buffer<CollectionType>::char_type CharType; - - std::basic_string<CharType> s; - s.push_back((CharType)0); - s.push_back((CharType)1); - s.push_back((CharType)2); - s.push_back((CharType)3); - - VERIFY_ARE_EQUAL(s.size(), wbuf.putn_nocopy(s.data(), s.size()).get()); - - VERIFY_ARE_EQUAL(s.size(), wbuf.putn_nocopy(s.data(), s.size()).get()); - - int count = 10; - auto seg2 = [&count](size_t) { return (--count > 0); }; - auto seg1 = [&s, &wbuf, seg2]() { return wbuf.putn_nocopy(s.data(), s.size()).then(seg2); }; - pplx::details::_do_while(seg1).wait(); - - wbuf.close().get(); - VERIFY_IS_FALSE(wbuf.can_write()); - - // verify putn_nocopy after close - VERIFY_ARE_EQUAL(0, wbuf.putn_nocopy(s.data(), s.size()).get()); -} - -template<class StreamBufferType> -void streambuf_alloc_commit(StreamBufferType& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - - VERIFY_ARE_EQUAL(0, wbuf.in_avail()); - - size_t allocSize = 10; - size_t commitSize = 2; - - for (size_t i = 0; i < allocSize / commitSize; i++) - { - // Allocate space for 10 chars - auto data = wbuf.alloc(allocSize); - - VERIFY_IS_TRUE(data != nullptr); - - // commit 2 - wbuf.commit(commitSize); - - VERIFY_ARE_EQUAL((i + 1) * commitSize, wbuf.in_avail()); - } - - VERIFY_ARE_EQUAL(allocSize, wbuf.in_avail()); - - wbuf.close().get(); - VERIFY_IS_FALSE(wbuf.can_write()); -} - -template<class CollectionType> -void streambuf_alloc_commit(concurrency::streams::container_buffer<CollectionType>& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - - VERIFY_ARE_EQUAL(0, wbuf.collection().size()); - - size_t allocSize = 10; - size_t commitSize = 2; - - for (size_t i = 0; i < allocSize / commitSize; i++) - { - // Allocate space for 10 chars - auto data = wbuf.alloc(allocSize); - - VERIFY_IS_TRUE(data != nullptr); - - // commit 2 - wbuf.commit(commitSize); - - VERIFY_IS_TRUE((i + 1) * commitSize <= wbuf.collection().size()); - } - - VERIFY_IS_TRUE(allocSize <= wbuf.collection().size()); - - wbuf.close().get(); - VERIFY_IS_FALSE(wbuf.can_write()); -} - -template<class CharType> -void streambuf_alloc_commit(concurrency::streams::rawptr_buffer<CharType>& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - - VERIFY_ARE_EQUAL(0, wbuf.block().size()); - - size_t allocSize = 10; - size_t commitSize = 2; - - for (size_t i = 0; i < allocSize / commitSize; i++) - { - // Allocate space for 10 chars - auto data = wbuf.alloc(allocSize); - - VERIFY_IS_TRUE(data != nullptr); - - // commit 2 - wbuf.commit(commitSize); - - VERIFY_IS_TRUE((i + 1) * commitSize <= wbuf.block().size()); - } - - VERIFY_IS_TRUE(allocSize <= wbuf.block().size()); - - VERIFY_IS_TRUE(wbuf.close().get()); - VERIFY_IS_FALSE(wbuf.can_write()); -} -template<class StreamBufferType> -void streambuf_seek_write(StreamBufferType& wbuf) -{ - VERIFY_IS_TRUE(wbuf.can_write()); - VERIFY_IS_TRUE(wbuf.can_seek()); - - auto beg = wbuf.seekoff(0, std::ios_base::beg, std::ios_base::out); - auto cur = wbuf.seekoff(0, std::ios_base::cur, std::ios_base::out); - - // current should be at the begining - VERIFY_ARE_EQUAL(beg, cur); - - auto end = wbuf.seekoff(0, std::ios_base::end, std::ios_base::out); - VERIFY_ARE_EQUAL(end, wbuf.seekpos(end, std::ios_base::out)); - - wbuf.close().get(); - VERIFY_IS_FALSE(wbuf.can_write()); - VERIFY_IS_FALSE(wbuf.can_seek()); -} - -template<class StreamBufferType> -void streambuf_getc(StreamBufferType& rbuf, typename StreamBufferType::char_type contents) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - - auto c = rbuf.getc().get(); - - VERIFY_ARE_EQUAL(c, contents); - - // Calling getc again should return the same character (getc do not advance read head) - VERIFY_ARE_EQUAL(c, rbuf.getc().get()); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); - - // getc should return eof after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), rbuf.getc().get()); -} - -template<class StreamBufferType> -void streambuf_sgetc(StreamBufferType& rbuf, typename StreamBufferType::char_type contents) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - - auto c = rbuf.sgetc(); - - VERIFY_ARE_EQUAL(c, contents); - - // Calling getc again should return the same character (getc do not advance read head) - VERIFY_ARE_EQUAL(c, rbuf.sgetc()); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); - - // sgetc should return eof after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), rbuf.sgetc()); -} - -template<class StreamBufferType> -void streambuf_bumpc(StreamBufferType& rbuf, const std::vector<typename StreamBufferType::char_type>& contents) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - - auto c = rbuf.bumpc().get(); - - VERIFY_ARE_EQUAL(c, contents[0]); - - // Calling bumpc again should return the next character - // Read till eof - auto d = rbuf.bumpc().get(); - - size_t index = 1; - - while (d != StreamBufferType::traits::eof()) - { - VERIFY_ARE_EQUAL(d, contents[index]); - d = rbuf.bumpc().get(); - index++; - } - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); - - // operation should return eof after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), rbuf.bumpc().get()); -} - -template<class StreamBufferType> -void streambuf_sbumpc(StreamBufferType& rbuf, const std::vector<typename StreamBufferType::char_type>& contents) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - - auto c = rbuf.sbumpc(); - - VERIFY_ARE_EQUAL(c, contents[0]); - - // Calling sbumpc again should return the next character - // Read till eof - auto d = rbuf.sbumpc(); - - size_t index = 1; - - while (d != StreamBufferType::traits::eof()) - { - VERIFY_ARE_EQUAL(d, contents[index]); - d = rbuf.sbumpc(); - index++; - } - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); - - // operation should return eof after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), rbuf.sbumpc()); -} - -template<class StreamBufferType> -void streambuf_nextc(StreamBufferType& rbuf, const std::vector<typename StreamBufferType::char_type>& contents) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - - auto c = rbuf.nextc().get(); - - VERIFY_ARE_EQUAL(c, contents[1]); - - // Calling getc should return the same contents as before. - VERIFY_ARE_EQUAL(c, rbuf.getc().get()); - - size_t index = 1; - - while (c != StreamBufferType::traits::eof()) - { - VERIFY_ARE_EQUAL(c, contents[index]); - c = rbuf.nextc().get(); - index++; - } - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); - - // operation should return eof after close - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), rbuf.nextc().get()); -} - -template<class StreamBufferType> -void streambuf_ungetc(StreamBufferType& rbuf, const std::vector<typename StreamBufferType::char_type>& contents) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - - // ungetc from the begining should return eof - VERIFY_ARE_EQUAL(StreamBufferType::traits::eof(), rbuf.ungetc().get()); - - VERIFY_ARE_EQUAL(contents[0], rbuf.bumpc().get()); - VERIFY_ARE_EQUAL(contents[1], rbuf.getc().get()); - - auto c = rbuf.ungetc().get(); - - // ungetc could be unsupported! - if (c != StreamBufferType::traits::eof()) - { - VERIFY_ARE_EQUAL(contents[0], c); - } - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); -} - -template<class StreamBufferType> -void streambuf_getn(StreamBufferType& rbuf, const std::vector<typename StreamBufferType::char_type>& contents) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - VERIFY_IS_FALSE(rbuf.can_write()); - - auto ptr = new typename StreamBufferType::char_type[contents.size()]; - VERIFY_ARE_EQUAL(contents.size(), rbuf.getn(ptr, contents.size()).get()); - - // We shouldn't be able to read any more - VERIFY_ARE_EQUAL(0, rbuf.getn(ptr, contents.size()).get()); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); - - // We shouldn't be able to read any more - VERIFY_ARE_EQUAL(0, rbuf.getn(ptr, contents.size()).get()); - - delete[] ptr; -} - -template<class StreamBufferType> -void streambuf_acquire_release(StreamBufferType& rbuf, const std::vector<typename StreamBufferType::char_type>&) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - - typename StreamBufferType::char_type* ptr = nullptr; - size_t size = 0; - rbuf.acquire(ptr, size); - - if (ptr != nullptr) - { - VERIFY_IS_TRUE(size > 0); - rbuf.release(ptr, size - 1); - - rbuf.acquire(ptr, size); - VERIFY_IS_TRUE(size > 0); - rbuf.release(ptr, 0); - - rbuf.acquire(ptr, size); - VERIFY_IS_TRUE(size > 0); - rbuf.release(ptr, size); - } - else - { - // This shouldn't crash - rbuf.release(ptr, size); - } - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); -} - -template<class StreamBufferType> -void streambuf_seek_read(StreamBufferType& rbuf) -{ - VERIFY_IS_TRUE(rbuf.can_read()); - VERIFY_IS_TRUE(rbuf.can_seek()); - - auto beg = rbuf.seekoff(0, std::ios_base::beg, std::ios_base::in); - auto cur = rbuf.seekoff(0, std::ios_base::cur, std::ios_base::in); - - // current should be at the begining - VERIFY_ARE_EQUAL(beg, cur); - - auto end = rbuf.seekoff(0, std::ios_base::end, std::ios_base::in); - VERIFY_ARE_EQUAL(end, rbuf.seekpos(end, std::ios_base::in)); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.can_read()); - VERIFY_IS_FALSE(rbuf.can_seek()); -} - -template<class StreamBufferType> -void streambuf_putn_getn(StreamBufferType& rwbuf) -{ - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - VERIFY_IS_FALSE(rwbuf.is_eof()); - std::basic_string<typename StreamBufferType::char_type> s; - s.push_back((typename StreamBufferType::char_type)0); - s.push_back((typename StreamBufferType::char_type)1); - s.push_back((typename StreamBufferType::char_type)2); - s.push_back((typename StreamBufferType::char_type)3); - - typename StreamBufferType::char_type ptr[4]; - - auto readTask = pplx::create_task([&s, &ptr, &rwbuf]() { - VERIFY_ARE_EQUAL(rwbuf.getn(ptr, 4).get(), 4); - - for (size_t i = 0; i < 4; i++) - { - VERIFY_ARE_EQUAL(s[i], ptr[i]); - } - VERIFY_IS_FALSE(rwbuf.is_eof()); - VERIFY_ARE_EQUAL(rwbuf.getc().get(), std::char_traits<char>::eof()); - VERIFY_IS_TRUE(rwbuf.is_eof()); - }); - - auto writeTask = pplx::create_task([&s, &rwbuf]() { - VERIFY_ARE_EQUAL(rwbuf.putn_nocopy(s.data(), s.size()).get(), s.size()); - rwbuf.close(std::ios_base::out); - }); - - writeTask.wait(); - readTask.wait(); - - rwbuf.close().get(); -} - -template<class StreamBufferType> -void streambuf_acquire_alloc(StreamBufferType& rwbuf) -{ - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - { - // There should be nothing to read - typename StreamBufferType::char_type* ptr = nullptr; - size_t count = 0; - rwbuf.acquire(ptr, count); - VERIFY_ARE_EQUAL(count, 0); - rwbuf.release(ptr, count); - } - - auto writeTask = pplx::create_task([&rwbuf]() { - auto ptr = rwbuf.alloc(8); - VERIFY_IS_TRUE(ptr != nullptr); - rwbuf.commit(4); - }); - - typename StreamBufferType::char_type* ptr = nullptr; - auto readTask = pplx::create_task([&rwbuf, &ptr, writeTask]() { - size_t count = 0; - - int repeat = 10; - while ((count == 0) && (repeat-- > 0)) - { - rwbuf.acquire(ptr, count); - } - - if (count == 0) - { - writeTask.wait(); - } - - rwbuf.acquire(ptr, count); - VERIFY_ARE_EQUAL(count, 4); - rwbuf.release(ptr, count); - }); - - writeTask.wait(); - readTask.wait(); - - rwbuf.close().get(); -} - -template<class StreamBufferType> -void streambuf_close(StreamBufferType& rwbuf) -{ - VERIFY_IS_TRUE(rwbuf.is_open()); - - bool can_rd = rwbuf.can_read(); - bool can_wr = rwbuf.can_write(); - - if (can_wr) - { - // Close the write head - rwbuf.close(std::ios_base::out).get(); - VERIFY_IS_FALSE(rwbuf.can_write()); - - if (can_rd) - { - VERIFY_IS_FALSE(rwbuf.can_write()); - VERIFY_IS_TRUE(rwbuf.can_read()); - - // The buffer should still be open for read - VERIFY_IS_TRUE(rwbuf.is_open()); - - // Closing the write head again should not throw - rwbuf.close(std::ios_base::out).wait(); - - // The read head should still be open - VERIFY_IS_TRUE(rwbuf.can_read()); - } - } - - if (can_rd) - { - // Close the read head - rwbuf.close(std::ios_base::in).get(); - VERIFY_IS_FALSE(rwbuf.can_read()); - - // Closing the read head again should not throw - rwbuf.close(std::ios_base::in).wait(); - } - - // The buffer should now be closed - VERIFY_IS_FALSE(rwbuf.is_open()); -} - -template<class StreamBufferType> -void streambuf_close_read_with_pending_read(StreamBufferType& rwbuf) -{ - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // Write 4 characters - std::basic_string<typename StreamBufferType::char_type> s; - s.push_back((typename StreamBufferType::char_type)0); - s.push_back((typename StreamBufferType::char_type)1); - s.push_back((typename StreamBufferType::char_type)2); - s.push_back((typename StreamBufferType::char_type)3); - - VERIFY_ARE_EQUAL(s.size(), rwbuf.putn_nocopy(s.data(), s.size()).get()); - VERIFY_ARE_EQUAL(s.size() * 1, rwbuf.in_avail()); - - // Try to read 8 characters - this should block - typename StreamBufferType::char_type data[8]; - auto readTask = rwbuf.getn(data, 8); - - // Close the write head - rwbuf.close(std::ios_base::out).get(); - VERIFY_IS_FALSE(rwbuf.can_write()); - - // The buffer should still be open for read - VERIFY_IS_TRUE(rwbuf.is_open()); - - // The read head should still be open - VERIFY_IS_TRUE(rwbuf.can_read()); - - // Closing the write head should trigger the completion of the read request - VERIFY_ARE_EQUAL(4, readTask.get()); - - // Close the read head - rwbuf.close(std::ios_base::in).get(); - VERIFY_IS_FALSE(rwbuf.can_read()); - - // The buffer should now be closed - VERIFY_IS_FALSE(rwbuf.is_open()); -} - -template<class StreamBufferType> -void streambuf_close_write_with_pending_read(StreamBufferType& rwbuf) -{ - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // Write 4 characters - std::basic_string<typename StreamBufferType::char_type> s; - s.push_back((typename StreamBufferType::char_type)0); - s.push_back((typename StreamBufferType::char_type)1); - s.push_back((typename StreamBufferType::char_type)2); - s.push_back((typename StreamBufferType::char_type)3); - - VERIFY_ARE_EQUAL(s.size(), rwbuf.putn_nocopy(s.data(), s.size()).get()); - VERIFY_ARE_EQUAL(s.size() * 1, rwbuf.in_avail()); - - // Try to read 8 characters - this should block - typename StreamBufferType::char_type data[8]; - auto readTask = rwbuf.getn(data, 8); - - // Close the read head - rwbuf.close(std::ios_base::in).get(); - VERIFY_IS_FALSE(rwbuf.can_read()); - - // The read task should not be completed - VERIFY_IS_FALSE(readTask.is_done()); - - // Close the write head - rwbuf.close(std::ios_base::out).get(); - VERIFY_IS_FALSE(rwbuf.can_write()); - - // Closing the write head should trigger the completion of the read request - VERIFY_ARE_EQUAL(4, readTask.get()); - - // The buffer should now be closed - VERIFY_IS_FALSE(rwbuf.is_open()); -} - -template<class StreamBufferType> -void streambuf_close_parallel(StreamBufferType& rwbuf) -{ - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // Close the read and write head in parallel - auto closeReadTask = pplx::create_task([&rwbuf]() { - VERIFY_IS_TRUE(rwbuf.can_read()); - - // Close the read head - rwbuf.close(std::ios_base::in).get(); - VERIFY_IS_FALSE(rwbuf.can_read()); - - // Closing the read head again should not throw - rwbuf.close(std::ios_base::in).wait(); - }); - - auto closeWriteTask = pplx::create_task([&rwbuf]() { - VERIFY_IS_TRUE(rwbuf.can_write()); - - // Close the write head - rwbuf.close(std::ios_base::out).get(); - VERIFY_IS_FALSE(rwbuf.can_write()); - - // Closing the write head again should not throw - rwbuf.close(std::ios_base::out).wait(); - }); - - closeReadTask.wait(); - closeWriteTask.wait(); - - // The buffer should now be closed - VERIFY_IS_FALSE(rwbuf.is_open()); -} - -streams::producer_consumer_buffer<uint8_t> create_producer_consumer_buffer_with_data(const std::vector<uint8_t>& s) -{ - streams::producer_consumer_buffer<uint8_t> buf; - VERIFY_ARE_EQUAL(buf.putn_nocopy(s.data(), s.size()).get(), s.size()); - buf.close(std::ios_base::out).get(); - return buf; -} - -SUITE(memstream_tests) -{ - TEST(string_buffer_putc) - { - stringstreambuf buf; - streambuf_putc(buf); - } - - TEST(charptr_buffer_putc_fail) - { - char chars[26]; - rawptr_buffer<char> buf(chars, 26); - VERIFY_ARE_EQUAL(buf.putn_nocopy("abcdefghijklmnopqrstuvwxyz", 26).get(), 26); - VERIFY_ARE_EQUAL(buf.putc('a').get(), std::char_traits<char>::eof()); - } - - TEST(wstring_buffer_putc) - { - wstringstreambuf buf; - streambuf_putc(buf); - } - - TEST(string_buffer_putn) - { - stringstreambuf buf; - streambuf_putn(buf); - } - TEST(wstring_buffer_putn) - { - wstringstreambuf buf; - streambuf_putn(buf); - } - TEST(charptr_buffer_putn) - { - { - char chars[128]; - rawptr_buffer<char> buf(chars, sizeof(chars)); - streambuf_putn(buf); - } - { - uint8_t chars[128]; - rawptr_buffer<uint8_t> buf(chars, sizeof(chars)); - streambuf_putn(buf); - } - { - utf16char chars[128]; - rawptr_buffer<utf16char> buf(chars, sizeof(chars) / sizeof(utf16char)); - streambuf_putn(buf); - } - } - TEST(charptr_buffer_putn_fail) - { - { - char chars[128]; - rawptr_buffer<char> buf(chars, 12); - VERIFY_THROWS(buf.putn_nocopy("abcdefghijklmnopqrstuvwxyz", 26).get(), std::runtime_error); - } - } - - TEST(bytevec_buffer_putn) - { - { - container_buffer<std::vector<uint8_t>> buf; - streambuf_putn(buf); - } - { - container_buffer<std::vector<char>> buf; - streambuf_putn(buf); - } - { - container_buffer<std::vector<utf16char>> buf; - streambuf_putn(buf); - } - } - TEST(mem_buffer_putn) - { - { - streams::producer_consumer_buffer<char> buf; - streambuf_putn(buf); - } - - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_putn(buf); - } - - { - streams::producer_consumer_buffer<utf16char> buf; - streambuf_putn(buf); - } - } - - TEST(string_buffer_alloc_commit) - { - stringstreambuf buf; - streambuf_alloc_commit(buf); - } - - TEST(wstring_buffer_alloc_commit) - { - wstringstreambuf buf; - streambuf_alloc_commit(buf); - } - - TEST(mem_buffer_alloc_commit) - { - { - streams::producer_consumer_buffer<char> buf; - streambuf_alloc_commit(buf); - } - - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_alloc_commit(buf); - } - - { - streams::producer_consumer_buffer<utf16char> buf; - streambuf_alloc_commit(buf); - } - } - - TEST(string_buffer_seek_write) - { - stringstreambuf buf; - streambuf_seek_write(buf); - } - TEST(wstring_buffer_seek_write) - { - wstringstreambuf buf; - streambuf_seek_write(buf); - } - TEST(charptr_buffer_seek_write) - { - { - char chars[128]; - rawptr_buffer<char> buf(chars, sizeof(chars)); - streambuf_seek_write(buf); - } - { - uint8_t chars[128]; - rawptr_buffer<uint8_t> buf(chars, sizeof(chars)); - streambuf_seek_write(buf); - } - { - utf16char chars[128]; - rawptr_buffer<utf16char> buf(chars, sizeof(chars) / sizeof(utf16char)); - streambuf_seek_write(buf); - } - } - TEST(bytevec_buffer_seek_write) - { - { - container_buffer<std::vector<uint8_t>> buf; - streambuf_seek_write(buf); - } - { - container_buffer<std::vector<char>> buf; - streambuf_seek_write(buf); - } - { - container_buffer<std::vector<utf16char>> buf; - streambuf_seek_write(buf); - } - } - TEST(mem_buffer_seek_write) - { - streams::producer_consumer_buffer<char> buf; - VERIFY_IS_FALSE(buf.can_seek()); - } - - TEST(string_buffer_getc) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_getc(buf, v[0]); - } - TEST(wstring_buffer_getc) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_getc(buf, v[0]); - } - TEST(charptr_buffer_getc) - { - { - char chars[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - rawptr_buffer<char> buf(chars, sizeof(chars), std::ios::in); - streambuf_getc(buf, chars[0]); - } - { - uint8_t chars[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - rawptr_buffer<uint8_t> buf(chars, sizeof(chars), std::ios::in); - streambuf_getc(buf, chars[0]); - } - { - utf16char chars[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - rawptr_buffer<utf16char> buf(chars, sizeof(chars) / sizeof(utf16char), std::ios::in); - streambuf_getc(buf, chars[0]); - } - } - TEST(bytevec_buffer_getc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_getc(buf, s[0]); - } - TEST(mem_buffer_getc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - streams::producer_consumer_buffer<uint8_t> buf = create_producer_consumer_buffer_with_data(s); - streambuf_getc(buf, s[0]); - } - - TEST(string_buffer_sgetc) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_sgetc(buf, v[0]); - } - TEST(wstring_buffer_sgetc) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_sgetc(buf, v[0]); - } - TEST(charptr_buffer_sgetc) - { - char chars[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - rawptr_buffer<char> buf(chars, sizeof(chars), std::ios::in); - streambuf_sgetc(buf, chars[0]); - } - TEST(bytevec_buffer_sgetc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_sgetc(buf, s[0]); - } - TEST(mem_buffer_sgetc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - streams::producer_consumer_buffer<uint8_t> buf = create_producer_consumer_buffer_with_data(s); - streambuf_sgetc(buf, s[0]); - } - - TEST(string_buffer_bumpc) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_bumpc(buf, v); - } - TEST(wstring_buffer_bumpc) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_bumpc(buf, v); - } - TEST(charptr_buffer_bumpc) - { - uint8_t chars[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(chars), std::end(chars)); - rawptr_buffer<uint8_t> buf(chars, sizeof(chars), std::ios::in); - streambuf_bumpc(buf, s); - } - TEST(bytevec_buffer_bumpc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_bumpc(buf, s); - } - - TEST(mem_buffer_bumpc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - streams::producer_consumer_buffer<uint8_t> buf = create_producer_consumer_buffer_with_data(s); - streambuf_bumpc(buf, s); - } - - TEST(string_buffer_sbumpc) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_sbumpc(buf, v); - } - TEST(wstring_buffer_sbumpc) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_sbumpc(buf, v); - } - TEST(charptr_buffer_sbumpc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - rawptr_buffer<uint8_t> buf(data, sizeof(data), std::ios::in); - streambuf_sbumpc(buf, s); - } - TEST(bytevec_buffer_sbumpc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_sbumpc(buf, s); - } - - TEST(mem_buffer_sbumpc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - streams::producer_consumer_buffer<uint8_t> buf = create_producer_consumer_buffer_with_data(s); - streambuf_sbumpc(buf, s); - } - TEST(string_buffer_nextc) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_nextc(buf, v); - } - TEST(wstring_buffer_nextc) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_nextc(buf, v); - } - TEST(charptr_buffer_nextc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - rawptr_buffer<uint8_t> buf(data, sizeof(data), std::ios::in); - streambuf_nextc(buf, s); - } - TEST(bytevec_buffer_nextc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_nextc(buf, s); - } - TEST(mem_buffer_nextc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - streams::producer_consumer_buffer<uint8_t> buf = create_producer_consumer_buffer_with_data(s); - streambuf_nextc(buf, s); - } - - TEST(string_buffer_ungetc) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_ungetc(buf, v); - } - TEST(wstring_buffer_ungetc) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_ungetc(buf, v); - } - TEST(charptr_buffer_ungetc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - rawptr_buffer<uint8_t> buf(data, sizeof(data), std::ios::in); - streambuf_ungetc(buf, s); - } - TEST(bytevec_buffer_ungetc) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_ungetc(buf, s); - } - - TEST(string_buffer_getn) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_getn(buf, v); - } - TEST(wstring_buffer_getn) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_getn(buf, v); - } - TEST(charptr_buffer_getn) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - rawptr_buffer<uint8_t> buf(data, sizeof(data), std::ios::in); - streambuf_getn(buf, s); - } - TEST(bytevec_buffer_getn) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_getn(buf, s); - } - TEST(mem_buffer_getn) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - streams::producer_consumer_buffer<uint8_t> buf = create_producer_consumer_buffer_with_data(s); - streambuf_getn(buf, s); - } - - TEST(string_buffer_acquire_release) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_acquire_release(buf, v); - } - TEST(wstring_buffer_acquire_release) - { - utility::string_t s(U("Hello World")); - std::vector<utility::char_t> v(std::begin(s), std::end(s)); - streams::wstringstreambuf buf(s); - streambuf_acquire_release(buf, v); - } - TEST(charptr_buffer_acquire_release) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - rawptr_buffer<uint8_t> buf(data, sizeof(data), std::ios::in); - streambuf_acquire_release(buf, s); - } - TEST(bytevec_buffer_acquire_release) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - container_buffer<std::vector<uint8_t>> buf(s); - streambuf_acquire_release(buf, s); - } - TEST(mem_buffer_acquire_release) - { - uint8_t data[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'}; - std::vector<uint8_t> s(std::begin(data), std::end(data)); - streams::producer_consumer_buffer<uint8_t> buf = create_producer_consumer_buffer_with_data(s); - streambuf_acquire_release(buf, s); - } - TEST(string_buffer_seek_read) - { - std::string s("Hello World"); - std::vector<char> v(std::begin(s), std::end(s)); - streams::stringstreambuf buf(s); - streambuf_seek_read(buf); - } - - TEST(mem_buffer_putn_getn) - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_putn_getn(buf); - } - - TEST(mem_buffer_acquire_alloc) - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_acquire_alloc(buf); - } - - TEST(string_buffer_close) - { - streams::stringstreambuf buf; - streambuf_close(buf); - } - TEST(wstring_buffer_close) - { - streams::wstringstreambuf buf; - streambuf_close(buf); - } - TEST(bytevec_buffer_close) - { - container_buffer<std::vector<uint8_t>> buf; - streambuf_close(buf); - } - TEST(mem_buffer_close) - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_close(buf); - } - - TEST(mem_buffer_close_read_with_pending_read) - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_close_read_with_pending_read(buf); - } - - TEST(mem_buffer_close_write_with_pending_read) - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_close_write_with_pending_read(buf); - } - - TEST(mem_buffer_close_parallel) - { - streams::producer_consumer_buffer<uint8_t> buf; - streambuf_close_parallel(buf); - } - - TEST(mem_buffer_close_destroy) - { - std::vector<pplx::task<void>> taskVector; - - for (int i = 0; i < 1000; i++) - { - streams::producer_consumer_buffer<uint8_t> buf; - taskVector.push_back(buf.close()); - } - - pplx::when_all(std::begin(taskVector), std::end(taskVector)).wait(); - } - - TEST(string_buffer_ctor) - { - std::string src("abcdef ghij"); - auto instream = streams::stringstream::open_istream(src); - - streams::stringstreambuf sbuf; - auto outstream = sbuf.create_ostream(); - - for (;;) - { - const int count = 4; - char temp[count]; - streams::rawptr_buffer<char> buf1(temp, count); - streams::rawptr_buffer<char> buf2(temp, count, std::ios::in); - auto size = instream.read(buf1, count).get(); - VERIFY_IS_TRUE(size <= count); - VERIFY_ARE_EQUAL(size, outstream.write(buf2, size).get()); - - if (size != count) break; - } - - auto& dest = sbuf.collection(); - VERIFY_ARE_EQUAL(src, dest); - } - - TEST(vec_buffer_ctor) - { - std::string srcstr("abcdef ghij"); - std::vector<uint8_t> src(begin(srcstr), end(srcstr)); - auto instream = streams::bytestream::open_istream(src); - - container_buffer<std::vector<uint8_t>> sbuf; - auto outstream = sbuf.create_ostream(); - - for (;;) - { - const int count = 4; - uint8_t temp[count]; - streams::rawptr_buffer<uint8_t> buf1(temp, count); - streams::rawptr_buffer<uint8_t> buf2(temp, count, std::ios::in); - auto size = instream.read(buf1, count).get(); - VERIFY_IS_TRUE(size <= count); - VERIFY_ARE_EQUAL(size, outstream.write(buf2, size).get()); - - if (size != count) break; - } - - auto& dest = sbuf.collection(); - VERIFY_ARE_EQUAL(src, dest); - } - - TEST(charptr_buffer_ctor_1) - { - char chars[] = {'a', 'b', 'c', 'd', 'e', 'f', ' ', 'g', 'h', 'i', 'j'}; - auto instream = streams::rawptr_stream<char>::open_istream(chars, sizeof(chars)); - - stringstreambuf sbuf; - auto outstream = sbuf.create_ostream(); - - for (;;) - { - const int count = 4; - char temp[count]; - streams::rawptr_buffer<char> buf1(temp, count); - streams::rawptr_buffer<char> buf2(temp, count, std::ios::in); - auto size = instream.read(buf1, count).get(); - VERIFY_IS_TRUE(size <= count); - VERIFY_ARE_EQUAL(size, outstream.write(buf2, size).get()); - - if (size != count) break; - } - - auto& dest = sbuf.collection(); - VERIFY_ARE_EQUAL(memcmp(chars, &(dest)[0], sizeof(chars)), 0); - } - - TEST(charptr_buffer_ctor_2) - { - char chars[] = {'a', 'b', 'c', 'd', 'e', 'f', ' ', 'g', 'h', 'i', 'j'}; - auto instream = streams::rawptr_stream<char>::open_istream(chars, sizeof(chars)); - - stringstreambuf sbuf; - auto outstream = sbuf.create_ostream(); - - for (;;) - { - const int count = 4; - char temp[count]; - streams::rawptr_buffer<char> buf1(temp, count); - streams::rawptr_buffer<char> buf2(temp, count, std::ios::in); - auto size = instream.read(buf1, count).get(); - VERIFY_IS_TRUE(size <= count); - VERIFY_ARE_EQUAL(size, outstream.write(buf2, size).get()); - - if (size != count) break; - } - - auto& dest = sbuf.collection(); - VERIFY_ARE_EQUAL(memcmp(chars, &(dest)[0], sizeof(chars)), 0); - } - - TEST(charptr_buffer_ctor_3) - { - char chars[128]; - memset(chars, 0, sizeof(chars)); - - rawptr_buffer<char> buf(chars, sizeof(chars)); - - auto outstream = buf.create_ostream(); - - auto t1 = outstream.print("Hello "); - auto t2 = outstream.print(10); - auto t3 = outstream.print(" Again!"); - (t1 && t2 && t3).wait(); - - std::string result(chars); - - VERIFY_ARE_EQUAL(result, "Hello 10 Again!"); - } - - TEST(validate_stream_mode) - { - VERIFY_THROWS(concurrency::streams::container_buffer<std::vector<char>>(std::ios::in | std::ios::out), - std::invalid_argument); - std::vector<char> vc; - VERIFY_THROWS(concurrency::streams::container_buffer<std::vector<char>>(vc, std::ios::in | std::ios::out), - std::invalid_argument); - } - - TEST(write_stream_test_1) - { - char chars[128]; - memset(chars, 0, sizeof(chars)); - - auto stream = streams::rawptr_stream<char>::open_ostream(chars, sizeof(chars)); - - std::vector<uint8_t> vect; - - for (char ch = 'a'; ch <= 'z'; ch++) - { - vect.push_back(ch); - } - - size_t vsz = vect.size(); - - concurrency::streams::container_stream<std::vector<uint8_t>>::buffer_type txtbuf(std::move(vect), - std::ios_base::in); - - VERIFY_ARE_EQUAL(stream.write(txtbuf, vsz).get(), vsz); - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyz"), 0); - - auto close = stream.close(); - - VERIFY_IS_TRUE(close.is_done()); - } - - TEST(mem_buffer_large_data) - { - // stream large amounts of data - // If the stream stores all the data then we will run out of VA space! - streams::producer_consumer_buffer<char> membuf; - - const size_t size = 4 * 1024 * 1024; // 4 MB - char* ptr = new char[size]; - - // stream 4 GB - for (size_t i = 0; i < 1024; i++) - { - // Fill some random positions in the buffer - ptr[i + 0] = 'a'; - ptr[i + 100] = 'b'; - - VERIFY_ARE_EQUAL(size, membuf.putn_nocopy(ptr, size).get()); - - // overwrite the values in ptr - ptr[i + 0] = 'c'; - ptr[i + 100] = 'd'; - - VERIFY_ARE_EQUAL(size, membuf.getn(ptr, size).get()); - - VERIFY_ARE_EQUAL(ptr[i + 0], 'a'); - VERIFY_ARE_EQUAL(ptr[i + 100], 'b'); - } - - delete[] ptr; - } - -#ifdef _WIN32 - - class ISequentialStream_bridge -#if defined(__cplusplus_winrt) - : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, - ISequentialStream> -#endif - { - public: - ISequentialStream_bridge(streambuf<char> buf) : m_buffer(buf) {} - - // ISequentialStream implementation - virtual HRESULT STDMETHODCALLTYPE Read(void* pv, ULONG cb, ULONG* pcbRead) - { - size_t count = m_buffer.getn((char*)pv, (size_t)cb).get(); - if (pcbRead != nullptr) *pcbRead = (ULONG)count; - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE Write(const void* pv, ULONG cb, ULONG* pcbWritten) - { - size_t count = m_buffer.putn_nocopy((const char*)pv, (size_t)cb).get(); - if (pcbWritten != nullptr) *pcbWritten = (ULONG)count; - return S_OK; - } - - private: - streambuf<char> m_buffer; - }; - - template<typename _StreamBufferType> - void IStreamTest1() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text = "This is a test"; - size_t len = text.size(); - - ULONG pcbWritten = 0; - - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text[0], (ULONG)text.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(text.size(), pcbWritten); - - text = " - but this is not"; - len += text.size(); - pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text[0], (ULONG)text.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(text.size(), pcbWritten); - - char buf[128]; - memset(buf, 0, sizeof(buf)); - - rbuf.getn((char*)buf, len).wait(); - - VERIFY_ARE_EQUAL(0, strcmp("This is a test - but this is not", buf)); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(membuf_IStreamTest1) { IStreamTest1<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest2() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text = "This is a test"; - size_t len = text.size(); - - ULONG pcbWritten = 0; - - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text[0], (ULONG)text.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(text.size(), pcbWritten); - - text = " - but this is not"; - len += text.size(); - pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text[0], (ULONG)text.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(text.size(), pcbWritten); - - char buf[128]; - memset(buf, 0, sizeof(buf)); - - rbuf.getn((char*)buf, len).wait(); - - VERIFY_ARE_EQUAL(0, strcmp("This is a test - but this is not", buf)); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(membuf_IStreamTest2) { IStreamTest2<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest3() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text1 = "This is a test"; - size_t len1 = text1.size(); - std::string text2 = " - but this is not"; - size_t len2 = text2.size(); - - char buf[128]; - memset(buf, 0, sizeof(buf)); - - // The read happens before the write. - - auto read = rbuf.getn((char*)buf, len1 + len2); - - ULONG pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text1[0], (ULONG)text1.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len1, pcbWritten); - pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text2[0], (ULONG)text2.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len2, pcbWritten); - - read.wait(); - - // We may or may not read data from both writes here. It depends on the - // stream in use. Both are correct behaviors. - if (read.get() == len1 + len2) - VERIFY_ARE_EQUAL(0, strcmp("This is a test - but this is not", (char*)buf)); - else - VERIFY_ARE_EQUAL(0, strcmp("This is a test", (char*)buf)); - - rbuf.close().get(); - } - - TEST(membuf_IStreamTest3) { IStreamTest3<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest4() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text1 = "This is a test"; - size_t len1 = text1.size(); - std::string text2 = " - but this is not"; - size_t len2 = text2.size(); - - char buf1[128]; - memset(buf1, 0, sizeof(buf1)); - char buf2[128]; - memset(buf2, 0, sizeof(buf2)); - - // The read happens before the write. - - auto read1 = rbuf.getn(buf1, 8); - auto read2 = rbuf.getn(buf2, 12); - - ULONG pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text1[0], (ULONG)text1.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len1, pcbWritten); - pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text2[0], (ULONG)text2.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len2, pcbWritten); - - VERIFY_ARE_EQUAL(8u, read1.get()); - // Different results depending on stream implementation. Both correct. - VERIFY_IS_TRUE(read2.get() == 12u || read2.get() == 6u); - - VERIFY_ARE_EQUAL(0, strcmp("This is ", (char*)buf1)); - if (read2.get() == 12u) - VERIFY_ARE_EQUAL(0, strcmp("a test - but", (char*)buf2)); - else - VERIFY_ARE_EQUAL(0, strcmp("a test", (char*)buf2)); - - rbuf.close().get(); - } - - TEST(membuf_IStreamTest4) { IStreamTest4<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest5() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text1 = "This is a test"; - size_t len1 = text1.size(); - - char buf1[128]; - memset(buf1, 0, sizeof(buf1)); - - // The read happens before the write. - - auto read1 = rbuf.getn(buf1, 28); - - ULONG pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text1[0], (ULONG)text1.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len1, pcbWritten); - - // We close the stream buffer before enough bytes have been written. - - rbuf.close().get(); - - VERIFY_ARE_EQUAL(len1, read1.get()); - VERIFY_ARE_EQUAL(len1, strlen((char*)buf1)); - VERIFY_ARE_EQUAL(0, strcmp("This is a test", (char*)buf1)); - } - - TEST(membuf_IStreamTest5) { IStreamTest5<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest6() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text1 = "abcdefghijklmnopqrstuvwxyz"; - size_t len1 = text1.size(); - - ULONG pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text1[0], (ULONG)text1.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len1, pcbWritten); - - bool validated = true; - for (int expected = 'a'; expected <= 'z'; expected++) - { - validated = validated && (expected == rbuf.bumpc().get()); - } - - VERIFY_IS_TRUE(validated); - rbuf.close().get(); - } - - TEST(membuf_IStreamTest6) { IStreamTest6<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest7() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::vector<task<int>> reads; - - for (int i = 0; i < 26; i++) - { - reads.push_back(rbuf.bumpc()); - } - - std::string text1 = "abcdefghijklmnopqrstuvwxyz"; - size_t len1 = text1.size(); - - ULONG pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text1[0], (ULONG)text1.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len1, pcbWritten); - - bool validated = true; - for (int i = 0; i < 26; i++) - { - int expected = 'a' + i; - validated = validated && (expected == reads[i].get()); - } - - VERIFY_IS_TRUE(validated); - rbuf.close().get(); - } - - TEST(membuf_IStreamTest7) { IStreamTest7<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest8() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text1 = "This is a test"; - size_t len1 = text1.size(); - - char buf1[128]; - memset(buf1, 0, sizeof(buf1)); - - // The read happens before the write. - - auto read1 = rbuf.getn(buf1, 28); - auto read2 = rbuf.getn(buf1, 8); - - ULONG pcbWritten = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Write((const void*)&text1[0], (ULONG)text1.size(), &pcbWritten)); - VERIFY_ARE_EQUAL(len1, pcbWritten); - - // We close the stream buffer before enough bytes have been written. - // Make sure that the first read results in fewer bytes than requested - // and that the second read returns -1. - - rbuf.close(std::ios_base::out).get(); - - VERIFY_ARE_EQUAL(len1, read1.get()); - VERIFY_ARE_EQUAL(-0, (int)read2.get()); - VERIFY_ARE_EQUAL(len1, strlen((char*)buf1)); - VERIFY_ARE_EQUAL(0, strcmp("This is a test", (char*)buf1)); - } - - TEST(membuf_IStreamTest8) { IStreamTest8<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest9() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - VERIFY_ARE_EQUAL((int)'a', rbuf.putc('a').get()); - VERIFY_ARE_EQUAL((int)'n', rbuf.putc('n').get()); - VERIFY_ARE_EQUAL((int)'q', rbuf.putc('q').get()); - VERIFY_ARE_EQUAL((int)'s', rbuf.putc('s').get()); - - VERIFY_ARE_EQUAL(4u, rbuf.in_avail()); - - std::string chars(32, '\0'); - ULONG pcbRead = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Read(&chars[0], 4, &pcbRead)); - VERIFY_ARE_EQUAL(4u, pcbRead); - - VERIFY_ARE_EQUAL("anqs", chars.c_str()); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(membuf_IStreamTest9) { IStreamTest9<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest10() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text(128, '\0'); - strcpy_s(&text[0], 128, "This is a test"); - size_t len1 = strlen(&text[0]); - - VERIFY_ARE_EQUAL(len1, rbuf.putn_nocopy(&text[0], len1).get()); - - strcpy_s(&text[0], 128, " - but this is not"); - size_t len2 = strlen(&text[0]); - - VERIFY_ARE_EQUAL(len2, rbuf.putn_nocopy(&text[0], len2).get()); - - VERIFY_ARE_EQUAL(len1 + len2, rbuf.in_avail()); - - std::string chars(128, '\0'); - size_t was_available = rbuf.in_avail(); - ULONG pcbRead = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Read(&chars[0], (ULONG)was_available, &pcbRead)); - VERIFY_ARE_EQUAL(was_available, pcbRead); - - VERIFY_ARE_EQUAL("This is a test - but this is not", chars.c_str()); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(membuf_IStreamTest10) { IStreamTest10<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest11() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - char ch = 'a'; - - auto seg2 = [&ch](int val) { return (val != -1) && (++ch <= 'z'); }; - auto seg1 = [=, &ch, &rbuf]() { return rbuf.putc(ch).then(seg2); }; - - pplx::details::_do_while(seg1).wait(); - - VERIFY_ARE_EQUAL(26u, rbuf.in_avail()); - - std::string chars(128, '\0'); - size_t was_available = rbuf.in_avail(); - ULONG pcbRead = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Read(&chars[0], (ULONG)was_available, &pcbRead)); - VERIFY_ARE_EQUAL(was_available, pcbRead); - - VERIFY_ARE_EQUAL("abcdefghijklmnopqrstuvwxyz", chars.c_str()); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(membuf_IStreamTest11) { IStreamTest11<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest12() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - std::string text(128, '\0'); - strcpy_s(&text[0], 128, "This is a test"); - size_t len1 = strlen(&text[0]); - - VERIFY_ARE_EQUAL(len1, rbuf.putn_nocopy(&text[0], len1).get()); - - strcpy_s(&text[0], 128, " - but this is not"); - size_t len2 = strlen(&text[0]); - - VERIFY_ARE_EQUAL(len2, rbuf.putn_nocopy(&text[0], len2).get()); - - VERIFY_ARE_EQUAL(len1 + len2, rbuf.in_avail()); - - std::string chars(128, '\0'); - size_t was_available = rbuf.in_avail(); - ULONG pcbRead = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Read(&chars[0], (ULONG)was_available, &pcbRead)); - VERIFY_ARE_EQUAL(was_available, pcbRead); - - VERIFY_ARE_EQUAL("This is a test - but this is not", chars.c_str()); - - rbuf.close().get(); - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(membuf_IStreamTest12) { IStreamTest12<streams::producer_consumer_buffer<char>>(); } - - template<typename _StreamBufferType> - void IStreamTest13() - { - _StreamBufferType rbuf; - ISequentialStream_bridge stream(rbuf); - - streams::basic_ostream<char> os(rbuf); - - auto a = os.print("This is a test"); - auto b = os.print(" "); - auto c = os.print("- but this is not"); - (a && b && c).wait(); - - VERIFY_ARE_EQUAL(32u, rbuf.in_avail()); - - std::string chars(128, '\0'); - size_t was_available = rbuf.in_avail(); - ULONG pcbRead = 0; - VERIFY_ARE_EQUAL(S_OK, stream.Read(&chars[0], (ULONG)was_available, &pcbRead)); - VERIFY_ARE_EQUAL(was_available, pcbRead); - - VERIFY_ARE_EQUAL("This is a test - but this is not", chars.c_str()); - - os.close().get(); - - // The read end should still be open - VERIFY_IS_TRUE(rbuf.is_open()); - - // close the read end - rbuf.close(std::ios_base::in).get(); - - // Now the buffer should no longer be open - VERIFY_IS_FALSE(rbuf.is_open()); - } - - TEST(membuf_IStreamTest13) { IStreamTest13<streams::producer_consumer_buffer<char>>(); } -#endif - - TEST(producer_consumer_buffer_flush_1) - { - streams::producer_consumer_buffer<char> rwbuf; - - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - char buf1[128], buf2[128]; - memset(buf1, 0, sizeof(buf1)); - memset(buf2, 0, sizeof(buf2)); - - // The read happens before the write. - - auto read1 = rwbuf.getn(buf1, 128); - auto read2 = rwbuf.getn(buf2, 128); - - std::string text1 = "This is a test"; - size_t len1 = text1.size(); - VERIFY_ARE_EQUAL(rwbuf.putn_nocopy(&text1[0], len1).get(), len1); - rwbuf.sync().wait(); - - std::string text2 = "- but this is not"; - size_t len2 = text2.size(); - VERIFY_ARE_EQUAL(rwbuf.putn_nocopy(&text2[0], len2).get(), len2); - rwbuf.sync().wait(); - - VERIFY_ARE_EQUAL(read1.get(), len1); - VERIFY_ARE_EQUAL(read2.get(), len2); - - rwbuf.close().get(); - } - - TEST(producer_consumer_buffer_flush_2) - { - streams::producer_consumer_buffer<char> rwbuf; - - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // The read happens after the write. - - std::string text1 = "This is a test"; - std::string text2 = "- but this is not"; - size_t len1 = text1.size(); - size_t len2 = text2.size(); - VERIFY_ARE_EQUAL(rwbuf.putn_nocopy(&text1[0], len1).get(), len1); - VERIFY_ARE_EQUAL(rwbuf.putn_nocopy(&text2[0], len2).get(), len2); - rwbuf.sync().wait(); - - char buf1[128], buf2[128]; - memset(buf1, 0, sizeof(buf1)); - memset(buf2, 0, sizeof(buf2)); - - auto read1 = rwbuf.getn(buf1, 128); - - VERIFY_ARE_EQUAL(read1.get(), len1 + len2); - - rwbuf.close().get(); - } - - TEST(producer_consumer_buffer_flush_3) - { - streams::producer_consumer_buffer<char> rwbuf; - - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // The read happens before the write. - - char buf1[128], buf2[128]; - memset(buf1, 0, sizeof(buf1)); - memset(buf2, 0, sizeof(buf2)); - - auto read1 = rwbuf.getn(buf1, 128); - auto read2 = rwbuf.getn(buf2, 128); - - for (char c = 'a'; c <= 'z'; ++c) - rwbuf.putc(c); - rwbuf.sync().wait(); - for (char c = 'a'; c <= 'z'; ++c) - rwbuf.putc(c); - - VERIFY_ARE_EQUAL(read1.get(), 26); - - rwbuf.close().get(); - - VERIFY_ARE_EQUAL(read2.get(), 26); - } - - TEST(producer_consumer_buffer_flush_4) - { - streams::producer_consumer_buffer<char> rwbuf; - - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // The read happens after the write. - - for (char c = 'a'; c <= 'z'; ++c) - rwbuf.putc(c); - rwbuf.sync().wait(); - - char buf1[128], buf2[128]; - memset(buf1, 0, sizeof(buf1)); - memset(buf2, 0, sizeof(buf2)); - - auto read1 = rwbuf.getn(buf1, 20); - auto read2 = rwbuf.getn(buf1, 128); - - VERIFY_ARE_EQUAL(read1.get(), 20); - VERIFY_ARE_EQUAL(read2.get(), 6); - - rwbuf.close().get(); - } - - TEST(producer_consumer_buffer_flush_5) - { - streams::producer_consumer_buffer<char> rwbuf; - - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // The read happens before the write. - - pplx::task<int> buf1[128]; - - for (int i = 0; i < 128; ++i) - { - buf1[i] = rwbuf.bumpc(); - } - - for (char c = 'a'; c <= 'z'; ++c) - rwbuf.putc(c); - rwbuf.sync().wait(); - - for (int i = 0; i < 26; ++i) - { - VERIFY_ARE_EQUAL('a' + i, buf1[i].get()); - } - for (int i = 26; i < 128; ++i) - { - VERIFY_IS_FALSE(buf1[i].is_done()); - } - rwbuf.close().get(); - } - - TEST(producer_consumer_buffer_flush_6) - { - streams::producer_consumer_buffer<char> rwbuf; - - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - // The read happens after the write. - - for (char c = 'a'; c <= 'z'; ++c) - rwbuf.putc(c); - rwbuf.sync().wait(); - - pplx::task<int> buf1[128]; - - for (int i = 0; i < 128; ++i) - { - buf1[i] = rwbuf.bumpc(); - } - - for (int i = 0; i < 26; ++i) - { - VERIFY_IS_TRUE(buf1[i].is_done()); - } - for (int i = 26; i < 128; ++i) - { - VERIFY_IS_FALSE(buf1[i].is_done()); - } - rwbuf.close().get(); - } - - TEST(producer_consumer_buffer_close_reader_early) - { - streams::producer_consumer_buffer<char> rwbuf; - - VERIFY_IS_TRUE(rwbuf.is_open()); - VERIFY_IS_TRUE(rwbuf.can_read()); - VERIFY_IS_TRUE(rwbuf.can_write()); - - rwbuf.close(std::ios::in).wait(); - - // Even though we have closed for read, we should - // still be able to write. - - auto size = rwbuf.in_avail(); - - for (char c = 'a'; c <= 'z'; ++c) - VERIFY_ARE_EQUAL((int)c, rwbuf.putc(c).get()); - - VERIFY_ARE_EQUAL(size, rwbuf.in_avail()); - - std::string text1 = "This is a test"; - size_t len1 = text1.size(); - VERIFY_ARE_EQUAL(rwbuf.putn_nocopy(&text1[0], len1).get(), len1); - - VERIFY_ARE_EQUAL(size, rwbuf.in_avail()); - - rwbuf.close().get(); - } - - TEST(container_buffer_exception_propagation) - { - struct MyException - { - }; - { - streams::stringstreambuf rwbuf(std::string("this is the test")); - rwbuf.close(std::ios::out, std::make_exception_ptr(MyException())).wait(); - char buffer[100]; - VERIFY_ARE_EQUAL(rwbuf.getn(buffer, 100).get(), 16); - VERIFY_THROWS(rwbuf.getn(buffer, 100).get(), MyException); - VERIFY_THROWS(rwbuf.getc().get(), MyException); - VERIFY_IS_FALSE(rwbuf.exception() == nullptr); - } - { - streams::stringstreambuf rwbuf(std::string("this is the test")); - rwbuf.close(std::ios::in, std::make_exception_ptr(MyException())); - char buffer[100]; - VERIFY_THROWS(rwbuf.getn(buffer, 100).get(), MyException); - VERIFY_THROWS(rwbuf.getc().get(), MyException); - VERIFY_IS_FALSE(rwbuf.exception() == nullptr); - } - - { - streams::stringstreambuf rwbuf; - rwbuf.putn_nocopy("this is the test", 16); - rwbuf.close(std::ios::out, std::make_exception_ptr(MyException())); - VERIFY_THROWS(rwbuf.putn_nocopy("this is the test", 16).get(), MyException); - VERIFY_THROWS(rwbuf.putc('c').get(), MyException); - VERIFY_IS_FALSE(rwbuf.exception() == nullptr); - } - } - - TEST(producer_consumer_buffer_exception_propagation) - { - struct MyException - { - }; - { - streams::producer_consumer_buffer<char> rwbuf; - rwbuf.putn_nocopy("this is the test", 16); - rwbuf.close(std::ios::out, std::make_exception_ptr(MyException())); - char buffer[100]; - VERIFY_ARE_EQUAL(rwbuf.getn(buffer, 100).get(), 16); - VERIFY_THROWS(rwbuf.getn(buffer, 100).get(), MyException); - VERIFY_THROWS(rwbuf.getc().get(), MyException); - VERIFY_IS_FALSE(rwbuf.exception() == nullptr); - } - { - streams::producer_consumer_buffer<char> rwbuf; - rwbuf.putn_nocopy("this is the test", 16); - rwbuf.close(std::ios::in, std::make_exception_ptr(MyException())); - char buffer[100]; - VERIFY_THROWS(rwbuf.getn(buffer, 100).get(), MyException); - VERIFY_THROWS(rwbuf.getc().get(), MyException); - VERIFY_IS_FALSE(rwbuf.exception() == nullptr); - } - - { - streams::producer_consumer_buffer<char> rwbuf; - rwbuf.putn_nocopy("this is the test", 16); - rwbuf.close(std::ios::out, std::make_exception_ptr(MyException())); - VERIFY_THROWS(rwbuf.putn_nocopy("this is the test", 16).get(), MyException); - VERIFY_THROWS(rwbuf.putc('c').get(), MyException); - VERIFY_IS_FALSE(rwbuf.exception() == nullptr); - } - } - - TEST(producer_consumer_alloc_after_close) - { - producer_consumer_buffer<char> buffer; - buffer.close().wait(); - VERIFY_IS_TRUE(buffer.alloc(2) == nullptr); - - buffer = producer_consumer_buffer<char>(); - buffer.close(std::ios::out); - VERIFY_IS_TRUE(buffer.alloc(2) == nullptr); - } - - TEST(producer_consumer_acquire_after_close) - { - char* temp = nullptr; - size_t size = 0; - producer_consumer_buffer<char> buffer; - buffer.close().wait(); - VERIFY_IS_FALSE(buffer.acquire(temp, size)); - VERIFY_IS_TRUE(nullptr == temp); - VERIFY_ARE_EQUAL(0, size); - buffer.release(temp, size); - - buffer = producer_consumer_buffer<char>(); - buffer.close(std::ios::out); - temp = (char*)1; - size = 1; - VERIFY_IS_TRUE(buffer.acquire(temp, size)); - VERIFY_IS_TRUE(nullptr == temp); - VERIFY_ARE_EQUAL(0, size); - buffer.release(temp, size); - } - - TEST(create_buffers_inout_error) - { - VERIFY_THROWS(container_buffer<std::string>(std::ios::in | std::ios::out), std::invalid_argument); - VERIFY_THROWS(container_buffer<std::string>("test data", std::ios::in | std::ios::out), std::invalid_argument); - char* data = nullptr; - VERIFY_THROWS(rawptr_buffer<char>(data, 2, std::ios::in | std::ios::out), std::invalid_argument); - } - - TEST(memstream_length) - { - producer_consumer_buffer<unsigned char> rbuf; - auto istr = rbuf.create_istream(); - - auto curr = istr.tell(); - VERIFY_ARE_EQUAL((long long)curr, 0); - } - - TEST(buffer_size) - { - { - container_buffer<std::string> buf("test data"); - VERIFY_IS_TRUE(buf.has_size()); - VERIFY_ARE_EQUAL(buf.size(), 9); - buf.seekoff(1024, std::ios::beg, std::ios::in); - VERIFY_ARE_EQUAL(buf.size(), 9); - } - { - container_buffer<std::string> buf; - VERIFY_IS_TRUE(buf.has_size()); - VERIFY_ARE_EQUAL(buf.size(), 0); - buf.seekoff(1024, std::ios::beg, std::ios::out); - VERIFY_ARE_EQUAL(buf.size(), 1024); - VERIFY_ARE_EQUAL(buf.collection().size(), 1024); - } - { - producer_consumer_buffer<uint8_t> buf; - VERIFY_IS_FALSE(buf.has_size()); - VERIFY_ARE_EQUAL(buf.size(), 0); - } - } - - TEST(rawptr_alloc_after_close) - { - char data[2]; - rawptr_buffer<char> buffer(&data[0], sizeof(data), std::ios::out); - buffer.close().wait(); - VERIFY_IS_TRUE(buffer.alloc(2) == nullptr); - - buffer = rawptr_buffer<char>(&data[0], sizeof(data), std::ios::out); - buffer.close(std::ios::out); - VERIFY_IS_TRUE(buffer.alloc(2) == nullptr); - } - - TEST(rawptr_alloc_too_large) - { - char data[4]; - rawptr_buffer<char> buffer(&data[0], sizeof(data), std::ios::out); - VERIFY_IS_TRUE(buffer.alloc(10) == nullptr); - } - - TEST(rawptr_buffer_acquire_after_close) - { - char* temp = nullptr; - size_t size = 0; - char data[2]; - rawptr_buffer<char> buffer(&data[0], sizeof(data), std::ios::in); - buffer.close().wait(); - VERIFY_IS_FALSE(buffer.acquire(temp, size)); - VERIFY_IS_TRUE(nullptr == temp); - VERIFY_ARE_EQUAL(0, size); - buffer.release(temp, size); - - buffer = rawptr_buffer<char>(nullptr, 0, std::ios::in); - temp = (char*)1; - size = 1; - VERIFY_IS_TRUE(buffer.acquire(temp, size)); - VERIFY_IS_TRUE(nullptr == temp); - VERIFY_ARE_EQUAL(0, size); - buffer.release(temp, size); - } - - TEST(container_buffer_alloc_after_close) - { - container_buffer<std::string> buffer; - buffer.close().wait(); - VERIFY_IS_TRUE(buffer.alloc(2) == nullptr); - - buffer = container_buffer<std::string>(); - buffer.close(std::ios::out); - VERIFY_IS_TRUE(buffer.alloc(2) == nullptr); - } - - TEST(container_buffer_acquire_after_close) - { - char* temp = nullptr; - size_t size = 0; - container_buffer<std::string> buffer("test data"); - buffer.close().wait(); - VERIFY_IS_FALSE(buffer.acquire(temp, size)); - VERIFY_IS_TRUE(nullptr == temp); - VERIFY_ARE_EQUAL(0, size); - buffer.release(temp, size); - - buffer = container_buffer<std::string>(std::ios::in); - temp = (char*)1; - size = 1; - VERIFY_IS_TRUE(buffer.acquire(temp, size)); - VERIFY_IS_TRUE(nullptr == temp); - VERIFY_ARE_EQUAL(0, size); - buffer.release(temp, size); - } - - TEST(bytestream_length) - { - // test byte stream - std::string s("12345"); - auto istr = bytestream::open_istream(s); - test_stream_length(istr, s.size()); - } - - TEST(read_pending_close_with_exception) - { - producer_consumer_buffer<char> sourceBuf; - - const size_t size = 4; - char buf[size]; - memset(&buf[0], '0', size); - auto firstRead = sourceBuf.getn(buf, size); - sourceBuf.putc('a').wait(); - - sourceBuf.close(std::ios::in | std::ios::out, std::make_exception_ptr(std::runtime_error("test exception"))) - .wait(); - VERIFY_ARE_EQUAL(firstRead.get(), 1); - VERIFY_ARE_EQUAL(buf[0], 'a'); - VERIFY_ARE_EQUAL(buf[1], '0'); - VERIFY_ARE_EQUAL(buf[2], '0'); - VERIFY_ARE_EQUAL(buf[3], '0'); - - VERIFY_THROWS(sourceBuf.getn(buf, size).get(), std::runtime_error); - VERIFY_ARE_EQUAL(buf[0], 'a'); - VERIFY_ARE_EQUAL(buf[1], '0'); - VERIFY_ARE_EQUAL(buf[2], '0'); - VERIFY_ARE_EQUAL(buf[3], '0'); - } - - TEST(close_on_one_head_write) - { - producer_consumer_buffer<char> sourceBuf; - sourceBuf.putc('a').wait(); - - auto ostream = sourceBuf.create_ostream(); - - ostream.close().wait(); - - // Check that the exception is generated by the 'get(),' not the operation. - auto t1 = sourceBuf.putc('b'); - auto t2 = ostream.write('b'); - VERIFY_ARE_EQUAL(t1.get(), streams::streambuf<char>::traits::eof()); - VERIFY_THROWS(t2.get(), std::runtime_error); - VERIFY_ARE_EQUAL(sourceBuf.getc().get(), 'a'); - } - - TEST(close_on_one_head_read) - { - producer_consumer_buffer<char> sourceBuf; - sourceBuf.putc('a').wait(); - - auto istream = sourceBuf.create_istream(); - - istream.close().wait(); - - // Check that the exception is generated by the 'get(),' not the operation. - auto t1 = sourceBuf.bumpc(); - auto t2 = istream.read(); - VERIFY_ARE_EQUAL(t1.get(), streams::streambuf<char>::traits::eof()); - VERIFY_THROWS(t2.get(), std::runtime_error); - VERIFY_ARE_EQUAL(sourceBuf.putc('a').get(), 'a'); - } - - TEST(close_with_exception_on_one_head_write) - { - producer_consumer_buffer<char> sourceBuf; - sourceBuf.putc('a').wait(); - - auto ostream = sourceBuf.create_ostream(); - - ostream.close(std::make_exception_ptr(std::invalid_argument("test exception"))).wait(); - - // Check that the exception is generated by the 'get(),' not the operation. - auto t1 = sourceBuf.putc('b'); - auto t2 = ostream.write('b'); - VERIFY_THROWS(t1.get(), std::invalid_argument); - VERIFY_THROWS(t2.get(), std::invalid_argument); - VERIFY_ARE_EQUAL(sourceBuf.getc().get(), 'a'); - } - - TEST(close_with_exception_on_one_head_read) - { - producer_consumer_buffer<char> sourceBuf; - sourceBuf.putc('a').wait(); - - auto istream = sourceBuf.create_istream(); - - istream.close(std::make_exception_ptr(std::invalid_argument("test exception"))).wait(); - - // Check that the exception is generated by the 'get(),' not the operation. - auto t1 = sourceBuf.bumpc(); - auto t2 = istream.read(); - VERIFY_THROWS(t1.get(), std::invalid_argument); - VERIFY_THROWS(t2.get(), std::invalid_argument); - VERIFY_ARE_EQUAL(sourceBuf.putc('a').get(), 'a'); - } - - TEST(close_twice) - { - // This test passes if it does not generate an exception. - { - producer_consumer_buffer<char> sourceBuf; - sourceBuf.close(std::ios::in).wait(); - sourceBuf.close(std::ios::in).wait(); - } - { - producer_consumer_buffer<char> sourceBuf; - sourceBuf.close(std::ios::out).wait(); - sourceBuf.close(std::ios::out).wait(); - } - { - producer_consumer_buffer<char> sourceBuf; - sourceBuf.close().wait(); - sourceBuf.close().wait(); - } - } -} - -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/ostream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/ostream_tests.cpp @@ -1,398 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for async output stream operations. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -using namespace concurrency::streams; - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -namespace tests -{ -namespace functional -{ -namespace streams -{ -using namespace utility; -using namespace ::pplx; - -// -// The following two functions will help mask the differences between non-WinRT environments and -// WinRT: on the latter, a file path is typically not used to open files. Rather, a UI element is used -// to get a 'StorageFile' reference and you go from there. However, to test the library properly, -// we need to get a StorageFile reference somehow, and one way to do that is to create all the files -// used in testing in the Documents folder. -// -template<typename _CharType> -pplx::task<concurrency::streams::basic_ostream<_CharType>> OPENSTR_W(const utility::string_t& name, - std::ios_base::openmode mode = std::ios_base::out) -{ -#if !defined(__cplusplus_winrt) - return concurrency::streams::file_stream<_CharType>::open_ostream(name, mode); -#else - auto file = pplx::create_task(KnownFolders::DocumentsLibrary->CreateFileAsync( - ref new Platform::String(name.c_str()), CreationCollisionOption::ReplaceExisting)) - .get(); - - return concurrency::streams::file_stream<_CharType>::open_ostream(file, mode); -#endif -} - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4100) // Because of '_Prot' in WinRT builds. -#endif -template<typename _CharType> -pplx::task<concurrency::streams::basic_istream<_CharType>> OPENSTR_R(const utility::string_t& name, - std::ios_base::openmode mode = std::ios_base::in) -{ -#if !defined(__cplusplus_winrt) - return concurrency::streams::file_stream<_CharType>::open_istream(name, mode); -#else - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))).get(); - - return concurrency::streams::file_stream<_CharType>::open_istream(file, mode); -#endif -} -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -SUITE(ostream_tests) -{ - TEST(BasicTest1) - { - auto open = OPENSTR_W<uint8_t>(U("BasicTest1.txt")); - auto basic_stream = open.get(); - VERIFY_IS_TRUE(basic_stream.can_seek()); - auto a = basic_stream.print(10); - auto b = basic_stream.print("-suffix"); - (a && b).wait(); - auto cls = basic_stream.close(); - cls.get(); - VERIFY_IS_TRUE(cls.is_done()); - } - - TEST(BasicTest2) - { - auto open = OPENSTR_W<uint8_t>(U("BasicTest2.txt")); - - auto cls = open.then([](pplx::task<concurrency::streams::ostream> op) -> pplx::task<void> { - auto basic_stream = op.get(); - auto a = basic_stream.print(10); - auto b = basic_stream.print("-suffix"); - (a && b).wait(); - return basic_stream.close(); - }); - - cls.get(); - - VERIFY_IS_TRUE(cls.is_done()); - } - - TEST(WriteSingleCharTest2) - { - auto open = OPENSTR_W<uint8_t>(U("WriteSingleCharStrTest1.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - - bool elements_equal = true; - - for (uint8_t ch = 'a'; ch <= 'z'; ch++) - { - elements_equal = elements_equal && (ch == stream.write(ch).get()); - } - - VERIFY_IS_TRUE(elements_equal); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - } - - TEST(WriteBufferTest1) - { - auto open = OPENSTR_W<uint8_t>(U("WriteBufferStrTest1.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - - std::vector<uint8_t> vect; - - for (char ch = 'a'; ch <= 'z'; ch++) - { - vect.push_back(ch); - } - - size_t vsz = vect.size(); - - concurrency::streams::container_stream<std::vector<uint8_t>>::buffer_type txtbuf(std::move(vect), - std::ios_base::in); - - VERIFY_ARE_EQUAL(stream.write(txtbuf, vsz).get(), vsz); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - } - - TEST(WriteBufferAndSyncTest1) - { - auto open = OPENSTR_W<uint8_t>(U("WriteBufferAndSyncStrTest1.txt")); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - - std::vector<char> vect; - - for (char ch = 'a'; ch <= 'z'; ch++) - { - vect.push_back(ch); - } - - size_t vsz = vect.size(); - concurrency::streams::rawptr_buffer<uint8_t> txtbuf(reinterpret_cast<const uint8_t*>(&vect[0]), vsz); - - auto write = stream.write(txtbuf, vsz); - stream.flush().get(); - - VERIFY_ARE_EQUAL(write.get(), vect.size()); - VERIFY_IS_TRUE(write.is_done()); - - auto close = stream.close(); - close.get(); - - VERIFY_IS_TRUE(close.is_done()); - } - - TEST(tell_bug) - { - auto count = OPENSTR_W<uint8_t>(U("tell_bug.txt"), std::ios_base::out | std::ios_base::trunc) - .then([=](concurrency::streams::ostream os) -> std::streamoff { - os.print("A"); - auto val = os.tell(); - os.close().get(); - return val; - }) - .get(); - - VERIFY_ARE_EQUAL(std::streamoff(1), count); - } - - TEST(iostream_container_buffer1) - { - concurrency::streams::container_buffer<std::vector<char>> buf; - - auto os = buf.create_ostream(); - os.write('a'); - os.write('b'); - os.close(); - - auto is = concurrency::streams::container_stream<std::vector<char>>::open_istream(std::move(buf.collection())); - VERIFY_ARE_EQUAL(is.read().get(), 'a'); - VERIFY_ARE_EQUAL(is.read().get(), 'b'); - } - - TEST(iostream_container_buffer2) - { - concurrency::streams::container_buffer<std::vector<char>> buf; - - { - auto os = buf.create_ostream(); - os.write('a'); - os.write('b'); - os.close(); - } - - { - auto is = - concurrency::streams::container_stream<std::vector<char>>::open_istream(std::move(buf.collection())); - - is.read() - .then([&is](concurrency::streams::basic_ostream<char>::int_type c) { - VERIFY_ARE_EQUAL(c, 'a'); - return is.read(); - }) - .then([&is](concurrency::streams::basic_ostream<char>::int_type c) -> pplx::task<void> { - VERIFY_ARE_EQUAL(c, 'b'); - return is.close(); - }) - .wait(); - } - } - - TEST(extract_on_space) - { - const int number1 = 42; - const int number2 = 123; - - auto open = OPENSTR_W<uint8_t>(U("SpaceWithNumber.txt"), std::ios::trunc); - auto stream = open.get(); - VERIFY_IS_TRUE(open.is_done()); - stream.print(" \r").wait(); - stream.print(number1).wait(); - stream.print("\n \t").wait(); - stream.print(number2).wait(); - stream.print(" \f \v ").wait(); - stream.close().wait(); - - auto istream = OPENSTR_R<uint8_t>(U("SpaceWithNumber.txt")).get(); - VERIFY_IS_TRUE(istream.can_seek()); - VERIFY_ARE_EQUAL(number1, istream.extract<int>().get()); - VERIFY_ARE_EQUAL(number2, istream.extract<long long>().get()); - } - - TEST(file_sequential_write) - { - auto open = OPENSTR_W<uint8_t>(U("WriteFileSequential.txt"), std::ios::trunc); - auto stream = open.get(); - - VERIFY_IS_TRUE(open.is_done()); - - std::vector<pplx::task<size_t>> v; - for (int i = 0; i < 100; i++) - { - v.push_back(stream.print(i)); - v.push_back(stream.print(' ')); - } - pplx::when_all(v.begin(), v.end()).wait(); - stream.close().wait(); - auto istream = OPENSTR_R<uint8_t>(U("WriteFileSequential.txt")).get(); - for (int i = 0; i < 100; i++) - { - int int_read = istream.extract<int>().get(); - if (int_read != i) - { - // This will fail - VERIFY_ARE_EQUAL(int_read, i); - - // This return statment will prevent the test from hanging, - // cause if the numbers are merged there will be less than 100 numbers, - // and reading from the file will block - return; - } - istream.read().get(); - } - } - - TEST(implied_out_mode) - { - auto ostr = OPENSTR_W<char>(U("implied_out_mode.txt"), std::ios::ios_base::app).get(); - - std::string str = "abcd"; - concurrency::streams::stringstreambuf block(str); - - size_t s = ostr.write(block, str.size()).get(); - - VERIFY_ARE_EQUAL(s, str.size()); - - auto cls = ostr.close(); - - cls.get(); - VERIFY_IS_TRUE(cls.is_done()); - } - - TEST(create_ostream_from_input_only) - { - container_buffer<std::string> sourceBuf("test data"); - VERIFY_THROWS(sourceBuf.create_ostream(), std::runtime_error); - } - - TEST(streambuf_close_with_exception_write) - { - container_buffer<std::string> sourceBuf; - sourceBuf.close(std::ios::out, std::make_exception_ptr(std::invalid_argument("custom exception"))).wait(); - - const size_t size = 4; - char targetBuf[size]; - auto t1 = sourceBuf.putn_nocopy(targetBuf, size); - VERIFY_THROWS(t1.get(), std::invalid_argument); - } - - TEST(stream_close_with_exception_write) - { - container_buffer<std::string> sourceBuf; - auto outStream = sourceBuf.create_ostream(); - outStream.close(std::make_exception_ptr(std::invalid_argument("custom exception"))).wait(); - - container_buffer<std::string> targetBuf("test data"); - auto t1 = outStream.write(targetBuf, 4); - VERIFY_THROWS(t1.get(), std::invalid_argument); - } - - TEST(input_after_close) - { - container_buffer<std::string> sourceBuf; - auto outStream = sourceBuf.create_ostream(); - outStream.close().wait(); - - container_buffer<std::string> targetBuf; - - auto t1 = outStream.flush(); - auto t2 = outStream.print('a'); - auto t3 = outStream.print(std::string("abc")); - - VERIFY_THROWS(t1.get(), std::runtime_error); - VERIFY_THROWS(t2.get(), std::runtime_error); - VERIFY_THROWS(t3.get(), std::runtime_error); - VERIFY_THROWS(outStream.seek(0), std::runtime_error); - VERIFY_THROWS(outStream.seek(0, std::ios::beg), std::runtime_error); - VERIFY_THROWS(outStream.tell(), std::runtime_error); - - auto t4 = outStream.write('a'); - auto t5 = outStream.write(targetBuf, 1); - VERIFY_THROWS(t4.get(), std::runtime_error); - VERIFY_THROWS(t5.get(), std::runtime_error); - } - - TEST(write_emptybuffer_to_ostream) - { - auto ofs = OPENSTR_W<char>(U("file.txt")).get(); - auto sbuf = concurrency::streams::producer_consumer_buffer<char>(); - auto result = ofs.write(sbuf, 0); - VERIFY_ARE_EQUAL(result.get(), 0); - } - - TEST(write_stream_twice) - { - producer_consumer_buffer<uint8_t> buf1; - auto t1 = pplx::create_task([&] { - buf1.alloc(8); - buf1.alloc(9); - }); - VERIFY_THROWS(t1.get(), std::logic_error); - - std::string strData("test string to write\n"); - container_buffer<std::string> buf2(std::move(strData)); - auto t2 = pplx::create_task([&] { - buf2.commit(8); - buf2.alloc(9); - }); - VERIFY_THROWS(t2.get(), std::logic_error); - - rawptr_buffer<std::string> buf3; - auto t3 = pplx::create_task([&] { - buf3.commit(8); - buf3.commit(9); - }); - VERIFY_THROWS(t3.get(), std::logic_error); - } - -} // SUITE(ostream_tests) - -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/prefix.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/prefix.h @@ -1,61 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * stdafx.h - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#ifndef __PREFIX_H -#define __PREFIX_H - -#include <fstream> -#include <memory> -#include <stdio.h> -#include <time.h> -#include <vector> - -#if defined(_MSC_VER) && (_MSC_VER >= 1800) -#include <ppltasks.h> -namespace pplx = Concurrency; -#else -#include "pplx/pplxtasks.h" -#endif - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/containerstream.h" -#include "cpprest/filestream.h" -#include "cpprest/interopstream.h" -#include "cpprest/producerconsumerstream.h" -#include "cpprest/rawptrstream.h" -#include "cpprest/streams.h" -#include "streams_tests.h" -#include "unittestpp.h" - -template class concurrency::streams::file_buffer<char>; -template class concurrency::streams::file_buffer<wchar_t>; -template class concurrency::streams::streambuf<char>; -template class concurrency::streams::streambuf<wchar_t>; - -template class concurrency::streams::rawptr_buffer<char>; -template class concurrency::streams::rawptr_buffer<wchar_t>; -template class concurrency::streams::rawptr_buffer<uint8_t>; -template class concurrency::streams::rawptr_buffer<utf16char>; - -template class concurrency::streams::container_buffer<std::vector<uint8_t>>; -template class concurrency::streams::container_buffer<std::vector<char>>; -template class concurrency::streams::container_buffer<std::vector<utf16char>>; - -template class concurrency::streams::producer_consumer_buffer<char>; -template class concurrency::streams::producer_consumer_buffer<uint8_t>; -template class concurrency::streams::producer_consumer_buffer<utf16char>; - -template class concurrency::streams::container_stream<std::basic_string<char>>; -template class concurrency::streams::container_stream<std::basic_string<wchar_t>>; - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/stdafx.cpp @@ -1,14 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" - -#if WIN32 -__declspec(dllexport) int streams_test_generate_lib = 0; -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/stdafx.h @@ -1,38 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * stdafx.h - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include <fstream> -#include <memory> -#include <stdio.h> -#include <time.h> -#include <vector> - -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) && !CPPREST_FORCE_PPLX -#include <ppltasks.h> -namespace pplx = Concurrency; -#else -#include "pplx/pplxtasks.h" -#endif - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/containerstream.h" -#include "cpprest/filestream.h" -#include "cpprest/interopstream.h" -#include "cpprest/producerconsumerstream.h" -#include "cpprest/rawptrstream.h" -#include "cpprest/streams.h" -#include "os_utilities.h" -#include "streams_tests.h" -#include "unittestpp.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/stdstream_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/stdstream_tests.cpp @@ -1,804 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for integration of async streams with std streams. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -#include "cpprest/filestream.h" -#include "cpprest/producerconsumerstream.h" -#include "cpprest/rawptrstream.h" - -#if (!defined(_WIN32) || !defined(CPPREST_EXCLUDE_WEBSOCKETS)) && !defined(__cplusplus_winrt) -#include <boost/interprocess/streams/bufferstream.hpp> -#endif - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -#ifdef _WIN32 -#define DEFAULT_PROT (int)std::ios_base::_Openprot -#else -#define DEFAULT_PROT 0 -#endif - -namespace tests -{ -namespace functional -{ -namespace streams -{ -using namespace ::pplx; -using namespace utility; - -utility::string_t get_full_name(const utility::string_t& name); - -template<typename CharType> -void extract_test(std::basic_istream<CharType>& stream, std::basic_string<CharType> expected) -{ - std::basic_string<CharType> s; - stream >> s; - VERIFY_ARE_EQUAL(s, expected); -} - -// Used to prepare data for read tests - -void fill_file(const utility::string_t& name, std::string text, size_t repetitions = 1) -{ - std::fstream stream(get_full_name(name), std::ios_base::out | std::ios_base::trunc); - - for (size_t i = 0; i < repetitions; i++) - stream << text; -} - -// -// The following functions will help mask the differences between non-WinRT environments and -// WinRT: on the latter, a file path is typically not used to open files. Rather, a UI element is used -// to get a 'StorageFile' reference and you go from there. However, to test the library properly, -// we need to get a StorageFile reference somehow, and one way to do that is to create all the files -// used in testing in the Documents folder. -// -template<typename _CharType> -pplx::task<Concurrency::streams::streambuf<_CharType>> OPEN_R(const utility::string_t& name) -{ -#if !defined(__cplusplus_winrt) - return Concurrency::streams::file_buffer<_CharType>::open(name, std::ios_base::in); -#else - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))).get(); - - return Concurrency::streams::file_buffer<_CharType>::open(file, std::ios_base::in); -#endif -} - -SUITE(stdstreambuf_tests) -{ - TEST(sync_on_async_write) - { - Concurrency::streams::stringstreambuf strbuf; - auto ss = strbuf.create_ostream(); - Concurrency::streams::async_ostream<char> bios(ss); - - auto text = "hello!"; - - bios.write(text, strlen(text)); - - auto buf = ss.streambuf(); - - VERIFY_ARE_EQUAL(strbuf.collection(), "hello!"); - } - - TEST(sync_on_async_put) - { - Concurrency::streams::stringstreambuf strbuf; - auto ss = strbuf.create_ostream(); - Concurrency::streams::async_ostream<char> bios(ss); - - bios.put('h').put('e').put('l').put('l').put('o').put('!'); - - VERIFY_ARE_EQUAL(strbuf.collection(), "hello!"); - } - - TEST(sync_on_async_insert) - { - Concurrency::streams::stringstreambuf strbuf; - auto ss = strbuf.create_ostream(); - Concurrency::streams::async_ostream<char> bios(ss); - - bios << "hello" - << ", there, this is " << 4711; - - VERIFY_ARE_EQUAL(strbuf.collection(), "hello, there, this is 4711"); - ss.close().wait(); - } - - TEST(sync_on_async_seekp) - { - Concurrency::streams::stringstreambuf strbuf; - auto ss = strbuf.create_ostream(); - Concurrency::streams::async_ostream<char> bios(ss); - - bios << "hello" - << ", there, this is " << 4711; - - bios.seekp(10); - bios << 'X'; - - VERIFY_ARE_EQUAL(strbuf.collection(), "hello, theXe, this is 4711"); - ss.close().wait(); - } - - TEST(sync_on_async_getline_1) - { - std::string s("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - auto ss = Concurrency::streams::stringstream::open_istream(s); - - Concurrency::streams::async_iostream<char> bios(ss.streambuf()); - - char chars[128]; - bios.getline(chars, sizeof(chars)); - - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0); - } - - TEST(sync_on_async_getline_2) - { - std::string s("abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"); - auto ss = Concurrency::streams::stringstream::open_istream(s); - - Concurrency::streams::async_iostream<char> bios(ss.streambuf()); - - char chars[128]; - - bios.getline(chars, sizeof(chars)); - - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyz"), 0); - - VERIFY_ARE_EQUAL(bios.get(), 'A'); - } - - TEST(sync_on_async_getline_3) - { - std::string s("abcdefghijklmnopqrstuvwxyz|ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - auto ss = Concurrency::streams::stringstream::open_istream(s); - - Concurrency::streams::async_iostream<char> bios(ss.streambuf()); - - char chars[128]; - - bios.getline(chars, sizeof(chars), '|'); - - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyz"), 0); - - VERIFY_ARE_EQUAL(bios.get(), 'A'); - } - - TEST(sync_on_async_get_1) - { - std::string s("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - auto ss = Concurrency::streams::stringstream::open_istream(s); - - Concurrency::streams::async_iostream<char> bios(ss.streambuf()); - - char chars[128]; - - bios.get(chars, sizeof(chars)); - - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0); - } - - TEST(sync_on_async_fget_1) - { - utility::string_t fname = U("sync_on_async_fget_1.txt"); - fill_file(fname, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - - auto ofs = OPEN_R<char>(fname).get(); - Concurrency::streams::async_istream<char> bios(ofs); - - char chars[128]; - - bios.get(chars, sizeof(chars)); - - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0); - ofs.close().wait(); - } - - TEST(sync_on_async_get_2) - { - std::string s("abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"); - auto ss = Concurrency::streams::stringstream::open_istream(s); - - Concurrency::streams::async_iostream<char> bios(ss.streambuf()); - - char chars[128]; - - bios.get(chars, sizeof(chars)); - - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyz"), 0); - - VERIFY_ARE_EQUAL(bios.get(), '\n'); - } - - TEST(sync_on_async_get_3) - { - std::string s("abcdefghijklmnopqrstuvwxyz|ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - auto ss = Concurrency::streams::stringstream::open_istream(s); - - Concurrency::streams::async_iostream<char> bios(ss.streambuf()); - - char chars[128]; - - bios.get(chars, sizeof(chars), '|'); - - VERIFY_ARE_EQUAL(strcmp(chars, "abcdefghijklmnopqrstuvwxyz"), 0); - - VERIFY_ARE_EQUAL(bios.get(), '|'); - } - - TEST(sync_on_async_extract_1) - { - auto ss = Concurrency::streams::stringstream::open_istream(std::string("abcdefg 10 1 9.4711")); - - Concurrency::streams::async_iostream<char> bios(ss.streambuf()); - - std::string s; - int i; - bool b; - double d; - - bios >> s >> i >> b >> d; - - VERIFY_ARE_EQUAL(s, "abcdefg"); - VERIFY_ARE_EQUAL(i, 10); - VERIFY_IS_TRUE(b); - VERIFY_ARE_EQUAL(d, 9.4711); - } - - TEST(sync_on_async_fextract_1) - { - utility::string_t fname = U("sync_on_async_fextract_1.txt"); - fill_file(fname, "abcdefg 10 1 9.4711"); - - auto ofs = OPEN_R<char>(fname).get(); - Concurrency::streams::async_istream<char> bios(ofs); - - std::string s; - int i; - bool b; - double d; - - bios >> s >> i >> b >> d; - - VERIFY_ARE_EQUAL(s, "abcdefg"); - VERIFY_ARE_EQUAL(i, 10); - VERIFY_IS_TRUE(b); - VERIFY_ARE_EQUAL(d, 9.4711); - - ofs.close().wait(); - } - - TEST(sync_on_async_extract_2) - { - std::string s("abcdefg 10 1 9.4711"); - auto is = Concurrency::streams::stringstream::open_istream(s); - - Concurrency::streams::async_istream<char> ss(is.streambuf()); - extract_test<char>(ss, "abcdefg"); - - is.close().wait(); - } - - TEST(sync_on_async_prodcons) - { - Concurrency::streams::producer_consumer_buffer<uint8_t> pcbuf; - - auto ostream = pcbuf.create_ostream(); - auto istream = pcbuf.create_istream(); - - const std::streamsize iterations = 100; - - const std::string the_alphabet("abcdefghijklmnopqrstuvwxyz"); - - auto writer = pplx::create_task([ostream, iterations, the_alphabet]() { - auto os = ostream; - for (std::streamsize i = 0; i < iterations; i++) - { - os.print(the_alphabet).wait(); - os.flush().wait(); - } - os.close(); - }); - - Concurrency::streams::async_istream<char> ss(istream.streambuf()); - - char chars[1024]; - std::streamsize count = 0; - - while (!ss.eof()) - { - memset(chars, 0, sizeof(chars)); - ss.read(chars, sizeof(chars) - 1); - count += strlen(chars); - } - - VERIFY_ARE_EQUAL(the_alphabet.size() * iterations, count); - - writer.wait(); - } - - TEST(sync_on_async_tellg) - { - Concurrency::streams::producer_consumer_buffer<uint8_t> pcbuf; - - auto ostream = pcbuf.create_ostream(); - auto istream = pcbuf.create_istream(); - - const std::streamsize iterations = 100; - - const std::string the_alphabet("abcdefghijklmnopqrstuvwxyz"); - - auto writer = pplx::create_task([ostream, iterations, the_alphabet]() { - auto os = ostream; - for (std::streamsize i = 0; i < iterations; i++) - { - os.print(the_alphabet).wait(); - os.flush().wait(); - VERIFY_ARE_EQUAL((i + 1) * the_alphabet.size(), os.tell()); - } - os.close(); - }); - - Concurrency::streams::async_istream<char> ss(istream.streambuf()); - - char chars[1024]; - std::streamsize count = 0; - - while (!ss.eof()) - { - VERIFY_ARE_EQUAL(count, ss.tellg()); - memset(chars, 0, sizeof(chars)); - ss.read(chars, sizeof(chars) - 1); - count += strlen(chars); - } - - VERIFY_ARE_EQUAL(the_alphabet.size() * iterations, count); - - writer.wait(); - } - - TEST(async_on_sync_read_1) - { - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << "abcdefghijklmnopqrstuvwxyz"; - - for (char c = 'a'; c <= 'z'; c++) - { - char ch = (char)astream.read().get(); - VERIFY_ARE_EQUAL(c, ch); - } - - astream.close().get(); - } - - TEST(async_on_sync_read_2) - { - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << "abcdefghijklmnopqrstuvwxyz"; - - char buffer[128]; - Concurrency::streams::rawptr_buffer<char> txtbuf(buffer, 128); - - VERIFY_ARE_EQUAL(26, astream.read(txtbuf, 26).get()); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - VERIFY_ARE_EQUAL(0, astream.read(txtbuf, 26).get()); - - astream.close().get(); - } - - TEST(async_on_sync_read_3) - { - Concurrency::streams::producer_consumer_buffer<char> trg; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << text; - - VERIFY_ARE_EQUAL(52, astream.read_to_delim(trg, '\n').get()); - - char buffer[128]; - VERIFY_ARE_EQUAL(52, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'A', buffer[i + 26]); - } - - astream.close().get(); - } - - TEST(async_on_sync_read_4) - { - Concurrency::streams::producer_consumer_buffer<char> trg; - - // There's one newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << text; - - VERIFY_ARE_EQUAL(26, astream.read_to_delim(trg, '\n').get()); - VERIFY_ARE_EQUAL('A', (char)astream.read().get()); - - char buffer[128]; - VERIFY_ARE_EQUAL(26, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - astream.close().get(); - } - - TEST(async_on_sync_read_5) - { - Concurrency::streams::producer_consumer_buffer<char> trg; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << text; - - VERIFY_ARE_EQUAL(52, astream.read_to_delim(trg, '|').get()); - - char buffer[128]; - VERIFY_ARE_EQUAL(52, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'A', buffer[i + 26]); - } - - astream.close().get(); - } - - TEST(async_on_sync_read_6) - { - Concurrency::streams::producer_consumer_buffer<char> trg; - - // There's one delimiter in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz|ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << text; - - VERIFY_ARE_EQUAL(26, astream.read_to_delim(trg, '|').get()); - VERIFY_ARE_EQUAL('A', (char)astream.read().get()); - - char buffer[128]; - VERIFY_ARE_EQUAL(26, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - astream.close().get(); - } - - TEST(async_on_sync_read_line_1) - { - Concurrency::streams::producer_consumer_buffer<char> trg; - - // There's no newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << text; - - VERIFY_ARE_EQUAL(26, astream.read_line(trg).get()); - VERIFY_ARE_EQUAL('A', (char)astream.read().get()); - - char buffer[128]; - VERIFY_ARE_EQUAL(26, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - astream.close().get(); - } - - TEST(async_on_sync_read_to_end_1) - { - Concurrency::streams::producer_consumer_buffer<char> trg; - - // There's one newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << text; - - VERIFY_ARE_EQUAL(53, astream.read_to_end(trg).get()); - - char buffer[128]; - VERIFY_ARE_EQUAL(53, trg.in_avail()); - trg.getn(buffer, trg.in_avail()).get(); - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'a', buffer[i]); - } - - for (int i = 0; i < 26; i++) - { - VERIFY_ARE_EQUAL((char)i + 'A', buffer[i + 27]); - } - - astream.close().get(); - } - - TEST(ostream_write_single_char) - { - std::stringstream stream; - - Concurrency::streams::stdio_ostream<char> os(stream); - - bool elements_equal = true; - - for (char ch = 'a'; ch <= 'z'; ch++) - { - elements_equal = elements_equal && (ch == os.write(ch).get()); - } - - VERIFY_IS_TRUE(elements_equal); - - VERIFY_ARE_EQUAL(stream.str(), "abcdefghijklmnopqrstuvwxyz"); - - os.close().get(); - } - - TEST(ostream_write_buffer) - { - std::stringstream stream; - - Concurrency::streams::stdio_ostream<char> os(stream); - - const char* text = "abcdefghijklmnopqrstuvwxyz"; - size_t len = strlen(text); - - Concurrency::streams::rawptr_buffer<char> txtbuf(text, len); - - VERIFY_ARE_EQUAL(os.write(txtbuf, len).get(), len); - - VERIFY_ARE_EQUAL(stream.str(), "abcdefghijklmnopqrstuvwxyz"); - - os.close().get(); - } - - TEST(ostream_output_print_string) - { - std::stringstream stream; - - Concurrency::streams::stdio_ostream<char> os(stream); - - os.print("abcdefghijklmnopqrstuvwxyz").wait(); - - VERIFY_ARE_EQUAL(stream.str(), "abcdefghijklmnopqrstuvwxyz"); - - os.close().get(); - } - - TEST(ostream_output_print_types) - { - std::stringstream stream; - - Concurrency::streams::stdio_ostream<char> os(stream); - - auto a = os.print("data: "); - auto b = os.print(10); - auto c = os.print(","); - auto d = os.print(true); - (a && b && c && d).wait(); - - VERIFY_ARE_EQUAL(stream.str(), "data: 10,1"); - - os.close().get(); - } - - TEST(ostream_output_print_line_string) - { - std::stringstream stream; - - Concurrency::streams::stdio_ostream<char> os(stream); - - os.print_line("abcdefghijklmnopqrstuvwxyz").wait(); - - VERIFY_ARE_EQUAL(stream.str(), "abcdefghijklmnopqrstuvwxyz\n"); - - os.close().get(); - } - - TEST(ostream_output_print_line_types) - { - std::stringstream stream; - - Concurrency::streams::stdio_ostream<char> os(stream); - - auto a = os.print_line("data: "); - auto b = os.print_line(10); - auto c = os.print_line(","); - auto d = os.print_line(true); - (a && b && c && d).wait(); - - VERIFY_ARE_EQUAL(stream.str(), "data: \n10\n,\n1\n"); - - os.close().get(); - } - - TEST(istream_extract_string) - { - const char* text = " abc defgsf "; - - std::stringstream stream; - stream << text; - - Concurrency::streams::stdio_istream<char> is(stream); - - std::string str1 = is.extract<std::string>().get(); - std::string str2 = is.extract<std::string>().get(); - - VERIFY_ARE_EQUAL(str1, "abc"); - VERIFY_ARE_EQUAL(str2, "defgsf"); - - is.close().get(); - } - - TEST(stdio_istream_error) - { - std::ifstream inFile; - inFile.open("stdio_istream_error.txt"); - concurrency::streams::stdio_istream<char> is(inFile); - - concurrency::streams::container_buffer<std::string> buffer; - VERIFY_ARE_EQUAL(0, is.read_to_end(buffer).get()); - VERIFY_IS_TRUE(is.is_eof()); - VERIFY_IS_TRUE(is.is_open()); - - is.close().wait(); - } - - TEST(stdio_istream_setstate) - { - std::ifstream inFile; - inFile.open("stdio_istream_setstate.txt"); - concurrency::streams::stdio_istream<char> is(inFile); - inFile.setstate(std::ios::failbit); - - concurrency::streams::container_buffer<std::string> buffer; - VERIFY_ARE_EQUAL(0, is.read_to_end(buffer).get()); - VERIFY_IS_TRUE(is.is_eof()); - VERIFY_IS_TRUE(is.is_open()); - - is.close().wait(); - } - - TEST(stdio_istream_close) - { - std::ifstream inFile; - inFile.open("stdio_istream_close.txt"); - concurrency::streams::stdio_istream<char> is(inFile); - inFile.close(); - - concurrency::streams::container_buffer<std::string> buffer; - VERIFY_ARE_EQUAL(0, is.read_to_end(buffer).get()); - // Won't fix bug TFS 639208 - // VERIFY_IS_FALSE(is.is_open()); - VERIFY_IS_TRUE(is.is_eof()); - } - - TEST(sync_on_async_close_early) - { - concurrency::streams::container_buffer<std::string> buffer; - concurrency::streams::async_ostream<char> os(buffer); - buffer.close(); - - os << 10 << std::endl; - VERIFY_IS_TRUE((std::ios::badbit & os.rdstate()) == std::ios::badbit); - } - - TEST(sync_on_async_close_with_exception) - { - const std::string& data("abc123"); - - // Try with a read. - { - concurrency::streams::container_buffer<std::string> buffer(data); - concurrency::streams::async_istream<char> inputStream(buffer); - buffer.close(std::ios::in, std::make_exception_ptr(std::invalid_argument("test exception"))).wait(); - const size_t tempBufSize = 4; - char tempBuf[tempBufSize]; - inputStream.read(&tempBuf[0], tempBufSize); - VERIFY_ARE_EQUAL(std::ios::failbit | std::ios::eofbit, inputStream.rdstate()); - } - - // Try with a write. - { - concurrency::streams::container_buffer<std::string> buffer(data); - concurrency::streams::async_ostream<char> outputStream(buffer); - buffer.close(std::ios::in, std::make_exception_ptr(std::invalid_argument("test exception"))).wait(); - const size_t tempBufSize = 4; - char tempBuf[tempBufSize]; - outputStream.write(&tempBuf[0], tempBufSize); - VERIFY_ARE_EQUAL(std::ios::badbit, outputStream.rdstate()); - } - } - -#if (!defined(_WIN32) || !defined(CPPREST_EXCLUDE_WEBSOCKETS)) && !defined(__cplusplus_winrt) - TEST(ostream_full_throw_exception) - { - char tgt_buffer[5]; - boost::interprocess::bufferstream limited_stream( - tgt_buffer, sizeof(tgt_buffer), ::std::ios_base::out | std::ios_base::binary); - concurrency::streams::stdio_ostream<char> os_wrapper(limited_stream); - concurrency::streams::streambuf<char> os_streambuf = os_wrapper.streambuf(); - - // There's one newline in the input. - const char* text = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - std::stringstream stream; - Concurrency::streams::stdio_istream<char> astream(stream); - - stream << text; - - VERIFY_THROWS(astream.read_to_end(os_streambuf).get(), std::exception); - } -#endif -} -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/streams_tests.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/streams_tests.h @@ -1,88 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * streams_tests.h - * - * Common routines for streams tests. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include <system_error> -#include <unittestpp.h> - -namespace tests -{ -namespace functional -{ -namespace streams -{ -template<typename CharType> -void test_stream_length(concurrency::streams::basic_istream<CharType> istr, size_t length) -{ - using namespace concurrency::streams; - - auto curr = istr.tell(); - auto t1 = (curr != static_cast<typename basic_istream<CharType>::pos_type>(basic_istream<CharType>::traits::eof())); - VERIFY_IS_TRUE(t1); - - auto end = istr.seek(0, std::ios_base::end); - VERIFY_IS_TRUE(end != - static_cast<typename basic_istream<CharType>::pos_type>(basic_istream<CharType>::traits::eof())); - - auto len = end - curr; - - VERIFY_ARE_EQUAL(len, length); - - { - auto curr2 = istr.tell(); - VERIFY_IS_TRUE(curr != - static_cast<typename basic_istream<CharType>::pos_type>(basic_istream<CharType>::traits::eof())); - - auto end2 = istr.seek(0, std::ios_base::end); - VERIFY_IS_TRUE(end != - static_cast<typename basic_istream<CharType>::pos_type>(basic_istream<CharType>::traits::eof())); - - auto len2 = end2 - curr2; - - VERIFY_ARE_EQUAL(len2, 0); - } - - auto newpos = istr.seek(curr); - VERIFY_IS_TRUE(newpos != - static_cast<typename basic_istream<CharType>::pos_type>(basic_istream<CharType>::traits::eof())); - - VERIFY_ARE_EQUAL(curr, newpos); -} - -// Helper function to verify std::system_error is thrown with correct error code -#define VERIFY_THROWS_SYSTEM_ERROR(__expression, __code) \ - UNITTEST_MULTILINE_MACRO_BEGIN \ - try \ - { \ - __expression; \ - VERIFY_IS_TRUE(false, "Expected std::system_error not thrown"); \ - } \ - catch (const std::system_error& _exc) \ - { \ - VERIFY_IS_TRUE(std::string(_exc.what()).size() > 0); \ - /* The reason we can't directly compare with the given std::errc code is because*/ \ - /* on Windows the STL implementation of error categories are NOT unique across*/ \ - /* dll boundaries.*/ \ - const std::error_condition _condFound = _exc.code().default_error_condition(); \ - VERIFY_ARE_EQUAL(static_cast<int>(__code), _condFound.value()); \ - } \ - catch (...) \ - { \ - VERIFY_IS_TRUE(false, "Exception other than std::system_error thrown"); \ - } \ - UNITTEST_MULTILINE_MACRO_END - -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/winrt_interop_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/streams/winrt_interop_tests.cpp @@ -1,258 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Basic tests for winrt interop streams. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -using namespace concurrency::streams; -using namespace utility; -using namespace ::pplx; - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -namespace tests -{ -namespace functional -{ -namespace streams -{ -SUITE(winrt_interop_tests) -{ - TEST(read_in) - { - producer_consumer_buffer<char> buf; - auto ostream = buf.create_ostream(); - std::string strData("abcdefghij"); - buf.putn_nocopy((char*)&strData[0], strData.size() * sizeof(char)).wait(); - - auto dr = ref new Windows::Storage::Streams::DataReader(winrt_stream::create_input_stream(buf)); - dr->ByteOrder = Windows::Storage::Streams::ByteOrder::LittleEndian; - - { - VERIFY_ARE_EQUAL(10, pplx::create_task(dr->LoadAsync(10)).get()); - - auto value = dr->ReadString(5); - VERIFY_ARE_EQUAL(utility::string_t(value->Data()), U("abcde")); - value = dr->ReadString(5); - VERIFY_ARE_EQUAL(utility::string_t(value->Data()), U("fghij")); - } - { - ostream.write(char(11)).wait(); - ostream.write(char(17)).wait(); - - VERIFY_ARE_EQUAL(2, pplx::create_task(dr->LoadAsync(2)).get()); - - auto ival = dr->ReadByte(); - VERIFY_ARE_EQUAL(ival, 11); - ival = dr->ReadByte(); - VERIFY_ARE_EQUAL(ival, 17); - } - { - for (int i = 0; i < 100; i++) - { - ostream.write(char(i)).wait(); - } - - VERIFY_ARE_EQUAL(100, pplx::create_task(dr->LoadAsync(100)).get()); - - auto arr = ref new Platform::Array<unsigned char, 1>(100); - dr->ReadBytes(arr); - - for (int i = 0; i < 100; i++) - { - VERIFY_ARE_EQUAL(arr[i], i); - } - } - buf.close(std::ios_base::out); - } - - TEST(read_rand) - { - producer_consumer_buffer<char> buf; - auto ostream = buf.create_ostream(); - std::string strData("abcdefghij"); - buf.putn_nocopy((char*)&strData[0], strData.size() * sizeof(char)).wait(); - - auto dr = ref new Windows::Storage::Streams::DataReader(winrt_stream::create_random_access_stream(buf)); - dr->ByteOrder = Windows::Storage::Streams::ByteOrder::LittleEndian; - - { - VERIFY_ARE_EQUAL(10, pplx::create_task(dr->LoadAsync(10)).get()); - - auto value = dr->ReadString(5); - VERIFY_ARE_EQUAL(utility::string_t(value->Data()), U("abcde")); - value = dr->ReadString(5); - VERIFY_ARE_EQUAL(utility::string_t(value->Data()), U("fghij")); - } - { - ostream.write(char(11)).wait(); - ostream.write(char(17)).wait(); - - VERIFY_ARE_EQUAL(2, pplx::create_task(dr->LoadAsync(2)).get()); - - auto ival = dr->ReadByte(); - VERIFY_ARE_EQUAL(ival, 11); - ival = dr->ReadByte(); - VERIFY_ARE_EQUAL(ival, 17); - } - { - for (int i = 0; i < 100; i++) - { - ostream.write(char(i)).wait(); - } - - VERIFY_ARE_EQUAL(100, pplx::create_task(dr->LoadAsync(100)).get()); - auto arr = ref new Platform::Array<unsigned char, 1>(100); - dr->ReadBytes(arr); - - for (int i = 0; i < 100; i++) - { - VERIFY_ARE_EQUAL(arr[i], i); - } - } - buf.close(std::ios_base::out); - } - - pplx::task<bool> StoreAndFlush(Windows::Storage::Streams::DataWriter ^ dw) - { - return pplx::create_task(dw->StoreAsync()).then([dw](unsigned int) { - return pplx::create_task(dw->FlushAsync()); - }); - } - - TEST(write_out) - { - producer_consumer_buffer<char> buf; - - auto dw = ref new Windows::Storage::Streams::DataWriter(winrt_stream::create_output_stream(buf)); - dw->ByteOrder = Windows::Storage::Streams::ByteOrder::LittleEndian; - - auto value = ref new ::Platform::String(U("10 4711 -10.0 hello!")); - dw->WriteString(value); - dw->WriteByte(11); // Take care to make this a non-character! - dw->WriteUInt16(17); - dw->WriteUInt32(4711); - VERIFY_IS_TRUE(StoreAndFlush(dw).get()); - buf.close(std::ios_base::out); - - auto istream = buf.create_istream(); - VERIFY_ARE_EQUAL(10, istream.extract<unsigned int>().get()); - VERIFY_ARE_EQUAL(4711, istream.extract<int>().get()); - VERIFY_ARE_EQUAL(-10.0, istream.extract<double>().get()); - VERIFY_ARE_EQUAL(utility::string_t(U("hello!")), istream.extract<utility::string_t>().get()); - VERIFY_ARE_EQUAL(11, istream.read().get()); - uint16_t int16; - buf.getn((char*)&int16, sizeof(int16)).wait(); - VERIFY_ARE_EQUAL(17, int16); - uint32_t int32; - buf.getn((char*)&int32, sizeof(int32)).wait(); - VERIFY_ARE_EQUAL(4711, int32); - } - - TEST(write_rand) - { - producer_consumer_buffer<char> buf; - - auto dw = ref new Windows::Storage::Streams::DataWriter(winrt_stream::create_random_access_stream(buf)); - dw->ByteOrder = Windows::Storage::Streams::ByteOrder::LittleEndian; - - auto value = ref new ::Platform::String(U("10 4711 -10.0 hello!")); - dw->WriteString(value); - dw->WriteByte(11); // Take care to make this a non-character! - dw->WriteUInt16(17); - dw->WriteUInt32(4711); - VERIFY_IS_TRUE(StoreAndFlush(dw).get()); - buf.close(std::ios_base::out); - - auto istream = buf.create_istream(); - VERIFY_ARE_EQUAL(10, istream.extract<unsigned int>().get()); - VERIFY_ARE_EQUAL(4711, istream.extract<int>().get()); - VERIFY_ARE_EQUAL(-10.0, istream.extract<double>().get()); - VERIFY_ARE_EQUAL(utility::string_t(U("hello!")), istream.extract<utility::string_t>().get()); - VERIFY_ARE_EQUAL(11, istream.read().get()); - uint16_t int16; - buf.getn((char*)&int16, sizeof(int16)).wait(); - VERIFY_ARE_EQUAL(17, int16); - uint32_t int32; - buf.getn((char*)&int32, sizeof(int32)).wait(); - VERIFY_ARE_EQUAL(4711, int32); - } - - TEST(read_write_attributes) - { - { - container_buffer<std::string> buf("test data"); - auto rastr = winrt_stream::create_random_access_stream(buf); - VERIFY_IS_TRUE(rastr->CanRead); - VERIFY_IS_FALSE(rastr->CanWrite); - VERIFY_ARE_EQUAL(rastr->Position, 0); - - VERIFY_ARE_EQUAL(rastr->Size, 9); - rastr->Size = 1024U; - VERIFY_ARE_EQUAL(rastr->Size, 9); - } - { - container_buffer<std::string> buf; - auto rastr = winrt_stream::create_random_access_stream(buf); - VERIFY_IS_FALSE(rastr->CanRead); - VERIFY_IS_TRUE(rastr->CanWrite); - VERIFY_ARE_EQUAL(rastr->Position, 0); - - VERIFY_ARE_EQUAL(rastr->Size, 0); - rastr->Size = 1024U; - VERIFY_ARE_EQUAL(rastr->Size, 1024U); - VERIFY_ARE_EQUAL(buf.collection().size(), 1024U); - } - { - producer_consumer_buffer<uint8_t> buf; - auto rastr = winrt_stream::create_random_access_stream(buf); - VERIFY_IS_TRUE(rastr->CanRead); - VERIFY_IS_TRUE(rastr->CanWrite); - VERIFY_ARE_EQUAL(rastr->Position, 0); - - VERIFY_ARE_EQUAL(rastr->Size, 0); - rastr->Size = 1024U; - VERIFY_ARE_EQUAL(rastr->Size, 1024U); - } - } - - TEST(cant_write) - { - container_buffer<std::string> buf("test data"); - - auto ostr = winrt_stream::create_output_stream(buf); - auto dw = ref new Windows::Storage::Streams::DataWriter(ostr); - dw->ByteOrder = Windows::Storage::Streams::ByteOrder::LittleEndian; - - auto value = ref new ::Platform::String(U("10 4711 -10.0 hello!")); - dw->WriteString(value); - - VERIFY_IS_FALSE(StoreAndFlush(dw).get()); - } - - TEST(cant_read) - { - container_buffer<std::string> buf; - auto ostream = buf.create_ostream(); - ostream.print<int>(10); - - auto istr = winrt_stream::create_input_stream(buf); - auto dr = ref new Windows::Storage::Streams::DataReader(istr); - dr->ByteOrder = Windows::Storage::Streams::ByteOrder::LittleEndian; - - VERIFY_ARE_EQUAL(0, pplx::create_task(dr->LoadAsync(2)).get()); - } - -} // SUITE - -} // namespace streams -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/CMakeLists.txt @@ -1,16 +0,0 @@ -set(SOURCES - accessor_tests.cpp - combining_tests.cpp - constructor_tests.cpp - conversions_tests.cpp - diagnostic_tests.cpp - encoding_tests.cpp - operator_tests.cpp - splitting_tests.cpp - uri_builder_tests.cpp - resolve_uri_tests.cpp -) - -add_casablanca_test(uri_test SOURCES) - -configure_pch(uri_test stdafx.h stdafx.cpp) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/accessor_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/accessor_tests.cpp @@ -1,55 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * constructor_string_tests.cpp - * - * Tests for constructors of the uri class - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -SUITE(accessor_tests) -{ - TEST(authority_string) - { - uri u(U("http://testname.com:81/path?baz")); - uri a = u.authority(); - - VERIFY_ARE_EQUAL(U("/path"), u.path()); - VERIFY_ARE_EQUAL(U("http"), a.scheme()); - VERIFY_ARE_EQUAL(U("testname.com"), a.host()); - VERIFY_ARE_EQUAL(81, a.port()); - VERIFY_ARE_EQUAL(uri(U("http://testname.com:81")), a); - } - - TEST(authority_wstring) - { - uri u(U("http://testname.com:81/path?baz")); - uri a = u.authority(); - - VERIFY_ARE_EQUAL(U("/path"), u.path()); - VERIFY_ARE_EQUAL(U("http"), a.scheme()); - VERIFY_ARE_EQUAL(U("testname.com"), a.host()); - VERIFY_ARE_EQUAL(81, a.port()); - VERIFY_ARE_EQUAL(uri(U("http://testname.com:81")), a); - } - -} // SUITE(accessor_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/combining_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/combining_tests.cpp @@ -1,89 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * combining_tests.cpp - * - * Tests for appending/combining features of the http::uri class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -SUITE(combining_tests) -{ - TEST(append_path) - { - utility::string_t uri_str = U("http://testname.com/path?baz"); - uri_builder ub(uri_str); - uri combined = ub.append_path(U("/baz")).to_uri(); - - VERIFY_ARE_EQUAL(uri(U("http://testname.com/path/baz?baz")), combined); - } - - TEST(append_empty_path) - { - utility::string_t uri_str(U("http://fakeuri.net")); - uri u = uri_str; - uri_builder ub(u); - uri combined = ub.append_path(U("")).to_uri(); - - VERIFY_ARE_EQUAL(u, combined); - } - - TEST(append_query) - { - utility::string_t uri_str(U("http://testname.com/path1?key1=value2")); - uri_builder ub(uri_str); - uri combined = ub.append_query(uri(U("http://testname2.com/path2?key2=value3")).query()).to_uri(); - - VERIFY_ARE_EQUAL(U("http://testname.com/path1?key1=value2&key2=value3"), combined.to_string()); - } - - TEST(append_empty_query) - { - utility::string_t uri_str(U("http://fakeuri.org/?key=value")); - uri u(uri_str); - uri_builder ub(u); - uri combined = ub.append_query(U("")).to_uri(); - - VERIFY_ARE_EQUAL(u, combined); - } - - TEST(append) - { - utility::string_t uri_str(U("http://testname.com/path1?key1=value2")); - uri_builder ub(uri_str); - uri combined = ub.append(U("http://testname2.com/path2?key2=value3")).to_uri(); - - VERIFY_ARE_EQUAL(U("http://testname.com/path1/path2?key1=value2&key2=value3"), combined.to_string()); - VERIFY_ARE_EQUAL(U("/path1/path2?key1=value2&key2=value3"), combined.resource().to_string()); - } - - TEST(append_empty) - { - utility::string_t uri_str(U("http://myhost.com")); - uri u(uri_str); - uri_builder ub(u); - uri combined = ub.append(U("")).to_uri(); - - VERIFY_ARE_EQUAL(u, combined); - } - -} // SUITE(combining_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/constructor_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/constructor_tests.cpp @@ -1,262 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * constructor_tests.cpp - * - * Tests for constructors of the uri class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -SUITE(constructor_tests) -{ - TEST(parsing_constructor_char) - { - uri u(uri::encode_uri(U("net.tcp://steve:@testname.com:81/bleh%?qstring#goo"))); - - VERIFY_ARE_EQUAL(U("net.tcp"), u.scheme()); - VERIFY_ARE_EQUAL(U("steve:"), u.user_info()); - VERIFY_ARE_EQUAL(U("testname.com"), u.host()); - VERIFY_ARE_EQUAL(81, u.port()); - VERIFY_ARE_EQUAL(U("/bleh%25"), u.path()); - VERIFY_ARE_EQUAL(U("qstring"), u.query()); - VERIFY_ARE_EQUAL(U("goo"), u.fragment()); - } - - TEST(parsing_constructor_encoded_string) - { - uri u(uri::encode_uri(U("net.tcp://testname.com:81/bleh%?qstring#goo"))); - - VERIFY_ARE_EQUAL(U("net.tcp"), u.scheme()); - VERIFY_ARE_EQUAL(U("testname.com"), u.host()); - VERIFY_ARE_EQUAL(81, u.port()); - VERIFY_ARE_EQUAL(U("/bleh%25"), u.path()); - VERIFY_ARE_EQUAL(U("qstring"), u.query()); - VERIFY_ARE_EQUAL(U("goo"), u.fragment()); - } - - TEST(parsing_constructor_string_string) - { - uri u(uri::encode_uri(U("net.tcp://testname.com:81/bleh%?qstring#goo"))); - - VERIFY_ARE_EQUAL(U("net.tcp"), u.scheme()); - VERIFY_ARE_EQUAL(U("testname.com"), u.host()); - VERIFY_ARE_EQUAL(81, u.port()); - VERIFY_ARE_EQUAL(U("/bleh%25"), u.path()); - VERIFY_ARE_EQUAL(U("qstring"), u.query()); - VERIFY_ARE_EQUAL(U("goo"), u.fragment()); - } - - TEST(empty_strings) - { - VERIFY_IS_TRUE(uri(U("")).is_empty()); - VERIFY_IS_TRUE(uri(U("")).is_empty()); - VERIFY_IS_TRUE(uri(uri::encode_uri(U(""))).is_empty()); - } - - TEST(default_constructor) { VERIFY_IS_TRUE(uri().is_empty()); } - - TEST(relative_ref_string) - { - uri u(uri::encode_uri(U("first/second#boff"))); - - VERIFY_ARE_EQUAL(U(""), u.scheme()); - VERIFY_ARE_EQUAL(U(""), u.host()); - VERIFY_ARE_EQUAL(0, u.port()); - VERIFY_ARE_EQUAL(U("first/second"), u.path()); - VERIFY_ARE_EQUAL(U(""), u.query()); - VERIFY_ARE_EQUAL(U("boff"), u.fragment()); - } - - TEST(absolute_ref_string) - { - uri u(uri::encode_uri(U("/first/second#boff"))); - - VERIFY_ARE_EQUAL(U(""), u.scheme()); - VERIFY_ARE_EQUAL(U(""), u.host()); - VERIFY_ARE_EQUAL(0, u.port()); - VERIFY_ARE_EQUAL(U("/first/second"), u.path()); - VERIFY_ARE_EQUAL(U(""), u.query()); - VERIFY_ARE_EQUAL(U("boff"), u.fragment()); - } - - TEST(copy_constructor) - { - uri original(U("http://st:pass@localhost:456/path1?qstring#goo")); - uri new_uri(original); - - VERIFY_ARE_EQUAL(original, new_uri); - } - - TEST(move_constructor) - { - const utility::string_t uri_str(U("http://localhost:456/path1?qstring#goo")); - uri original(uri_str); - uri new_uri = std::move(original); - - VERIFY_ARE_EQUAL(uri_str, new_uri.to_string()); - VERIFY_ARE_EQUAL(uri(uri_str), new_uri); - } - - TEST(assignment_operator) - { - uri original(U("http://localhost:456/path?qstring#goo")); - uri new_uri = original; - - VERIFY_ARE_EQUAL(original, new_uri); - } - - // Tests invalid URI being passed in constructor. - TEST(parsing_constructor_invalid) - { - VERIFY_THROWS(uri(U("123http://localhost:345/")), uri_exception); - VERIFY_THROWS(uri(U("h*ttp://localhost:345/")), uri_exception); - VERIFY_THROWS(uri(U("http://localhost:345/\"")), uri_exception); - VERIFY_THROWS(uri(U("http://localhost:345/path?\"")), uri_exception); - VERIFY_THROWS(uri(U("http://local\"host:345/")), uri_exception); - } - - // Tests a variety of different URIs using the examples in RFC 2732 - TEST(RFC_2732_examples_string) - { - // The URI parser will make characters lower case - uri http1(U("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html")); - VERIFY_ARE_EQUAL(U("http"), http1.scheme()); - VERIFY_ARE_EQUAL(U("[fedc:ba98:7654:3210:fedc:ba98:7654:3210]"), http1.host()); - VERIFY_ARE_EQUAL(80, http1.port()); - VERIFY_ARE_EQUAL(U("/index.html"), http1.path()); - VERIFY_ARE_EQUAL(U(""), http1.query()); - - uri http2(U("http://[1080:0:0:0:8:800:200C:417A]/index.html")); - VERIFY_ARE_EQUAL(U("http"), http2.scheme()); - VERIFY_ARE_EQUAL(U("[1080:0:0:0:8:800:200c:417a]"), http2.host()); - VERIFY_ARE_EQUAL(0, http2.port()); - VERIFY_ARE_EQUAL(U("/index.html"), http2.path()); - VERIFY_ARE_EQUAL(U(""), http2.query()); - - uri http3(U("https://[3ffe:2a00:100:7031::1]")); - VERIFY_ARE_EQUAL(U("https"), http3.scheme()); - VERIFY_ARE_EQUAL(U("[3ffe:2a00:100:7031::1]"), http3.host()); - VERIFY_ARE_EQUAL(0, http3.port()); - VERIFY_ARE_EQUAL(U("/"), http3.path()); - VERIFY_ARE_EQUAL(U(""), http3.query()); - - uri http4(U("http://[::192.9.5.5]/ipng")); - VERIFY_ARE_EQUAL(U("http"), http4.scheme()); - VERIFY_ARE_EQUAL(U("[::192.9.5.5]"), http4.host()); - VERIFY_ARE_EQUAL(0, http4.port()); - VERIFY_ARE_EQUAL(U("/ipng"), http4.path()); - VERIFY_ARE_EQUAL(U(""), http4.query()); - - uri http5(U("http://[1080::8:800:200C:417A]/foo")); - VERIFY_ARE_EQUAL(U("http"), http5.scheme()); - VERIFY_ARE_EQUAL(U("[1080::8:800:200c:417a]"), http5.host()); - VERIFY_ARE_EQUAL(0, http5.port()); - VERIFY_ARE_EQUAL(U("/foo"), http5.path()); - VERIFY_ARE_EQUAL(U(""), http5.query()); - - uri http6(U("http://[::FFFF:129.144.52.38]:80/index.html")); - VERIFY_ARE_EQUAL(U("http"), http6.scheme()); - VERIFY_ARE_EQUAL(U("[::ffff:129.144.52.38]"), http6.host()); - VERIFY_ARE_EQUAL(80, http6.port()); - VERIFY_ARE_EQUAL(U("/index.html"), http6.path()); - VERIFY_ARE_EQUAL(U(""), http6.query()); - - uri http7(U("http://[2010:836B:4179::836B:4179]")); - VERIFY_ARE_EQUAL(U("http"), http7.scheme()); - VERIFY_ARE_EQUAL(U("[2010:836b:4179::836b:4179]"), http7.host()); - VERIFY_ARE_EQUAL(0, http7.port()); - VERIFY_ARE_EQUAL(U("/"), http7.path()); - VERIFY_ARE_EQUAL(U(""), http7.query()); - } - - // Tests a variety of different URIs using the examples in RFC 3986. - TEST(RFC_3968_examples_string) - { - uri ftp(U("ftp://ftp.is.co.za/rfc/rfc1808.txt")); - VERIFY_ARE_EQUAL(U("ftp"), ftp.scheme()); - VERIFY_ARE_EQUAL(U(""), ftp.user_info()); - VERIFY_ARE_EQUAL(U("ftp.is.co.za"), ftp.host()); - VERIFY_ARE_EQUAL(0, ftp.port()); - VERIFY_ARE_EQUAL(U("/rfc/rfc1808.txt"), ftp.path()); - VERIFY_ARE_EQUAL(U(""), ftp.query()); - VERIFY_ARE_EQUAL(U(""), ftp.fragment()); - - // TFS #371892 - // uri ldap(U("ldap://[2001:db8::7]/?c=GB#objectClass?one")); - // VERIFY_ARE_EQUAL(U("ldap"), ldap.scheme()); - // VERIFY_ARE_EQUAL(U(""), ldap.user_info()); - // VERIFY_ARE_EQUAL(U("2001:db8::7"), ldap.host()); - // VERIFY_ARE_EQUAL(0, ldap.port()); - // VERIFY_ARE_EQUAL(U("/"), ldap.path()); - // VERIFY_ARE_EQUAL(U("c=GB"), ldap.query()); - // VERIFY_ARE_EQUAL(U("objectClass?one"), ldap.fragment()); - - // We don't support anything scheme specific like in C# so - // these common ones don't have a great experience yet. - uri mailto(U("mailto:John.Doe@example.com")); - VERIFY_ARE_EQUAL(U("mailto"), mailto.scheme()); - VERIFY_ARE_EQUAL(U(""), mailto.user_info()); - VERIFY_ARE_EQUAL(U(""), mailto.host()); - VERIFY_ARE_EQUAL(0, mailto.port()); - VERIFY_ARE_EQUAL(U("John.Doe@example.com"), mailto.path()); - VERIFY_ARE_EQUAL(U(""), mailto.query()); - VERIFY_ARE_EQUAL(U(""), mailto.fragment()); - - uri tel(U("tel:+1-816-555-1212")); - VERIFY_ARE_EQUAL(U("tel"), tel.scheme()); - VERIFY_ARE_EQUAL(U(""), tel.user_info()); - VERIFY_ARE_EQUAL(U(""), tel.host()); - VERIFY_ARE_EQUAL(0, tel.port()); - VERIFY_ARE_EQUAL(U("+1-816-555-1212"), tel.path()); - VERIFY_ARE_EQUAL(U(""), tel.query()); - VERIFY_ARE_EQUAL(U(""), tel.fragment()); - - uri telnet(U("telnet://192.0.2.16:80/")); - VERIFY_ARE_EQUAL(U("telnet"), telnet.scheme()); - VERIFY_ARE_EQUAL(U(""), telnet.user_info()); - VERIFY_ARE_EQUAL(U("192.0.2.16"), telnet.host()); - VERIFY_ARE_EQUAL(80, telnet.port()); - VERIFY_ARE_EQUAL(U("/"), telnet.path()); - VERIFY_ARE_EQUAL(U(""), telnet.query()); - VERIFY_ARE_EQUAL(U(""), telnet.fragment()); - } - - TEST(user_info_string) - { - uri ftp(U("ftp://johndoe:testname@ftp.is.co.za/rfc/rfc1808.txt")); - VERIFY_ARE_EQUAL(U("ftp"), ftp.scheme()); - VERIFY_ARE_EQUAL(U("johndoe:testname"), ftp.user_info()); - VERIFY_ARE_EQUAL(U("ftp.is.co.za"), ftp.host()); - VERIFY_ARE_EQUAL(0, ftp.port()); - VERIFY_ARE_EQUAL(U("/rfc/rfc1808.txt"), ftp.path()); - VERIFY_ARE_EQUAL(U(""), ftp.query()); - VERIFY_ARE_EQUAL(U(""), ftp.fragment()); - } - - // Test query component can be separated with '&' or ';'. - TEST(query_seperated_with_semi_colon) - { - uri u(U("http://localhost/path1?key1=val1;key2=val2")); - VERIFY_ARE_EQUAL(U("key1=val1;key2=val2"), u.query()); - } - -} // SUITE(constructor_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/conversions_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/conversions_tests.cpp @@ -1,53 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * conversion_tests.cpp - * - * Tests to string functions and implicit conversions of the http::uri class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -SUITE(conversions_tests) -{ - TEST(to_string_conversion) - { - utility::string_t encoded = uri::encode_uri(U("http://testname.com/%%?qstring")); - uri u1(U("http://testname.com/%25%25?qstring")); - - VERIFY_ARE_EQUAL(uri::decode(encoded), uri::decode(u1.to_string())); - } - - TEST(to_encoded_string) - { - utility::string_t encoded = uri::encode_uri(U("http://testname.com/%%?qstring")); - uri u(U("http://testname.com/%25%25?qstring")); - - VERIFY_ARE_EQUAL(encoded, u.to_string()); - } - - TEST(empty_to_string) - { - uri u; - VERIFY_ARE_EQUAL(U("/"), u.to_string()); - } - -} // SUITE(conversions_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/diagnostic_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/diagnostic_tests.cpp @@ -1,117 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * diagnostic_tests.cpp - * - * Tests for diagnostic functions like is_host_loopback of the uri class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -SUITE(diagnostic_tests) -{ - TEST(empty_components) - { - VERIFY_IS_TRUE(uri().is_empty()); - - VERIFY_IS_FALSE(uri().is_authority()); - - VERIFY_IS_FALSE(uri().is_host_loopback()); - VERIFY_IS_FALSE(uri().is_host_wildcard()); - VERIFY_IS_FALSE(uri().is_host_portable()); - - VERIFY_IS_FALSE(uri().is_port_default()); - } - - TEST(is_authority) - { - VERIFY_IS_TRUE(uri(U("http://first.second/")).is_authority()); - VERIFY_IS_TRUE(uri(U("http://first.second")).is_authority()); - - VERIFY_IS_FALSE(uri(U("http://first.second/b")).is_authority()); - VERIFY_IS_FALSE(uri(U("http://first.second?qstring")).is_authority()); - VERIFY_IS_FALSE(uri(U("http://first.second#third")).is_authority()); - } - - TEST(has_same_authority) - { - VERIFY_IS_TRUE(uri(U("http://first.second/")).has_same_authority(uri(U("http://first.second/path")))); - VERIFY_IS_TRUE(uri(U("http://first.second:83/")).has_same_authority(uri(U("http://first.second:83/path:83")))); - - VERIFY_IS_FALSE(uri(U("http://first.second:82/")).has_same_authority(uri(U("http://first.second/path")))); - VERIFY_IS_FALSE(uri(U("tcp://first.second:82/")).has_same_authority(uri(U("http://first.second/path")))); - VERIFY_IS_FALSE(uri(U("http://path.:82/")).has_same_authority(uri(U("http://first.second/path")))); - } - - TEST(has_same_authority_empty) - { - VERIFY_IS_FALSE(uri().has_same_authority(uri())); - VERIFY_IS_FALSE(uri(U("http://first.second/")).has_same_authority(uri())); - VERIFY_IS_FALSE(uri().has_same_authority(uri(U("http://first.second/")))); - } - - TEST(is_host_wildcard) - { - VERIFY_IS_TRUE(uri(U("http://*/")).is_host_wildcard()); - VERIFY_IS_TRUE(uri(U("http://+/?qstring")).is_host_wildcard()); - - VERIFY_IS_FALSE(uri(U("http://bleh/?qstring")).is_host_wildcard()); - VERIFY_IS_FALSE(uri(U("http://+*/?qstring")).is_host_wildcard()); - } - - TEST(is_host_loopback) - { - VERIFY_IS_TRUE(uri(U("http://localhost/")).is_host_loopback()); - VERIFY_IS_TRUE(uri(U("http://LoCALHoST/")).is_host_loopback()); - - VERIFY_IS_FALSE(uri(U("http://127")).is_host_loopback()); - VERIFY_IS_FALSE(uri(U("http://bleh/?qstring")).is_host_loopback()); - VERIFY_IS_FALSE(uri(U("http://+*/?qstring")).is_host_loopback()); - VERIFY_IS_TRUE(uri(U("http://127.0.0.1/")).is_host_loopback()); - VERIFY_IS_TRUE(uri(U("http://127.155.0.1/")).is_host_loopback()); - VERIFY_IS_FALSE(uri(U("http://128.0.0.1/")).is_host_loopback()); - } - - TEST(is_host_portable) - { - VERIFY_IS_TRUE(uri(U("http://bleh/?qstring")).is_host_portable()); - - VERIFY_IS_FALSE(uri(U("http://localhost/")).is_host_portable()); - VERIFY_IS_FALSE(uri(U("http://+/?qstring")).is_host_portable()); - } - - TEST(is_port_default) - { - VERIFY_IS_TRUE(uri(U("http://bleh/?qstring")).is_port_default()); - VERIFY_IS_TRUE(uri(U("http://localhost:0/")).is_port_default()); - - VERIFY_IS_FALSE(uri(U("http://+:85/?qstring")).is_port_default()); - } - - TEST(is_path_empty) - { - VERIFY_IS_TRUE(uri(U("http://bleh/?qstring")).is_path_empty()); - VERIFY_IS_TRUE(uri(U("http://localhost:0")).is_path_empty()); - - VERIFY_IS_FALSE(uri(U("http://+:85/path/?qstring")).is_path_empty()); - } - -} // SUITE(diagnostic_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/encoding_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/encoding_tests.cpp @@ -1,134 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests for encoding features of the uri class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -SUITE(encoding_tests) -{ -#ifdef _WIN32 -#pragma warning(push) -#pragma warning(disable : 4428) - TEST(encode_string) - { - utility::string_t result = uri::encode_uri(L"first%second\u4e2d\u56fd"); - VERIFY_ARE_EQUAL(U("first%25second%E4%B8%AD%E5%9B%BD"), result); - - result = uri::encode_uri(U("first%second")); - VERIFY_ARE_EQUAL(U("first%25second"), result); - } - - TEST(decode_string) - { - utility::string_t result = uri::decode(U("first%25second%E4%B8%AD%E5%9B%BD")); - VERIFY_ARE_EQUAL(L"first%second\u4e2d\u56fd", result); - - result = uri::decode(U("first%25second")); - VERIFY_ARE_EQUAL(U("first%second"), result); - } -#pragma warning(pop) -#endif - - TEST(encode_characters_in_resource) - { - utility::string_t result = uri::encode_uri(U("http://path%name/%#!%")); - VERIFY_ARE_EQUAL(U("http://path%25name/%25#!%25"), result); - } - - // Tests trying to encode empty strings. - TEST(encode_decode_empty_strings) - { - // utility::string_t - utility::string_t result = uri::encode_uri(U("")); - VERIFY_ARE_EQUAL(U(""), result); - utility::string_t str = uri::decode(result); - VERIFY_ARE_EQUAL(U(""), str); - - // std::wstring - result = uri::encode_uri(U("")); - VERIFY_ARE_EQUAL(U(""), result); - auto wstr = uri::decode(result); - VERIFY_ARE_EQUAL(U(""), wstr); - } - - // Tests encoding in various components of the URI. - TEST(encode_uri_multiple_components) - { - // only encodes characters that aren't in the unreserved and reserved set. - - // utility::string_t - utility::string_t str(U("htt p://^localhost:80/path ?^one=two# frag")); - utility::string_t result = uri::encode_uri(str); - VERIFY_ARE_EQUAL(U("htt%20p://%5Elocalhost:80/path%20?%5Eone=two#%20frag"), result); - VERIFY_ARE_EQUAL(str, uri::decode(result)); - } - - // Tests encoding individual components of a URI. - TEST(encode_uri_component) - { - // encodes all characters not in the unreserved set. - - // utility::string_t - utility::string_t str(U("path with^spaced")); - utility::string_t result = uri::encode_uri(str); - VERIFY_ARE_EQUAL(U("path%20with%5Espaced"), result); - VERIFY_ARE_EQUAL(str, uri::decode(result)); - } - - // Tests trying to decode a string that doesn't have 2 hex digits after % - TEST(decode_invalid_hex) - { - VERIFY_THROWS(uri::decode(U("hehe%")), uri_exception); - VERIFY_THROWS(uri::decode(U("hehe%2")), uri_exception); - VERIFY_THROWS(uri::decode(U("hehe%4H")), uri_exception); - VERIFY_THROWS(uri::decode(U("he%kkhe")), uri_exception); - } - - // Tests making sure '+' is encoded even though nonstandard, so it doesn't - // get mistaken later by some implementations as a space. - TEST(encode_plus_char) - { - const utility::string_t encodedPlus(U("%2B")); - - uri_builder builder; - builder.set_user_info(U("+"), true); - builder.set_path(U("+"), true); - builder.set_query(U("+"), true); - builder.set_fragment(U("+"), true); - - VERIFY_ARE_EQUAL(builder.user_info(), encodedPlus); - VERIFY_ARE_EQUAL(builder.path(), encodedPlus); - VERIFY_ARE_EQUAL(builder.query(), encodedPlus); - VERIFY_ARE_EQUAL(builder.fragment(), encodedPlus); - } - - TEST(bug_417601) - { - utility::ostringstream_t ss1; - auto enc1 = uri::encode_data_string(U("!")); - ss1 << enc1; - - VERIFY_ARE_EQUAL(U("%21"), ss1.str()); - } - -} // SUITE(encoding_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/operator_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/operator_tests.cpp @@ -1,80 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * operator_tests.cpp - * - * Tests for operators of the uri class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -SUITE(operator_tests) -{ - TEST(uri_basic_equality) - { - VERIFY_ARE_EQUAL(uri(U("")), uri(U(""))); - - uri u1(U("http://localhost:80/path1")); - uri u2(U("http://localhost:80/path1")); - VERIFY_ARE_EQUAL(u1, u2); - } - - TEST(uri_decoded_equality) - { - uri_builder u3b(U("http://localhost:80")); - u3b.set_path(U("path 1"), true); - - uri u3 = u3b.to_uri(); - uri u4(U("http://localhost:80/path%201")); - VERIFY_ARE_EQUAL(u3, u4); - - uri u5(U("http://localhost:80/pat%68a1")); - uri u6(U("http://localhost:80/patha1")); - VERIFY_ARE_EQUAL(u5, u6); - - uri u9(U("http://localhost:80/patha1?name=first#t%65st")); - uri u10(U("http://localhost:80/patha1?name=first#test")); - VERIFY_ARE_EQUAL(u9, u10); - } - - TEST(uri_basic_inequality) - { - VERIFY_ARE_NOT_EQUAL(uri(U("http://localhost:80/path1")), uri(U("https://localhost:80/path1"))); - VERIFY_ARE_NOT_EQUAL(uri(U("http://localhost:80/path1")), uri(U("http://localhost2:80/path1"))); - VERIFY_ARE_NOT_EQUAL(uri(U("http://localhost:80/path1")), uri(U("http://localhost:81/path1"))); - VERIFY_ARE_NOT_EQUAL(uri(U("http://localhost:80/path1")), uri(U("http://localhost:80/path2"))); - VERIFY_ARE_NOT_EQUAL(uri(U("http://localhost:80/path1?key=value")), - uri(U("http://localhost:80/path1?key=value2"))); - VERIFY_ARE_NOT_EQUAL(uri(U("http://localhost:80/path1?key=value#nose")), - uri(U("http://localhost:80/path1?key=value#nose1"))); - } - - TEST(test_empty) - { - VERIFY_ARE_EQUAL(uri(), uri()); - VERIFY_ARE_EQUAL(uri(U("htTp://Path")), uri(U("hTtp://pAth"))); - - VERIFY_ARE_NOT_EQUAL(uri(U("http://path")), uri()); - VERIFY_ARE_NOT_EQUAL(uri(), uri(U("http://path"))); - VERIFY_ARE_NOT_EQUAL(uri(U("http://path1")), uri(U("http://path2"))); - } - -} // SUITE(operator_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/resolve_uri_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/resolve_uri_tests.cpp @@ -1,74 +0,0 @@ -#include "stdafx.h" - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -// testing resolution against examples from Section 5.4 https://tools.ietf.org/html/rfc3986#section-5.4 -SUITE(resolve_uri_tests) -{ - // 5.4.1. Normal Examples https://tools.ietf.org/html/rfc3986#section-5.4.1 - TEST(resolve_uri_normal) - { - const uri baseUri = U("http://a/b/c/d;p?q"); - - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g:h")), U("g:h")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g")), U("http://a/b/c/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./g")), U("http://a/b/c/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g/")), U("http://a/b/c/g/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("/g")), U("http://a/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("//g")), U("http://g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("?y")), U("http://a/b/c/d;p?y")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y")), U("http://a/b/c/g?y")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("#s")), U("http://a/b/c/d;p?q#s")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g#s")), U("http://a/b/c/g#s")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y#s")), U("http://a/b/c/g?y#s")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U(";x")), U("http://a/b/c/;x")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x")), U("http://a/b/c/g;x")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x?y#s")), U("http://a/b/c/g;x?y#s")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("")), U("http://a/b/c/d;p?q")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U(".")), U("http://a/b/c/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./")), U("http://a/b/c/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("..")), U("http://a/b/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../")), U("http://a/b/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../g")), U("http://a/b/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../..")), U("http://a/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../")), U("http://a/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../g")), U("http://a/g")); - } - // 5.4.2. Abnormal Examples https://tools.ietf.org/html/rfc3986#section-5.4.2 - TEST(resolve_uri_abnormal) - { - const uri baseUri = U("http://a/b/c/d;p?q"); - - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../../g")), U("http://a/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("../../../../g")), U("http://a/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("/./g")), U("http://a/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("/../g")), U("http://a/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g.")), U("http://a/b/c/g.")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U(".g")), U("http://a/b/c/.g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g..")), U("http://a/b/c/g..")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("..g")), U("http://a/b/c/..g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./../g")), U("http://a/b/g")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("./g/.")), U("http://a/b/c/g/")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g/./h")), U("http://a/b/c/g/h")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g/../h")), U("http://a/b/c/h")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x=1/./y")), U("http://a/b/c/g;x=1/y")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g;x=1/../y")), U("http://a/b/c/y")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y/./x")), U("http://a/b/c/g?y/./x")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g?y/../x")), U("http://a/b/c/g?y/../x")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g#s/./x")), U("http://a/b/c/g#s/./x")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("g#s/../x")), U("http://a/b/c/g#s/../x")); - VERIFY_ARE_EQUAL(baseUri.resolve_uri(U("http:g")), U("http:g")); - } - -} // SUITE(resolve_uri_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/splitting_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/splitting_tests.cpp @@ -1,181 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * splitting_tests.cpp - * - * Tests for path and query splitting features of the uri class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -using namespace web; -using namespace utility; - -SUITE(splitting_tests) -{ - TEST(split_string) - { - std::vector<utility::string_t> s = uri::split_path(U("/first/second/third")); - VERIFY_ARE_EQUAL(3u, s.size()); - VERIFY_ARE_EQUAL(U("first"), s[0]); - VERIFY_ARE_EQUAL(U("second"), s[1]); - VERIFY_ARE_EQUAL(U("third"), s[2]); - } - - TEST(split_encoded_string) - { - std::vector<utility::string_t> s = uri::split_path(utility::string_t(U("heh%2Ffirst/second/third"))); - VERIFY_ARE_EQUAL(3u, s.size()); - VERIFY_ARE_EQUAL(U("heh%2Ffirst"), s[0]); - VERIFY_ARE_EQUAL(U("second"), s[1]); - VERIFY_ARE_EQUAL(U("third"), s[2]); - } - - TEST(split_no_slash) - { - std::vector<utility::string_t> s = uri::split_path(utility::string_t(U("noslash"))); - VERIFY_ARE_EQUAL(1u, s.size()); - VERIFY_ARE_EQUAL(U("noslash"), s[0]); - } - - TEST(split_query_basic) - { - { - // Separating with '&' - std::map<utility::string_t, utility::string_t> keyMap = - uri::split_query(U("key1=value1&key2=value2&key3=value3")); - VERIFY_ARE_EQUAL(3u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key1"), iter->first); - VERIFY_ARE_EQUAL(U("value1"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key2"), iter->first); - VERIFY_ARE_EQUAL(U("value2"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key3"), iter->first); - VERIFY_ARE_EQUAL(U("value3"), iter->second); - } - { - // Separating with ';' - std::map<utility::string_t, utility::string_t> keyMap = - uri::split_query(U("key1=value1;key2=value2;key3=value3")); - VERIFY_ARE_EQUAL(3u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key1"), iter->first); - VERIFY_ARE_EQUAL(U("value1"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key2"), iter->first); - VERIFY_ARE_EQUAL(U("value2"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key3"), iter->first); - VERIFY_ARE_EQUAL(U("value3"), iter->second); - } - } - - TEST(split_encoded_query) - { - { - // Separating with '&' - std::map<utility::string_t, utility::string_t> keyMap = - uri::split_query(utility::string_t(U("key=value%26key1%20=value1&key2=%5Evalue2&key3=value3%20"))); - VERIFY_ARE_EQUAL(3u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key"), iter->first); - VERIFY_ARE_EQUAL(U("value%26key1%20=value1"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key2"), iter->first); - VERIFY_ARE_EQUAL(U("%5Evalue2"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key3"), iter->first); - VERIFY_ARE_EQUAL(U("value3%20"), iter->second); - } - { - // Separating with ';' - std::map<utility::string_t, utility::string_t> keyMap = - uri::split_query(utility::string_t(U("key=value%26key1%20=value1;key2=%5Evalue2;key3=value3%20"))); - VERIFY_ARE_EQUAL(3u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key"), iter->first); - VERIFY_ARE_EQUAL(U("value%26key1%20=value1"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key2"), iter->first); - VERIFY_ARE_EQUAL(U("%5Evalue2"), iter->second); - ++iter; - VERIFY_ARE_EQUAL(U("key3"), iter->first); - VERIFY_ARE_EQUAL(U("value3%20"), iter->second); - } - } - - TEST(split_query_empty) - { - std::map<utility::string_t, utility::string_t> keyMap = uri::split_query(U("")); - VERIFY_ARE_EQUAL(0u, keyMap.size()); - } - - TEST(split_query_single) - { - std::map<utility::string_t, utility::string_t> keyMap = uri::split_query(U("key1=44")); - VERIFY_ARE_EQUAL(1u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key1"), iter->first); - VERIFY_ARE_EQUAL(U("44"), iter->second); - } - - TEST(split_query_no_value) - { - std::map<utility::string_t, utility::string_t> keyMap = uri::split_query(U("key1")); - VERIFY_ARE_EQUAL(0u, keyMap.size()); - keyMap = uri::split_query(U("key1=")); - VERIFY_ARE_EQUAL(1u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key1"), iter->first); - VERIFY_ARE_EQUAL(U(""), iter->second); - keyMap = uri::split_query(U("key1&")); - VERIFY_ARE_EQUAL(0u, keyMap.size()); - } - - TEST(split_query_no_key) - { - std::map<utility::string_t, utility::string_t> keyMap = uri::split_query(U("=value1")); - VERIFY_ARE_EQUAL(1u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U(""), iter->first); - VERIFY_ARE_EQUAL(U("value1"), iter->second); - } - - TEST(split_query_end_with_amp) - { - { - // Separating with '&' - std::map<utility::string_t, utility::string_t> keyMap = uri::split_query(U("key1=44&")); - VERIFY_ARE_EQUAL(1u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key1"), iter->first); - VERIFY_ARE_EQUAL(U("44"), iter->second); - } - { - // Separating with ';' - std::map<utility::string_t, utility::string_t> keyMap = uri::split_query(U("key1=44;")); - VERIFY_ARE_EQUAL(1u, keyMap.size()); - auto iter = keyMap.begin(); - VERIFY_ARE_EQUAL(U("key1"), iter->first); - VERIFY_ARE_EQUAL(U("44"), iter->second); - } - } - -} // SUITE(splitting_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/stdafx.cpp @@ -1,15 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ - -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" - -#if WIN32 -__declspec(dllexport) int uri_test_generate_lib = 0; -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/stdafx.h @@ -1,19 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * stdafx.h - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/uri.h" -#include "unittestpp.h" -#include "uri_tests.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/uri_builder_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/uri_builder_tests.cpp @@ -1,610 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests for the URI builder class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include <locale_guard.h> - -using namespace web; -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -// Helper functions to verify components of a builder. -static void VERIFY_URI_BUILDER(uri_builder& builder, - const utility::string_t& scheme, - const utility::string_t& user_info, - const utility::string_t& host, - const int port, - const utility::string_t& path, - const utility::string_t& query, - const utility::string_t& fragment) -{ - VERIFY_ARE_EQUAL(scheme, builder.scheme()); - VERIFY_ARE_EQUAL(host, builder.host()); - VERIFY_ARE_EQUAL(user_info, builder.user_info()); - VERIFY_ARE_EQUAL(port, builder.port()); - VERIFY_ARE_EQUAL(path, builder.path()); - VERIFY_ARE_EQUAL(query, builder.query()); - VERIFY_ARE_EQUAL(fragment, builder.fragment()); -} -static void VERIFY_URI_BUILDER(uri_builder& builder, - const utility::string_t& scheme, - const utility::string_t& host, - const int port) -{ - VERIFY_URI_BUILDER(builder, - scheme, - utility::string_t(), - host, - port, - utility::string_t(U("/")), - utility::string_t(), - utility::string_t()); -} -static void VERIFY_URI_BUILDER_IS_EMPTY(uri_builder& builder) -{ - VERIFY_URI_BUILDER(builder, - utility::string_t(), - utility::string_t(), - utility::string_t(), - -1, - utility::string_t(U("/")), - utility::string_t(), - utility::string_t()); -} - -SUITE(uri_builder_tests) -{ - TEST(constructor_tests) - { - // Default constructor - uri_builder builder; - VERIFY_URI_BUILDER_IS_EMPTY(builder); - // scheme, user_info, host, port - utility::string_t scheme(U("ftp")); - utility::string_t user_info(U("steve:pass")); - utility::string_t host(U("localhost")); - int port = 44; - utility::string_t path(U("/Yeshere888")); - utility::string_t uri_str(U("ftp://steve:pass@localhost:44/Yeshere888")); - - // utility::string_t - utility::string_t uri_wstr(U("ftp://steve:pass@localhost:44/Yeshere888?abc:123&abc2:456#nose")); - builder = uri_builder(uri_wstr); - VERIFY_URI_BUILDER(builder, - scheme, - user_info, - host, - port, - path, - utility::string_t(U("abc:123&abc2:456")), - utility::string_t(U("nose"))); - - // copy constructor - uri_builder other(builder); - builder = uri_builder(uri_str); - VERIFY_URI_BUILDER(other, - scheme, - user_info, - host, - port, - path, - utility::string_t(U("abc:123&abc2:456")), - utility::string_t(U("nose"))); - VERIFY_URI_BUILDER(builder, scheme, user_info, host, port, path, U(""), U("")); - - // move constructor - uri_builder move_other = std::move(builder); - VERIFY_URI_BUILDER(move_other, scheme, user_info, host, port, path, U(""), U("")); - } - - TEST(assignment_operators) - { - // assignment operator - const utility::string_t scheme = U("http"), host = U("localhost"); - const int port = 44; - uri_builder original; - original.set_scheme(scheme).set_host(host).set_port(port); - uri_builder assign; - assign = original; - VERIFY_URI_BUILDER(assign, scheme, utility::string_t(host), port); - - // move assignment operator - uri_builder move_assign; - move_assign = std::move(original); - VERIFY_URI_BUILDER(assign, scheme, utility::string_t(host), port); - } - - TEST(set_port_as_string) - { - uri_builder builder; - - VERIFY_THROWS(builder.set_port(U("")), std::invalid_argument); - VERIFY_ARE_EQUAL(-1, builder.port()); - - builder.set_port(U("987")); - VERIFY_ARE_EQUAL(987, builder.port()); - - VERIFY_THROWS(builder.set_port(U("abc")), std::invalid_argument); - VERIFY_ARE_EQUAL(987, builder.port()); - - builder.set_port(U(" 44 ")); - VERIFY_ARE_EQUAL(44, builder.port()); - - builder.set_port(U("99")); - VERIFY_ARE_EQUAL(99, builder.port()); - } - - TEST(component_assignment) - { - uri_builder builder; - const utility::string_t scheme(U("myscheme")); - const utility::string_t uinfo(U("johndoe:test")); - const utility::string_t host(U("localhost")); - const int port = 88; - const utility::string_t path(U("jklajsd")); - const utility::string_t query(U("key1=val1")); - const utility::string_t fragment(U("last")); - - builder.set_scheme(scheme); - builder.set_user_info(uinfo); - builder.set_host(host); - builder.set_port(port); - builder.set_path(path); - builder.set_query(query); - builder.set_fragment(fragment); - - VERIFY_URI_BUILDER(builder, scheme, uinfo, host, port, path, query, fragment); - } - - TEST(component_assignment_encode) - { - { - uri_builder builder; - const utility::string_t scheme(U("myscheme")); - const utility::string_t uinfo(U("johndoe:test")); - const utility::string_t host(U("localhost")); - const int port = 88; - const utility::string_t path(U("jklajsd/yes no")); - const utility::string_t query(U("key1=va%l1")); - const utility::string_t fragment(U("las t")); - - builder.set_scheme(scheme); - builder.set_user_info(uinfo, true); - builder.set_host(host, true); - builder.set_port(port); - builder.set_path(path, true); - builder.set_query(query, true); - builder.set_fragment(fragment, true); - - VERIFY_URI_BUILDER(builder, - scheme, - utility::string_t(U("johndoe:test")), - utility::string_t(U("localhost")), - port, - utility::string_t(U("jklajsd/yes%20no")), - utility::string_t(U("key1=va%25l1")), - utility::string_t(U("las%20t"))); - } - { - uri_builder builder; - const utility::string_t scheme(U("myscheme")); - const utility::string_t uinfo(U("johndoe:test")); - const utility::string_t host(U("localhost")); - const int port = 88; - const utility::string_t path(U("jklajsd/yes no")); - const utility::string_t query(U("key1=va%l1")); - const utility::string_t fragment(U("las t")); - - builder.set_scheme(scheme); - builder.set_user_info(uinfo, true); - builder.set_host(host, true); - builder.set_port(port); - builder.set_path(path, true); - builder.set_query(query, true); - builder.set_fragment(fragment, true); - - VERIFY_URI_BUILDER(builder, - scheme, - utility::string_t(U("johndoe:test")), - utility::string_t(U("localhost")), - port, - utility::string_t(U("jklajsd/yes%20no")), - utility::string_t(U("key1=va%25l1")), - utility::string_t(U("las%20t"))); - } - } - - TEST(validation) - { - { - // true - uri_builder builder(U("http://localhost:4567/")); - VERIFY_IS_TRUE(builder.is_valid()); - - // false - builder = uri_builder(); - builder.set_scheme(U("123")); - VERIFY_IS_FALSE(builder.is_valid()); - } - { - // true - uri_builder builder(U("http://localhost:4567/")); - VERIFY_IS_TRUE(builder.is_valid()); - - // false - builder = uri_builder(); - builder.set_scheme(U("123")); - VERIFY_IS_FALSE(builder.is_valid()); - } - } - - TEST(uri_creation_string) - { - utility::string_t uri_str(U("http://steve:temp@localhost:4556/")); - - // to_string - uri_builder builder(uri_str); - VERIFY_ARE_EQUAL(uri_str, builder.to_string()); - - // to_string - VERIFY_ARE_EQUAL(uri_str, builder.to_string()); - - // to uri - VERIFY_ARE_EQUAL(uri_str, builder.to_uri().to_string()); - - // to encoded string - uri_builder with_space(builder); - with_space.set_path(utility::string_t(U("path%20with%20space"))); - VERIFY_ARE_EQUAL(U("http://steve:temp@localhost:4556/path%20with%20space"), with_space.to_string()); - } - - TEST(append_path_string) - { - // empty uri builder path - uri_builder builder; - builder.append_path(U("/path1")); - VERIFY_ARE_EQUAL(U("/path1"), builder.path()); - - // empty append path - builder.append_path(U("")); - VERIFY_ARE_EQUAL(U("/path1"), builder.path()); - - // uri builder with slash - builder.append_path(U("/")); - builder.append_path(U("path2")); - VERIFY_ARE_EQUAL(U("/path1/path2"), builder.path()); - - // both with slash - builder.append_path(U("/")); - builder.append_path(U("/path3")); - VERIFY_ARE_EQUAL(U("/path1/path2/path3"), builder.path()); - - // both without slash - builder.append_path(U("path4")); - VERIFY_ARE_EQUAL(U("/path1/path2/path3/path4"), builder.path()); - - // encoding - builder.clear(); - builder.append_path(U("encode%things")); - VERIFY_ARE_EQUAL(U("/encode%things"), builder.path()); - - builder.clear(); - builder.append_path(U("encode%things"), false); - VERIFY_ARE_EQUAL(U("/encode%things"), builder.path()); - - builder.clear(); - builder.append_path(U("encode%things"), true); - VERIFY_ARE_EQUAL(U("/encode%25things"), builder.path()); - - // self references - builder.set_path(U("example")); - builder.append_path(builder.path()); - VERIFY_ARE_EQUAL(U("example/example"), builder.path()); - - builder.set_path(U("/example")); - builder.append_path(builder.path()); - VERIFY_ARE_EQUAL(U("/example/example"), builder.path()); - - builder.set_path(U("/example/")); - builder.append_path(builder.path()); - VERIFY_ARE_EQUAL(U("/example/example/"), builder.path()); - } - - TEST(append_path_raw_string) - { - // empty uri builder path - uri_builder builder; - builder.append_path_raw(U("path1")); - VERIFY_ARE_EQUAL(U("/path1"), builder.path()); - - // empty append path - builder.append_path_raw(U("")); - VERIFY_ARE_EQUAL(U("/path1"), builder.path()); - - // uri builder with slash - builder.append_path_raw(U("/")); - builder.append_path_raw(U("path2")); - VERIFY_ARE_EQUAL(U("/path1///path2"), builder.path()); - - // leading slash (should result in "//") - builder.append_path_raw(U("/path3")); - VERIFY_ARE_EQUAL(U("/path1///path2//path3"), builder.path()); - - // trailing slash - builder.append_path_raw(U("path4/")); - builder.append_path_raw(U("path5")); - VERIFY_ARE_EQUAL(U("/path1///path2//path3/path4//path5"), builder.path()); - - // encoding - builder.clear(); - builder.append_path_raw(U("encode%things")); - VERIFY_ARE_EQUAL(U("/encode%things"), builder.path()); - - builder.clear(); - builder.append_path_raw(U("encode%things"), false); - VERIFY_ARE_EQUAL(U("/encode%things"), builder.path()); - - builder.clear(); - builder.append_path_raw(U("encode%things"), true); - VERIFY_ARE_EQUAL(U("/encode%25things"), builder.path()); - - // self references - builder.set_path(U("example")); - builder.append_path_raw(builder.path()); - VERIFY_ARE_EQUAL(U("example/example"), builder.path()); - - builder.set_path(U("/example")); - builder.append_path_raw(builder.path()); - VERIFY_ARE_EQUAL(U("/example//example"), builder.path()); - - builder.set_path(U("/example/")); - builder.append_path_raw(builder.path()); - VERIFY_ARE_EQUAL(U("/example///example/"), builder.path()); - } - - TEST(append_query_string) - { - // empty uri builder query - uri_builder builder; - builder.append_query(U("key1=value1")); - VERIFY_ARE_EQUAL(U("key1=value1"), builder.query()); - - // empty append query - builder.append_query(U("")); - VERIFY_ARE_EQUAL(U("key1=value1"), builder.query()); - - // uri builder with ampersand - builder.append_query(U("&")); - builder.append_query(U("key2=value2")); - VERIFY_ARE_EQUAL(U("key1=value1&key2=value2"), builder.query()); - - // both with ampersand - builder.append_query(U("&")); - builder.append_query(U("&key3=value3")); - VERIFY_ARE_EQUAL(U("key1=value1&key2=value2&key3=value3"), builder.query()); - - // both without ampersand - builder.append_query(U("key4=value4")); - VERIFY_ARE_EQUAL(U("key1=value1&key2=value2&key3=value3&key4=value4"), builder.query()); - - // number query - builder.append_query(U("key5"), 1); - VERIFY_ARE_EQUAL(U("key1=value1&key2=value2&key3=value3&key4=value4&key5=1"), builder.query()); - - // string query - builder.append_query(U("key6"), U("val6")); - VERIFY_ARE_EQUAL(U("key1=value1&key2=value2&key3=value3&key4=value4&key5=1&key6=val6"), builder.query()); - - // key and value separate with '=', '&', and ';' - builder.append_query(U("key=&;"), U("=&;value")); - VERIFY_ARE_EQUAL( - U("key1=value1&key2=value2&key3=value3&key4=value4&key5=1&key6=val6&key%3D%26%3B=%3D%26%3Bvalue"), - builder.query()); - - // self references - builder.set_query(U("example")); - builder.append_query(builder.query()); - VERIFY_ARE_EQUAL(U("example&example"), builder.query()); - - builder.set_query(U("&example")); - builder.append_query(builder.query()); - VERIFY_ARE_EQUAL(U("&example&example"), builder.query()); - - builder.set_query(U("&example&")); - builder.append_query(builder.query()); - VERIFY_ARE_EQUAL(U("&example&example&"), builder.query()); - } - - TEST(append_query_string_no_encode) - { - uri_builder builder; - builder.append_query(U("key=&;"), U("=&;value"), false); - VERIFY_ARE_EQUAL(U("key=&;==&;value"), builder.query()); - } - - TEST(append_string) - { - // with just path - uri_builder builder; - builder.append(U("/path1")); - VERIFY_ARE_EQUAL(U("/path1"), builder.path()); - - // with just query - builder.append(U("?key1=value1")); - VERIFY_ARE_EQUAL(U("/path1"), builder.path()); - VERIFY_ARE_EQUAL(U("key1=value1"), builder.query()); - VERIFY_ARE_EQUAL(U("/path1?key1=value1"), builder.to_string()); - - // with just fragment - builder.append(U("#fragment")); - VERIFY_ARE_EQUAL(U("/path1"), builder.path()); - VERIFY_ARE_EQUAL(U("key1=value1"), builder.query()); - VERIFY_ARE_EQUAL(U("fragment"), builder.fragment()); - VERIFY_ARE_EQUAL(U("/path1?key1=value1#fragment"), builder.to_string()); - - // with all - builder.append(U("/path2?key2=value2#frag2")); - VERIFY_ARE_EQUAL(U("/path1/path2"), builder.path()); - VERIFY_ARE_EQUAL(U("key1=value1&key2=value2"), builder.query()); - VERIFY_ARE_EQUAL(U("fragmentfrag2"), builder.fragment()); - VERIFY_ARE_EQUAL(U("/path1/path2?key1=value1&key2=value2#fragmentfrag2"), builder.to_string()); - } - - TEST(append_empty_string) - { - utility::string_t uri_str(U("http://uribuilder.com/")); - uri_builder builder(uri_str); - builder.append(U("")); - - VERIFY_ARE_EQUAL(builder.to_string(), uri_str); - } - - TEST(append_path_encoding) - { - uri_builder builder; - builder.append_path(U("/path space"), true); - VERIFY_ARE_EQUAL(U("/path%20space"), builder.path()); - - builder.append_path(U("path2")); - VERIFY_ARE_EQUAL(U("/path%20space/path2"), builder.path()); - } - - TEST(append_query_encoding) - { - uri_builder builder; - builder.append_query(U("key1 =value2"), true); - VERIFY_ARE_EQUAL(U("key1%20=value2"), builder.query()); - - builder.append_query(U("key2=value3")); - VERIFY_ARE_EQUAL(U("key1%20=value2&key2=value3"), builder.query()); - } - - TEST(append_encoding) - { - uri_builder builder; - builder.append(uri::encode_uri(U("path space?key =space#frag space"))); - VERIFY_ARE_EQUAL(U("/path%20space"), builder.path()); - VERIFY_ARE_EQUAL(U("key%20=space"), builder.query()); - VERIFY_ARE_EQUAL(U("frag%20space"), builder.fragment()); - VERIFY_ARE_EQUAL(U("/path%20space?key%20=space#frag%20space"), builder.to_string()); - - // try with encoded_string - builder = uri_builder(); - builder.append(U("/path2?key2=value2#frag2")); - VERIFY_ARE_EQUAL(U("/path2"), builder.path()); - VERIFY_ARE_EQUAL(U("key2=value2"), builder.query()); - VERIFY_ARE_EQUAL(U("frag2"), builder.fragment()); - VERIFY_ARE_EQUAL(U("/path2?key2=value2#frag2"), builder.to_string()); - } - - TEST(host_encoding) - { - // Check that ASCII characters that are invalid in a host name - // do not get percent-encoded. - - uri_builder ub1; - ub1.set_scheme(U("http")).set_host(U("????dfasddsf!@#$%^&*()_+")).set_port(80); - - VERIFY_IS_FALSE(ub1.is_valid()); - } - - TEST(clear) - { - uri_builder ub; - ub.clear(); - CHECK(ub.scheme() == U("")); - CHECK(ub.user_info() == U("")); - CHECK(ub.host() == U("")); - CHECK(ub.port() == -1); - CHECK(ub.path() == U("/")); - CHECK(ub.query() == U("")); - CHECK(ub.fragment() == U("")); - - ub = uri_builder(U("http://myhost.com/path1")); - ub.append_path(U("path2")); - uri u = ub.to_uri(); - ub.clear(); - CHECK(ub.scheme() == U("")); - CHECK(ub.user_info() == U("")); - CHECK(ub.host() == U("")); - CHECK(ub.port() == -1); - CHECK(ub.path() == U("/")); - CHECK(ub.query() == U("")); - CHECK(ub.fragment() == U("")); - CHECK(u.to_string() == U("http://myhost.com/path1/path2")); - - ub.append_path(U("path3")); - ub.set_host(U("hahah")); - ub.set_fragment(U("No")); - ub.clear(); - CHECK(ub.scheme() == U("")); - CHECK(ub.user_info() == U("")); - CHECK(ub.host() == U("")); - CHECK(ub.port() == -1); - CHECK(ub.path() == U("/")); - CHECK(ub.query() == U("")); - CHECK(ub.fragment() == U("")); - } - - TEST(to_string_invalid_uri) - { - uri_builder builder(U("http://invaliduri.com")); - builder.set_scheme(U("1http")); - VERIFY_THROWS(builder.to_string(), uri_exception); - VERIFY_THROWS(builder.to_uri(), uri_exception); - - builder.set_scheme(U("ht*ip")); - VERIFY_THROWS(builder.to_string(), uri_exception); - - builder.set_scheme(U("htt%20p")); - VERIFY_THROWS(builder.to_string(), uri_exception); - } - - TEST(append_query_locale, "Ignore:Android", "Locale unsupported on Android") - { - std::locale changedLocale; - try - { -#ifdef _WIN32 - changedLocale = std::locale("fr-FR"); -#else - changedLocale = std::locale("fr_FR.UTF-8"); -#endif - } - catch (const std::exception&) - { - // Silently pass if locale isn't installed on machine. - return; - } - - tests::common::utilities::locale_guard loc(changedLocale); - - uri_builder builder; - auto const& key = U("key1000"); - builder.append_query(key, 1000); - ::utility::string_t expected(key); - expected.append(U("=1000")); - VERIFY_ARE_EQUAL(expected, builder.query()); - } - - TEST(github_crash_994) { web::uri uri(U("http://127.0.0.1:34568/")); } - -} // SUITE(uri_builder_tests) - -} // namespace uri_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/uri_tests.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/uri/uri_tests.h @@ -1,25 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * uri_tests.h - * - * Common utilities and helper functions for URI tests. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "cpprest/uri.h" -#include "unittestpp.h" - -namespace tests -{ -namespace functional -{ -namespace uri_tests -{ -} -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/CMakeLists.txt @@ -1,16 +0,0 @@ -set(SOURCES - datetime.cpp - base64.cpp - strings.cpp - macro_test.cpp - nonce_generator_tests.cpp - win32_encryption_tests.cpp -) - -add_casablanca_test(utils_test SOURCES) - -if(CMAKE_COMPILER_IS_GNUCXX) - target_compile_options(utils_test PRIVATE "-Wno-deprecated-declarations") -endif() - -configure_pch(utils_test stdafx.h stdafx.cpp) diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/base64.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/base64.cpp @@ -1,260 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * base64.cpp - * - * Tests for base64-related utility functions and classes. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace utils_tests -{ -SUITE(base64) -{ - // Note: base64 works by encoding any 3 bytes as a four-byte string. Each triple is encoded independently of - // previous and subsequent triples. If, for a given set of input bytes, the number is not an even multiple of 3, - // the remaining 1 or two bytes are encoded and padded using '=' characters at the end. The encoding format is - // defined by IETF RFC 4648. Such padding is only allowed at the end of a encoded string, which makes it impossible - // to generally concatenate encoded strings and wind up with a string that is a valid base64 encoding. - // - // Since each triple of bytes is independent of others, we don't have to test particularly large sets if input data, - // validating that the algorithm can process at least two triples should be sufficient. - // - TEST(rfc_4648_tests_encode) - { - // These tests are what base64 RFC 4648 proposes. - { - std::vector<unsigned char> str1; - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('f'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Zg==")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('f'); - str1.push_back('o'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Zm8=")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('f'); - str1.push_back('o'); - str1.push_back('o'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Zm9v")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('f'); - str1.push_back('o'); - str1.push_back('o'); - str1.push_back('b'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Zm9vYg==")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('f'); - str1.push_back('o'); - str1.push_back('o'); - str1.push_back('b'); - str1.push_back('a'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Zm9vYmE=")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('f'); - str1.push_back('o'); - str1.push_back('o'); - str1.push_back('b'); - str1.push_back('a'); - str1.push_back('r'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Zm9vYmFy")), utility::conversions::to_base64(str1)); - } - } - - TEST(rfc_4648_tests_decode) - { - // These tests are what base64 RFC 4648 proposes. - { - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("")); - VERIFY_ARE_EQUAL(0u, str1.size()); - } - { - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Zg==")); - VERIFY_ARE_EQUAL(1u, str1.size()); - VERIFY_ARE_EQUAL('f', str1[0]); - } - { - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Zm8=")); - VERIFY_ARE_EQUAL(2u, str1.size()); - VERIFY_ARE_EQUAL('f', str1[0]); - VERIFY_ARE_EQUAL('o', str1[1]); - } - { - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Zm9v")); - VERIFY_ARE_EQUAL(3u, str1.size()); - VERIFY_ARE_EQUAL('f', str1[0]); - VERIFY_ARE_EQUAL('o', str1[1]); - VERIFY_ARE_EQUAL('o', str1[2]); - } - { - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Zm9vYg==")); - VERIFY_ARE_EQUAL(4u, str1.size()); - VERIFY_ARE_EQUAL('f', str1[0]); - VERIFY_ARE_EQUAL('o', str1[1]); - VERIFY_ARE_EQUAL('o', str1[2]); - VERIFY_ARE_EQUAL('b', str1[3]); - } - { - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Zm9vYmE=")); - VERIFY_ARE_EQUAL(5u, str1.size()); - VERIFY_ARE_EQUAL('f', str1[0]); - VERIFY_ARE_EQUAL('o', str1[1]); - VERIFY_ARE_EQUAL('o', str1[2]); - VERIFY_ARE_EQUAL('b', str1[3]); - VERIFY_ARE_EQUAL('a', str1[4]); - } - { - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Zm9vYmFy")); - VERIFY_ARE_EQUAL(6u, str1.size()); - VERIFY_ARE_EQUAL('f', str1[0]); - VERIFY_ARE_EQUAL('o', str1[1]); - VERIFY_ARE_EQUAL('o', str1[2]); - VERIFY_ARE_EQUAL('b', str1[3]); - VERIFY_ARE_EQUAL('a', str1[4]); - VERIFY_ARE_EQUAL('r', str1[5]); - } - } - - TEST(additional_encode) - { - { - // Check '/' encoding - std::vector<unsigned char> str1; - str1.push_back(254); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("/g==")), utility::conversions::to_base64(str1)); - } - { - // Check '+' encoding - std::vector<unsigned char> str1; - str1.push_back(250); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("+g==")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('f'); - str1.push_back('o'); - str1.push_back(239); - str1.push_back('b'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Zm/vYg==")), utility::conversions::to_base64(str1)); - } - { - std::vector<unsigned char> str1; - str1.push_back('g'); - str1.push_back(239); - str1.push_back('o'); - str1.push_back('b'); - VERIFY_ARE_EQUAL(string_t(_XPLATSTR("Z+9vYg==")), utility::conversions::to_base64(str1)); - } - } - - TEST(additional_decode) - { - // Tests beyond what the RFC recommends. - { - // Check '/' decoding - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("/g==")); - VERIFY_ARE_EQUAL(1u, str1.size()); - VERIFY_ARE_EQUAL(254u, str1[0]); - } - { - // Check '+' decoding - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("+g==")); - VERIFY_ARE_EQUAL(1u, str1.size()); - VERIFY_ARE_EQUAL(250u, str1[0]); - } - { - // Check '/' decoding - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Zm/vYg==")); - VERIFY_ARE_EQUAL(4u, str1.size()); - VERIFY_ARE_EQUAL('f', str1[0]); - VERIFY_ARE_EQUAL('o', str1[1]); - VERIFY_ARE_EQUAL(239, str1[2]); - VERIFY_ARE_EQUAL('b', str1[3]); - } - { - // Check '+' decoding - std::vector<unsigned char> str1 = utility::conversions::from_base64(_XPLATSTR("Z+9vYg==")); - VERIFY_ARE_EQUAL(4u, str1.size()); - VERIFY_ARE_EQUAL('g', str1[0]); - VERIFY_ARE_EQUAL(239, str1[1]); - VERIFY_ARE_EQUAL('o', str1[2]); - VERIFY_ARE_EQUAL('b', str1[3]); - } - { - // Check the whole base64 alphabet - std::vector<unsigned char> str1 = utility::conversions::from_base64( - _XPLATSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")); - VERIFY_ARE_EQUAL(48u, str1.size()); - } - } - - TEST(bad_decode) - { - // These tests are for input that should be disallowed by a very strict decoder, but - // the available APIs on Windows accept them, as does glib, which is used on Linux. - - // Invalid character before padding, unused ones. - VERIFY_THROWS(utility::conversions::from_base64(_XPLATSTR("/q==")), std::runtime_error); - VERIFY_THROWS(utility::conversions::from_base64(_XPLATSTR("Zm9vYmD=")), std::runtime_error); - - // CRLF in the middle. - VERIFY_THROWS(utility::conversions::from_base64( - _XPLATSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\nabcdefghijklmnopqrstuvwxyz\r\n0123456789+/")), - std::runtime_error); - - // Not the right length. - VERIFY_THROWS(utility::conversions::from_base64(_XPLATSTR("/q")), std::runtime_error); - // Characters not in the alphabet - VERIFY_THROWS(utility::conversions::from_base64(_XPLATSTR("$%#@")), std::runtime_error); - // Too much padding at the end. - VERIFY_THROWS(utility::conversions::from_base64(_XPLATSTR("/q=========")), std::runtime_error); - // Valid strings, concatenated - VERIFY_THROWS(utility::conversions::from_base64(_XPLATSTR("Z+9vYg==Z+9vYg==")), std::runtime_error); - } - - TEST(large_string) - { - const size_t size = 64 * 1024; - - std::vector<unsigned char> data(size); - for (auto i = 0u; i < size; ++i) - { - data[i] = (unsigned char)(rand() & 0xFF); - } - - auto string = utility::conversions::to_base64(data); - auto data2 = utility::conversions::from_base64(string); - - VERIFY_ARE_EQUAL(data, data2); - } - -} // SUITE(base64) - -} // namespace utils_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/datetime.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/datetime.cpp @@ -1,556 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests for datetime-related utility functions and classes. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#include <stdint.h> -#include <string> - -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace utils_tests -{ -SUITE(datetime) -{ - // This is by no means a comprehensive test suite for the datetime functionality. - // It's a response to a particular bug and should be amended over time. - - TEST(parsing_dateandtime_basic) - { - // ISO 8601 - // RFC 1123 - - auto dt1 = utility::datetime::from_string(_XPLATSTR("20130517T00:00:00Z"), utility::datetime::ISO_8601); - VERIFY_ARE_NOT_EQUAL(0u, dt1.to_interval()); - - auto dt2 = - utility::datetime::from_string(_XPLATSTR("Fri, 17 May 2013 00:00:00 GMT"), utility::datetime::RFC_1123); - VERIFY_ARE_NOT_EQUAL(0u, dt2.to_interval()); - - VERIFY_ARE_EQUAL(dt1.to_interval(), dt2.to_interval()); - } - - TEST(parsing_dateandtime_extended) - { - // ISO 8601 - // RFC 1123 - - auto dt1 = utility::datetime::from_string(_XPLATSTR("2013-05-17T00:00:00Z"), utility::datetime::ISO_8601); - VERIFY_ARE_NOT_EQUAL(0u, dt1.to_interval()); - - auto dt2 = - utility::datetime::from_string(_XPLATSTR("Fri, 17 May 2013 00:00:00 GMT"), utility::datetime::RFC_1123); - VERIFY_ARE_NOT_EQUAL(0u, dt2.to_interval()); - - VERIFY_ARE_EQUAL(dt1.to_interval(), dt2.to_interval()); - } - - TEST(parsing_date_basic) - { - // ISO 8601 - { - auto dt = utility::datetime::from_string(_XPLATSTR("20130517"), utility::datetime::ISO_8601); - - VERIFY_ARE_NOT_EQUAL(0u, dt.to_interval()); - } - } - - TEST(parsing_date_extended) - { - // ISO 8601 - { - auto dt = utility::datetime::from_string(_XPLATSTR("2013-05-17"), utility::datetime::ISO_8601); - - VERIFY_ARE_NOT_EQUAL(0u, dt.to_interval()); - } - } - - void TestDateTimeRoundtrip(utility::string_t str, utility::string_t strExpected) - { - auto dt = utility::datetime::from_string(str, utility::datetime::ISO_8601); - utility::string_t str2 = dt.to_string(utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(str2, strExpected); - - auto dt_me = utility::datetime::from_string_maximum_error(str, utility::datetime::ISO_8601); - utility::string_t str3 = dt_me.to_string(utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(str3, strExpected); - } - - void TestDateTimeRoundtrip(utility::string_t str) { TestDateTimeRoundtrip(str, str); } - - TEST(parsing_time_roundtrip_datetime1) - { - // Preserve all 7 digits after the comma: - TestDateTimeRoundtrip(_XPLATSTR("2013-11-19T14:30:59.1234567Z")); - } - - TEST(parsing_time_roundtrip_datetime2) - { - // lose the last '000' - TestDateTimeRoundtrip(_XPLATSTR("2013-11-19T14:30:59.1234567000Z"), _XPLATSTR("2013-11-19T14:30:59.1234567Z")); - // lose the last '999' without rounding up - TestDateTimeRoundtrip(_XPLATSTR("2013-11-19T14:30:59.1234567999Z"), _XPLATSTR("2013-11-19T14:30:59.1234567Z")); - } - - TEST(parsing_time_roundtrip_datetime3) - { - // leading 0-s after the comma, tricky to parse correctly - TestDateTimeRoundtrip(_XPLATSTR("2013-11-19T14:30:59.00123Z")); - } - - TEST(parsing_time_roundtrip_datetime4) - { - // another leading 0 test - TestDateTimeRoundtrip(_XPLATSTR("2013-11-19T14:30:59.0000001Z")); - } - - TEST(parsing_time_roundtrip_datetime5) - { - // this is going to be truncated - TestDateTimeRoundtrip(_XPLATSTR("2013-11-19T14:30:59.00000001Z"), _XPLATSTR("2013-11-19T14:30:59Z")); - } - - TEST(parsing_time_roundtrip_datetime6) - { - // Only one digit after the dot - TestDateTimeRoundtrip(_XPLATSTR("2013-11-19T14:30:59.5Z")); - } - - TEST(parsing_time_roundtrip_year_1900) { TestDateTimeRoundtrip(_XPLATSTR("1900-01-01T00:00:00Z")); } - - TEST(parsing_time_roundtrip_year_9999) { TestDateTimeRoundtrip(_XPLATSTR("9999-12-31T23:59:59Z")); } - - TEST(parsing_time_roundtrip_year_2016) { TestDateTimeRoundtrip(_XPLATSTR("2016-12-31T20:59:59Z")); } - - TEST(parsing_time_roundtrip_year_2020) { TestDateTimeRoundtrip(_XPLATSTR("2020-12-31T20:59:59Z")); } - - TEST(parsing_time_roundtrip_year_2021) { TestDateTimeRoundtrip(_XPLATSTR("2021-01-01T20:59:59Z")); } - - TEST(parsing_time_roundtrip_year_1601) { TestDateTimeRoundtrip(_XPLATSTR("1601-01-01T00:00:00Z")); } - - TEST(parsing_time_roundtrip_year_1602) { TestDateTimeRoundtrip(_XPLATSTR("1602-01-01T00:00:00Z")); } - - TEST(parsing_time_roundtrip_year_1603) { TestDateTimeRoundtrip(_XPLATSTR("1603-01-01T00:00:00Z")); } - - TEST(parsing_time_roundtrip_year_1604) { TestDateTimeRoundtrip(_XPLATSTR("1604-01-01T00:00:00Z")); } - - TEST(emitting_time_correct_day) - { - const auto test = utility::datetime() + UINT64_C(132004507640000000); // 2019-04-22T23:52:44 is a Monday - const auto actual = test.to_string(utility::datetime::RFC_1123); - const utility::string_t expected(_XPLATSTR("Mon")); - VERIFY_ARE_EQUAL(actual.substr(0, 3), expected); - } - - void TestRfc1123IsTimeT(const utility::char_t* str, uint64_t t) - { - datetime dt = datetime::from_string(str, utility::datetime::RFC_1123); - uint64_t interval = dt.to_interval(); - VERIFY_ARE_EQUAL(0, interval % 10000000); - interval /= 10000000; - interval -= 11644473600; // NT epoch adjustment - VERIFY_ARE_EQUAL(static_cast<uint64_t>(t), interval); - } - - TEST(parsing_time_rfc1123_accepts_each_day) - { - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 00:00:00 GMT"), 0); - TestRfc1123IsTimeT(_XPLATSTR("Fri, 02 Jan 1970 00:00:00 GMT"), 86400 * 1); - TestRfc1123IsTimeT(_XPLATSTR("Sat, 03 Jan 1970 00:00:00 GMT"), 86400 * 2); - TestRfc1123IsTimeT(_XPLATSTR("Sun, 04 Jan 1970 00:00:00 GMT"), 86400 * 3); - TestRfc1123IsTimeT(_XPLATSTR("Mon, 05 Jan 1970 00:00:00 GMT"), 86400 * 4); - TestRfc1123IsTimeT(_XPLATSTR("Tue, 06 Jan 1970 00:00:00 GMT"), 86400 * 5); - TestRfc1123IsTimeT(_XPLATSTR("Wed, 07 Jan 1970 00:00:00 GMT"), 86400 * 6); - } - - TEST(parsing_time_rfc1123_boundary_cases) - { - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 00:00:00 GMT"), 0); - TestRfc1123IsTimeT(_XPLATSTR("19 Jan 2038 03:14:06 GMT"), INT_MAX - 1); - TestRfc1123IsTimeT(_XPLATSTR("19 Jan 2038 03:13:07 -0001"), INT_MAX); - TestRfc1123IsTimeT(_XPLATSTR("19 Jan 2038 03:14:07 -0000"), INT_MAX); - TestRfc1123IsTimeT(_XPLATSTR("14 Jan 2019 23:16:21 +0000"), 1547507781); - TestRfc1123IsTimeT(_XPLATSTR("14 Jan 2019 23:16:21 -0001"), 1547507841); - TestRfc1123IsTimeT(_XPLATSTR("14 Jan 2019 23:16:21 +0001"), 1547507721); - TestRfc1123IsTimeT(_XPLATSTR("14 Jan 2019 23:16:21 -0100"), 1547511381); - TestRfc1123IsTimeT(_XPLATSTR("14 Jan 2019 23:16:21 +0100"), 1547504181); - } - - TEST(parsing_time_rfc1123_uses_each_field) - { - TestRfc1123IsTimeT(_XPLATSTR("02 Jan 1970 00:00:00 GMT"), 86400); - TestRfc1123IsTimeT(_XPLATSTR("12 Jan 1970 00:00:00 GMT"), 950400); - TestRfc1123IsTimeT(_XPLATSTR("01 Feb 1970 00:00:00 GMT"), 2678400); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 2000 00:00:00 GMT"), 946684800); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 2100 00:00:00 GMT"), 4102444800); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1990 00:00:00 GMT"), 631152000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1971 00:00:00 GMT"), 31536000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 10:00:00 GMT"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 01:00:00 GMT"), 3600); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 00:10:00 GMT"), 600); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 00:01:00 GMT"), 60); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 00:00:10 GMT"), 10); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 00:00:01 GMT"), 1); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 10:00:00 GMT"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 02:00:00 PST"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 03:00:00 PDT"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 03:00:00 MST"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 04:00:00 MDT"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 04:00:00 CST"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 05:00:00 CDT"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 05:00:00 EST"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 06:00:00 EDT"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 06:00:00 -0400"), 36000); - TestRfc1123IsTimeT(_XPLATSTR("01 Jan 1970 05:59:00 -0401"), 36000); - } - - TEST(parsing_time_rfc1123_max_days) - { - TestRfc1123IsTimeT(_XPLATSTR("31 Jan 1970 00:00:00 GMT"), 2592000); - TestRfc1123IsTimeT(_XPLATSTR("28 Feb 2019 00:00:00 GMT"), 1551312000); // non leap year allows feb 28 - TestRfc1123IsTimeT(_XPLATSTR("29 Feb 2020 00:00:00 GMT"), 1582934400); // leap year allows feb 29 - TestRfc1123IsTimeT(_XPLATSTR("31 Mar 1970 00:00:00 GMT"), 7689600); - TestRfc1123IsTimeT(_XPLATSTR("30 Apr 1970 00:00:00 GMT"), 10281600); - TestRfc1123IsTimeT(_XPLATSTR("31 May 1970 00:00:00 GMT"), 12960000); - TestRfc1123IsTimeT(_XPLATSTR("30 Jun 1970 00:00:00 GMT"), 15552000); - TestRfc1123IsTimeT(_XPLATSTR("31 Jul 1970 00:00:00 GMT"), 18230400); - TestRfc1123IsTimeT(_XPLATSTR("31 Aug 1970 00:00:00 GMT"), 20908800); - TestRfc1123IsTimeT(_XPLATSTR("30 Sep 1970 00:00:00 GMT"), 23500800); - TestRfc1123IsTimeT(_XPLATSTR("31 Oct 1970 00:00:00 GMT"), 26179200); - TestRfc1123IsTimeT(_XPLATSTR("30 Nov 1970 00:00:00 GMT"), 28771200); - TestRfc1123IsTimeT(_XPLATSTR("31 Dec 1970 00:00:00 GMT"), 31449600); - } - - TEST(parsing_time_rfc1123_invalid_cases) - { - const utility::string_t bad_strings[] = { - _XPLATSTR("Ahu, 01 Jan 1970 00:00:00 GMT"), // bad letters in each place - _XPLATSTR("TAu, 01 Jan 1970 00:00:00 GMT"), - _XPLATSTR("ThA, 01 Jan 1970 00:00:00 GMT"), - _XPLATSTR("ThuA 01 Jan 1970 00:00:00 GMT"), - _XPLATSTR("Thu,A01 Jan 1970 00:00:00 GMT"), - _XPLATSTR("Thu, A1 Jan 1970 00:00:00 GMT"), - _XPLATSTR("Thu, 0A Jan 1970 00:00:00 GMT"), - _XPLATSTR("Thu, 01AJan 1970 00:00:00 GMT"), - _XPLATSTR("Thu, 01 Aan 1970 00:00:00 GMT"), - _XPLATSTR("Thu, 01 JAn 1970 00:00:00 GMT"), - _XPLATSTR("Thu, 01 JaA 1970 00:00:00 GMT"), - _XPLATSTR("Thu, 01 JanA1970 00:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan A970 00:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1A70 00:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 19A0 00:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 197A 00:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970A00:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 A0:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 0A:00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 00A00:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:A0:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:0A:00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:00A00 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:A0 GMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:0A GMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00AGMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00 AMT"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00 GAT"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00 GMA"), - _XPLATSTR(""), // truncation - _XPLATSTR("T"), - _XPLATSTR("Th"), - _XPLATSTR("Thu"), - _XPLATSTR("Thu,"), - _XPLATSTR("Thu, "), - _XPLATSTR("Thu, 0"), - _XPLATSTR("Thu, 01"), - _XPLATSTR("Thu, 01 "), - _XPLATSTR("Thu, 01 J"), - _XPLATSTR("Thu, 01 Ja"), - _XPLATSTR("Thu, 01 Jan"), - _XPLATSTR("Thu, 01 Jan "), - _XPLATSTR("Thu, 01 Jan 1"), - _XPLATSTR("Thu, 01 Jan 19"), - _XPLATSTR("Thu, 01 Jan 197"), - _XPLATSTR("Thu, 01 Jan 1970"), - _XPLATSTR("Thu, 01 Jan 1970 "), - _XPLATSTR("Thu, 01 Jan 1970 0"), - _XPLATSTR("Thu, 01 Jan 1970 00"), - _XPLATSTR("Thu, 01 Jan 1970 00:"), - _XPLATSTR("Thu, 01 Jan 1970 00:0"), - _XPLATSTR("Thu, 01 Jan 1970 00:00"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:0"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00 "), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00 G"), - _XPLATSTR("Thu, 01 Jan 1970 00:00:00 GM"), - _XPLATSTR("Fri, 01 Jan 1970 00:00:00 GMT"), // wrong day - _XPLATSTR("01 Jan 1600 00:00:00 GMT"), // year too small - _XPLATSTR("01 Xxx 1971 00:00:00 GMT"), // month bad - _XPLATSTR("00 Jan 1971 00:00:00 GMT"), // day too small - _XPLATSTR("32 Jan 1971 00:00:00 GMT"), // day too big - _XPLATSTR("30 Feb 1971 00:00:00 GMT"), // day too big for feb - _XPLATSTR("30 Feb 1971 00:00:00 GMT"), // day too big for feb (non-leap year) - _XPLATSTR("32 Mar 1971 00:00:00 GMT"), // other months - _XPLATSTR("31 Apr 1971 00:00:00 GMT"), - _XPLATSTR("32 May 1971 00:00:00 GMT"), - _XPLATSTR("31 Jun 1971 00:00:00 GMT"), - _XPLATSTR("32 Jul 1971 00:00:00 GMT"), - _XPLATSTR("32 Aug 1971 00:00:00 GMT"), - _XPLATSTR("31 Sep 1971 00:00:00 GMT"), - _XPLATSTR("32 Oct 1971 00:00:00 GMT"), - _XPLATSTR("31 Nov 1971 00:00:00 GMT"), - _XPLATSTR("32 Dec 1971 00:00:00 GMT"), - _XPLATSTR("01 Jan 1971 70:00:00 GMT"), // hour too big - _XPLATSTR("01 Jan 1971 24:00:00 GMT"), - _XPLATSTR("01 Jan 1971 00:60:00 GMT"), // minute too big - _XPLATSTR("01 Jan 1971 00:00:70 GMT"), // second too big - _XPLATSTR("01 Jan 1971 00:00:61 GMT"), - _XPLATSTR("01 Jan 1600 00:00:00 GMT"), // underflow - _XPLATSTR("01 Jan 1969 00:00:00 CEST"), // bad tz - _XPLATSTR("14 Jan 2019 23:16:21 G0100"), // bad tzoffsets - _XPLATSTR("01 Jan 1970 00:00:00 +2400"), - _XPLATSTR("01 Jan 1970 00:00:00 -3000"), - _XPLATSTR("01 Jan 1970 00:00:00 +2160"), - _XPLATSTR("01 Jan 1970 00:00:00 -2400"), - _XPLATSTR("01 Jan 1970 00:00:00 -2160"), - _XPLATSTR("00 Jan 1971 00:00:00 GMT"), // zero month day - }; - - for (const auto& str : bad_strings) - { - auto dt = utility::datetime::from_string(str, utility::datetime::RFC_1123); - VERIFY_ARE_EQUAL(0, dt.to_interval()); - auto dt_me = utility::datetime::from_string_maximum_error(str, utility::datetime::RFC_1123); - VERIFY_ARE_EQUAL(utility::datetime::maximum(), dt_me); - } - } - - TEST(parsing_time_iso8601_boundary_cases) - { - // boundary cases: - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T00:00:00Z")); // epoch - TestDateTimeRoundtrip(_XPLATSTR("2038-01-19T03:14:06+00:00"), _XPLATSTR("2038-01-19T03:14:06Z")); // INT_MAX - 1 - TestDateTimeRoundtrip(_XPLATSTR("2038-01-19T03:13:07-00:01"), - _XPLATSTR("2038-01-19T03:14:07Z")); // INT_MAX after subtacting 1 - TestDateTimeRoundtrip(_XPLATSTR("2038-01-19T03:14:07-00:00"), _XPLATSTR("2038-01-19T03:14:07Z")); - } - - TEST(parsing_time_iso8601_uses_each_timezone_digit) - { - TestDateTimeRoundtrip(_XPLATSTR("2019-01-14T23:16:21+00:00"), _XPLATSTR("2019-01-14T23:16:21Z")); - TestDateTimeRoundtrip(_XPLATSTR("2019-01-14T23:16:21-00:01"), _XPLATSTR("2019-01-14T23:17:21Z")); - TestDateTimeRoundtrip(_XPLATSTR("2019-01-14T23:16:21+00:01"), _XPLATSTR("2019-01-14T23:15:21Z")); - TestDateTimeRoundtrip(_XPLATSTR("2019-01-14T23:16:21-01:00"), _XPLATSTR("2019-01-15T00:16:21Z")); - TestDateTimeRoundtrip(_XPLATSTR("2019-01-14T23:16:21+01:00"), _XPLATSTR("2019-01-14T22:16:21Z")); - } - - TEST(parsing_time_iso8601_uses_each_digit) - { - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T00:00:01Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T00:01:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T01:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-02T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-02-01T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1971-01-01T00:00:00Z")); - - TestDateTimeRoundtrip(_XPLATSTR("1999-01-01T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-12-01T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-09-01T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-30T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-31T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T23:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T19:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T00:59:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T00:00:59Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T00:00:60Z"), _XPLATSTR("1970-01-01T00:01:00Z")); // leap seconds - } - - TEST(parsing_time_iso8601_accepts_month_max_days) - { - TestDateTimeRoundtrip(_XPLATSTR("1970-01-31T00:00:00Z")); // jan - TestDateTimeRoundtrip(_XPLATSTR("2019-02-28T00:00:00Z")); // non leap year allows feb 28 - TestDateTimeRoundtrip(_XPLATSTR("2020-02-29T00:00:00Z")); // leap year allows feb 29 - TestDateTimeRoundtrip(_XPLATSTR("1970-03-31T00:00:00Z")); // mar - TestDateTimeRoundtrip(_XPLATSTR("1970-04-30T00:00:00Z")); // apr - TestDateTimeRoundtrip(_XPLATSTR("1970-05-31T00:00:00Z")); // may - TestDateTimeRoundtrip(_XPLATSTR("1970-06-30T00:00:00Z")); // jun - TestDateTimeRoundtrip(_XPLATSTR("1970-07-31T00:00:00Z")); // jul - TestDateTimeRoundtrip(_XPLATSTR("1970-08-31T00:00:00Z")); // aug - TestDateTimeRoundtrip(_XPLATSTR("1970-09-30T00:00:00Z")); // sep - TestDateTimeRoundtrip(_XPLATSTR("1970-10-31T00:00:00Z")); // oct - TestDateTimeRoundtrip(_XPLATSTR("1970-11-30T00:00:00Z")); // nov - TestDateTimeRoundtrip(_XPLATSTR("1970-12-31T00:00:00Z")); // dec - } - - TEST(parsing_time_iso8601_accepts_lowercase_t_z) - { - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01t00:00:00Z"), _XPLATSTR("1970-01-01T00:00:00Z")); - TestDateTimeRoundtrip(_XPLATSTR("1970-01-01T00:00:00z"), _XPLATSTR("1970-01-01T00:00:00Z")); - } - - TEST(parsing_time_roundtrip_datetime_accepts_invalid_no_trailing_timezone) - { - // No digits after the dot, or non-digits. This is not a valid input, but we should not choke on it, - // Simply ignore the bad fraction - const utility::string_t bad_strings[] = {_XPLATSTR("2013-11-19T14:30:59.Z"), - _XPLATSTR("2013-11-19T14:30:59.a12Z")}; - utility::string_t str_corrected = _XPLATSTR("2013-11-19T14:30:59Z"); - - for (const auto& str : bad_strings) - { - auto dt = utility::datetime::from_string(str, utility::datetime::ISO_8601); - utility::string_t str2 = dt.to_string(utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(str2, str_corrected); - } - } - - TEST(parsing_time_roundtrip_datetime_invalid2) - { - // Various unsupported cases. In all cases, we have produce an empty date time - const utility::string_t bad_strings[] = { - _XPLATSTR(""), // empty - _XPLATSTR(".Z"), // too short - _XPLATSTR(".Zx"), // no trailing Z - _XPLATSTR("3.14Z") // not a valid date - _XPLATSTR("a971-01-01T00:00:00Z"), // any non digits or valid separators - _XPLATSTR("1a71-01-01T00:00:00Z"), - _XPLATSTR("19a1-01-01T00:00:00Z"), - _XPLATSTR("197a-01-01T00:00:00Z"), - _XPLATSTR("1971a01-01T00:00:00Z"), - _XPLATSTR("1971-a1-01T00:00:00Z"), - _XPLATSTR("1971-0a-01T00:00:00Z"), - _XPLATSTR("1971-01a01T00:00:00Z"), - _XPLATSTR("1971-01-a1T00:00:00Z"), - _XPLATSTR("1971-01-0aT00:00:00Z"), - // _XPLATSTR("1971-01-01a00:00:00Z"), parsed as complete date - _XPLATSTR("1971-01-01Ta0:00:00Z"), - _XPLATSTR("1971-01-01T0a:00:00Z"), - _XPLATSTR("1971-01-01T00a00:00Z"), - _XPLATSTR("1971-01-01T00:a0:00Z"), - _XPLATSTR("1971-01-01T00:0a:00Z"), - _XPLATSTR("1971-01-01T00:00a00Z"), - _XPLATSTR("1971-01-01T00:00:a0Z"), - _XPLATSTR("1971-01-01T00:00:0aZ"), - // "1971-01-01T00:00:00a", accepted as per invalid_no_trailing_timezone above - _XPLATSTR("1"), // truncation - _XPLATSTR("19"), - _XPLATSTR("197"), - _XPLATSTR("1970"), - _XPLATSTR("1970-"), - _XPLATSTR("1970-0"), - _XPLATSTR("1970-01"), - _XPLATSTR("1970-01-"), - _XPLATSTR("1970-01-0"), - // _XPLATSTR("1970-01-01"), complete date - _XPLATSTR("1970-01-01T"), - _XPLATSTR("1970-01-01T0"), - _XPLATSTR("1970-01-01T00"), - _XPLATSTR("1970-01-01T00:"), - _XPLATSTR("1970-01-01T00:0"), - _XPLATSTR("1970-01-01T00:00"), - _XPLATSTR("1970-01-01T00:00:"), - _XPLATSTR("1970-01-01T00:00:0"), - // _XPLATSTR("1970-01-01T00:00:00"), // accepted as invalid timezone above - _XPLATSTR("1600-01-01T00:00:00Z"), // year too small - _XPLATSTR("1971-00-01T00:00:00Z"), // month too small - _XPLATSTR("1971-20-01T00:00:00Z"), // month too big - _XPLATSTR("1971-13-01T00:00:00Z"), - _XPLATSTR("1971-01-00T00:00:00Z"), // day too small - _XPLATSTR("1971-01-32T00:00:00Z"), // day too big - _XPLATSTR("1971-02-30T00:00:00Z"), // day too big for feb - _XPLATSTR("1971-02-30T00:00:00Z"), // day too big for feb (non-leap year) - _XPLATSTR("1971-03-32T00:00:00Z"), // other months - _XPLATSTR("1971-04-31T00:00:00Z"), - _XPLATSTR("1971-05-32T00:00:00Z"), - _XPLATSTR("1971-06-31T00:00:00Z"), - _XPLATSTR("1971-07-32T00:00:00Z"), - _XPLATSTR("1971-08-32T00:00:00Z"), - _XPLATSTR("1971-09-31T00:00:00Z"), - _XPLATSTR("1971-10-32T00:00:00Z"), - _XPLATSTR("1971-11-31T00:00:00Z"), - _XPLATSTR("1971-12-32T00:00:00Z"), - _XPLATSTR("1971-01-01T70:00:00Z"), // hour too big - _XPLATSTR("1971-01-01T24:00:00Z"), - _XPLATSTR("1971-01-01T00:60:00Z"), // minute too big - _XPLATSTR("1971-01-01T00:00:70Z"), // second too big - _XPLATSTR("1971-01-01T00:00:61Z"), - _XPLATSTR("1600-01-01T00:00:00Z"), // underflow - _XPLATSTR("1601-01-01T00:00:00+00:01"), // time zone underflow - // _XPLATSTR("1970-01-01T00:00:00.Z"), // accepted as invalid timezone above - _XPLATSTR("1970-01-01T00:00:00+24:00"), // bad tzoffsets - _XPLATSTR("1970-01-01T00:00:00-30:00"), - _XPLATSTR("1970-01-01T00:00:00+21:60"), - _XPLATSTR("1970-01-01T00:00:00-24:00"), - _XPLATSTR("1970-01-01T00:00:00-21:60"), - _XPLATSTR("1971-01-00"), // zero month day - }; - - for (const auto& str : bad_strings) - { - auto dt = utility::datetime::from_string(str, utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(dt.to_interval(), 0); - auto dt_me = utility::datetime::from_string_maximum_error(str, utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(dt_me, utility::datetime::maximum()); - } - } - - TEST(can_emit_nt_epoch_zero_rfc_1123) - { - auto result = utility::datetime {}.to_string(utility::datetime::RFC_1123); - VERIFY_ARE_EQUAL(_XPLATSTR("Mon, 01 Jan 1601 00:00:00 GMT"), result); - } - - TEST(can_emit_nt_epoch_zero_iso_8601) - { - auto result = utility::datetime {}.to_string(utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(_XPLATSTR("1601-01-01T00:00:00Z"), result); - } - - TEST(can_emit_year_9999_rfc_1123) - { - auto result = - utility::datetime::from_interval(INT64_C(0x24C85A5ED1C018F0)).to_string(utility::datetime::RFC_1123); - VERIFY_ARE_EQUAL(_XPLATSTR("Fri, 31 Dec 9999 23:59:59 GMT"), result); - } - - TEST(can_emit_year_9999_iso_8601) - { - auto result = - utility::datetime::from_interval(INT64_C(0x24C85A5ED1C018F0)).to_string(utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(_XPLATSTR("9999-12-31T23:59:59.999Z"), result); - } - - TEST(can_parse_nt_epoch_zero_rfc_1123) - { - auto dt = - utility::datetime::from_string(_XPLATSTR("Mon, 01 Jan 1601 00:00:00 GMT"), utility::datetime::RFC_1123); - VERIFY_ARE_EQUAL(0U, dt.to_interval()); - auto dt_me = utility::datetime::from_string_maximum_error(_XPLATSTR("Mon, 01 Jan 1601 00:00:00 GMT"), - utility::datetime::RFC_1123); - VERIFY_ARE_EQUAL(0U, dt_me.to_interval()); - } - - TEST(can_parse_nt_epoch_zero_iso_8601) - { - auto dt = utility::datetime::from_string(_XPLATSTR("1601-01-01T00:00:00Z"), utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(0U, dt.to_interval()); - auto dt_me = utility::datetime::from_string_maximum_error(_XPLATSTR("1601-01-01T00:00:00Z"), - utility::datetime::ISO_8601); - VERIFY_ARE_EQUAL(0U, dt_me.to_interval()); - } -} // SUITE(datetime) - -} // namespace utils_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/macro_test.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/macro_test.cpp @@ -1,38 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * macro_test.cpp - * - * Tests cases for macro name conflicts. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -#include "cpprest/http_client.h" -#include "cpprest/http_msg.h" -#include "cpprest/json.h" -#include "cpprest/uri_builder.h" - -namespace tests -{ -namespace functional -{ -namespace utils_tests -{ -template<typename U> -void macro_U_Test() -{ - (void)U(); -} - -SUITE(macro_test) -{ - TEST(U_test) { macro_U_Test<int>(); } -} -} // namespace utils_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/nonce_generator_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/nonce_generator_tests.cpp @@ -1,60 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * nonce_generator_tests.cpp - * - * Tests for nonce_generator class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace utils_tests -{ -SUITE(nonce_generator_tests) -{ - TEST(nonce_generator_set_length) - { - utility::nonce_generator gen; - VERIFY_ARE_EQUAL(utility::nonce_generator::default_length, gen.generate().length()); - - gen.set_length(1); - VERIFY_ARE_EQUAL(1, gen.generate().length()); - - gen.set_length(0); - VERIFY_ARE_EQUAL(0, gen.generate().length()); - - gen.set_length(500); - VERIFY_ARE_EQUAL(500, gen.generate().length()); - } - - TEST(nonce_generator_unique_strings) - { - // Generate 100 nonces and check each is unique. - std::vector<utility::string_t> nonces(100); - utility::nonce_generator gen; - for (auto&& v : nonces) - { - v = gen.generate(); - } - for (auto v : nonces) - { - VERIFY_ARE_EQUAL(1, std::count(nonces.begin(), nonces.end(), v)); - } - } - -} // SUITE(nonce_generator_tests) - -} // namespace utils_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/stdafx.cpp @@ -1,15 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ - -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" - -#if WIN32 -__declspec(dllexport) int utils_test_generate_lib = 0; -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/stdafx.h @@ -1,21 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * stdafx.h - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once -#define _TURN_OFF_PLATFORM_STRING - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/details/web_utilities.h" -#include "cpprest/uri.h" -#include "unittestpp.h" -#include "utils_tests.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/strings.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/strings.cpp @@ -1,409 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * base64.cpp - * - * Tests for base64-related utility functions and classes. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if !defined(__GLIBCXX__) -#include <codecvt> -#endif - -#include <locale_guard.h> - -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace utils_tests -{ -SUITE(strings) -{ - TEST(usascii_to_utf16) - { - std::string str_ascii("This is a test"); - utf16string str_utf16 = utility::conversions::usascii_to_utf16(str_ascii); - - for (size_t i = 0; i < str_ascii.size(); ++i) - { - VERIFY_ARE_EQUAL((utf16char)str_ascii[i], str_utf16[i]); - } - } - -#ifdef _WIN32 -#define UTF16(x) L##x -#else -#define UTF16(x) u##x -#endif - - TEST(utf16_to_utf8) - { -#if !defined(__GLIBCXX__) - std::wstring_convert<std::codecvt_utf8_utf16<utf16char>, utf16char> conversion; -#endif - - // encodes to single byte character - VERIFY_ARE_EQUAL("ABC987", utility::conversions::utf16_to_utf8(UTF16("ABC987"))); - utf16string input; - input.push_back(0x7F); // last ASCII character - auto result = utility::conversions::utf16_to_utf8(input); - VERIFY_ARE_EQUAL(0x7F, result[0]); - - // encodes to 2 byte character - input.clear(); - input.push_back(0x80); - input.push_back(0x14D); - input.push_back(0x7FF); - result = utility::conversions::utf16_to_utf8(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(194u, static_cast<unsigned char>(result[0])); - VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[1])); - VERIFY_ARE_EQUAL(197u, static_cast<unsigned char>(result[2])); - VERIFY_ARE_EQUAL(141u, static_cast<unsigned char>(result[3])); - VERIFY_ARE_EQUAL(223u, static_cast<unsigned char>(result[4])); - VERIFY_ARE_EQUAL(191u, static_cast<unsigned char>(result[5])); -#else - VERIFY_ARE_EQUAL(conversion.to_bytes(input), result); -#endif - - // encodes to 3 byte character - input.clear(); - input.push_back(0x800); - input.push_back(0x14AB); - input.push_back(0xFFFF); - result = utility::conversions::utf16_to_utf8(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(224u, static_cast<unsigned char>(result[0])); - VERIFY_ARE_EQUAL(160u, static_cast<unsigned char>(result[1])); - VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[2])); - VERIFY_ARE_EQUAL(225u, static_cast<unsigned char>(result[3])); - VERIFY_ARE_EQUAL(146u, static_cast<unsigned char>(result[4])); - VERIFY_ARE_EQUAL(171u, static_cast<unsigned char>(result[5])); - VERIFY_ARE_EQUAL(239u, static_cast<unsigned char>(result[6])); - VERIFY_ARE_EQUAL(191u, static_cast<unsigned char>(result[7])); - VERIFY_ARE_EQUAL(191u, static_cast<unsigned char>(result[8])); -#else - VERIFY_ARE_EQUAL(conversion.to_bytes(input), result); -#endif - - // surrogate pair - encodes to 4 byte character - input.clear(); - // U+10000 - input.push_back(0xD800); - input.push_back(0xDC00); - // U+12345 - input.push_back(0xD802); - input.push_back(0xDD29); - // U+10FFFF - input.push_back(0xDA3F); - input.push_back(0xDFFF); - result = utility::conversions::utf16_to_utf8(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(240u, static_cast<unsigned char>(result[0])); - VERIFY_ARE_EQUAL(144u, static_cast<unsigned char>(result[1])); - VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[2])); - VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[3])); - VERIFY_ARE_EQUAL(240u, static_cast<unsigned char>(result[4])); - VERIFY_ARE_EQUAL(144u, static_cast<unsigned char>(result[5])); - VERIFY_ARE_EQUAL(164u, static_cast<unsigned char>(result[6])); - VERIFY_ARE_EQUAL(169u, static_cast<unsigned char>(result[7])); - VERIFY_ARE_EQUAL(242u, static_cast<unsigned char>(result[8])); - VERIFY_ARE_EQUAL(159u, static_cast<unsigned char>(result[9])); - VERIFY_ARE_EQUAL(191u, static_cast<unsigned char>(result[10])); - VERIFY_ARE_EQUAL(191u, static_cast<unsigned char>(result[11])); -#else - VERIFY_ARE_EQUAL(conversion.to_bytes(input), result); -#endif - - // surrogate pair - covering regression bug where 0x10000 was accidentally bitwise OR'ed instead of added. - input.clear(); - input.push_back(0xD840); - input.push_back(0xDC00); - result = utility::conversions::utf16_to_utf8(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(240u, static_cast<unsigned char>(result[0])); - VERIFY_ARE_EQUAL(160u, static_cast<unsigned char>(result[1])); - VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[2])); - VERIFY_ARE_EQUAL(128u, static_cast<unsigned char>(result[3])); -#else - VERIFY_ARE_EQUAL(conversion.to_bytes(input), result); -#endif - } - - TEST(utf8_to_utf16) - { -#if !defined(__GLIBCXX__) - std::wstring_convert<std::codecvt_utf8_utf16<utf16char>, utf16char> conversion; -#endif - - // single byte character - VERIFY_ARE_EQUAL(UTF16("ABC123"), utility::conversions::utf8_to_utf16("ABC123")); - std::string input; - input.push_back(0x7F); // last ASCII character - auto result = utility::conversions::utf8_to_utf16(input); - VERIFY_ARE_EQUAL(0x7F, result[0]); - - // null byte - input.clear(); - input.push_back(0); - input.push_back(0); - result = utility::conversions::utf8_to_utf16(input); - VERIFY_ARE_EQUAL(0, result[0]); - VERIFY_ARE_EQUAL(0, result[1]); - - // 2 byte character - input.clear(); - // U+80 - input.push_back(208u); // 11010000 - input.push_back(128u); // 10000000 - // U+7FF - input.push_back(223u); // 11011111 - input.push_back(191u); // 10111111 - result = utility::conversions::utf8_to_utf16(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(1024, result[0]); - VERIFY_ARE_EQUAL(2047, result[1]); -#else - VERIFY_ARE_EQUAL(conversion.from_bytes(input), result); -#endif - - // 3 byte character - input.clear(); - // U+800 - input.push_back(232u); // 11101000 - input.push_back(128u); // 10000000 - input.push_back(128u); // 10000000 - // U+FFFF - input.push_back(239u); // 11101111 - input.push_back(191u); // 10111111 - input.push_back(191u); // 10111111 - result = utility::conversions::utf8_to_utf16(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(32768, result[0]); - VERIFY_ARE_EQUAL(65535, result[1]); -#else - VERIFY_ARE_EQUAL(conversion.from_bytes(input), result); -#endif - - // 4 byte character - input.clear(); - // U+10000 - input.push_back(244u); // 11110100 - input.push_back(128u); // 10000000 - input.push_back(128u); // 10000000 - input.push_back(128u); // 10000000 - // U+10FFFF - input.push_back(244u); // 11110100 - input.push_back(143u); // 10001111 - input.push_back(191u); // 10111111 - input.push_back(191u); // 10111111 - result = utility::conversions::utf8_to_utf16(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(56256, result[0]); - VERIFY_ARE_EQUAL(56320, result[1]); - VERIFY_ARE_EQUAL(56319, result[2]); - VERIFY_ARE_EQUAL(57343, result[3]); -#else - VERIFY_ARE_EQUAL(conversion.from_bytes(input), result); -#endif - - // 1 byte character followed by 4 byte character - input.clear(); - input.push_back(51u); // 00110011 - // U+10000 - input.push_back(244u); // 11110100 - input.push_back(128u); // 10000000 - input.push_back(128u); // 10000000 - input.push_back(128u); // 10000000 - // U+10FFFF - input.push_back(244u); // 11110100 - input.push_back(143u); // 10001111 - input.push_back(191u); // 10111111 - input.push_back(191u); // 10111111 - result = utility::conversions::utf8_to_utf16(input); -#if defined(__GLIBCXX__) - VERIFY_ARE_EQUAL(51, result[0]); - VERIFY_ARE_EQUAL(56256, result[1]); - VERIFY_ARE_EQUAL(56320, result[2]); - VERIFY_ARE_EQUAL(56319, result[3]); - VERIFY_ARE_EQUAL(57343, result[4]); -#else - VERIFY_ARE_EQUAL(conversion.from_bytes(input), result); -#endif - } - - TEST(utf16_to_utf8_errors) - { - VERIFY_ARE_EQUAL("ABC987", utility::conversions::utf16_to_utf8(UTF16("ABC987"))); - utf16string input; - - // high surrogate with missing low surrogate. - input.push_back(0xD800); - input.push_back(0x0); - VERIFY_THROWS(utility::conversions::utf16_to_utf8(input), std::range_error); - - // high surrogate with no more characters - input.clear(); - input.push_back(0xD800); - VERIFY_THROWS(utility::conversions::utf16_to_utf8(input), std::range_error); - } - - TEST(utf8_to_utf16_errors) - { - // missing second continuation byte - std::string input; - input.push_back(207u); // 11001111 - VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); - - // missing third continuation byte - input.clear(); - input.push_back(230u); // 11100110 - input.push_back(141u); // 10001101 - VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); - - // missing fourth continuation byte - input.clear(); - input.push_back(240u); // 11110000 - input.push_back(173u); // 10101101 - input.push_back(157u); // 10011101 - VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); - - // continuation byte missing leading 10xxxxxx - input.clear(); - input.push_back(230u); // 11100110 - input.push_back(141u); // 00001101 - VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); - input.clear(); - input.push_back(230u); // 11100110 - input.push_back(141u); // 11001101 - VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); - - // invalid for a first character to start with 1xxxxxxx - input.clear(); - input.push_back(128u); // 10000000 - input.push_back(128u); // 10000000 - VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); - input.clear(); - input.push_back(191u); // 10111111 - input.push_back(128u); // 10000000 - VERIFY_THROWS(utility::conversions::utf8_to_utf16(input), std::range_error); - } - - TEST(latin1_to_utf16) - { - char in[256] = {0}; - char16_t expectedResult[256] = {0}; - for (size_t i = 0; i < 256; ++i) - { - in[i] = static_cast<char>(i); - expectedResult[i] = static_cast<char16_t>(i); - } - - std::string str_latin1(in, 256); - - auto actualResult = utility::conversions::latin1_to_utf16(str_latin1); - - VERIFY_ARE_EQUAL(str_latin1.size(), actualResult.size()); - for (size_t i = 0; i < actualResult.size(); ++i) - { - VERIFY_ARE_EQUAL(expectedResult[i], actualResult[i]); - } - } - -#if defined(_MSC_VER) -#pragma warning(disable : 4996) -#elif defined(__clang__) -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#elif defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - - TEST(print_string_locale, "Ignore:Android", "Locale unsupported on Android") - { - std::locale changedLocale; - try - { -#ifdef _WIN32 - changedLocale = std::locale("fr-FR"); -#else - changedLocale = std::locale("fr_FR.UTF-8"); -#endif - } - catch (const std::exception&) - { - // Silently pass if locale isn't installed on machine. - return; - } - - tests::common::utilities::locale_guard loc(changedLocale); - - utility::ostringstream_t oss; - oss << 1000; - VERIFY_ARE_EQUAL(oss.str(), utility::conversions::print_string(1000)); - VERIFY_ARE_EQUAL(_XPLATSTR("1000"), utility::conversions::print_string(1000, std::locale::classic())); - } - - TEST(scan_string_locale, "Ignore:Android", "Locale unsupported on Android") - { - std::locale changedLocale; - try - { -#ifdef _WIN32 - changedLocale = std::locale("fr-FR"); -#else - changedLocale = std::locale("fr_FR.UTF-8"); -#endif - } - catch (const std::exception&) - { - // Silently pass if locale isn't installed on machine. - return; - } - - VERIFY_ARE_EQUAL(_XPLATSTR("1000"), - utility::conversions::scan_string<utility::string_t>(utility::string_t(_XPLATSTR("1000")))); - VERIFY_ARE_EQUAL(_XPLATSTR("1,000"), - utility::conversions::scan_string<utility::string_t>(utility::string_t(_XPLATSTR("1,000")))); - - VERIFY_ARE_EQUAL( - _XPLATSTR("1000"), - utility::conversions::scan_string<utility::string_t>(utility::string_t(_XPLATSTR("1000")), changedLocale)); - VERIFY_ARE_EQUAL( - _XPLATSTR("1,000"), - utility::conversions::scan_string<utility::string_t>(utility::string_t(_XPLATSTR("1,000")), changedLocale)); - - { - tests::common::utilities::locale_guard loc(changedLocale); - VERIFY_ARE_EQUAL(_XPLATSTR("1000"), - utility::conversions::scan_string<utility::string_t>(utility::string_t(_XPLATSTR("1000")), - std::locale::classic())); - VERIFY_ARE_EQUAL(_XPLATSTR("1,000"), - utility::conversions::scan_string<utility::string_t>(utility::string_t(_XPLATSTR("1,000")), - std::locale::classic())); - } - } - -#ifdef _WIN32 - TEST(windows_category_message) - { - // Ensure the error message string returned by windows_category doesn't contain trailing zeros. - std::string error_message = utility::details::windows_category().message(0); - std::string zero_terminated_copy = error_message.c_str(); - VERIFY_ARE_EQUAL(zero_terminated_copy, error_message); - } -#endif // _WIN32 -} - -} // namespace utils_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/utils_tests.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/utils_tests.h @@ -1,24 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * utils_tests.h - * - * Common utilities and helper functions for utility tests - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "unittestpp.h" - -namespace tests -{ -namespace functional -{ -namespace utils_tests -{ -} -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/win32_encryption_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/utils/win32_encryption_tests.cpp @@ -1,49 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * win32_encryption_tests.cpp - * - * Tests for win32_encryption class. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -using namespace utility; - -namespace tests -{ -namespace functional -{ -namespace utils_tests -{ -#if defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_VISTA && !defined(__cplusplus_winrt) -SUITE(win32_encryption) -{ - TEST(win32_encryption_random_string) - { - utility::string_t rndStr = utility::conversions::to_string_t("random string"); - web::details::win32_encryption enc(rndStr); - - VERIFY_ARE_EQUAL(*enc.decrypt(), rndStr); - } - - TEST(win32_encryption_empty_string) - { - utility::string_t emptyStr = utility::conversions::to_string_t(""); - web::details::win32_encryption enc(emptyStr); - - VERIFY_ARE_EQUAL(*enc.decrypt(), emptyStr); - } - -} // SUITE(win32_encryption) - -#endif // defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_VISTA && !defined(__cplusplus_winrt) - -} // namespace utils_tests -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/CMakeLists.txt b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/CMakeLists.txt @@ -1,35 +0,0 @@ -if (NOT CPPREST_EXCLUDE_WEBSOCKETS) - add_library(websockettest_utilities utilities/test_websocket_server.cpp) - target_include_directories(websockettest_utilities PUBLIC utilities) - target_compile_definitions(websockettest_utilities PRIVATE -DWEBSOCKETTESTUTILITY_EXPORTS) - if(NOT WIN32) - target_compile_definitions(websockettest_utilities PRIVATE "-DWEBSOCKET_UTILITY_API=__attribute__ ((visibility (\"default\")))") - target_compile_definitions(websockettest_utilities INTERFACE "-DWEBSOCKET_UTILITY_API=") - endif() - - cpprest_find_websocketpp() - target_link_libraries(websockettest_utilities - PRIVATE - cpprest - unittestpp - common_utilities - cpprestsdk_websocketpp_internal - ) - - # websocketsclient_test - set(SOURCES - client/authentication_tests.cpp - client/client_construction.cpp - client/close_tests.cpp - client/error_tests.cpp - client/receive_msg_tests.cpp - client/send_msg_tests.cpp - client/stdafx.cpp - ) - - add_casablanca_test(websocketsclient_test SOURCES) - if(NOT TEST_LIBRARY_TARGET_TYPE STREQUAL "OBJECT") - target_link_libraries(websocketsclient_test PRIVATE websockettest_utilities) - endif() - target_include_directories(websocketsclient_test PRIVATE utilities) -endif() diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/authentication_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/authentication_tests.cpp @@ -1,164 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * authentication_tests.cpp - * - * Tests cases for covering authentication using websocket_client - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) || !defined(_M_ARM) - -using namespace web::websockets; -using namespace web::websockets::client; - -using namespace tests::functional::websocket::utilities; - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -SUITE(authentication_tests) -{ -// Authorization not implemented in non WinRT websocket_client yet - CodePlex 254 -#if defined(__cplusplus_winrt) - void auth_helper(test_websocket_server & server, - const utility::string_t& username = U(""), - const utility::string_t& password = U("")) - { - server.set_http_handler([username, password](test_http_request request) { - test_http_response resp; - if (request->username().empty()) // No credentials -> challenge the request - { - resp.set_status_code(401); // Unauthorized. - resp.set_realm("My Realm"); - } - else if (request->username().compare(utility::conversions::to_utf8string(username)) || - request->password().compare(utility::conversions::to_utf8string(password))) - { - resp.set_status_code(403); // User name/password did not match: Forbidden - auth failure. - } - else - { - resp.set_status_code(200); // User name and passwords match. Successful auth. - } - return resp; - }); - } - - // connect without credentials, when the server expects credentials - TEST_FIXTURE(uri_address, auth_no_credentials, "Ignore", "245") - { - test_websocket_server server; - websocket_client client; - auth_helper(server); - VERIFY_THROWS(client.connect(m_uri).wait(), websocket_exception); - } - - // Connect with credentials - TEST_FIXTURE(uri_address, auth_with_credentials, "Ignore", "245") - { - test_websocket_server server; - websocket_client_config config; - web::credentials cred(U("user"), U("password")); - config.set_credentials(cred); - websocket_client client(config); - - auth_helper(server, cred.username(), U("password")); - client.connect(m_uri).wait(); - client.close().wait(); - } -#endif - - // helper function to check if failure is due to timeout. - bool is_timeout(const std::string& msg) - { - if (msg.find("set_fail_handler") != std::string::npos) - { - if (msg.find("handshake timed out") != std::string::npos || msg.find("Timer Expired") != std::string::npos) - { - return true; - } - } - return false; - } - - TEST(ssl_test) - { - websocket_client client; - std::string body_str("hello"); - - try - { - client.connect(U("wss://echo.websocket.org/")).wait(); - auto receive_task = client.receive().then([body_str](websocket_incoming_message ret_msg) { - VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length()); - auto ret_str = ret_msg.extract_string().get(); - - VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }); - - websocket_outgoing_message msg; - msg.set_utf8_message(body_str); - client.send(msg).wait(); - - receive_task.wait(); - client.close().wait(); - } - catch (const websocket_exception& e) - { - if (is_timeout(e.what())) - { - // Since this test depends on an outside server sometimes it sporadically can fail due to timeouts - // especially on our build machines. - return; - } - throw; - } - } - - void handshake_error_test_impl(const ::utility::string_t& host) - { - websocket_client client; - try - { - client.connect(host).wait(); - VERIFY_IS_TRUE(false); - } - catch (const websocket_exception& e) - { - if (is_timeout(e.what())) - { - // Since this test depends on an outside server sometimes it sporadically can fail due to timeouts - // especially on our build machines. - return; - } - VERIFY_ARE_EQUAL("TLS handshake failed", e.error_code().message()); - } - } - - TEST(self_signed_cert) { handshake_error_test_impl(U("wss://self-signed.badssl.com/")); } - - TEST(hostname_mismatch) { handshake_error_test_impl(U("wss://wrong.host.badssl.com/")); } - - TEST(cert_expired) { handshake_error_test_impl(U("wss://expired.badssl.com/")); } - -} // SUITE(authentication_tests) - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/client_construction.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/client_construction.cpp @@ -1,255 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * client_construction.cpp - * - * Tests cases for covering creating websocket_clients. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) || !defined(_M_ARM) - -using namespace concurrency::streams; - -using namespace web; -using namespace web::websockets; -using namespace web::websockets::client; - -using namespace tests::functional::websocket::utilities; - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -SUITE(client_construction) -{ - // Helper function verifies that when constructing a websocket_client with invalid - // URI std::invalid_argument is thrown. - static void verify_client_invalid_argument(const uri& address) - { - try - { - websocket_client client; - client.connect(address).wait(); - VERIFY_IS_TRUE(false); - } - catch (std::invalid_argument&) - { - // expected - } - } - - TEST_FIXTURE(uri_address, client_construction_error_cases) - { - uri address(U("notws://localhost:34567/")); - - // Invalid scheme. - verify_client_invalid_argument(address); - - // empty host. - address = uri(U("ws://:34567/")); - verify_client_invalid_argument(address); - } - - // Verify that we can read the config from the websocket_client - TEST_FIXTURE(uri_address, get_client_config) - { - websocket_client_config config; - - web::credentials cred(U("username"), U("password")); - config.set_credentials(cred); - websocket_client client(config); - - const websocket_client_config& config2 = client.config(); - VERIFY_ARE_EQUAL(config2.credentials().username(), cred.username()); - } - - // Verify that we can read the config from the websocket_callback_client - TEST_FIXTURE(uri_address, get_client_config_callback_client) - { - websocket_client_config config; - - web::credentials cred(U("username"), U("password")); - config.set_credentials(cred); - websocket_callback_client client(config); - - const websocket_client_config& config2 = client.config(); - VERIFY_ARE_EQUAL(config2.credentials().username(), cred.username()); - } - - // Verify that we can get the baseuri from websocket_client connect. - TEST_FIXTURE(uri_address, uri_test) - { - websocket_client client1; - VERIFY_ARE_EQUAL(client1.uri(), U("/")); - - test_websocket_server server; - client1.connect(m_uri).wait(); - VERIFY_ARE_EQUAL(client1.uri(), m_uri); - client1.close().wait(); - - websocket_client_config config; - websocket_client client2(config); - VERIFY_ARE_EQUAL(client2.uri(), U("/")); - - client2.connect(m_uri).wait(); - VERIFY_ARE_EQUAL(client2.uri(), m_uri); - client2.close().wait(); - } - - TEST_FIXTURE(uri_address, move_operations) - { - std::string body("hello"); - std::vector<unsigned char> body_vec(body.begin(), body.end()); - - test_websocket_server server; - websocket_client client; - - client.connect(m_uri).wait(); - - // Move constructor - websocket_client client2 = std::move(client); - - server.next_message([&](test_websocket_msg msg) // Handler to verify the message sent by the client. - { - websocket_asserts::assert_message_equals( - msg, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - - websocket_outgoing_message msg; - msg.set_utf8_message(body); - client2.send(std::move(msg)).wait(); - - auto t = client2.receive().then([&](websocket_incoming_message ret_msg) { - VERIFY_ARE_EQUAL(ret_msg.length(), body.length()); - auto ret_str = ret_msg.extract_string().get(); - - VERIFY_ARE_EQUAL(body.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }); - - test_websocket_msg rmsg; - rmsg.set_data(body_vec); - rmsg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - server.send_msg(rmsg); - t.wait(); - - // Move assignment - client = std::move(client2); - server.next_message([&](test_websocket_msg msg) // Handler to verify the message sent by the client. - { - websocket_asserts::assert_message_equals( - msg, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - - websocket_outgoing_message msg1; - msg1.set_utf8_message(body); - client.send(std::move(msg1)).wait(); - - test_websocket_msg rmsg1; - rmsg1.set_data(body_vec); - rmsg1.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - server.send_msg(rmsg1); - auto t1 = client.receive().then([&](websocket_incoming_message ret_msg) { - VERIFY_ARE_EQUAL(ret_msg.length(), body.length()); - auto ret_str = ret_msg.extract_string().get(); - - VERIFY_ARE_EQUAL(body.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }); - t1.wait(); - client.close().wait(); - } - - void header_test_impl(const uri& address, - const utility::string_t& headerName, - const utility::string_t& headerValue, - const utility::string_t& expectedHeaderValue = U("")) - { - test_websocket_server server; - websocket_client_config config; - utility::string_t expectedValue = headerValue; - if (!expectedHeaderValue.empty()) - { - expectedValue = expectedHeaderValue; - } - config.headers().add(headerName, headerValue); - websocket_client client(config); - - server.set_http_handler([&](test_http_request request) { - test_http_response resp; - if (request->get_header_val(utility::conversions::to_utf8string(headerName)) - .compare(utility::conversions::to_utf8string(expectedValue)) == 0) - resp.set_status_code(200); // Handshake request will be completed only if header match succeeds. - else - resp.set_status_code(400); // Else fail the handshake, websocket client connect will fail in this case. - return resp; - }); - client.connect(address).wait(); - client.close().wait(); - } - - TEST_FIXTURE(uri_address, connect_with_headers) - { - header_test_impl(m_uri, U("HeaderTest"), U("ConnectSuccessfully")); - } - - TEST_FIXTURE(uri_address, manually_set_protocol_header) - { - utility::string_t headerName(U("Sec-WebSocket-Protocol")); - header_test_impl(m_uri, headerName, U("myprotocol")); - header_test_impl(m_uri, headerName, U("myprotocol2,"), U("myprotocol2")); - header_test_impl(m_uri, headerName, U("myprotocol2,protocol3"), U("myprotocol2, protocol3")); - header_test_impl( - m_uri, headerName, U("myprotocol2, protocol3, protocol6,,"), U("myprotocol2, protocol3, protocol6")); - } - - TEST_FIXTURE(uri_address, set_subprotocol) - { - test_websocket_server server; - websocket_client_config config; - - utility::string_t expected1(U("pro1")); - config.add_subprotocol(expected1); - VERIFY_ARE_EQUAL(1, config.subprotocols().size()); - VERIFY_ARE_EQUAL(expected1, config.subprotocols()[0]); - - utility::string_t expected2(U("second")); - config.add_subprotocol(expected2); - VERIFY_ARE_EQUAL(2, config.subprotocols().size()); - VERIFY_ARE_EQUAL(expected1, config.subprotocols()[0]); - VERIFY_ARE_EQUAL(expected2, config.subprotocols()[1]); - - websocket_client client(config); - server.set_http_handler([&](test_http_request request) { - test_http_response resp; - if (request->get_header_val(utility::conversions::to_utf8string(U("Sec-WebSocket-Protocol"))) - .compare(utility::conversions::to_utf8string(expected1 + U(", ") + expected2)) == 0) - resp.set_status_code(200); // Handshake request will be completed only if header match succeeds. - else - resp.set_status_code(400); // Else fail the handshake, websocket client connect will fail in this case. - return resp; - }); - - client.connect(m_uri).wait(); - client.close().wait(); - } - -} // SUITE(client_construction) - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/close_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/close_tests.cpp @@ -1,167 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * close_tests.cpp - * - * Tests cases for closing websocket_client objects. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) || !defined(_M_ARM) - -using namespace concurrency::streams; - -using namespace web::websockets; -using namespace web::websockets::client; - -using namespace tests::functional::websocket::utilities; - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -SUITE(close_tests) -{ - // Test close websocket connection: client sends an empty close and server responds with close frame - TEST_FIXTURE(uri_address, close_client_websocket) - { - test_websocket_server server; - - websocket_client client; - - client.connect(m_uri).wait(); - - client.close().wait(); - } - - // Test close websocket connection: client sends a close with reason and server responds with close frame - TEST_FIXTURE(uri_address, close_with_reason) - { - test_websocket_server server; - - websocket_client client; - - client.connect(m_uri).wait(); - - client.close(websocket_close_status::going_away, U("Client disconnecting")).wait(); - } - - // Server sends a close frame (server initiated close) - TEST_FIXTURE(uri_address, close_from_server) - { - std::string body("hello"); - test_websocket_server server; - - websocket_client client; - - client.connect(m_uri).wait(); - - // Send close frame from server - test_websocket_msg msg; - msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_CLOSE_TYPE); - server.send_msg(msg); - - client.close().wait(); - } - - // Test close websocket connection with callback client: client sends an empty close and server responds with close - // frame - TEST_FIXTURE(uri_address, close_callback_client_websocket, "Ignore", "319") - { - test_websocket_server server; - const utility::string_t close_reason = U("Too large"); - - // verify it is ok not to set close handler - websocket_callback_client client; - - client.connect(m_uri).wait(); - - client.close().wait(); - - websocket_callback_client client1; - - client1.set_close_handler([&close_reason](websocket_close_status status, - const utility::string_t& reason, - const std::error_code& code) { - VERIFY_ARE_EQUAL(status, websocket_close_status::too_large); - VERIFY_ARE_EQUAL(reason, close_reason); - VERIFY_ARE_EQUAL(code.value(), 0); - }); - - client1.connect(m_uri).wait(); - - client1.close(websocket_close_status::too_large, close_reason).wait(); - } - - // Test close websocket connection: client sends a close with reason and server responds with close frame - TEST_FIXTURE(uri_address, close_callback_client_with_reason, "Ignore", "319") - { - const utility::string_t close_reason = U("Client disconnecting"); - test_websocket_server server; - - websocket_callback_client client; - - client.set_close_handler([close_reason](websocket_close_status status, - const utility::string_t& reason, - const std::error_code& code) { - VERIFY_ARE_EQUAL(status, websocket_close_status::normal); - VERIFY_ARE_EQUAL(reason, close_reason); - VERIFY_ARE_EQUAL(code.value(), 0); - }); - - client.connect(m_uri).wait(); - - client.close(websocket_close_status::normal, close_reason).wait(); - } - - // Server sends a close frame (server initiated close) - TEST_FIXTURE(uri_address, close_callback_client_from_server, "Ignore", "319") - { - std::string body("hello"); - test_websocket_server server; - - websocket_callback_client client; - - int hitCount = 0; - pplx::task_completion_event<void> closeEvent; - client.set_close_handler([&hitCount, closeEvent](websocket_close_status status, - const utility::string_t& reason, - const std::error_code& code) { - VERIFY_ARE_EQUAL(status, websocket_close_status::going_away); - VERIFY_ARE_EQUAL(reason, U("")); - VERIFY_ARE_EQUAL(code.value(), 0); - - hitCount++; - closeEvent.set(); - }); - - client.connect(m_uri).wait(); - - // Send close frame from server - test_websocket_msg msg; - msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_CLOSE_TYPE); - server.send_msg(msg); - - // make sure it only called once. - pplx::create_task(closeEvent).wait(); - VERIFY_ARE_EQUAL(hitCount, 1); - } - -} // SUITE(close_tests) - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/error_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/error_tests.cpp @@ -1,172 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Tests cases error connection cases with websocket_client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) || !defined(_M_ARM) - -using namespace concurrency::streams; - -using namespace web::websockets; -using namespace web::websockets::client; - -using namespace tests::functional::websocket::utilities; - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -SUITE(error_tests) -{ - // Send before connecting - TEST_FIXTURE(uri_address, send_before_connect) - { - websocket_client client; - - websocket_outgoing_message msg; - msg.set_utf8_message("xyz"); - - VERIFY_THROWS(client.send(msg).wait(), websocket_exception); - } - - // Server does not exist - TEST_FIXTURE(uri_address, server_doesnt_exist) - { - websocket_client client; - VERIFY_THROWS(client.connect(m_uri).get(), websocket_exception); - } - -// Send after close -// CodePlex 319 fails on VS2013. -#if !defined(_MSC_VER) || _MSC_VER >= 1900 - TEST_FIXTURE(uri_address, send_after_close) - { - std::string body("hello"); - test_websocket_server server; - - server.next_message([&](test_websocket_msg msg) { - websocket_asserts::assert_message_equals( - msg, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - websocket_client client; - - client.connect(m_uri).wait(); - client.close().wait(); - - websocket_outgoing_message msg; - msg.set_utf8_message(body); - VERIFY_THROWS(client.send(msg).wait(), websocket_exception); - } -#endif - - // Send after close for callback client - TEST_FIXTURE(uri_address, send_after_close_callback_client, "Ignore", "319") - { - std::string body("hello"); - test_websocket_server server; - - server.next_message([&](test_websocket_msg msg) { - websocket_asserts::assert_message_equals( - msg, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - websocket_callback_client client; - - client.connect(m_uri).wait(); - client.close().wait(); - - websocket_outgoing_message msg; - msg.set_utf8_message(body); - VERIFY_THROWS(client.send(msg).wait(), websocket_exception); - } - - // Receive after close - TEST_FIXTURE(uri_address, receive_after_close) - { - test_websocket_server server; - websocket_client client; - client.connect(m_uri).wait(); - auto t = client.receive(); - client.close().wait(); - VERIFY_THROWS(t.wait(), websocket_exception); - } - - // Start receive task after client has closed - TEST_FIXTURE(uri_address, try_receive_after_close) - { - test_websocket_server server; - websocket_client client; - client.connect(m_uri).wait(); - client.close().wait(); - auto t = client.receive(); - VERIFY_THROWS(t.wait(), websocket_exception); - } - - // Start the receive task after server has sent a close frame - TEST_FIXTURE(uri_address, try_receive_after_server_initiated_close) - { - test_websocket_server server; - websocket_client client; - client.connect(m_uri).wait(); - - // Send close frame from server - test_websocket_msg msg; - msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_CLOSE_TYPE); - server.send_msg(msg); - - // 100 ms should be plenty for local loopback - std::chrono::milliseconds dura(100); - std::this_thread::sleep_for(dura); - - auto t = client.receive(); - VERIFY_THROWS(t.wait(), websocket_exception); - - client.close().wait(); - } - - // Destroy the client without closing it explicitly - TEST_FIXTURE(uri_address, destroy_without_close) - { - test_websocket_server server; - websocket_client client; - client.connect(m_uri).wait(); - } - - // Destroy the callback client without closing it explicitly - TEST_FIXTURE(uri_address, destroy_without_close_callback_client) - { - // test won't finish if we can't release client properly - test_websocket_server server; - websocket_callback_client client; - client.connect(m_uri).wait(); - } - - // connect fails while user is waiting on receive - TEST_FIXTURE(uri_address, connect_fail_with_receive) - { - websocket_client client; - auto t = client.receive(); - - VERIFY_THROWS(client.connect(U("ws://localhost:9981/ws")).get(), websocket_exception); - VERIFY_THROWS(t.get(), websocket_exception); - } - -} // SUITE(error_tests) - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/proxy_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/proxy_tests.cpp @@ -1,92 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * proxy_tests.cpp - * - * Tests cases for covering proxies using websocket_client - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) || !defined(_M_ARM) - -using namespace web::websockets; -using namespace web::websockets::client; - -using namespace tests::functional::websocket::utilities; - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -SUITE(proxy_tests) -{ -#ifdef __cplusplus_winrt - TEST_FIXTURE(uri_address, no_proxy_options_on_winrt) - { - websocket_client_config config; - config.set_proxy(web::web_proxy::use_auto_discovery); - websocket_client client(config); - VERIFY_THROWS(client.connect(m_uri).wait(), websocket_exception); - } -#endif - -#ifndef __cplusplus_winrt - // Can't specify a proxy with WinRT implementation. - TEST_FIXTURE(uri_address, proxy_with_credentials, "Ignore:Android", "390") - { - web::web_proxy proxy(U("http://netproxy.redmond.corp.microsoft.com")); - web::credentials cred(U("artur"), U("fred")); // relax, this is not my real password - proxy.set_credentials(cred); - websocket_client_config config; - config.set_proxy(proxy); - - websocket_client client(config); - - try - { - client.connect(U("wss://echo.websocket.org/")).wait(); - const auto text = std::string("hello"); - websocket_outgoing_message msg; - msg.set_utf8_message(text); - client.send(msg).wait(); - auto response = client.receive().get(); - VERIFY_ARE_EQUAL(text, response.extract_string().get()); - client.close().wait(); - } - catch (websocket_exception const& e) - { - if (e.error_code().value() == 12007) - { - // The above "netproxy.redmond.corp.microsoft.com" is an internal site not generally accessible. - // This will cause a failure to resolve the URL. - // This is ok. - return; - } - else if (e.error_code().value() == 9 || e.error_code().value() == 5) - { - // Timer expired case, since this is an outside test don't fail due to timing out. - return; - } - throw; - } - } -#endif - -} // SUITE(proxy_tests) - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/receive_msg_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/receive_msg_tests.cpp @@ -1,307 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * receive_msg_tests.cpp - * - * Test cases covering receiving messages from websocket server. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) || !defined(_M_ARM) - -using namespace concurrency; -using namespace concurrency::streams; - -using namespace web::websockets; -using namespace web::websockets::client; - -using namespace tests::functional::websocket::utilities; - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -SUITE(receive_msg_tests) -{ - pplx::task<void> receive_text_msg_helper(websocket_client & client, - test_websocket_server & server, - web::uri uri, - const std::string& body_str, - bool connect_client = true) - { - std::vector<unsigned char> body(body_str.begin(), body_str.end()); - - if (connect_client) client.connect(uri).wait(); - - auto t = client.receive().then([body_str](websocket_incoming_message ret_msg) { - VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length()); - auto ret_str = ret_msg.extract_string().get(); - - VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }); - - test_websocket_msg msg; - msg.set_data(std::move(body)); - msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - server.send_msg(msg); - - return t; - } - - pplx::task<void> receive_msg_stream_helper(websocket_client & client, - test_websocket_server & server, - web::uri uri, - const std::vector<unsigned char>& body, - test_websocket_message_type type, - bool connect_client = true) - { - if (connect_client) client.connect(uri).wait(); - - auto t = client.receive().then([body, type](websocket_incoming_message ret_msg) { - auto is = ret_msg.body(); - streams::container_buffer<std::vector<uint8_t>> ret_data; - is.read_to_end(ret_data).wait(); - - VERIFY_ARE_EQUAL(ret_msg.length(), body.size()); - VERIFY_ARE_EQUAL(body, ret_data.collection()); - if (type == test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE) - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::binary_message); - else if (type == test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE) - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }); - - test_websocket_msg msg; - msg.set_data(std::move(body)); - msg.set_msg_type(type); - server.send_msg(msg); - - return t; - } - - // Receive text message (no fragmentation) - TEST_FIXTURE(uri_address, receive_text_msg) - { - test_websocket_server server; - websocket_client client; - - receive_text_msg_helper(client, server, m_uri, "hello").wait(); - client.close().wait(); - } - - // Receive text message (no fragmentation) - // Test the stream interface to read data - TEST_FIXTURE(uri_address, receive_text_msg_stream) - { - std::string body_str("hello"); - std::vector<unsigned char> body(body_str.begin(), body_str.end()); - test_websocket_server server; - websocket_client client; - - receive_msg_stream_helper( - client, server, m_uri, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE) - .wait(); - client.close().wait(); - } - - // Receive binary message (no fragmentation) - TEST_FIXTURE(uri_address, receive_binary_msg) - { - std::vector<uint8_t> body; - body.resize(6); - memcpy(&body[0], "a\0b\0c\0", 6); - - test_websocket_server server; - - websocket_client client; - - receive_msg_stream_helper( - client, server, m_uri, body, test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE) - .wait(); - client.close().wait(); - } - - // Server sends text message fragmented in 2 fragments - TEST_FIXTURE(uri_address, receive_text_msg_fragments, "Ignore", "898451") - { - std::string body_str("hello"); - std::vector<unsigned char> body(body_str.begin(), body_str.end()); - test_websocket_server server; - - websocket_client client; - - client.connect(m_uri).wait(); - - auto t = client.receive().then([&](websocket_incoming_message ret_msg) { - auto ret_str = ret_msg.extract_string().get(); - - VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }); - - test_websocket_msg msg1; - msg1.set_data(std::move(body)); - msg1.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_FRAGMENT_TYPE); - server.send_msg(msg1); - - test_websocket_msg msg2; - msg2.set_data(std::move(body)); - msg2.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_FRAGMENT_TYPE); - server.send_msg(msg2); - - t.wait(); - client.close().wait(); - } - - // Server sends message of length 0 - TEST_FIXTURE(uri_address, receive_zero_length_msg) - { - test_websocket_server server; - websocket_client client; - - receive_text_msg_helper(client, server, m_uri, "").wait(); - - client.close().wait(); - } - - // Receive UTF-8 string with special characters - TEST_FIXTURE(uri_address, receive_multi_byte_utf8_msg) - { - std::string body_str = "\xC3\xA0\xC3\xB8"; - test_websocket_server server; - websocket_client client; - - receive_text_msg_helper(client, server, m_uri, body_str).wait(); - - client.close().wait(); - } - - // Receive multiple messages - TEST_FIXTURE(uri_address, receive_multiple_msges) - { - test_websocket_server server; - websocket_client client; - - auto t1 = receive_text_msg_helper(client, server, m_uri, "hello1"); - auto t2 = receive_text_msg_helper(client, server, m_uri, "hello2", false); - - t1.wait(); - t2.wait(); - - client.close().wait(); - } - - // Start the receive task after the server has sent a message - TEST_FIXTURE(uri_address, receive_after_server_send) - { - std::string body_str("hello"); - std::vector<unsigned char> body(body_str.begin(), body_str.end()); - - test_websocket_server server; - - websocket_client client; - - client.connect(m_uri).wait(); - - test_websocket_msg msg; - msg.set_data(std::move(body)); - msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - server.send_msg(msg); - - // We dont have a way of knowing if the message has been received by our client. - // Hence Sleep for 100 msecs and then initiate the receive - std::chrono::milliseconds dura(100); - std::this_thread::sleep_for(dura); - - client.receive() - .then([&](websocket_incoming_message ret_msg) { - auto ret_str = ret_msg.extract_string().get(); - VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }) - .wait(); - - client.close().wait(); - } - - // Start task to receive text message before connecting. - TEST_FIXTURE(uri_address, receive_before_connect) - { - test_websocket_server server; - websocket_client client; - - std::string body_str("hello"); - std::vector<unsigned char> body(body_str.begin(), body_str.end()); - - auto t = client.receive().then([body_str](websocket_incoming_message ret_msg) { - VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length()); - auto ret_str = ret_msg.extract_string().get(); - - VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - }); - - // Connect after the client is waiting on a receive task. - client.connect(m_uri).wait(); - - // Now send the message from the server - test_websocket_msg msg; - msg.set_data(std::move(body)); - msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - server.send_msg(msg); - - t.wait(); - client.close().wait(); - } - - // Receive message using callback APIs - TEST_FIXTURE(uri_address, receive_text_msg_callback_client) - { - test_websocket_server server; - websocket_callback_client client; - - client.connect(m_uri).wait(); - std::string body_str("hello"); - std::vector<unsigned char> body(body_str.begin(), body_str.end()); - - pplx::task_completion_event<void> receiveEvent; - // make sure client works fine without setting receive handler - test_websocket_msg msg; - msg.set_data(std::move(body)); - msg.set_msg_type(test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - server.send_msg(msg); - - // set receive handler - client.set_message_handler([body_str, &receiveEvent](websocket_incoming_message ret_msg) { - VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length()); - auto ret_str = ret_msg.extract_string().get(); - - VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0); - VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message); - - receiveEvent.set(); - }); - - server.send_msg(msg); - - pplx::create_task(receiveEvent).wait(); - client.close().wait(); - } -} // SUITE(receive_msg_tests) - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/send_msg_tests.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/send_msg_tests.cpp @@ -1,565 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * send_msg_tests.cpp - * - * Tests cases for covering sending messages from websocket client. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#include "stdafx.h" - -#if defined(__cplusplus_winrt) || !defined(_M_ARM) - -using namespace concurrency; -using namespace concurrency::streams; - -using namespace web::websockets; -using namespace web::websockets::client; - -using namespace tests::functional::websocket::utilities; - -#if defined(__cplusplus_winrt) -using namespace Windows::Storage; -#endif - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -SUITE(send_msg_tests) -{ - utility::string_t get_full_name(const utility::string_t& name) - { -#if defined(__cplusplus_winrt) - // On WinRT, we must compensate for the fact that we will be accessing files in the - // Documents folder - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->CreateFileAsync(ref new Platform::String(name.c_str()), - CreationCollisionOption::ReplaceExisting)) - .get(); - return file->Path->Data(); -#else - return name; -#endif - } - - template<typename _CharType> - pplx::task<streams::streambuf<_CharType>> OPEN_R(const utility::string_t& name) - { -#if !defined(__cplusplus_winrt) - return streams::file_buffer<_CharType>::open(name, std::ios_base::in); -#else - auto file = - pplx::create_task(KnownFolders::DocumentsLibrary->GetFileAsync(ref new Platform::String(name.c_str()))) - .get(); - - return streams::file_buffer<_CharType>::open(file, std::ios_base::in); -#endif - } - - // Used to prepare data for stream tests - void fill_file(const utility::string_t& name, const std::vector<uint8_t>& body, size_t repetitions = 1) - { - std::fstream stream(get_full_name(name), std::ios_base::out | std::ios_base::trunc); - - for (size_t i = 0; i < repetitions; i++) - stream.write((char*)&body[0], body.size()); - stream.close(); - } - - void fill_buffer(streams::streambuf<uint8_t> rbuf, const std::vector<uint8_t>& body, size_t repetitions = 1) - { - size_t len = body.size(); - for (size_t i = 0; i < repetitions; i++) - rbuf.putn_nocopy((const uint8_t*)&body[0], len).wait(); - } - - template<class SocketClientClass> - pplx::task<void> send_text_msg_helper(SocketClientClass & client, - web::uri uri, - test_websocket_server & server, - const std::string& body, - bool connect_client = true) - { - server.next_message([body](test_websocket_msg msg) // Handler to verify the message sent by the client. - { - websocket_asserts::assert_message_equals( - msg, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - - if (connect_client) client.connect(uri).wait(); - - websocket_outgoing_message msg; - msg.set_utf8_message(body); - return client.send(msg); - } - - template<class SocketClientClass> - pplx::task<void> send_ping_msg_helper(SocketClientClass & client, web::uri uri, test_websocket_server & server, - const std::string& body = "") - { - server.next_message( - [body](test_websocket_msg msg) // Handler to verify the message sent by the client. - { websocket_asserts::assert_message_equals(msg, body, test_websocket_message_type::WEB_SOCKET_PING_TYPE); }); - - client.connect(uri).wait(); - - websocket_outgoing_message msg; - msg.set_ping_message(body); - return client.send(msg); - } - - template<class SocketClientClass> - pplx::task<void> send_pong_msg_helper(SocketClientClass & client, web::uri uri, test_websocket_server & server, - const std::string& body = "") - { - server.next_message( - [body](test_websocket_msg msg) // Handler to verify the message sent by the client. - { websocket_asserts::assert_message_equals(msg, body, test_websocket_message_type::WEB_SOCKET_PONG_TYPE); }); - - client.connect(uri).wait(); - - websocket_outgoing_message msg; - msg.set_pong_message(body); - return client.send(msg); - } - - pplx::task<void> send_msg_from_stream(websocket_client & client, - test_websocket_server & server, - web::uri uri, - const std::vector<uint8_t>& body, - streams::streambuf<uint8_t> buf, - test_websocket_message_type type, - bool fill_data, - bool connect_client = true) - { - server.next_message( - [body, type](test_websocket_msg msg) { websocket_asserts::assert_message_equals(msg, body, type); }); - - if (connect_client) client.connect(uri).wait(); - if (fill_data) fill_buffer(buf, body); - - websocket_outgoing_message msg; - if (type == test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE) - msg.set_utf8_message(streams::istream(buf), body.size()); - else if (type == test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE) - msg.set_binary_message(streams::istream(buf), body.size()); - - return client.send(msg); - } - - // Send message from input stream -> data is already populated in the stream buffer - pplx::task<void> send_msg_from_istream_helper(websocket_client & client, - test_websocket_server & server, - web::uri uri, - const std::vector<uint8_t>& body, - streams::streambuf<uint8_t> rbuf, - test_websocket_message_type type, - bool connect_client = true) - { - return send_msg_from_stream(client, server, uri, body, rbuf, type, false, connect_client); - } - - pplx::task<void> send_msg_from_stream_helper(websocket_client & client, - test_websocket_server & server, - web::uri uri, - const std::vector<uint8_t>& body, - streams::streambuf<uint8_t> rbuf, - test_websocket_message_type type, - bool connect_client = true) - { - return send_msg_from_stream(client, server, uri, body, rbuf, type, true, connect_client); - } - - // Send text message (no fragmentation) - TEST_FIXTURE(uri_address, send_text_msg) - { - test_websocket_server server; - websocket_client client; - send_text_msg_helper(client, m_uri, server, "hello").wait(); - client.close().wait(); - } - - // Send text message with websocket_callback_client - TEST_FIXTURE(uri_address, send_text_msg_callback_client) - { - test_websocket_server server; - websocket_callback_client client; - send_text_msg_helper(client, m_uri, server, "hello").wait(); - client.close().wait(); - } - - // Send text message (no fragmentation) - // Test the stream interface to send data - TEST_FIXTURE(uri_address, send_text_msg_stream) - { - test_websocket_server server; - streams::producer_consumer_buffer<uint8_t> rbuf; - std::vector<uint8_t> body(26); - memcpy(&body[0], "abcdefghijklmnopqrstuvwxyz", 26); - - websocket_client client; - send_msg_from_stream_helper( - client, server, m_uri, body, rbuf, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE) - .wait(); - - rbuf.close(std::ios::out).wait(); - client.close().wait(); - } - - // Send Binary message (no fragmentation) - TEST_FIXTURE(uri_address, send_binary_msg) - { - test_websocket_server server; - streams::producer_consumer_buffer<uint8_t> rbuf; - std::vector<uint8_t> body(6); - memcpy(&body[0], "a\0b\0c\0", 6); - - websocket_client client; - - send_msg_from_stream_helper( - client, server, m_uri, body, rbuf, test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE) - .wait(); - rbuf.close(std::ios::out); - client.close().wait(); - } - - // Send empty text message - // WinRT client does not handle empty messages. Verify websocket_exception is thrown. - TEST_FIXTURE(uri_address, send_empty_text_msg) - { - test_websocket_server server; - websocket_client client; - - client.connect(m_uri).wait(); - - websocket_outgoing_message msg; - msg.set_utf8_message(""); - VERIFY_THROWS(client.send(msg).wait(), websocket_exception); - - client.close().wait(); - } - - // Send multiple text messages - TEST_FIXTURE(uri_address, send_multiple_text_msges) - { - test_websocket_server server; - websocket_client client; - - send_text_msg_helper(client, m_uri, server, "hello1").wait(); - send_text_msg_helper(client, m_uri, server, "hello2", false).wait(); - - client.close().wait(); - } - - // Send multiple text messages - TEST_FIXTURE(uri_address, send_multiple_text_msges_async) - { - test_websocket_server server; - websocket_client client; - - auto t1 = send_text_msg_helper(client, m_uri, server, "hello1"); - auto t2 = send_text_msg_helper(client, m_uri, server, "hello2", false); - - t2.wait(); - t1.wait(); - client.close().wait(); - } - - // Send multiple text messages from a stream - TEST_FIXTURE(uri_address, send_multiple_text_msges_stream) - { - test_websocket_server server; - streams::producer_consumer_buffer<uint8_t> rbuf; - std::vector<uint8_t> body1(26); - memcpy(&body1[0], "abcdefghijklmnopqrstuvwxyz", 26); - std::vector<uint8_t> body2(26); - memcpy(&body2[0], "zyxwvutsrqponmlkjihgfedcba", 26); - - websocket_client client; - - auto t1 = send_msg_from_stream_helper( - client, server, m_uri, body1, rbuf, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - auto t2 = send_msg_from_stream_helper( - client, server, m_uri, body2, rbuf, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE, false); - - t1.wait(); - t2.wait(); - client.close().wait(); - } - - // Send multiple text messages from a file stream - // send uses stream::acquire API, acquire will fail for file streams. - TEST_FIXTURE(uri_address, send_text_msges_fstream) - { - test_websocket_server server; - utility::string_t fname = U("send_multiple_text_msges_fstream.txt"); - std::vector<uint8_t> body1(26); - memcpy(&body1[0], "abcdefghijklmnopqrstuvwxyz", 26); - fill_file(fname, body1, 2); - auto file_buf = OPEN_R<uint8_t>(fname).get(); - websocket_client client; - - auto t1 = send_msg_from_istream_helper( - client, server, m_uri, body1, file_buf, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - auto t2 = send_msg_from_istream_helper( - client, server, m_uri, body1, file_buf, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE, false); - - t1.wait(); - t2.wait(); - client.close().wait(); - } - - // Send multiple text messages from a container stream, where container stream has more data than what we want to - // send in a single message - TEST_FIXTURE(uri_address, send_text_msges_cstream) - { - test_websocket_server server; - std::vector<uint8_t> body(26); - memcpy(&body[0], "abcdefghijklmnopqrstuvwxyz", 26); - auto cbuf = streams::container_stream<std::vector<uint8_t>>::open_istream(body).streambuf(); - - websocket_client client; - - auto t1 = send_msg_from_istream_helper(client, - server, - m_uri, - std::vector<uint8_t>(body.begin(), body.begin() + body.size() / 2), - cbuf, - test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - auto t2 = send_msg_from_istream_helper(client, - server, - m_uri, - std::vector<uint8_t>(body.begin() + body.size() / 2, body.end()), - cbuf, - test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE, - false); - - t1.wait(); - t2.wait(); - client.close().wait(); - } - - // Send multiple text messages from a producer consumer stream, where stream initially has less data than what we - // want to send in a single message Write data to the buffer after initiating the send, send should succeed. - TEST_FIXTURE(uri_address, send_text_msges_pcstream_lessdata) - { - test_websocket_server server; - streams::producer_consumer_buffer<uint8_t> rbuf; - std::vector<uint8_t> body(26); - memcpy(&body[0], "abcdefghijklmnopqrstuvwxyz", 26); - fill_buffer(rbuf, body); - - server.next_message([](test_websocket_msg msg) { - websocket_asserts::assert_message_equals( - msg, "abcdefghijklmnopqrstuvwxyzabcd", test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - - websocket_client client; - client.connect(m_uri).wait(); - websocket_outgoing_message msg; - msg.set_utf8_message(rbuf.create_istream(), 30); - auto t1 = client.send(msg); - - fill_buffer(rbuf, body); - t1.wait(); - client.close().wait(); - } - - // Send multiple text messages from a container stream, where stream has less data than what we want to send in a - // single message Since container stream does not support in | out simultaneously, websocket send_msg will fail to - // read the required number of bytes and throws an exception. - TEST_FIXTURE(uri_address, send_text_msges_cstream_lessdata) - { - test_websocket_server server; - std::vector<uint8_t> body(26); - memcpy(&body[0], "abcdefghijklmnopqrstuvwxyz", 26); - auto cbuf = streams::container_stream<std::vector<uint8_t>>::open_istream(body).streambuf(); - - server.next_message([](test_websocket_msg msg) { - websocket_asserts::assert_message_equals( - msg, "abcdefghijklmnopqrstuvwxyzabcd", test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - - websocket_client client; - client.connect(m_uri).wait(); - websocket_outgoing_message msg; - msg.set_utf8_message(cbuf.create_istream(), 30); - - VERIFY_THROWS(client.send(msg).wait(), websocket_exception); - client.close().wait(); - } - - // Send multiple binary messages from the same stream - TEST_FIXTURE(uri_address, send_multiple_binary_msg_same_stream) - { - test_websocket_server server; - streams::producer_consumer_buffer<uint8_t> rbuf; - std::vector<uint8_t> body1(6); - memcpy(&body1[0], "a\0b\0c\0", 6); - std::vector<uint8_t> body2(6); - memcpy(&body2[0], "a\0b\0c\0", 6); - - websocket_client client; - - auto t1 = send_msg_from_stream_helper( - client, server, m_uri, body1, rbuf, test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE); - auto t2 = send_msg_from_stream_helper( - client, server, m_uri, body2, rbuf, test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE, false); - - t1.wait(); - t2.wait(); - rbuf.close(std::ios_base::out); - client.close().wait(); - } - - // Send text message followed by binary message - TEST_FIXTURE(uri_address, send_text_and_binary) - { - test_websocket_server server; - streams::producer_consumer_buffer<uint8_t> rbuf; - std::vector<uint8_t> body2(6); - memcpy(&body2[0], "a\0b\0c\0", 6); - - websocket_client client; - - send_text_msg_helper(client, m_uri, server, "hello1").wait(); - send_msg_from_stream_helper( - client, server, m_uri, body2, rbuf, test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE, false) - .wait(); - - rbuf.close(std::ios::out).wait(); - client.close().wait(); - } - - // Send a multi byte UTF-8 text message - TEST_FIXTURE(uri_address, send_multi_byte_utf8_msg) - { - test_websocket_server server; - std::string body = "\xC3\xA0\xC3\xB8"; - websocket_client client; - - send_text_msg_helper(client, m_uri, server, body).wait(); - client.close().wait(); - } - - // Send a streamed text message without specifying length - TEST_FIXTURE(uri_address, send_stream_utf8_msg_no_length) - { - test_websocket_server server; - - std::string body = "\xC3\xA0\xC3\xB8"; - std::vector<uint8_t> msgbuf(body.begin(), body.end()); - - auto is = streams::container_stream<std::vector<uint8_t>>::open_istream(std::move(msgbuf)); - - websocket_client client; - { - server.next_message([body](test_websocket_msg msg) // Handler to verify the message sent by the client. - { - websocket_asserts::assert_message_equals( - msg, body, test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE); - }); - - client.connect(m_uri).wait(); - - websocket_outgoing_message msg; - msg.set_utf8_message(is); - client.send(msg).wait(); - } - - client.close().wait(); - } - - // Send a streamed binary message without specifying length - TEST_FIXTURE(uri_address, send_stream_binary_msg_no_length) - { - test_websocket_server server; - - std::string body = "\x00\x01\x02\x00"; - std::vector<uint8_t> msgbuf(body.begin(), body.end()); - - auto is = streams::container_stream<std::vector<uint8_t>>::open_istream(std::move(msgbuf)); - - websocket_client client; - { - server.next_message([body](test_websocket_msg msg) // Handler to verify the message sent by the client. - { - websocket_asserts::assert_message_equals( - msg, body, test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE); - }); - - client.connect(m_uri).wait(); - - websocket_outgoing_message msg; - msg.set_binary_message(is); - client.send(msg).wait(); - } - - client.close().wait(); - } - -#if !defined(__cplusplus_winrt) - // Send a ping message to the server - TEST_FIXTURE(uri_address, send_ping_msg) - { - test_websocket_server server; - websocket_client client; - send_ping_msg_helper(client, m_uri, server).wait(); - client.close().wait(); - } - - // Send a ping message to the server with a body - TEST_FIXTURE(uri_address, send_ping_msg_body) - { - test_websocket_server server; - websocket_client client; - send_ping_msg_helper(client, m_uri, server, "abcdefghijklmnopqrstuvwxyz").wait(); - client.close().wait(); - } - - // Send an unsolicited pong message to the server - TEST_FIXTURE(uri_address, send_pong_msg) - { - test_websocket_server server; - websocket_client client; - send_pong_msg_helper(client, m_uri, server).wait(); - client.close().wait(); - } - - // Send an unsolicited pong message to the server with a body - TEST_FIXTURE(uri_address, send_pong_msg_body) - { - test_websocket_server server; - websocket_client client; - send_pong_msg_helper(client, m_uri, server, "abcdefghijklmnopqrstuvwxyz").wait(); - client.close().wait(); - } - - // Send an unsolicited pong message to the server with websocket_callback_client - TEST_FIXTURE(uri_address, send_pong_msg_callback_client) - { - test_websocket_server server; - websocket_callback_client client; - send_pong_msg_helper(client, m_uri, server).wait(); - client.close().wait(); - } -#endif - -} // SUITE(send_msg_tests) - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/stdafx.cpp @@ -1,14 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" - -#if WIN32 -__declspec(dllexport) int websocket_client_test_generate_lib = 0; -#endif diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/stdafx.h @@ -1,30 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#ifdef _WIN32 -#include <winsock2.h> -#endif - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/containerstream.h" -#include "cpprest/filestream.h" -#include "cpprest/producerconsumerstream.h" -#include "cpprest/rawptrstream.h" -#include "cpprest/ws_client.h" -#include "cpprest/ws_msg.h" -#include "os_utilities.h" -#include "test_websocket_server.h" -#include "unittestpp.h" -#include "websocket_client_tests.h" -#include <chrono> -#include <thread> diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/websocket_client_tests.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/client/websocket_client_tests.h @@ -1,37 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * websocket_client_tests.h - * - * Common declarations and helper functions for http_client test cases. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include "cpprest/uri.h" -#include "unittestpp.h" - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace client -{ -class uri_address -{ -public: - uri_address() : m_uri(U("ws://localhost:9980/ws")) {} - web::uri m_uri; -}; - -} // namespace client -} // namespace websocket -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/stdafx.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/stdafx.cpp @@ -1,10 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - **/ -// stdafx.cpp : -// Include the standard header and generate the precompiled header. - -#include "stdafx.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/stdafx.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/stdafx.h @@ -1,33 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Pre-compiled headers - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#if defined(_WIN32) -// Include first to avoid any issues with Windows.h. -#include <winsock2.h> -#endif - -#if defined(_WIN32) -// Trick Boost.Asio into thinking CE, otherwise _beginthreadex will be used which is banned -// for the Windows Runtime pre VS2015. Then CreateThread will be used instead. -#if _MSC_VER < 1900 -#if defined(__cplusplus_winrt) -#define UNDER_CE 1 -#endif -#endif -#endif - -#include "cpprest/asyncrt_utils.h" -#include "cpprest/containerstream.h" -#include "cpprest/streams.h" -#include "cpprest/uri.h" -#include "unittestpp.h" diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/test_websocket_server.cpp b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/test_websocket_server.cpp @@ -1,288 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * Defines a test server to handle websocket messages. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ -#include "stdafx.h" - -#include "test_websocket_server.h" - -#include <algorithm> -#include <os_utilities.h> -#include <thread> - -#ifdef _WIN32 -#pragma warning(disable : 4503) // generated too late for disable to be effective inside push/pop -#pragma warning(push) -#pragma warning(disable : 4100 4127 4996 4512 4701 4267 4067 4005) -#define _WEBSOCKETPP_CPP11_STL_ -#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ -#if _MSC_VER < 1900 -#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ -#endif -#endif /* _WIN32 */ - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Winfinite-recursion" -#endif - -#include <websocketpp/config/asio_no_tls.hpp> -#include <websocketpp/server.hpp> - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -#ifdef _WIN32 -#pragma warning(pop) -#endif - -using namespace web; -using namespace utility; -using namespace utility::conversions; - -// In the future this should be configurable through option in test server. -#define WEBSOCKETS_TEST_SERVER_PORT 9980 - -// Websocketpp typedefs -typedef websocketpp::server<websocketpp::config::asio> server; - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace utilities -{ -/// <summary> -/// Implementation of http request from websocket handshake to avoid leaking -/// details about websocketpp into test utilities. -/// </summary> -class test_http_request_impl : public test_http_request_interface -{ -public: - test_http_request_impl(server::connection_ptr connection) : m_connection(std::move(connection)) {} - - const std::string& username() override { throw std::runtime_error("NYI"); } - const std::string& password() override { throw std::runtime_error("NYI"); } - - const std::string& get_header_val(const std::string& header_name) override - { - return m_connection->get_request_header(header_name); - } - -private: - server::connection_ptr m_connection; -}; - -class _test_websocket_server -{ -public: - _test_websocket_server(test_websocket_server* test_srv) : m_test_srv(test_srv) - { - m_srv.clear_access_channels(websocketpp::log::alevel::all); - m_srv.clear_error_channels(websocketpp::log::elevel::all); - connect(); - } - - void connect() - { - m_srv.set_validate_handler([this](websocketpp::connection_hdl hdl) { - auto handler = m_test_srv->get_http_handler(); - if (handler) - { - server::connection_ptr connection = m_srv.get_con_from_hdl(hdl); - test_http_request request(new test_http_request_impl(connection)); - test_http_response response = handler(std::move(request)); - - // Also need to indicate the connection is rejected if non 200 status code. - connection->set_status(static_cast<websocketpp::http::status_code::value>(response.status_code())); - if (response.status_code() != 200) - { - return false; - } - } - return true; - }); - - m_srv.set_open_handler([this](websocketpp::connection_hdl hdl) { - m_con = hdl; - m_server_connected.set(); - }); - - m_srv.set_fail_handler([this](websocketpp::connection_hdl hdl) { - m_con = hdl; - m_server_connected.set_exception(std::runtime_error("Connection attempt failed.")); - }); - - m_srv.set_ping_handler([this](websocketpp::connection_hdl hdl, std::string input) { - auto fn = m_test_srv->get_next_message_handler(); - assert(fn); - - test_websocket_msg wsmsg; - - wsmsg.set_data(std::vector<uint8_t>(input.begin(), input.end())); - - wsmsg.set_msg_type(WEB_SOCKET_PING_TYPE); - fn(wsmsg); - - return true; - }); - - m_srv.set_pong_handler([this](websocketpp::connection_hdl hdl, std::string input) { - auto fn = m_test_srv->get_next_message_handler(); - assert(fn); - - test_websocket_msg wsmsg; - - wsmsg.set_data(std::vector<uint8_t>(input.begin(), input.end())); - - wsmsg.set_msg_type(WEB_SOCKET_PONG_TYPE); - fn(wsmsg); - }); - - m_srv.set_message_handler([this](websocketpp::connection_hdl hdl, server::message_ptr msg) { - auto pay = msg->get_payload(); - - auto fn = m_test_srv->get_next_message_handler(); - assert(fn); - - test_websocket_msg wsmsg; - - wsmsg.set_data(std::vector<uint8_t>(pay.begin(), pay.end())); - - switch (msg->get_opcode()) - { - case websocketpp::frame::opcode::binary: - wsmsg.set_msg_type(utilities::WEB_SOCKET_BINARY_MESSAGE_TYPE); - break; - case websocketpp::frame::opcode::text: - wsmsg.set_msg_type(utilities::WEB_SOCKET_UTF8_MESSAGE_TYPE); - break; - case websocketpp::frame::opcode::close: wsmsg.set_msg_type(utilities::WEB_SOCKET_CLOSE_TYPE); break; - default: - // Websocketspp does not currently support explicit fragmentation. We should not get here. - std::abort(); - } - - fn(wsmsg); - }); - - m_srv.init_asio(); - m_srv.start_perpetual(); - - m_srv.set_reuse_addr(true); - - websocketpp::lib::error_code ec; - m_srv.listen(WEBSOCKETS_TEST_SERVER_PORT, ec); - if (ec) - { - throw std::runtime_error(ec.message()); - } - - m_srv.start_accept(); - m_thread = std::thread(&server::run, &m_srv); - } - - ~_test_websocket_server() - { - close("destructor"); - m_srv.stop_listening(); - m_srv.stop_perpetual(); - _ASSERTE(m_thread.joinable()); - m_thread.join(); - } - - void send_msg(const test_websocket_msg& msg); - - void close(const std::string& reasoning) - { - websocketpp::lib::error_code ec; - m_srv.close(m_con, websocketpp::close::status::going_away, reasoning, ec); - // Ignore the error code. - } - -private: - test_websocket_server* m_test_srv; - - std::thread m_thread; - - server m_srv; - websocketpp::connection_hdl m_con; - // Once the WebSocket object has been initialized, - // the below event wil be used to signal that the server has been initialized. - // The server can now send messages to the client. - pplx::task_completion_event<void> m_server_connected; -}; - -test_websocket_server::test_websocket_server() : m_p_impl(std::make_shared<_test_websocket_server>(this)) {} - -void test_websocket_server::next_message(std::function<void(test_websocket_msg)> handler) -{ - std::lock_guard<std::mutex> lg(m_handler_queue_lock); - assert(handler); - m_handler_queue.push(handler); - assert(m_handler_queue.front()); -} - -std::function<void(test_websocket_msg)> test_websocket_server::get_next_message_handler() -{ - std::lock_guard<std::mutex> lg(m_handler_queue_lock); - assert(m_handler_queue.size() > 0); - auto handler = m_handler_queue.front(); - assert(handler); - m_handler_queue.pop(); - assert(handler); - return handler; -} - -void test_websocket_server::send_msg(const test_websocket_msg& msg) { m_p_impl->send_msg(msg); } - -std::shared_ptr<_test_websocket_server> test_websocket_server::get_impl() { return m_p_impl; } - -void _test_websocket_server::send_msg(const test_websocket_msg& msg) -{ - // Wait for the websocket server to be initialized. - pplx::task<void>(m_server_connected).wait(); - const auto& data = msg.data(); - auto flags = websocketpp::frame::opcode::close; - switch (msg.msg_type()) - { - case test_websocket_message_type::WEB_SOCKET_UTF8_MESSAGE_TYPE: - flags = websocketpp::frame::opcode::text; // WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_TEXT; - break; - case test_websocket_message_type::WEB_SOCKET_BINARY_MESSAGE_TYPE: - flags = websocketpp::frame::opcode::binary; // WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_BINARY; - break; - case test_websocket_message_type::WEB_SOCKET_CLOSE_TYPE: - flags = websocketpp::frame::opcode::close; // WebSocket::FRAME_OP_CLOSE; - break; - case test_websocket_message_type::WEB_SOCKET_UTF8_FRAGMENT_TYPE: - case test_websocket_message_type::WEB_SOCKET_BINARY_FRAGMENT_TYPE: - default: throw std::runtime_error("invalid message type"); - } - - std::string strmsg(data.begin(), data.end()); - - if (msg.msg_type() == test_websocket_message_type::WEB_SOCKET_CLOSE_TYPE) - { - close(strmsg); - } - else - { - // std::cerr << "Sending message from server: " << strmsg << std::endl; - m_srv.send(m_con, strmsg, flags); - } -} - -} // namespace utilities -} // namespace websocket -} // namespace functional -} // namespace tests diff --git a/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/test_websocket_server.h b/src/cpprestsdk/cpprestsdk/Release/tests/functional/websockets/utilities/test_websocket_server.h @@ -1,164 +0,0 @@ -/*** - * Copyright (C) Microsoft. All rights reserved. - * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. - * - * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ - * - * test_websocket_server.h -- Defines a test server to handle incoming and outgoing messages. - * - * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - ****/ - -#pragma once - -#include <condition_variable> -#include <iostream> -#include <map> -#include <mutex> -#include <sstream> -#include <unittestpp.h> - -#ifndef WEBSOCKET_UTILITY_API -#ifdef WEBSOCKETTESTUTILITY_EXPORTS -#define WEBSOCKET_UTILITY_API __declspec(dllexport) -#else -#define WEBSOCKET_UTILITY_API __declspec(dllimport) -#endif -#endif - -#if !defined(_M_ARM) || defined(__cplusplus_winrt) - -namespace tests -{ -namespace functional -{ -namespace websocket -{ -namespace utilities -{ -class _test_websocket_server; - -// The different types of a websocket message. -enum test_websocket_message_type -{ - WEB_SOCKET_BINARY_MESSAGE_TYPE, - WEB_SOCKET_BINARY_FRAGMENT_TYPE, - WEB_SOCKET_UTF8_MESSAGE_TYPE, - WEB_SOCKET_UTF8_FRAGMENT_TYPE, - WEB_SOCKET_CLOSE_TYPE, - WEB_SOCKET_PING_TYPE, - WEB_SOCKET_PONG_TYPE -}; - -// Interface containing details about the HTTP handshake request received by the test server. -class test_http_request_interface -{ -public: - virtual ~test_http_request_interface() {} - virtual const std::string& username() = 0; - virtual const std::string& password() = 0; - virtual const std::string& get_header_val(const std::string& header_name) = 0; -}; -typedef std::unique_ptr<test_http_request_interface> test_http_request; - -// Class that contains details about the HTTP handshake response to be sent by the test server -class test_http_response -{ -public: - void set_realm(std::string realm) { m_realm = std::move(realm); } - void set_status_code(unsigned short code) { m_status_code = code; } - const std::string& realm() const { return m_realm; } - unsigned short status_code() const { return m_status_code; } - -private: - std::string m_realm; - unsigned short m_status_code; -}; - -// Represents a websocket message at the test server. -// Contains a vector that can contain text/binary data -// and a type variable to denote the message type. -class test_websocket_msg -{ -public: - const std::vector<unsigned char>& data() const { return m_data; } - void set_data(std::vector<unsigned char> data) { m_data = std::move(data); } - - test_websocket_message_type msg_type() const { return m_msg_type; } - void set_msg_type(test_websocket_message_type type) { m_msg_type = type; } - -private: - std::vector<unsigned char> m_data; - test_websocket_message_type m_msg_type; -}; - -class websocket_asserts -{ -public: - static void assert_message_equals(test_websocket_msg& msg, - const std::string& expected_data, - test_websocket_message_type expected_flag) - { - std::vector<unsigned char> temp_vec(expected_data.begin(), expected_data.end()); - assert_message_equals(msg, temp_vec, expected_flag); - } - - static void assert_message_equals(test_websocket_msg& msg, - const std::vector<unsigned char>& expected_data, - test_websocket_message_type expected_flag) - { - VERIFY_ARE_EQUAL(msg.msg_type(), expected_flag); - auto& data = msg.data(); - VERIFY_ARE_EQUAL(data.size(), expected_data.size()); - VERIFY_IS_TRUE(std::equal(expected_data.begin(), expected_data.end(), data.begin())); - } - -private: - websocket_asserts() {} - ~websocket_asserts() CPPREST_NOEXCEPT {} -}; - -// Test websocket server. -class test_websocket_server -{ -public: - WEBSOCKET_UTILITY_API test_websocket_server(); - - // Tests can add a handler to handle (verify) the next message received by the server. - // If the test plans to send n messages, n handlers must be registered. - // The server will call the handler in order, for each incoming message. - WEBSOCKET_UTILITY_API void next_message(std::function<void __cdecl(test_websocket_msg)> msg_handler); - WEBSOCKET_UTILITY_API std::function<void(test_websocket_msg)> get_next_message_handler(); - - // Handler for initial HTTP request. - typedef std::function<test_http_response __cdecl(test_http_request)> http_handler; - WEBSOCKET_UTILITY_API void set_http_handler(http_handler handler) { m_http_handler = handler; } - WEBSOCKET_UTILITY_API http_handler get_http_handler() { return m_http_handler; } - - // Tests can use this API to send a message from the server to the client. - WEBSOCKET_UTILITY_API void send_msg(const test_websocket_msg& msg); - WEBSOCKET_UTILITY_API std::shared_ptr<_test_websocket_server> get_impl(); - -private: -#if !defined(_MSC_VER) || _MSC_VER >= 1800 - test_websocket_server(const test_websocket_server&) = delete; - test_websocket_server& operator=(const test_websocket_server&) = delete; - test_websocket_server(test_websocket_server&&) = delete; - test_websocket_server& operator=(test_websocket_server&&) = delete; -#endif - - // Queue to maintain the request handlers. - // Note: This queue is not thread-safe. Use m_handler_queue_lock to synchronize. - std::mutex m_handler_queue_lock; - std::queue<std::function<void(test_websocket_msg)>> m_handler_queue; - // Handler to address the HTTP handshake request. To be used in scenarios where tests may wish to fail the HTTP - // request and not proceed with the websocket connection. - http_handler m_http_handler; - std::shared_ptr<_test_websocket_server> m_p_impl; -}; -} // namespace utilities -} // namespace websocket -} // namespace functional -} // namespace tests - -#endif