func (*environSuite) TestAttemptCreateServiceCreatesService(c *C) { prefix := "myservice" affinityGroup := "affinity-group" location := "location" responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(makeAvailabilityResponse(c), http.StatusOK, nil), gwacl.NewDispatcherResponse(nil, http.StatusOK, nil), } requests := gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "", "West US") c.Assert(err, IsNil) service, err := attemptCreateService(azure, prefix, affinityGroup, location) c.Assert(err, IsNil) c.Assert(*requests, HasLen, 2) body := parseCreateServiceRequest(c, (*requests)[1]) c.Check(body.ServiceName, Equals, service.ServiceName) c.Check(body.AffinityGroup, Equals, affinityGroup) c.Check(service.ServiceName, Matches, prefix+".*") c.Check(service.Location, Equals, location) label, err := base64.StdEncoding.DecodeString(service.Label) c.Assert(err, IsNil) c.Check(string(label), Equals, service.ServiceName) }
func (*EnvironSuite) TestAttemptCreateServicePropagatesOtherFailure(c *C) { responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(nil, http.StatusNotFound, nil), } gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "certfile.pem") c.Assert(err, IsNil) _, err = attemptCreateService(azure, "service", "affinity-group") c.Assert(err, NotNil) c.Check(err, ErrorMatches, ".*Not Found.*") }
func (*environSuite) TestAttemptCreateServiceReturnsNilIfNameNotUnique(c *C) { responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(makeNonAvailabilityResponse(c), http.StatusOK, nil), } gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "", "West US") c.Assert(err, IsNil) service, err := attemptCreateService(azure, "service", "affinity-group", "location") c.Check(err, IsNil) c.Check(service, IsNil) }
func (*EnvironSuite) TestAttemptCreateServiceReturnsNilIfNameNotUnique(c *C) { errorBody := makeServiceNameAlreadyTakenError(c) responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(errorBody, http.StatusConflict, nil), } gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "certfile.pem") c.Assert(err, IsNil) service, err := attemptCreateService(azure, "service", "affinity-group") c.Check(err, IsNil) c.Check(service, IsNil) }
func (*EnvironSuite) TestNewHostedServiceFailsIfUnableToFindUniqueName(c *C) { errorBody := makeServiceNameAlreadyTakenError(c) responses := []gwacl.DispatcherResponse{} for counter := 0; counter < 100; counter++ { responses = append(responses, gwacl.NewDispatcherResponse(errorBody, http.StatusConflict, nil)) } gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "certfile.pem") c.Assert(err, IsNil) _, err = newHostedService(azure, "service", "affinity-group") c.Assert(err, NotNil) c.Check(err, ErrorMatches, "could not come up with a unique hosted service name.*") }
func (*environSuite) TestNewHostedServiceRetriesIfNotUnique(c *C) { errorBody := makeNonAvailabilityResponse(c) okBody := makeAvailabilityResponse(c) // In this scenario, the first two names that we try are already // taken. The third one is unique though, so we succeed. responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(errorBody, http.StatusOK, nil), gwacl.NewDispatcherResponse(errorBody, http.StatusOK, nil), gwacl.NewDispatcherResponse(okBody, http.StatusOK, nil), gwacl.NewDispatcherResponse(nil, http.StatusOK, nil), } requests := gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "", "West US") c.Assert(err, IsNil) service, err := newHostedService(azure, "service", "affinity-group", "location") c.Check(err, IsNil) c.Assert(*requests, HasLen, 4) // How many names have been attempted, and how often? // There is a minute chance that this tries the same name twice, and // then this test will fail. If that happens, try seeding the // randomizer with some fixed seed that doens't produce the problem. attemptedNames := make(map[string]int) for _, request := range *requests { // Exit the loop if we hit the request to create the service, it comes // after the check calls. if request.Method == "POST" { break } // Name is the last part of the URL from the GET requests that check // availability. _, name := path.Split(strings.TrimRight(request.URL, "/")) attemptedNames[name] += 1 } // The three attempts we just made all had different service names. c.Check(attemptedNames, HasLen, 3) // Once newHostedService succeeds, we get a hosted service with the // last requested name. c.Check( service.ServiceName, Equals, parseCreateServiceRequest(c, (*requests)[3]).ServiceName) }
func (*EnvironSuite) TestNewHostedServiceCreatesService(c *C) { prefix := "myservice" affinityGroup := "affinity-group" responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(nil, http.StatusOK, nil), } requests := gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "certfile.pem") c.Assert(err, IsNil) service, err := newHostedService(azure, prefix, affinityGroup) c.Assert(err, IsNil) c.Assert(*requests, HasLen, 1) body := parseCreateServiceRequest(c, (*requests)[0]) c.Check(body.ServiceName, Equals, service.ServiceName) c.Check(body.AffinityGroup, Equals, affinityGroup) c.Check(service.ServiceName, Matches, prefix+".*") }
// getManagementAPI obtains a context object for interfacing with Azure's // management API. // For now, each invocation just returns a separate object. This is probably // wasteful (each context gets its own SSL connection) and may need optimizing // later. func (env *azureEnviron) getManagementAPI() (*azureManagementContext, error) { snap := env.getSnapshot() subscription := snap.ecfg.ManagementSubscriptionId() certData := snap.ecfg.ManagementCertificate() certFile, err := newTempCertFile([]byte(certData)) if err != nil { return nil, err } // After this point, if we need to leave prematurely, we should clean // up that certificate file. mgtAPI, err := gwacl.NewManagementAPI(subscription, certFile.Path()) if err != nil { certFile.Delete() return nil, err } context := azureManagementContext{ ManagementAPI: mgtAPI, certFile: certFile, } return &context, nil }
func (*EnvironSuite) TestAttemptCreateServiceRecognizesChangedConflictError(c *C) { // Even if Azure or gwacl makes slight changes to the error they // return (e.g. to translate output), attemptCreateService can still // recognize the error that means "this service name is not unique." errorBody, err := xml.Marshal(gwacl.AzureError{ error: fmt.Errorf("broken HTTP request"), HTTPStatus: http.StatusConflict, Code: "ServiceNameTaken", Message: "De aangevraagde naam is al in gebruik.", }) c.Assert(err, IsNil) responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(errorBody, http.StatusConflict, nil), } gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "certfile.pem") c.Assert(err, IsNil) service, err := attemptCreateService(azure, "service", "affinity-group") c.Check(err, IsNil) c.Check(service, IsNil) }
func (*EnvironSuite) TestNewHostedServiceRetriesIfNotUnique(c *C) { errorBody := makeServiceNameAlreadyTakenError(c) // In this scenario, the first two names that we try are already // taken. The third one is unique though, so we succeed. responses := []gwacl.DispatcherResponse{ gwacl.NewDispatcherResponse(errorBody, http.StatusConflict, nil), gwacl.NewDispatcherResponse(errorBody, http.StatusConflict, nil), gwacl.NewDispatcherResponse(nil, http.StatusOK, nil), } requests := gwacl.PatchManagementAPIResponses(responses) azure, err := gwacl.NewManagementAPI("subscription", "certfile.pem") c.Assert(err, IsNil) service, err := newHostedService(azure, "service", "affinity-group") c.Check(err, IsNil) c.Assert(*requests, HasLen, 3) // How many names have been attempted, and how often? // There is a minute chance that this tries the same name twice, and // then this test will fail. If that happens, try seeding the // randomizer with some fixed seed that doens't produce the problem. attemptedNames := make(map[string]int) for _, request := range *requests { name := parseCreateServiceRequest(c, request).ServiceName attemptedNames[name] += 1 } // The three attempts we just made all had different service names. c.Check(attemptedNames, HasLen, 3) // Once newHostedService succeeds, we get a hosted service with the // last requested name. c.Check( service.ServiceName, Equals, parseCreateServiceRequest(c, (*requests)[2]).ServiceName) }