@@ -9,6 +9,7 @@ namespace InteropTests;
9
9
10
10
// All interop test cases, minus GCE authentication specific tests.
11
11
// Tests are separate methods so that they can be quarantined separately.
12
+ [ Retry ]
12
13
public class InteropTests
13
14
{
14
15
private static readonly TimeSpan DefaultTimeout = TimeSpan . FromSeconds ( 100 ) ;
@@ -83,13 +84,48 @@ public InteropTests(ITestOutputHelper output)
83
84
84
85
private async Task InteropTestCase ( string name )
85
86
{
87
+ // Building interop tests processes can be flaky. Sometimes it times out.
88
+ // To mitigate this, we retry the test case a few times on timeout.
89
+ const int maxRetries = 3 ;
90
+ var attempt = 0 ;
91
+
92
+ while ( true )
93
+ {
94
+ attempt ++ ;
95
+
96
+ try
97
+ {
98
+ await InteropTestCaseCore ( name ) ;
99
+ break ; // Exit loop on success
100
+ }
101
+ catch ( TimeoutException ex )
102
+ {
103
+ _output . WriteLine ( $ "Attempt { attempt } failed: { ex . Message } ") ;
104
+
105
+ if ( attempt == maxRetries )
106
+ {
107
+ _output . WriteLine ( "Maximum retry attempts reached. Giving up." ) ;
108
+ throw ;
109
+ }
110
+ else
111
+ {
112
+ await Task . Delay ( TimeSpan . FromSeconds ( 1 ) ) ;
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ private async Task InteropTestCaseCore ( string name )
119
+ {
120
+ _output . WriteLine ( $ "Starting { nameof ( WebsiteProcess ) } .") ;
86
121
using ( var serverProcess = new WebsiteProcess ( _serverPath , _output ) )
87
122
{
88
123
try
89
124
{
125
+ _output . WriteLine ( $ "Waiting for { nameof ( WebsiteProcess ) } to be ready.") ;
90
126
await serverProcess . WaitForReady ( ) . TimeoutAfter ( DefaultTimeout ) ;
91
127
}
92
- catch ( Exception ex )
128
+ catch ( Exception ex ) when ( ex is not TimeoutException )
93
129
{
94
130
var errorMessage = $@ "Error while running server process.
95
131
@@ -102,17 +138,20 @@ private async Task InteropTestCase(string name)
102
138
throw new InvalidOperationException ( errorMessage , ex ) ;
103
139
}
104
140
141
+ _output . WriteLine ( $ "Starting { nameof ( ClientProcess ) } .") ;
105
142
using ( var clientProcess = new ClientProcess ( _output , _clientPath , serverProcess . ServerPort , name ) )
106
143
{
107
144
try
108
145
{
146
+ _output . WriteLine ( $ "Waiting for { nameof ( ClientProcess ) } to be ready.") ;
109
147
await clientProcess . WaitForReadyAsync ( ) . TimeoutAfter ( DefaultTimeout ) ;
110
148
149
+ _output . WriteLine ( $ "Waiting for { nameof ( ClientProcess ) } to exit.") ;
111
150
await clientProcess . WaitForExitAsync ( ) . TimeoutAfter ( DefaultTimeout ) ;
112
151
113
152
Assert . Equal ( 0 , clientProcess . ExitCode ) ;
114
153
}
115
- catch ( Exception ex )
154
+ catch ( Exception ex ) when ( ex is not TimeoutException )
116
155
{
117
156
var errorMessage = $@ "Error while running client process.
118
157
0 commit comments