ArchiverTests.cs 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.IO;
  30. using System.Reflection;
  31. using System.Threading;
  32. using log4net.Config;
  33. using Nini.Config;
  34. using NUnit.Framework;
  35. using OpenMetaverse;
  36. using OpenMetaverse.Assets;
  37. using OpenSim.Framework;
  38. using OpenSim.Framework.Serialization;
  39. using OpenSim.Framework.Serialization.External;
  40. using OpenSim.Region.CoreModules.World.Land;
  41. using OpenSim.Region.CoreModules.World.Serialiser;
  42. using OpenSim.Region.CoreModules.World.Terrain;
  43. using OpenSim.Region.Framework.Scenes;
  44. using OpenSim.Region.Framework.Scenes.Serialization;
  45. using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
  46. using OpenSim.Tests.Common;
  47. using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
  48. using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader;
  49. using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter;
  50. using RegionSettings = OpenSim.Framework.RegionSettings;
  51. using OpenSim.Region.Framework.Interfaces;
  52. namespace OpenSim.Region.CoreModules.World.Archiver.Tests
  53. {
  54. [TestFixture]
  55. public class ArchiverTests : OpenSimTestCase
  56. {
  57. private Guid m_lastRequestId;
  58. private string m_lastErrorMessage;
  59. protected SceneHelpers m_sceneHelpers;
  60. protected TestScene m_scene;
  61. protected ArchiverModule m_archiverModule;
  62. protected SerialiserModule m_serialiserModule;
  63. protected TaskInventoryItem m_soundItem;
  64. private AutoResetEvent m_oarEvent = new AutoResetEvent(false);
  65. [SetUp]
  66. public override void SetUp()
  67. {
  68. base.SetUp();
  69. m_archiverModule = new ArchiverModule();
  70. m_serialiserModule = new SerialiserModule();
  71. TerrainModule terrainModule = new TerrainModule();
  72. m_sceneHelpers = new SceneHelpers();
  73. m_scene = m_sceneHelpers.SetupScene();
  74. SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, m_serialiserModule, terrainModule);
  75. }
  76. private void LoadCompleted(Guid requestId, List<UUID> loadedScenes, string errorMessage)
  77. {
  78. lock (this)
  79. {
  80. m_lastRequestId = requestId;
  81. m_lastErrorMessage = errorMessage;
  82. Console.WriteLine("About to pulse ArchiverTests on LoadCompleted");
  83. m_oarEvent.Set();
  84. }
  85. }
  86. private void SaveCompleted(Guid requestId, string errorMessage)
  87. {
  88. lock (this)
  89. {
  90. m_lastRequestId = requestId;
  91. m_lastErrorMessage = errorMessage;
  92. Console.WriteLine("About to pulse ArchiverTests on SaveCompleted");
  93. m_oarEvent.Set();
  94. }
  95. }
  96. protected SceneObjectPart CreateSceneObjectPart1()
  97. {
  98. string partName = "My Little Pony";
  99. UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
  100. PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
  101. Vector3 groupPosition = new Vector3(10, 20, 30);
  102. Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
  103. rotationOffset.Normalize();
  104. // Vector3 offsetPosition = new Vector3(5, 10, 15);
  105. return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, Vector3.Zero) { Name = partName };
  106. }
  107. protected SceneObjectPart CreateSceneObjectPart2()
  108. {
  109. string partName = "Action Man";
  110. UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
  111. PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
  112. Vector3 groupPosition = new Vector3(90, 80, 70);
  113. Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
  114. rotationOffset.Normalize();
  115. Vector3 offsetPosition = new Vector3(20, 25, 30);
  116. return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
  117. }
  118. private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
  119. {
  120. SceneObjectPart part1 = CreateSceneObjectPart1();
  121. sog1 = new SceneObjectGroup(part1);
  122. scene.AddNewSceneObject(sog1, false);
  123. AssetNotecard nc = new AssetNotecard();
  124. nc.BodyText = "Hello World!";
  125. nc.Encode();
  126. ncAssetUuid = UUID.Random();
  127. UUID ncItemUuid = UUID.Random();
  128. AssetBase ncAsset
  129. = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
  130. m_scene.AssetService.Store(ncAsset);
  131. TaskInventoryItem ncItem
  132. = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
  133. SceneObjectPart part2 = CreateSceneObjectPart2();
  134. sog2 = new SceneObjectGroup(part2);
  135. part2.Inventory.AddInventoryItem(ncItem, true);
  136. scene.AddNewSceneObject(sog2, false);
  137. }
  138. private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid)
  139. {
  140. using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName))
  141. {
  142. using (BinaryReader br = new BinaryReader(resource))
  143. {
  144. // FIXME: Use the inspector instead
  145. soundData = br.ReadBytes(99999999);
  146. soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
  147. string soundAssetFileName
  148. = ArchiveConstants.ASSETS_PATH + soundUuid
  149. + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
  150. tar.WriteFile(soundAssetFileName, soundData);
  151. /*
  152. AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
  153. scene.AssetService.Store(soundAsset);
  154. asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
  155. */
  156. }
  157. }
  158. }
  159. /// <summary>
  160. /// Test saving an OpenSim Region Archive.
  161. /// </summary>
  162. [Test]
  163. public void TestSaveOar()
  164. {
  165. TestHelpers.InMethod();
  166. // log4net.Config.XmlConfigurator.Configure();
  167. SceneObjectGroup sog1;
  168. SceneObjectGroup sog2;
  169. UUID ncAssetUuid;
  170. CreateTestObjects(m_scene, out sog1, out sog2, out ncAssetUuid);
  171. MemoryStream archiveWriteStream = new MemoryStream();
  172. m_scene.EventManager.OnOarFileSaved += SaveCompleted;
  173. Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
  174. m_oarEvent.Reset();
  175. m_archiverModule.ArchiveRegion(archiveWriteStream, requestId);
  176. //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
  177. //while (assetServer.HasWaitingRequests())
  178. // assetServer.ProcessNextRequest();
  179. m_oarEvent.WaitOne(60000);
  180. Assert.That(m_lastRequestId, Is.EqualTo(requestId));
  181. byte[] archive = archiveWriteStream.ToArray();
  182. MemoryStream archiveReadStream = new MemoryStream(archive);
  183. TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
  184. bool gotNcAssetFile = false;
  185. string expectedNcAssetFileName = string.Format("{0}_{1}", ncAssetUuid, "notecard.txt");
  186. List<string> foundPaths = new List<string>();
  187. List<string> expectedPaths = new List<string>();
  188. expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog1));
  189. expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
  190. string filePath;
  191. TarArchiveReader.TarEntryType tarEntryType;
  192. byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
  193. Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
  194. Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
  195. ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
  196. arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
  197. Assert.That(arr.ControlFileLoaded, Is.True);
  198. while (tar.ReadEntry(out filePath, out tarEntryType) != null)
  199. {
  200. if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
  201. {
  202. string fileName = filePath.Remove(0, ArchiveConstants.ASSETS_PATH.Length);
  203. Assert.That(fileName, Is.EqualTo(expectedNcAssetFileName));
  204. gotNcAssetFile = true;
  205. }
  206. else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
  207. {
  208. foundPaths.Add(filePath);
  209. }
  210. }
  211. Assert.That(gotNcAssetFile, Is.True, "No notecard asset file in archive");
  212. Assert.That(foundPaths, Is.EquivalentTo(expectedPaths));
  213. // TODO: Test presence of more files and contents of files.
  214. }
  215. /// <summary>
  216. /// Test saving an OpenSim Region Archive with the no assets option
  217. /// </summary>
  218. [Test]
  219. public void TestSaveOarNoAssets()
  220. {
  221. TestHelpers.InMethod();
  222. // log4net.Config.XmlConfigurator.Configure();
  223. SceneObjectPart part1 = CreateSceneObjectPart1();
  224. SceneObjectGroup sog1 = new SceneObjectGroup(part1);
  225. m_scene.AddNewSceneObject(sog1, false);
  226. SceneObjectPart part2 = CreateSceneObjectPart2();
  227. AssetNotecard nc = new AssetNotecard();
  228. nc.BodyText = "Hello World!";
  229. nc.Encode();
  230. UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
  231. UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
  232. AssetBase ncAsset
  233. = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
  234. m_scene.AssetService.Store(ncAsset);
  235. SceneObjectGroup sog2 = new SceneObjectGroup(part2);
  236. TaskInventoryItem ncItem
  237. = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
  238. part2.Inventory.AddInventoryItem(ncItem, true);
  239. m_scene.AddNewSceneObject(sog2, false);
  240. MemoryStream archiveWriteStream = new MemoryStream();
  241. Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
  242. Dictionary<string, Object> options = new Dictionary<string, Object>();
  243. options.Add("noassets", true);
  244. m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
  245. // Don't wait for completion - with --noassets save oar happens synchronously
  246. // Monitor.Wait(this, 60000);
  247. Assert.That(m_lastRequestId, Is.EqualTo(requestId));
  248. byte[] archive = archiveWriteStream.ToArray();
  249. MemoryStream archiveReadStream = new MemoryStream(archive);
  250. TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
  251. List<string> foundPaths = new List<string>();
  252. List<string> expectedPaths = new List<string>();
  253. expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog1));
  254. expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
  255. string filePath;
  256. TarArchiveReader.TarEntryType tarEntryType;
  257. byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
  258. Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
  259. Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
  260. ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
  261. arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
  262. Assert.That(arr.ControlFileLoaded, Is.True);
  263. while (tar.ReadEntry(out filePath, out tarEntryType) != null)
  264. {
  265. if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
  266. {
  267. Assert.Fail("Asset was found in saved oar of TestSaveOarNoAssets()");
  268. }
  269. else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
  270. {
  271. foundPaths.Add(filePath);
  272. }
  273. }
  274. Assert.That(foundPaths, Is.EquivalentTo(expectedPaths));
  275. // TODO: Test presence of more files and contents of files.
  276. }
  277. /// <summary>
  278. /// Test loading an OpenSim Region Archive.
  279. /// </summary>
  280. [Test]
  281. public void TestLoadOar()
  282. {
  283. TestHelpers.InMethod();
  284. // log4net.Config.XmlConfigurator.Configure();
  285. MemoryStream archiveWriteStream = new MemoryStream();
  286. TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
  287. // Put in a random blank directory to check that this doesn't upset the load process
  288. tar.WriteDir("ignoreme");
  289. // Also check that direct entries which will also have a file entry containing that directory doesn't
  290. // upset load
  291. tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
  292. tar.WriteFile(
  293. ArchiveConstants.CONTROL_FILE_PATH,
  294. new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
  295. SceneObjectPart part1 = CreateSceneObjectPart1();
  296. part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
  297. part1.SitTargetPosition = new Vector3(1, 2, 3);
  298. SceneObjectGroup object1 = new SceneObjectGroup(part1);
  299. // Let's put some inventory items into our object
  300. string soundItemName = "sound-item1";
  301. UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
  302. Type type = GetType();
  303. Assembly assembly = type.Assembly;
  304. string soundDataResourceName = null;
  305. string[] names = assembly.GetManifestResourceNames();
  306. foreach (string name in names)
  307. {
  308. if (name.EndsWith(".Resources.test-sound.wav"))
  309. soundDataResourceName = name;
  310. }
  311. Assert.That(soundDataResourceName, Is.Not.Null);
  312. byte[] soundData;
  313. UUID soundUuid;
  314. CreateSoundAsset(tar, assembly, soundDataResourceName, out soundData, out soundUuid);
  315. TaskInventoryItem item1
  316. = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
  317. part1.Inventory.AddInventoryItem(item1, true);
  318. m_scene.AddNewSceneObject(object1, false);
  319. string object1FileName = string.Format(
  320. "{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
  321. part1.Name,
  322. Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
  323. part1.UUID);
  324. tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1));
  325. tar.Close();
  326. MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
  327. m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
  328. m_oarEvent.Reset();
  329. m_archiverModule.DearchiveRegion(archiveReadStream);
  330. m_oarEvent.WaitOne(60000);
  331. Assert.That(m_lastErrorMessage, Is.Null);
  332. TestLoadedRegion(part1, soundItemName, soundData);
  333. }
  334. /// <summary>
  335. /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
  336. /// 2 can come after 3).
  337. /// </summary>
  338. [Test]
  339. public void TestLoadOarUnorderedParts()
  340. {
  341. TestHelpers.InMethod();
  342. UUID ownerId = TestHelpers.ParseTail(0xaaaa);
  343. MemoryStream archiveWriteStream = new MemoryStream();
  344. TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
  345. tar.WriteFile(
  346. ArchiveConstants.CONTROL_FILE_PATH,
  347. new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
  348. SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
  349. SceneObjectPart sop2
  350. = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId);
  351. SceneObjectPart sop3
  352. = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId);
  353. // Add the parts so they will be written out in reverse order to the oar
  354. sog1.AddPart(sop3);
  355. sop3.LinkNum = 3;
  356. sog1.AddPart(sop2);
  357. sop2.LinkNum = 2;
  358. tar.WriteFile(
  359. ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition),
  360. SceneObjectSerializer.ToXml2Format(sog1));
  361. tar.Close();
  362. MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
  363. m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
  364. m_oarEvent.Reset();
  365. m_archiverModule.DearchiveRegion(archiveReadStream);
  366. m_oarEvent.WaitOne(60000);
  367. Assert.That(m_lastErrorMessage, Is.Null);
  368. SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2");
  369. Assert.That(part2.LinkNum, Is.EqualTo(2));
  370. SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3");
  371. Assert.That(part3.LinkNum, Is.EqualTo(3));
  372. }
  373. /// <summary>
  374. /// Test loading an OpenSim Region Archive saved with the --publish option.
  375. /// </summary>
  376. [Test]
  377. public void TestLoadPublishedOar()
  378. {
  379. TestHelpers.InMethod();
  380. // log4net.Config.XmlConfigurator.Configure();
  381. SceneObjectPart part1 = CreateSceneObjectPart1();
  382. SceneObjectGroup sog1 = new SceneObjectGroup(part1);
  383. m_scene.AddNewSceneObject(sog1, false);
  384. SceneObjectPart part2 = CreateSceneObjectPart2();
  385. AssetNotecard nc = new AssetNotecard();
  386. nc.BodyText = "Hello World!";
  387. nc.Encode();
  388. UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
  389. UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
  390. AssetBase ncAsset
  391. = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
  392. m_scene.AssetService.Store(ncAsset);
  393. SceneObjectGroup sog2 = new SceneObjectGroup(part2);
  394. TaskInventoryItem ncItem
  395. = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
  396. part2.Inventory.AddInventoryItem(ncItem, true);
  397. m_scene.AddNewSceneObject(sog2, false);
  398. MemoryStream archiveWriteStream = new MemoryStream();
  399. m_scene.EventManager.OnOarFileSaved += SaveCompleted;
  400. Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
  401. m_oarEvent.Reset();
  402. m_archiverModule.ArchiveRegion(
  403. archiveWriteStream, requestId, new Dictionary<string, Object>() { { "wipe-owners", Boolean.TrueString } });
  404. m_oarEvent.WaitOne(60000);
  405. Assert.That(m_lastRequestId, Is.EqualTo(requestId));
  406. byte[] archive = archiveWriteStream.ToArray();
  407. MemoryStream archiveReadStream = new MemoryStream(archive);
  408. {
  409. UUID estateOwner = TestHelpers.ParseTail(0x4747);
  410. UUID objectOwner = TestHelpers.ParseTail(0x15);
  411. // Reload to new scene
  412. ArchiverModule archiverModule = new ArchiverModule();
  413. SerialiserModule serialiserModule = new SerialiserModule();
  414. TerrainModule terrainModule = new TerrainModule();
  415. SceneHelpers m_sceneHelpers2 = new SceneHelpers();
  416. TestScene scene2 = m_sceneHelpers2.SetupScene();
  417. SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule);
  418. // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is
  419. // behaving correctly
  420. UserAccountHelpers.CreateUserWithInventory(scene2, objectOwner);
  421. scene2.RegionInfo.EstateSettings.EstateOwner = estateOwner;
  422. scene2.EventManager.OnOarFileLoaded += LoadCompleted;
  423. m_oarEvent.Reset();
  424. archiverModule.DearchiveRegion(archiveReadStream);
  425. m_oarEvent.WaitOne(60000);
  426. Assert.That(m_lastErrorMessage, Is.Null);
  427. SceneObjectGroup loadedSog = scene2.GetSceneObjectGroup(part1.Name);
  428. Assert.That(loadedSog.OwnerID, Is.EqualTo(estateOwner));
  429. Assert.That(loadedSog.LastOwnerID, Is.EqualTo(estateOwner));
  430. }
  431. }
  432. /// <summary>
  433. /// Test OAR loading where the land parcel is group deeded.
  434. /// </summary>
  435. /// <remarks>
  436. /// In this situation, the owner ID is set to the group ID.
  437. /// </remarks>
  438. [Test]
  439. public void TestLoadOarDeededLand()
  440. {
  441. TestHelpers.InMethod();
  442. // TestHelpers.EnableLogging();
  443. UUID landID = TestHelpers.ParseTail(0x10);
  444. MockGroupsServicesConnector groupsService = new MockGroupsServicesConnector();
  445. IConfigSource configSource = new IniConfigSource();
  446. IConfig config = configSource.AddConfig("Groups");
  447. config.Set("Enabled", true);
  448. config.Set("Module", "GroupsModule");
  449. config.Set("DebugEnabled", true);
  450. SceneHelpers.SetupSceneModules(
  451. m_scene, configSource, new object[] { new GroupsModule(), groupsService, new LandManagementModule() });
  452. // Create group in scene for loading
  453. // FIXME: For now we'll put up with the issue that we'll get a group ID that varies across tests.
  454. UUID groupID
  455. = groupsService.CreateGroup(UUID.Zero, "group1", "", true, UUID.Zero, 3, true, true, true, UUID.Zero);
  456. // Construct OAR
  457. MemoryStream oarStream = new MemoryStream();
  458. TarArchiveWriter tar = new TarArchiveWriter(oarStream);
  459. tar.WriteDir(ArchiveConstants.LANDDATA_PATH);
  460. tar.WriteFile(
  461. ArchiveConstants.CONTROL_FILE_PATH,
  462. new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
  463. LandObject lo = new LandObject(groupID, true, m_scene);
  464. lo.SetLandBitmap(lo.BasicFullRegionLandBitmap());
  465. LandData ld = lo.LandData;
  466. ld.GlobalID = landID;
  467. string ldPath = ArchiveConstants.CreateOarLandDataPath(ld);
  468. Dictionary<string, object> options = new Dictionary<string, object>();
  469. tar.WriteFile(ldPath, LandDataSerializer.Serialize(ld, options));
  470. tar.Close();
  471. oarStream = new MemoryStream(oarStream.ToArray());
  472. // Load OAR
  473. m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
  474. m_oarEvent.Reset();
  475. m_archiverModule.DearchiveRegion(oarStream);
  476. m_oarEvent.WaitOne(60000);
  477. ILandObject rLo = m_scene.LandChannel.GetLandObject(16, 16);
  478. LandData rLd = rLo.LandData;
  479. Assert.That(rLd.GlobalID, Is.EqualTo(landID));
  480. Assert.That(rLd.OwnerID, Is.EqualTo(groupID));
  481. Assert.That(rLd.GroupID, Is.EqualTo(groupID));
  482. Assert.That(rLd.IsGroupOwned, Is.EqualTo(true));
  483. }
  484. /// <summary>
  485. /// Test loading the region settings of an OpenSim Region Archive.
  486. /// </summary>
  487. [Test]
  488. public void TestLoadOarRegionSettings()
  489. {
  490. TestHelpers.InMethod();
  491. //log4net.Config.XmlConfigurator.Configure();
  492. MemoryStream archiveWriteStream = new MemoryStream();
  493. TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
  494. tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
  495. tar.WriteFile(
  496. ArchiveConstants.CONTROL_FILE_PATH,
  497. new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
  498. RegionSettings rs = new RegionSettings();
  499. rs.AgentLimit = 17;
  500. rs.AllowDamage = true;
  501. rs.AllowLandJoinDivide = true;
  502. rs.AllowLandResell = true;
  503. rs.BlockFly = true;
  504. rs.BlockShowInSearch = true;
  505. rs.BlockTerraform = true;
  506. rs.DisableCollisions = true;
  507. rs.DisablePhysics = true;
  508. rs.DisableScripts = true;
  509. rs.Elevation1NW = 15.9;
  510. rs.Elevation1NE = 45.3;
  511. rs.Elevation1SE = 49;
  512. rs.Elevation1SW = 1.9;
  513. rs.Elevation2NW = 4.5;
  514. rs.Elevation2NE = 19.2;
  515. rs.Elevation2SE = 9.2;
  516. rs.Elevation2SW = 2.1;
  517. rs.FixedSun = true;
  518. rs.SunPosition = 12.0;
  519. rs.ObjectBonus = 1.4;
  520. rs.RestrictPushing = true;
  521. rs.TerrainLowerLimit = 0.4;
  522. rs.TerrainRaiseLimit = 17.9;
  523. rs.TerrainTexture1 = UUID.Parse("00000000-0000-0000-0000-000000000020");
  524. rs.TerrainTexture2 = UUID.Parse("00000000-0000-0000-0000-000000000040");
  525. rs.TerrainTexture3 = UUID.Parse("00000000-0000-0000-0000-000000000060");
  526. rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
  527. rs.UseEstateSun = true;
  528. rs.WaterHeight = 23;
  529. rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111");
  530. rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33"));
  531. tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs, null, new EstateSettings()));
  532. tar.Close();
  533. MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
  534. m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
  535. m_oarEvent.Reset();
  536. m_archiverModule.DearchiveRegion(archiveReadStream);
  537. m_oarEvent.WaitOne(60000);
  538. Assert.That(m_lastErrorMessage, Is.Null);
  539. RegionSettings loadedRs = m_scene.RegionInfo.RegionSettings;
  540. Assert.That(loadedRs.AgentLimit, Is.EqualTo(17));
  541. Assert.That(loadedRs.AllowDamage, Is.True);
  542. Assert.That(loadedRs.AllowLandJoinDivide, Is.True);
  543. Assert.That(loadedRs.AllowLandResell, Is.True);
  544. Assert.That(loadedRs.BlockFly, Is.True);
  545. Assert.That(loadedRs.BlockShowInSearch, Is.True);
  546. Assert.That(loadedRs.BlockTerraform, Is.True);
  547. Assert.That(loadedRs.DisableCollisions, Is.True);
  548. Assert.That(loadedRs.DisablePhysics, Is.True);
  549. Assert.That(loadedRs.DisableScripts, Is.True);
  550. Assert.That(loadedRs.Elevation1NW, Is.EqualTo(15.9));
  551. Assert.That(loadedRs.Elevation1NE, Is.EqualTo(45.3));
  552. Assert.That(loadedRs.Elevation1SE, Is.EqualTo(49));
  553. Assert.That(loadedRs.Elevation1SW, Is.EqualTo(1.9));
  554. Assert.That(loadedRs.Elevation2NW, Is.EqualTo(4.5));
  555. Assert.That(loadedRs.Elevation2NE, Is.EqualTo(19.2));
  556. Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2));
  557. Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1));
  558. Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4));
  559. Assert.That(loadedRs.RestrictPushing, Is.True);
  560. Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4));
  561. Assert.That(loadedRs.TerrainRaiseLimit, Is.EqualTo(17.9));
  562. Assert.That(loadedRs.TerrainTexture1, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000020")));
  563. Assert.That(loadedRs.TerrainTexture2, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000040")));
  564. Assert.That(loadedRs.TerrainTexture3, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000060")));
  565. Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080")));
  566. Assert.That(loadedRs.WaterHeight, Is.EqualTo(23));
  567. Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID
  568. Assert.AreEqual(0, loadedRs.SpawnPoints().Count);
  569. }
  570. /// <summary>
  571. /// Test merging an OpenSim Region Archive into an existing scene
  572. /// </summary>
  573. //[Test]
  574. public void TestMergeOar()
  575. {
  576. TestHelpers.InMethod();
  577. //XmlConfigurator.Configure();
  578. MemoryStream archiveWriteStream = new MemoryStream();
  579. // string part2Name = "objectMerge";
  580. // PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
  581. // Vector3 part2GroupPosition = new Vector3(90, 80, 70);
  582. // Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
  583. // Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
  584. SceneObjectPart part2 = CreateSceneObjectPart2();
  585. // Create an oar file that we can use for the merge
  586. {
  587. ArchiverModule archiverModule = new ArchiverModule();
  588. SerialiserModule serialiserModule = new SerialiserModule();
  589. TerrainModule terrainModule = new TerrainModule();
  590. Scene scene = m_sceneHelpers.SetupScene();
  591. SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
  592. m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
  593. // Write out this scene
  594. scene.EventManager.OnOarFileSaved += SaveCompleted;
  595. m_oarEvent.Reset();
  596. m_archiverModule.ArchiveRegion(archiveWriteStream);
  597. m_oarEvent.WaitOne(60000);
  598. }
  599. {
  600. SceneObjectPart part1 = CreateSceneObjectPart1();
  601. m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
  602. // Merge in the archive we created earlier
  603. byte[] archive = archiveWriteStream.ToArray();
  604. MemoryStream archiveReadStream = new MemoryStream(archive);
  605. m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
  606. Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
  607. archiveOptions.Add("merge", null);
  608. m_oarEvent.Reset();
  609. m_archiverModule.DearchiveRegion(archiveReadStream, Guid.Empty, archiveOptions);
  610. m_oarEvent.WaitOne(60000);
  611. SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name);
  612. Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
  613. Assert.That(object1Existing.Name, Is.EqualTo(part1.Name), "object1 names not identical after merge");
  614. Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal after merge");
  615. SceneObjectPart object2PartMerged = m_scene.GetSceneObjectPart(part2.Name);
  616. Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge");
  617. Assert.That(object2PartMerged.Name, Is.EqualTo(part2.Name), "object2 names not identical after merge");
  618. Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge");
  619. }
  620. }
  621. /// <summary>
  622. /// Test saving a multi-region OAR.
  623. /// </summary>
  624. [Test]
  625. public void TestSaveMultiRegionOar()
  626. {
  627. TestHelpers.InMethod();
  628. // Create test regions
  629. int WIDTH = 2;
  630. int HEIGHT = 2;
  631. List<Scene> scenes = new List<Scene>();
  632. // Maps (Directory in OAR file -> scene)
  633. Dictionary<string, Scene> regionPaths = new Dictionary<string, Scene>();
  634. // Maps (Scene -> expected object paths)
  635. Dictionary<UUID, List<string>> expectedPaths = new Dictionary<UUID, List<string>>();
  636. // List of expected assets
  637. List<UUID> expectedAssets = new List<UUID>();
  638. for (uint y = 0; y < HEIGHT; y++)
  639. {
  640. for (uint x = 0; x < WIDTH; x++)
  641. {
  642. Scene scene;
  643. if (x == 0 && y == 0)
  644. {
  645. scene = m_scene; // this scene was already created in SetUp()
  646. }
  647. else
  648. {
  649. scene = m_sceneHelpers.SetupScene(string.Format("Unit test region {0}", (y * WIDTH) + x + 1), UUID.Random(), 1000 + x, 1000 + y);
  650. SceneHelpers.SetupSceneModules(scene, new ArchiverModule(), m_serialiserModule, new TerrainModule());
  651. }
  652. scenes.Add(scene);
  653. string dir = String.Format("{0}_{1}_{2}", x + 1, y + 1, scene.RegionInfo.RegionName.Replace(" ", "_"));
  654. regionPaths[dir] = scene;
  655. SceneObjectGroup sog1;
  656. SceneObjectGroup sog2;
  657. UUID ncAssetUuid;
  658. CreateTestObjects(scene, out sog1, out sog2, out ncAssetUuid);
  659. expectedPaths[scene.RegionInfo.RegionID] = new List<string>();
  660. expectedPaths[scene.RegionInfo.RegionID].Add(ArchiveHelpers.CreateObjectPath(sog1));
  661. expectedPaths[scene.RegionInfo.RegionID].Add(ArchiveHelpers.CreateObjectPath(sog2));
  662. expectedAssets.Add(ncAssetUuid);
  663. }
  664. }
  665. // Save OAR
  666. MemoryStream archiveWriteStream = new MemoryStream();
  667. Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
  668. Dictionary<string, Object> options = new Dictionary<string, Object>();
  669. options.Add("all", true);
  670. m_scene.EventManager.OnOarFileSaved += SaveCompleted;
  671. m_oarEvent.Reset();
  672. m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
  673. m_oarEvent.WaitOne(60000);
  674. // Check that the OAR contains the expected data
  675. Assert.That(m_lastRequestId, Is.EqualTo(requestId));
  676. byte[] archive = archiveWriteStream.ToArray();
  677. MemoryStream archiveReadStream = new MemoryStream(archive);
  678. TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
  679. Dictionary<UUID, List<string>> foundPaths = new Dictionary<UUID, List<string>>();
  680. List<UUID> foundAssets = new List<UUID>();
  681. foreach (Scene scene in scenes)
  682. {
  683. foundPaths[scene.RegionInfo.RegionID] = new List<string>();
  684. }
  685. string filePath;
  686. TarArchiveReader.TarEntryType tarEntryType;
  687. byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
  688. Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
  689. Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
  690. ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
  691. arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
  692. Assert.That(arr.ControlFileLoaded, Is.True);
  693. while (tar.ReadEntry(out filePath, out tarEntryType) != null)
  694. {
  695. if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
  696. {
  697. // Assets are shared, so this file doesn't belong to any specific region.
  698. string fileName = filePath.Remove(0, ArchiveConstants.ASSETS_PATH.Length);
  699. if (fileName.EndsWith("_notecard.txt"))
  700. foundAssets.Add(UUID.Parse(fileName.Substring(0, fileName.Length - "_notecard.txt".Length)));
  701. }
  702. else
  703. {
  704. // This file belongs to one of the regions. Find out which one.
  705. Assert.IsTrue(filePath.StartsWith(ArchiveConstants.REGIONS_PATH));
  706. string[] parts = filePath.Split(new Char[] { '/' }, 3);
  707. Assert.AreEqual(3, parts.Length);
  708. string regionDirectory = parts[1];
  709. string relativePath = parts[2];
  710. Scene scene = regionPaths[regionDirectory];
  711. if (relativePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
  712. {
  713. foundPaths[scene.RegionInfo.RegionID].Add(relativePath);
  714. }
  715. }
  716. }
  717. Assert.AreEqual(scenes.Count, foundPaths.Count);
  718. foreach (Scene scene in scenes)
  719. {
  720. Assert.That(foundPaths[scene.RegionInfo.RegionID], Is.EquivalentTo(expectedPaths[scene.RegionInfo.RegionID]));
  721. }
  722. Assert.That(foundAssets, Is.EquivalentTo(expectedAssets));
  723. }
  724. /// <summary>
  725. /// Test loading a multi-region OAR.
  726. /// </summary>
  727. [Test]
  728. public void TestLoadMultiRegionOar()
  729. {
  730. TestHelpers.InMethod();
  731. // Create an ArchiveScenesGroup with the regions in the OAR. This is needed to generate the control file.
  732. int WIDTH = 2;
  733. int HEIGHT = 2;
  734. for (uint y = 0; y < HEIGHT; y++)
  735. {
  736. for (uint x = 0; x < WIDTH; x++)
  737. {
  738. Scene scene;
  739. if (x == 0 && y == 0)
  740. {
  741. scene = m_scene; // this scene was already created in SetUp()
  742. }
  743. else
  744. {
  745. scene = m_sceneHelpers.SetupScene(string.Format("Unit test region {0}", (y * WIDTH) + x + 1), UUID.Random(), 1000 + x, 1000 + y);
  746. SceneHelpers.SetupSceneModules(scene, new ArchiverModule(), m_serialiserModule, new TerrainModule());
  747. }
  748. }
  749. }
  750. ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();
  751. m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene)
  752. {
  753. scenesGroup.AddScene(scene);
  754. });
  755. scenesGroup.CalcSceneLocations();
  756. // Generate the OAR file
  757. MemoryStream archiveWriteStream = new MemoryStream();
  758. TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
  759. ArchiveWriteRequest writeRequest = new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty);
  760. writeRequest.MultiRegionFormat = true;
  761. tar.WriteFile(
  762. ArchiveConstants.CONTROL_FILE_PATH, writeRequest.CreateControlFile(scenesGroup));
  763. SceneObjectPart part1 = CreateSceneObjectPart1();
  764. part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
  765. part1.SitTargetPosition = new Vector3(1, 2, 3);
  766. SceneObjectGroup object1 = new SceneObjectGroup(part1);
  767. // Let's put some inventory items into our object
  768. string soundItemName = "sound-item1";
  769. UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
  770. Type type = GetType();
  771. Assembly assembly = type.Assembly;
  772. string soundDataResourceName = null;
  773. string[] names = assembly.GetManifestResourceNames();
  774. foreach (string name in names)
  775. {
  776. if (name.EndsWith(".Resources.test-sound.wav"))
  777. soundDataResourceName = name;
  778. }
  779. Assert.That(soundDataResourceName, Is.Not.Null);
  780. byte[] soundData;
  781. UUID soundUuid;
  782. CreateSoundAsset(tar, assembly, soundDataResourceName, out soundData, out soundUuid);
  783. TaskInventoryItem item1
  784. = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
  785. part1.Inventory.AddInventoryItem(item1, true);
  786. m_scene.AddNewSceneObject(object1, false);
  787. string object1FileName = string.Format(
  788. "{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
  789. part1.Name,
  790. Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
  791. part1.UUID);
  792. string path = "regions/1_1_Unit_test_region/" + ArchiveConstants.OBJECTS_PATH + object1FileName;
  793. tar.WriteFile(path, SceneObjectSerializer.ToXml2Format(object1));
  794. tar.Close();
  795. // Delete the current objects, to test that they're loaded from the OAR and didn't
  796. // just remain in the scene.
  797. m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene)
  798. {
  799. scene.DeleteAllSceneObjects();
  800. });
  801. // Create a "hole", to test that that the corresponding region isn't loaded from the OAR
  802. m_sceneHelpers.SceneManager.CloseScene(SceneManager.Instance.Scenes[1]);
  803. // Check thay the OAR file contains the expected data
  804. MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
  805. m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
  806. m_oarEvent.Reset();
  807. m_archiverModule.DearchiveRegion(archiveReadStream);
  808. m_oarEvent.WaitOne(60000);
  809. Assert.That(m_lastErrorMessage, Is.Null);
  810. Assert.AreEqual(3, m_sceneHelpers.SceneManager.Scenes.Count);
  811. TestLoadedRegion(part1, soundItemName, soundData);
  812. }
  813. private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData)
  814. {
  815. SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
  816. Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
  817. Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
  818. Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
  819. Quaternion qtmp1 = new Quaternion (
  820. (float)Math.Round(object1PartLoaded.RotationOffset.X,5),
  821. (float)Math.Round(object1PartLoaded.RotationOffset.Y,5),
  822. (float)Math.Round(object1PartLoaded.RotationOffset.Z,5),
  823. (float)Math.Round(object1PartLoaded.RotationOffset.W,5));
  824. Quaternion qtmp2 = new Quaternion (
  825. (float)Math.Round(part1.RotationOffset.X,5),
  826. (float)Math.Round(part1.RotationOffset.Y,5),
  827. (float)Math.Round(part1.RotationOffset.Z,5),
  828. (float)Math.Round(part1.RotationOffset.W,5));
  829. Assert.That(qtmp1, Is.EqualTo(qtmp2), "object1 rotation offset not equal");
  830. Assert.That(
  831. object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
  832. Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
  833. Assert.That(object1PartLoaded.SitTargetPosition, Is.EqualTo(part1.SitTargetPosition));
  834. TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
  835. Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
  836. AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
  837. Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
  838. Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
  839. Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels");
  840. }
  841. }
  842. }