aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAlexRa2010-05-17 12:37:49 +0300
committerAlexRa2010-05-23 11:47:36 +0300
commit91ad1f4ee71dc8e945e9be7b85f7d4e0ddcf4156 (patch)
tree20c64a9e438bbc476b77f10e4628ed419689e030
parentApply http://opensimulator.org/mantis/view.php?id=4632 (diff)
downloadopensim-SC-91ad1f4ee71dc8e945e9be7b85f7d4e0ddcf4156.zip
opensim-SC-91ad1f4ee71dc8e945e9be7b85f7d4e0ddcf4156.tar.gz
opensim-SC-91ad1f4ee71dc8e945e9be7b85f7d4e0ddcf4156.tar.bz2
opensim-SC-91ad1f4ee71dc8e945e9be7b85f7d4e0ddcf4156.tar.xz
Added generic base classes for testing database services
These are some generic classes that simplify writing tests for any of the data connectors and databases. Among other things, configuring the connection strings is done once, in a separate resource file. Tests based on the new BasicDataServiceTest class require NUnit 2.5 or better.
-rw-r--r--OpenSim/Data/Tests/BasicDataServiceTest.cs171
-rw-r--r--OpenSim/Data/Tests/DefaultTestConns.cs63
-rw-r--r--OpenSim/Data/Tests/Resources/TestDataConnections.ini7
3 files changed, 241 insertions, 0 deletions
diff --git a/OpenSim/Data/Tests/BasicDataServiceTest.cs b/OpenSim/Data/Tests/BasicDataServiceTest.cs
new file mode 100644
index 0000000..82f29d6
--- /dev/null
+++ b/OpenSim/Data/Tests/BasicDataServiceTest.cs
@@ -0,0 +1,171 @@
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 protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
31
32 public BasicDataServiceTest()
33 : this("")
34 {
35 }
36
37 public BasicDataServiceTest(string conn)
38 {
39 m_connStr = !String.IsNullOrEmpty(conn) ? conn : DefaultTestConns.Get(typeof(TConn));
40
41 OpenSim.Tests.Common.TestLogging.LogToConsole(); // TODO: Is that right?
42 }
43
44 /// <summary>
45 /// To be overridden in derived classes. Do whatever init with the m_service, like setting the conn string to it.
46 /// You'd probably want to to cast the 'service' to a more specific type and store it in a member var.
47 /// This framework takes care of disposing it, if it's disposable.
48 /// </summary>
49 /// <param name="service">The service being tested</param>
50 protected virtual void InitService(object service)
51 {
52 }
53
54 [TestFixtureSetUp]
55 public void Init()
56 {
57 // Sorry, some SQLite-specific stuff goes here (not a big deal, as its just some file ops)
58 if (typeof(TConn).Name.StartsWith("Sqlite"))
59 {
60 // SQLite doesn't work on power or z linux
61 if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
62 Assert.Ignore();
63
64 // for SQLite, if no explicit conn string is specified, use a temp file
65 if (String.IsNullOrEmpty(m_connStr))
66 {
67 m_file = Path.GetTempFileName() + ".db";
68 m_connStr = "URI=file:" + m_file + ",version=3";
69 }
70 }
71
72 if (String.IsNullOrEmpty(m_connStr))
73 {
74 string msg = String.Format("Connection string for {0} is not defined, ignoring tests", typeof(TConn).Name);
75 m_log.Error(msg);
76 Assert.Ignore(msg);
77 }
78
79 // If we manage to connect to the database with the user
80 // and password above it is our test database, and run
81 // these tests. If anything goes wrong, ignore these
82 // tests.
83 try
84 {
85 m_service = new TService();
86 InitService(m_service);
87 }
88 catch (Exception e)
89 {
90 m_log.Error(e.ToString());
91 Assert.Ignore();
92 }
93 }
94
95 [TestFixtureTearDown]
96 public void Cleanup()
97 {
98 if (m_service != null)
99 {
100 if( m_service is IDisposable)
101 ((IDisposable)m_service).Dispose();
102 m_service = null;
103 }
104
105 if( !String.IsNullOrEmpty(m_file) && File.Exists(m_file) )
106 File.Delete(m_file);
107 }
108
109 protected virtual DbConnection Connect()
110 {
111 DbConnection cnn = new TConn();
112 cnn.ConnectionString = m_connStr;
113 cnn.Open();
114 return cnn;
115 }
116
117 protected virtual void ExecuteSql(string sql)
118 {
119 using (DbConnection dbcon = Connect())
120 {
121 using (DbCommand cmd = dbcon.CreateCommand())
122 {
123 cmd.CommandText = sql;
124 cmd.ExecuteNonQuery();
125 }
126 }
127 }
128
129 protected delegate bool ProcessRow(IDataReader reader);
130
131 protected virtual int ExecQuery(string sql, bool bSingleRow, ProcessRow action)
132 {
133 int nRecs = 0;
134 using (DbConnection dbcon = Connect())
135 {
136 using (DbCommand cmd = dbcon.CreateCommand())
137 {
138 cmd.CommandText = sql;
139 CommandBehavior cb = bSingleRow ? CommandBehavior.SingleRow : CommandBehavior.Default;
140 using (DbDataReader rdr = cmd.ExecuteReader(cb))
141 {
142 while (rdr.Read())
143 {
144 nRecs++;
145 if (!action(rdr))
146 break;
147 }
148 }
149 }
150 }
151 return nRecs;
152 }
153
154 /// <summary>Drop tables (listed as parameters). There is no "DROP IF EXISTS" syntax common for all
155 /// databases, so we just DROP and ignore an exception.
156 /// </summary>
157 /// <param name="tables"></param>
158 protected virtual void DropTables(params string[] tables)
159 {
160 foreach (string tbl in tables)
161 {
162 try
163 {
164 ExecuteSql("DROP TABLE " + tbl + ";");
165 }catch
166 {
167 }
168 }
169 }
170 }
171}
diff --git a/OpenSim/Data/Tests/DefaultTestConns.cs b/OpenSim/Data/Tests/DefaultTestConns.cs
new file mode 100644
index 0000000..7b52af5
--- /dev/null
+++ b/OpenSim/Data/Tests/DefaultTestConns.cs
@@ -0,0 +1,63 @@
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Reflection;
6using System.IO;
7using Nini.Config;
8
9namespace OpenSim.Data.Tests
10{
11 /// <summary>This static class looks for TestDataConnections.ini file in the /bin directory to obtain
12 /// a connection string for testing one of the supported databases.
13 /// The connections must be in the section [TestConnections] with names matching the connection class
14 /// name for the specific database, e.g.:
15 ///
16 /// [TestConnections]
17 /// MySqlConnection="..."
18 /// SqlConnection="..."
19 /// SqliteConnection="..."
20 ///
21 /// Note that the conn string may also be set explicitly in the [TestCase()] attribute of test classes
22 /// based on BasicDataServiceTest.cs.
23 /// </summary>
24
25 static class DefaultTestConns
26 {
27 private static Dictionary<Type, string> conns = new Dictionary<Type, string>();
28
29 public static string Get(Type connType)
30 {
31 string sConn;
32
33 if (conns.TryGetValue(connType, out sConn))
34 return sConn;
35
36 Assembly asm = Assembly.GetExecutingAssembly();
37 string sType = connType.Name;
38
39 // Note: when running from NUnit, the DLL is located in some temp dir, so how do we get
40 // to the INI file? Ok, so put it into the resources!
41 // string iniName = Path.Combine(Path.GetDirectoryName(asm.Location), "TestDataConnections.ini");
42
43 string[] allres = asm.GetManifestResourceNames();
44 string sResFile = Array.Find(allres, s => s.Contains("TestDataConnections.ini"));
45
46 if (String.IsNullOrEmpty(sResFile))
47 throw new Exception(String.Format("Please add resource TestDataConnections.ini, with section [TestConnections] and settings like {0}=\"...\"",
48 sType));
49
50 using (Stream resource = asm.GetManifestResourceStream(sResFile))
51 {
52 IConfigSource source = new IniConfigSource(resource);
53 var cfg = source.Configs["TestConnections"];
54 sConn = cfg.Get(sType, "");
55 }
56
57 if (!String.IsNullOrEmpty(sConn))
58 conns[connType] = sConn;
59
60 return sConn;
61 }
62 }
63}
diff --git a/OpenSim/Data/Tests/Resources/TestDataConnections.ini b/OpenSim/Data/Tests/Resources/TestDataConnections.ini
new file mode 100644
index 0000000..d149744
--- /dev/null
+++ b/OpenSim/Data/Tests/Resources/TestDataConnections.ini
@@ -0,0 +1,7 @@
1; The default connections to the test databases. Used by tests based on BasicDataServiceTest.cs.
2; Read by code in DefaultTestConns.cs
3
4[TestConnections]
5MySqlConnection="Server=localhost;Port=3306;Database=opensim-nunit;User ID=opensim-nunit;Password=opensim-nunit;"
6;SqlConnection="..."
7;SqliteConnection="..." \ No newline at end of file