DesktopLauncherDownloaderTest.cpp (4136B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 #include "gtest/gtest.h" 5 #include <windows.h> 6 #include <string> 7 #include <shellapi.h> 8 #include <winhttp.h> 9 10 #include "find_firefox.h" 11 #include "tempfile_name.h" 12 #include "download_firefox.h" 13 #include "data_sink.h" 14 15 static const size_t python_path_len = 32768; 16 static wchar_t python_path[python_path_len]; 17 18 static wchar_t* getPythonPath() { 19 DWORD res = GetEnvironmentVariableW(L"PYTHON", python_path, python_path_len); 20 if (res == 0) { 21 std::wcout << L"Can't find python" << std::endl; 22 return nullptr; 23 } 24 return python_path; 25 } 26 27 static HANDLE startWebServer() { 28 SHELLEXECUTEINFOW execInfo{}; 29 execInfo.cbSize = sizeof(SHELLEXECUTEINFOW); 30 execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC; 31 execInfo.lpVerb = L"open"; 32 execInfo.lpFile = getPythonPath(); 33 if (!execInfo.lpFile) { 34 // Can't find Python 35 return nullptr; 36 } 37 execInfo.lpParameters = 38 L"-m http.server --protocol HTTP/1.1 --bind 127.0.0.1 9191"; 39 execInfo.nShow = SW_HIDE; 40 41 if (!ShellExecuteExW(&execInfo)) { 42 std::wcout << L"Can't exec python web server" << std::endl; 43 return nullptr; 44 } 45 return execInfo.hProcess; 46 } 47 48 static void stopWebServer(HANDLE processHandle) { 49 if (processHandle) { 50 TerminateProcess(processHandle, 0); 51 CloseHandle(processHandle); 52 } 53 processHandle = nullptr; 54 } 55 56 class StringDataSink : public DataSink { 57 public: 58 std::string data; 59 60 bool accept(char* buf, int count) { 61 std::string str(buf, count); 62 data += str; 63 return true; 64 } 65 }; 66 67 static void DownloadAndCheckStub(const std::wstring& product) { 68 StringDataSink sink; 69 std::wstring object_name = L"/?os=win64&lang=en-US&product=" + product; 70 71 ErrCode ec = 72 download_file(&sink, L"download.mozilla.org", INTERNET_DEFAULT_HTTPS_PORT, 73 true, // HTTPS 74 object_name, L"application/x-msdos-program"); 75 76 // First, ensure that the request was successful 77 ASSERT_EQ(ec, ErrCode::OK); 78 79 // All .exe files start with MZ 80 ASSERT_EQ((unsigned char)sink.data[0], 'M') 81 << "File is not a valid PE executable"; 82 ASSERT_EQ((unsigned char)sink.data[1], 'Z'); 83 } 84 85 class DesktopLauncherDownloaderTest : public ::testing::Test { 86 protected: 87 HANDLE serverProcessHandle = nullptr; 88 89 void SetUp() override { serverProcessHandle = startWebServer(); } 90 91 void TearDown() override { stopWebServer(serverProcessHandle); } 92 }; 93 94 TEST_F(DesktopLauncherDownloaderTest, TestDownloadFileSuccess) { 95 if (serverProcessHandle == nullptr) { 96 FAIL() << "No process."; 97 } 98 StringDataSink sink; 99 ErrCode ec = 100 download_file(&sink, L"localhost", 9191, false, 101 L"/desktop_launcher_test_content.txt", L"text/plain"); 102 ASSERT_EQ(ec, ErrCode::OK); 103 ASSERT_STREQ(sink.data.c_str(), "Testing 123"); 104 } 105 106 TEST_F(DesktopLauncherDownloaderTest, TestDownloadFile_NotFound) { 107 if (serverProcessHandle == nullptr) { 108 FAIL() << "No process."; 109 } 110 StringDataSink sink; 111 ErrCode ec = download_file(&sink, L"localhost", 9191, false, 112 L"/this_file_should_not_exist.txt", L"text/plain"); 113 ASSERT_EQ(ec, ErrCode::ERR_FILE_NOT_FOUND); 114 ASSERT_STREQ(sink.data.c_str(), ""); 115 } 116 117 TEST_F(DesktopLauncherDownloaderTest, TestDownloadFile_InvalidRequest) { 118 if (serverProcessHandle == nullptr) { 119 FAIL() << "No process."; 120 } 121 StringDataSink sink; 122 // Requesting https download from the non-https server. 123 ErrCode ec = download_file(&sink, L"localhost", 9191, true, 124 L"/name_doesnt_matter.txt", L"text/plain"); 125 ASSERT_EQ(ec, ErrCode::ERR_REQUEST_INVALID); 126 ASSERT_STREQ(sink.data.c_str(), ""); 127 } 128 129 TEST(DesktopLauncherDownloaderReal, DownloadNightlyStub) 130 { 131 DownloadAndCheckStub(L"firefox-nightly-stub"); 132 } 133 134 TEST(DesktopLauncherDownloaderReal, DownloadBetaStub) 135 { 136 DownloadAndCheckStub(L"firefox-beta-stub"); 137 } 138 139 TEST(DesktopLauncherDownloaderReal, DownloadDevStub) 140 { 141 DownloadAndCheckStub(L"firefox-devedition-stub"); 142 }