opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 // for SQLite, if no explicit conn string is specified, use a temp file
103 if (String.IsNullOrEmpty(m_connStr))
104 {
105 m_file = Path.GetTempFileName() + ".db";
106 m_connStr = "URI=file:" + m_file + ",version=3";
107 }
108 }
109  
110 if (String.IsNullOrEmpty(m_connStr))
111 {
112 string msg = String.Format("Connection string for {0} is not defined, ignoring tests", typeof(TConn).Name);
113 m_log.Warn(msg);
114 Assert.Ignore(msg);
115 }
116  
117 // Try the connection, ignore tests if Open() fails
118 using (TConn conn = new TConn())
119 {
120 conn.ConnectionString = m_connStr;
121 try
122 {
123 conn.Open();
124 conn.Close();
125 }
126 catch
127 {
128 string msg = String.Format("{0} is unable to connect to the database, ignoring tests", typeof(TConn).Name);
129 m_log.Warn(msg);
130 Assert.Ignore(msg);
131 }
132 }
133  
134 // If we manage to connect to the database with the user
135 // and password above it is our test database, and run
136 // these tests. If anything goes wrong, ignore these
137 // tests.
138 try
139 {
140 m_service = new TService();
141 InitService(m_service);
142 }
143 catch (Exception e)
144 {
145 m_log.Error(e.ToString());
146 Assert.Ignore();
147 }
148 }
149  
150 [TestFixtureTearDown]
151 public void Cleanup()
152 {
153 if (m_service != null)
154 {
155 if (m_service is IDisposable)
156 ((IDisposable)m_service).Dispose();
157 m_service = null;
158 }
159  
160 if (!String.IsNullOrEmpty(m_file) && File.Exists(m_file))
161 File.Delete(m_file);
162 }
163  
164 protected virtual DbConnection Connect()
165 {
166 DbConnection cnn = new TConn();
167 cnn.ConnectionString = m_connStr;
168 cnn.Open();
169 return cnn;
170 }
171  
172 protected virtual void ExecuteSql(string sql)
173 {
174 using (DbConnection dbcon = Connect())
175 {
176 using (DbCommand cmd = dbcon.CreateCommand())
177 {
178 cmd.CommandText = sql;
179 cmd.ExecuteNonQuery();
180 }
181 }
182 }
183  
184 protected delegate bool ProcessRow(IDataReader reader);
185  
186 protected virtual int ExecQuery(string sql, bool bSingleRow, ProcessRow action)
187 {
188 int nRecs = 0;
189 using (DbConnection dbcon = Connect())
190 {
191 using (DbCommand cmd = dbcon.CreateCommand())
192 {
193 cmd.CommandText = sql;
194 CommandBehavior cb = bSingleRow ? CommandBehavior.SingleRow : CommandBehavior.Default;
195 using (DbDataReader rdr = cmd.ExecuteReader(cb))
196 {
197 while (rdr.Read())
198 {
199 nRecs++;
200 if (!action(rdr))
201 break;
202 }
203 }
204 }
205 }
206 return nRecs;
207 }
208  
209 /// <summary>Drop tables (listed as parameters). There is no "DROP IF EXISTS" syntax common for all
210 /// databases, so we just DROP and ignore an exception.
211 /// </summary>
212 /// <param name="tables"></param>
213 protected virtual void DropTables(params string[] tables)
214 {
215 foreach (string tbl in tables)
216 {
217 try
218 {
219 ExecuteSql("DROP TABLE " + tbl + ";");
220 }catch
221 {
222 }
223 }
224 }
225  
226 /// <summary>Clear tables listed as parameters (without dropping them).
227 /// </summary>
228 /// <param name="tables"></param>
229 protected virtual void ResetMigrations(params string[] stores)
230 {
231 string lst = "";
232 foreach (string store in stores)
233 {
234 string s = "'" + store + "'";
235 if (lst == "")
236 lst = s;
237 else
238 lst += ", " + s;
239 }
240  
241 string sCond = stores.Length > 1 ? ("in (" + lst + ")") : ("=" + lst);
242 try
243 {
244 ExecuteSql("DELETE FROM migrations where name " + sCond);
245 }
246 catch
247 {
248 }
249 }
250  
251 /// <summary>Clear tables listed as parameters (without dropping them).
252 /// </summary>
253 /// <param name="tables"></param>
254 protected virtual void ClearTables(params string[] tables)
255 {
256 foreach (string tbl in tables)
257 {
258 try
259 {
260 ExecuteSql("DELETE FROM " + tbl + ";");
261 }
262 catch
263 {
264 }
265 }
266 }
267 }
268 }