17
17
18
18
namespace Microsoft . DotNet . SourceBuild . SmokeTests ;
19
19
20
- [ Trait ( "Category" , "SdkContent" ) ]
21
20
public class ArtifactsSizeTests : SdkTests
22
21
{
23
- private const int SizeThresholdPercentage = 25 ;
24
- private static readonly string BaselineFilePath = BaselineHelper . GetBaselineFilePath ( $ "{ Config . TargetRid } .txt", nameof ( ArtifactsSizeTests ) ) ;
25
- private readonly Dictionary < string , long > Baseline = new ( ) ;
26
- private Dictionary < string , int > FilePathCountMap = new ( ) ;
27
- private StringBuilder Differences = new ( ) ;
22
+ private const string SdkType = "sdk" ;
23
+ private readonly StringBuilder _differences = new ( ) ;
24
+ private readonly List < string > _newExclusions = new List < string > ( ) ;
25
+ private readonly Dictionary < string , int > _filePathCountMap = new ( ) ;
26
+ private readonly ExclusionsHelper _exclusionsHelper = new ExclusionsHelper ( "ZeroSizeExclusions.txt" , nameof ( ArtifactsSizeTests ) ) ;
27
+ public static bool IncludeArtifactsSizeTests => ! string . IsNullOrWhiteSpace ( Config . SdkTarballPath ) ;
28
28
29
- public ArtifactsSizeTests ( ITestOutputHelper outputHelper ) : base ( outputHelper )
30
- {
31
- if ( File . Exists ( BaselineFilePath ) )
32
- {
33
- string [ ] baselineFileContent = File . ReadAllLines ( BaselineFilePath ) ;
34
- foreach ( string entry in baselineFileContent )
35
- {
36
- string [ ] splitEntry = entry . Split ( ':' , StringSplitOptions . TrimEntries ) ;
37
- Baseline [ splitEntry [ 0 ] ] = long . Parse ( splitEntry [ 1 ] ) ;
38
- }
39
- }
40
- else
41
- {
42
- Assert . Fail ( $ "Baseline file `{ BaselineFilePath } ' does not exist. Please create the baseline file then rerun the test.") ;
43
- }
44
- }
29
+ public ArtifactsSizeTests ( ITestOutputHelper outputHelper ) : base ( outputHelper ) { }
45
30
46
- [ ConditionalFact ( typeof ( Config ) , nameof ( Config . IncludeArtifactsSizeTests ) ) ]
47
- public void CompareArtifactsToBaseline ( )
31
+ [ ConditionalFact ( typeof ( ArtifactsSizeTests ) , nameof ( IncludeArtifactsSizeTests ) ) ]
32
+ public void CheckZeroSizeArtifacts ( )
48
33
{
49
- Assert . False ( string . IsNullOrWhiteSpace ( Config . SourceBuiltArtifactsPath ) ) ;
50
- Assert . False ( string . IsNullOrWhiteSpace ( Config . SdkTarballPath ) ) ;
34
+ ProcessTarball ( Config . SdkTarballPath ! , SdkType ) ;
51
35
52
- var tarEntries = ProcessSdkAndArtifactsTarballs ( ) ;
53
- ScanForDifferences ( tarEntries ) ;
54
- UpdateBaselineFile ( ) ;
36
+ _exclusionsHelper . GenerateNewBaselineFile ( updatedFileTag : null , _newExclusions ) ;
55
37
56
- // Must wait to report differences until after the baseline file is updated else a failure
57
- // will cause the baseline file to not be updated.
38
+ // Wait to report differences until after the baseline file is updated.
39
+ // Else a failure will cause the baseline file to not be updated.
58
40
ReportDifferences ( ) ;
59
41
}
60
42
61
- private Dictionary < string , long > ProcessSdkAndArtifactsTarballs ( )
43
+ private void ProcessTarball ( string tarballPath , string type )
62
44
{
63
45
string tempTarballDir = Path . Combine ( Path . GetTempPath ( ) , Path . GetRandomFileName ( ) ) ;
64
46
Directory . CreateDirectory ( tempTarballDir ) ;
65
47
66
- Utilities . ExtractTarball ( Config . SdkTarballPath ! , tempTarballDir , OutputHelper ) ;
67
- Utilities . ExtractTarball ( Config . SourceBuiltArtifactsPath ! , tempTarballDir , OutputHelper ) ;
48
+ Utilities . ExtractTarball ( tarballPath , tempTarballDir , OutputHelper ) ;
68
49
69
- Dictionary < string , long > tarEntries = Directory . EnumerateFiles ( tempTarballDir , "*" , SearchOption . AllDirectories )
70
- . Where ( filePath => ! filePath . Contains ( "SourceBuildReferencePackages" ) )
71
- . Select ( filePath =>
72
- {
73
- string relativePath = filePath . Substring ( tempTarballDir . Length + 1 ) ;
74
- return ( ProcessFilePath ( relativePath ) , new FileInfo ( filePath ) . Length ) ;
75
- } )
76
- . ToDictionary ( tuple => tuple . Item1 , tuple => tuple . Item2 ) ;
50
+ var newZeroSizedFiles = Directory
51
+ . EnumerateFiles ( tempTarballDir , "*" , SearchOption . AllDirectories )
52
+ . Where ( filePath => new FileInfo ( filePath ) . Length == 0 )
53
+ . Select ( filePath => ProcessFilePath ( tempTarballDir , filePath ) )
54
+ . Where ( processedPath => ! _exclusionsHelper . IsFileExcluded ( processedPath , type ) ) ;
77
55
78
- Directory . Delete ( tempTarballDir , true ) ;
56
+ foreach ( string file in newZeroSizedFiles )
57
+ {
58
+ _newExclusions . Add ( $ "{ file } |{ type } ") ;
59
+ TrackDifference ( $ "{ file } is 0 bytes.") ;
60
+ }
79
61
80
- return tarEntries ;
62
+ Directory . Delete ( tempTarballDir , true ) ;
81
63
}
82
64
83
- private string ProcessFilePath ( string originalPath )
65
+ private string ProcessFilePath ( string relativeTo , string originalPath )
84
66
{
85
- string result = BaselineHelper . RemoveRids ( originalPath ) ;
67
+ string relativePath = Path . GetRelativePath ( relativeTo , originalPath ) ;
68
+ string result = BaselineHelper . RemoveRids ( relativePath ) ;
86
69
result = BaselineHelper . RemoveVersions ( result ) ;
87
70
88
71
return AddDifferenciatingSuffix ( result ) ;
@@ -111,8 +94,8 @@ private string AddDifferenciatingSuffix(string filePath)
111
94
112
95
if ( matchIndex != - 1 )
113
96
{
114
- int count = FilePathCountMap . TryGetValue ( filePath , out count ) ? count : 0 ;
115
- FilePathCountMap [ filePath ] = count + 1 ;
97
+ int count = _filePathCountMap . TryGetValue ( filePath , out count ) ? count : 0 ;
98
+ _filePathCountMap [ filePath ] = count + 1 ;
116
99
117
100
if ( count > 0 )
118
101
{
@@ -123,94 +106,14 @@ private string AddDifferenciatingSuffix(string filePath)
123
106
return filePath ;
124
107
}
125
108
126
- private void ScanForDifferences ( Dictionary < string , long > tarEntries )
127
- {
128
- foreach ( var entry in tarEntries )
129
- {
130
- if ( ! Baseline . TryGetValue ( entry . Key , out long baselineBytes ) )
131
- {
132
- TrackDifference ( $ "{ entry . Key } does not exist in baseline. It is { entry . Value } bytes. Adding it to the baseline file.") ;
133
- Baseline . Add ( entry . Key , entry . Value ) ;
134
- }
135
- else
136
- {
137
- CompareFileSizes ( entry . Key , entry . Value , baselineBytes ) ;
138
- }
139
- }
140
-
141
- foreach ( var removedFile in Baseline . Keys . Except ( tarEntries . Keys ) )
142
- {
143
- TrackDifference ( $ "`{ removedFile } ` is no longer being produced. It was { Baseline [ removedFile ] } bytes.") ;
144
- Baseline . Remove ( removedFile ) ;
145
- }
146
- }
147
-
148
- private void CompareFileSizes ( string filePath , long fileSize , long baselineSize )
149
- {
150
- // Only update the baseline with breaking differences. Non-breaking differences are file size changes
151
- // less than the threshold percentage. This makes it easier to review the breaking changes and prevents
152
- // inadvertently allowing small percentage changes to be accepted that can add up to a significant
153
- // difference over time.
154
- string breakingDifference = string . Empty ;
155
-
156
- if ( fileSize == 0 && baselineSize != 0 )
157
- {
158
- breakingDifference = $ "'{ filePath } ' is now 0 bytes. It was { baselineSize } bytes.";
159
- }
160
- else if ( fileSize != 0 && baselineSize == 0 )
161
- {
162
- breakingDifference = $ "'{ filePath } ' is no longer 0 bytes. It is now { fileSize } bytes.";
163
- }
164
- else if ( baselineSize != 0 && ( ( ( fileSize - baselineSize ) / ( double ) baselineSize ) * 100 ) >= SizeThresholdPercentage )
165
- {
166
- breakingDifference =
167
- $ "'{ filePath } ' increased in size by more than { SizeThresholdPercentage } %. It was originally { baselineSize } bytes and is now { fileSize } bytes.";
168
- }
169
- else if ( baselineSize != 0 && ( ( ( baselineSize - fileSize ) / ( double ) baselineSize ) * 100 ) >= SizeThresholdPercentage )
170
- {
171
- breakingDifference =
172
- $ "'{ filePath } ' decreased in size by more than { SizeThresholdPercentage } %. It was originally { baselineSize } bytes and is now { fileSize } bytes.";
173
- }
174
-
175
- if ( ! string . IsNullOrEmpty ( breakingDifference ) )
176
- {
177
- TrackDifference ( breakingDifference ) ;
178
- Baseline [ filePath ] = fileSize ;
179
- }
180
- }
181
-
182
- private void TrackDifference ( string difference ) => Differences . AppendLine ( difference ) ;
109
+ private void TrackDifference ( string difference ) => _differences . AppendLine ( difference ) ;
183
110
184
111
private void ReportDifferences ( )
185
112
{
186
- if ( Differences . Length > 0 )
187
- {
188
- if ( Config . WarnOnSdkContentDiffs )
189
- {
190
- OutputHelper . LogWarningMessage ( Differences . ToString ( ) ) ;
191
- }
192
- else
193
- {
194
- OutputHelper . WriteLine ( Differences . ToString ( ) ) ;
195
- Assert . Fail ( "Differences were found in the artifacts sizes." ) ;
196
- }
197
- }
198
- }
199
-
200
- private void UpdateBaselineFile ( )
201
- {
202
- try
203
- {
204
- string actualFilePath = Path . Combine ( Config . LogsDirectory , $ "Updated{ Config . TargetRid } .txt") ;
205
- File . WriteAllLines (
206
- actualFilePath ,
207
- Baseline
208
- . OrderBy ( kvp => kvp . Key )
209
- . Select ( kvp => $ "{ kvp . Key } : { kvp . Value } ") ) ;
210
- }
211
- catch ( IOException ex )
113
+ if ( _differences . Length > 0 )
212
114
{
213
- throw new InvalidOperationException ( $ "An error occurred while copying the baselines file: { BaselineFilePath } ", ex ) ;
115
+ OutputHelper . LogWarningMessage ( _differences . ToString ( ) ) ;
116
+ Assert . Fail ( "Differences were found in the artifacts sizes." ) ;
214
117
}
215
118
}
216
119
}
0 commit comments