Skip to content
This repository has been archived by the owner on Jul 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #116 from GoogleCloudPlatform/develop
Browse files Browse the repository at this point in the history
some new dependencies and async integration test framework
  • Loading branch information
ccemeraldeyes authored Mar 7, 2017
2 parents 5a28674 + 13ae1c1 commit a8c276d
Show file tree
Hide file tree
Showing 590 changed files with 172,104 additions and 62,353 deletions.
4 changes: 2 additions & 2 deletions brokerapi/brokers/name_generator/name_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ func (bng *BasicNameGenerator) InstanceNameWithSeparator(sep string) string {
return bng.newNameWithSeperator(sep)
}

func (bng *SqlNameGenerator) InstanceName() string {
return bng.newNameWithSeperator("-")
func (sng *SqlNameGenerator) InstanceName() string {
return sng.newNameWithSeperator("-")
}

func (sng *SqlNameGenerator) DatabaseName() string {
Expand Down
68 changes: 68 additions & 0 deletions fakes/fake_env_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,71 @@ const Services string = `[
"tags": ["gcp", "ml"]
}
]`

const PreconfiguredPlans = `[
{
"service_id": "b9e4332e-b42b-4680-bda5-ea1506797474",
"name": "standard",
"display_name": "Standard",
"description": "Standard storage class",
"features": {"storage_class": "STANDARD"}
},
{
"service_id": "b9e4332e-b42b-4680-bda5-ea1506797474",
"name": "nearline",
"display_name": "Nearline",
"description": "Nearline storage class",
"features": {"storage_class": "NEARLINE"}
},
{
"service_id": "b9e4332e-b42b-4680-bda5-ea1506797474",
"name": "reduced_availability",
"display_name": "Durable Reduced Availability",
"description": "Durable Reduced Availability storage class",
"features": {"storage_class": "DURABLE_REDUCED_AVAILABILITY"}
},
{
"service_id": "628629e3-79f5-4255-b981-d14c6c7856be",
"name": "default",
"display_name": "Default",
"description": "PubSub Default plan",
"features": ""
},
{ "service_id": "f80c0a3e-bd4d-4809-a900-b4e33a6450f1",
"name": "default",
"display_name": "Default",
"description": "BigQuery default plan",
"features": ""
},
{
"service_id": "5ad2dce0-51f7-4ede-8b46-293d6df1e8d4",
"name": "default",
"display_name": "Default",
"description": "Machine Learning api default plan",
"features": ""
}
]`

const TestCloudSQLPlan = `{
"test_cloudsql_plan": {
"guid": "test_cloudsql_plan",
"name": "test_cloudsql_plan",
"description": "test-cloudsql-plan",
"tier": "D4",
"pricing_plan": "PER_USE",
"max_disk_size": "20",
"display_name": "test_cloudsql_plan",
"service": "4bc59b9a-8520-409f-85da-1c7552315863"
}
}`
const TestBigtablePlan = `{
"test_bigtable_plan": {
"guid": "test_bigtable_plan",
"name": "test_bigtable_plan",
"description": "test-bigtable-plan",
"storage_type": "SSD",
"num_nodes": "3",
"display_name": "test_bigtable_plan",
"service": "b8e19880-ac58-42ef-b033-f7cd9c94d1fe"
}
}`
20 changes: 20 additions & 0 deletions fakes/fake_name_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,23 @@ func (sg *StaticNameGenerator) InstanceNameWithSeparator(sep string) string {
func (sg *StaticNameGenerator) DatabaseName() string {
return sg.Val
}

type StaticSQLNameGenerator struct {
StaticNameGenerator
}

func (sng *StaticSQLNameGenerator) InstanceName() string {
return sng.Val
}

func (sng *StaticSQLNameGenerator) DatabaseName() string {
return sng.Val
}

func (sng *StaticSQLNameGenerator) GenerateUsername(instanceID, bindingID string) (string, error) {
return sng.Val[:16], nil
}

func (sng *StaticSQLNameGenerator) GeneratePassword() (string, error) {
return sng.Val, nil
}
38 changes: 26 additions & 12 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import:
- bigtable
- bigquery
- storage
- spanner/admin/instance/apiv1
- spanner/...
testImport:
- package: github.com/onsi/ginkgo
version: ~1.2.0
Expand Down
179 changes: 179 additions & 0 deletions integration_tests/async_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// Copyright the Service Broker Project Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
//

package integration_tests

import (
"code.cloudfoundry.org/lager"
"fmt"
"gcp-service-broker/brokerapi/brokers"
. "gcp-service-broker/brokerapi/brokers"
"gcp-service-broker/brokerapi/brokers/models"
"gcp-service-broker/brokerapi/brokers/name_generator"
"gcp-service-broker/db_service"
"gcp-service-broker/fakes"
"github.com/jinzhu/gorm"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
googlecloudsql "google.golang.org/api/sqladmin/v1beta4"
"os"
"time"
)

func pollForMaxFiveMins(gcpb *GCPAsyncServiceBroker, instanceId string) error {
var err error
timeout := time.After(5 * time.Minute)
tick := time.Tick(30 * time.Second)

// Keep trying until we're timed out or got a result or got an error
for {
select {
case <-timeout:
return err
case <-tick:
done, err := gcpb.LastOperation(instanceId)
if err != nil {
return err
} else if done.State == models.Succeeded {
return nil
}
}
}
}

var _ = Describe("AsyncIntegrationTests", func() {
var (
gcpBroker *GCPAsyncServiceBroker
err error
logger lager.Logger
serviceNameToId map[string]string = make(map[string]string)
serviceNameToPlanId map[string]string = make(map[string]string)
instance_name string
cloudsqlInstanceName string
)

BeforeEach(func() {
logger = lager.NewLogger("brokers_test")
logger.RegisterSink(lager.NewWriterSink(GinkgoWriter, lager.DEBUG))

testDb, _ := gorm.Open("sqlite3", "test.db")
testDb.CreateTable(models.ServiceInstanceDetails{})
testDb.CreateTable(models.ServiceBindingCredentials{})
testDb.CreateTable(models.PlanDetails{})
testDb.CreateTable(models.ProvisionRequestDetails{})
testDb.CreateTable(models.CloudOperation{})

db_service.DbConnection = testDb

os.Setenv("SECURITY_USER_NAME", "username")
os.Setenv("SECURITY_USER_PASSWORD", "password")
os.Setenv("SERVICES", fakes.Services)
os.Setenv("PRECONFIGURED_PLANS", fakes.PreconfiguredPlans)

os.Setenv("CLOUDSQL_CUSTOM_PLANS", fakes.TestCloudSQLPlan)
os.Setenv("BIGTABLE_CUSTOM_PLANS", fakes.TestBigtablePlan)

var creds models.GCPCredentials
creds, err = brokers.GetCredentialsFromEnv()
if err != nil {
logger.Error("error", err)
}
instance_name = generateInstanceName(creds.ProjectId, "-")
cloudsqlInstanceName = fmt.Sprintf("pcf-sb-test-%d", time.Now().UnixNano())
name_generator.Basic = &fakes.StaticNameGenerator{Val: instance_name}
name_generator.Sql = &fakes.StaticSQLNameGenerator{
StaticNameGenerator: fakes.StaticNameGenerator{Val: cloudsqlInstanceName},
}

gcpBroker, err = brokers.New(logger)
if err != nil {
logger.Error("error", err)
}

for _, service := range *gcpBroker.Catalog {
serviceNameToId[service.Name] = service.ID
serviceNameToPlanId[service.Name] = service.Plans[0].ID
}
})

Describe("Cloud SQL", func() {

var dbService *googlecloudsql.InstancesService
var sslService *googlecloudsql.SslCertsService
BeforeEach(func() {
sqlService, err := googlecloudsql.New(gcpBroker.GCPClient)
Expect(err).NotTo(HaveOccurred())
dbService = googlecloudsql.NewInstancesService(sqlService)
sslService = googlecloudsql.NewSslCertsService(sqlService)
})

It("can provision/bind/unbind/deprovision", func() {
provisionDetails := models.ProvisionDetails{
ServiceID: serviceNameToId[models.CloudsqlName],
PlanID: serviceNameToPlanId[models.CloudsqlName],
}
_, err = gcpBroker.Provision("integration_test_instance", provisionDetails, true)
Expect(err).NotTo(HaveOccurred())
pollForMaxFiveMins(gcpBroker, "integration_test_instance")

var count int
db_service.DbConnection.Model(&models.ServiceInstanceDetails{}).Where("id = ?", "integration_test_instance").Count(&count)
Expect(count).To(Equal(1))

clouddb, err := dbService.Get(gcpBroker.RootGCPCredentials.ProjectId, cloudsqlInstanceName).Do()
Expect(err).NotTo(HaveOccurred())
Expect(clouddb.Name).To(Equal(cloudsqlInstanceName))

bindDetails := models.BindDetails{
ServiceID: serviceNameToId[models.CloudsqlName],
PlanID: serviceNameToPlanId[models.CloudsqlName],
}
creds, err := gcpBroker.Bind("integration_test_instance", "binding_id", bindDetails)
Expect(err).NotTo(HaveOccurred())
credsMap := creds.Credentials.(map[string]string)

Expect(credsMap["Username"]).ToNot(Equal(""))
_, err = sslService.Get(gcpBroker.RootGCPCredentials.ProjectId, cloudsqlInstanceName, credsMap["Sha1Fingerprint"]).Do()
Expect(err).NotTo(HaveOccurred())

unBindDetails := models.UnbindDetails{
ServiceID: serviceNameToId[models.CloudsqlName],
PlanID: serviceNameToPlanId[models.CloudsqlName],
}
err = gcpBroker.Unbind("integration_test_instance", "binding_id", unBindDetails)
Expect(err).NotTo(HaveOccurred())
certsList, err := sslService.List(gcpBroker.RootGCPCredentials.ProjectId, cloudsqlInstanceName).Do()
Expect(len(certsList.Items)).To(Equal(0))

deprovisionDetails := models.DeprovisionDetails{
ServiceID: serviceNameToId[models.CloudsqlName],
PlanID: serviceNameToPlanId[models.CloudsqlName],
}
_, err = gcpBroker.Deprovision("integration_test_instance", deprovisionDetails, true)
Expect(err).NotTo(HaveOccurred())
pollForMaxFiveMins(gcpBroker, "integration_test_instance")
_, err = dbService.Get(gcpBroker.RootGCPCredentials.ProjectId, cloudsqlInstanceName).Do()
Expect(err).To(HaveOccurred())
})

})

AfterEach(func() {
os.Remove(models.AppCredsFileName)
os.Remove("test.db")
})
})
Loading

0 comments on commit a8c276d

Please sign in to comment.