5
5
using System ;
6
6
using System . Collections . Generic ;
7
7
using System . IO ;
8
+ using System . Linq ;
8
9
using System . Net ;
9
10
using System . Net . Http ;
10
11
using System . Threading ;
@@ -21,6 +22,12 @@ public abstract class RemoteApplicationFixture : IDisposable
21
22
22
23
private Action _setupConfiguration ;
23
24
private Action _exerciseApplication ;
25
+ private HashSet < uint > _errorsToRetryOn = new HashSet < uint >
26
+ {
27
+ 0xC000_0005 // System.AccessViolationException. This is a .NET bug that
28
+ // is supposed to be fixed but we're still seeing
29
+ // https://github.com/dotnet/runtime/issues/62145
30
+ } ;
24
31
25
32
public Dictionary < string , string > EnvironmentVariables ;
26
33
@@ -88,8 +95,8 @@ public bool KeepWorkingDirectory
88
95
set { RemoteApplication . KeepWorkingDirectory = value ; }
89
96
}
90
97
91
- // We think that the test retry loop may be masking real problems and/or actually causing them, so we've disabled it for now
92
- protected virtual int MaxTries => 1 ;
98
+ // Tests are only retried if they return a known error not related to the test
99
+ protected virtual int MaxTries => 3 ;
93
100
94
101
public void DisableAsyncLocalCallStack ( )
95
102
{
@@ -190,11 +197,23 @@ public RemoteApplicationFixture SetAdditionalEnvironmentVariable(string key, str
190
197
return this ;
191
198
}
192
199
200
+ public void AddErrorToRetryOn ( uint error )
201
+ {
202
+ _errorsToRetryOn . Add ( error ) ;
203
+ }
204
+
193
205
private void ExerciseApplication ( )
194
206
{
195
207
_exerciseApplication ? . Invoke ( ) ;
196
208
}
197
209
210
+ private string FormatExitCode ( int ? exitCode )
211
+ {
212
+ if ( exitCode == null ) return "[null]" ;
213
+ if ( Math . Abs ( exitCode . Value ) < 10 ) return exitCode . Value . ToString ( ) ;
214
+ return exitCode . Value . ToString ( "X8" ) ;
215
+ }
216
+
198
217
public virtual void Initialize ( )
199
218
{
200
219
lock ( _initializeLock )
@@ -214,16 +233,14 @@ public virtual void Initialize()
214
233
try
215
234
{
216
235
var retryTest = false ;
217
- var exceptionInExerciseApplication = false ;
236
+ var retryMessage = "" ;
218
237
var applicationHadNonZeroExitCode = false ;
219
238
220
-
221
239
do
222
240
{
223
241
TestLogger ? . WriteLine ( "Test Home" + RemoteApplication . DestinationNewRelicHomeDirectoryPath ) ;
224
242
225
243
// reset these for each loop iteration
226
- exceptionInExerciseApplication = false ;
227
244
applicationHadNonZeroExitCode = false ;
228
245
retryTest = false ;
229
246
@@ -245,8 +262,9 @@ public virtual void Initialize()
245
262
}
246
263
catch ( Exception ex )
247
264
{
248
- exceptionInExerciseApplication = true ;
265
+ retryTest = true ;
249
266
TestLogger ? . WriteLine ( "Exception occurred in try number " + ( numberOfTries + 1 ) + " : " + ex . ToString ( ) ) ;
267
+ retryMessage = "Exception thrown." ;
250
268
}
251
269
finally
252
270
{
@@ -278,15 +296,19 @@ public virtual void Initialize()
278
296
RemoteApplication . WaitForExit ( ) ;
279
297
280
298
applicationHadNonZeroExitCode = RemoteApplication . ExitCode != 0 ;
299
+ var formattedExitCode = FormatExitCode ( RemoteApplication . ExitCode ) ;
281
300
282
- TestLogger ? . WriteLine ( $ "Remote application exited with a { ( applicationHadNonZeroExitCode ? "failure" : "success" ) } exit code of { RemoteApplication . ExitCode } .") ;
301
+ TestLogger ? . WriteLine ( $ "Remote application exited with a { ( applicationHadNonZeroExitCode ? "failure" : "success" ) } exit code of { formattedExitCode } .") ;
283
302
284
- retryTest = exceptionInExerciseApplication || applicationHadNonZeroExitCode ;
303
+ if ( applicationHadNonZeroExitCode && _errorsToRetryOn . Contains ( ( uint ) RemoteApplication . ExitCode . Value ) )
304
+ {
305
+ retryMessage = $ "{ formattedExitCode } is a known error.";
306
+ retryTest = true ;
307
+ }
285
308
286
- if ( retryTest )
309
+ if ( retryTest && ( numberOfTries < MaxTries ) )
287
310
{
288
- var message = $ "Retrying test. Exception caught when exercising test app = { exceptionInExerciseApplication } , application had non-zero exit code = { applicationHadNonZeroExitCode } .";
289
- TestLogger ? . WriteLine ( message ) ;
311
+ TestLogger ? . WriteLine ( retryMessage + " Retrying test." ) ;
290
312
Thread . Sleep ( 1000 ) ;
291
313
numberOfTries ++ ;
292
314
}
0 commit comments