SceneSetupHelpers.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  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.Net;
  29. using System.Collections.Generic;
  30. using Nini.Config;
  31. using OpenMetaverse;
  32. using OpenSim.Framework;
  33. using OpenSim.Framework.Communications;
  34. using OpenSim.Framework.Communications.Cache;
  35. using OpenSim.Framework.Console;
  36. using OpenSim.Framework.Servers;
  37. using OpenSim.Framework.Servers.HttpServer;
  38. using OpenSim.Region.Physics.Manager;
  39. using OpenSim.Region.Framework;
  40. using OpenSim.Region.Framework.Interfaces;
  41. using OpenSim.Region.Framework.Scenes;
  42. using OpenSim.Region.CoreModules.Agent.Capabilities;
  43. using OpenSim.Region.CoreModules.Avatar.Gods;
  44. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset;
  45. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory;
  46. using OpenSim.Services.Interfaces;
  47. using OpenSim.Tests.Common.Mock;
  48. namespace OpenSim.Tests.Common.Setup
  49. {
  50. /// <summary>
  51. /// Helpers for setting up scenes.
  52. /// </summary>
  53. public class SceneSetupHelpers
  54. {
  55. // These static variables in order to allow regions to be linked by shared modules and same
  56. // CommunicationsManager.
  57. private static ISharedRegionModule m_assetService = null;
  58. private static ISharedRegionModule m_inventoryService = null;
  59. private static TestCommunicationsManager commsManager = null;
  60. /// <summary>
  61. /// Set up a test scene
  62. /// </summary>
  63. ///
  64. /// Automatically starts service threads, as would the normal runtime.
  65. ///
  66. /// <returns></returns>
  67. public static TestScene SetupScene()
  68. {
  69. return SetupScene("");
  70. }
  71. /// <summary>
  72. /// Set up a test scene
  73. /// </summary>
  74. ///
  75. /// <param name="realServices">Starts real inventory and asset services, as opposed to mock ones, if true</param>
  76. /// <returns></returns>
  77. public static TestScene SetupScene(String realServices)
  78. {
  79. return SetupScene(
  80. "Unit test region", UUID.Random(), 1000, 1000, new TestCommunicationsManager(), realServices);
  81. }
  82. /// <summary>
  83. /// Set up a test scene
  84. /// </summary>
  85. ///
  86. /// <param name="realServices">Starts real inventory and asset services, as opposed to mock ones, if true</param>
  87. /// <param name="cm">This should be the same if simulating two scenes within a standalone</param>
  88. /// <returns></returns>
  89. public static TestScene SetupScene(TestCommunicationsManager cm, String realServices)
  90. {
  91. return SetupScene(
  92. "Unit test region", UUID.Random(), 1000, 1000, cm, "");
  93. }
  94. /// <summary>
  95. /// Set up a test scene
  96. /// </summary>
  97. /// <param name="name">Name of the region</param>
  98. /// <param name="id">ID of the region</param>
  99. /// <param name="x">X co-ordinate of the region</param>
  100. /// <param name="y">Y co-ordinate of the region</param>
  101. /// <param name="cm">This should be the same if simulating two scenes within a standalone</param>
  102. /// <returns></returns>
  103. public static TestScene SetupScene(string name, UUID id, uint x, uint y, TestCommunicationsManager cm)
  104. {
  105. return SetupScene(name, id, x, y, cm, "");
  106. }
  107. /// <summary>
  108. /// Set up a scene. If it's more then one scene, use the same CommunicationsManager to link regions
  109. /// or a different, to get a brand new scene with new shared region modules.
  110. /// </summary>
  111. /// <param name="name">Name of the region</param>
  112. /// <param name="id">ID of the region</param>
  113. /// <param name="x">X co-ordinate of the region</param>
  114. /// <param name="y">Y co-ordinate of the region</param>
  115. /// <param name="cm">This should be the same if simulating two scenes within a standalone</param>
  116. /// <param name="realServices">Starts real inventory and asset services, as opposed to mock ones, if true</param>
  117. /// <returns></returns>
  118. public static TestScene SetupScene(
  119. string name, UUID id, uint x, uint y, TestCommunicationsManager cm, String realServices)
  120. {
  121. bool newScene= false;
  122. Console.WriteLine("Setting up test scene {0}", name);
  123. // If cm is the same as our last commsManager used, this means the tester wants to link
  124. // regions. In this case, don't use the sameshared region modules and dont initialize them again.
  125. // Also, no need to start another MainServer and MainConsole instance.
  126. if (cm == null || cm != commsManager)
  127. {
  128. System.Console.WriteLine("Starting a brand new scene");
  129. newScene = true;
  130. MainConsole.Instance = new LocalConsole("TEST PROMPT");
  131. MainServer.Instance = new BaseHttpServer(980);
  132. commsManager = cm;
  133. }
  134. // We must set up a console otherwise setup of some modules may fail
  135. RegionInfo regInfo = new RegionInfo(x, y, new IPEndPoint(IPAddress.Loopback, 9000), "127.0.0.1");
  136. regInfo.RegionName = name;
  137. regInfo.RegionID = id;
  138. AgentCircuitManager acm = new AgentCircuitManager();
  139. SceneCommunicationService scs = new SceneCommunicationService(cm);
  140. StorageManager sm = new StorageManager("OpenSim.Data.Null.dll", "", "");
  141. IConfigSource configSource = new IniConfigSource();
  142. TestScene testScene = new TestScene(
  143. regInfo, acm, cm, scs, sm, null, false, false, false, configSource, null);
  144. INonSharedRegionModule capsModule = new CapabilitiesModule();
  145. capsModule.Initialise(new IniConfigSource());
  146. testScene.AddRegionModule(capsModule.Name, capsModule);
  147. capsModule.AddRegion(testScene);
  148. IRegionModule godsModule = new GodsModule();
  149. godsModule.Initialise(testScene, new IniConfigSource());
  150. testScene.AddModule(godsModule.Name, godsModule);
  151. realServices = realServices.ToLower();
  152. IConfigSource config = new IniConfigSource();
  153. // If we have a brand new scene, need to initialize shared region modules
  154. if ((m_assetService == null && m_inventoryService == null) || newScene)
  155. {
  156. if (realServices.Contains("asset"))
  157. StartAssetService(testScene, true);
  158. else
  159. StartAssetService(testScene, false);
  160. if (realServices.Contains("inventory"))
  161. StartInventoryService(testScene, true);
  162. else
  163. StartInventoryService(testScene, false);
  164. }
  165. // If not, make sure the shared module gets references to this new scene
  166. else
  167. {
  168. m_assetService.AddRegion(testScene);
  169. m_assetService.RegionLoaded(testScene);
  170. m_inventoryService.AddRegion(testScene);
  171. m_inventoryService.RegionLoaded(testScene);
  172. }
  173. m_inventoryService.PostInitialise();
  174. m_assetService.PostInitialise();
  175. testScene.CommsManager.UserService.SetInventoryService(testScene.InventoryService);
  176. testScene.SetModuleInterfaces();
  177. testScene.LandChannel = new TestLandChannel();
  178. testScene.LoadWorldMap();
  179. PhysicsPluginManager physicsPluginManager = new PhysicsPluginManager();
  180. physicsPluginManager.LoadPluginsFromAssembly("Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll");
  181. testScene.PhysicsScene
  182. = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test");
  183. return testScene;
  184. }
  185. private static void StartAssetService(Scene testScene, bool real)
  186. {
  187. ISharedRegionModule assetService = new LocalAssetServicesConnector();
  188. IConfigSource config = new IniConfigSource();
  189. config.AddConfig("Modules");
  190. config.AddConfig("AssetService");
  191. config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
  192. if (real)
  193. config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
  194. else
  195. config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestAssetService");
  196. config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
  197. assetService.Initialise(config);
  198. assetService.AddRegion(testScene);
  199. assetService.RegionLoaded(testScene);
  200. testScene.AddRegionModule(assetService.Name, assetService);
  201. m_assetService = assetService;
  202. }
  203. private static void StartInventoryService(Scene testScene, bool real)
  204. {
  205. ISharedRegionModule inventoryService = new LocalInventoryServicesConnector();
  206. IConfigSource config = new IniConfigSource();
  207. config.AddConfig("Modules");
  208. config.AddConfig("InventoryService");
  209. config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector");
  210. if (real)
  211. config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService");
  212. else
  213. config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestInventoryService");
  214. config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
  215. inventoryService.Initialise(config);
  216. inventoryService.AddRegion(testScene);
  217. inventoryService.RegionLoaded(testScene);
  218. testScene.AddRegionModule(inventoryService.Name, inventoryService);
  219. m_inventoryService = inventoryService;
  220. }
  221. /// <summary>
  222. /// Setup modules for a scene using their default settings.
  223. /// </summary>
  224. /// <param name="scene"></param>
  225. /// <param name="modules"></param>
  226. public static void SetupSceneModules(Scene scene, params object[] modules)
  227. {
  228. SetupSceneModules(scene, null, modules);
  229. }
  230. /// <summary>
  231. /// Setup modules for a scene.
  232. /// </summary>
  233. /// <param name="scene"></param>
  234. /// <param name="config"></param>
  235. /// <param name="modules"></param>
  236. public static void SetupSceneModules(Scene scene, IConfigSource config, params object[] modules)
  237. {
  238. List<IRegionModuleBase> newModules = new List<IRegionModuleBase>();
  239. foreach (object module in modules)
  240. {
  241. if (module is IRegionModule)
  242. {
  243. IRegionModule m = (IRegionModule)module;
  244. m.Initialise(scene, config);
  245. scene.AddModule(m.Name, m);
  246. m.PostInitialise();
  247. }
  248. else if (module is IRegionModuleBase)
  249. {
  250. // for the new system, everything has to be initialised first,
  251. // shared modules have to be post-initialised, then all get an AddRegion with the scene
  252. IRegionModuleBase m = (IRegionModuleBase)module;
  253. m.Initialise(config);
  254. newModules.Add(m);
  255. }
  256. }
  257. foreach (IRegionModuleBase module in newModules)
  258. {
  259. if (module is ISharedRegionModule) ((ISharedRegionModule)module).PostInitialise();
  260. }
  261. foreach (IRegionModuleBase module in newModules)
  262. {
  263. module.AddRegion(scene);
  264. module.RegionLoaded(scene);
  265. scene.AddRegionModule(module.Name, module);
  266. }
  267. scene.SetModuleInterfaces();
  268. }
  269. /// <summary>
  270. /// Generate some standard agent connection data.
  271. /// </summary>
  272. /// <param name="agentId"></param>
  273. /// <returns></returns>
  274. public static AgentCircuitData GenerateAgentData(UUID agentId)
  275. {
  276. string firstName = "testfirstname";
  277. AgentCircuitData agentData = new AgentCircuitData();
  278. agentData.AgentID = agentId;
  279. agentData.firstname = firstName;
  280. agentData.lastname = "testlastname";
  281. agentData.SessionID = UUID.Zero;
  282. agentData.SecureSessionID = UUID.Zero;
  283. agentData.circuitcode = 123;
  284. agentData.BaseFolder = UUID.Zero;
  285. agentData.InventoryFolder = UUID.Zero;
  286. agentData.startpos = Vector3.Zero;
  287. agentData.CapsPath = "http://wibble.com";
  288. return agentData;
  289. }
  290. /// <summary>
  291. /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test
  292. /// </summary>
  293. /// <param name="scene"></param>
  294. /// <param name="agentId"></param>
  295. /// <returns></returns>
  296. public static TestClient AddRootAgent(Scene scene, UUID agentId)
  297. {
  298. return AddRootAgent(scene, GenerateAgentData(agentId));
  299. }
  300. /// <summary>
  301. /// Add a root agent.
  302. /// </summary>
  303. ///
  304. /// This function
  305. ///
  306. /// 1) Tells the scene that an agent is coming. Normally, the login service (local if standalone, from the
  307. /// userserver if grid) would give initial login data back to the client and separately tell the scene that the
  308. /// agent was coming.
  309. ///
  310. /// 2) Connects the agent with the scene
  311. ///
  312. /// This function performs actions equivalent with notifying the scene that an agent is
  313. /// coming and then actually connecting the agent to the scene. The one step missed out is the very first
  314. ///
  315. /// <param name="scene"></param>
  316. /// <param name="agentData"></param>
  317. /// <returns></returns>
  318. public static TestClient AddRootAgent(Scene scene, AgentCircuitData agentData)
  319. {
  320. string reason;
  321. // We emulate the proper login sequence here by doing things in three stages
  322. // Stage 1: simulate login by telling the scene to expect a new user connection
  323. scene.NewUserConnection(agentData, out reason);
  324. // Stage 2: add the new client as a child agent to the scene
  325. TestClient client = new TestClient(agentData, scene);
  326. scene.AddNewClient(client);
  327. // Stage 3: Invoke agent crossing, which converts the child agent into a root agent (with appearance,
  328. // inventory, etc.)
  329. //scene.AgentCrossing(agentData.AgentID, new Vector3(90, 90, 90), false); OBSOLETE
  330. ScenePresence scp = scene.GetScenePresence(agentData.AgentID);
  331. scp.MakeRootAgent(new Vector3(90,90,90), true);
  332. return client;
  333. }
  334. /// <summary>
  335. /// Add a test object
  336. /// </summary>
  337. /// <param name="scene"></param>
  338. /// <returns></returns>
  339. public static SceneObjectPart AddSceneObject(Scene scene)
  340. {
  341. return AddSceneObject(scene, "Test Object");
  342. }
  343. /// <summary>
  344. /// Add a test object
  345. /// </summary>
  346. /// <param name="scene"></param>
  347. /// <param name="name"></param>
  348. /// <returns></returns>
  349. public static SceneObjectPart AddSceneObject(Scene scene, string name)
  350. {
  351. SceneObjectPart part
  352. = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero);
  353. part.Name = name;
  354. //part.UpdatePrimFlags(false, false, true);
  355. //part.ObjectFlags |= (uint)PrimFlags.Phantom;
  356. scene.AddNewSceneObject(new SceneObjectGroup(part), false);
  357. return part;
  358. }
  359. /// <summary>
  360. /// Delete a scene object asynchronously
  361. /// </summary>
  362. /// <param name="scene"></param>
  363. /// <param name="part"></param>
  364. /// <param name="action"></param>
  365. /// <param name="destinationId"></param>
  366. /// <param name="client"></param>
  367. public static void DeleteSceneObjectAsync(
  368. TestScene scene, SceneObjectPart part, DeRezAction action, UUID destinationId, IClientAPI client)
  369. {
  370. // Turn off the timer on the async sog deleter - we'll crank it by hand within a unit test
  371. AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
  372. sogd.Enabled = false;
  373. scene.DeRezObject(client, part.LocalId, UUID.Zero, action, destinationId);
  374. sogd.InventoryDeQueueAndDelete();
  375. }
  376. }
  377. }