OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
LSL_ApiHttpTests.cs
Go to the documentation of this file.
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 
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Net;
32 using System.Reflection;
33 using System.Text;
34 using log4net;
35 using Nini.Config;
36 using NUnit.Framework;
37 using OpenMetaverse;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Servers;
40 using OpenSim.Framework.Servers.HttpServer;
41 using OpenSim.Region.CoreModules.Scripting.LSLHttp;
42 using OpenSim.Region.Framework.Scenes;
43 using OpenSim.Region.ScriptEngine.Shared;
44 using OpenSim.Region.ScriptEngine.Shared.Api;
45 using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46 using OpenSim.Services.Interfaces;
47 using OpenSim.Tests.Common;
48 
49 namespace OpenSim.Region.ScriptEngine.Shared.Tests
50 {
54  [TestFixture]
56  {
57  private Scene m_scene;
58  private MockScriptEngine m_engine;
59  private UrlModule m_urlModule;
60 
61  private TaskInventoryItem m_scriptItem;
62  private LSL_Api m_lslApi;
63 
64  [TestFixtureSetUp]
65  public void TestFixtureSetUp()
66  {
67  // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
68  Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
69  }
70 
71  [TestFixtureTearDown]
72  public void TestFixureTearDown()
73  {
74  // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
75  // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
76  // tests really shouldn't).
77  Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
78  }
79 
80  [SetUp]
81  public override void SetUp()
82  {
83  base.SetUp();
84 
85  // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
86  // variables and the VM is not restarted between tests.
87  uint port = 9999;
88  MainServer.RemoveHttpServer(port);
89 
90  BaseHttpServer server = new BaseHttpServer(port, false, 0, "");
91  MainServer.AddHttpServer(server);
92  MainServer.Instance = server;
93 
94  server.Start();
95 
96  m_engine = new MockScriptEngine();
97  m_urlModule = new UrlModule();
98 
99  m_scene = new SceneHelpers().SetupScene();
100  SceneHelpers.SetupSceneModules(m_scene, new IniConfigSource(), m_engine, m_urlModule);
101 
102  SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
103  m_scriptItem = TaskInventoryHelpers.AddScript(m_scene.AssetService, so.RootPart);
104 
105  // This is disconnected from the actual script - the mock engine does not set up any LSL_Api atm.
106  // Possibly this could be done and we could obtain it directly from the MockScriptEngine.
107  m_lslApi = new LSL_Api();
108  m_lslApi.Initialize(m_engine, so.RootPart, m_scriptItem);
109  }
110 
111  [TearDown]
112  public void TearDown()
113  {
114  MainServer.Instance.Stop();
115  }
116 
117  [Test]
118  public void TestLlReleaseUrl()
119  {
120  TestHelpers.InMethod();
121 
122  m_lslApi.llRequestURL();
123  string returnedUri = m_engine.PostedEvents[m_scriptItem.ItemID][0].Params[2].ToString();
124 
125  {
126  // Check that the initial number of URLs is correct
127  Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
128  }
129 
130  {
131  // Check releasing a non-url
132  m_lslApi.llReleaseURL("GARBAGE");
133  Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
134  }
135 
136  {
137  // Check releasing a non-existing url
138  m_lslApi.llReleaseURL("http://example.com");
139  Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
140  }
141 
142  {
143  // Check URL release
144  m_lslApi.llReleaseURL(returnedUri);
145  Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
146 
147  HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri);
148 
149  bool gotExpectedException = false;
150 
151  try
152  {
153  using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
154  {}
155  }
156  catch (WebException e)
157  {
158 // using (HttpWebResponse response = (HttpWebResponse)e.Response)
159 // gotExpectedException = response.StatusCode == HttpStatusCode.NotFound;
160  gotExpectedException = true;
161  }
162 
163  Assert.That(gotExpectedException, Is.True);
164  }
165 
166  {
167  // Check releasing the same URL again
168  m_lslApi.llReleaseURL(returnedUri);
169  Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
170  }
171  }
172 
173  [Test]
174  public void TestLlRequestUrl()
175  {
176  TestHelpers.InMethod();
177 
178  string requestId = m_lslApi.llRequestURL();
179  Assert.That(requestId, Is.Not.EqualTo(UUID.Zero.ToString()));
180  string returnedUri;
181 
182  {
183  // Check that URL is correctly set up
184  Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
185 
186  Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
187 
188  List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
189  Assert.That(events.Count, Is.EqualTo(1));
190  EventParams eventParams = events[0];
191  Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
192 
193  UUID returnKey;
194  string rawReturnKey = eventParams.Params[0].ToString();
195  string method = eventParams.Params[1].ToString();
196  returnedUri = eventParams.Params[2].ToString();
197 
198  Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
199  Assert.That(method, Is.EqualTo(ScriptBaseClass.URL_REQUEST_GRANTED));
200  Assert.That(Uri.IsWellFormedUriString(returnedUri, UriKind.Absolute), Is.True);
201  }
202 
203  {
204  // Check that request to URL works.
205  string testResponse = "Hello World";
206 
207  m_engine.ClearPostedEvents();
208  m_engine.PostEventHook
209  += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse);
210 
211 // Console.WriteLine("Trying {0}", returnedUri);
212 
213  AssertHttpResponse(returnedUri, testResponse);
214 
215  Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
216 
217  List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
218  Assert.That(events.Count, Is.EqualTo(1));
219  EventParams eventParams = events[0];
220  Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
221 
222  UUID returnKey;
223  string rawReturnKey = eventParams.Params[0].ToString();
224  string method = eventParams.Params[1].ToString();
225  string body = eventParams.Params[2].ToString();
226 
227  Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
228  Assert.That(method, Is.EqualTo("GET"));
229  Assert.That(body, Is.EqualTo(""));
230  }
231  }
232 
233  private void AssertHttpResponse(string uri, string expectedResponse)
234  {
235  HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
236 
237  using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
238  {
239  using (Stream stream = webResponse.GetResponseStream())
240  {
241  using (StreamReader reader = new StreamReader(stream))
242  {
243  Assert.That(reader.ReadToEnd(), Is.EqualTo(expectedResponse));
244  }
245  }
246  }
247  }
248  }
249 }
Contains all LSL ll-functions. This class will be in Default AppDomain.
Definition: LSL_Api.cs:95
This module provides external URLs for in-world scripts.
Definition: UrlModule.cs:80
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
Represents an item in a task inventory
Helpers for setting up scenes.
Definition: SceneHelpers.cs:60
Holds all the data required to execute a scripting event.
Definition: Helpers.cs:281