Skip to content

Commit

Permalink
Add API Tests
Browse files Browse the repository at this point in the history
Signed-off-by: Frank Jogeleit <[email protected]>
  • Loading branch information
Frank Jogeleit committed Apr 28, 2024
1 parent deac4a0 commit 48d5c0f
Show file tree
Hide file tree
Showing 7 changed files with 735 additions and 10 deletions.
1 change: 1 addition & 0 deletions pkg/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func (h *APIHandler) Register(engine *gin.RouterGroup) error {
engine.GET("namespaces", h.ListNamespaces)
engine.GET("policy-reports", h.ListPolicyReports)
engine.GET("cluster-policy-reports", h.ListClusterPolicyReports)
engine.GET("rule-status-count", h.RuleStatusCounts)

ns := engine.Group("namespaced-resources")
ns.GET("sources", h.ListNamespacedFilter("source"))
Expand Down
287 changes: 287 additions & 0 deletions pkg/api/v1/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
package v1_test

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"

"github.com/kyverno/policy-reporter/pkg/api"
v1 "github.com/kyverno/policy-reporter/pkg/api/v1"
"github.com/kyverno/policy-reporter/pkg/database"
"github.com/kyverno/policy-reporter/pkg/fixtures"
"github.com/kyverno/policy-reporter/pkg/report"
"github.com/kyverno/policy-reporter/pkg/target"
"github.com/kyverno/policy-reporter/pkg/target/webhook"
)

func TestV1(t *testing.T) {
db, err := database.NewSQLiteDB("db_v2.db")
if err != nil {
assert.Fail(t, "failed to init SQLite DB")
}

store, err := database.NewStore(db, "1.0")
if err != nil {
assert.Fail(t, "failed to init Store")
}

if err := store.PrepareDatabase(context.Background()); err != nil {
assert.Fail(t, "failed to prepare Store")
}

store.Add(context.Background(), fixtures.DefaultPolicyReport)
store.Add(context.Background(), fixtures.KyvernoPolicyReport)
store.Add(context.Background(), fixtures.KyvernoClusterPolicyReport)

gin.SetMode(gin.ReleaseMode)

server := api.NewServer(gin.New(), v1.WithAPI(store, []target.Client{
webhook.NewClient(webhook.Options{
ClientOptions: target.ClientOptions{
Name: "Webhook",
SkipExistingOnStartup: true,
ResultFilter: &report.ResultFilter{
MinimumPriority: "",
Sources: []string{"Kyverno"},
},
},
Host: "http://localhost:8080",
}),
}))

t.Run("TargetResponse", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/targets", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]v1.Target, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 1, len(resp))
assert.Contains(t, resp, v1.Target{
Name: "Webhook",
MinimumPriority: "debug",
Sources: []string{"Kyverno"},
SkipExistingOnStartup: true,
})
}
})

t.Run("ListPolicyReports", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/policy-reports", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := api.Paginated[v1.PolicyReport]{}

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 2, resp.Count)
}
})

t.Run("ListClusterPolicyReports", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/cluster-policy-reports", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := api.Paginated[v1.PolicyReport]{}

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 1, resp.Count)
}
})

t.Run("ListNamespaces", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/namespaces", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]string, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 2, len(resp))
}
})

t.Run("RuleStatusCounts", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/rule-status-count?policy=required-limit&rule=resource-limit-required", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]v1.StatusCount, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 5, len(resp))
assert.Contains(t, resp, v1.StatusCount{Status: "pass", Count: 1})
assert.Contains(t, resp, v1.StatusCount{Status: "warn", Count: 1})
}
})

t.Run("ListClusterFilter(Source)", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/cluster-resources/sources", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]string, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 1, len(resp))
assert.Contains(t, resp, "Kyverno")
}
})

t.Run("ListNamespacedFilter(Source)", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/namespaced-resources/sources", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]string, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 2, len(resp))
assert.Contains(t, resp, "Kyverno")
}
})

t.Run("ListClusterResources", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/cluster-resources/resources", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]v1.Resource, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 1, len(resp))
}
})

t.Run("ListNamespacedResources", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/namespaced-resources/resources", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]v1.Resource, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 4, len(resp))
}
})

t.Run("ListClusterStatusCounts", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/cluster-resources/status-counts", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]v1.StatusCount, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 5, len(resp))
}
})

t.Run("ListNamespacedStatusCounts", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/namespaced-resources/status-counts", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := make([]v1.NamespaceCount, 0)

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 5, len(resp))
}
})

t.Run("ListClusterResults", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/cluster-resources/results", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := api.Paginated[v1.Result]{}

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 1, resp.Count)
}
})

t.Run("ListNamespacedResults", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/namespaced-resources/results", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

assert.Equal(t, http.StatusOK, w.Code)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := api.Paginated[v1.Result]{}

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 5, resp.Count)
}
})
}
43 changes: 43 additions & 0 deletions pkg/api/v1/model_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package v1_test

import (
"testing"

v1 "github.com/kyverno/policy-reporter/pkg/api/v1"
"github.com/kyverno/policy-reporter/pkg/database"
"github.com/stretchr/testify/assert"
)

func TestMapping(t *testing.T) {
t.Run("MapClusterStatusCounts", func(t *testing.T) {
result := v1.MapClusterStatusCounts([]database.StatusCount{
{Source: "kyverno", Status: "pass", Count: 3},
{Source: "kyverno", Status: "fail", Count: 4},
}, []string{"pass", "fail"})

assert.Equal(t, 2, len(result))
assert.Contains(t, result, v1.StatusCount{Status: "pass", Count: 3})
assert.Contains(t, result, v1.StatusCount{Status: "fail", Count: 4})
})

t.Run("MapNamespaceStatusCounts", func(t *testing.T) {
result := v1.MapNamespaceStatusCounts([]database.StatusCount{
{Source: "kyverno", Status: "pass", Count: 3, Namespace: "default"},
{Source: "kyverno", Status: "fail", Count: 4, Namespace: "default"},
{Source: "kyverno", Status: "pass", Count: 2, Namespace: "user"},
{Source: "kyverno", Status: "fail", Count: 2, Namespace: "user"},
}, []string{"pass", "fail"})

assert.Equal(t, 2, len(result))

assert.Contains(t, result, v1.NamespaceStatusCount{Status: "pass", Items: []v1.NamespaceCount{
{Namespace: "default", Count: 3, Status: "pass"},
{Namespace: "user", Count: 2, Status: "pass"},
}})

assert.Contains(t, result, v1.NamespaceStatusCount{Status: "fail", Items: []v1.NamespaceCount{
{Namespace: "default", Count: 4, Status: "fail"},
{Namespace: "user", Count: 2, Status: "fail"},
}})
})
}
35 changes: 35 additions & 0 deletions pkg/api/v2/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,4 +440,39 @@ func TestV2(t *testing.T) {
assert.True(t, resp["resources"])
}
})

t.Run("ListFindings", func(t *testing.T) {
req, _ := http.NewRequest("GET", "/v2/findings", nil)
w := httptest.NewRecorder()

server.Serve(w, req)

if ok := assert.Equal(t, http.StatusOK, w.Code); ok {
resp := v2.Findings{}

json.NewDecoder(w.Body).Decode(&resp)

assert.Equal(t, 6, resp.Total)
assert.Equal(t, 4, resp.PerResult["fail"])
assert.Equal(t, 1, resp.PerResult["pass"])
assert.Equal(t, 1, resp.PerResult["warn"])
assert.Equal(t, 2, len(resp.Counts))
assert.Contains(t, resp.Counts, &v2.FindingCounts{
Total: 3,
Source: "Kyverno",
Counts: map[string]int{
"fail": 1,
"pass": 1,
"warn": 1,
},
})
assert.Contains(t, resp.Counts, &v2.FindingCounts{
Total: 3,
Source: "test",
Counts: map[string]int{
"fail": 3,
},
})
}
})
}
Loading

0 comments on commit 48d5c0f

Please sign in to comment.