Пример #1
0
func TestServicePrincipalTokenRefreshUsesPOST(t *testing.T) {
	spt := newServicePrincipalToken()

	body := mocks.NewBody("")
	resp := mocks.NewResponseWithBodyAndStatus(body, 200, "OK")

	c := mocks.NewSender()
	s := autorest.DecorateSender(c,
		(func() autorest.SendDecorator {
			return func(s autorest.Sender) autorest.Sender {
				return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) {
					if r.Method != "POST" {
						t.Fatalf("azure: ServicePrincipalToken#Refresh did not correctly set HTTP method -- expected %v, received %v", "POST", r.Method)
					}
					return resp, nil
				})
			}
		})())
	spt.SetSender(s)
	spt.Refresh()

	if body.IsOpen() {
		t.Fatalf("the response was not closed!")
	}
}
Пример #2
0
func TestDoPollForAsynchronous_StopsPollingIfItReceivesAnInvalidOperationResource(t *testing.T) {
	r1 := newAsynchronousResponse()
	r2 := newOperationResourceResponse("busy")
	r3 := newOperationResourceResponse("busy")
	r3.Body = mocks.NewBody(operationResourceIllegal)
	r4 := newOperationResourceResponse(operationSucceeded)

	client := mocks.NewSender()
	client.AppendResponse(r1)
	client.AppendAndRepeatResponse(r2, 2)
	client.AppendAndRepeatResponse(r3, 1)
	client.AppendAndRepeatResponse(r4, 1)

	r, err := autorest.SendWithSender(client, mocks.NewRequest(),
		DoPollForAsynchronous(time.Millisecond))

	if client.Attempts() > 4 {
		t.Fatalf("azure: DoPollForAsynchronous failed to stop polling after receiving an invalid OperationResource")
	}
	if err == nil {
		t.Fatalf("azure: DoPollForAsynchronous failed to return an error after receving an invalid OperationResource")
	}

	autorest.Respond(r,
		autorest.ByClosing())
}
Пример #3
0
func newAsynchronousResponseWithError() *http.Response {
	r := mocks.NewResponseWithStatus("400 Bad Request", http.StatusBadRequest)
	mocks.SetRetryHeader(r, retryDelay)
	r.Request = mocks.NewRequestForURL(mocks.TestURL)
	r.Body = mocks.NewBody(errorResponse)
	return r
}
Пример #4
0
func newAsynchronousResponse() *http.Response {
	r := mocks.NewResponseWithStatus("201 Created", http.StatusCreated)
	r.Body = mocks.NewBody(fmt.Sprintf(pollingStateFormat, operationInProgress))
	mocks.SetResponseHeader(r, http.CanonicalHeaderKey(headerAsyncOperation), mocks.TestAzureAsyncURL)
	mocks.SetResponseHeader(r, http.CanonicalHeaderKey(autorest.HeaderLocation), mocks.TestLocationURL)
	mocks.SetRetryHeader(r, retryDelay)
	r.Request = mocks.NewRequestForURL(mocks.TestURL)
	return r
}
Пример #5
0
func (s *environSuite) TestStartInstanceTooManyRequests(c *gc.C) {
	env := s.openEnviron(c)
	senders := s.startInstanceSenders(false)
	s.requests = nil

	// 6 failures to get to 1 minute, and show that we cap it there.
	const failures = 6

	// Make the VirtualMachines.CreateOrUpdate call respond with
	// 429 (StatusTooManyRequests) failures, and then with success.
	rateLimitedSender := mocks.NewSender()
	rateLimitedSender.AppendAndRepeatResponse(mocks.NewResponseWithBodyAndStatus(
		mocks.NewBody("{}"), // empty JSON response to appease go-autorest
		http.StatusTooManyRequests,
		"(」゜ロ゜)」",
	), failures)
	successSender := senders[len(senders)-1]
	senders = senders[:len(senders)-1]
	for i := 0; i < failures; i++ {
		senders = append(senders, rateLimitedSender)
	}
	senders = append(senders, successSender)
	s.sender = senders

	_, err := env.StartInstance(makeStartInstanceParams(c, s.controllerUUID, "quantal"))
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(s.requests, gc.HasLen, numExpectedStartInstanceRequests+failures)
	s.assertStartInstanceRequests(c, s.requests[:numExpectedStartInstanceRequests], assertStartInstanceRequestsParams{
		imageReference: &quantalImageReference,
		diskSizeGB:     32,
		osProfile:      &linuxOsProfile,
	})

	// The final requests should all be identical.
	for i := numExpectedStartInstanceRequests; i < numExpectedStartInstanceRequests+failures; i++ {
		c.Assert(s.requests[i].Method, gc.Equals, "PUT")
		c.Assert(s.requests[i].URL.Path, gc.Equals, s.requests[numExpectedStartInstanceRequests-1].URL.Path)
	}

	s.retryClock.CheckCalls(c, []gitjujutesting.StubCall{
		{"After", []interface{}{5 * time.Second}},
		{"After", []interface{}{10 * time.Second}},
		{"After", []interface{}{20 * time.Second}},
		{"After", []interface{}{40 * time.Second}},
		{"After", []interface{}{1 * time.Minute}},
		{"After", []interface{}{1 * time.Minute}},
	})
}
Пример #6
0
func TestDeviceCodeReturnsErrorIfBadRequest(t *testing.T) {
	sender := mocks.NewSender()
	body := mocks.NewBody("doesn't matter")
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, 400, "Bad Request"))
	client := &autorest.Client{Sender: sender}

	_, err := InitiateDeviceAuth(client, TestOAuthConfig, TestClientID, TestResource)
	if err == nil || !strings.Contains(err.Error(), errCodeHandlingFails) {
		t.Fatalf("azure: failed to get correct error expected(%s) actual(%s)", errCodeHandlingFails, err.Error())
	}

	if body.IsOpen() {
		t.Fatalf("response body was left open!")
	}
}
Пример #7
0
func TestDeviceTokenReturnsErrorIfSlowDown(t *testing.T) {
	sender := mocks.NewSender()
	body := mocks.NewBody(errorDeviceTokenResponse("slow_down"))
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, 400, "Bad Request"))
	client := &autorest.Client{Sender: sender}

	_, err := CheckForUserCompletion(client, deviceCode())
	if err != ErrDeviceSlowDown {
		t.Fatalf("!!!")
	}

	if body.IsOpen() {
		t.Fatalf("response body was left open!")
	}
}
Пример #8
0
func TestDeviceTokenReturnsErrorIfCodeExpired(t *testing.T) {
	sender := mocks.NewSender()
	body := mocks.NewBody(errorDeviceTokenResponse("code_expired"))
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, 400, "Bad Request"))
	client := &autorest.Client{Sender: sender}

	_, err := WaitForUserCompletion(client, deviceCode())
	if err != ErrDeviceCodeExpired {
		t.Fatalf("azure: got wrong error expected(%s) actual(%s)", ErrDeviceCodeExpired.Error(), err.Error())
	}

	if body.IsOpen() {
		t.Fatalf("response body was left open!")
	}
}
Пример #9
0
func TestDeviceTokenReturnsErrorIfServerError(t *testing.T) {
	sender := mocks.NewSender()
	body := mocks.NewBody("")
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, 500, "Internal Server Error"))
	client := &autorest.Client{Sender: sender}

	_, err := WaitForUserCompletion(client, deviceCode())
	if err == nil || !strings.Contains(err.Error(), errTokenHandlingFails) {
		t.Fatalf("azure: failed to get correct error expected(%s) actual(%s)", errTokenHandlingFails, err.Error())
	}

	if body.IsOpen() {
		t.Fatalf("response body was left open!")
	}
}
Пример #10
0
func TestDeviceTokenReturns(t *testing.T) {
	sender := mocks.NewSender()
	body := mocks.NewBody(MockDeviceTokenResponse)
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, 200, "OK"))
	client := &autorest.Client{Sender: sender}

	_, err := WaitForUserCompletion(client, deviceCode())
	if err != nil {
		t.Fatalf("azure: got error unexpectedly")
	}

	if body.IsOpen() {
		t.Fatalf("response body was left open!")
	}
}
Пример #11
0
func TestDeviceCodeReturnsErrorIfCannotDeserializeDeviceCode(t *testing.T) {
	gibberishJSON := strings.Replace(MockDeviceCodeResponse, "expires_in", "\":, :gibberish", -1)
	sender := mocks.NewSender()
	body := mocks.NewBody(gibberishJSON)
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, 200, "OK"))
	client := &autorest.Client{Sender: sender}

	_, err := InitiateDeviceAuth(client, TestOAuthConfig, TestClientID, TestResource)
	if err == nil || !strings.Contains(err.Error(), errCodeHandlingFails) {
		t.Fatalf("azure: failed to get correct error expected(%s) actual(%s)", errCodeHandlingFails, err.Error())
	}

	if body.IsOpen() {
		t.Fatalf("response body was left open!")
	}
}
Пример #12
0
func TestDeviceTokenReturnsErrorIfCannotDeserializeDeviceToken(t *testing.T) {
	gibberishJSON := strings.Replace(MockDeviceTokenResponse, "expires_in", ";:\"gibberish", -1)
	sender := mocks.NewSender()
	body := mocks.NewBody(gibberishJSON)
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, 200, "OK"))
	client := &autorest.Client{Sender: sender}

	_, err := WaitForUserCompletion(client, deviceCode())
	if err == nil || !strings.Contains(err.Error(), errTokenHandlingFails) {
		t.Fatalf("azure: failed to get correct error expected(%s) actual(%s)", errTokenHandlingFails, err.Error())
	}

	if body.IsOpen() {
		t.Fatalf("response body was left open!")
	}
}
Пример #13
0
func (s *environSuite) TestStartInstanceTooManyRequestsTimeout(c *gc.C) {
	env := s.openEnviron(c)
	senders := s.startInstanceSenders(false)
	s.requests = nil

	// 8 failures to get to 5 minutes, which is as long as we'll keep
	// retrying before giving up.
	const failures = 8

	// Make the VirtualMachines.Get call respond with enough 429
	// (StatusTooManyRequests) failures to cause the method to give
	// up retrying.
	rateLimitedSender := mocks.NewSender()
	rateLimitedSender.AppendAndRepeatResponse(mocks.NewResponseWithBodyAndStatus(
		mocks.NewBody("{}"), // empty JSON response to appease go-autorest
		http.StatusTooManyRequests,
		"(」゜ロ゜)」",
	), failures)
	senders = senders[:len(senders)-1]
	for i := 0; i < failures; i++ {
		senders = append(senders, rateLimitedSender)
	}
	s.sender = senders

	_, err := env.StartInstance(makeStartInstanceParams(c, s.controllerUUID, "quantal"))
	c.Assert(err, gc.ErrorMatches, `creating virtual machine "machine-0": creating deployment "machine-0": max duration exceeded: .*`)

	s.retryClock.CheckCalls(c, []gitjujutesting.StubCall{
		{"After", []interface{}{5 * time.Second}},  // t0 + 5s
		{"After", []interface{}{10 * time.Second}}, // t0 + 15s
		{"After", []interface{}{20 * time.Second}}, // t0 + 35s
		{"After", []interface{}{40 * time.Second}}, // t0 + 1m15s
		{"After", []interface{}{1 * time.Minute}},  // t0 + 2m15s
		{"After", []interface{}{1 * time.Minute}},  // t0 + 3m15s
		{"After", []interface{}{1 * time.Minute}},  // t0 + 4m15s
		// There would be another call here, but since the time
		// exceeds the give minute limit, retrying is aborted.
	})
}
Пример #14
0
func TestDoPollForAsynchronous_WithNilURI(t *testing.T) {
	r1 := newAsynchronousResponse()
	r1.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
	r1.Header.Del(http.CanonicalHeaderKey(autorest.HeaderLocation))

	r2 := newOperationResourceResponse("busy")
	r2.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
	r2.Header.Del(http.CanonicalHeaderKey(autorest.HeaderLocation))

	client := mocks.NewSender()
	client.AppendResponse(r1)
	client.AppendResponse(r2)

	req, _ := http.NewRequest("POST", "https://microsoft.com/a/b/c/", mocks.NewBody(""))
	r, err := autorest.SendWithSender(client, req,
		DoPollForAsynchronous(time.Millisecond))

	if err == nil {
		t.Fatalf("azure: DoPollForAsynchronous failed to return error for nil URI. got: nil; want: Azure Polling Error - Unable to obtain polling URI for POST")
	}

	autorest.Respond(r,
		autorest.ByClosing())
}
Пример #15
0
func newOperationResourceErrorResponse(status string) *http.Response {
	r := newAsynchronousResponse()
	r.Body = mocks.NewBody(fmt.Sprintf(operationResourceErrorFormat, status))
	return r
}
Пример #16
0
func newProvisioningStatusResponse(status string) *http.Response {
	r := newAsynchronousResponse()
	r.Body = mocks.NewBody(fmt.Sprintf(pollingStateFormat, status))
	return r
}
Пример #17
0
func createServicePrincipalAlreadyExistsSender() autorest.Sender {
	sender := mocks.NewSender()
	body := mocks.NewBody(`{"odata.error":{"code":"Request_MultipleObjectsWithSameKeyValue"}}`)
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, http.StatusConflict, ""))
	return sender
}
Пример #18
0
func roleAssignmentAlreadyExistsSender() autorest.Sender {
	sender := mocks.NewSender()
	body := mocks.NewBody(`{"error":{"code":"RoleAssignmentExists"}}`)
	sender.AppendResponse(mocks.NewResponseWithBodyAndStatus(body, http.StatusConflict, ""))
	return sender
}