1 /** 2 * Tests all Network implementations. 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <ae@cy.md> 12 */ 13 14 module ae.sys.net.test; 15 16 import std.array; 17 import std.file; 18 import std.process : environment; 19 20 import ae.net.http.common; 21 import ae.sys.data : Data; 22 import ae.sys.dataset : DataVec, joinToGC; 23 import ae.utils.array : asBytes, as; 24 25 static import ae.sys.net.ae; 26 static import ae.sys.net.curl; 27 version(Windows) 28 static import ae.sys.net.wininet; 29 static import ae.sys.net.cachedcurl; 30 31 debug static import std.stdio; 32 33 /// Test endpoint base. 34 /// Server-side test scripts are here: 35 /// https://gist.github.com/58df32ed1dbe64fffd0545f87d9321ad 36 string testBaseURL = "http://thecybershadow.net/d/nettest/"; // (must be HTTP) 37 38 /// Test a `ae.sys.net.Network` implementation. 39 void test(string moduleName, string className)() 40 { 41 debug std.stdio.stderr.writeln("Testing " ~ className); 42 43 mixin("import ae.sys.net." ~ moduleName ~ ";"); 44 mixin("alias Net = " ~ className ~ ";"); 45 auto net = new Net(); 46 47 debug std.stdio.stderr.writeln(" - getFile"); 48 { 49 assert(net.getFile(testBaseURL ~ "testUrl1") == "Hello world\n"); 50 } 51 52 debug std.stdio.stderr.writeln(" - downloadFile"); 53 { 54 enum fn = "test.txt"; 55 if (fn.exists) fn.remove(); 56 scope(exit) if (fn.exists) fn.remove(); 57 58 net.downloadFile(testBaseURL ~ "testUrl1", fn); 59 assert(fn.readText() == "Hello world\n"); 60 } 61 62 debug std.stdio.stderr.writeln(" - urlOK"); 63 { 64 assert( net.urlOK(testBaseURL ~ "testUrl1")); 65 assert(!net.urlOK(testBaseURL ~ "testUrlNX")); 66 static if (moduleName == "wininet") 67 assert( net.urlOK(testBaseURL.replace("http://", "https://") ~ "testUrl1")); 68 } 69 70 debug std.stdio.stderr.writeln(" - resolveRedirect"); 71 { 72 auto result = net.resolveRedirect(testBaseURL ~ "testUrl3"); 73 assert(result == testBaseURL ~ "testUrl2", result); 74 } 75 76 debug std.stdio.stderr.writeln(" - post"); 77 { 78 auto result = net.post(testBaseURL ~ "testUrl4", "Hello world\n".asBytes).as!string; 79 assert(result == "Hello world\n", result); 80 } 81 82 debug std.stdio.stderr.writeln(" - httpRequest"); 83 { 84 auto request = new HttpRequest(testBaseURL ~ "testUrl5"); 85 request.method = "PUT"; 86 request.headers.add("Test-Request-Header", "foo"); 87 request.data = DataVec(Data("bar".asBytes)); 88 auto response = net.httpRequest(request); 89 assert(response.status == HttpStatusCode.Accepted); 90 assert(response.statusMessage == "Custom Message"); 91 assert(response.data.joinToGC() == "PUT foo bar"); 92 assert(response.headers["Test-Response-Header"] == "baz"); 93 } 94 } 95 96 unittest 97 { 98 // Don't do network requests on the project tester. 99 // See: 100 // - https://github.com/CyberShadow/ae/issues/30 101 // - https://github.com/dlang/dmd/pull/9618#issuecomment-483214780 102 if (environment.get("BUILDKITE_AGENT_NAME")) 103 return; 104 105 test!("ae", "AENetwork"); 106 test!("curl", "CurlNetwork"); 107 version(Windows) 108 test!("wininet", "WinINetNetwork"); 109 110 import ae.utils.meta : classInit; 111 auto cacheDir = classInit!(ae.sys.net.cachedcurl.CachedCurlNetwork).cacheDir; 112 if (cacheDir.exists) cacheDir.rmdirRecurse(); 113 scope(exit) if (cacheDir.exists) cacheDir.rmdirRecurse(); 114 test!("cachedcurl", "CachedCurlNetwork"); 115 }