Skip to content

Commit f30db23

Browse files
committed
test: Improve mocked discovery server to support custom URLs
This makes it easier to test the identity client Signed-off-by: Ashley Davis <[email protected]>
1 parent a0aa19d commit f30db23

File tree

3 files changed

+136
-88
lines changed

3 files changed

+136
-88
lines changed

pkg/internal/cyberark/servicediscovery/discovery_test.go

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -2,101 +2,18 @@ package servicediscovery
22

33
import (
44
"context"
5-
"crypto/rand"
6-
"encoding/hex"
7-
"encoding/json"
85
"fmt"
9-
"net/http"
10-
"net/http/httptest"
11-
"strings"
126
"testing"
13-
14-
"github.com/jetstack/preflight/pkg/version"
15-
16-
_ "embed"
177
)
188

19-
//go:embed testdata/discovery_success.json
20-
var discoverySuccessResponse string
21-
22-
func testHandler(w http.ResponseWriter, r *http.Request) {
23-
if r.Method != http.MethodGet {
24-
// This was observed by making a POST request to the integration environment
25-
// Normally, we'd expect 405 Method Not Allowed but we match the observed response here
26-
w.WriteHeader(http.StatusForbidden)
27-
_, _ = w.Write([]byte(`{"message":"Missing Authentication Token"}`))
28-
return
29-
}
30-
31-
if !strings.HasPrefix(r.URL.String(), "/services/subdomain/") {
32-
// This was observed by making a request to /api/v2/services/asd
33-
// Normally, we'd expect 404 Not Found but we match the observed response here
34-
w.WriteHeader(http.StatusForbidden)
35-
_, _ = w.Write([]byte(`{"message":"Missing Authentication Token"}`))
36-
return
37-
}
38-
39-
if r.Header.Get("User-Agent") != version.UserAgent() {
40-
w.WriteHeader(http.StatusInternalServerError)
41-
_, _ = w.Write([]byte("should set user agent on all requests"))
42-
return
43-
}
44-
45-
if r.Header.Get("Accept") != "application/json" {
46-
w.WriteHeader(http.StatusInternalServerError)
47-
_, _ = w.Write([]byte("should request JSON on all requests"))
48-
return
49-
}
50-
51-
subdomain := strings.TrimPrefix(r.URL.String(), "/services/subdomain/")
52-
53-
switch subdomain {
54-
case "venafi-test":
55-
_, _ = w.Write([]byte(discoverySuccessResponse))
56-
57-
case "no-identity":
58-
// return a snippet of valid service discovery JSON, but don't include the identity service
59-
_, _ = w.Write([]byte(`{"data_privacy": {"ui": "https://ui.dataprivacy.integration-cyberark.cloud/", "api": "https://us-east-1.dataprivacy.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-data_privacy.integration-cyberark.cloud", "region": "us-east-1"}}`))
60-
61-
case "bad-request":
62-
// test how the client handles a random unexpected response
63-
w.WriteHeader(http.StatusBadRequest)
64-
_, _ = w.Write([]byte("{}"))
65-
66-
case "json-invalid":
67-
// test that the client correctly rejects handles invalid JSON
68-
w.WriteHeader(http.StatusOK)
69-
_, _ = w.Write([]byte(`{"a": a}`))
70-
71-
case "json-too-long":
72-
// test that the client correctly rejects JSON which is too long
73-
w.WriteHeader(http.StatusOK)
74-
75-
// we'll hex encode the random bytes (doubling the size)
76-
longData := make([]byte, 1+maxDiscoverBodySize/2)
77-
_, _ = rand.Read(longData)
78-
79-
longJSON, err := json.Marshal(map[string]string{"key": hex.EncodeToString(longData)})
80-
if err != nil {
81-
panic(err)
82-
}
83-
84-
_, _ = w.Write(longJSON)
85-
86-
default:
87-
w.WriteHeader(http.StatusNotFound)
88-
_, _ = w.Write([]byte("{}"))
89-
}
90-
}
91-
929
func Test_DiscoverIdentityAPIURL(t *testing.T) {
9310
tests := map[string]struct {
9411
subdomain string
9512
expectedURL string
9613
expectedError error
9714
}{
9815
"successful request": {
99-
subdomain: "venafi-test",
16+
subdomain: MockDiscoverySubdomain,
10017
expectedURL: "https://ajp5871.id.integration-cyberark.cloud",
10118
expectedError: nil,
10219
},
@@ -131,11 +48,10 @@ func Test_DiscoverIdentityAPIURL(t *testing.T) {
13148
t.Run(name, func(t *testing.T) {
13249
ctx := context.Background()
13350

134-
ts := httptest.NewServer(http.HandlerFunc(testHandler))
135-
51+
ts := MockDiscoveryServer()
13652
defer ts.Close()
13753

138-
client := New(WithCustomEndpoint(ts.URL))
54+
client := New(WithCustomEndpoint(ts.Server.URL))
13955

14056
apiURL, err := client.DiscoverIdentityAPIURL(ctx, testSpec.subdomain)
14157
if err != nil {
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package servicediscovery
2+
3+
import (
4+
"bytes"
5+
"crypto/rand"
6+
_ "embed"
7+
"encoding/hex"
8+
"encoding/json"
9+
"net/http"
10+
"net/http/httptest"
11+
"strings"
12+
"text/template"
13+
14+
"github.com/jetstack/preflight/pkg/version"
15+
)
16+
17+
const (
18+
// MockDiscoverySubdomain is the subdomain for which the MockDiscoveryServer will return a success response
19+
MockDiscoverySubdomain = "venafi-test"
20+
21+
defaultIdentityAPIURL = "https://ajp5871.id.integration-cyberark.cloud"
22+
)
23+
24+
//go:embed testdata/discovery_success.json.template
25+
var discoverySuccessTemplate string
26+
27+
type mockDiscoveryServer struct {
28+
Server *httptest.Server
29+
30+
successResponse string
31+
}
32+
33+
// MockDiscoveryServer returns a mocked discovery server with a default value for the Identity API.
34+
// The returned server should be Closed by the caller after use.
35+
func MockDiscoveryServer() *mockDiscoveryServer {
36+
return MockDiscoveryServerWithCustomAPIURL(defaultIdentityAPIURL)
37+
}
38+
39+
func MockDiscoveryServerWithCustomAPIURL(apiURL string) *mockDiscoveryServer {
40+
tmpl := template.Must(template.New("mockDiscoverySuccess").Parse(discoverySuccessTemplate))
41+
42+
buf := &bytes.Buffer{}
43+
44+
err := tmpl.Execute(buf, struct{ IdentityAPIURL string }{apiURL})
45+
if err != nil {
46+
panic(err)
47+
}
48+
49+
mds := &mockDiscoveryServer{
50+
successResponse: buf.String(),
51+
}
52+
53+
server := httptest.NewServer(mds)
54+
55+
mds.Server = server
56+
57+
return mds
58+
}
59+
60+
func (mds *mockDiscoveryServer) Close() {
61+
mds.Server.Close()
62+
}
63+
64+
func (mds *mockDiscoveryServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
65+
if r.Method != http.MethodGet {
66+
// This was observed by making a POST request to the integration environment
67+
// Normally, we'd expect 405 Method Not Allowed but we match the observed response here
68+
w.WriteHeader(http.StatusForbidden)
69+
_, _ = w.Write([]byte(`{"message":"Missing Authentication Token"}`))
70+
return
71+
}
72+
73+
if !strings.HasPrefix(r.URL.String(), "/services/subdomain/") {
74+
// This was observed by making a request to /api/v2/services/asd
75+
// Normally, we'd expect 404 Not Found but we match the observed response here
76+
w.WriteHeader(http.StatusForbidden)
77+
_, _ = w.Write([]byte(`{"message":"Missing Authentication Token"}`))
78+
return
79+
}
80+
81+
if r.Header.Get("User-Agent") != version.UserAgent() {
82+
w.WriteHeader(http.StatusInternalServerError)
83+
_, _ = w.Write([]byte("should set user agent on all requests"))
84+
return
85+
}
86+
87+
if r.Header.Get("Accept") != "application/json" {
88+
w.WriteHeader(http.StatusInternalServerError)
89+
_, _ = w.Write([]byte("should request JSON on all requests"))
90+
return
91+
}
92+
93+
subdomain := strings.TrimPrefix(r.URL.String(), "/services/subdomain/")
94+
95+
switch subdomain {
96+
case MockDiscoverySubdomain:
97+
_, _ = w.Write([]byte(mds.successResponse))
98+
99+
case "no-identity":
100+
// return a snippet of valid service discovery JSON, but don't include the identity service
101+
_, _ = w.Write([]byte(`{"data_privacy": {"ui": "https://ui.dataprivacy.integration-cyberark.cloud/", "api": "https://us-east-1.dataprivacy.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-data_privacy.integration-cyberark.cloud", "region": "us-east-1"}}`))
102+
103+
case "bad-request":
104+
// test how the client handles a random unexpected response
105+
w.WriteHeader(http.StatusBadRequest)
106+
_, _ = w.Write([]byte("{}"))
107+
108+
case "json-invalid":
109+
// test that the client correctly rejects handles invalid JSON
110+
w.WriteHeader(http.StatusOK)
111+
_, _ = w.Write([]byte(`{"a": a}`))
112+
113+
case "json-too-long":
114+
// test that the client correctly rejects JSON which is too long
115+
w.WriteHeader(http.StatusOK)
116+
117+
// we'll hex encode the random bytes (doubling the size)
118+
longData := make([]byte, 1+maxDiscoverBodySize/2)
119+
_, _ = rand.Read(longData)
120+
121+
longJSON, err := json.Marshal(map[string]string{"key": hex.EncodeToString(longData)})
122+
if err != nil {
123+
panic(err)
124+
}
125+
126+
_, _ = w.Write(longJSON)
127+
128+
default:
129+
w.WriteHeader(http.StatusNotFound)
130+
_, _ = w.Write([]byte("{}"))
131+
}
132+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"data_privacy": {"ui": "https://ui.dataprivacy.integration-cyberark.cloud/", "api": "https://us-east-1.dataprivacy.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-data_privacy.integration-cyberark.cloud", "region": "us-east-1"}, "secrets_manager": {"ui": "https://ui.test-conjur.cloud", "api": "https://venafi-test.secretsmgr.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-secrets_manager.integration-cyberark.cloud", "region": "us-east-2"}, "idaptive_risk_analytics": {"ui": "https://ajp5871-my.analytics.idaptive.qa", "api": "https://ajp5871-my.analytics.idaptive.qa", "bootstrap": "https://venafi-test-idaptive_risk_analytics.integration-cyberark.cloud", "region": "US-East-Pod"}, "component_manager": {"ui": "https://ui-connectormanagement.connectormanagement.integration-cyberark.cloud", "api": "https://venafi-test.connectormanagement.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-component_manager.integration-cyberark.cloud", "region": "us-east-1"}, "recording": {"ui": "https://us-east-1.rec-ui.recording.integration-cyberark.cloud", "api": "https://venafi-test.recording.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-recording.integration-cyberark.cloud", "region": "us-east-1"}, "identity_user_portal": {"ui": "https://ajp5871.id.integration-cyberark.cloud", "api": "https://ajp5871.id.integration-cyberark.cloud", "bootstrap": "https://venafi-test-identity_user_portal.integration-cyberark.cloud/my", "region": "US-East-Pod"}, "userportal": {"ui": "https://us-east-1.ui.userportal.integration-cyberark.cloud/", "api": "https://venafi-test.api.userportal.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-userportal.integration-cyberark.cloud", "region": "us-east-1"}, "cloud_onboarding": {"ui": "https://ui-cloudonboarding.cloudonboarding.integration-cyberark.cloud/", "api": "https://venafi-test.cloudonboarding.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-cloud_onboarding.integration-cyberark.cloud", "region": "us-east-1"}, "identity_administration": {"ui": "https://ajp5871.id.integration-cyberark.cloud", "api": "https://ajp5871.id.integration-cyberark.cloud", "bootstrap": "https://venafi-test-identity_administration.integration-cyberark.cloud/admin", "region": "US-East-Pod"}, "adminportal": {"ui": "https://ui-adminportal.adminportal.integration-cyberark.cloud", "api": "https://venafi-test.adminportal.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-adminportal.integration-cyberark.cloud", "region": "us-east-1"}, "analytics": {"ui": "https://venafi-test.analytics.integration-cyberark.cloud/", "api": "https://venafi-test.analytics.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-analytics.integration-cyberark.cloud", "region": "us-east-1"}, "session_monitoring": {"ui": "https://us-east-1.sm-ui.sessionmonitoring.integration-cyberark.cloud", "api": "https://venafi-test.sessionmonitoring.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-session_monitoring.integration-cyberark.cloud", "region": "us-east-1"}, "audit": {"ui": "https://ui.audit-ui.integration-cyberark.cloud", "api": "https://venafi-test.audit.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-audit.integration-cyberark.cloud", "region": "us-east-1"}, "fmcdp": {"ui": "https://tagtig.io/", "api": "https://tagtig.io/api", "bootstrap": "https://venafi-test-fmcdp.integration-cyberark.cloud", "region": "us-east-1"}, "featureadopt": {"ui": "https://ui-featureadopt.featureadopt.integration-cyberark.cloud/", "api": "https://us-east-1-featureadopt.featureadopt.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-featureadopt.integration-cyberark.cloud", "region": "us-east-1"}}
1+
{"data_privacy": {"ui": "https://ui.dataprivacy.integration-cyberark.cloud/", "api": "https://us-east-1.dataprivacy.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-data_privacy.integration-cyberark.cloud", "region": "us-east-1"}, "secrets_manager": {"ui": "https://ui.test-conjur.cloud", "api": "https://venafi-test.secretsmgr.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-secrets_manager.integration-cyberark.cloud", "region": "us-east-2"}, "idaptive_risk_analytics": {"ui": "https://ajp5871-my.analytics.idaptive.qa", "api": "https://ajp5871-my.analytics.idaptive.qa", "bootstrap": "https://venafi-test-idaptive_risk_analytics.integration-cyberark.cloud", "region": "US-East-Pod"}, "component_manager": {"ui": "https://ui-connectormanagement.connectormanagement.integration-cyberark.cloud", "api": "https://venafi-test.connectormanagement.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-component_manager.integration-cyberark.cloud", "region": "us-east-1"}, "recording": {"ui": "https://us-east-1.rec-ui.recording.integration-cyberark.cloud", "api": "https://venafi-test.recording.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-recording.integration-cyberark.cloud", "region": "us-east-1"}, "identity_user_portal": {"ui": "https://ajp5871.id.integration-cyberark.cloud", "api": "https://ajp5871.id.integration-cyberark.cloud", "bootstrap": "https://venafi-test-identity_user_portal.integration-cyberark.cloud/my", "region": "US-East-Pod"}, "userportal": {"ui": "https://us-east-1.ui.userportal.integration-cyberark.cloud/", "api": "https://venafi-test.api.userportal.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-userportal.integration-cyberark.cloud", "region": "us-east-1"}, "cloud_onboarding": {"ui": "https://ui-cloudonboarding.cloudonboarding.integration-cyberark.cloud/", "api": "https://venafi-test.cloudonboarding.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-cloud_onboarding.integration-cyberark.cloud", "region": "us-east-1"}, "identity_administration": {"ui": "https://ajp5871.id.integration-cyberark.cloud", "api": "{{ .IdentityAPIURL }}", "bootstrap": "https://venafi-test-identity_administration.integration-cyberark.cloud/admin", "region": "US-East-Pod"}, "adminportal": {"ui": "https://ui-adminportal.adminportal.integration-cyberark.cloud", "api": "https://venafi-test.adminportal.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-adminportal.integration-cyberark.cloud", "region": "us-east-1"}, "analytics": {"ui": "https://venafi-test.analytics.integration-cyberark.cloud/", "api": "https://venafi-test.analytics.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-analytics.integration-cyberark.cloud", "region": "us-east-1"}, "session_monitoring": {"ui": "https://us-east-1.sm-ui.sessionmonitoring.integration-cyberark.cloud", "api": "https://venafi-test.sessionmonitoring.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-session_monitoring.integration-cyberark.cloud", "region": "us-east-1"}, "audit": {"ui": "https://ui.audit-ui.integration-cyberark.cloud", "api": "https://venafi-test.audit.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-audit.integration-cyberark.cloud", "region": "us-east-1"}, "fmcdp": {"ui": "https://tagtig.io/", "api": "https://tagtig.io/api", "bootstrap": "https://venafi-test-fmcdp.integration-cyberark.cloud", "region": "us-east-1"}, "featureadopt": {"ui": "https://ui-featureadopt.featureadopt.integration-cyberark.cloud/", "api": "https://us-east-1-featureadopt.featureadopt.integration-cyberark.cloud/api", "bootstrap": "https://venafi-test-featureadopt.integration-cyberark.cloud", "region": "us-east-1"}}

0 commit comments

Comments
 (0)