Skip to content

Commit

Permalink
Merge pull request #325 from PagerDuty/better_last_response_handling
Browse files Browse the repository at this point in the history
Add support for better API debugging; start v1.5.0 development
  • Loading branch information
theckman committed Aug 29, 2021
2 parents e23b94c + 4f01c5b commit a4171cc
Show file tree
Hide file tree
Showing 27 changed files with 741 additions and 187 deletions.
62 changes: 61 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,22 @@ An example of the `service` sub-command
pd service list
```
### Client Library
#### NOTICE: Breaking API Changes in master branch
As part of the upcoming `v1.5.0` release, we will be fixing features that have
never worked correctly and require a breaking API change to fix. One example is
the issue reported in [\#232](https://github.com/PagerDuty/go-pagerduty/issues/232),
as well as a handful of other examples within the
[v1.5.0 milestone](https://github.com/PagerDuty/go-pagerduty/milestone/2).
As a result, the `master` branch now contains breaking changes since the last
`v1.4.x` release. We will clearly highlight the breaking changes in the `v1.5.0`
release notes when it's ready.
#### Example Usage
```go
package main
Expand Down Expand Up @@ -113,6 +126,53 @@ func main() {
}
```

#### Extending and Debugging Client

##### Extending The Client

The `*pagerduty.Client` has a `Do` method which allows consumers to wrap the
client, and make their own requests to the PagerDuty API. The method signature
is similar to that of the `http.Client.Do` method, except it also includes a
`bool` to incidate whether the API endpoint is authenticated (i.e., the REST
API). When the API is authenticated, the client will annotate the request with
the appropriate headers to be authenticated by the API.

If PagerDuty the client doesn't natively expose functionality that you wish to
use, such as undocumented JSON fields, you can use the `Do()` method to issue
your own request that you can parse the response of.

Likewise, you can use it to issue requests to the API for the purposes of
debugging. However, that's not the only mechanism for debugging.

##### Debugging the Client

The `*pagerduty.Client` has a method that allows consumers to enable debug
functionality, including interception of PagerDuty API responses. This is done
by using the `SetDebugFlag()` method using the `pagerduty.DebugFlag` unsigned
integer type. There are also exported constants to help consumers enable
specific debug behaviors.

###### Capturing Last PagerDuty Response

If you're not getting the response you expect from the PagerDuty Go client, you
can enable the `DebugCaptureLastResponse` debug flag to capture the HTTP
responses. You can then use one of the methods to make an API call, and then
inspect the API response received. For example:

```Go
client := pagerduty.NewClient("exmaple")

client.SetDebugFlag(pagerduty.DebugCaptureLastResponse)

oncalls, err := client.ListOnCallsWithContext(ctx, pagerduty.ListOnCallOptions{})

resp, ok := client.LastAPIReponse()
if ok { // resp is an *http.Response we can inspect
body, err := ioutil.ReadAll(resp.Body)
// ...
}
```

## Contributing

1. Fork it ( https://github.com/PagerDuty/go-pagerduty/fork )
Expand Down
8 changes: 4 additions & 4 deletions ability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestAbility_ListAbilities(t *testing.T) {
_, _ = w.Write([]byte(`{"abilities": ["sso"]}`))
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")
want := &ListAbilityResponse{Abilities: []string{"sso"}}

res, err := client.ListAbilities()
Expand All @@ -34,7 +34,7 @@ func TestAbility_ListAbilitiesFailure(t *testing.T) {
w.WriteHeader(http.StatusForbidden)
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")

if _, err := client.ListAbilities(); err == nil {
t.Fatal("expected error; got nil")
Expand All @@ -50,7 +50,7 @@ func TestAbility_TestAbility(t *testing.T) {
w.WriteHeader(http.StatusNoContent)
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")

if err := client.TestAbility("sso"); err != nil {
t.Fatal(err)
Expand All @@ -66,7 +66,7 @@ func TestAbility_TestAbilityFailure(t *testing.T) {
w.WriteHeader(http.StatusForbidden)
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")

if err := client.TestAbility("sso"); err == nil {
t.Fatal("expected error; got nil")
Expand Down
10 changes: 5 additions & 5 deletions addon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestAddon_List(t *testing.T) {
})
listObj := APIListObject{Limit: 0, Offset: 0, More: false, Total: 0}
var opts ListAddonOptions
client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")

res, err := client.ListAddons(opts)
want := &ListAddonResponse{
Expand Down Expand Up @@ -46,7 +46,7 @@ func TestAddon_Install(t *testing.T) {
_, _ = w.Write([]byte(`{"addon": {"name": "Internal Status Page", "id": "1"}}`))
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")

res, err := client.InstallAddon(input)

Expand All @@ -70,7 +70,7 @@ func TestAddon_Get(t *testing.T) {
testMethod(t, r, "GET")
_, _ = w.Write([]byte(`{"addon": {"id": "1"}}`))
})
client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")

res, err := client.GetAddon("1")

Expand All @@ -93,7 +93,7 @@ func TestAddon_Update(t *testing.T) {
testMethod(t, r, "PUT")
_, _ = w.Write([]byte(`{"addon": {"name": "Internal Status Page", "id": "1"}}`))
})
client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")

input := Addon{
Name: "Internal Status Page",
Expand Down Expand Up @@ -121,7 +121,7 @@ func TestAddon_Delete(t *testing.T) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")
err := client.DeleteAddon("1")
if err != nil {
t.Fatal(err)
Expand Down
18 changes: 3 additions & 15 deletions analytics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ func TestAnalytics_GetAggregatedIncidentData(t *testing.T) {
_, _ = w.Write(bytesAnalyticsResponse)
})

client := &Client{
apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}
client := defaultTestClient(server.URL, "foo")

res, err := client.GetAggregatedIncidentData(context.Background(), analyticsRequest)
want := AnalyticsResponse{
Expand Down Expand Up @@ -85,11 +81,7 @@ func TestAnalytics_GetAggregatedServiceData(t *testing.T) {
_, _ = w.Write(bytesAnalyticsResponse)
})

client := &Client{
apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}
client := defaultTestClient(server.URL, "foo")

res, err := client.GetAggregatedServiceData(context.Background(), analyticsRequest)
want := AnalyticsResponse{
Expand Down Expand Up @@ -133,11 +125,7 @@ func TestAnalytics_GetAggregatedTeamData(t *testing.T) {
_, _ = w.Write(bytesAnalyticsResponse)
})

client := &Client{
apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}
client := defaultTestClient(server.URL, "foo")

res, err := client.GetAggregatedTeamData(context.Background(), analyticsRequest)
want := AnalyticsResponse{
Expand Down
10 changes: 5 additions & 5 deletions business_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestBusinessService_List(t *testing.T) {
})

listObj := APIListObject{Limit: 0, Offset: 0, More: false, Total: 0}
client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")
opts := ListBusinessServiceOptions{
APIListObject: listObj,
}
Expand Down Expand Up @@ -47,7 +47,7 @@ func TestBusinessService_Create(t *testing.T) {
_, _ = w.Write([]byte(`{"business_service": {"id": "1", "name": "foo"}}`))
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")
input := &BusinessService{
Name: "foo",
}
Expand All @@ -74,7 +74,7 @@ func TestBusinessService_Get(t *testing.T) {
_, _ = w.Write([]byte(`{"business_service": {"id": "1", "name":"foo"}}`))
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")
ruleSetID := "1"

res, _, err := client.GetBusinessService(ruleSetID)
Expand Down Expand Up @@ -112,7 +112,7 @@ func TestBusinessService_Update(t *testing.T) {
_, _ = w.Write([]byte(`{"business_service": {"id": "1", "name":"foo"}}`))
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")
input := &BusinessService{
ID: "1",
Name: "foo",
Expand All @@ -139,7 +139,7 @@ func TestBusinessService_Delete(t *testing.T) {
testMethod(t, r, "DELETE")
})

client := &Client{apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
client := defaultTestClient(server.URL, "foo")
ID := "1"
err := client.DeleteBusinessService(ID)
if err != nil {
Expand Down
14 changes: 2 additions & 12 deletions change_events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ func TestChangeEvent_Create(t *testing.T) {
},
)

client := &Client{
v2EventsAPIEndpoint: server.URL,
apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}
client := defaultTestClient(server.URL, "foo")

want := ChangeEventResponse{
Status: "success",
Expand Down Expand Up @@ -81,12 +76,7 @@ func TestChangeEvent_CreateWithPayloadVerification(t *testing.T) {
},
)

client := &Client{
v2EventsAPIEndpoint: server.URL,
apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}
client := defaultTestClient(server.URL, "foo")

eventDetails := map[string]interface{}{"DetailKey1": "DetailValue1", "DetailKey2": "DetailValue2"}
ce := ChangeEvent{
Expand Down
Loading

0 comments on commit a4171cc

Please sign in to comment.