/ToMigrate/Raven.SlowTests/Issues/RavenDB_1603.cs

https://github.com/fitzchak/ravendb · C# · 953 lines · 838 code · 104 blank · 11 comment · 14 complexity · 5e8fa4f8f68202f0036e5688a4aa2a3e MD5 · raw file

  1. // -----------------------------------------------------------------------
  2. // <copyright file="RavenDB_1603.cs" company="Hibernating Rhinos LTD">
  3. // Copyright (c) Hibernating Rhinos LTD. All rights reserved.
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. using System;
  7. using System.Collections.Generic;
  8. using System.ComponentModel.Composition.Hosting;
  9. using System.IO;
  10. using System.IO.Compression;
  11. using System.Linq;
  12. using System.Threading;
  13. using System.Threading.Tasks;
  14. using Raven.Abstractions.Data;
  15. using Raven.Abstractions.Exceptions;
  16. using Raven.Abstractions.Extensions;
  17. using Raven.Abstractions.Smuggler;
  18. using Raven.Abstractions.Smuggler.Data;
  19. using Raven.Client;
  20. using Raven.Client.Document;
  21. using Raven.Client.Embedded;
  22. using Raven.Database.Config;
  23. using Raven.Database.Extensions;
  24. using Raven.Database.Smuggler;
  25. using Raven.Json.Linq;
  26. using Raven.Smuggler;
  27. using Raven.Tests.Common;
  28. using Raven.Tests.Common.Triggers;
  29. using Raven.Tests.Common.Util;
  30. using Xunit;
  31. namespace Raven.SlowTests.Issues
  32. {
  33. public class RavenDB_1603 : RavenTest
  34. {
  35. public class User
  36. {
  37. public string Name { get; set; }
  38. public string Id { get; set; }
  39. }
  40. public class Developer
  41. {
  42. public string Name { get; set; }
  43. public string Id { get; set; }
  44. }
  45. protected override void ModifyConfiguration(InMemoryRavenConfiguration configuration)
  46. {
  47. configuration.Container = new CompositionContainer(new TypeCatalog(
  48. typeof(HiddenDocumentsTrigger)));
  49. }
  50. [Fact, Trait("Category", "Smuggler")]
  51. public async Task CanPerformDump_Dumper()
  52. {
  53. var backupPath = NewDataPath("BackupFolder");
  54. try
  55. {
  56. using (var store = NewDocumentStore())
  57. {
  58. InsertUsers(store, 0, 2000);
  59. var dumper = new DatabaseDataDumper(store.SystemDatabase) { Options = { Incremental = true } };
  60. await dumper.ExportData(
  61. new SmugglerExportOptions<RavenConnectionStringOptions>
  62. {
  63. ToFile = backupPath,
  64. });
  65. }
  66. VerifyDump(backupPath, store =>
  67. {
  68. using (var session = store.OpenSession())
  69. {
  70. Assert.Equal(2000, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  71. }
  72. });
  73. }
  74. finally
  75. {
  76. IOExtensions.DeleteDirectory(backupPath);
  77. }
  78. }
  79. [Fact, Trait("Category", "Smuggler")]
  80. public async Task CanPerformDump_Smuggler()
  81. {
  82. var backupPath = NewDataPath("BackupFolder");
  83. try
  84. {
  85. using (var store = NewRemoteDocumentStore())
  86. {
  87. InsertUsers(store, 0, 2000);
  88. var dumper = new SmugglerDatabaseApi { Options = { Incremental = true } };
  89. await dumper.ExportData(
  90. new SmugglerExportOptions<RavenConnectionStringOptions>
  91. {
  92. ToFile = backupPath,
  93. From = new RavenConnectionStringOptions
  94. {
  95. Url = "http://localhost:8079",
  96. DefaultDatabase = store.DefaultDatabase,
  97. }
  98. });
  99. }
  100. VerifyDump(backupPath, store =>
  101. {
  102. using (var session = store.OpenSession())
  103. {
  104. Assert.Equal(2000, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  105. }
  106. });
  107. }
  108. finally
  109. {
  110. IOExtensions.DeleteDirectory(backupPath);
  111. }
  112. }
  113. [Fact, Trait("Category", "Smuggler")]
  114. public async Task CanPerformDumpWithLimit_Dumper()
  115. {
  116. var backupPath = NewDataPath("BackupFolder");
  117. try
  118. {
  119. using (var store = NewDocumentStore())
  120. {
  121. InsertUsers(store, 0, 2000);
  122. var dumper = new DatabaseDataDumper(store.SystemDatabase) { Options = { Limit = 1500, Incremental = true } };
  123. dumper.Options.Filters.Add(
  124. new FilterSetting
  125. {
  126. Path = "@metadata.Raven-Entity-Name",
  127. Values = {"Users"},
  128. ShouldMatch = true,
  129. });
  130. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  131. }
  132. VerifyDump(backupPath, store =>
  133. {
  134. using (var session = store.OpenSession())
  135. {
  136. Assert.Equal(1500, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  137. }
  138. });
  139. }
  140. finally
  141. {
  142. IOExtensions.DeleteDirectory(backupPath);
  143. }
  144. }
  145. [Fact, Trait("Category", "Smuggler")]
  146. public async Task CanPerformDumpWithLimit_Smuggler()
  147. {
  148. var backupPath = NewDataPath("BackupFolder");
  149. try
  150. {
  151. using (var store = NewRemoteDocumentStore())
  152. {
  153. List<User> generatedUsers;
  154. InsertUsers(store, 0, 2000, out generatedUsers);
  155. var dumper = new SmugglerDatabaseApi { Options = { Limit = 1500, Incremental = true } };
  156. dumper.Options.Filters.Add(
  157. new FilterSetting
  158. {
  159. Path = "@metadata.Raven-Entity-Name",
  160. Values = { "Users" },
  161. ShouldMatch = true,
  162. });
  163. await dumper.ExportData(
  164. new SmugglerExportOptions<RavenConnectionStringOptions>
  165. {
  166. From = new RavenConnectionStringOptions {DefaultDatabase = store.DefaultDatabase, Url = "http://localhost:8079"},
  167. ToFile = backupPath
  168. });
  169. }
  170. VerifyDump(backupPath, store =>
  171. {
  172. using (var session = store.OpenSession())
  173. {
  174. Assert.Equal(1500, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  175. }
  176. });
  177. }
  178. finally
  179. {
  180. IOExtensions.DeleteDirectory(backupPath);
  181. }
  182. }
  183. private void VerifyDump(string backupPath, Action<EmbeddableDocumentStore> action)
  184. {
  185. using (var store = NewDocumentStore())
  186. {
  187. var dumper = new DatabaseDataDumper(store.SystemDatabase) { Options = { Incremental = true } };
  188. dumper.ImportData(new SmugglerImportOptions<RavenConnectionStringOptions> { FromFile = backupPath }).Wait();
  189. action(store);
  190. }
  191. }
  192. [Fact, Trait("Category", "Smuggler")]
  193. public async Task CanPerformDumpWithLimitAndFilter_Dumper()
  194. {
  195. var backupPath = NewDataPath("BackupFolder");
  196. try
  197. {
  198. using (var store = NewDocumentStore())
  199. {
  200. var counter = 0;
  201. counter = InsertUsers(store, counter, 1000);
  202. counter = InsertDevelopers(store, counter, 2);
  203. counter = InsertUsers(store, counter, 1000);
  204. InsertDevelopers(store, counter, 2);
  205. WaitForIndexing(store);
  206. var dumper = new DatabaseDataDumper(store.SystemDatabase) { Options = { Limit = 5, Incremental = true } };
  207. dumper.Options.Filters.Add(
  208. new FilterSetting
  209. {
  210. Path = "@metadata.Raven-Entity-Name",
  211. Values = {"Developers"},
  212. ShouldMatch = true,
  213. });
  214. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  215. }
  216. VerifyDump(backupPath, store =>
  217. {
  218. using (var session = store.OpenSession())
  219. {
  220. Assert.Equal(4, session.Query<Developer>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  221. }
  222. });
  223. }
  224. finally
  225. {
  226. IOExtensions.DeleteDirectory(backupPath);
  227. }
  228. }
  229. [Fact, Trait("Category", "Smuggler")]
  230. public async Task CanPerformDumpWithLimitAndFilter_Smuggler()
  231. {
  232. var backupPath = NewDataPath("BackupFolder");
  233. try
  234. {
  235. using (var store = NewRemoteDocumentStore())
  236. {
  237. var counter = 0;
  238. counter = InsertUsers(store, counter, 1000);
  239. counter = InsertDevelopers(store, counter, 2);
  240. counter = InsertUsers(store, counter, 1000);
  241. InsertDevelopers(store, counter, 2);
  242. WaitForIndexing(store);
  243. var dumper = new SmugglerDatabaseApi { Options = { Limit = 5, Incremental = true } };
  244. dumper.Options.Filters.Add(
  245. new FilterSetting
  246. {
  247. Path = "@metadata.Raven-Entity-Name",
  248. Values = {"Developers"},
  249. ShouldMatch = true,
  250. });
  251. await dumper.ExportData(
  252. new SmugglerExportOptions<RavenConnectionStringOptions>
  253. {
  254. ToFile = backupPath,
  255. From = new RavenConnectionStringOptions
  256. {
  257. Url = "http://localhost:8079",
  258. DefaultDatabase = store.DefaultDatabase,
  259. }
  260. });
  261. }
  262. VerifyDump(backupPath, store =>
  263. {
  264. using (var session = store.OpenSession())
  265. {
  266. Assert.Equal(4, session.Query<Developer>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  267. }
  268. });
  269. }
  270. finally
  271. {
  272. IOExtensions.DeleteDirectory(backupPath);
  273. }
  274. }
  275. private static int InsertDevelopers(IDocumentStore store, int counter, int amount)
  276. {
  277. using (var session = store.OpenSession())
  278. {
  279. for (var j = 0; j < amount; j++)
  280. {
  281. counter++;
  282. session.Store(new Developer { Name = "Developer #" + (counter) });
  283. }
  284. session.SaveChanges();
  285. }
  286. return counter;
  287. }
  288. private static int InsertUsers(IDocumentStore store, int counter, int amount)
  289. {
  290. for (var i = 0; i < amount / 25; i++)
  291. {
  292. using (var session = store.OpenSession())
  293. {
  294. for (var j = 0; j < 25; j++)
  295. {
  296. counter++;
  297. var user = new User { Name = "User #" + counter };
  298. session.Store(user);
  299. }
  300. session.SaveChanges();
  301. }
  302. }
  303. return counter;
  304. }
  305. private static int InsertUsers(IDocumentStore store, int counter, int amount, out List<User> generatedUsers)
  306. {
  307. generatedUsers = new List<User>();
  308. for (var i = 0; i < amount / 25; i++)
  309. {
  310. using (var session = store.OpenSession())
  311. {
  312. for (var j = 0; j < 25; j++)
  313. {
  314. counter++;
  315. var user = new User { Name = "User #" + counter };
  316. generatedUsers.Add(user);
  317. session.Store(user);
  318. }
  319. session.SaveChanges();
  320. }
  321. }
  322. return counter;
  323. }
  324. [Fact, Trait("Category", "Smuggler")]
  325. public async Task CanDumpWhenHiddenDocs_Dumper()
  326. {
  327. var backupPath = NewDataPath("BackupFolder");
  328. try
  329. {
  330. using (var server = GetNewServer())
  331. {
  332. using (var store = new DocumentStore { Url = "http://localhost:8079" }.Initialize())
  333. {
  334. InsertHidenUsers(store, 2000);
  335. var user1 = store.DatabaseCommands.Get("users/1");
  336. Assert.Null(user1);
  337. InsertUsers(store, 1, 25);
  338. // now perform full backup
  339. var dumper = new DatabaseDataDumper(server.SystemDatabase) { Options = { Incremental = true } };
  340. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  341. }
  342. }
  343. VerifyDump(backupPath, store =>
  344. {
  345. using (var session = store.OpenSession())
  346. {
  347. Assert.Equal(25, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  348. }
  349. });
  350. }
  351. finally
  352. {
  353. IOExtensions.DeleteDirectory(backupPath);
  354. }
  355. }
  356. [Fact, Trait("Category", "Smuggler")]
  357. public async Task CanDumpWhenHiddenDocs_Smuggler()
  358. {
  359. var backupPath = NewDataPath("BackupFolder");
  360. try
  361. {
  362. using (NewRemoteDocumentStore())
  363. {
  364. using (var store = new DocumentStore {Url = "http://localhost:8079"})
  365. {
  366. store.Initialize();
  367. InsertHidenUsers(store, 2000);
  368. var user1 = store.DatabaseCommands.Get("users/1");
  369. Assert.Null(user1);
  370. InsertUsers(store, 1, 25);
  371. // now perform full backup
  372. var dumper = new SmugglerDatabaseApi { Options = { Incremental = true } };
  373. await dumper.ExportData(
  374. new SmugglerExportOptions<RavenConnectionStringOptions>
  375. {
  376. ToFile = backupPath,
  377. From = new RavenConnectionStringOptions
  378. {
  379. Url = "http://localhost:8079",
  380. DefaultDatabase = store.DefaultDatabase,
  381. }
  382. });
  383. }
  384. }
  385. VerifyDump(backupPath, store =>
  386. {
  387. using (var session = store.OpenSession())
  388. {
  389. Assert.Equal(25, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  390. }
  391. });
  392. }
  393. finally
  394. {
  395. IOExtensions.DeleteDirectory(backupPath);
  396. }
  397. }
  398. [Fact, Trait("Category", "Smuggler")]
  399. public async Task CanDumpEmptyDatabase_Dumper()
  400. {
  401. var backupPath = NewDataPath("BackupFolder");
  402. try
  403. {
  404. using (var server = GetNewServer(databaseName: Constants.SystemDatabase))
  405. {
  406. using (new DocumentStore { Url = "http://localhost:8079" }.Initialize())
  407. {
  408. // now perform full backup
  409. var dumper = new DatabaseDataDumper(server.SystemDatabase) { Options = { Incremental = true } };
  410. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  411. }
  412. }
  413. VerifyDump(backupPath, store => Assert.Equal(0, store.SystemDatabase.Documents.GetDocumentsAsJson(0, int.MaxValue, null, CancellationToken.None).Count()));
  414. }
  415. finally
  416. {
  417. IOExtensions.DeleteDirectory(backupPath);
  418. }
  419. }
  420. [Fact, Trait("Category", "Smuggler")]
  421. public async Task CanDumpEmptyDatabase_Smuggler()
  422. {
  423. var backupPath = NewDataPath("BackupFolder");
  424. try
  425. {
  426. using (var store = NewRemoteDocumentStore())
  427. {
  428. // now perform full backup
  429. var dumper = new SmugglerDatabaseApi { Options = {Incremental = true} };
  430. await dumper.ExportData(
  431. new SmugglerExportOptions<RavenConnectionStringOptions>
  432. {
  433. ToFile = backupPath,
  434. From = new RavenConnectionStringOptions
  435. {
  436. Url = "http://localhost:8079",
  437. DefaultDatabase = store.DefaultDatabase,
  438. }
  439. });
  440. }
  441. VerifyDump(backupPath, store => Assert.Equal(0, store.SystemDatabase.Documents.GetDocumentsAsJson(0,int.MaxValue, null, CancellationToken.None).Count()));
  442. }
  443. finally
  444. {
  445. IOExtensions.DeleteDirectory(backupPath);
  446. }
  447. }
  448. [Fact, Trait("Category", "Smuggler")]
  449. public async Task CanDumpWhenHiddenDocsWithLimit_Dumper()
  450. {
  451. var backupPath = NewDataPath("BackupFolder");
  452. using (var server = GetNewServer())
  453. {
  454. using (var store = new DocumentStore { Url = "http://localhost:8079" }.Initialize())
  455. {
  456. InsertHidenUsers(store, 2000);
  457. var user1 = store.DatabaseCommands.Get("users/1");
  458. Assert.Null(user1);
  459. InsertUsers(store, 1, 25);
  460. // now perform full backup
  461. var dumper = new DatabaseDataDumper(server.SystemDatabase) { Options = { Incremental = true } };
  462. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  463. }
  464. }
  465. VerifyDump(backupPath, store =>
  466. {
  467. using (var session = store.OpenSession())
  468. {
  469. Assert.Equal(25, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  470. }
  471. });
  472. IOExtensions.DeleteDirectory(backupPath);
  473. }
  474. [Fact, Trait("Category", "Smuggler")]
  475. public async Task CanDumpWhenHiddenDocsWithLimit_Smuggler()
  476. {
  477. var backupPath = NewDataPath("BackupFolder");
  478. try
  479. {
  480. using (GetNewServer())
  481. {
  482. using (var store = new DocumentStore { Url = "http://localhost:8079" })
  483. {
  484. store.Initialize();
  485. InsertHidenUsers(store, 2000);
  486. var user1 = store.DatabaseCommands.Get("users/1");
  487. Assert.Null(user1);
  488. InsertUsers(store, 1, 25);
  489. // now perform full backup
  490. var dumper = new SmugglerDatabaseApi { Options = { Incremental = true } };
  491. await dumper.ExportData(
  492. new SmugglerExportOptions<RavenConnectionStringOptions>
  493. {
  494. ToFile = backupPath,
  495. From = new RavenConnectionStringOptions
  496. {
  497. Url = "http://localhost:8079",
  498. DefaultDatabase = store.DefaultDatabase,
  499. }
  500. });
  501. }
  502. }
  503. VerifyDump(backupPath, store =>
  504. {
  505. using (var session = store.OpenSession())
  506. {
  507. Assert.Equal(25, session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).Count());
  508. }
  509. });
  510. }
  511. finally
  512. {
  513. IOExtensions.DeleteDirectory(backupPath);
  514. }
  515. }
  516. private static void InsertHidenUsers(IDocumentStore store, int amount)
  517. {
  518. for (var i = 0; i < amount; i++)
  519. {
  520. store.DatabaseCommands.Put("user/" + (i + 1), null, new RavenJObject(), RavenJObject.FromObject(new
  521. {
  522. hidden = true
  523. }));
  524. }
  525. }
  526. [Fact, Trait("Category", "Smuggler")]
  527. public async Task CanDumpAttachments_Dumper()
  528. {
  529. var backupPath = NewDataPath("BackupFolder");
  530. try
  531. {
  532. using (var store = NewDocumentStore())
  533. {
  534. InsertAttachments(store, 328);
  535. var dumper = new DatabaseDataDumper(store.SystemDatabase) { Options = { Incremental = true, BatchSize = 100 } };
  536. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  537. }
  538. VerifyDump(backupPath, store => Assert.Equal(328, store.DatabaseCommands.GetAttachmentHeadersStartingWith("user", 0, 500).Count()));
  539. }
  540. finally
  541. {
  542. IOExtensions.DeleteDirectory(backupPath);
  543. }
  544. }
  545. [Fact, Trait("Category", "Smuggler")]
  546. public async Task CanDumpAttachments_Smuggler()
  547. {
  548. var backupPath = NewDataPath("BackupFolder");
  549. try
  550. {
  551. using (var store = NewRemoteDocumentStore())
  552. {
  553. InsertAttachments(store, 328);
  554. var dumper = new SmugglerDatabaseApi { Options = { Incremental = true, BatchSize = 100 } };
  555. await dumper.ExportData(
  556. new SmugglerExportOptions<RavenConnectionStringOptions>
  557. {
  558. ToFile = backupPath,
  559. From = new RavenConnectionStringOptions
  560. {
  561. Url = "http://localhost:8079",
  562. DefaultDatabase = store.DefaultDatabase,
  563. }
  564. });
  565. }
  566. VerifyDump(backupPath, store => Assert.Equal(328, store.DatabaseCommands.GetAttachmentHeadersStartingWith("user", 0, 500).Count()));
  567. }
  568. finally
  569. {
  570. IOExtensions.DeleteDirectory(backupPath);
  571. }
  572. }
  573. [Fact, Trait("Category", "Smuggler")]
  574. public async Task CanDumpAttachmentsWithLimit_Dumper()
  575. {
  576. var backupPath = NewDataPath("BackupFolder");
  577. try
  578. {
  579. using (var store = NewDocumentStore())
  580. {
  581. InsertAttachments(store, 328);
  582. var dumper = new DatabaseDataDumper(store.SystemDatabase) { Options = { Incremental = true, BatchSize = 100, Limit = 206 } };
  583. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  584. }
  585. VerifyDump(backupPath, store => Assert.Equal(206, store.DatabaseCommands.GetAttachmentHeadersStartingWith("user", 0, 500).Count()));
  586. }
  587. finally
  588. {
  589. IOExtensions.DeleteDirectory(backupPath);
  590. }
  591. }
  592. [Fact, Trait("Category", "Smuggler")]
  593. public async Task CanDumpAttachmentsWithLimit_Smuggler()
  594. {
  595. var backupPath = NewDataPath("BackupFolder");
  596. try
  597. {
  598. using (var store = NewRemoteDocumentStore())
  599. {
  600. InsertAttachments(store, 328);
  601. var dumper = new SmugglerDatabaseApi { Options = { Incremental = true, BatchSize = 100, Limit = 206 } };
  602. await dumper.ExportData(
  603. new SmugglerExportOptions<RavenConnectionStringOptions>
  604. {
  605. ToFile = backupPath,
  606. From = new RavenConnectionStringOptions
  607. {
  608. Url = "http://localhost:8079",
  609. DefaultDatabase = store.DefaultDatabase,
  610. }
  611. });
  612. }
  613. VerifyDump(backupPath, store => Assert.Equal(206, store.DatabaseCommands.GetAttachmentHeadersStartingWith("user", 0, 500).Count()));
  614. }
  615. finally
  616. {
  617. IOExtensions.DeleteDirectory(backupPath);
  618. }
  619. }
  620. [Fact, Trait("Category", "Smuggler")]
  621. public async Task CanDumpAttachmentsEmpty_Dumper()
  622. {
  623. var backupPath = NewDataPath("BackupFolder");
  624. try
  625. {
  626. using (var store = NewDocumentStore())
  627. {
  628. var dumper = new DatabaseDataDumper(store.SystemDatabase) { Options = { Incremental = true, BatchSize = 100, Limit = 206 } };
  629. await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions> { ToFile = backupPath });
  630. }
  631. VerifyDump(backupPath, store => Assert.Equal(0, store.DatabaseCommands.GetAttachmentHeadersStartingWith("user", 0, 500).Count()));
  632. }
  633. finally
  634. {
  635. IOExtensions.DeleteDirectory(backupPath);
  636. }
  637. }
  638. [Fact, Trait("Category", "Smuggler")]
  639. public async Task CanDumpAttachmentsEmpty_Smuggler()
  640. {
  641. var backupPath = NewDataPath("BackupFolder");
  642. try
  643. {
  644. using (var store = NewRemoteDocumentStore())
  645. {
  646. var dumper = new SmugglerDatabaseApi { Options = { Incremental = true, BatchSize = 100, Limit = 206 } };
  647. await dumper.ExportData(
  648. new SmugglerExportOptions<RavenConnectionStringOptions>
  649. {
  650. ToFile = backupPath,
  651. From = new RavenConnectionStringOptions
  652. {
  653. Url = "http://localhost:8079",
  654. DefaultDatabase = store.DefaultDatabase,
  655. }
  656. });
  657. }
  658. VerifyDump(backupPath, store => Assert.Equal(0, store.DatabaseCommands.GetAttachmentHeadersStartingWith("user", 0, 500).Count()));
  659. }
  660. finally
  661. {
  662. IOExtensions.DeleteDirectory(backupPath);
  663. }
  664. }
  665. private static void InsertAttachments(IDocumentStore store, int amount)
  666. {
  667. var counter = 0;
  668. var data = new byte[] { 1, 2, 3, 4 };
  669. for (var i = 0; i < amount; i++)
  670. {
  671. var documentKey = "users/" + (++counter);
  672. store.DatabaseCommands.PutAttachment(documentKey, null, new MemoryStream(data), new RavenJObject());
  673. }
  674. }
  675. [Fact, Trait("Category", "Smuggler")]
  676. public async Task CanHandleDocumentExceptionsGracefully_Smuggler()
  677. {
  678. var backupPath = NewDataPath("BackupFolder");
  679. var server = GetNewServer(databaseName: Constants.SystemDatabase);
  680. var alreadyReset = false;
  681. var port = 8070;
  682. var forwarder = new ProxyServer(ref port, 8079)
  683. {
  684. VetoTransfer = (totalRead, buffer) =>
  685. {
  686. if (alreadyReset == false && totalRead > 25000)
  687. {
  688. alreadyReset = true;
  689. return true;
  690. }
  691. return false;
  692. }
  693. };
  694. try
  695. {
  696. string databaseName;
  697. using (var store = new DocumentStore
  698. {
  699. Url = "http://localhost:8079"
  700. })
  701. {
  702. databaseName = store.DefaultDatabase;
  703. store.Initialize();
  704. InsertUsers(store, 0, 2000);
  705. }
  706. var dumper = new SmugglerDatabaseApi { Options = { Limit = 1900, Incremental = true } };
  707. var allDocs = new List<RavenJObject>();
  708. OperationState exportResult = null;
  709. try
  710. {
  711. exportResult = await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions>
  712. {
  713. ToFile = backupPath,
  714. From = new RavenConnectionStringOptions
  715. {
  716. Url = "http://localhost:" + port,
  717. DefaultDatabase = databaseName,
  718. }
  719. });
  720. Assert.False(true, "Previous op should throw.");
  721. }
  722. catch (SmugglerExportException e)
  723. {
  724. exportResult = new OperationState
  725. {
  726. FilePath = e.File
  727. };
  728. }
  729. using (var fileSteam = new FileStream(exportResult.FilePath, FileMode.Open))
  730. using (var stream = new GZipStream(fileSteam, CompressionMode.Decompress))
  731. {
  732. var chunk1 = RavenJToken.TryLoad(stream) as RavenJObject;
  733. var doc1 = chunk1["Docs"] as RavenJArray;
  734. allDocs.AddRange(doc1.Values<RavenJObject>());
  735. }
  736. exportResult = await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions>
  737. {
  738. ToFile = backupPath,
  739. From = new RavenConnectionStringOptions
  740. {
  741. Url = "http://localhost:8070",
  742. DefaultDatabase = databaseName,
  743. }
  744. });
  745. using (var fileStream = new FileStream(exportResult.FilePath, FileMode.Open))
  746. using (var stream = new GZipStream(fileStream, CompressionMode.Decompress))
  747. {
  748. var chunk2 = RavenJToken.TryLoad(stream) as RavenJObject;
  749. var doc2 = chunk2["Docs"] as RavenJArray;
  750. allDocs.AddRange(doc2.Values<RavenJObject>());
  751. }
  752. Assert.Equal(2000, allDocs.Count(d => (d.Value<string>("Name") ?? String.Empty).StartsWith("User")));
  753. }
  754. finally
  755. {
  756. forwarder.Dispose();
  757. server.Dispose();
  758. IOExtensions.DeleteDirectory(backupPath);
  759. }
  760. }
  761. [Fact, Trait("Category", "Smuggler")]
  762. public async Task CanHandleAttachmentExceptionsGracefully_Smuggler()
  763. {
  764. var backupPath = NewDataPath("BackupFolder");
  765. var server = GetNewServer();
  766. int allowDownload = 0;
  767. var port = 8070;
  768. var forwarder = new ProxyServer(ref port, 8079)
  769. {
  770. VetoTransfer = (totalRead, buffer) =>
  771. {
  772. var payload = System.Text.Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count);
  773. return payload.Contains("GET /static/users/678 ") && Thread.VolatileRead(ref allowDownload) == 0;
  774. }
  775. };
  776. try
  777. {
  778. string databaseName;
  779. using (var store = new DocumentStore
  780. {
  781. Url = "http://localhost:8079"
  782. })
  783. {
  784. databaseName = store.DefaultDatabase;
  785. store.Initialize();
  786. InsertAttachments(store, 2000);
  787. }
  788. var dumper = new SmugglerDatabaseApi { Options = { Limit = 1500, Incremental = true } };
  789. var allAttachments = new List<RavenJObject>();
  790. OperationState exportResult = null;
  791. try
  792. {
  793. exportResult = dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions>
  794. {
  795. ToFile = backupPath,
  796. From = new RavenConnectionStringOptions
  797. {
  798. Url = "http://localhost:" + port,
  799. DefaultDatabase = databaseName,
  800. }
  801. }).Result;
  802. Assert.False(true, "Previous op should throw.");
  803. }
  804. catch (AggregateException e)
  805. {
  806. var extractSingleInnerException = e.ExtractSingleInnerException() as SmugglerExportException;
  807. if (extractSingleInnerException == null)
  808. throw;
  809. var inner = extractSingleInnerException;
  810. exportResult = new OperationState
  811. {
  812. FilePath = inner.File
  813. };
  814. }
  815. Interlocked.Increment(ref allowDownload);
  816. using (var fileStream = new FileStream(exportResult.FilePath, FileMode.Open))
  817. using (var stream = new GZipStream(fileStream, CompressionMode.Decompress))
  818. {
  819. var chunk1 = RavenJToken.TryLoad(stream) as RavenJObject;
  820. var att1 = chunk1["Attachments"] as RavenJArray;
  821. allAttachments.AddRange(att1.Values<RavenJObject>());
  822. }
  823. exportResult = await dumper.ExportData(new SmugglerExportOptions<RavenConnectionStringOptions>
  824. {
  825. ToFile = backupPath,
  826. From = new RavenConnectionStringOptions
  827. {
  828. Url = "http://localhost:8070",
  829. DefaultDatabase = databaseName,
  830. }
  831. });
  832. using (var fileStream = new FileStream(exportResult.FilePath, FileMode.Open))
  833. using (var stream = new GZipStream(fileStream, CompressionMode.Decompress))
  834. {
  835. var chunk2 = RavenJToken.TryLoad(stream) as RavenJObject;
  836. var attr2 = chunk2["Attachments"] as RavenJArray;
  837. allAttachments.AddRange(attr2.Values<RavenJObject>());
  838. }
  839. Assert.Equal(2000, allAttachments.Count());
  840. }
  841. finally
  842. {
  843. IOExtensions.DeleteDirectory(backupPath);
  844. forwarder.Dispose();
  845. server.Dispose();
  846. }
  847. }
  848. }
  849. }