Skip to content

Commit

Permalink
Merge pull request #265 from ugur-zongur/master
Browse files Browse the repository at this point in the history
Fix incorrect state after failed updates
  • Loading branch information
DRuggeri authored Aug 5, 2024
2 parents f66246a + 244b7de commit f1b8ec8
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 3 deletions.
3 changes: 3 additions & 0 deletions restapi/resource_api_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ func resourceRestAPIRead(d *schema.ResourceData, meta interface{}) error {
func resourceRestAPIUpdate(d *schema.ResourceData, meta interface{}) error {
obj, err := makeAPIObject(d, meta)
if err != nil {
d.Partial(true)
return err
}

Expand All @@ -317,6 +318,8 @@ func resourceRestAPIUpdate(d *schema.ResourceData, meta interface{}) error {
err = obj.updateObject()
if err == nil {
setResourceState(obj, d)
} else {
d.Partial(true)
}
return err
}
Expand Down
79 changes: 76 additions & 3 deletions restapi/resource_api_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ package restapi
import (
"encoding/json"
"fmt"
"net/http"
"os"
"regexp"
"testing"

"github.com/Mastercard/terraform-provider-restapi/fakeserver"
Expand Down Expand Up @@ -106,9 +108,9 @@ func TestAccRestApiObject_Basic(t *testing.T) {
svr.Shutdown()
}

/* This function generates a terraform JSON configuration from
a name, JSON data and a list of params to set by coaxing it
all to maps and then serializing to JSON */
// This function generates a terraform JSON configuration from
// a name, JSON data and a list of params to set by coaxing it
// all to maps and then serializing to JSON
func generateTestResource(name string, data string, params map[string]interface{}) string {
strData, _ := json.Marshal(data)
config := []string{
Expand All @@ -130,3 +132,74 @@ resource "restapi_object" "%s" {
}
`, name, strConfig)
}

func mockServer(host string, returnCodes map[string]int, responses map[string]string) *http.Server {
serverMux := http.NewServeMux()
serverMux.HandleFunc("/api/", func(w http.ResponseWriter, req *http.Request) {
key := fmt.Sprintf("%s %s", req.Method, req.RequestURI) // e.g. "PUT /api/objects/1234"
returnCode, ok := returnCodes[key]
if !ok {
returnCode = http.StatusOK
}
w.WriteHeader(returnCode)
responseBody, ok := responses[key]
if !ok {
responseBody = ""
}
w.Write([]byte(responseBody))
})
srv := &http.Server{
Addr: host,
Handler: serverMux,
}
go srv.ListenAndServe()
return srv
}

func TestAccRestApiObject_FailedUpdate(t *testing.T) {
host := "127.0.0.1:8082"
returnCodes := map[string]int{
"PUT /api/objects/1234": http.StatusBadRequest,
}
responses := map[string]string{
"GET /api/objects/1234": `{ "id": "1234", "foo": "Bar" }`,
}
srv := mockServer(host, returnCodes, responses)
defer srv.Close()

os.Setenv("REST_API_URI", "http://"+host)

resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
{
// Create the resource
Config: generateTestResource(
"Foo",
`{ "id": "1234", "foo": "Bar" }`,
make(map[string]interface{}),
),
Check: resource.TestCheckResourceAttr("restapi_object.Foo", "data", `{ "id": "1234", "foo": "Bar" }`),
},
{
// Try update. It will fail becuase we return 400 for PUT operations from mock server
Config: generateTestResource(
"Foo",
`{ "id": "1234", "foo": "Updated" }`,
make(map[string]interface{}),
),
ExpectError: regexp.MustCompile("unexpected response code '400'"),
},
{
// Expecting plan to be non-empty because the failed apply above shouldn't update terraform state
Config: generateTestResource(
"Foo",
`{ "id": "1234", "foo": "Updated" }`,
make(map[string]interface{}),
),
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
},
})
}

0 comments on commit f1b8ec8

Please sign in to comment.