You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

UnitTest.cs 15 kB

10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. using System;
  2. using Microsoft.VisualStudio.TestTools.UnitTesting;
  3. using Shadowsocks.Controller;
  4. using Shadowsocks.Encryption;
  5. using GlobalHotKey;
  6. using System.Windows.Input;
  7. using System.Threading;
  8. using System.Collections.Generic;
  9. using Shadowsocks.Controller.Hotkeys;
  10. using Shadowsocks.Encryption.Stream;
  11. using Shadowsocks.Model;
  12. namespace test
  13. {
  14. [TestClass]
  15. public class UnitTest
  16. {
  17. [TestMethod]
  18. public void TestCompareVersion()
  19. {
  20. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1.0", "2.3.1") == 0);
  21. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2", "1.3") < 0);
  22. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.2") > 0);
  23. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.3") == 0);
  24. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2.1", "1.2") > 0);
  25. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1", "2.4") < 0);
  26. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3.2", "1.3.1") > 0);
  27. }
  28. [ TestMethod ]
  29. public void TestHotKey2Str() {
  30. Assert.AreEqual( "Ctrl+A", HotKeys.HotKey2Str( Key.A, ModifierKeys.Control ) );
  31. Assert.AreEqual( "Ctrl+Alt+D2", HotKeys.HotKey2Str( Key.D2, (ModifierKeys.Alt | ModifierKeys.Control) ) );
  32. Assert.AreEqual("Ctrl+Alt+Shift+NumPad7", HotKeys.HotKey2Str(Key.NumPad7, (ModifierKeys.Alt|ModifierKeys.Control|ModifierKeys.Shift)));
  33. Assert.AreEqual( "Ctrl+Alt+Shift+F6", HotKeys.HotKey2Str( Key.F6, (ModifierKeys.Alt|ModifierKeys.Control|ModifierKeys.Shift)));
  34. Assert.AreNotEqual("Ctrl+Shift+Alt+F6", HotKeys.HotKey2Str(Key.F6, (ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift)));
  35. }
  36. [TestMethod]
  37. public void TestStr2HotKey()
  38. {
  39. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+A").Equals(new HotKey(Key.A, ModifierKeys.Control)));
  40. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Alt+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt))));
  41. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Shift+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Shift))));
  42. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Alt+Shift+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt| ModifierKeys.Shift))));
  43. HotKey testKey0 = HotKeys.Str2HotKey("Ctrl+Alt+Shift+A");
  44. Assert.IsTrue(testKey0 != null && testKey0.Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  45. HotKey testKey1 = HotKeys.Str2HotKey("Ctrl+Alt+Shift+F2");
  46. Assert.IsTrue(testKey1 != null && testKey1.Equals(new HotKey(Key.F2, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  47. HotKey testKey2 = HotKeys.Str2HotKey("Ctrl+Shift+Alt+D7");
  48. Assert.IsTrue(testKey2 != null && testKey2.Equals(new HotKey(Key.D7, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  49. HotKey testKey3 = HotKeys.Str2HotKey("Ctrl+Shift+Alt+NumPad7");
  50. Assert.IsTrue(testKey3 != null && testKey3.Equals(new HotKey(Key.NumPad7, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  51. }
  52. [TestMethod]
  53. public void TestMD5()
  54. {
  55. for (int len = 1; len < 64; len++)
  56. {
  57. System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
  58. byte[] bytes = new byte[len];
  59. var random = new Random();
  60. random.NextBytes(bytes);
  61. string md5str = Convert.ToBase64String(md5.ComputeHash(bytes));
  62. string md5str2 = Convert.ToBase64String(MbedTLS.MD5(bytes));
  63. Assert.IsTrue(md5str == md5str2);
  64. }
  65. }
  66. private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor)
  67. {
  68. RNG.Reload();
  69. byte[] plain = new byte[16384];
  70. byte[] cipher = new byte[plain.Length + 16];
  71. byte[] plain2 = new byte[plain.Length + 16];
  72. int outLen = 0;
  73. int outLen2 = 0;
  74. var random = new Random();
  75. random.NextBytes(plain);
  76. encryptor.Encrypt(plain, plain.Length, cipher, out outLen);
  77. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  78. Assert.AreEqual(plain.Length, outLen2);
  79. for (int j = 0; j < plain.Length; j++)
  80. {
  81. Assert.AreEqual(plain[j], plain2[j]);
  82. }
  83. encryptor.Encrypt(plain, 1000, cipher, out outLen);
  84. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  85. Assert.AreEqual(1000, outLen2);
  86. for (int j = 0; j < outLen2; j++)
  87. {
  88. Assert.AreEqual(plain[j], plain2[j]);
  89. }
  90. encryptor.Encrypt(plain, 12333, cipher, out outLen);
  91. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  92. Assert.AreEqual(12333, outLen2);
  93. for (int j = 0; j < outLen2; j++)
  94. {
  95. Assert.AreEqual(plain[j], plain2[j]);
  96. }
  97. }
  98. private static bool encryptionFailed = false;
  99. private static object locker = new object();
  100. [TestMethod]
  101. public void TestMbedTLSEncryption()
  102. {
  103. // run it once before the multi-threading test to initialize global tables
  104. RunSingleMbedTLSEncryptionThread();
  105. List<Thread> threads = new List<Thread>();
  106. for (int i = 0; i < 10; i++)
  107. {
  108. Thread t = new Thread(new ThreadStart(RunSingleMbedTLSEncryptionThread));
  109. threads.Add(t);
  110. t.Start();
  111. }
  112. foreach (Thread t in threads)
  113. {
  114. t.Join();
  115. }
  116. RNG.Close();
  117. Assert.IsFalse(encryptionFailed);
  118. }
  119. private void RunSingleMbedTLSEncryptionThread()
  120. {
  121. try
  122. {
  123. for (int i = 0; i < 100; i++)
  124. {
  125. IEncryptor encryptor;
  126. IEncryptor decryptor;
  127. encryptor = new StreamMbedTLSEncryptor("aes-256-cfb", "barfoo!");
  128. decryptor = new StreamMbedTLSEncryptor("aes-256-cfb", "barfoo!");
  129. RunEncryptionRound(encryptor, decryptor);
  130. }
  131. }
  132. catch
  133. {
  134. encryptionFailed = true;
  135. throw;
  136. }
  137. }
  138. [TestMethod]
  139. public void TestRC4Encryption()
  140. {
  141. // run it once before the multi-threading test to initialize global tables
  142. RunSingleRC4EncryptionThread();
  143. List<Thread> threads = new List<Thread>();
  144. for (int i = 0; i < 10; i++)
  145. {
  146. Thread t = new Thread(new ThreadStart(RunSingleRC4EncryptionThread));
  147. threads.Add(t);
  148. t.Start();
  149. }
  150. foreach (Thread t in threads)
  151. {
  152. t.Join();
  153. }
  154. RNG.Close();
  155. Assert.IsFalse(encryptionFailed);
  156. }
  157. private void RunSingleRC4EncryptionThread()
  158. {
  159. try
  160. {
  161. for (int i = 0; i < 100; i++)
  162. {
  163. var random = new Random();
  164. IEncryptor encryptor;
  165. IEncryptor decryptor;
  166. encryptor = new StreamMbedTLSEncryptor("rc4-md5", "barfoo!");
  167. decryptor = new StreamMbedTLSEncryptor("rc4-md5", "barfoo!");
  168. RunEncryptionRound(encryptor, decryptor);
  169. }
  170. }
  171. catch
  172. {
  173. encryptionFailed = true;
  174. throw;
  175. }
  176. }
  177. [TestMethod]
  178. public void TestSodiumEncryption()
  179. {
  180. // run it once before the multi-threading test to initialize global tables
  181. RunSingleSodiumEncryptionThread();
  182. List<Thread> threads = new List<Thread>();
  183. for (int i = 0; i < 10; i++)
  184. {
  185. Thread t = new Thread(new ThreadStart(RunSingleSodiumEncryptionThread));
  186. threads.Add(t);
  187. t.Start();
  188. }
  189. foreach (Thread t in threads)
  190. {
  191. t.Join();
  192. }
  193. RNG.Close();
  194. Assert.IsFalse(encryptionFailed);
  195. }
  196. private void RunSingleSodiumEncryptionThread()
  197. {
  198. try
  199. {
  200. for (int i = 0; i < 100; i++)
  201. {
  202. var random = new Random();
  203. IEncryptor encryptor;
  204. IEncryptor decryptor;
  205. encryptor = new StreamSodiumEncryptor("salsa20", "barfoo!");
  206. decryptor = new StreamSodiumEncryptor("salsa20", "barfoo!");
  207. RunEncryptionRound(encryptor, decryptor);
  208. }
  209. }
  210. catch
  211. {
  212. encryptionFailed = true;
  213. throw;
  214. }
  215. }
  216. [TestMethod]
  217. public void ParseAndGenerateShadowsocksUrl()
  218. {
  219. var server = new Server
  220. {
  221. server = "192.168.100.1",
  222. server_port = 8888,
  223. password = "test",
  224. method = "bf-cfb"
  225. };
  226. var serverCanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4";
  227. var serverWithRemark = new Server
  228. {
  229. server = server.server,
  230. server_port = server.server_port,
  231. password = server.password,
  232. method = server.method,
  233. remarks = "example-server"
  234. };
  235. var serverWithRemarkCanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4#example-server";
  236. var serverWithPlugin = new Server
  237. {
  238. server = server.server,
  239. server_port = server.server_port,
  240. password = server.password,
  241. method = server.method,
  242. plugin = "obfs-local",
  243. plugin_opts = "obfs=http;obfs-host=google.com"
  244. };
  245. var serverWithPluginCanonUrl =
  246. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com";
  247. var serverWithPluginAndRemark = new Server
  248. {
  249. server = server.server,
  250. server_port = server.server_port,
  251. password = server.password,
  252. method = server.method,
  253. plugin = serverWithPlugin.plugin,
  254. plugin_opts = serverWithPlugin.plugin_opts,
  255. remarks = serverWithRemark.remarks
  256. };
  257. var serverWithPluginAndRemarkCanonUrl =
  258. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com#example-server";
  259. RunParseShadowsocksUrlTest(
  260. string.Join(
  261. "\r\n",
  262. serverCanonUrl,
  263. "\r\n",
  264. "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4/",
  265. serverWithRemarkCanonUrl,
  266. "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4/#example-server"),
  267. new[]
  268. {
  269. server,
  270. server,
  271. serverWithRemark,
  272. serverWithRemark
  273. });
  274. RunParseShadowsocksUrlTest(
  275. string.Join(
  276. "\r\n",
  277. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888",
  278. "\r\n",
  279. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/",
  280. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888#example-server",
  281. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/#example-server",
  282. serverWithPluginCanonUrl,
  283. serverWithPluginAndRemarkCanonUrl,
  284. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com&unsupported=1#example-server"),
  285. new[]
  286. {
  287. server,
  288. server,
  289. serverWithRemark,
  290. serverWithRemark,
  291. serverWithPlugin,
  292. serverWithPluginAndRemark,
  293. serverWithPluginAndRemark
  294. });
  295. var generateUrlCases = new Dictionary<string, Server>
  296. {
  297. [serverCanonUrl] = server,
  298. [serverWithRemarkCanonUrl] = serverWithRemark,
  299. [serverWithPluginCanonUrl] = serverWithPlugin,
  300. [serverWithPluginAndRemarkCanonUrl] = serverWithPluginAndRemark
  301. };
  302. RunGenerateShadowsocksUrlTest(generateUrlCases);
  303. }
  304. private static void RunParseShadowsocksUrlTest(string testCase, IReadOnlyList<Server> expected)
  305. {
  306. var actual = Server.GetServers(testCase);
  307. if (actual.Count != expected.Count)
  308. {
  309. Assert.Fail("Wrong number of configs. Expected: {0}. Actual: {1}", expected.Count, actual.Count);
  310. }
  311. for (int i = 0; i < expected.Count; i++)
  312. {
  313. var expectedServer = expected[i];
  314. var actualServer = actual[i];
  315. Assert.AreEqual(expectedServer.server, actualServer.server);
  316. Assert.AreEqual(expectedServer.server_port, actualServer.server_port);
  317. Assert.AreEqual(expectedServer.password, actualServer.password);
  318. Assert.AreEqual(expectedServer.method, actualServer.method);
  319. Assert.AreEqual(expectedServer.plugin, actualServer.plugin);
  320. Assert.AreEqual(expectedServer.plugin_opts, actualServer.plugin_opts);
  321. Assert.AreEqual(expectedServer.remarks, actualServer.remarks);
  322. Assert.AreEqual(expectedServer.timeout, actualServer.timeout);
  323. }
  324. }
  325. private static void RunGenerateShadowsocksUrlTest(IReadOnlyDictionary<string, Server> testCases)
  326. {
  327. foreach (var testCase in testCases)
  328. {
  329. string expected = testCase.Key;
  330. Server config = testCase.Value;
  331. var actual = ShadowsocksController.GetQRCode(config);
  332. Assert.AreEqual(expected, actual);
  333. }
  334. }
  335. }
  336. }