clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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.IO;
30 using System.Collections.Generic;
31 using log4net.Config;
32 using NUnit.Framework;
33 using NUnit.Framework.Constraints;
34 using OpenMetaverse;
35 using OpenSim.Framework;
36 using OpenSim.Tests.Common;
37 using log4net;
38 using System.Data;
39 using System.Data.Common;
40 using System.Reflection;
41  
42 namespace OpenSim.Data.Tests
43 {
44 /// <summary>This is a base class for testing any Data service for any DBMS.
45 /// Requires NUnit 2.5 or better (to support the generics).
46 /// </summary>
47 /// <remarks>
48 /// FIXME: Should extend OpenSimTestCase but compile on mono 2.4.3 currently fails with
49 /// AssetTests`2 : System.MemberAccessException : Cannot create an instance of OpenSim.Data.Tests.AssetTests`2[TConn,TAssetData] because Type.ContainsGenericParameters is true.
50 /// and similar on EstateTests, InventoryTests and RegionTests.
51 /// Runs fine with mono 2.10.8.1, so easiest thing is to wait until min Mono version uplifts.
52 /// </remarks>
53 /// <typeparam name="TConn"></typeparam>
54 /// <typeparam name="TService"></typeparam>
55 public class BasicDataServiceTest<TConn, TService>
56 where TConn : DbConnection, new()
57 where TService : class, new()
58 {
59 protected string m_connStr;
60 private TService m_service;
61 private string m_file;
62  
63 // TODO: Is this in the right place here?
64 // Later: apparently it's not, but does it matter here?
65 // protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
66  
67 protected ILog m_log; // doesn't matter here that it's not static, init to correct type in instance .ctor
68  
69 public BasicDataServiceTest()
70 : this("")
71 {
72 }
73  
74 public BasicDataServiceTest(string conn)
75 {
76 m_connStr = !String.IsNullOrEmpty(conn) ? conn : DefaultTestConns.Get(typeof(TConn));
77  
78 m_log = LogManager.GetLogger(this.GetType());
79 OpenSim.Tests.Common.TestLogging.LogToConsole(); // TODO: Is that right?
80 }
81  
82 /// <summary>
83 /// To be overridden in derived classes. Do whatever init with the m_service, like setting the conn string to it.
84 /// You'd probably want to to cast the 'service' to a more specific type and store it in a member var.
85 /// This framework takes care of disposing it, if it's disposable.
86 /// </summary>
87 /// <param name="service">The service being tested</param>
88 protected virtual void InitService(object service)
89 {
90 }
91  
92 [TestFixtureSetUp]
93 public void Init()
94 {
95 // Sorry, some SQLite-specific stuff goes here (not a big deal, as its just some file ops)
96 if (typeof(TConn).Name.StartsWith("Sqlite"))
97 {
98 // SQLite doesn't work on power or z linux
99 if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
100 Assert.Ignore();
101  
102 if (Util.IsWindows())
103 Util.LoadArchSpecificWindowsDll("sqlite3.dll");
104  
105 // for SQLite, if no explicit conn string is specified, use a temp file
106 if (String.IsNullOrEmpty(m_connStr))
107 {
108 m_file = Path.GetTempFileName() + ".db";
109 m_connStr = "URI=file:" + m_file + ",version=3";
110 }
111 }
112  
113 if (String.IsNullOrEmpty(m_connStr))
114 {
115 string msg = String.Format("Connection string for {0} is not defined, ignoring tests", typeof(TConn).Name);
116 m_log.Warn(msg);
117 Assert.Ignore(msg);
118 }
119  
120 // Try the connection, ignore tests if Open() fails
121 using (TConn conn = new TConn())
122 {
123 conn.ConnectionString = m_connStr;
124 try
125 {
126 conn.Open();
127 conn.Close();
128 }
129 catch
130 {
131 string msg = String.Format("{0} is unable to connect to the database, ignoring tests", typeof(TConn).Name);
132 m_log.Warn(msg);
133 Assert.Ignore(msg);
134 }
135 }
136  
137 // If we manage to connect to the database with the user
138 // and password above it is our test database, and run
139 // these tests. If anything goes wrong, ignore these
140 // tests.
141 try
142 {
143 m_service = new TService();
144 InitService(m_service);
145 }
146 catch (Exception e)
147 {
148 m_log.Error(e.ToString());
149 Assert.Ignore();
150 }
151 }
152  
153 [TestFixtureTearDown]
154 public void Cleanup()
155 {
156 if (m_service != null)
157 {
158 if (m_service is IDisposable)
159 ((IDisposable)m_service).Dispose();
160 m_service = null;
161 }
162  
163 if (!String.IsNullOrEmpty(m_file) && File.Exists(m_file))
164 File.Delete(m_file);
165 }
166  
167 protected virtual DbConnection Connect()
168 {
169 DbConnection cnn = new TConn();
170 cnn.ConnectionString = m_connStr;
171 cnn.Open();
172 return cnn;
173 }
174  
175 protected virtual void ExecuteSql(string sql)
176 {
177 using (DbConnection dbcon = Connect())
178 {
179 using (DbCommand cmd = dbcon.CreateCommand())
180 {
181 cmd.CommandText = sql;
182 cmd.ExecuteNonQuery();
183 }
184 }
185 }
186  
187 protected delegate bool ProcessRow(IDataReader reader);
188  
189 protected virtual int ExecQuery(string sql, bool bSingleRow, ProcessRow action)
190 {
191 int nRecs = 0;
192 using (DbConnection dbcon = Connect())
193 {
194 using (DbCommand cmd = dbcon.CreateCommand())
195 {
196 cmd.CommandText = sql;
197 CommandBehavior cb = bSingleRow ? CommandBehavior.SingleRow : CommandBehavior.Default;
198 using (DbDataReader rdr = cmd.ExecuteReader(cb))
199 {
200 while (rdr.Read())
201 {
202 nRecs++;
203 if (!action(rdr))
204 break;
205 }
206 }
207 }
208 }
209 return nRecs;
210 }
211  
212 /// <summary>Drop tables (listed as parameters). There is no "DROP IF EXISTS" syntax common for all
213 /// databases, so we just DROP and ignore an exception.
214 /// </summary>
215 /// <param name="tables"></param>
216 protected virtual void DropTables(params string[] tables)
217 {
218 foreach (string tbl in tables)
219 {
220 try
221 {
222 ExecuteSql("DROP TABLE " + tbl + ";");
223 }catch
224 {
225 }
226 }
227 }
228  
229 /// <summary>Clear tables listed as parameters (without dropping them).
230 /// </summary>
231 /// <param name="tables"></param>
232 protected virtual void ResetMigrations(params string[] stores)
233 {
234 string lst = "";
235 foreach (string store in stores)
236 {
237 string s = "'" + store + "'";
238 if (lst == "")
239 lst = s;
240 else
241 lst += ", " + s;
242 }
243  
244 string sCond = stores.Length > 1 ? ("in (" + lst + ")") : ("=" + lst);
245 try
246 {
247 ExecuteSql("DELETE FROM migrations where name " + sCond);
248 }
249 catch
250 {
251 }
252 }
253  
254 /// <summary>Clear tables listed as parameters (without dropping them).
255 /// </summary>
256 /// <param name="tables"></param>
257 protected virtual void ClearTables(params string[] tables)
258 {
259 foreach (string tbl in tables)
260 {
261 try
262 {
263 ExecuteSql("DELETE FROM " + tbl + ";");
264 }
265 catch
266 {
267 }
268 }
269 }
270 }
271 }