Advertisement
metal6

pylong ??runtests

Sep 21st, 2020
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.35 KB | None | 0 0
  1. /*
  2. pylon unit testing for KV-related stuff, similar to the ??runtests command in the Pylon server.
  3. I only did the unit tests that I was able to replicate off name alone as I obviously
  4. did not have access to the real code running on the pylon server.
  5.  
  6. If for whatever reason you find this useful (i.e. building your own unit tests, despite how easy it is?)
  7. please consider giving thanks to metal#0666 or potatos OwO
  8.  
  9. */
  10.  
  11. const commandstests = new discord.command.CommandGroup({
  12. defaultPrefix: '??'
  13. });
  14.  
  15. commandstests.raw('runtests', async (m) => {
  16. const testingkv = new pylon.KVNamespace('testingkv');
  17. const start = Date.now();
  18. let passed = 0;
  19. const tests: { [key: string]: Function } = {
  20. 'get & put': async (name: string) => {
  21. await testingkv.put(name, '1234');
  22. const check = await testingkv.get(name);
  23. return check === '1234';
  24. },
  25. 'put if not exists fails if key exists': async (name: string) => {
  26. await testingkv.put(name, true);
  27. try {
  28. await testingkv.put(name, false, { ifNotExists: true });
  29. return false;
  30. } catch (e) {
  31. return true;
  32. }
  33. },
  34. 'put if not exists sets key': async (name: string) => {
  35. await testingkv.put(name, '1234', { ifNotExists: true });
  36. const check = await testingkv.get(name);
  37. return check === '1234';
  38. },
  39. delete: async (name: string) => {
  40. await testingkv.put(name, '1234');
  41. const check = await testingkv.get(name);
  42. if (check !== '1234') {
  43. return false;
  44. }
  45. await testingkv.delete(name);
  46. const check2 = await testingkv.get(name);
  47. return check2 === undefined;
  48. },
  49. 'delete if equals': async (name: string) => {
  50. await testingkv.put(name, '1234');
  51. await testingkv.delete(name, { prevValue: '1234' });
  52. const check2 = await testingkv.get(name);
  53. return check2 === undefined;
  54. },
  55. 'delete if equals does not delete if not equals': async (name: string) => {
  56. await testingkv.put(name, '1234');
  57. try {
  58. await testingkv.delete(name, { prevValue: 1234 });
  59. return false;
  60. } catch (e) {}
  61. const check = await testingkv.get(name);
  62. return check !== undefined;
  63. },
  64. 'put with ttl': async (name: string) => {
  65. await testingkv.put(name, '1234', { ttl: 200 });
  66. const check = await testingkv.get(name);
  67. if (check === undefined) {
  68. return false;
  69. }
  70. await sleep(201);
  71. const check2 = await testingkv.get(name);
  72. return check2 === undefined;
  73. },
  74. 'put with ttlEpoch': async (name: string) => {
  75. await testingkv.put(name, '1234', {
  76. ttlEpoch: new Date(Date.now() + 200)
  77. });
  78. const check = await testingkv.get(name);
  79. if (check === undefined) {
  80. return false;
  81. }
  82. await sleep(201);
  83. const check2 = await testingkv.get(name);
  84. return check2 === undefined;
  85. },
  86. list: async (name: string) => {
  87. for (let i = 0; i < 5; i++) {
  88. await testingkv.put(`${name}_${i}`, true);
  89. }
  90. const list = await testingkv.list();
  91. for (let i = 0; i < 5; i++) {
  92. const check = list.includes(`${name}_${i}`);
  93. if (!check) {
  94. return false;
  95. }
  96. }
  97. return true;
  98. },
  99. 'cas set nx': async (name: string) => {
  100. await testingkv.cas(name, undefined, '1234');
  101. const check = await testingkv.get(name);
  102. return check === '1234';
  103. },
  104. 'cas set nx fail': async (name: string) => {
  105. await testingkv.put(name, '1234');
  106. try {
  107. await testingkv.cas(name, undefined, '12345');
  108. } catch (e) {}
  109. const check = await testingkv.get(name);
  110. return check === '1234';
  111. },
  112. 'cas set nx expires': async (name: string) => {
  113. await testingkv.cas(name, undefined, '1234', 200);
  114. const check = await testingkv.get(name);
  115. if (check === undefined) {
  116. return false;
  117. }
  118. await sleep(201);
  119. const check2 = await testingkv.get(name);
  120. return check2 === undefined;
  121. },
  122. 'cas - swap': async (name: string) => {
  123. await testingkv.put(name, 1);
  124. await testingkv.cas(name, 1, 2);
  125. const check = await testingkv.get(name);
  126. return check === 2;
  127. },
  128. 'cas - delete': async (name: string) => {
  129. await testingkv.put(name, 1);
  130. await testingkv.cas(name, 1, undefined);
  131. const list = await testingkv.list();
  132. return !list.includes(name);
  133. },
  134. 'cas multi': async (name: string) => {
  135. const keys = [];
  136. for (let i = 0; i < 5; i++) {
  137. keys.push(`${name}_${i + 1}`);
  138. }
  139. const ops: pylon.KVNamespace.CasOperation[] = keys.map((v) => ({
  140. key: v,
  141. compare: undefined,
  142. set: v
  143. }));
  144. await testingkv.casMulti(ops);
  145. const results: boolean[] = [];
  146. await Promise.all(
  147. keys.map(async (val) => {
  148. const thisR = await testingkv.get(val);
  149. results.push(thisR === val);
  150. })
  151. );
  152. return results.every((v) => v === true);
  153. },
  154. 'cas multi delete': async (name: string) => {
  155. const keys = [];
  156. for (let i = 0; i < 5; i++) {
  157. keys.push(`${name}_${i + 1}`);
  158. }
  159. const ops1: pylon.KVNamespace.CasOperation[] = keys.map((v) => ({
  160. key: v,
  161. compare: undefined,
  162. set: v
  163. }));
  164. await testingkv.casMulti(ops1);
  165. const ops2: pylon.KVNamespace.CasOperation[] = keys.map((v) => ({
  166. key: v,
  167. compare: v,
  168. set: undefined
  169. }));
  170. await testingkv.casMulti(ops2);
  171. const list = await testingkv.list();
  172. const results = keys.map((key) => !list.includes(key));
  173. return results.every((v) => v === true);
  174. },
  175. 'cas multi expires': async (name: string) => {
  176. const keys = [];
  177. for (let i = 0; i < 5; i++) {
  178. keys.push(`${name}_${i + 1}`);
  179. }
  180. const ops1: pylon.KVNamespace.CasOperation[] = keys.map((v) => ({
  181. key: v,
  182. compare: undefined,
  183. set: v,
  184. ttl: 200
  185. }));
  186. await testingkv.casMulti(ops1);
  187. const list1 = await testingkv.list();
  188. const results1 = keys.map((key) => list1.includes(key));
  189. if (!results1.every((v) => v === true)) {
  190. return false;
  191. }
  192. await sleep(201);
  193. const list2 = await testingkv.list();
  194. const results2 = keys.map((key) => !list2.includes(key));
  195. return results2.every((v) => v === true);
  196. },
  197. transact: async (name: string) => {
  198. await testingkv.put(name, '1234');
  199. let corrVal = false;
  200. await testingkv.transact(name, (v) => {
  201. if (v === '1234') {
  202. corrVal = true;
  203. }
  204. return v;
  205. });
  206. return corrVal;
  207. },
  208. 'transact update': async (name: string) => {
  209. await testingkv.put(name, '1234');
  210. await testingkv.transact(name, (v) => {
  211. if (v === '1234') {
  212. v = '12345';
  213. }
  214. return v;
  215. });
  216. const result = await testingkv.get(name);
  217. return result === '12345';
  218. },
  219. 'transact delete': async (name: string) => {
  220. await testingkv.put(name, '1234');
  221. await testingkv.transact(name, (v) => {
  222. if (v === '1234') {
  223. v = undefined;
  224. }
  225. return v;
  226. });
  227. const result = await testingkv.list();
  228. return !result.includes(name);
  229. },
  230. 'transact with result': async (name: string) => {
  231. await testingkv.put(name, '1234');
  232. const test = await testingkv.transactWithResult(name, (v) => {
  233. if (v !== '1234') {
  234. return { next: v, result: false };
  235. }
  236. return { next: '12345', result: true };
  237. });
  238. return test.result === true && test.next === '12345';
  239. },
  240. 'transact multi': async (name: string) => {
  241. const keys = [`${name}_1`, `${name}_2`];
  242. // @ts-ignore
  243. await testingkv.transactMulti(keys, (v) => ['2', '3']);
  244. const list = await testingkv.items();
  245. const first = list.find((v) => v.key === keys[0]);
  246. const second = list.find((v) => v.key === keys[1]);
  247. if (!first || !second) {
  248. return false;
  249. }
  250. if (first.value !== '2' || second.value !== '3') {
  251. return false;
  252. }
  253. return true;
  254. },
  255. 'transact multi with result': async (name: string) => {
  256. const keys = [`${name}_1`, `${name}_2`];
  257. await testingkv.put(keys[0], '1');
  258. await testingkv.put(keys[1], '2');
  259. // @ts-ignore
  260. const res = await testingkv.transactMultiWithResult(keys, (v) => {
  261. // @ts-ignore
  262. if (v[0] !== '1' || v[1] !== '2') {
  263. return { next: v, result: false };
  264. }
  265. return { next: ['2', '3'], result: true };
  266. });
  267. const list = await testingkv.items();
  268. const first = list.find((v) => v.key === keys[0]);
  269. const second = list.find((v) => v.key === keys[1]);
  270. const rest: any[] = res.next;
  271. if (!first || !second || rest.length !== 2) {
  272. return false;
  273. }
  274. if (first.value !== '2' || second.value !== '3') {
  275. return false;
  276. }
  277. if (res.result !== true || rest[0] !== '2' || rest[1] !== '3') {
  278. return false;
  279. }
  280. return true;
  281. }
  282. };
  283. let txt = '';
  284. await testingkv.clear();
  285. const results: { [key: string]: boolean } = {};
  286. for (const key in tests) {
  287. results[key] = false;
  288. }
  289. await pylon.requestCpuBurst(async () => {
  290. await Promise.all(
  291. Object.keys(tests).map(async (key) => {
  292. try {
  293. const result: boolean = await tests[key](`${key}`);
  294. if (result === true) {
  295. results[key] = true;
  296. passed += 1;
  297. }
  298. } catch (e) {
  299. console.error(e);
  300. }
  301. })
  302. );
  303. });
  304. for (const key in results) {
  305. txt += `\n${
  306. results[key] === true
  307. ? discord.decor.Emojis.GREEN_CIRCLE
  308. : discord.decor.Emojis.RED_CIRCLE
  309. } **${key}**`;
  310. }
  311. await testingkv.clear();
  312. const emb = new discord.Embed();
  313. emb.setDescription(txt);
  314. emb.setTitle(`${passed}/${Object.keys(tests).length} tests passed`);
  315. await m.reply({
  316. content: `Done. Took **${Date.now() - start}ms** (~**${Math.floor(
  317. (Date.now() - start) / Object.keys(tests).length
  318. )}ms** per test)`,
  319. embed: emb
  320. });
  321. });
  322.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement