Skip to content

Commit 1281489

Browse files
mocking http server for unit tests
1 parent 421067f commit 1281489

File tree

4 files changed

+164
-0
lines changed

4 files changed

+164
-0
lines changed

remediation/workflow/pin/action_image_manifest_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,75 @@
11
package pin
22

33
import (
4+
"io/ioutil"
5+
"net/http"
6+
"net/http/httptest"
7+
"net/url"
8+
"strings"
49
"testing"
510
)
611

12+
var (
13+
testFilesDir = "../../../testfiles/pinactions/immutableActionResponses/"
14+
)
15+
16+
func createTestServer(t *testing.T) *httptest.Server {
17+
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
18+
19+
w.Header().Set("Content-Type", "application/json")
20+
21+
// Mock manifest endpoints
22+
switch r.URL.Path {
23+
24+
case "/token":
25+
// for immutable actions, since image will be present in registry...it returns 200 OK with token
26+
// otherwise it returns 403 Forbidden
27+
scope := r.URL.Query().Get("scope")
28+
switch scope {
29+
case "repository:actions/checkout:pull":
30+
fallthrough
31+
case "repository:step-security/wait-for-secrets:pull":
32+
w.WriteHeader(http.StatusOK)
33+
w.Write([]byte(`{"token": "test-token", "access_token": "test-token"}`))
34+
default:
35+
w.WriteHeader(http.StatusForbidden)
36+
w.Write([]byte(`{"errors": [{"code": "DENIED", "message": "requested access to the resource is denied"}]}`))
37+
}
38+
39+
case "/v2/actions/checkout/manifests/4.2.2":
40+
fallthrough
41+
case "/v2/step-security/wait-for-secrets/manifests/1.2.0":
42+
w.Write(readHttpResponseForAction(t, r.URL.Path))
43+
case "/v2/actions/checkout/manifests/1.2.3": // since this version doesn't exist
44+
fallthrough
45+
default:
46+
w.WriteHeader(http.StatusNotFound)
47+
w.Write(readHttpResponseForAction(t, "default"))
48+
}
49+
}))
50+
}
51+
752
func Test_isImmutableAction(t *testing.T) {
53+
// Create test server that mocks GitHub Container Registry
54+
server := createTestServer(t)
55+
defer server.Close()
56+
57+
// Create a custom client that redirects ghcr.io to our test server
58+
originalClient := http.DefaultClient
59+
http.DefaultClient = &http.Client{
60+
Transport: &http.Transport{
61+
Proxy: func(req *http.Request) (*url.URL, error) {
62+
if strings.Contains(req.URL.Host, "ghcr.io") {
63+
return url.Parse(server.URL)
64+
}
65+
return nil, nil
66+
},
67+
},
68+
}
69+
defer func() {
70+
http.DefaultClient = originalClient
71+
}()
72+
873
tests := []struct {
974
name string
1075
action string
@@ -52,3 +117,18 @@ func Test_isImmutableAction(t *testing.T) {
52117
})
53118
}
54119
}
120+
121+
func readHttpResponseForAction(t *testing.T, actionPath string) []byte {
122+
// remove v2 prefix from action path
123+
actionPath = strings.TrimPrefix(actionPath, "v2/")
124+
125+
fileName := strings.ReplaceAll(actionPath, "/", "-")
126+
respFilePath := testFilesDir + fileName
127+
128+
resp, err := ioutil.ReadFile(respFilePath)
129+
if err != nil {
130+
t.Fatalf("error reading test file")
131+
}
132+
133+
return resp
134+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"errors":[
3+
{
4+
"code":"MANIFEST_UNKNOWN",
5+
"message":"manifest unknown"
6+
}
7+
]
8+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"schemaVersion": 2,
3+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
4+
"artifactType": "application/vnd.github.actions.package.v1+json",
5+
"config": {
6+
"mediaType": "application/vnd.oci.empty.v1+json",
7+
"size": 2,
8+
"digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
9+
},
10+
"layers": [
11+
{
12+
"mediaType": "application/vnd.github.actions.package.layer.v1.tar+gzip",
13+
"size": 424913,
14+
"digest": "sha256:309d5e1a7604a5e688e2b55a6763e4109eb07349dca6d3c44e85c57ab2bb4f3f",
15+
"annotations": {
16+
"org.opencontainers.image.title": "actions-checkout_4.2.2.tar.gz"
17+
}
18+
},
19+
{
20+
"mediaType": "application/vnd.github.actions.package.layer.v1.zip",
21+
"size": 546845,
22+
"digest": "sha256:e9808fe811a75b46234757f9566987635166bca838090fcbc8021a0d45c737b3",
23+
"annotations": {
24+
"org.opencontainers.image.title": "actions-checkout_4.2.2.zip"
25+
}
26+
}
27+
],
28+
"annotations": {
29+
"org.opencontainers.image.created": "2024-10-23T14:46:13.071Z",
30+
"action.tar.gz.digest": "sha256:309d5e1a7604a5e688e2b55a6763e4109eb07349dca6d3c44e85c57ab2bb4f3f",
31+
"action.zip.digest": "sha256:e9808fe811a75b46234757f9566987635166bca838090fcbc8021a0d45c737b3",
32+
"com.github.package.type": "actions_oci_pkg",
33+
"com.github.package.version": "4.2.2",
34+
"com.github.source.repo.id": "197814629",
35+
"com.github.source.repo.owner.id": "44036562",
36+
"com.github.source.commit": "11bd71901bbe5b1630ceea73d27597364c9af683"
37+
}
38+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"schemaVersion": 2,
3+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
4+
"artifactType": "application/vnd.github.actions.package.v1+json",
5+
"config": {
6+
"mediaType": "application/vnd.oci.empty.v1+json",
7+
"size": 2,
8+
"digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
9+
},
10+
"layers": [
11+
{
12+
"mediaType": "application/vnd.github.actions.package.layer.v1.tar+gzip",
13+
"size": 689381,
14+
"digest": "sha256:6390cea2d46095ef08dd2746d4323b11b7d1190d7e9ad9ef4a23b8ee5481d295",
15+
"annotations": {
16+
"org.opencontainers.image.title": "step-security-wait-for-secrets_1.2.0.tar.gz"
17+
}
18+
},
19+
{
20+
"mediaType": "application/vnd.github.actions.package.layer.v1.zip",
21+
"size": 723541,
22+
"digest": "sha256:56f5004c2b1bff0f148c3998aa0f5bd47a315a602428031b8ba72d881edfb429",
23+
"annotations": {
24+
"org.opencontainers.image.title": "step-security-wait-for-secrets_1.2.0.zip"
25+
}
26+
}
27+
],
28+
"annotations": {
29+
"org.opencontainers.image.created": "2024-10-24T05:13:19.501Z",
30+
"action.tar.gz.digest": "sha256:6390cea2d46095ef08dd2746d4323b11b7d1190d7e9ad9ef4a23b8ee5481d295",
31+
"action.zip.digest": "sha256:56f5004c2b1bff0f148c3998aa0f5bd47a315a602428031b8ba72d881edfb429",
32+
"com.github.package.type": "actions_oci_pkg",
33+
"com.github.package.version": "1.2.0",
34+
"com.github.source.repo.id": "498456330",
35+
"com.github.source.repo.owner.id": "88700172",
36+
"com.github.source.commit": "5809f7d044804a5a1d43217fa8f3e855939fc9ef"
37+
}
38+
}

0 commit comments

Comments
 (0)