1
// Permission is hereby granted, free of charge, to any person obtaining
2
// a copy of this software and associated documentation files (the
3
// "Software"), to deal in the Software without restriction, including
4
// without limitation the rights to use, copy, modify, merge, publish,
5
// distribute, sublicense, and/or sell copies of the Software, and to
6
// permit persons to whom the Software is furnished to do so, subject to
7
// the following conditions:
9
// The above copyright notice and this permission notice shall be
10
// included in all copies or substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
// Copyright (c) 2007-2008 Novell, Inc.
23
//>-Rusty Howell (rhowell@novell.com)
30
using System.Collections.Generic;
31
using System.Diagnostics;
35
namespace MoonlightTests {
37
public class DbReport : IReport {
39
private string connectionString = string.Empty;
40
private IDbConnection dbcon = null;
41
private IDbCommand dbcmd = null;
43
private string runtime;
44
private int runtimeid;
45
private string masters = "masters";
47
private string test_run_dir;
48
private string test_suite = string.Empty;
49
private bool debug = false;
51
public bool HasConnection
53
get {return (connectionString != string.Empty);}
60
test_suite = Environment.GetEnvironmentVariable ("MS_TEST_SUITE");
62
if ((test_suite != null) && (test_suite.Trim().ToLower() == "true")) {
64
throw new Exception("DbReport not enabled for MS test suite");// We should not log MS test suite results
69
StreamReader reader = new StreamReader(".dbconnection.txt");
70
connectionString = reader.ReadLine(); // Read the first line of the file
73
//Log(string.Format("Connecting to Postgresql server: '{0}'",connectionString));
74
dbcon = new NpgsqlConnection(connectionString);
76
dbcmd = dbcon.CreateCommand();
77
string query = "select id from testcases;";
79
dbcmd.CommandText = query;
80
IDataReader dbreader = dbcmd.ExecuteReader();
82
while(dbreader.Read()) {
83
int id = dbreader.GetInt32(0);
86
Log(string.Format("{0} test cases read", count));
90
Console.WriteLine("\nDbReport enabled\n");
94
Console.WriteLine("\nDbReport disabled\n"); // Use Console.WriteLine() so that this line always appears
96
Log(string.Format("\n{1} {0}",ex.GetType(), ex.Message));
97
connectionString = string.Empty;
101
private void WriteHelp()
104
string str = "\nDbReport is disabled because of missing file or invalid connection string\n";
105
str += "\nCreate file moon/test/.dbconnection.txt with the first line being the connection string to use.";
106
str += "\nServer=mysqlserver.company.com;Database=db;User ID=user;Password=password;Pooling=false;\n";
111
#region IReport members
112
public void BeginRun(TestRun run)
115
if (!HasConnection) {
120
string dir = "test-run-data";
121
string filename = "moonTestSuite.db";
123
runtime = run.StartTime.ToString("yyyy-MM-dd HH:mm");//Postgres timestamp format
124
test_run_dir = Path.Combine(dir,runtime);
126
if (!Directory.Exists(test_run_dir)) {
127
Directory.CreateDirectory(test_run_dir);
129
if (!Directory.Exists(Path.Combine(dir,masters))) {
130
Directory.CreateDirectory(Path.Combine(dir,masters));
134
Log(string.Format("Runtime: {0}", runtime));
142
public void Executing(Test test)
146
public void AddResult(Test test, TestResult result)
148
if (!HasConnection) {
153
string info = string.Empty;
155
string testname = test.InputFileName.Split('.')[0];
156
string masterfile = Path.Combine(masters, Path.GetFileName(test.MasterFile));
157
string renderfile = Path.Combine(runtime, Path.GetFileName(test.ResultFile));
159
string result_file = XmlReport.GetFilePath (test.ResultFile);
160
string master_file = XmlReport.GetFilePath (test.MasterFile);
162
//Log("masterfile = " + masterfile);
163
//Log("renderfile = " + renderfile);
165
//Log("result_file = " + result_file);
166
//Log("master_file = " + master_file);
169
XmlReport.CopyImageToRunDirectory(test_run_dir,result_file);
170
XmlReport.CopyImageToRunDirectory(Path.Combine("test-run-data",masters), master_file);
172
if (masterfile.EndsWith("tif") || masterfile.EndsWith("tiff")) {
173
masterfile += ".png";
174
renderfile += ".png";
177
int internal_id = AddTestCase(test.Id,testname,masterfile,test_suite);
181
case TestResult.Fail:
182
info = test.FailedReason;
184
case TestResult.Ignore:
185
info = test.IgnoreReason;
187
case TestResult.KnownFailure:
188
info = test.KnownFailureReason;
195
string query = string.Format("INSERT INTO results (internal_id,runtimeid,result,renderfile,info) VALUES ('{0}','{1}','{2}','{3}', '{4}');",internal_id, runtimeid, result.ToString(), renderfile, info);
199
private int AddTestCase(string id, string testname, string masterfile, string suite)
201
int intid = Convert.ToInt32(id);
202
int internal_id = -1;
204
string query = string.Format("Select internal_id from testcases where id={0} and suite='{1}'",intid,suite);
206
dbcmd.CommandText = query;
207
IDataReader reader = dbcmd.ExecuteReader();
209
// If the test case is not found, add it
212
query = string.Format("INSERT INTO testcases (id, suite, name, masterfile) VALUES ({0},'{1}','{2}','{3}');",intid, suite, testname, masterfile);
217
internal_id = reader.GetInt32(0);
218
Log(string.Format("Testcase exists with internal_id={0}",internal_id));
223
if (internal_id != -1)
226
dbcmd.CommandText = string.Format("SELECT internal_id FROM testcases WHERE id={0} AND suite='{1}';",intid,suite);
227
reader = dbcmd.ExecuteReader();
230
internal_id = reader.GetInt32(0);
251
private void AddBuild(string time)
254
string revision = GetSubersionRevision();
255
string arch = GetArch();
257
string query = string.Format("INSERT INTO builds (revision, runtime, arch) VALUES ('{0}','{1}','{2}');",revision,time,arch);
258
//execnonquery(query);
259
dbcmd.CommandText = query;
261
dbcmd.ExecuteNonQuery();
263
catch(Exception ex) {
267
IDataReader reader = execreader(string.Format("select id from builds where revision={0} and runtime='{1}' and arch='{2}';",revision,time,arch));
268
if ((reader != null) && reader.Read())
270
this.runtimeid = reader.GetInt32(0);
278
private void AddTags(Test test)
280
foreach(string tag in test.Categories)
282
string query = string.Format("SELECT id FROM tags WHERE name = '{0}';",tag.ToLower());
283
dbcmd.CommandText = query;
284
IDataReader reader = null;
285
int tagid = int.MinValue;
288
reader = dbcmd.ExecuteReader();
290
tagid = reader.GetInt32(0);
293
catch(Exception ex) {
294
Log("Tag exists:" + tag);
295
tagid = int.MinValue;
305
if (tagid == int.MinValue) {
307
query = string.Format("INSERT INTO tags (name) VALUES ('{0}');",tag.ToLower());
310
query = string.Format("SELECT id FROM tags WHERE name = '{0}';",tag.ToLower());
311
dbcmd.CommandText = query;
312
reader = dbcmd.ExecuteReader();
314
tagid = reader.GetInt32(0);
317
catch (Exception ex) {
319
Log("ADDTAG " +ex.Message);
322
if (reader != null) {
329
AddTaggedCase(test.Id,tagid);
332
private void AddTaggedCase(string testid, int tagid)
334
string query = string.Format("select testcaseid,tagid from taggedcases where testcaseid={0} and tagid={1};",testid,tagid);
335
IDataReader reader = execreader(query);
336
if ((reader != null) && reader.Read()) {
338
//Log(string.Format("tagged case EXISTS for testcaseid={0} and tagid={1};",testid,tagid));
343
query = string.Format("INSERT INTO taggedcases values ({0},'{1}');",tagid, testid);
349
private void execnonquery(string query)
352
dbcmd.CommandText = query;
353
dbcmd.ExecuteNonQuery();
355
catch(Exception ex) {
356
Log(string.Format("EXECQUERY {0}: {1}",ex.GetType().ToString(), ex.Message));
360
private IDataReader execreader(string query)
363
dbcmd.CommandText = query;
364
IDataReader reader = dbcmd.ExecuteReader();
367
catch(Exception ex) {
368
Log(string.Format("NONEXEC {0}: {1}",ex.GetType().ToString(), query));
373
private string GetArch()
375
ProcessStartInfo info = new ProcessStartInfo();
376
info.FileName = "uname";
377
info.Arguments = "-i";
379
info.UseShellExecute = false;
380
info.RedirectStandardOutput = true;
381
Process p = new Process();
385
string output = p.StandardOutput.ReadToEnd();
387
return output.Trim();
390
private string GetSubersionRevision()
393
ProcessStartInfo info = new ProcessStartInfo();
394
info.FileName = "svn";
395
info.Arguments = "info";
396
info.UseShellExecute = false;
397
info.RedirectStandardOutput = true;
398
Process p = new Process();
402
string revision = string.Empty;
403
string output = p.StandardOutput.ReadToEnd();
404
string[] lines = output.Split('\n');
408
foreach (string line in lines) {
409
if (line.StartsWith("Revision")) {
410
revision = line.Split(':')[1].Trim();
414
catch (Exception ex) {
416
Log("Cannot get revision number via svn info: " + ex.Message);
417
revision = string.Empty;
420
if (revision == string.Empty) {
421
revision = Environment.GetEnvironmentVariable ("SVN_REVISION");
427
private void Log(string msg)
430
Console.WriteLine(msg);