fetch_network.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #!/usr/bin/env node
  2. "use strict";
  3. process.on("unhandledRejection", exn => { throw exn; });
  4. const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
  5. const USE_VIRTIO = !!process.env.USE_VIRTIO;
  6. const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
  7. const assert = require("assert").strict;
  8. const SHOW_LOGS = false;
  9. const tests =
  10. [
  11. {
  12. name: "DHCP",
  13. start: () =>
  14. {
  15. emulator.serial0_send("udhcpc\n");
  16. emulator.serial0_send("echo -e done\\\\tudhcpc\n");
  17. },
  18. end_trigger: "done\tudhcpc",
  19. end: (capture) =>
  20. {
  21. assert(/lease of 192.168.86.100 obtained/.test(capture), "lease of 192.168.86.100 obtained");
  22. },
  23. },
  24. {
  25. name: "lspci",
  26. timeout: 60,
  27. start: () =>
  28. {
  29. emulator.serial0_send("lspci -k\n");
  30. emulator.serial0_send("echo -e done\\\\tlspci\n");
  31. },
  32. end_trigger: "done\tlspci",
  33. end: (capture) =>
  34. {
  35. if(!USE_VIRTIO) {
  36. assert(/ne2k/.test(capture), "ne2k missing from lspci");
  37. } else {
  38. assert(!/ne2k/.test(capture), "ne2k in lspci");
  39. }
  40. },
  41. },
  42. {
  43. name: "ifconfig",
  44. start: () =>
  45. {
  46. emulator.serial0_send("ifconfig\n");
  47. emulator.serial0_send("echo -e done\\\\tifconfig\n");
  48. },
  49. end_trigger: "done\tifconfig",
  50. end: (capture) =>
  51. {
  52. assert(/192.168.86.100/.test(capture), "192.168.86.100");
  53. },
  54. },
  55. {
  56. name: "route",
  57. start: () =>
  58. {
  59. emulator.serial0_send("ip route\n");
  60. emulator.serial0_send("echo -e done\\\\troute\n");
  61. },
  62. end_trigger: "done\troute",
  63. end: (capture) =>
  64. {
  65. assert(/192.168.86.1/.test(capture), "192.168.86.100");
  66. },
  67. },
  68. {
  69. name: "ping 1.2.3.4",
  70. start: () =>
  71. {
  72. emulator.serial0_send("ping -c 2 1.2.3.4\n");
  73. emulator.serial0_send("echo -e done\\\\tping\n");
  74. },
  75. end_trigger: "done\tping",
  76. end: (capture) =>
  77. {
  78. assert(/2 packets transmitted, 2 packets received, 0% packet loss/.test(capture), "2 packets transmitted, 2 packets received, 0% packet loss");
  79. },
  80. },
  81. {
  82. name: "arp -a",
  83. start: () =>
  84. {
  85. emulator.serial0_send("arp -a\n");
  86. emulator.serial0_send("echo -e done\\\\tarp\n");
  87. },
  88. end_trigger: "done\tarp",
  89. end: (capture) =>
  90. {
  91. assert(/.192.168.86.1. at 52:54:00:01:02:03 \[ether\] {2}on eth0/.test(capture), "(192.168.86.1) at 52:54:00:01:02:03 [ether] on eth0");
  92. },
  93. },
  94. {
  95. name: "Curl mocked.example.org",
  96. allow_failure: true,
  97. start: () =>
  98. {
  99. emulator.serial0_send("wget -T 10 -O - mocked.example.org\n");
  100. emulator.serial0_send("echo -e done\\\\tmocked.example.org\n");
  101. },
  102. end_trigger: "done\tmocked.example.org",
  103. end: (capture) =>
  104. {
  105. assert(/This text is from the mock/.test(capture), "got mocked.example.org text");
  106. },
  107. },
  108. {
  109. name: "Curl example.org",
  110. allow_failure: true,
  111. start: () =>
  112. {
  113. emulator.serial0_send("wget -T 10 -O - example.org\n");
  114. emulator.serial0_send("echo -e done\\\\texample.org\n");
  115. },
  116. end_trigger: "done\texample.org",
  117. end: (capture) =>
  118. {
  119. assert(/This domain is for use in illustrative examples in documents/.test(capture), "got example.org text");
  120. },
  121. },
  122. {
  123. name: "Forbidden character in header name",
  124. start: () =>
  125. {
  126. emulator.serial0_send("wget --header='test.v86: 123' -T 10 -O - test.domain\n");
  127. emulator.serial0_send("echo -e done\\\\tincorrect header name\n");
  128. },
  129. end_trigger: "done\tincorrect header name",
  130. end: (capture) =>
  131. {
  132. assert(/400 Bad Request/.test(capture), "got error 400");
  133. },
  134. },
  135. {
  136. name: "Empty header value",
  137. start: () =>
  138. {
  139. emulator.serial0_send("wget --header='test:' -T 10 -O - test.domain\n");
  140. emulator.serial0_send("echo -e done\\\\tempty header value\n");
  141. },
  142. end_trigger: "done\tempty header value",
  143. end: (capture) =>
  144. {
  145. assert(/400 Bad Request/.test(capture), "got error 400");
  146. },
  147. },
  148. {
  149. name: "Header without separator",
  150. start: () =>
  151. {
  152. emulator.serial0_send("wget --spider --header='testheader' -T 10 -O - test.domain\n");
  153. emulator.serial0_send("echo -e done\\\\theader without colon\n");
  154. },
  155. end_trigger: "done\theader without colon",
  156. end: (capture) =>
  157. {
  158. assert(/400 Bad Request/.test(capture), "got error 400");
  159. },
  160. }
  161. ];
  162. const emulator = new V86({
  163. bios: { url: __dirname + "/../../bios/seabios.bin" },
  164. vga_bios: { url: __dirname + "/../../bios/vgabios.bin" },
  165. cdrom: { url: __dirname + "/../../images/linux4.iso" },
  166. autostart: true,
  167. memory_size: 64 * 1024 * 1024,
  168. disable_jit: +process.env.DISABLE_JIT,
  169. net_device: {
  170. relay_url: "fetch",
  171. type: USE_VIRTIO ? "virtio" : "ne2k",
  172. },
  173. log_level: SHOW_LOGS ? 0x400000 : 0,
  174. });
  175. emulator.add_listener("emulator-ready", function () {
  176. let network_adapter = emulator.network_adapter;
  177. let original_fetch = network_adapter.fetch;
  178. network_adapter.fetch = (url, opts) => {
  179. if(/^http:\/\/mocked.example.org\/?/.test(url)) {
  180. let contents = new TextEncoder().encode("This text is from the mock");
  181. let headers = new Headers();
  182. return new Promise(res => setTimeout(() => res([
  183. {status: 200, statusText: "OK", headers: headers},
  184. contents.buffer
  185. ]), 50));
  186. }
  187. return original_fetch.call(network_adapter, url, opts);
  188. };
  189. });
  190. let test_num = 0;
  191. let booted = false;
  192. let line = "";
  193. let capture = "";
  194. let end_trigger;
  195. emulator.bus.register("emulator-started", function()
  196. {
  197. console.log("Booting now, please stand by");
  198. });
  199. emulator.add_listener("serial0-output-byte", function(byte)
  200. {
  201. const chr = String.fromCharCode(byte);
  202. if(chr < " " && chr !== "\n" && chr !== "\t" || chr > "~")
  203. {
  204. return;
  205. }
  206. let new_line = "";
  207. if(chr === "\n")
  208. {
  209. console.log(" Captured: %s", line);
  210. new_line = line;
  211. capture += line + "\n";
  212. line = "";
  213. }
  214. else
  215. {
  216. line += chr;
  217. }
  218. if(new_line === end_trigger)
  219. {
  220. let test_has_failed = false;
  221. try {
  222. tests[test_num].end(capture);
  223. } catch(e) {
  224. console.log(e);
  225. test_has_failed = true;
  226. }
  227. if(!test_has_failed)
  228. {
  229. console.log("[+] Test #%d passed: %s", test_num, tests[test_num].name);
  230. }
  231. else
  232. {
  233. if(tests[test_num].allow_failure)
  234. {
  235. console.warn("[!] Test #%d failed: %s (failure allowed)", test_num, tests[test_num].name);
  236. }
  237. else
  238. {
  239. console.error("[-] Test #%d failed: %s", test_num, tests[test_num].name);
  240. process.exit(1);
  241. }
  242. }
  243. test_num++;
  244. }
  245. if(!booted && line.endsWith("~% ") || new_line === end_trigger)
  246. {
  247. booted = true;
  248. if(test_num >= tests.length)
  249. {
  250. emulator.stop();
  251. emulator.destroy();
  252. console.log("Tests finished.");
  253. }
  254. else
  255. {
  256. console.log("Starting test #%d: %s", test_num, tests[test_num].name);
  257. capture = "";
  258. end_trigger = tests[test_num].end_trigger;
  259. tests[test_num].start();
  260. }
  261. }
  262. });