aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/Tests/BasicDataServiceTest.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/Tests/BasicDataServiceTest.cs')
-rw-r--r--OpenSim/Data/Tests/BasicDataServiceTest.cs234
1 files changed, 234 insertions, 0 deletions
diff --git a/OpenSim/Data/Tests/BasicDataServiceTest.cs b/OpenSim/Data/Tests/BasicDataServiceTest.cs
new file mode 100644
index 0000000..c261126
--- /dev/null
+++ b/OpenSim/Data/Tests/BasicDataServiceTest.cs
@@ -0,0 +1,234 @@
1using System;
2using System.IO;
3using System.Collections.Generic;
4using log4net.Config;
5using NUnit.Framework;
6using NUnit.Framework.Constraints;
7using OpenMetaverse;
8using OpenSim.Framework;
9using log4net;
10using System.Data;
11using System.Data.Common;
12using System.Reflection;
13
14namespace OpenSim.Data.Tests
15{
16 /// <summary>This is a base class for testing any Data service for any DBMS.
17 /// Requires NUnit 2.5 or better (to support the generics).
18 /// </summary>
19 /// <typeparam name="TConn"></typeparam>
20 /// <typeparam name="TService"></typeparam>
21 public class BasicDataServiceTest<TConn, TService>
22 where TConn : DbConnection, new()
23 where TService : class, new()
24 {
25 protected string m_connStr;
26 private TService m_service;
27 private string m_file;
28
29 // TODO: Is this in the right place here?
30 // Later: apparently it's not, but does it matter here?
31// protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
32
33 protected ILog m_log; // doesn't matter here that it's not static, init to correct type in instance .ctor
34
35 public BasicDataServiceTest()
36 : this("")
37 {
38 }
39
40 public BasicDataServiceTest(string conn)
41 {
42 m_connStr = !String.IsNullOrEmpty(conn) ? conn : DefaultTestConns.Get(typeof(TConn));
43
44 m_log = LogManager.GetLogger(this.GetType());
45 OpenSim.Tests.Common.TestLogging.LogToConsole(); // TODO: Is that right?
46 }
47
48 /// <summary>
49 /// To be overridden in derived classes. Do whatever init with the m_service, like setting the conn string to it.
50 /// You'd probably want to to cast the 'service' to a more specific type and store it in a member var.
51 /// This framework takes care of disposing it, if it's disposable.
52 /// </summary>
53 /// <param name="service">The service being tested</param>
54 protected virtual void InitService(object service)
55 {
56 }
57
58 [TestFixtureSetUp]
59 public void Init()
60 {
61 // Sorry, some SQLite-specific stuff goes here (not a big deal, as its just some file ops)
62 if (typeof(TConn).Name.StartsWith("Sqlite"))
63 {
64 // SQLite doesn't work on power or z linux
65 if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
66 Assert.Ignore();
67
68 // for SQLite, if no explicit conn string is specified, use a temp file
69 if (String.IsNullOrEmpty(m_connStr))
70 {
71 m_file = Path.GetTempFileName() + ".db";
72 m_connStr = "URI=file:" + m_file + ",version=3";
73 }
74 }
75
76 if (String.IsNullOrEmpty(m_connStr))
77 {
78 string msg = String.Format("Connection string for {0} is not defined, ignoring tests", typeof(TConn).Name);
79 m_log.Warn(msg);
80 Assert.Ignore(msg);
81 }
82
83 // Try the connection, ignore tests if Open() fails
84 using (TConn conn = new TConn())
85 {
86 conn.ConnectionString = m_connStr;
87 try
88 {
89 conn.Open();
90 conn.Close();
91 }
92 catch
93 {
94 string msg = String.Format("{0} is unable to connect to the database, ignoring tests", typeof(TConn).Name);
95 m_log.Warn(msg);
96 Assert.Ignore(msg);
97 }
98 }
99
100 // If we manage to connect to the database with the user
101 // and password above it is our test database, and run
102 // these tests. If anything goes wrong, ignore these
103 // tests.
104 try
105 {
106 m_service = new TService();
107 InitService(m_service);
108 }
109 catch (Exception e)
110 {
111 m_log.Error(e.ToString());
112 Assert.Ignore();
113 }
114 }
115
116 [TestFixtureTearDown]
117 public void Cleanup()
118 {
119 if (m_service != null)
120 {
121 if( m_service is IDisposable)
122 ((IDisposable)m_service).Dispose();
123 m_service = null;
124 }
125
126 if( !String.IsNullOrEmpty(m_file) && File.Exists(m_file) )
127 File.Delete(m_file);
128 }
129
130 protected virtual DbConnection Connect()
131 {
132 DbConnection cnn = new TConn();
133 cnn.ConnectionString = m_connStr;
134 cnn.Open();
135 return cnn;
136 }
137
138 protected virtual void ExecuteSql(string sql)
139 {
140 using (DbConnection dbcon = Connect())
141 {
142 using (DbCommand cmd = dbcon.CreateCommand())
143 {
144 cmd.CommandText = sql;
145 cmd.ExecuteNonQuery();
146 }
147 }
148 }
149
150 protected delegate bool ProcessRow(IDataReader reader);
151
152 protected virtual int ExecQuery(string sql, bool bSingleRow, ProcessRow action)
153 {
154 int nRecs = 0;
155 using (DbConnection dbcon = Connect())
156 {
157 using (DbCommand cmd = dbcon.CreateCommand())
158 {
159 cmd.CommandText = sql;
160 CommandBehavior cb = bSingleRow ? CommandBehavior.SingleRow : CommandBehavior.Default;
161 using (DbDataReader rdr = cmd.ExecuteReader(cb))
162 {
163 while (rdr.Read())
164 {
165 nRecs++;
166 if (!action(rdr))
167 break;
168 }
169 }
170 }
171 }
172 return nRecs;
173 }
174
175 /// <summary>Drop tables (listed as parameters). There is no "DROP IF EXISTS" syntax common for all
176 /// databases, so we just DROP and ignore an exception.
177 /// </summary>
178 /// <param name="tables"></param>
179 protected virtual void DropTables(params string[] tables)
180 {
181 foreach (string tbl in tables)
182 {
183 try
184 {
185 ExecuteSql("DROP TABLE " + tbl + ";");
186 }catch
187 {
188 }
189 }
190 }
191
192 /// <summary>Clear tables listed as parameters (without dropping them).
193 /// </summary>
194 /// <param name="tables"></param>
195 protected virtual void ResetMigrations(params string[] stores)
196 {
197 string lst = "";
198 foreach (string store in stores)
199 {
200 string s = "'" + store + "'";
201 if (lst == "")
202 lst = s;
203 else
204 lst += ", " + s;
205 }
206
207 string sCond = stores.Length > 1 ? ("in (" + lst + ")") : ("=" + lst);
208 try
209 {
210 ExecuteSql("DELETE FROM migrations where name " + sCond);
211 }
212 catch
213 {
214 }
215 }
216
217 /// <summary>Clear tables listed as parameters (without dropping them).
218 /// </summary>
219 /// <param name="tables"></param>
220 protected virtual void ClearTables(params string[] tables)
221 {
222 foreach (string tbl in tables)
223 {
224 try
225 {
226 ExecuteSql("DELETE FROM " + tbl + ";");
227 }
228 catch
229 {
230 }
231 }
232 }
233 }
234}