-
Notifications
You must be signed in to change notification settings - Fork 60
/
Remotion.BuildTargets.Testing.include.build
269 lines (225 loc) · 13.2 KB
/
Remotion.BuildTargets.Testing.include.build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
<?xml version="1.0" encoding="UTF-8" ?>
<!-- This file is part of the re-motion Core Framework (www.re-motion.org)
! Copyright (c) rubicon IT GmbH, www.rubicon.eu
!
! The re-motion Core Framework is free software; you can redistribute it
! and/or modify it under the terms of the GNU Lesser General Public License
! as published by the Free Software Foundation; either version 2.1 of the
! License, or (at your option) any later version.
!
! re-motion is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
! along with re-motion; if not, see http://www.gnu.org/licenses.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Constants -->
<PropertyGroup>
<NoDatabaseRequired>NoDatabaseRequired</NoDatabaseRequired>
</PropertyGroup>
<ItemGroup>
<NumberOfTestFailuresPerProject Include="0"/>
<NumberOfTestErrorsPerProject Include="0"/>
</ItemGroup>
<!-- Main target; reporting only, calls RunTestsInternal for actual work -->
<Target Name="RunTests" DependsOnTargets="CreateActiveConfiguration;CreateTestConfigurations;CreateLogDirectory;BuildTestProjects;LogRunTestsStartTime;RunTestsInternal">
<Error Text="ItemGroup 'NumberOfTestFailuresPerProject' is empty, but should contain test results!" Condition="@(NumberOfTestFailuresPerProject) == ''"/>
<Error Text="ItemGroup 'NumberOfTestErrorsPerProject' is empty, but should contain test results!" Condition="@(NumberOfTestErrorsPerProject) == ''"/>
<MSBuild.ExtensionPack.Science.Maths TaskAction="Add" Numbers="@(NumberOfTestFailuresPerProject)">
<Output PropertyName="_failures" TaskParameter="Result"/>
</MSBuild.ExtensionPack.Science.Maths>
<MSBuild.ExtensionPack.Science.Maths TaskAction="Add" Numbers="@(NumberOfTestErrorsPerProject)">
<Output PropertyName="_errors" TaskParameter="Result"/>
</MSBuild.ExtensionPack.Science.Maths>
<!-- NUnit-Task output error compensation. Remove when implementing RM-5154 (update of MSBuild Extension Pack) -->
<MSBuild.ExtensionPack.Science.Maths TaskAction="Subtract" Numbers="$(_failures);$(_errors)">
<Output PropertyName="_failures" TaskParameter="Result"/>
</MSBuild.ExtensionPack.Science.Maths>
<CallTarget Targets="CreateNUnitErrorsProperty" />
<Error
Text="Running Unit-Tests failed because of $(_failures) failures and/or $(_errors) errors in: %0A@(FailedProjects->'%(Identity) (%(Platform)/%(DatabaseSystem)) with %(Failures) failures and %(Errors) errors','%0A')"
Condition="$(_failures) > 0 or $(_errors) > 0"/>
<PropertyGroup>
<_timeTaken>$([System.DateTime]::UtcNow.Subtract($([System.DateTime]::Parse($(RunTestsStartTime)))).TotalMilliseconds.ToString(0))</_timeTaken>
</PropertyGroup>
<Message Text="##teamcity[buildStatisticValue key='Duration.RunTests.$(ConfigurationID)' value='$(_timeTaken)']"
Condition="'$(TEAMCITY_VERSION)' != ''" />
<Message Text="Done running tests, ConfigurationID=$(ConfigurationID)" Importance="High"/>
</Target>
<Target Name="LogRunTestsStartTime">
<PropertyGroup>
<RunTestsStartTime>$([System.DateTime]::UtcNow)</RunTestsStartTime>
</PropertyGroup>
</Target>
<!--
Actual testing happens here.
BuildTestOutputFilesCrossProduct creates all test configurations (the result is a cross product of TestOutputFiles x
AllPlatforms x AllDatabaseSystems), see description on the target for more information. Afterwards _testOutputFiles contains
entries like:
Identity = MyUnitTests1.dll ; Platform = x86 ; DatabaseSystem = SqlServer2005
Identity = MyUnitTests1.dll ; Platform = x64 ; DatabaseSystem = SqlServer2005
Identity = MyUnitTests1.dll ; Platform = x86 ; DatabaseSystem = SqlServer2008
...
Identity = MyUnitTests2.dll ; Platform = x86 ; DatabaseSystem = NoDatabaseRequired
...
(only relevant metadata shown)
RunTestsInternal uses target batching to be called once for each combination of "Identity;Platform;DatabaseSystem".
By batching over all the parameters, the _testOutputFiles-ItemGroup contains only a single item per batch.
-->
<Target Name="RunTestsInternal" DependsOnTargets="BuildTestOutputFilesCrossProduct" Outputs="%(_testOutputFiles.Identity);%(_testOutputFiles.Platform);%(_testOutputFiles.DatabaseSystem)">
<Message Text="Running tests %(_testOutputFiles.FullPath), ConfigurationID=$(ConfigurationID), Additional Configuration Information = %(_testOutputFiles.Platform), %(_testOutputFiles.DatabaseSystem)" Importance="High"/>
<MSBuild.ExtensionPack.Framework.MsBuildHelper TaskAction="GetItemCount" InputItems1="@(_testOutputFiles)">
<Output TaskParameter="ItemCount" PropertyName="_testOutputFilesCount"/>
</MSBuild.ExtensionPack.Framework.MsBuildHelper>
<Error Text="More than one item found in _testOutputFiles." Condition="$(_testOutputFilesCount) > 1" />
<PropertyGroup>
<_testAssemblyFileName>%(_testOutputFiles.Filename)</_testAssemblyFileName>
<_testAssemblyFullPath>%(_testOutputFiles.FullPath)</_testAssemblyFullPath>
<_use32Bit>%(_testOutputFiles.Use32Bit)</_use32Bit>
<_platform>%(_testOutputFiles.Platform)</_platform>
<_databaseSystem>%(_testOutputFiles.DatabaseSystem)</_databaseSystem>
<_dataSource>%(_testOutputFiles.DataSource)</_dataSource>
<_databaseDirectory>%(_testOutputFiles.DatabaseDirectory)</_databaseDirectory>
<_appConfigFile>%(_testOutputFiles.FullPath).config</_appConfigFile>
</PropertyGroup>
<!-- Adapt App.Config to use correct database -->
<ItemGroup>
<_appConfigAttributes Remove="@(_appConfigAttributes)"/>
<_appConfigAttributes Include="/configuration/appSettings/add[@key='DataSource']">
<Key>value</Key>
<Value>$(_dataSource)</Value>
</_appConfigAttributes>
<_appConfigAttributes Include="/configuration/appSettings/add[@key='DatabaseDirectory']">
<Key>value</Key>
<Value>$(_databaseDirectory)</Value>
</_appConfigAttributes>
</ItemGroup>
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="UpdateAttribute"
File="$(_appConfigFile)"
XPath="%(_appConfigAttributes.Identity)"
Key="%(_appConfigAttributes.Key)"
Value="%(_appConfigAttributes.Value)"
Condition="'$(_databaseSystem)' != '$(NoDatabaseRequired)'"/>
<!-- Run tests -->
<PropertyGroup>
<_testName>$(_testAssemblyFileName).$(ActiveConfigurationName).$(_platform).$(_databaseSystem)</_testName>
<_testResultFile>$(LogDirectory)$(_testName).xml</_testResultFile>
</PropertyGroup>
<MSBuild.ExtensionPack.CodeQuality.NUnit
ToolPath="$(NUnitToolPath)"
Assemblies="$(_testAssemblyFullPath)"
ContinueOnError="True"
Framework="$(ActiveConfigurationFramework)"
Use32Bit="$(_use32Bit)"
NoShadow="True"
OutputXmlFile="$(_testResultFile)">
<Output TaskParameter="Failures" PropertyName="_nunit_failures"/>
<Output TaskParameter="Errors" PropertyName="_nunit_errors"/>
</MSBuild.ExtensionPack.CodeQuality.NUnit>
<Message Text="##teamcity[importData type='nunit' path='$(_testResultFile)' verbose='true' whenNoDataPublished='error']"
Condition="'$(TEAMCITY_VERSION)' != ''" />
<MSBuild.ExtensionPack.Xml.XmlFile
TaskAction="ReadAttribute"
File="$(_testResultFile)"
XPath="/test-results/test-suite/@time">
<Output TaskParameter="Value" PropertyName="_testTime" />
</MSBuild.ExtensionPack.Xml.XmlFile>
<MSBuild.ExtensionPack.Framework.TextString TaskAction="Replace" OldString="$(_testTime)" OldValue="." NewValue="">
<Output TaskParameter="NewString" PropertyName="_testTime" />
</MSBuild.ExtensionPack.Framework.TextString>
<Message Text="##teamcity[buildStatisticValue key='$(_testName)' value='$(_testTime)']"
Condition="'$(TEAMCITY_VERSION)' != ''" />
<ItemGroup Condition="$(_nunit_failures) > 0 or $(_nunit_errors) > 0">
<NumberOfTestFailuresPerProject Include="$(_nunit_failures)" />
<NumberOfTestErrorsPerProject Include="$(_nunit_errors)" />
<FailedProjects Include="$(_testAssemblyFullPath)">
<Platform>$(_platform)</Platform>
<DatabaseSystem>$(_databaseSystem)</DatabaseSystem>
<Failures>$(_nunit_failures)</Failures>
<Errors>$(_nunit_errors)</Errors>
</FailedProjects>
</ItemGroup>
</Target>
<!--
BuildTestOutputFilesCrossProduct creates all test configurations (the result is a cross product of TestOutputFiles x
AllPlatforms x AllDatabaseSystems).
Building cross products with MSBuild is not straightforward, see:
http://coding-insomnia.com/2007/02/02/generating-a-cross-product-with-msbuild/
for more details.
-->
<Target Name="BuildTestOutputFilesCrossProduct">
<!-- Step 1: Build the cross product testOutputFiles1 = TestOutputFiles x AllPlatforms -->
<CreateItem Include="@(TestOutputFiles)"
AdditionalMetadata="Platform=%(AllPlatforms.Identity);
Use32Bit=%(AllPlatforms.Use32Bit)">
<Output ItemName="_testOutputFiles1" TaskParameter="Include"/>
</CreateItem>
<!-- Step 2: Build the cross product _testOutputFiles2 = _testOutputFiles1 x AllDatabaseSystems
Warning: Contains also entries for %(_testOutputFiles1.IsDatabaseTest) == False as well! -->
<CreateItem Include="@(_testOutputFiles1)"
AdditionalMetadata="DatabaseSystem=%(AllDatabaseSystems.Identity);
DataSource=%(AllDatabaseSystems.DataSource);
DatabaseDirectory=%(AllDatabaseSystems.DatabaseDirectory)">
<!-- Condition="'%(IsDatabaseTest)' == 'True'" not possible (double batching) => filter afterwards -->
<Output ItemName="_testOutputFiles2" TaskParameter="Include"/>
</CreateItem>
<!-- Step 3: Filter entries, _testOutputFiles3 = _testOutputFiles2 where %(IsDatabaseTest) -->
<ItemGroup>
<_testOutputFiles3 Remove="@(_testOutputFiles3)"/>
<_testOutputFiles3 Include="@(_testOutputFiles2)" Condition="'%(IsDatabaseTest)' == 'True'"/>
</ItemGroup>
<!-- Step 4: Add additional $(NoDatabaseRequired)-metadata to _testOutputFiles1 where !%(IsDatabaseText) -> _testOutputFiles4 -->
<CreateItem Include="@(_testOutputFiles1)"
AdditionalMetadata="DatabaseSystem=$(NoDatabaseRequired);
DataSource=;
DatabaseDirectory="
Condition="'%(IsDatabaseTest)' == 'False'">
<Output ItemName="_testOutputFiles4" TaskParameter="Include"/>
</CreateItem>
<!-- Step 5: _testOutputFiles = _testOutputFiles3 + _testOutputFiles4 -->
<ItemGroup>
<_testOutputFiles Remove="@(_testOutputFiles)"/>
<_testOutputFiles Include="@(_testOutputFiles3)"/>
<_testOutputFiles Include="@(_testOutputFiles4)"/>
</ItemGroup>
<!-- Print all created configurations -->
<Message Text="Created test configuration: $(ActiveConfigurationName) %(_testOutputFiles.FullPath) %(_testOutputFiles.Platform) %(_testOutputFiles.DatabaseSystem)" Importance="high"/>
</Target>
<Target Name="CreateNUnitErrorsProperty" Condition="'$(TEAMCITY_VERSION)' != ''">
<!-- Create temp directory for transformed files -->
<PropertyGroup>
<_tempDir>$(LogDirectory)\output\</_tempDir>
</PropertyGroup>
<MakeDir Directories="$(_tempDir)"/>
<!-- Find all NUnit result files -->
<ItemGroup>
<_nunitTestResultFiles Include="$(LogDirectory)\Remotion.*Tests.*.xml">
<OutputPath></OutputPath>
</_nunitTestResultFiles>
<_nunitTestResultFiles>
<OutputPath>$(_tempDir)\%(FileName).output.xml</OutputPath>
</_nunitTestResultFiles>
</ItemGroup>
<!-- Transform NUnit result files to temporary files containing failures/errors only -->
<XslTransformation XmlInputPaths="%(_nunitTestResultFiles.Identity)"
XslInputPath="$(MSBuildProjectDirectory)\NUnitErrors.xslt"
OutputPaths="%(_nunitTestResultFiles.OutputPath)"
Condition="@(_nunitTestResultFiles) != ''"/>
<!-- XslTransformation outputs files, read all files into one single property -->
<ItemGroup>
<_fileContents Include="$([System.IO.File]::ReadAllText (%(_nunitTestResultFiles.OutputPath)))"/>
</ItemGroup>
<PropertyGroup>
<!-- Two new lines are required, do not reformat! -->
<_mergedFileContents>@(_fileContents,'
')</_mergedFileContents>
</PropertyGroup>
<!-- Output for TeamCity -->
<Message Condition="'$(TEAMCITY_VERSION)' != '' and '$(_mergedFileContents)' != ''" Text="##teamcity[setParameter name='nunit_errors' value='$(_mergedFileContents)']" />
<!-- Delete temp directory containing transformed files -->
<RemoveDir Directories="$(_tempDir)"/>
</Target>
</Project>