http-reader-test.cpp
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:11k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. /*  HttpReader unit test program
  2.  *  Copyright (C) 2006   Written by VCL
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  */
  18. #undef NDEBUG
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <assert.h>
  23. #include <time.h>
  24. #include <list>
  25. #ifdef WIN32
  26. #define WIN32_LEAN_AND_MEAN
  27. #include <windows.h>
  28. #else
  29. #include <unistd.h>
  30. #define Sleep(miliseconds) usleep(miliseconds * 1000)
  31. #endif
  32. #include "std-http-reader.h"
  33. #include "mirror-http-reader.h"
  34. using namespace std;
  35. using namespace OpenKore;
  36. typedef HttpReader * (*HttpReaderCreator) (const char *url);
  37. typedef HttpReader * (*HttpReaderPostCreator) (const char *url, const char *postData, int postDataSize);
  38. #define SMALL_TEST_URL "http://www.openkore.com/test/HttpReader.txt"
  39. #define SMALL_TEST_CONTENT "Hello world!n"
  40. #define SMALL_TEST_SIZE 13
  41. #define SMALL_TEST_CHECKSUM 2773980202U
  42. #define LARGE_TEST_URL "http://www.openkore.com:80/test/HttpReaderLarge.txt"
  43. #define LARGE_TEST_SIZE 74048
  44. #define LARGE_TEST_CHECKSUM 1690026430U
  45. #define SLOW_TEST_URL "http://kambing.vlsm.org/gnu/gcc/gcc-4.1.0/gcc-core-4.1.0.tar.bz2"
  46. #define ERROR_URL "http://www.openkore.com/test/FileNotFound.txt"
  47. #define INVALID_URL "http://111.111.111.111:82/"
  48. #define INVALID_URL2 "http://www.fooooooo.com"
  49. #define SECURE_URL "https://sourceforge.net"
  50. #define POST_TEST_URL "http://www.openkore.com/test/TestPost.php"
  51. #define POST_TEST_DATA "mydata=hello+world"
  52. static HttpReader *
  53. createStdHttpReader(const char *url) {
  54. return StdHttpReader::create(url);
  55. }
  56. static HttpReader *
  57. createStdHttpReaderPost(const char *url, const char *postData, int postDataSize) {
  58. return StdHttpReader::createAndPost(url, postData, postDataSize);
  59. }
  60. static HttpReader *
  61. createMirrorHttpReader(const char *url) {
  62. list<const char *> urls;
  63. urls.push_back(url);
  64. return new MirrorHttpReader(urls, 3000);
  65. }
  66. /**
  67.  * A class for testing a HttpReader implementation.
  68.  */
  69. class Tester {
  70. public:
  71. /**
  72.  * Create a new Tester object.
  73.  *
  74.  * @param creatorFunc  A function which creates a HttpReader instance.
  75.  * @require creatorFunc != NULL
  76.  */
  77. Tester(HttpReaderCreator creatorFunc, HttpReaderPostCreator creatorPostFunc) {
  78. this->createHttpReader = creatorFunc;
  79. this->createHttpReaderPost = creatorPostFunc;
  80. }
  81. virtual ~Tester() {}
  82. /** Run the unit tests. */
  83. void
  84. virtual run() {
  85. printf("Testing status transitions (1)...n");
  86. assert( testStatusTransitions(SMALL_TEST_URL) );
  87. printf("Testing status transitions (2)...n");
  88. assert( testStatusTransitions(LARGE_TEST_URL) );
  89. printf("Testing status transitions (3)...n");
  90. assert( !testStatusTransitions(ERROR_URL) );
  91. printf("Testing status transitions (4)...n");
  92. assert( testStatusTransitions(SECURE_URL) );
  93. printf("Testing status transitions (5)...n");
  94. printf("Testing getData (1)...n");
  95. assert( testGetData(SMALL_TEST_URL, SMALL_TEST_CONTENT, SMALL_TEST_SIZE) );
  96. printf("Testing getData (2)...n");
  97. assert( testGetData(LARGE_TEST_URL, NULL, LARGE_TEST_SIZE) );
  98. printf("Testing getData (3)...n");
  99. assert( !testGetData(ERROR_URL, NULL, 0) );
  100. printf("Testing getData (4)...n");
  101. assert( !testGetData(INVALID_URL2, NULL, 0) );
  102. printf("Testing pullData (1)...n");
  103. assert( testPullData(SMALL_TEST_URL, SMALL_TEST_SIZE, SMALL_TEST_CHECKSUM) );
  104. printf("Testing pullData (2)...n");
  105. assert( testPullData(LARGE_TEST_URL, LARGE_TEST_SIZE, LARGE_TEST_CHECKSUM) );
  106. printf("Testing pullData (3)...n");
  107. assert( !testPullData(ERROR_URL, 0, 0) );
  108. printf("Testing pullData (4)...n");
  109. assert( !testPullData(INVALID_URL2, 0, 0) );
  110. if (createHttpReaderPost != NULL) {
  111. printf("Testing POST...n");
  112. testPOST(POST_TEST_URL, POST_TEST_DATA);
  113. }
  114. printf("Testing cancellation while connecting (1)...n");
  115. testConnectCancellation(INVALID_URL);
  116. printf("Testing cancellation while connecting (2)...n");
  117. testConnectCancellation(INVALID_URL2);
  118. printf("Testing cancellation while downloading...n");
  119. testDownloadCancellation(SLOW_TEST_URL);
  120. }
  121. protected:
  122. /**
  123.  * Calculate a simple checksum of the specified data.
  124.  */
  125. unsigned int
  126. calcChecksum(const char *data, unsigned int len, unsigned int seed = 0) {
  127. for (unsigned int i = 0; i < len; i++) {
  128. seed = seed * 32 + data[i];
  129. }
  130. return seed;
  131. }
  132. private:
  133. HttpReaderCreator createHttpReader;
  134. HttpReaderPostCreator createHttpReaderPost;
  135. protected:
  136. // Test whether status transitions behave as documented.
  137. bool
  138. testStatusTransitions(const char *url) {
  139. HttpReader *http = createHttpReader(url);
  140. HttpReaderStatus status = HTTP_READER_CONNECTING;
  141. HttpReaderStatus oldStatus;
  142. do {
  143. oldStatus = status;
  144. status = http->getStatus();
  145. switch (oldStatus) {
  146. case HTTP_READER_CONNECTING:
  147. assert(status == HTTP_READER_CONNECTING
  148. || status == HTTP_READER_DOWNLOADING
  149. || status == HTTP_READER_DONE
  150. || status == HTTP_READER_ERROR);
  151. break;
  152. case HTTP_READER_DOWNLOADING:
  153. assert(status == HTTP_READER_DOWNLOADING
  154. || status == HTTP_READER_DONE
  155. || status == HTTP_READER_ERROR);
  156. break;
  157. case HTTP_READER_DONE:
  158. assert(status == HTTP_READER_DONE);
  159. break;
  160. case HTTP_READER_ERROR:
  161. assert(status == HTTP_READER_ERROR);
  162. break;
  163. default:
  164. printf("Unknown status %dn", (int) status);
  165. abort();
  166. break;
  167. };
  168. Sleep(10);
  169. } while (status != HTTP_READER_DONE && status != HTTP_READER_ERROR);
  170. Sleep(1000);
  171. if (status == HTTP_READER_DONE) {
  172. assert(http->getStatus() == HTTP_READER_DONE);
  173. } else {
  174. assert(http->getStatus() == HTTP_READER_ERROR);
  175. assert(http->getSize() == -2);
  176. }
  177. delete http;
  178. return status == HTTP_READER_DONE;
  179. }
  180. // Test whether getData() works
  181. bool
  182. testGetData(const char *url, const char *content, unsigned int size) {
  183. HttpReader *http = createHttpReader(url);
  184. while (http->getStatus() != HTTP_READER_DONE
  185.     && http->getStatus() != HTTP_READER_ERROR) {
  186. Sleep(10);
  187. }
  188. if (http->getStatus() != HTTP_READER_DONE) {
  189. assert(http->getSize() == -2);
  190. delete http;
  191. return false;
  192. }
  193. unsigned int downloadedLen = 0;
  194. const char *downloadedData = http->getData(downloadedLen);
  195. assert(downloadedLen == size);
  196. assert(http->getSize() == (int) size);
  197. if (content != NULL) {
  198. assert(strcmp(downloadedData, content) == 0);
  199. }
  200. delete http;
  201. return true;
  202. }
  203. // Test whether pullData() works
  204. bool
  205. testPullData(const char *url, unsigned int expectedSize, unsigned int expectedChecksum) {
  206. HttpReader *http = createHttpReader(url);
  207. bool result;
  208. unsigned int checksum = 0;
  209. unsigned int size = 0;
  210. char buffer[1024];
  211. int ret;
  212. bool done = false;
  213. while (http->getStatus() == HTTP_READER_CONNECTING) {
  214. Sleep(10);
  215. }
  216. while (!done) {
  217. ret = http->pullData(buffer, sizeof(buffer));
  218. if (ret == -1) {
  219. Sleep(10);
  220. } else if (ret > 0) {
  221. checksum = calcChecksum(buffer, ret, checksum);
  222. size += ret;
  223. } else if (ret == -2 || ret == 0) {
  224. done = true;
  225. } else {
  226. printf("pullData() returned an invalid value: %dn", ret);
  227. abort();
  228. }
  229. }
  230. result = http->getStatus() == HTTP_READER_DONE;
  231. if (result) {
  232. assert(expectedSize == size);
  233. assert(expectedChecksum == checksum);
  234. } else {
  235. assert(http->getSize() == -2);
  236. }
  237. delete http;
  238. return result;
  239. }
  240. // Test whether cancellation while connecting works.
  241. void
  242. testConnectCancellation(const char *url) {
  243. HttpReader *http = createHttpReader(url);
  244. time_t time1, time2;
  245. Sleep(1000);
  246. assert(http->getStatus() == HTTP_READER_CONNECTING
  247. || http->getStatus() == HTTP_READER_ERROR);
  248. time1 = time(NULL);
  249. delete http;
  250. time2 = time(NULL);
  251. // Verify that cancellation doesn't take more than 2 seconds
  252. assert(time1 + 2 > time2);
  253. }
  254. // Test whether cancellation while downloading works.
  255. // You must pass an URL to a large file so that download
  256. // takes a while to complete.
  257. void
  258. testDownloadCancellation(const char *url) {
  259. HttpReader *http = createHttpReader(url);
  260. time_t time1, time2;
  261. while (http->getStatus() == HTTP_READER_CONNECTING) {
  262. Sleep(10);
  263. }
  264. assert(http->getStatus() == HTTP_READER_DOWNLOADING);
  265. Sleep(1000);
  266. time1 = time(NULL);
  267. delete http;
  268. time2 = time(NULL);
  269. assert(time1 + 2 > time2);
  270. }
  271. void testPOST(const char *url, const char *data) {
  272. HttpReader *http = createHttpReaderPost(url, data, -1);
  273. while (http->getStatus() != HTTP_READER_DONE
  274.     && http->getStatus() != HTTP_READER_ERROR) {
  275. Sleep(10);
  276. }
  277. assert(http->getStatus() == HTTP_READER_DONE);
  278. unsigned int downloadedLen = 0;
  279. const char *downloadedData = http->getData(downloadedLen);
  280. assert(strcmp(downloadedData, "yes") == 0);
  281. delete http;
  282. }
  283. };
  284. /**
  285.  * A class for testing MirrorHttpReader.
  286.  */
  287. class MirrorTester: public Tester {
  288. public:
  289. MirrorTester() : Tester(createMirrorHttpReader, NULL) {
  290. }
  291. virtual void
  292. run() {
  293. list<const char *> urls;
  294. Tester::run();
  295. printf("Testing usage of multiple mirrors (1)...n");
  296. urls.push_back(INVALID_URL);
  297. urls.push_back(ERROR_URL);
  298. urls.push_back(LARGE_TEST_URL);
  299. urls.push_back(SECURE_URL); // Will never be used
  300. assert( testMirrors(urls, LARGE_TEST_SIZE, LARGE_TEST_CHECKSUM) );
  301. printf("Testing usage of multiple mirrors (2)...n");
  302. urls.clear();
  303. urls.push_back(INVALID_URL);
  304. urls.push_back(ERROR_URL);
  305. urls.push_back("http://www.gnome.org:90");
  306. assert( !testMirrors(urls, 0, 0) );
  307. printf("Testing usage of multiple mirrors (3)...n");
  308. urls.clear();
  309. urls.push_back(SECURE_URL);
  310. urls.push_back(INVALID_URL); // Never used
  311. urls.push_back(ERROR_URL);   // ditto
  312. assert( testMirrors(urls, 0, 0) );
  313. printf("Testing getData (5)...n");
  314. assert( !testGetData(INVALID_URL, NULL, 0) );
  315. printf("Testing pullData (5)...n");
  316. assert( !testPullData(INVALID_URL, 0, 0) );
  317. }
  318. private:
  319. bool
  320. testMirrors(const list<const char *> &urls, unsigned int expectedSize,
  321.     unsigned int expectedChecksum) {
  322. HttpReader *http = new MirrorHttpReader(urls, 3000);
  323. HttpReaderStatus status;
  324. status = http->getStatus();
  325. while (status != HTTP_READER_DONE && status != HTTP_READER_ERROR) {
  326. Sleep(10);
  327. status = http->getStatus();
  328. }
  329. if (status == HTTP_READER_DONE && expectedChecksum != 0) {
  330. unsigned int len, checksum;
  331. const char *data;
  332. data = http->getData(len);
  333. assert(len == expectedSize);
  334. checksum = calcChecksum(data, len);
  335. assert(checksum == expectedChecksum);
  336. }
  337. delete http;
  338. return status == HTTP_READER_DONE;
  339. }
  340. };
  341. int
  342. main() {
  343. StdHttpReader::init();
  344. Tester *tester;
  345. printf("### StdHttpReadern");
  346. tester = new Tester(createStdHttpReader, createStdHttpReaderPost);
  347. tester->run();
  348. delete tester;
  349. printf("### MirrorHttpReadern");
  350. tester = new MirrorTester();
  351. tester->run();
  352. delete tester;
  353. return 0;
  354. }