@@ -15,7 +15,9 @@ package azure
15
15
// limitations under the License.
16
16
17
17
import (
18
+ "context"
18
19
"encoding/json"
20
+ "errors"
19
21
"fmt"
20
22
"io/ioutil"
21
23
"net/http"
@@ -634,7 +636,7 @@ func TestDoPollForAsynchronous_PollsForStatusAccepted(t *testing.T) {
634
636
r , _ := autorest .SendWithSender (client , mocks .NewRequest (),
635
637
DoPollForAsynchronous (time .Millisecond ))
636
638
637
- if client .Attempts () < 4 {
639
+ if client .Attempts () < client . NumResponses () {
638
640
t .Fatalf ("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource" )
639
641
}
640
642
@@ -657,7 +659,7 @@ func TestDoPollForAsynchronous_PollsForStatusCreated(t *testing.T) {
657
659
r , _ := autorest .SendWithSender (client , mocks .NewRequest (),
658
660
DoPollForAsynchronous (time .Millisecond ))
659
661
660
- if client .Attempts () < 4 {
662
+ if client .Attempts () < client . NumResponses () {
661
663
t .Fatalf ("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource" )
662
664
}
663
665
@@ -681,7 +683,7 @@ func TestDoPollForAsynchronous_PollsUntilProvisioningStatusTerminates(t *testing
681
683
r , _ := autorest .SendWithSender (client , mocks .NewRequest (),
682
684
DoPollForAsynchronous (time .Millisecond ))
683
685
684
- if client .Attempts () < 4 {
686
+ if client .Attempts () < client . NumResponses () {
685
687
t .Fatalf ("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource" )
686
688
}
687
689
@@ -705,7 +707,7 @@ func TestDoPollForAsynchronous_PollsUntilProvisioningStatusSucceeds(t *testing.T
705
707
r , _ := autorest .SendWithSender (client , mocks .NewRequest (),
706
708
DoPollForAsynchronous (time .Millisecond ))
707
709
708
- if client .Attempts () < 4 {
710
+ if client .Attempts () < client . NumResponses () {
709
711
t .Fatalf ("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource" )
710
712
}
711
713
@@ -726,7 +728,7 @@ func TestDoPollForAsynchronous_PollsUntilOperationResourceHasTerminated(t *testi
726
728
r , _ := autorest .SendWithSender (client , mocks .NewRequest (),
727
729
DoPollForAsynchronous (time .Millisecond ))
728
730
729
- if client .Attempts () < 4 {
731
+ if client .Attempts () < client . NumResponses () {
730
732
t .Fatalf ("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource" )
731
733
}
732
734
@@ -747,7 +749,7 @@ func TestDoPollForAsynchronous_PollsUntilOperationResourceHasSucceeded(t *testin
747
749
r , _ := autorest .SendWithSender (client , mocks .NewRequest (),
748
750
DoPollForAsynchronous (time .Millisecond ))
749
751
750
- if client .Attempts () < 4 {
752
+ if client .Attempts () < client . NumResponses () {
751
753
t .Fatalf ("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource" )
752
754
}
753
755
@@ -876,7 +878,7 @@ func TestDoPollForAsynchronous_ReturnsErrorForLastErrorResponse(t *testing.T) {
876
878
r1 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
877
879
r2 := newProvisioningStatusResponse ("busy" )
878
880
r2 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
879
- r3 := newAsynchronousResponseWithError ()
881
+ r3 := newAsynchronousResponseWithError ("400 Bad Request" , http . StatusBadRequest )
880
882
r3 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
881
883
882
884
client := mocks .NewSender ()
@@ -923,7 +925,7 @@ func TestDoPollForAsynchronous_ReturnsOperationResourceErrorForFailedOperations(
923
925
924
926
func TestDoPollForAsynchronous_ReturnsErrorForFirstPutRequest (t * testing.T ) {
925
927
// Return 400 bad response with error code and message in first put
926
- r1 := newAsynchronousResponseWithError ()
928
+ r1 := newAsynchronousResponseWithError ("400 Bad Request" , http . StatusBadRequest )
927
929
client := mocks .NewSender ()
928
930
client .AppendResponse (r1 )
929
931
@@ -1044,7 +1046,7 @@ func TestFuture_PollsUntilProvisioningStatusSucceeds(t *testing.T) {
1044
1046
time .Sleep (delay )
1045
1047
}
1046
1048
1047
- if client .Attempts () < 4 {
1049
+ if client .Attempts () < client . NumResponses () {
1048
1050
t .Fatalf ("azure: TestFuture stopped polling before receiving a terminated OperationResource" )
1049
1051
}
1050
1052
@@ -1096,6 +1098,129 @@ func TestFuture_Marshalling(t *testing.T) {
1096
1098
}
1097
1099
}
1098
1100
1101
+ func TestFuture_WaitForCompletion (t * testing.T ) {
1102
+ r1 := newAsynchronousResponse ()
1103
+ r1 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1104
+ r2 := newProvisioningStatusResponse ("busy" )
1105
+ r2 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1106
+ r3 := newAsynchronousResponseWithError ("Internal server error" , http .StatusInternalServerError )
1107
+ r3 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1108
+ r3 .Header .Del (http .CanonicalHeaderKey ("Retry-After" ))
1109
+ r4 := newProvisioningStatusResponse (operationSucceeded )
1110
+ r4 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1111
+
1112
+ sender := mocks .NewSender ()
1113
+ sender .AppendResponse (r1 )
1114
+ sender .AppendError (errors .New ("transient network failure" ))
1115
+ sender .AppendAndRepeatResponse (r2 , 2 )
1116
+ sender .AppendResponse (r3 )
1117
+ sender .AppendResponse (r4 )
1118
+
1119
+ future := NewFuture (mocks .NewRequest ())
1120
+
1121
+ client := autorest.Client {
1122
+ PollingDelay : 1 * time .Second ,
1123
+ PollingDuration : autorest .DefaultPollingDuration ,
1124
+ RetryAttempts : autorest .DefaultRetryAttempts ,
1125
+ RetryDuration : 1 * time .Second ,
1126
+ Sender : sender ,
1127
+ }
1128
+
1129
+ err := future .WaitForCompletion (context .Background (), client )
1130
+ if err != nil {
1131
+ t .Fatalf ("azure: WaitForCompletion returned non-nil error" )
1132
+ }
1133
+
1134
+ if sender .Attempts () < sender .NumResponses () {
1135
+ t .Fatalf ("azure: TestFuture stopped polling before receiving a terminated OperationResource" )
1136
+ }
1137
+
1138
+ autorest .Respond (future .Response (),
1139
+ autorest .ByClosing ())
1140
+ }
1141
+
1142
+ func TestFuture_WaitForCompletionTimedOut (t * testing.T ) {
1143
+ r1 := newAsynchronousResponse ()
1144
+ r1 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1145
+ r2 := newProvisioningStatusResponse ("busy" )
1146
+ r2 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1147
+
1148
+ sender := mocks .NewSender ()
1149
+ sender .AppendResponse (r1 )
1150
+ sender .AppendAndRepeatResponseWithDelay (r2 , 1 * time .Second , 5 )
1151
+
1152
+ future := NewFuture (mocks .NewRequest ())
1153
+
1154
+ client := autorest.Client {
1155
+ PollingDelay : autorest .DefaultPollingDelay ,
1156
+ PollingDuration : 2 * time .Second ,
1157
+ RetryAttempts : autorest .DefaultRetryAttempts ,
1158
+ RetryDuration : 1 * time .Second ,
1159
+ Sender : sender ,
1160
+ }
1161
+
1162
+ err := future .WaitForCompletion (context .Background (), client )
1163
+ if err == nil {
1164
+ t .Fatalf ("azure: WaitForCompletion returned nil error, should have timed out" )
1165
+ }
1166
+ }
1167
+
1168
+ func TestFuture_WaitForCompletionRetriesExceeded (t * testing.T ) {
1169
+ r1 := newAsynchronousResponse ()
1170
+ r1 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1171
+
1172
+ sender := mocks .NewSender ()
1173
+ sender .AppendResponse (r1 )
1174
+ sender .AppendAndRepeatError (errors .New ("transient network failure" ), autorest .DefaultRetryAttempts + 1 )
1175
+
1176
+ future := NewFuture (mocks .NewRequest ())
1177
+
1178
+ client := autorest.Client {
1179
+ PollingDelay : autorest .DefaultPollingDelay ,
1180
+ PollingDuration : autorest .DefaultPollingDuration ,
1181
+ RetryAttempts : autorest .DefaultRetryAttempts ,
1182
+ RetryDuration : 100 * time .Millisecond ,
1183
+ Sender : sender ,
1184
+ }
1185
+
1186
+ err := future .WaitForCompletion (context .Background (), client )
1187
+ if err == nil {
1188
+ t .Fatalf ("azure: WaitForCompletion returned nil error, should have errored out" )
1189
+ }
1190
+ }
1191
+
1192
+ func TestFuture_WaitForCompletionCancelled (t * testing.T ) {
1193
+ r1 := newAsynchronousResponse ()
1194
+ r1 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1195
+ r2 := newProvisioningStatusResponse ("busy" )
1196
+ r2 .Header .Del (http .CanonicalHeaderKey (headerAsyncOperation ))
1197
+
1198
+ sender := mocks .NewSender ()
1199
+ sender .AppendResponse (r1 )
1200
+ sender .AppendAndRepeatResponseWithDelay (r2 , 1 * time .Second , 5 )
1201
+
1202
+ future := NewFuture (mocks .NewRequest ())
1203
+
1204
+ client := autorest.Client {
1205
+ PollingDelay : autorest .DefaultPollingDelay ,
1206
+ PollingDuration : autorest .DefaultPollingDuration ,
1207
+ RetryAttempts : autorest .DefaultRetryAttempts ,
1208
+ RetryDuration : autorest .DefaultRetryDuration ,
1209
+ Sender : sender ,
1210
+ }
1211
+
1212
+ ctx , cancel := context .WithCancel (context .Background ())
1213
+ go func () {
1214
+ time .Sleep (2 * time .Second )
1215
+ cancel ()
1216
+ }()
1217
+
1218
+ err := future .WaitForCompletion (ctx , client )
1219
+ if err == nil {
1220
+ t .Fatalf ("azure: WaitForCompletion returned nil error, should have been cancelled" )
1221
+ }
1222
+ }
1223
+
1099
1224
const (
1100
1225
operationResourceIllegal = `
1101
1226
This is not JSON and should fail...badly.
@@ -1171,8 +1296,8 @@ func newAsynchronousResponse() *http.Response {
1171
1296
return r
1172
1297
}
1173
1298
1174
- func newAsynchronousResponseWithError () * http.Response {
1175
- r := mocks .NewResponseWithStatus ("400 Bad Request" , http . StatusBadRequest )
1299
+ func newAsynchronousResponseWithError (response string , status int ) * http.Response {
1300
+ r := mocks .NewResponseWithStatus (response , status )
1176
1301
mocks .SetRetryHeader (r , retryDelay )
1177
1302
r .Request = mocks .NewRequestForURL (mocks .TestURL )
1178
1303
r .Body = mocks .NewBody (errorResponse )
0 commit comments