Permalink
Fetching contributors…
Cannot retrieve contributors at this time
474 lines (421 sloc) 19.5 KB
<?xml version="1.0" ?>
<project name="NHibernate TeamCity Build" xmlns="http://nant.sf.net/release/0.90/nant.xsd" default="clean-configure-test" xsi:schemaLocation="http://nant.sf.net/release/0.90/nant.xsd Tools\nant\schema\nant.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<property name="root.dir" value="." />
<property name="config.teamcity" value="default"/>
<include buildfile="${root.dir}/default.build" />
<if test="${not property::exists('CCNetLabel') and not property::exists('build.number')}">
<fail message="This build file is for use with CruiseControl.NET or TeamCity" />
</if>
<property name="build.number" value="${CCNetLabel}" if="${property::exists('CCNetLabel')}" />
<target name="clean-configure-test" depends="cleanall init copy-teamcity-configuration binaries test verify-test-results binaries-zip" />
<target name="copy-teamcity-configuration">
<copy file="build-common/teamcity-hibernate.cfg.xml" tofile="${bin.dir}/hibernate.cfg.xml" />
<call target="setup-teamcity-${config.teamcity}"/>
<property name="app.config" value="../${bin.dir}/hibernate.cfg.xml" />
<nant buildfile="${root.dir}/build-common/common-project.xml" target="common.put-connection-settings-into-defined-app-config" />
</target>
<target name="verify-test-results">
<if test="${property::exists('NHibernate.Test.IgnoreFail')}">
<!-- Process the current results first, so that these will be available in build artifacts even
if the last-result files is missing. -->
<property name="teamcity.current.result" value="${testResult::StripTimings(testresults.dir + '/NHibernate.Test.dll-results.xml', 'NHibernate.Test.current-results.xml')}" />
<copy file="${teamcity.last.result}" todir="${testresults.dir}" />
<property name="teamcity.report" value="${testResult::CompareResults(teamcity.current.result, teamcity.last.result)}" />
</if>
</target>
<target name="setup-teamcity-default">
<!-- default (SQL Server) does not require any additional settings/binaries -->
</target>
<target name="setup-teamcity-sqlServerOdbc">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.OdbcDriver" />
<property name="nhibernate.odbc.explicit_datetime_scale" value="3" />
<!-- We need to use a dialect that avoids mapping DbType.Time to TIME on MSSQL. On modern SQL Server
this becomes TIME(7). Later, such values cannot be read back over ODBC. The
error we get is "System.ArgumentException : Unknown SQL type - SS_TIME_EX.". I don't know for certain
why this occurs, but MS docs do say that for a client "compiled using a version of SQL Server Native
Client prior to SQL Server 2008", TIME(7) cannot be converted back to the client. Assuming that .Net's
OdbcDriver would be considered a "client compiled with a previous version", it would make sense. Anyway,
using the MsSql2005Dialect avoids these test failures. -->
<property name="nhibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<!-- The OdbcDriver inherits SupportsMultipleOpenReaders=true from DriverBase, which requires Mars_Connection=yes for SQL Server. -->
<property name="nhibernate.connection.connection_string" value="Driver={SQL Server Native Client 11.0};Server=.\SQLExpress;Database=nhibernateOdbc;Trusted_Connection=yes;Mars_Connection=yes;" />
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/sqlServerOdbc/NHibernate.Test.last-results.xml" />
</target>
<target name="setup-teamcity-sqlServer2012">
<property name="nhibernate.dialect" value="NHibernate.Dialect.MsSql2012Dialect" />
</target>
<target name="setup-teamcity-sqlServerCe32">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.SqlServerCeDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.MsSqlCe40Dialect" />
<property name="nhibernate.connection.connection_string" value="Data Source=NHibernate.sdf" />
<property name="nhibernate.command_timeout" value="0" />
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/sqlServerCe/NHibernate.Test.last-results.xml" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/sqlServerCe/X86">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<target name="setup-teamcity-sqlServerCe64">
<property name="nunit-x64" value="true" />
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.SqlServerCeDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.MsSqlCe40Dialect" />
<property name="nhibernate.connection.connection_string" value="Data Source=NHibernate.sdf" />
<property name="nhibernate.command_timeout" value="0" />
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/sqlServerCe/NHibernate.Test.last-results.xml" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/sqlServerCe/AMD64">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<target name="setup-teamcity-firebird32">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.FirebirdClientDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.FirebirdDialect" />
<property name="nhibernate.connection.connection_string" value="DataSource=localhost;Database=nhibernate;User ID=SYSDBA;Password=masterkey;MaxPoolSize=200;" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/firebird">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<target name="setup-teamcity-firebird64">
<property name="nunit-x64" value="true" />
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.FirebirdClientDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.FirebirdDialect" />
<property name="nhibernate.connection.connection_string" value="DataSource=localhost;Database=nhibernate;User ID=SYSDBA;Password=masterkey;MaxPoolSize=200;" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/firebird">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<target name="setup-teamcity-sqlite32">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.SQLite20Driver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.SQLiteDialect" />
<property name="nhibernate.connection.connection_string" value="Data Source=NHibernate.db" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/sqlite/x86">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<target name="setup-teamcity-sqlite64">
<property name="nunit-x64" value="true" />
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.SQLite20Driver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.SQLiteDialect" />
<property name="nhibernate.connection.connection_string" value="Data Source=NHibernate.db" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/sqlite/x64">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<target name="setup-teamcity-postgresql">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.NpgsqlDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.PostgreSQL83Dialect" />
<property name="nhibernate.connection.connection_string" value="Host=localhost;Port=5432;Database=nhibernate;Username=nhibernate;Password=nhibernate;Enlist=true" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/postgresql">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<target name="setup-teamcity-oracle">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.OracleClientDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.Oracle10gDialect" />
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Data Source=XE" />
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/oracle/NHibernate.Test.last-results.xml" />
</target>
<target name="setup-teamcity-oracle32">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.OracleDataClientDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.Oracle10gDialect" />
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/oracle/x86">
<include name="*.dll"/>
</fileset>
</copy>
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/oracle/NHibernate.Test.last-results.xml" />
</target>
<target name="setup-teamcity-oracle64">
<property name="nunit-x64" value="true" />
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.OracleDataClientDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.Oracle10gDialect" />
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/oracle/x64">
<include name="*.dll"/>
</fileset>
</copy>
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/oracle/NHibernate.Test.last-results.xml" />
</target>
<target name="setup-teamcity-oracle-managed32">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.OracleManagedDataClientDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.Oracle10gDialect" />
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/oracle-managed/common">
<include name="*.dll"/>
</fileset>
</copy>
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/oracle-managed/x86">
<include name="*.dll"/>
</fileset>
</copy>
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/oracle-managed/NHibernate.Test.last-results.xml" />
</target>
<target name="setup-teamcity-oracle-managed64">
<property name="nunit-x64" value="true" />
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.OracleManagedDataClientDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.Oracle10gDialect" />
<property name="nhibernate.connection.connection_string" value="User ID=nhibernate;Password=nhibernate;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/oracle-managed/common">
<include name="*.dll"/>
</fileset>
</copy>
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/oracle-managed/x64">
<include name="*.dll"/>
</fileset>
</copy>
<property name="NHibernate.Test.IgnoreFail" value="true" />
<property name="teamcity.last.result" value="${root.dir}/lib/teamcity/oracle-managed/NHibernate.Test.last-results.xml" />
</target>
<target name="setup-teamcity-mysql">
<property name="nhibernate.connection.driver_class" value="NHibernate.Driver.MySqlDataDriver" />
<property name="nhibernate.dialect" value="NHibernate.Dialect.MySQL5Dialect" />
<property name="nhibernate.connection.connection_string" value="Data Source=localhost;Database=nhibernate;User ID=nhibernate;Password=nhibernate;Protocol=memory;Old Guids=True;" />
<copy todir="${bin.dir}">
<fileset basedir="${root.dir}/lib/teamcity/mysql">
<include name="*.dll"/>
</fileset>
</copy>
</target>
<script language="C#" prefix="testResult">
<references>
<include name="System.dll" />
<include name="System.Core.dll" />
<include name="System.Data.dll" />
<include name="System.Xml.dll" />
</references>
<imports>
<import namespace="System.Collections.Generic"/>
<import namespace="System.Data"/>
<import namespace="System.Data.Common"/>
<import namespace="System.Data.SqlClient"/>
<import namespace="System.IO"/>
<import namespace="System.Linq"/>
<import namespace="System.Xml"/>
</imports>
<code>
<![CDATA[
public static void StripAttributes(XmlDocument source, string xpath)
{
foreach (XmlAttribute att in source.SelectNodes(xpath))
att.OwnerElement.RemoveAttribute(att.Name);
}
public static void StripElements(XmlDocument source, string xpath)
{
foreach (XmlElement el in source.SelectNodes(xpath))
el.ParentNode.RemoveChild(el);
}
[Function("StripTimings")]
public static string StripTimings(string testResultFile, string outputFile)
{
try
{
XmlDocument testResults = new XmlDocument();
testResults.Load(testResultFile);
StripElements(testResults, "//stack-trace");
StripAttributes(testResults, "//@cwd");
StripAttributes(testResults, "//@total");
StripAttributes(testResults, "//@date");
StripAttributes(testResults, "//@time");
StripAttributes(testResults, "//@machine-name");
StripAttributes(testResults, "//@user");
StripAttributes(testResults, "//@user-domain");
outputFile = Path.GetDirectoryName(testResultFile) + "/" + outputFile;
testResults.Save(outputFile);
return outputFile;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public enum ResultStatus
{
None,
Failure,
Ignored,
Inconclusive,
Success
}
public class Result
{
public string Name;
public ResultStatus Status;
public bool Executed;
public bool Success;
public bool Inconclusive
{
get
{
return Executed && !Success && (Status == ResultStatus.Success || Status == ResultStatus.Inconclusive);
}
}
private static Result Parse(XmlNode testCase)
{
var result = new Result
{
Name = testCase.Attributes["name"].Value,
Executed = bool.Parse(testCase.Attributes["executed"].Value)
};
ResultStatus status;
Enum.TryParse<ResultStatus>(testCase.Attributes["result"].Value, out status);
result.Status = status;
if (result.Executed)
result.Success = bool.Parse(testCase.Attributes["success"].Value);
return result;
}
public override string ToString()
{
var prefix = "IGNORED - ";
if (Executed)
prefix = Success ? "PASS - " :
Inconclusive ? "INCONCL - " : "FAIL - ";
return prefix + Name;
}
public static IList<Result> ParseFile(string file)
{
var run1 = new XmlDocument();
run1.Load(file);
var results = new List<Result>();
foreach (XmlNode testCase in run1.SelectNodes("//test-case"))
{
var result = Parse(testCase);
results.Add(result);
}
return results;
}
}
[Function("CompareResults")]
public static string CompareResults(string currentResult, string lastResult)
{
try
{
var outputFile = Path.Combine(Path.GetDirectoryName(currentResult), "Comparison.txt");
var report = new StringBuilder();
report.AppendLine("Comparison Results");
report.AppendLine("==================");
var before = Result.ParseFile(lastResult);
var beforeByName = before
// Some multi-value tests may be duplicated
.GroupBy(b => b.Name)
.ToDictionary(
g => g.Key,
// Take one, preferably not failing first, thus ensuring an after failing test
// will be match as broken in case one of the dup was not failing.
g => g
// Succeeded
.OrderByDescending(r => r.Success)
// Else ignored
.ThenBy(r => r.Executed)
// Else inconclusive
.ThenBy(r => r.Inconclusive ? 0 : 1)
.First());
var after = Result.ParseFile(currentResult);
var newFailingTests = new List<Result>();
var newInconclusiveTests = new List<Result>();
var newNotFailingTests = new List<Result>();
var fixedTests = new List<Result>();
var ignoredTests = new List<Result>();
var brokenTests = new List<Result>();
var inconclusiveTests = new List<Result>();
var afterTestNames = new HashSet<string>();
foreach (var afterResult in after)
{
afterTestNames.Add(afterResult.Name);
Result beforeResult;
if (beforeByName.TryGetValue(afterResult.Name, out beforeResult))
{
if (!beforeResult.Success && afterResult.Success)
fixedTests.Add(afterResult);
if (beforeResult.Executed && !afterResult.Executed)
ignoredTests.Add(afterResult);
if (beforeResult.Success && afterResult.Executed && !afterResult.Success)
{
if (afterResult.Inconclusive)
inconclusiveTests.Add(afterResult);
else
brokenTests.Add(afterResult);
}
if (beforeResult.Inconclusive && afterResult.Executed && !afterResult.Success && !afterResult.Inconclusive)
brokenTests.Add(afterResult);
}
else
{
if (afterResult.Executed && !afterResult.Success)
{
if (afterResult.Inconclusive)
newInconclusiveTests.Add(afterResult);
else
newFailingTests.Add(afterResult);
}
else
newNotFailingTests.Add(afterResult);
}
}
var missingTests = new List<Result>();
foreach (var result in before)
if (!afterTestNames.Contains(result.Name))
missingTests.Add(result);
ReportResultGroup(report, brokenTests, "Tests broken since last recorded results");
ReportResultGroup(report, newFailingTests, "Tests new (failed) since last recorded results");
ReportResultGroup(report, inconclusiveTests, "Tests inconclusive since last recorded results");
ReportResultGroup(report, newInconclusiveTests, "Tests new (inconclusive) since last recorded results");
ReportResultGroup(report, fixedTests, "Tests fixed since last recorded results");
ReportResultGroup(report, ignoredTests, "Tests ignored since last recorded results");
ReportResultGroup(report, newNotFailingTests, "Tests new (not failing) since last recorded results");
ReportResultGroup(report, missingTests, "Tests missing since last recorded results");
var output = report.ToString();
File.WriteAllText(outputFile, output);
if (brokenTests.Count > 0)
throw new Exception("Previously passing tests have been broken\n\n" + output);
if (newFailingTests.Count > 0)
throw new Exception("New tests that fail have been added\n\n" + output);
return output;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public static void ReportResultGroup(StringBuilder report, IList<Result> resultGroup, string groupTitle)
{
report.AppendLine();
report.Append("*** ").Append(groupTitle).AppendLine(" ***");
if (resultGroup.Count > 0)
{
foreach (var result in resultGroup)
report.AppendLine(result.ToString());
}
else
report.AppendLine("None");
}
]]>
</code>
</script>
</project>