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 25 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
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  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. using Shadowsocks.Controller.Service;
  13. using System.Diagnostics;
  14. using System.Net;
  15. namespace test
  16. {
  17. [TestClass]
  18. public class UnitTest
  19. {
  20. [TestMethod]
  21. public void TestCompareVersion()
  22. {
  23. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1.0", "2.3.1") == 0);
  24. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2", "1.3") < 0);
  25. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.2") > 0);
  26. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.3") == 0);
  27. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2.1", "1.2") > 0);
  28. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1", "2.4") < 0);
  29. Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3.2", "1.3.1") > 0);
  30. }
  31. [TestMethod]
  32. public void TestHotKey2Str()
  33. {
  34. Assert.AreEqual("Ctrl+A", HotKeys.HotKey2Str(Key.A, ModifierKeys.Control));
  35. Assert.AreEqual("Ctrl+Alt+D2", HotKeys.HotKey2Str(Key.D2, (ModifierKeys.Alt | ModifierKeys.Control)));
  36. Assert.AreEqual("Ctrl+Alt+Shift+NumPad7", HotKeys.HotKey2Str(Key.NumPad7, (ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift)));
  37. Assert.AreEqual("Ctrl+Alt+Shift+F6", HotKeys.HotKey2Str(Key.F6, (ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift)));
  38. Assert.AreNotEqual("Ctrl+Shift+Alt+F6", HotKeys.HotKey2Str(Key.F6, (ModifierKeys.Alt | ModifierKeys.Control | ModifierKeys.Shift)));
  39. }
  40. [TestMethod]
  41. public void TestStr2HotKey()
  42. {
  43. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+A").Equals(new HotKey(Key.A, ModifierKeys.Control)));
  44. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Alt+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt))));
  45. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Shift+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Shift))));
  46. Assert.IsTrue(HotKeys.Str2HotKey("Ctrl+Alt+Shift+A").Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  47. HotKey testKey0 = HotKeys.Str2HotKey("Ctrl+Alt+Shift+A");
  48. Assert.IsTrue(testKey0 != null && testKey0.Equals(new HotKey(Key.A, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  49. HotKey testKey1 = HotKeys.Str2HotKey("Ctrl+Alt+Shift+F2");
  50. Assert.IsTrue(testKey1 != null && testKey1.Equals(new HotKey(Key.F2, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  51. HotKey testKey2 = HotKeys.Str2HotKey("Ctrl+Shift+Alt+D7");
  52. Assert.IsTrue(testKey2 != null && testKey2.Equals(new HotKey(Key.D7, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  53. HotKey testKey3 = HotKeys.Str2HotKey("Ctrl+Shift+Alt+NumPad7");
  54. Assert.IsTrue(testKey3 != null && testKey3.Equals(new HotKey(Key.NumPad7, (ModifierKeys.Control | ModifierKeys.Alt | ModifierKeys.Shift))));
  55. }
  56. [TestMethod]
  57. public void TestMD5()
  58. {
  59. for (int len = 1; len < 64; len++)
  60. {
  61. System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
  62. byte[] bytes = new byte[len];
  63. var random = new Random();
  64. random.NextBytes(bytes);
  65. string md5str = Convert.ToBase64String(md5.ComputeHash(bytes));
  66. string md5str2 = Convert.ToBase64String(MbedTLS.MD5(bytes));
  67. Assert.IsTrue(md5str == md5str2);
  68. }
  69. }
  70. private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor)
  71. {
  72. RNG.Reload();
  73. byte[] plain = new byte[16384];
  74. byte[] cipher = new byte[plain.Length + 16];
  75. byte[] plain2 = new byte[plain.Length + 16];
  76. int outLen = 0;
  77. int outLen2 = 0;
  78. var random = new Random();
  79. random.NextBytes(plain);
  80. encryptor.Encrypt(plain, plain.Length, cipher, out outLen);
  81. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  82. Assert.AreEqual(plain.Length, outLen2);
  83. for (int j = 0; j < plain.Length; j++)
  84. {
  85. Assert.AreEqual(plain[j], plain2[j]);
  86. }
  87. encryptor.Encrypt(plain, 1000, cipher, out outLen);
  88. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  89. Assert.AreEqual(1000, outLen2);
  90. for (int j = 0; j < outLen2; j++)
  91. {
  92. Assert.AreEqual(plain[j], plain2[j]);
  93. }
  94. encryptor.Encrypt(plain, 12333, cipher, out outLen);
  95. decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
  96. Assert.AreEqual(12333, outLen2);
  97. for (int j = 0; j < outLen2; j++)
  98. {
  99. Assert.AreEqual(plain[j], plain2[j]);
  100. }
  101. }
  102. private static bool encryptionFailed = false;
  103. private static object locker = new object();
  104. [TestMethod]
  105. public void TestMbedTLSEncryption()
  106. {
  107. // run it once before the multi-threading test to initialize global tables
  108. RunSingleMbedTLSEncryptionThread();
  109. List<Thread> threads = new List<Thread>();
  110. for (int i = 0; i < 10; i++)
  111. {
  112. Thread t = new Thread(new ThreadStart(RunSingleMbedTLSEncryptionThread));
  113. threads.Add(t);
  114. t.Start();
  115. }
  116. foreach (Thread t in threads)
  117. {
  118. t.Join();
  119. }
  120. RNG.Close();
  121. Assert.IsFalse(encryptionFailed);
  122. }
  123. private void RunSingleMbedTLSEncryptionThread()
  124. {
  125. try
  126. {
  127. for (int i = 0; i < 100; i++)
  128. {
  129. IEncryptor encryptor;
  130. IEncryptor decryptor;
  131. encryptor = new StreamMbedTLSEncryptor("aes-256-cfb", "barfoo!");
  132. decryptor = new StreamMbedTLSEncryptor("aes-256-cfb", "barfoo!");
  133. RunEncryptionRound(encryptor, decryptor);
  134. }
  135. }
  136. catch
  137. {
  138. encryptionFailed = true;
  139. throw;
  140. }
  141. }
  142. [TestMethod]
  143. public void TestRC4Encryption()
  144. {
  145. // run it once before the multi-threading test to initialize global tables
  146. RunSingleRC4EncryptionThread();
  147. List<Thread> threads = new List<Thread>();
  148. for (int i = 0; i < 10; i++)
  149. {
  150. Thread t = new Thread(new ThreadStart(RunSingleRC4EncryptionThread));
  151. threads.Add(t);
  152. t.Start();
  153. }
  154. foreach (Thread t in threads)
  155. {
  156. t.Join();
  157. }
  158. RNG.Close();
  159. Assert.IsFalse(encryptionFailed);
  160. }
  161. private void RunSingleRC4EncryptionThread()
  162. {
  163. try
  164. {
  165. for (int i = 0; i < 100; i++)
  166. {
  167. var random = new Random();
  168. IEncryptor encryptor;
  169. IEncryptor decryptor;
  170. encryptor = new StreamMbedTLSEncryptor("rc4-md5", "barfoo!");
  171. decryptor = new StreamMbedTLSEncryptor("rc4-md5", "barfoo!");
  172. RunEncryptionRound(encryptor, decryptor);
  173. }
  174. }
  175. catch
  176. {
  177. encryptionFailed = true;
  178. throw;
  179. }
  180. }
  181. [TestMethod]
  182. public void TestSodiumEncryption()
  183. {
  184. // run it once before the multi-threading test to initialize global tables
  185. RunSingleSodiumEncryptionThread();
  186. List<Thread> threads = new List<Thread>();
  187. for (int i = 0; i < 10; i++)
  188. {
  189. Thread t = new Thread(new ThreadStart(RunSingleSodiumEncryptionThread));
  190. threads.Add(t);
  191. t.Start();
  192. }
  193. foreach (Thread t in threads)
  194. {
  195. t.Join();
  196. }
  197. RNG.Close();
  198. Assert.IsFalse(encryptionFailed);
  199. }
  200. private void RunSingleSodiumEncryptionThread()
  201. {
  202. try
  203. {
  204. for (int i = 0; i < 100; i++)
  205. {
  206. var random = new Random();
  207. IEncryptor encryptor;
  208. IEncryptor decryptor;
  209. encryptor = new StreamSodiumEncryptor("salsa20", "barfoo!");
  210. decryptor = new StreamSodiumEncryptor("salsa20", "barfoo!");
  211. RunEncryptionRound(encryptor, decryptor);
  212. }
  213. }
  214. catch
  215. {
  216. encryptionFailed = true;
  217. throw;
  218. }
  219. }
  220. [TestMethod]
  221. public void TestOpenSSLEncryption()
  222. {
  223. // run it once before the multi-threading test to initialize global tables
  224. RunSingleOpenSSLEncryptionThread();
  225. List<Thread> threads = new List<Thread>();
  226. for (int i = 0; i < 10; i++)
  227. {
  228. Thread t = new Thread(new ThreadStart(RunSingleOpenSSLEncryptionThread));
  229. threads.Add(t);
  230. t.Start();
  231. }
  232. foreach (Thread t in threads)
  233. {
  234. t.Join();
  235. }
  236. RNG.Close();
  237. Assert.IsFalse(encryptionFailed);
  238. }
  239. private void RunSingleOpenSSLEncryptionThread()
  240. {
  241. try
  242. {
  243. for (int i = 0; i < 100; i++)
  244. {
  245. var random = new Random();
  246. IEncryptor encryptor;
  247. IEncryptor decryptor;
  248. encryptor = new StreamOpenSSLEncryptor("aes-256-cfb", "barfoo!");
  249. decryptor = new StreamOpenSSLEncryptor("aes-256-cfb", "barfoo!");
  250. RunEncryptionRound(encryptor, decryptor);
  251. }
  252. }
  253. catch
  254. {
  255. encryptionFailed = true;
  256. throw;
  257. }
  258. }
  259. [TestMethod]
  260. public void ParseAndGenerateShadowsocksUrl()
  261. {
  262. var server = new Server
  263. {
  264. server = "192.168.100.1",
  265. server_port = 8888,
  266. password = "test",
  267. method = "bf-cfb"
  268. };
  269. var serverCanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4";
  270. var server2 = new Server
  271. {
  272. server = "192.168.1.1",
  273. server_port = 8388,
  274. password = "test",
  275. method = "bf-cfb"
  276. };
  277. var server2CanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA==";
  278. var serverWithRemark = new Server
  279. {
  280. server = server.server,
  281. server_port = server.server_port,
  282. password = server.password,
  283. method = server.method,
  284. remarks = "example-server"
  285. };
  286. var serverWithRemarkCanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4#example-server";
  287. var server2WithRemark = new Server
  288. {
  289. server = server2.server,
  290. server_port = server2.server_port,
  291. password = server2.password,
  292. method = server2.method,
  293. remarks = "example-server"
  294. };
  295. var server2WithRemarkCanonUrl = "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA==#example-server";
  296. var serverWithPlugin = new Server
  297. {
  298. server = server.server,
  299. server_port = server.server_port,
  300. password = server.password,
  301. method = server.method,
  302. plugin = "obfs-local",
  303. plugin_opts = "obfs=http;obfs-host=google.com"
  304. };
  305. var serverWithPluginCanonUrl =
  306. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com";
  307. var server2WithPlugin = new Server
  308. {
  309. server = server2.server,
  310. server_port = server2.server_port,
  311. password = server2.password,
  312. method = server2.method,
  313. plugin = "obfs-local",
  314. plugin_opts = "obfs=http;obfs-host=google.com"
  315. };
  316. var server2WithPluginCanonUrl =
  317. "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com";
  318. var serverWithPluginAndRemark = new Server
  319. {
  320. server = server.server,
  321. server_port = server.server_port,
  322. password = server.password,
  323. method = server.method,
  324. plugin = serverWithPlugin.plugin,
  325. plugin_opts = serverWithPlugin.plugin_opts,
  326. remarks = serverWithRemark.remarks
  327. };
  328. var serverWithPluginAndRemarkCanonUrl =
  329. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com#example-server";
  330. var server2WithPluginAndRemark = new Server
  331. {
  332. server = server2.server,
  333. server_port = server2.server_port,
  334. password = server2.password,
  335. method = server2.method,
  336. plugin = server2WithPlugin.plugin,
  337. plugin_opts = server2WithPlugin.plugin_opts,
  338. remarks = server2WithRemark.remarks
  339. };
  340. var server2WithPluginAndRemarkCanonUrl =
  341. "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com#example-server";
  342. RunParseShadowsocksUrlTest(
  343. string.Join(
  344. "\r\n",
  345. serverCanonUrl,
  346. "\r\n",
  347. "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4/",
  348. serverWithRemarkCanonUrl,
  349. "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xMDAuMTo4ODg4/#example-server"),
  350. new[]
  351. {
  352. server,
  353. server,
  354. serverWithRemark,
  355. serverWithRemark
  356. });
  357. RunParseShadowsocksUrlTest(
  358. string.Join(
  359. "\r\n",
  360. server2CanonUrl,
  361. "\r\n",
  362. "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA==/",
  363. server2WithRemarkCanonUrl,
  364. "ss://YmYtY2ZiOnRlc3RAMTkyLjE2OC4xLjE6ODM4OA==/#example-server"),
  365. new[]
  366. {
  367. server2,
  368. server2,
  369. server2WithRemark,
  370. server2WithRemark
  371. });
  372. RunParseShadowsocksUrlTest(
  373. string.Join(
  374. "\r\n",
  375. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888",
  376. "\r\n",
  377. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/",
  378. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888#example-server",
  379. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/#example-server",
  380. serverWithPluginCanonUrl,
  381. serverWithPluginAndRemarkCanonUrl,
  382. "ss://YmYtY2ZiOnRlc3Q@192.168.100.1:8888/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com&unsupported=1#example-server"),
  383. new[]
  384. {
  385. server,
  386. server,
  387. serverWithRemark,
  388. serverWithRemark,
  389. serverWithPlugin,
  390. serverWithPluginAndRemark,
  391. serverWithPluginAndRemark
  392. });
  393. RunParseShadowsocksUrlTest(
  394. string.Join(
  395. "\r\n",
  396. "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388",
  397. "\r\n",
  398. "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/",
  399. "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388#example-server",
  400. "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/#example-server",
  401. server2WithPluginCanonUrl,
  402. server2WithPluginAndRemarkCanonUrl,
  403. "ss://YmYtY2ZiOnRlc3Q@192.168.1.1:8388/?plugin=obfs-local%3bobfs%3dhttp%3bobfs-host%3dgoogle.com&unsupported=1#example-server"),
  404. new[]
  405. {
  406. server2,
  407. server2,
  408. server2WithRemark,
  409. server2WithRemark,
  410. server2WithPlugin,
  411. server2WithPluginAndRemark,
  412. server2WithPluginAndRemark
  413. });
  414. var generateUrlCases = new Dictionary<string, Server>
  415. {
  416. [serverCanonUrl] = server,
  417. [serverWithRemarkCanonUrl] = serverWithRemark,
  418. [serverWithPluginCanonUrl] = serverWithPlugin,
  419. [serverWithPluginAndRemarkCanonUrl] = serverWithPluginAndRemark
  420. };
  421. RunGenerateShadowsocksUrlTest(generateUrlCases);
  422. }
  423. private static void RunParseShadowsocksUrlTest(string testCase, IReadOnlyList<Server> expected)
  424. {
  425. var actual = Server.GetServers(testCase);
  426. if (actual.Count != expected.Count)
  427. {
  428. Assert.Fail("Wrong number of configs. Expected: {0}. Actual: {1}", expected.Count, actual.Count);
  429. }
  430. for (int i = 0; i < expected.Count; i++)
  431. {
  432. var expectedServer = expected[i];
  433. var actualServer = actual[i];
  434. Assert.AreEqual(expectedServer.server, actualServer.server);
  435. Assert.AreEqual(expectedServer.server_port, actualServer.server_port);
  436. Assert.AreEqual(expectedServer.password, actualServer.password);
  437. Assert.AreEqual(expectedServer.method, actualServer.method);
  438. Assert.AreEqual(expectedServer.plugin, actualServer.plugin);
  439. Assert.AreEqual(expectedServer.plugin_opts, actualServer.plugin_opts);
  440. Assert.AreEqual(expectedServer.remarks, actualServer.remarks);
  441. Assert.AreEqual(expectedServer.timeout, actualServer.timeout);
  442. }
  443. }
  444. private static void RunGenerateShadowsocksUrlTest(IReadOnlyDictionary<string, Server> testCases)
  445. {
  446. foreach (var testCase in testCases)
  447. {
  448. string expected = testCase.Key;
  449. Server config = testCase.Value;
  450. var actual = ShadowsocksController.GetServerURL(config);
  451. Assert.AreEqual(expected, actual);
  452. }
  453. }
  454. [TestMethod]
  455. public void PluginSupport()
  456. {
  457. string fake_plugin = "ftp";
  458. var NoPlugin = Sip003Plugin.CreateIfConfigured(new Server
  459. {
  460. server = "192.168.100.1",
  461. server_port = 8888,
  462. password = "test",
  463. method = "bf-cfb"
  464. });
  465. RunPluginSupportTest(
  466. NoPlugin,
  467. "",
  468. "",
  469. "",
  470. "192.168.100.1",
  471. 8888);
  472. var Plugin = Sip003Plugin.CreateIfConfigured(new Server
  473. {
  474. server = "192.168.100.1",
  475. server_port = 8888,
  476. password = "test",
  477. method = "bf-cfb",
  478. plugin = fake_plugin
  479. });
  480. RunPluginSupportTest(
  481. Plugin,
  482. fake_plugin,
  483. "",
  484. "",
  485. "192.168.100.1",
  486. 8888);
  487. var PluginWithOpts = Sip003Plugin.CreateIfConfigured(new Server
  488. {
  489. server = "192.168.100.1",
  490. server_port = 8888,
  491. password = "test",
  492. method = "bf-cfb",
  493. plugin = fake_plugin,
  494. plugin_opts = "_option"
  495. });
  496. RunPluginSupportTest(
  497. PluginWithOpts,
  498. fake_plugin,
  499. "_option",
  500. "",
  501. "192.168.100.1",
  502. 8888);
  503. var PluginWithArgs = Sip003Plugin.CreateIfConfigured(new Server
  504. {
  505. server = "192.168.100.1",
  506. server_port = 8888,
  507. password = "test",
  508. method = "bf-cfb",
  509. plugin = fake_plugin,
  510. plugin_args = "_test"
  511. });
  512. RunPluginSupportTest(
  513. PluginWithArgs,
  514. fake_plugin,
  515. "",
  516. "_test",
  517. "192.168.100.1",
  518. 8888);
  519. var PluginWithOptsAndArgs = Sip003Plugin.CreateIfConfigured(new Server
  520. {
  521. server = "192.168.100.1",
  522. server_port = 8888,
  523. password = "test",
  524. method = "bf-cfb",
  525. plugin = fake_plugin,
  526. plugin_opts = "_option",
  527. plugin_args = "_test"
  528. });
  529. RunPluginSupportTest(
  530. PluginWithOptsAndArgs,
  531. fake_plugin,
  532. "_option",
  533. "_test",
  534. "192.168.100.1",
  535. 8888);
  536. var PluginWithArgsReplaced = Sip003Plugin.CreateIfConfigured(new Server
  537. {
  538. server = "192.168.100.1",
  539. server_port = 8888,
  540. password = "test",
  541. method = "bf-cfb",
  542. plugin = fake_plugin,
  543. plugin_args = "_test,%SS_REMOTE_HOST%"
  544. });
  545. RunPluginSupportTest(
  546. PluginWithArgsReplaced,
  547. fake_plugin,
  548. "",
  549. "_test,192.168.100.1",
  550. "192.168.100.1",
  551. 8888);
  552. var PluginWithOptsAndArgsReplaced = Sip003Plugin.CreateIfConfigured(new Server
  553. {
  554. server = "192.168.100.1",
  555. server_port = 8888,
  556. password = "test",
  557. method = "bf-cfb",
  558. plugin = fake_plugin,
  559. plugin_opts = "_option",
  560. plugin_args = "_test,%SS_REMOTE_HOST%,%SS_PLUGIN_OPTIONS%"
  561. });
  562. RunPluginSupportTest(
  563. PluginWithOptsAndArgsReplaced,
  564. fake_plugin,
  565. "_option",
  566. "_test,192.168.100.1,_option",
  567. "192.168.100.1",
  568. 8888);
  569. }
  570. private static void RunPluginSupportTest(Sip003Plugin plugin, string pluginName, string pluginOpts, string pluginArgs, string serverAddress, int serverPort)
  571. {
  572. if (string.IsNullOrWhiteSpace(pluginName)) return;
  573. plugin.StartIfNeeded();
  574. Process[] processes = Process.GetProcessesByName(pluginName);
  575. Assert.AreEqual(processes.Length, 1);
  576. Process p = processes[0];
  577. var penv = ProcessEnvironment.ReadEnvironmentVariables(p);
  578. var pcmd = ProcessEnvironment.GetCommandLine(p).Trim();
  579. pcmd = pcmd.IndexOf(' ') >= 0 ? pcmd.Substring(pcmd.IndexOf(' ') + 1) : "";
  580. Assert.AreEqual(penv["SS_REMOTE_HOST"], serverAddress);
  581. Assert.AreEqual(penv["SS_REMOTE_PORT"], serverPort.ToString());
  582. Assert.AreEqual(penv["SS_LOCAL_HOST"], IPAddress.Loopback.ToString());
  583. int _ignored;
  584. Assert.IsTrue(int.TryParse(penv["SS_LOCAL_PORT"], out _ignored));
  585. Assert.AreEqual(penv["SS_PLUGIN_OPTIONS"], pluginOpts);
  586. Assert.AreEqual(pcmd, pluginArgs);
  587. plugin.Dispose();
  588. for (int i = 0; i < 50; i++)
  589. {
  590. if (Process.GetProcessesByName(pluginName).Length == 0) return;
  591. Thread.Sleep(50);
  592. }
  593. }
  594. }
  595. }