Skip to content

Commit

Permalink
Investigate and fix flaky sql user test.
Browse files Browse the repository at this point in the history
This test fails for a few reasons: one, there are persistent quota
and service-unavailable errors with the second-gen SQL instances.
Two, the issue mentioned in #1184, that there's unspecified behavior
in tests where two resources have the same ID.  This changes the ID
to be user/host/instance instead of user/instance, and adds 429/503
handling to the sqladminOperationWait().
  • Loading branch information
nat-henderson committed Mar 16, 2018
1 parent 684029c commit f1deed8
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
8 changes: 4 additions & 4 deletions google/resource_sql_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func resourceSqlUserCreate(d *schema.ResourceData, meta interface{}) error {
"user %s into instance %s: %s", name, instance, err)
}

d.SetId(fmt.Sprintf("%s/%s", instance, name))
d.SetId(fmt.Sprintf("%s/%s/%s", user.Name, user.Host, user.Instance))

err = sqladminOperationWait(config, op, project, "Insert User")

Expand All @@ -109,7 +109,7 @@ func resourceSqlUserRead(d *schema.ResourceData, meta interface{}) error {

instance := d.Get("instance").(string)
name := d.Get("name").(string)
host := d.Get("host").(string)
host, hostOk := d.GetOk("host")

users, err := config.clientSqlAdmin.Users.List(project, instance).Do()

Expand All @@ -119,7 +119,7 @@ func resourceSqlUserRead(d *schema.ResourceData, meta interface{}) error {

var user *sqladmin.User
for _, currentUser := range users.Items {
if currentUser.Name == name && currentUser.Host == host {
if currentUser.Name == name && (!hostOk || currentUser.Host == host.(string)) {
user = currentUser
break
}
Expand All @@ -136,6 +136,7 @@ func resourceSqlUserRead(d *schema.ResourceData, meta interface{}) error {
d.Set("instance", user.Instance)
d.Set("name", user.Name)
d.Set("project", project)
d.SetId(fmt.Sprintf("%s/%s/%s", user.Name, user.Host, user.Instance))
return nil
}

Expand Down Expand Up @@ -225,7 +226,6 @@ func resourceSqlUserImporter(d *schema.ResourceData, meta interface{}) ([]*schem
d.Set("instance", parts[0])
d.Set("host", parts[1])
d.Set("name", parts[2])
d.SetId(fmt.Sprintf("%s/%s", parts[0], parts[2]))
} else {
return nil, fmt.Errorf("Invalid specifier. Expecting {instance}/{name} for 2nd generation instance and {instance}/{host}/{name} for 1st generation instance")
}
Expand Down
1 change: 1 addition & 0 deletions google/resource_sql_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func TestAccSqlUser_secondGen(t *testing.T) {
},
resource.TestStep{
ResourceName: "google_sql_user.user",
ImportStateId: instance + "/admin",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"password"},
Expand Down
19 changes: 17 additions & 2 deletions google/sqladmin_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package google

import (
"bytes"
"errors"
"fmt"
"log"
"time"

"github.com/hashicorp/terraform/helper/resource"
"google.golang.org/api/googleapi"
"google.golang.org/api/sqladmin/v1beta4"
)

Expand All @@ -20,10 +22,23 @@ func (w *SqlAdminOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
return func() (interface{}, string, error) {
var op *sqladmin.Operation
var err error
backoff := 1 * time.Second

log.Printf("[DEBUG] self_link: %s", w.Op.SelfLink)
op, err = w.Service.Operations.Get(w.Project, w.Op.Name).Do()

for {
op, err = w.Service.Operations.Get(w.Project, w.Op.Name).Do()

if e, ok := err.(*googleapi.Error); ok && (e.Code == 429 || e.Code == 503) {
backoff = backoff * 2
if backoff > 30*time.Second {
return nil, "", errors.New("Too many quota / service unavailable errors waiting for operation.")
}
time.Sleep(backoff)
continue
} else {
break
}
}
if err != nil {
return nil, "", err
}
Expand Down

0 comments on commit f1deed8

Please sign in to comment.