diff options
author | AlexRa | 2010-05-17 12:37:49 +0300 |
---|---|---|
committer | AlexRa | 2010-05-23 11:47:36 +0300 |
commit | 91ad1f4ee71dc8e945e9be7b85f7d4e0ddcf4156 (patch) | |
tree | 20c64a9e438bbc476b77f10e4628ed419689e030 /OpenSim/Data/Tests/BasicDataServiceTest.cs | |
parent | Apply http://opensimulator.org/mantis/view.php?id=4632 (diff) | |
download | opensim-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.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Data/Tests/BasicDataServiceTest.cs | 171 |
1 files changed, 171 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 @@ | |||
1 | using System; | ||
2 | using System.IO; | ||
3 | using System.Collections.Generic; | ||
4 | using log4net.Config; | ||
5 | using NUnit.Framework; | ||
6 | using NUnit.Framework.Constraints; | ||
7 | using OpenMetaverse; | ||
8 | using OpenSim.Framework; | ||
9 | using log4net; | ||
10 | using System.Data; | ||
11 | using System.Data.Common; | ||
12 | using System.Reflection; | ||
13 | |||
14 | namespace 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 | } | ||