/ToMigrate/Raven.Tests/Storage/TasksStorageActionsTests.cs

https://github.com/fitzchak/ravendb · C# · 574 lines · 485 code · 84 blank · 5 comment · 15 complexity · b565b9301d002f231f5efc0362708a19 MD5 · raw file

  1. // -----------------------------------------------------------------------
  2. // <copyright file="TasksStorageActions.cs" company="Hibernating Rhinos LTD">
  3. // Copyright (c) Hibernating Rhinos LTD. All rights reserved.
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. using System.Collections.Generic;
  7. using Raven.Abstractions;
  8. using Raven.Abstractions.Data;
  9. using Raven.Tests.Common;
  10. namespace Raven.Tests.Storage
  11. {
  12. using System;
  13. using Database.Tasks;
  14. using Xunit;
  15. using Xunit.Extensions;
  16. [Trait("VoronTest", "StorageActionsTests")]
  17. public class TasksStorageActionsTests : TransactionalStorageTestBase
  18. {
  19. [Theory]
  20. [PropertyData("Storages")]
  21. public void SimpleTask(string requestedStorage)
  22. {
  23. using (var storage = NewTransactionalStorage(requestedStorage))
  24. {
  25. storage.Batch(accessor => accessor.Tasks.AddTask(new RemoveFromIndexTask(101), DateTime.Now));
  26. storage.Batch(accessor =>
  27. {
  28. var alreadySeen = new HashSet<IComparable>();
  29. var task = accessor.Tasks.GetMergedTask<RemoveFromIndexTask>(new List<int>(), new[] {101}, alreadySeen);
  30. Assert.NotNull(task);
  31. accessor.Tasks.DeleteTasks(alreadySeen);
  32. });
  33. storage.Batch(accessor =>
  34. {
  35. Assert.False(accessor.Tasks.HasTasks);
  36. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  37. });
  38. }
  39. }
  40. [Theory]
  41. [PropertyData("Storages")]
  42. public void MergingTask(string requestedStorage)
  43. {
  44. using (var storage = NewTransactionalStorage(requestedStorage))
  45. {
  46. storage.Batch(accessor => accessor.Tasks.AddTask(new RemoveFromIndexTask(101), DateTime.Now));
  47. storage.Batch(accessor => accessor.Tasks.AddTask(new RemoveFromIndexTask(101), DateTime.Now));
  48. storage.Batch(accessor =>
  49. {
  50. var alreadySeen = new HashSet<IComparable>();
  51. var task = accessor.Tasks.GetMergedTask<RemoveFromIndexTask>(new List<int>(), new[] {101}, alreadySeen);
  52. Assert.NotNull(task);
  53. accessor.Tasks.DeleteTasks(alreadySeen);
  54. });
  55. storage.Batch(accessor =>
  56. {
  57. Assert.False(accessor.Tasks.HasTasks);
  58. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  59. });
  60. }
  61. }
  62. [Theory]
  63. [PropertyData("Storages")]
  64. public void CanAddAndRemoveMultipleTasks_InSingleTx(string requestedStorage)
  65. {
  66. using (var storage = NewTransactionalStorage(requestedStorage))
  67. {
  68. storage.Batch(actions =>
  69. {
  70. for (int i = 0; i < 3; i++)
  71. {
  72. var task = new RemoveFromIndexTask(100);
  73. task.AddKey("tasks/" + i);
  74. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  75. }
  76. });
  77. storage.Batch(actions =>
  78. {
  79. var alreadySeen = new HashSet<IComparable>();
  80. var task = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(new List<int>(), new[] {100}, alreadySeen);
  81. Assert.NotNull(task);
  82. actions.Tasks.DeleteTasks(alreadySeen);
  83. task = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(new List<int>(), new[] {100}, new HashSet<IComparable>());
  84. Assert.Null(task);
  85. });
  86. storage.Batch(accessor =>
  87. {
  88. Assert.False(accessor.Tasks.HasTasks);
  89. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  90. });
  91. storage.Batch(actions =>
  92. {
  93. var isIndexStale = actions.Staleness.IsIndexStale(100, null, null);
  94. Assert.False(isIndexStale);
  95. });
  96. }
  97. }
  98. [Theory]
  99. [PropertyData("Storages")]
  100. public void CanAddAndRemoveMultipleTasks_DifferentTypes(string requestedStorage)
  101. {
  102. using (var storage = NewTransactionalStorage(requestedStorage))
  103. {
  104. storage.Batch(actions =>
  105. {
  106. for (int i = 0; i < 3; i++)
  107. {
  108. var task = new RemoveFromIndexTask(100);
  109. task.AddKey("tasks/" + i);
  110. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  111. }
  112. for (int i = 0; i < 3; i++)
  113. {
  114. var task = new TouchReferenceDocumentIfChangedTask(100);
  115. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  116. }
  117. });
  118. storage.Batch(actions =>
  119. {
  120. var idsToSkip = new List<int>();
  121. var allIndexes = new[] { 100 };
  122. var alreadySeen = new HashSet<IComparable>();
  123. var task1 = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(idsToSkip, allIndexes, alreadySeen);
  124. Assert.NotNull(task1);
  125. task1 = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(idsToSkip, allIndexes, alreadySeen);
  126. Assert.Null(task1);
  127. var task2 = actions.Tasks.GetMergedTask<TouchReferenceDocumentIfChangedTask>(idsToSkip, allIndexes, alreadySeen);
  128. Assert.NotNull(task2);
  129. task2 = actions.Tasks.GetMergedTask<TouchReferenceDocumentIfChangedTask>(idsToSkip, allIndexes, alreadySeen);
  130. Assert.Null(task2);
  131. actions.Tasks.DeleteTasks(alreadySeen);
  132. });
  133. storage.Batch(accessor =>
  134. {
  135. Assert.False(accessor.Tasks.HasTasks);
  136. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  137. });
  138. storage.Batch(actions =>
  139. {
  140. var isIndexStale = actions.Staleness.IsIndexStale(100, null, null);
  141. Assert.False(isIndexStale);
  142. });
  143. }
  144. }
  145. [Theory]
  146. [PropertyData("Storages")]
  147. public void returns_only_tasks_for_existing_indexes(string requestedStorage)
  148. {
  149. using (var storage = NewTransactionalStorage(requestedStorage))
  150. {
  151. storage.Batch(actions =>
  152. {
  153. int id = 99;
  154. for (int i = 0; i < 3; i++)
  155. {
  156. var task = new RemoveFromIndexTask(id);
  157. id++;
  158. task.AddKey("tasks/" + i);
  159. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  160. }
  161. id = 99;
  162. for (int i = 0; i < 3; i++)
  163. {
  164. var task = new TouchReferenceDocumentIfChangedTask(id);
  165. id++;
  166. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  167. }
  168. });
  169. storage.Batch(actions =>
  170. {
  171. var idsToSkip = new List<int>();
  172. var allIndexes = new[] {100};
  173. var alreadySeen = new HashSet<IComparable>();
  174. var task1 = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(idsToSkip, allIndexes, alreadySeen);
  175. Assert.Equal(1, task1.NumberOfKeys);
  176. Assert.NotNull(task1);
  177. Assert.Equal(100, task1.Index);
  178. actions.Tasks.DeleteTasks(alreadySeen);
  179. task1 = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(idsToSkip, allIndexes, alreadySeen);
  180. Assert.Null(task1);
  181. var task2 = actions.Tasks.GetMergedTask<TouchReferenceDocumentIfChangedTask>(idsToSkip, allIndexes, alreadySeen);
  182. Assert.NotNull(task2);
  183. Assert.Equal(false, task2.SeparateTasksByIndex);
  184. Assert.Equal(100, task2.Index);
  185. actions.Tasks.DeleteTasks(alreadySeen);
  186. task2 = actions.Tasks.GetMergedTask<TouchReferenceDocumentIfChangedTask>(idsToSkip, allIndexes, alreadySeen);
  187. Assert.Null(task2);
  188. });
  189. storage.Batch(actions =>
  190. {
  191. var isIndexStale = actions.Staleness.IsIndexStale(100, null, null);
  192. Assert.False(isIndexStale);
  193. });
  194. }
  195. }
  196. [Theory]
  197. [PropertyData("Storages")]
  198. public void returns_only_tasks_for_existing_indexes_with_merging(string requestedStorage)
  199. {
  200. using (var storage = NewTransactionalStorage(requestedStorage))
  201. {
  202. storage.Batch(actions =>
  203. {
  204. int id = 100;
  205. for (int i = 0; i < 3; i++)
  206. {
  207. var task = new RemoveFromIndexTask(id);
  208. id++;
  209. task.AddKey("tasks/" + i);
  210. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  211. task = new RemoveFromIndexTask(id);
  212. id++;
  213. task.AddKey("tasks/" + i + 1);
  214. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  215. }
  216. id = 100;
  217. for (int i = 0; i < 3; i++)
  218. {
  219. var task = new TouchReferenceDocumentIfChangedTask(id);
  220. id++;
  221. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  222. task = new TouchReferenceDocumentIfChangedTask(id);
  223. id++;
  224. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  225. }
  226. });
  227. storage.Batch(actions =>
  228. {
  229. var idsToSkip = new List<int>();
  230. var allIndexes = new[] { 100 };
  231. var alreadySeen = new HashSet<IComparable>();
  232. var task1 = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(idsToSkip, allIndexes, alreadySeen);
  233. Assert.Equal(1, task1.NumberOfKeys);
  234. Assert.NotNull(task1);
  235. Assert.Equal(100, task1.Index);
  236. actions.Tasks.DeleteTasks(alreadySeen);
  237. task1 = actions.Tasks.GetMergedTask<RemoveFromIndexTask>(idsToSkip, allIndexes, alreadySeen);
  238. Assert.Null(task1);
  239. var task2 = actions.Tasks.GetMergedTask<TouchReferenceDocumentIfChangedTask>(idsToSkip, allIndexes, alreadySeen);
  240. Assert.NotNull(task2);
  241. Assert.Equal(false, task2.SeparateTasksByIndex);
  242. Assert.Equal(100, task2.Index);
  243. actions.Tasks.DeleteTasks(alreadySeen);
  244. task2 = actions.Tasks.GetMergedTask<TouchReferenceDocumentIfChangedTask>(idsToSkip, allIndexes, alreadySeen);
  245. Assert.Null(task2);
  246. });
  247. storage.Batch(actions =>
  248. {
  249. var isIndexStale = actions.Staleness.IsIndexStale(100, null, null);
  250. Assert.False(isIndexStale);
  251. });
  252. }
  253. }
  254. [Theory]
  255. [PropertyData("Storages")]
  256. public void returns_only_working_indexes(string requestedStorage)
  257. {
  258. using (var storage = NewTransactionalStorage(requestedStorage))
  259. {
  260. storage.Batch(actions =>
  261. {
  262. var id = 100;
  263. for (int i = 0; i < 3; i++)
  264. {
  265. var task = new TouchReferenceDocumentIfChangedTask(id);
  266. task.UpdateReferenceToCheck(new KeyValuePair<string, Etag>(i.ToString(), Etag.Empty));
  267. id++;
  268. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  269. }
  270. });
  271. storage.Batch(actions =>
  272. {
  273. var idsToSkip = new List<int>() { 101 };
  274. var allIndexes = new[] { 100 };
  275. var alreadySeen = new HashSet<IComparable>();
  276. var task1 = actions.Tasks.GetMergedTask<TouchReferenceDocumentIfChangedTask>(idsToSkip, allIndexes, alreadySeen);
  277. Assert.Equal(1, task1.NumberOfKeys);
  278. Assert.NotNull(task1);
  279. Assert.Equal(100, task1.Index);
  280. });
  281. storage.Batch(actions =>
  282. {
  283. var isIndexStale = actions.Staleness.IsIndexStale(100, null, null);
  284. Assert.False(isIndexStale);
  285. });
  286. }
  287. }
  288. [Theory]
  289. [PropertyData("Storages")]
  290. public void can_remove_all_tasks_for_one_index(string requestedStorage)
  291. {
  292. using (var storage = NewTransactionalStorage(requestedStorage))
  293. {
  294. storage.Batch(actions =>
  295. {
  296. for (int i = 0; i < 3; i++)
  297. {
  298. var task = new RemoveFromIndexTask(100);
  299. task.AddKey("tasks/" + i);
  300. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  301. }
  302. });
  303. storage.Batch(actions =>
  304. {
  305. Assert.Equal(3, actions.Tasks.ApproximateTaskCount);
  306. actions.Tasks.DeleteTasksForIndex(100);
  307. });
  308. storage.Batch(accessor =>
  309. {
  310. Assert.False(accessor.Tasks.HasTasks);
  311. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  312. });
  313. storage.Batch(actions =>
  314. {
  315. var isIndexStale = actions.Staleness.IsIndexStale(100, null, null);
  316. Assert.False(isIndexStale);
  317. });
  318. }
  319. }
  320. [Theory]
  321. [PropertyData("Storages")]
  322. public void can_remove_two_tasks_for_one_index(string requestedStorage)
  323. {
  324. using (var storage = NewTransactionalStorage(requestedStorage))
  325. {
  326. storage.Batch(actions =>
  327. {
  328. for (int i = 0; i < 3; i++)
  329. {
  330. var task = new RemoveFromIndexTask(100);
  331. task.AddKey("tasks/" + i);
  332. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  333. }
  334. for (int i = 0; i < 3; i++)
  335. {
  336. var task = new RemoveFromIndexTask(101);
  337. task.AddKey("tasks/" + i);
  338. actions.Tasks.AddTask(task, SystemTime.UtcNow);
  339. }
  340. });
  341. storage.Batch(actions =>
  342. {
  343. Assert.Equal(6, actions.Tasks.ApproximateTaskCount);
  344. actions.Tasks.DeleteTasksForIndex(100);
  345. });
  346. storage.Batch(accessor =>
  347. {
  348. Assert.True(accessor.Tasks.HasTasks);
  349. Assert.Equal(3, accessor.Tasks.ApproximateTaskCount);
  350. });
  351. storage.Batch(actions =>
  352. {
  353. var isIndexStale = actions.Staleness.IsIndexStaleByTask(100, null);
  354. Assert.False(isIndexStale);
  355. isIndexStale = actions.Staleness.IsIndexStaleByTask(101, null);
  356. Assert.True(isIndexStale);
  357. });
  358. storage.Batch(actions => actions.Tasks.DeleteTasksForIndex(101));
  359. storage.Batch(accessor =>
  360. {
  361. Assert.False(accessor.Tasks.HasTasks);
  362. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  363. });
  364. }
  365. }
  366. [Theory]
  367. [PropertyData("Storages")]
  368. public void can_remove_two_different_type_tasks_for_one_index(string requestedStorage)
  369. {
  370. using (var storage = NewTransactionalStorage(requestedStorage))
  371. {
  372. storage.Batch(actions =>
  373. {
  374. for (int i = 0; i < 3; i++)
  375. {
  376. var task1 = new RemoveFromIndexTask(100);
  377. task1.AddKey("tasks/" + i);
  378. actions.Tasks.AddTask(task1, SystemTime.UtcNow);
  379. var task2 = new TouchReferenceDocumentIfChangedTask(101);
  380. actions.Tasks.AddTask(task2, SystemTime.UtcNow);
  381. }
  382. });
  383. storage.Batch(actions =>
  384. {
  385. Assert.Equal(6, actions.Tasks.ApproximateTaskCount);
  386. actions.Tasks.DeleteTasksForIndex(100);
  387. });
  388. storage.Batch(accessor => Assert.True(accessor.Tasks.HasTasks));
  389. storage.Batch(actions =>
  390. {
  391. var isIndexStale = actions.Staleness.IsIndexStaleByTask(100, null);
  392. Assert.False(isIndexStale);
  393. isIndexStale = actions.Staleness.IsIndexStaleByTask(101, null);
  394. Assert.True(isIndexStale);
  395. });
  396. storage.Batch(actions => actions.Tasks.DeleteTasksForIndex(101));
  397. storage.Batch(accessor =>
  398. {
  399. Assert.False(accessor.Tasks.HasTasks);
  400. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  401. var isIndexStale = accessor.Staleness.IsIndexStaleByTask(101, null);
  402. Assert.False(isIndexStale);
  403. });
  404. }
  405. }
  406. [Theory]
  407. [PropertyData("Storages")]
  408. public void can_remove_different_type_tasks_for_one_index(string requestedStorage)
  409. {
  410. using (var storage = NewTransactionalStorage(requestedStorage))
  411. {
  412. storage.Batch(actions =>
  413. {
  414. for (int i = 0; i < 3; i++)
  415. {
  416. var task1 = new RemoveFromIndexTask(100);
  417. task1.AddKey("tasks/" + i);
  418. actions.Tasks.AddTask(task1, SystemTime.UtcNow);
  419. var task2 = new TouchReferenceDocumentIfChangedTask(100);
  420. actions.Tasks.AddTask(task2, SystemTime.UtcNow);
  421. }
  422. });
  423. storage.Batch(actions =>
  424. {
  425. Assert.Equal(6, actions.Tasks.ApproximateTaskCount);
  426. actions.Tasks.DeleteTasksForIndex(101);
  427. });
  428. storage.Batch(accessor =>
  429. {
  430. Assert.True(accessor.Tasks.HasTasks);
  431. Assert.Equal(6, accessor.Tasks.ApproximateTaskCount);
  432. });
  433. storage.Batch(actions =>
  434. {
  435. var isIndexStale = actions.Staleness.IsIndexStale(100, null, null);
  436. Assert.False(isIndexStale);
  437. });
  438. storage.Batch(actions => actions.Tasks.DeleteTasksForIndex(100));
  439. storage.Batch(accessor =>
  440. {
  441. Assert.False(accessor.Tasks.HasTasks);
  442. Assert.Equal(0, accessor.Tasks.ApproximateTaskCount);
  443. var isIndexStale = accessor.Staleness.IsIndexStale(101, null, null);
  444. Assert.False(isIndexStale);
  445. });
  446. }
  447. }
  448. [Fact]
  449. public void CanGetNumberOfKeysFromRemoveTask()
  450. {
  451. var task1 = new RemoveFromIndexTask(101);
  452. Assert.Equal(0, task1.NumberOfKeys);
  453. for (var i = 0; i < 100; i++)
  454. {
  455. task1.AddKey("key/" + i);
  456. }
  457. Assert.Equal(100, task1.NumberOfKeys);
  458. var task2 = new RemoveFromIndexTask(102);
  459. task2.AddKey("test1");
  460. task2.AddKey("test2");
  461. task1.Merge(task2);
  462. Assert.Equal(102, task1.NumberOfKeys);
  463. var task3 = new RemoveFromIndexTask(103);
  464. task2.AddKey("test2");
  465. task1.Merge(task3);
  466. Assert.Equal(102, task1.NumberOfKeys);
  467. }
  468. [Fact]
  469. public void CanGetNumberOfKeysFromTouchReferenceTask()
  470. {
  471. var task1 = new TouchReferenceDocumentIfChangedTask(101);
  472. Assert.Equal(0, task1.NumberOfKeys);
  473. for (var i = 0; i < 100; i++)
  474. {
  475. task1.UpdateReferenceToCheck(new KeyValuePair<string, Etag>("key/" + i, Etag.Empty));
  476. }
  477. Assert.Equal(100, task1.NumberOfKeys);
  478. var task2 = new TouchReferenceDocumentIfChangedTask(102);
  479. task2.UpdateReferenceToCheck(new KeyValuePair<string, Etag>("test1", Etag.Empty));
  480. task2.UpdateReferenceToCheck(new KeyValuePair<string, Etag>("test2", Etag.Empty));
  481. task1.Merge(task2);
  482. Assert.Equal(102, task1.NumberOfKeys);
  483. var task3 = new TouchReferenceDocumentIfChangedTask(103);
  484. task3.UpdateReferenceToCheck(new KeyValuePair<string, Etag>("test1", Etag.Empty.IncrementBy(2)));
  485. task3.UpdateReferenceToCheck(new KeyValuePair<string, Etag>("test2", Etag.Empty.IncrementBy(1)));
  486. task1.Merge(task3);
  487. Assert.Equal(102, task1.NumberOfKeys);
  488. }
  489. }
  490. }