Update go dependencies
This commit is contained in:
parent
a858c549d9
commit
f3bde94d68
643 changed files with 14296 additions and 19354 deletions
1
vendor/github.com/Azure/go-autorest/.travis.yml
generated
vendored
1
vendor/github.com/Azure/go-autorest/.travis.yml
generated
vendored
|
|
@ -6,7 +6,6 @@ go:
|
|||
- 1.9
|
||||
- 1.8
|
||||
- 1.7
|
||||
- 1.6
|
||||
|
||||
install:
|
||||
- go get -u github.com/golang/lint/golint
|
||||
|
|
|
|||
33
vendor/github.com/Azure/go-autorest/CHANGELOG.md
generated
vendored
33
vendor/github.com/Azure/go-autorest/CHANGELOG.md
generated
vendored
|
|
@ -1,5 +1,38 @@
|
|||
# CHANGELOG
|
||||
|
||||
## v9.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
- Added WaitForCompletion() to Future as a default polling implementation.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Method Future.Done() shouldn't update polling status for unexpected HTTP status codes.
|
||||
|
||||
## v9.3.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- DoRetryForStatusCodes will retry if sender.Do returns a non-nil error.
|
||||
|
||||
## v9.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
- Added PollingMethod() to Future so callers know what kind of polling mechanism is used.
|
||||
- Added azure.ChangeToGet() which transforms an http.Request into a GET (to be used with LROs).
|
||||
|
||||
## v9.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
- Added support for custom Azure Stack endpoints.
|
||||
- Added type azure.Future used to track the status of long-running operations.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Preserve the original error in DoRetryWithRegistration when registration fails.
|
||||
|
||||
## v9.1.1
|
||||
|
||||
|
|
|
|||
3
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
3
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
|
|
@ -87,6 +87,9 @@ const (
|
|||
// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set
|
||||
// and false otherwise.
|
||||
func ResponseHasStatusCode(resp *http.Response, codes ...int) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
return containsInt(codes, resp.StatusCode)
|
||||
}
|
||||
|
||||
|
|
|
|||
245
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
245
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
|
|
@ -16,6 +16,8 @@ package azure
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
|
@ -37,6 +39,152 @@ const (
|
|||
operationSucceeded string = "Succeeded"
|
||||
)
|
||||
|
||||
var pollingCodes = [...]int{http.StatusAccepted, http.StatusCreated, http.StatusOK}
|
||||
|
||||
// Future provides a mechanism to access the status and results of an asynchronous request.
|
||||
// Since futures are stateful they should be passed by value to avoid race conditions.
|
||||
type Future struct {
|
||||
req *http.Request
|
||||
resp *http.Response
|
||||
ps pollingState
|
||||
}
|
||||
|
||||
// NewFuture returns a new Future object initialized with the specified request.
|
||||
func NewFuture(req *http.Request) Future {
|
||||
return Future{req: req}
|
||||
}
|
||||
|
||||
// Response returns the last HTTP response or nil if there isn't one.
|
||||
func (f Future) Response() *http.Response {
|
||||
return f.resp
|
||||
}
|
||||
|
||||
// Status returns the last status message of the operation.
|
||||
func (f Future) Status() string {
|
||||
if f.ps.State == "" {
|
||||
return "Unknown"
|
||||
}
|
||||
return f.ps.State
|
||||
}
|
||||
|
||||
// PollingMethod returns the method used to monitor the status of the asynchronous operation.
|
||||
func (f Future) PollingMethod() PollingMethodType {
|
||||
return f.ps.PollingMethod
|
||||
}
|
||||
|
||||
// Done queries the service to see if the operation has completed.
|
||||
func (f *Future) Done(sender autorest.Sender) (bool, error) {
|
||||
// exit early if this future has terminated
|
||||
if f.ps.hasTerminated() {
|
||||
return true, f.errorInfo()
|
||||
}
|
||||
|
||||
resp, err := sender.Do(f.req)
|
||||
f.resp = resp
|
||||
if err != nil || !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = updatePollingState(resp, &f.ps)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if f.ps.hasTerminated() {
|
||||
return true, f.errorInfo()
|
||||
}
|
||||
|
||||
f.req, err = newPollingRequest(f.ps)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// GetPollingDelay returns a duration the application should wait before checking
|
||||
// the status of the asynchronous request and true; this value is returned from
|
||||
// the service via the Retry-After response header. If the header wasn't returned
|
||||
// then the function returns the zero-value time.Duration and false.
|
||||
func (f Future) GetPollingDelay() (time.Duration, bool) {
|
||||
if f.resp == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
retry := f.resp.Header.Get(autorest.HeaderRetryAfter)
|
||||
if retry == "" {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
d, err := time.ParseDuration(retry + "s")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return d, true
|
||||
}
|
||||
|
||||
// WaitForCompletion will return when one of the following conditions is met: the long
|
||||
// running operation has completed, the provided context is cancelled, or the client's
|
||||
// polling duration has been exceeded. It will retry failed polling attempts based on
|
||||
// the retry value defined in the client up to the maximum retry attempts.
|
||||
func (f Future) WaitForCompletion(ctx context.Context, client autorest.Client) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.PollingDuration)
|
||||
defer cancel()
|
||||
|
||||
done, err := f.Done(client)
|
||||
for attempts := 0; !done; done, err = f.Done(client) {
|
||||
if attempts >= client.RetryAttempts {
|
||||
return autorest.NewErrorWithError(err, "azure", "WaitForCompletion", f.resp, "the number of retries has been exceeded")
|
||||
}
|
||||
// we want delayAttempt to be zero in the non-error case so
|
||||
// that DelayForBackoff doesn't perform exponential back-off
|
||||
var delayAttempt int
|
||||
var delay time.Duration
|
||||
if err == nil {
|
||||
// check for Retry-After delay, if not present use the client's polling delay
|
||||
var ok bool
|
||||
delay, ok = f.GetPollingDelay()
|
||||
if !ok {
|
||||
delay = client.PollingDelay
|
||||
}
|
||||
} else {
|
||||
// there was an error polling for status so perform exponential
|
||||
// back-off based on the number of attempts using the client's retry
|
||||
// duration. update attempts after delayAttempt to avoid off-by-one.
|
||||
delayAttempt = attempts
|
||||
delay = client.RetryDuration
|
||||
attempts++
|
||||
}
|
||||
// wait until the delay elapses or the context is cancelled
|
||||
delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, ctx.Done())
|
||||
if !delayElapsed {
|
||||
return autorest.NewErrorWithError(ctx.Err(), "azure", "WaitForCompletion", f.resp, "context has been cancelled")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// if the operation failed the polling state will contain
|
||||
// error information and implements the error interface
|
||||
func (f *Future) errorInfo() error {
|
||||
if !f.ps.hasSucceeded() {
|
||||
return f.ps
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (f Future) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&f.ps)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (f *Future) UnmarshalJSON(data []byte) error {
|
||||
err := json.Unmarshal(data, &f.ps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.req, err = newPollingRequest(f.ps)
|
||||
return err
|
||||
}
|
||||
|
||||
// DoPollForAsynchronous returns a SendDecorator that polls if the http.Response is for an Azure
|
||||
// long-running operation. It will delay between requests for the duration specified in the
|
||||
// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by
|
||||
|
|
@ -48,8 +196,7 @@ func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator {
|
|||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
pollingCodes := []int{http.StatusAccepted, http.StatusCreated, http.StatusOK}
|
||||
if !autorest.ResponseHasStatusCode(resp, pollingCodes...) {
|
||||
if !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
|
@ -66,10 +213,11 @@ func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator {
|
|||
break
|
||||
}
|
||||
|
||||
r, err = newPollingRequest(resp, ps)
|
||||
r, err = newPollingRequest(ps)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
r.Cancel = resp.Request.Cancel
|
||||
|
||||
delay = autorest.GetRetryAfter(resp, delay)
|
||||
resp, err = autorest.SendWithSender(s, r,
|
||||
|
|
@ -160,36 +308,42 @@ func (ps provisioningStatus) hasProvisioningError() bool {
|
|||
return ps.ProvisioningError != ServiceError{}
|
||||
}
|
||||
|
||||
type pollingResponseFormat string
|
||||
// PollingMethodType defines a type used for enumerating polling mechanisms.
|
||||
type PollingMethodType string
|
||||
|
||||
const (
|
||||
usesOperationResponse pollingResponseFormat = "OperationResponse"
|
||||
usesProvisioningStatus pollingResponseFormat = "ProvisioningStatus"
|
||||
formatIsUnknown pollingResponseFormat = ""
|
||||
// PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header.
|
||||
PollingAsyncOperation PollingMethodType = "AsyncOperation"
|
||||
|
||||
// PollingLocation indicates the polling method uses the Location header.
|
||||
PollingLocation PollingMethodType = "Location"
|
||||
|
||||
// PollingUnknown indicates an unknown polling method and is the default value.
|
||||
PollingUnknown PollingMethodType = ""
|
||||
)
|
||||
|
||||
type pollingState struct {
|
||||
responseFormat pollingResponseFormat
|
||||
uri string
|
||||
state string
|
||||
code string
|
||||
message string
|
||||
PollingMethod PollingMethodType `json:"pollingMethod"`
|
||||
URI string `json:"uri"`
|
||||
State string `json:"state"`
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (ps pollingState) hasSucceeded() bool {
|
||||
return hasSucceeded(ps.state)
|
||||
return hasSucceeded(ps.State)
|
||||
}
|
||||
|
||||
func (ps pollingState) hasTerminated() bool {
|
||||
return hasTerminated(ps.state)
|
||||
return hasTerminated(ps.State)
|
||||
}
|
||||
|
||||
func (ps pollingState) hasFailed() bool {
|
||||
return hasFailed(ps.state)
|
||||
return hasFailed(ps.State)
|
||||
}
|
||||
|
||||
func (ps pollingState) Error() string {
|
||||
return fmt.Sprintf("Long running operation terminated with status '%s': Code=%q Message=%q", ps.state, ps.code, ps.message)
|
||||
return fmt.Sprintf("Long running operation terminated with status '%s': Code=%q Message=%q", ps.State, ps.Code, ps.Message)
|
||||
}
|
||||
|
||||
// updatePollingState maps the operation status -- retrieved from either a provisioningState
|
||||
|
|
@ -204,7 +358,7 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
// -- The first response will always be a provisioningStatus response; only the polling requests,
|
||||
// depending on the header returned, may be something otherwise.
|
||||
var pt provisioningTracker
|
||||
if ps.responseFormat == usesOperationResponse {
|
||||
if ps.PollingMethod == PollingAsyncOperation {
|
||||
pt = &operationResource{}
|
||||
} else {
|
||||
pt = &provisioningStatus{}
|
||||
|
|
@ -212,30 +366,30 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
|
||||
// If this is the first request (that is, the polling response shape is unknown), determine how
|
||||
// to poll and what to expect
|
||||
if ps.responseFormat == formatIsUnknown {
|
||||
if ps.PollingMethod == PollingUnknown {
|
||||
req := resp.Request
|
||||
if req == nil {
|
||||
return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Original HTTP request is missing")
|
||||
}
|
||||
|
||||
// Prefer the Azure-AsyncOperation header
|
||||
ps.uri = getAsyncOperation(resp)
|
||||
if ps.uri != "" {
|
||||
ps.responseFormat = usesOperationResponse
|
||||
ps.URI = getAsyncOperation(resp)
|
||||
if ps.URI != "" {
|
||||
ps.PollingMethod = PollingAsyncOperation
|
||||
} else {
|
||||
ps.responseFormat = usesProvisioningStatus
|
||||
ps.PollingMethod = PollingLocation
|
||||
}
|
||||
|
||||
// Else, use the Location header
|
||||
if ps.uri == "" {
|
||||
ps.uri = autorest.GetLocation(resp)
|
||||
if ps.URI == "" {
|
||||
ps.URI = autorest.GetLocation(resp)
|
||||
}
|
||||
|
||||
// Lastly, requests against an existing resource, use the last request URI
|
||||
if ps.uri == "" {
|
||||
if ps.URI == "" {
|
||||
m := strings.ToUpper(req.Method)
|
||||
if m == http.MethodPatch || m == http.MethodPut || m == http.MethodGet {
|
||||
ps.uri = req.URL.String()
|
||||
ps.URI = req.URL.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -256,23 +410,23 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
// -- Unknown states are per-service inprogress states
|
||||
// -- Otherwise, infer state from HTTP status code
|
||||
if pt.hasTerminated() {
|
||||
ps.state = pt.state()
|
||||
ps.State = pt.state()
|
||||
} else if pt.state() != "" {
|
||||
ps.state = operationInProgress
|
||||
ps.State = operationInProgress
|
||||
} else {
|
||||
switch resp.StatusCode {
|
||||
case http.StatusAccepted:
|
||||
ps.state = operationInProgress
|
||||
ps.State = operationInProgress
|
||||
|
||||
case http.StatusNoContent, http.StatusCreated, http.StatusOK:
|
||||
ps.state = operationSucceeded
|
||||
ps.State = operationSucceeded
|
||||
|
||||
default:
|
||||
ps.state = operationFailed
|
||||
ps.State = operationFailed
|
||||
}
|
||||
}
|
||||
|
||||
if ps.state == operationInProgress && ps.uri == "" {
|
||||
if ps.State == operationInProgress && ps.URI == "" {
|
||||
return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Unable to obtain polling URI for %s %s", resp.Request.Method, resp.Request.URL)
|
||||
}
|
||||
|
||||
|
|
@ -281,35 +435,30 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
// -- Response
|
||||
// -- Otherwise, Unknown
|
||||
if ps.hasFailed() {
|
||||
if ps.responseFormat == usesOperationResponse {
|
||||
if ps.PollingMethod == PollingAsyncOperation {
|
||||
or := pt.(*operationResource)
|
||||
ps.code = or.OperationError.Code
|
||||
ps.message = or.OperationError.Message
|
||||
ps.Code = or.OperationError.Code
|
||||
ps.Message = or.OperationError.Message
|
||||
} else {
|
||||
p := pt.(*provisioningStatus)
|
||||
if p.hasProvisioningError() {
|
||||
ps.code = p.ProvisioningError.Code
|
||||
ps.message = p.ProvisioningError.Message
|
||||
ps.Code = p.ProvisioningError.Code
|
||||
ps.Message = p.ProvisioningError.Message
|
||||
} else {
|
||||
ps.code = "Unknown"
|
||||
ps.message = "None"
|
||||
ps.Code = "Unknown"
|
||||
ps.Message = "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newPollingRequest(resp *http.Response, ps pollingState) (*http.Request, error) {
|
||||
req := resp.Request
|
||||
if req == nil {
|
||||
return nil, autorest.NewError("azure", "newPollingRequest", "Azure Polling Error - Original HTTP request is missing")
|
||||
}
|
||||
|
||||
reqPoll, err := autorest.Prepare(&http.Request{Cancel: req.Cancel},
|
||||
func newPollingRequest(ps pollingState) (*http.Request, error) {
|
||||
reqPoll, err := autorest.Prepare(&http.Request{},
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(ps.uri))
|
||||
autorest.WithBaseURL(ps.URI))
|
||||
if err != nil {
|
||||
return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.uri)
|
||||
return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.URI)
|
||||
}
|
||||
|
||||
return reqPoll, nil
|
||||
|
|
|
|||
293
vendor/github.com/Azure/go-autorest/autorest/azure/async_test.go
generated
vendored
293
vendor/github.com/Azure/go-autorest/autorest/azure/async_test.go
generated
vendored
|
|
@ -15,6 +15,9 @@ package azure
|
|||
// limitations under the License.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
|
@ -145,27 +148,27 @@ func TestProvisioningStatus_HasTerminatedReturnsFalseForUnknownStates(t *testing
|
|||
}
|
||||
|
||||
func TestPollingState_HasSucceededReturnsFalseIfNotSuccess(t *testing.T) {
|
||||
if (pollingState{state: "not a success string"}).hasSucceeded() {
|
||||
if (pollingState{State: "not a success string"}).hasSucceeded() {
|
||||
t.Fatalf("azure: pollingState#hasSucceeded failed to return false for a canceled operation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPollingState_HasSucceededReturnsTrueIfSuccessful(t *testing.T) {
|
||||
if !(pollingState{state: operationSucceeded}).hasSucceeded() {
|
||||
if !(pollingState{State: operationSucceeded}).hasSucceeded() {
|
||||
t.Fatalf("azure: pollingState#hasSucceeded failed to return true for a successful operation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPollingState_HasTerminatedReturnsTrueForKnownStates(t *testing.T) {
|
||||
for _, state := range []string{operationSucceeded, operationCanceled, operationFailed} {
|
||||
if !(pollingState{state: state}).hasTerminated() {
|
||||
if !(pollingState{State: state}).hasTerminated() {
|
||||
t.Fatalf("azure: pollingState#hasTerminated failed to return true for the '%s' state", state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPollingState_HasTerminatedReturnsFalseForUnknownStates(t *testing.T) {
|
||||
if (pollingState{state: "not a known state"}).hasTerminated() {
|
||||
if (pollingState{State: "not a known state"}).hasTerminated() {
|
||||
t.Fatalf("azure: pollingState#hasTerminated returned true for a non-terminal operation")
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +185,7 @@ func TestUpdatePollingState_ReturnsTerminatedForKnownProvisioningStates(t *testi
|
|||
for _, state := range []string{operationSucceeded, operationCanceled, operationFailed} {
|
||||
resp := mocks.NewResponseWithContent(fmt.Sprintf(pollingStateFormat, state))
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesProvisioningStatus}
|
||||
ps := &pollingState{PollingMethod: PollingLocation}
|
||||
updatePollingState(resp, ps)
|
||||
if !ps.hasTerminated() {
|
||||
t.Fatalf("azure: updatePollingState failed to return a terminating pollingState for the '%s' state", state)
|
||||
|
|
@ -193,7 +196,7 @@ func TestUpdatePollingState_ReturnsTerminatedForKnownProvisioningStates(t *testi
|
|||
func TestUpdatePollingState_ReturnsSuccessForSuccessfulProvisioningState(t *testing.T) {
|
||||
resp := mocks.NewResponseWithContent(fmt.Sprintf(pollingStateFormat, operationSucceeded))
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesProvisioningStatus}
|
||||
ps := &pollingState{PollingMethod: PollingLocation}
|
||||
updatePollingState(resp, ps)
|
||||
if !ps.hasSucceeded() {
|
||||
t.Fatalf("azure: updatePollingState failed to return a successful pollingState for the '%s' state", operationSucceeded)
|
||||
|
|
@ -204,7 +207,7 @@ func TestUpdatePollingState_ReturnsInProgressForAllOtherProvisioningStates(t *te
|
|||
s := "not a recognized state"
|
||||
resp := mocks.NewResponseWithContent(fmt.Sprintf(pollingStateFormat, s))
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesProvisioningStatus}
|
||||
ps := &pollingState{PollingMethod: PollingLocation}
|
||||
updatePollingState(resp, ps)
|
||||
if ps.hasTerminated() {
|
||||
t.Fatalf("azure: updatePollingState returned terminated for unknown state '%s'", s)
|
||||
|
|
@ -215,7 +218,7 @@ func TestUpdatePollingState_ReturnsSuccessWhenProvisioningStateFieldIsAbsentForS
|
|||
for _, sc := range []int{http.StatusOK, http.StatusCreated, http.StatusNoContent} {
|
||||
resp := mocks.NewResponseWithContent(pollingStateEmpty)
|
||||
resp.StatusCode = sc
|
||||
ps := &pollingState{responseFormat: usesProvisioningStatus}
|
||||
ps := &pollingState{PollingMethod: PollingLocation}
|
||||
updatePollingState(resp, ps)
|
||||
if !ps.hasSucceeded() {
|
||||
t.Fatalf("azure: updatePollingState failed to return success when the provisionState field is absent for Status Code %d", sc)
|
||||
|
|
@ -226,7 +229,7 @@ func TestUpdatePollingState_ReturnsSuccessWhenProvisioningStateFieldIsAbsentForS
|
|||
func TestUpdatePollingState_ReturnsInProgressWhenProvisioningStateFieldIsAbsentForAccepted(t *testing.T) {
|
||||
resp := mocks.NewResponseWithContent(pollingStateEmpty)
|
||||
resp.StatusCode = http.StatusAccepted
|
||||
ps := &pollingState{responseFormat: usesProvisioningStatus}
|
||||
ps := &pollingState{PollingMethod: PollingLocation}
|
||||
updatePollingState(resp, ps)
|
||||
if ps.hasTerminated() {
|
||||
t.Fatalf("azure: updatePollingState returned terminated when the provisionState field is absent for Status Code Accepted")
|
||||
|
|
@ -236,7 +239,7 @@ func TestUpdatePollingState_ReturnsInProgressWhenProvisioningStateFieldIsAbsentF
|
|||
func TestUpdatePollingState_ReturnsFailedWhenProvisioningStateFieldIsAbsentForUnknownStatusCodes(t *testing.T) {
|
||||
resp := mocks.NewResponseWithContent(pollingStateEmpty)
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesProvisioningStatus}
|
||||
ps := &pollingState{PollingMethod: PollingLocation}
|
||||
updatePollingState(resp, ps)
|
||||
if !ps.hasTerminated() || ps.hasSucceeded() {
|
||||
t.Fatalf("azure: updatePollingState did not return failed when the provisionState field is absent for an unknown Status Code")
|
||||
|
|
@ -247,7 +250,7 @@ func TestUpdatePollingState_ReturnsTerminatedForKnownOperationResourceStates(t *
|
|||
for _, state := range []string{operationSucceeded, operationCanceled, operationFailed} {
|
||||
resp := mocks.NewResponseWithContent(fmt.Sprintf(operationResourceFormat, state))
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesOperationResponse}
|
||||
ps := &pollingState{PollingMethod: PollingAsyncOperation}
|
||||
updatePollingState(resp, ps)
|
||||
if !ps.hasTerminated() {
|
||||
t.Fatalf("azure: updatePollingState failed to return a terminating pollingState for the '%s' state", state)
|
||||
|
|
@ -258,7 +261,7 @@ func TestUpdatePollingState_ReturnsTerminatedForKnownOperationResourceStates(t *
|
|||
func TestUpdatePollingState_ReturnsSuccessForSuccessfulOperationResourceState(t *testing.T) {
|
||||
resp := mocks.NewResponseWithContent(fmt.Sprintf(operationResourceFormat, operationSucceeded))
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesOperationResponse}
|
||||
ps := &pollingState{PollingMethod: PollingAsyncOperation}
|
||||
updatePollingState(resp, ps)
|
||||
if !ps.hasSucceeded() {
|
||||
t.Fatalf("azure: updatePollingState failed to return a successful pollingState for the '%s' state", operationSucceeded)
|
||||
|
|
@ -269,7 +272,7 @@ func TestUpdatePollingState_ReturnsInProgressForAllOtherOperationResourceStates(
|
|||
s := "not a recognized state"
|
||||
resp := mocks.NewResponseWithContent(fmt.Sprintf(operationResourceFormat, s))
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesOperationResponse}
|
||||
ps := &pollingState{PollingMethod: PollingAsyncOperation}
|
||||
updatePollingState(resp, ps)
|
||||
if ps.hasTerminated() {
|
||||
t.Fatalf("azure: updatePollingState returned terminated for unknown state '%s'", s)
|
||||
|
|
@ -280,7 +283,7 @@ func TestUpdatePollingState_CopiesTheResponseBody(t *testing.T) {
|
|||
s := fmt.Sprintf(pollingStateFormat, operationSucceeded)
|
||||
resp := mocks.NewResponseWithContent(s)
|
||||
resp.StatusCode = 42
|
||||
ps := &pollingState{responseFormat: usesOperationResponse}
|
||||
ps := &pollingState{PollingMethod: PollingAsyncOperation}
|
||||
updatePollingState(resp, ps)
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
|
|
@ -294,7 +297,7 @@ func TestUpdatePollingState_CopiesTheResponseBody(t *testing.T) {
|
|||
func TestUpdatePollingState_ClosesTheOriginalResponseBody(t *testing.T) {
|
||||
resp := mocks.NewResponse()
|
||||
b := resp.Body.(*mocks.Body)
|
||||
ps := &pollingState{responseFormat: usesProvisioningStatus}
|
||||
ps := &pollingState{PollingMethod: PollingLocation}
|
||||
updatePollingState(resp, ps)
|
||||
if b.IsOpen() {
|
||||
t.Fatal("azure: updatePollingState failed to close the original http.Response Body")
|
||||
|
|
@ -312,23 +315,23 @@ func TestUpdatePollingState_FailsWhenResponseLacksRequest(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUpdatePollingState_SetsTheResponseFormatWhenUsingTheAzureAsyncOperationHeader(t *testing.T) {
|
||||
func TestUpdatePollingState_SetsThePollingMethodWhenUsingTheAzureAsyncOperationHeader(t *testing.T) {
|
||||
ps := pollingState{}
|
||||
updatePollingState(newAsynchronousResponse(), &ps)
|
||||
|
||||
if ps.responseFormat != usesOperationResponse {
|
||||
if ps.PollingMethod != PollingAsyncOperation {
|
||||
t.Fatal("azure: updatePollingState failed to set the correct response format when using the Azure-AsyncOperation header")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdatePollingState_SetsTheResponseFormatWhenUsingTheAzureAsyncOperationHeaderIsMissing(t *testing.T) {
|
||||
func TestUpdatePollingState_SetsThePollingMethodWhenUsingTheAzureAsyncOperationHeaderIsMissing(t *testing.T) {
|
||||
resp := newAsynchronousResponse()
|
||||
resp.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
ps := pollingState{}
|
||||
updatePollingState(resp, &ps)
|
||||
|
||||
if ps.responseFormat != usesProvisioningStatus {
|
||||
if ps.PollingMethod != PollingLocation {
|
||||
t.Fatal("azure: updatePollingState failed to set the correct response format when the Azure-AsyncOperation header is absent")
|
||||
}
|
||||
}
|
||||
|
|
@ -337,10 +340,10 @@ func TestUpdatePollingState_DoesNotChangeAnExistingReponseFormat(t *testing.T) {
|
|||
resp := newAsynchronousResponse()
|
||||
resp.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
ps := pollingState{responseFormat: usesOperationResponse}
|
||||
ps := pollingState{PollingMethod: PollingAsyncOperation}
|
||||
updatePollingState(resp, &ps)
|
||||
|
||||
if ps.responseFormat != usesOperationResponse {
|
||||
if ps.PollingMethod != PollingAsyncOperation {
|
||||
t.Fatal("azure: updatePollingState failed to leave an existing response format setting")
|
||||
}
|
||||
}
|
||||
|
|
@ -351,7 +354,7 @@ func TestUpdatePollingState_PrefersTheAzureAsyncOperationHeader(t *testing.T) {
|
|||
ps := pollingState{}
|
||||
updatePollingState(resp, &ps)
|
||||
|
||||
if ps.uri != mocks.TestAzureAsyncURL {
|
||||
if ps.URI != mocks.TestAzureAsyncURL {
|
||||
t.Fatal("azure: updatePollingState failed to prefer the Azure-AsyncOperation header")
|
||||
}
|
||||
}
|
||||
|
|
@ -363,7 +366,7 @@ func TestUpdatePollingState_PrefersLocationWhenTheAzureAsyncOperationHeaderMissi
|
|||
ps := pollingState{}
|
||||
updatePollingState(resp, &ps)
|
||||
|
||||
if ps.uri != mocks.TestLocationURL {
|
||||
if ps.URI != mocks.TestLocationURL {
|
||||
t.Fatal("azure: updatePollingState failed to prefer the Location header when the Azure-AsyncOperation header is missing")
|
||||
}
|
||||
}
|
||||
|
|
@ -377,7 +380,7 @@ func TestUpdatePollingState_UsesTheObjectLocationIfAsyncHeadersAreMissing(t *tes
|
|||
ps := pollingState{}
|
||||
updatePollingState(resp, &ps)
|
||||
|
||||
if ps.uri != mocks.TestURL {
|
||||
if ps.URI != mocks.TestURL {
|
||||
t.Fatal("azure: updatePollingState failed to use the Object URL when the asynchronous headers are missing")
|
||||
}
|
||||
}
|
||||
|
|
@ -392,7 +395,7 @@ func TestUpdatePollingState_RecognizesLowerCaseHTTPVerbs(t *testing.T) {
|
|||
ps := pollingState{}
|
||||
updatePollingState(resp, &ps)
|
||||
|
||||
if ps.uri != mocks.TestURL {
|
||||
if ps.URI != mocks.TestURL {
|
||||
t.Fatalf("azure: updatePollingState failed to recognize the lower-case HTTP verb '%s'", m)
|
||||
}
|
||||
}
|
||||
|
|
@ -412,32 +415,22 @@ func TestUpdatePollingState_ReturnsAnErrorIfAsyncHeadersAreMissingForANewOrDelet
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewPollingRequest_FailsWhenResponseLacksRequest(t *testing.T) {
|
||||
resp := newAsynchronousResponse()
|
||||
resp.Request = nil
|
||||
|
||||
_, err := newPollingRequest(resp, pollingState{})
|
||||
if err == nil {
|
||||
t.Fatal("azure: newPollingRequest failed to return an error when the http.Response lacked the original http.Request")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPollingRequest_ReturnsAnErrorWhenPrepareFails(t *testing.T) {
|
||||
_, err := newPollingRequest(newAsynchronousResponse(), pollingState{responseFormat: usesOperationResponse, uri: mocks.TestBadURL})
|
||||
_, err := newPollingRequest(pollingState{PollingMethod: PollingAsyncOperation, URI: mocks.TestBadURL})
|
||||
if err == nil {
|
||||
t.Fatal("azure: newPollingRequest failed to return an error when Prepare fails")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPollingRequest_DoesNotReturnARequestWhenPrepareFails(t *testing.T) {
|
||||
req, _ := newPollingRequest(newAsynchronousResponse(), pollingState{responseFormat: usesOperationResponse, uri: mocks.TestBadURL})
|
||||
req, _ := newPollingRequest(pollingState{PollingMethod: PollingAsyncOperation, URI: mocks.TestBadURL})
|
||||
if req != nil {
|
||||
t.Fatal("azure: newPollingRequest returned an http.Request when Prepare failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPollingRequest_ReturnsAGetRequest(t *testing.T) {
|
||||
req, _ := newPollingRequest(newAsynchronousResponse(), pollingState{responseFormat: usesOperationResponse, uri: mocks.TestAzureAsyncURL})
|
||||
req, _ := newPollingRequest(pollingState{PollingMethod: PollingAsyncOperation, URI: mocks.TestAzureAsyncURL})
|
||||
if req.Method != "GET" {
|
||||
t.Fatalf("azure: newPollingRequest did not create an HTTP GET request -- actual method %v", req.Method)
|
||||
}
|
||||
|
|
@ -643,7 +636,7 @@ func TestDoPollForAsynchronous_PollsForStatusAccepted(t *testing.T) {
|
|||
r, _ := autorest.SendWithSender(client, mocks.NewRequest(),
|
||||
DoPollForAsynchronous(time.Millisecond))
|
||||
|
||||
if client.Attempts() < 4 {
|
||||
if client.Attempts() < client.NumResponses() {
|
||||
t.Fatalf("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
|
|
@ -666,7 +659,7 @@ func TestDoPollForAsynchronous_PollsForStatusCreated(t *testing.T) {
|
|||
r, _ := autorest.SendWithSender(client, mocks.NewRequest(),
|
||||
DoPollForAsynchronous(time.Millisecond))
|
||||
|
||||
if client.Attempts() < 4 {
|
||||
if client.Attempts() < client.NumResponses() {
|
||||
t.Fatalf("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
|
|
@ -690,7 +683,7 @@ func TestDoPollForAsynchronous_PollsUntilProvisioningStatusTerminates(t *testing
|
|||
r, _ := autorest.SendWithSender(client, mocks.NewRequest(),
|
||||
DoPollForAsynchronous(time.Millisecond))
|
||||
|
||||
if client.Attempts() < 4 {
|
||||
if client.Attempts() < client.NumResponses() {
|
||||
t.Fatalf("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
|
|
@ -714,7 +707,7 @@ func TestDoPollForAsynchronous_PollsUntilProvisioningStatusSucceeds(t *testing.T
|
|||
r, _ := autorest.SendWithSender(client, mocks.NewRequest(),
|
||||
DoPollForAsynchronous(time.Millisecond))
|
||||
|
||||
if client.Attempts() < 4 {
|
||||
if client.Attempts() < client.NumResponses() {
|
||||
t.Fatalf("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
|
|
@ -735,7 +728,7 @@ func TestDoPollForAsynchronous_PollsUntilOperationResourceHasTerminated(t *testi
|
|||
r, _ := autorest.SendWithSender(client, mocks.NewRequest(),
|
||||
DoPollForAsynchronous(time.Millisecond))
|
||||
|
||||
if client.Attempts() < 4 {
|
||||
if client.Attempts() < client.NumResponses() {
|
||||
t.Fatalf("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
|
|
@ -756,7 +749,7 @@ func TestDoPollForAsynchronous_PollsUntilOperationResourceHasSucceeded(t *testin
|
|||
r, _ := autorest.SendWithSender(client, mocks.NewRequest(),
|
||||
DoPollForAsynchronous(time.Millisecond))
|
||||
|
||||
if client.Attempts() < 4 {
|
||||
if client.Attempts() < client.NumResponses() {
|
||||
t.Fatalf("azure: DoPollForAsynchronous stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
|
|
@ -885,7 +878,7 @@ func TestDoPollForAsynchronous_ReturnsErrorForLastErrorResponse(t *testing.T) {
|
|||
r1.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r2 := newProvisioningStatusResponse("busy")
|
||||
r2.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r3 := newAsynchronousResponseWithError()
|
||||
r3 := newAsynchronousResponseWithError("400 Bad Request", http.StatusBadRequest)
|
||||
r3.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
client := mocks.NewSender()
|
||||
|
|
@ -932,7 +925,7 @@ func TestDoPollForAsynchronous_ReturnsOperationResourceErrorForFailedOperations(
|
|||
|
||||
func TestDoPollForAsynchronous_ReturnsErrorForFirstPutRequest(t *testing.T) {
|
||||
// Return 400 bad response with error code and message in first put
|
||||
r1 := newAsynchronousResponseWithError()
|
||||
r1 := newAsynchronousResponseWithError("400 Bad Request", http.StatusBadRequest)
|
||||
client := mocks.NewSender()
|
||||
client.AppendResponse(r1)
|
||||
|
||||
|
|
@ -1024,6 +1017,210 @@ func TestDoPollForAsynchronous_StopsPollingIfItReceivesAnInvalidOperationResourc
|
|||
autorest.ByClosing())
|
||||
}
|
||||
|
||||
func TestFuture_PollsUntilProvisioningStatusSucceeds(t *testing.T) {
|
||||
r1 := newAsynchronousResponse()
|
||||
r1.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r2 := newProvisioningStatusResponse("busy")
|
||||
r2.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r3 := newProvisioningStatusResponse(operationSucceeded)
|
||||
r3.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
client := mocks.NewSender()
|
||||
client.AppendResponse(r1)
|
||||
client.AppendAndRepeatResponse(r2, 2)
|
||||
client.AppendResponse(r3)
|
||||
|
||||
future := NewFuture(mocks.NewRequest())
|
||||
|
||||
for done, err := future.Done(client); !done; done, err = future.Done(client) {
|
||||
if future.PollingMethod() != PollingLocation {
|
||||
t.Fatalf("azure: wrong future polling method")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("azure: TestFuture polling Done failed")
|
||||
}
|
||||
delay, ok := future.GetPollingDelay()
|
||||
if !ok {
|
||||
t.Fatalf("expected Retry-After value")
|
||||
}
|
||||
time.Sleep(delay)
|
||||
}
|
||||
|
||||
if client.Attempts() < client.NumResponses() {
|
||||
t.Fatalf("azure: TestFuture stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
autorest.Respond(future.Response(),
|
||||
autorest.ByClosing())
|
||||
}
|
||||
|
||||
func TestFuture_Marshalling(t *testing.T) {
|
||||
client := mocks.NewSender()
|
||||
client.AppendResponse(newAsynchronousResponse())
|
||||
|
||||
future := NewFuture(mocks.NewRequest())
|
||||
done, err := future.Done(client)
|
||||
if err != nil {
|
||||
t.Fatalf("azure: TestFuture marshalling Done failed")
|
||||
}
|
||||
if done {
|
||||
t.Fatalf("azure: TestFuture marshalling shouldn't be done")
|
||||
}
|
||||
if future.PollingMethod() != PollingAsyncOperation {
|
||||
t.Fatalf("azure: wrong future polling method")
|
||||
}
|
||||
|
||||
data, err := json.Marshal(future)
|
||||
if err != nil {
|
||||
t.Fatalf("azure: TestFuture failed to marshal")
|
||||
}
|
||||
|
||||
var future2 Future
|
||||
err = json.Unmarshal(data, &future2)
|
||||
if err != nil {
|
||||
t.Fatalf("azure: TestFuture failed to unmarshal")
|
||||
}
|
||||
|
||||
if future.ps.Code != future2.ps.Code {
|
||||
t.Fatalf("azure: TestFuture marshalling codes don't match")
|
||||
}
|
||||
if future.ps.Message != future2.ps.Message {
|
||||
t.Fatalf("azure: TestFuture marshalling messages don't match")
|
||||
}
|
||||
if future.ps.PollingMethod != future2.ps.PollingMethod {
|
||||
t.Fatalf("azure: TestFuture marshalling response formats don't match")
|
||||
}
|
||||
if future.ps.State != future2.ps.State {
|
||||
t.Fatalf("azure: TestFuture marshalling states don't match")
|
||||
}
|
||||
if future.ps.URI != future2.ps.URI {
|
||||
t.Fatalf("azure: TestFuture marshalling URIs don't match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFuture_WaitForCompletion(t *testing.T) {
|
||||
r1 := newAsynchronousResponse()
|
||||
r1.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r2 := newProvisioningStatusResponse("busy")
|
||||
r2.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r3 := newAsynchronousResponseWithError("Internal server error", http.StatusInternalServerError)
|
||||
r3.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r3.Header.Del(http.CanonicalHeaderKey("Retry-After"))
|
||||
r4 := newProvisioningStatusResponse(operationSucceeded)
|
||||
r4.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
sender := mocks.NewSender()
|
||||
sender.AppendResponse(r1)
|
||||
sender.AppendError(errors.New("transient network failure"))
|
||||
sender.AppendAndRepeatResponse(r2, 2)
|
||||
sender.AppendResponse(r3)
|
||||
sender.AppendResponse(r4)
|
||||
|
||||
future := NewFuture(mocks.NewRequest())
|
||||
|
||||
client := autorest.Client{
|
||||
PollingDelay: 1 * time.Second,
|
||||
PollingDuration: autorest.DefaultPollingDuration,
|
||||
RetryAttempts: autorest.DefaultRetryAttempts,
|
||||
RetryDuration: 1 * time.Second,
|
||||
Sender: sender,
|
||||
}
|
||||
|
||||
err := future.WaitForCompletion(context.Background(), client)
|
||||
if err != nil {
|
||||
t.Fatalf("azure: WaitForCompletion returned non-nil error")
|
||||
}
|
||||
|
||||
if sender.Attempts() < sender.NumResponses() {
|
||||
t.Fatalf("azure: TestFuture stopped polling before receiving a terminated OperationResource")
|
||||
}
|
||||
|
||||
autorest.Respond(future.Response(),
|
||||
autorest.ByClosing())
|
||||
}
|
||||
|
||||
func TestFuture_WaitForCompletionTimedOut(t *testing.T) {
|
||||
r1 := newAsynchronousResponse()
|
||||
r1.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r2 := newProvisioningStatusResponse("busy")
|
||||
r2.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
sender := mocks.NewSender()
|
||||
sender.AppendResponse(r1)
|
||||
sender.AppendAndRepeatResponseWithDelay(r2, 1*time.Second, 5)
|
||||
|
||||
future := NewFuture(mocks.NewRequest())
|
||||
|
||||
client := autorest.Client{
|
||||
PollingDelay: autorest.DefaultPollingDelay,
|
||||
PollingDuration: 2 * time.Second,
|
||||
RetryAttempts: autorest.DefaultRetryAttempts,
|
||||
RetryDuration: 1 * time.Second,
|
||||
Sender: sender,
|
||||
}
|
||||
|
||||
err := future.WaitForCompletion(context.Background(), client)
|
||||
if err == nil {
|
||||
t.Fatalf("azure: WaitForCompletion returned nil error, should have timed out")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFuture_WaitForCompletionRetriesExceeded(t *testing.T) {
|
||||
r1 := newAsynchronousResponse()
|
||||
r1.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
sender := mocks.NewSender()
|
||||
sender.AppendResponse(r1)
|
||||
sender.AppendAndRepeatError(errors.New("transient network failure"), autorest.DefaultRetryAttempts+1)
|
||||
|
||||
future := NewFuture(mocks.NewRequest())
|
||||
|
||||
client := autorest.Client{
|
||||
PollingDelay: autorest.DefaultPollingDelay,
|
||||
PollingDuration: autorest.DefaultPollingDuration,
|
||||
RetryAttempts: autorest.DefaultRetryAttempts,
|
||||
RetryDuration: 100 * time.Millisecond,
|
||||
Sender: sender,
|
||||
}
|
||||
|
||||
err := future.WaitForCompletion(context.Background(), client)
|
||||
if err == nil {
|
||||
t.Fatalf("azure: WaitForCompletion returned nil error, should have errored out")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFuture_WaitForCompletionCancelled(t *testing.T) {
|
||||
r1 := newAsynchronousResponse()
|
||||
r1.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
r2 := newProvisioningStatusResponse("busy")
|
||||
r2.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
|
||||
sender := mocks.NewSender()
|
||||
sender.AppendResponse(r1)
|
||||
sender.AppendAndRepeatResponseWithDelay(r2, 1*time.Second, 5)
|
||||
|
||||
future := NewFuture(mocks.NewRequest())
|
||||
|
||||
client := autorest.Client{
|
||||
PollingDelay: autorest.DefaultPollingDelay,
|
||||
PollingDuration: autorest.DefaultPollingDuration,
|
||||
RetryAttempts: autorest.DefaultRetryAttempts,
|
||||
RetryDuration: autorest.DefaultRetryDuration,
|
||||
Sender: sender,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second)
|
||||
cancel()
|
||||
}()
|
||||
|
||||
err := future.WaitForCompletion(ctx, client)
|
||||
if err == nil {
|
||||
t.Fatalf("azure: WaitForCompletion returned nil error, should have been cancelled")
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
operationResourceIllegal = `
|
||||
This is not JSON and should fail...badly.
|
||||
|
|
@ -1099,8 +1296,8 @@ func newAsynchronousResponse() *http.Response {
|
|||
return r
|
||||
}
|
||||
|
||||
func newAsynchronousResponseWithError() *http.Response {
|
||||
r := mocks.NewResponseWithStatus("400 Bad Request", http.StatusBadRequest)
|
||||
func newAsynchronousResponseWithError(response string, status int) *http.Response {
|
||||
r := mocks.NewResponseWithStatus(response, status)
|
||||
mocks.SetRetryHeader(r, retryDelay)
|
||||
r.Request = mocks.NewRequestForURL(mocks.TestURL)
|
||||
r.Body = mocks.NewBody(errorResponse)
|
||||
|
|
|
|||
34
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
34
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
|
|
@ -15,10 +15,17 @@ package azure
|
|||
// limitations under the License.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EnvironmentFilepathName captures the name of the environment variable containing the path to the file
|
||||
// to be used while populating the Azure Environment.
|
||||
const EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH"
|
||||
|
||||
var environments = map[string]Environment{
|
||||
"AZURECHINACLOUD": ChinaCloud,
|
||||
"AZUREGERMANCLOUD": GermanCloud,
|
||||
|
|
@ -133,12 +140,37 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
// EnvironmentFromName returns an Environment based on the common name specified
|
||||
// EnvironmentFromName returns an Environment based on the common name specified.
|
||||
func EnvironmentFromName(name string) (Environment, error) {
|
||||
// IMPORTANT
|
||||
// As per @radhikagupta5:
|
||||
// This is technical debt, fundamentally here because Kubernetes is not currently accepting
|
||||
// contributions to the providers. Once that is an option, the provider should be updated to
|
||||
// directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation
|
||||
// from this method based on the name that is provided to us.
|
||||
if strings.EqualFold(name, "AZURESTACKCLOUD") {
|
||||
return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName))
|
||||
}
|
||||
|
||||
name = strings.ToUpper(name)
|
||||
env, ok := environments[name]
|
||||
if !ok {
|
||||
return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name)
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
// EnvironmentFromFile loads an Environment from a configuration file available on disk.
|
||||
// This function is particularly useful in the Hybrid Cloud model, where one must define their own
|
||||
// endpoints.
|
||||
func EnvironmentFromFile(location string) (unmarshaled Environment, err error) {
|
||||
fileContents, err := ioutil.ReadFile(location)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fileContents, &unmarshaled)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
54
vendor/github.com/Azure/go-autorest/autorest/azure/environments_test.go
generated
vendored
54
vendor/github.com/Azure/go-autorest/autorest/azure/environments_test.go
generated
vendored
|
|
@ -17,9 +17,63 @@ package azure
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// This correlates to the expected contents of ./testdata/test_environment_1.json
|
||||
var testEnvironment1 = Environment{
|
||||
Name: "--unit-test--",
|
||||
ManagementPortalURL: "--management-portal-url",
|
||||
PublishSettingsURL: "--publish-settings-url--",
|
||||
ServiceManagementEndpoint: "--service-management-endpoint--",
|
||||
ResourceManagerEndpoint: "--resource-management-endpoint--",
|
||||
ActiveDirectoryEndpoint: "--active-directory-endpoint--",
|
||||
GalleryEndpoint: "--gallery-endpoint--",
|
||||
KeyVaultEndpoint: "--key-vault--endpoint--",
|
||||
GraphEndpoint: "--graph-endpoint--",
|
||||
StorageEndpointSuffix: "--storage-endpoint-suffix--",
|
||||
SQLDatabaseDNSSuffix: "--sql-database-dns-suffix--",
|
||||
TrafficManagerDNSSuffix: "--traffic-manager-dns-suffix--",
|
||||
KeyVaultDNSSuffix: "--key-vault-dns-suffix--",
|
||||
ServiceBusEndpointSuffix: "--service-bus-endpoint-suffix--",
|
||||
ServiceManagementVMDNSSuffix: "--asm-vm-dns-suffix--",
|
||||
ResourceManagerVMDNSSuffix: "--arm-vm-dns-suffix--",
|
||||
ContainerRegistryDNSSuffix: "--container-registry-dns-suffix--",
|
||||
}
|
||||
|
||||
func TestEnvironment_EnvironmentFromFile(t *testing.T) {
|
||||
got, err := EnvironmentFromFile(filepath.Join("testdata", "test_environment_1.json"))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if got != testEnvironment1 {
|
||||
t.Logf("got: %v want: %v", got, testEnvironment1)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvironment_EnvironmentFromName_Stack(t *testing.T) {
|
||||
_, currentFile, _, _ := runtime.Caller(0)
|
||||
prevEnvFilepathValue := os.Getenv(EnvironmentFilepathName)
|
||||
os.Setenv(EnvironmentFilepathName, filepath.Join(path.Dir(currentFile), "testdata", "test_environment_1.json"))
|
||||
defer os.Setenv(EnvironmentFilepathName, prevEnvFilepathValue)
|
||||
|
||||
got, err := EnvironmentFromName("AZURESTACKCLOUD")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if got != testEnvironment1 {
|
||||
t.Logf("got: %v want: %v", got, testEnvironment1)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvironmentFromName(t *testing.T) {
|
||||
name := "azurechinacloud"
|
||||
if env, _ := EnvironmentFromName(name); env != ChinaCloud {
|
||||
|
|
|
|||
9
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
9
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
|
|
@ -55,15 +55,16 @@ func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator {
|
|||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
err = re
|
||||
|
||||
if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" {
|
||||
err = register(client, r, re)
|
||||
if err != nil {
|
||||
return resp, fmt.Errorf("failed auto registering Resource Provider: %s", err)
|
||||
regErr := register(client, r, re)
|
||||
if regErr != nil {
|
||||
return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %s", regErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return resp, errors.New("failed request and resource provider registration")
|
||||
return resp, fmt.Errorf("failed request: %s", err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
5
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
|
|
@ -35,6 +35,9 @@ const (
|
|||
|
||||
// DefaultRetryAttempts is number of attempts for retry status codes (5xx).
|
||||
DefaultRetryAttempts = 3
|
||||
|
||||
// DefaultRetryDuration is the duration to wait between retries.
|
||||
DefaultRetryDuration = 30 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -172,7 +175,7 @@ func NewClientWithUserAgent(ua string) Client {
|
|||
PollingDelay: DefaultPollingDelay,
|
||||
PollingDuration: DefaultPollingDuration,
|
||||
RetryAttempts: DefaultRetryAttempts,
|
||||
RetryDuration: 30 * time.Second,
|
||||
RetryDuration: DefaultRetryDuration,
|
||||
UserAgent: defaultUserAgent,
|
||||
}
|
||||
c.Sender = c.sender()
|
||||
|
|
|
|||
6
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
6
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
|
|
@ -221,7 +221,8 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err != nil || !ResponseHasStatusCode(resp, codes...) {
|
||||
// we want to retry if err is not nil (e.g. transient network failure)
|
||||
if err == nil && !ResponseHasStatusCode(resp, codes...) {
|
||||
return resp, err
|
||||
}
|
||||
delayed := DelayWithRetryAfter(resp, r.Cancel)
|
||||
|
|
@ -237,6 +238,9 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header in
|
||||
// responses with status code 429
|
||||
func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
retryAfter, _ := strconv.Atoi(resp.Header.Get("Retry-After"))
|
||||
if resp.StatusCode == http.StatusTooManyRequests && retryAfter > 0 {
|
||||
select {
|
||||
|
|
|
|||
12
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
12
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
|
|
@ -20,6 +20,7 @@ import (
|
|||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
|
@ -190,3 +191,14 @@ func createQuery(v url.Values) string {
|
|||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't).
|
||||
// This is mainly useful for long-running operations that use the Azure-AsyncOperation
|
||||
// header, so we change the initial PUT into a GET to retrieve the final result.
|
||||
func ChangeToGet(req *http.Request) *http.Request {
|
||||
req.Method = "GET"
|
||||
req.Body = nil
|
||||
req.ContentLength = 0
|
||||
req.Header.Del("Content-Length")
|
||||
return req
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue