snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
160
internal/e2e/full_suit_test.go
Normal file
160
internal/e2e/full_suit_test.go
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ory/herodot"
|
||||
"github.com/ory/x/cmdx"
|
||||
prometheus "github.com/ory/x/prometheusx"
|
||||
|
||||
"github.com/ory/keto/cmd"
|
||||
cliclient "github.com/ory/keto/cmd/client"
|
||||
"github.com/ory/keto/internal/relationtuple"
|
||||
"github.com/ory/keto/internal/x/dbx"
|
||||
"github.com/ory/keto/ketoapi"
|
||||
)
|
||||
|
||||
type (
|
||||
transactClient interface {
|
||||
client
|
||||
transactTuples(t testing.TB, ins []*ketoapi.RelationTuple, del []*ketoapi.RelationTuple)
|
||||
}
|
||||
client interface {
|
||||
createTuple(t testing.TB, r *ketoapi.RelationTuple)
|
||||
deleteTuple(t testing.TB, r *ketoapi.RelationTuple)
|
||||
deleteAllTuples(t testing.TB, q *ketoapi.RelationQuery)
|
||||
queryTuple(t testing.TB, q *ketoapi.RelationQuery, opts ...paginationOptionSetter) *ketoapi.GetResponse
|
||||
queryTupleErr(t testing.TB, expected *herodot.DefaultError, q *ketoapi.RelationQuery, opts ...paginationOptionSetter)
|
||||
check(t testing.TB, r *ketoapi.RelationTuple) bool
|
||||
batchCheck(t testing.TB, r []*ketoapi.RelationTuple) []checkResponse
|
||||
batchCheckErr(t testing.TB, requestTuples []*ketoapi.RelationTuple, expected *herodot.DefaultError)
|
||||
expand(t testing.TB, r *ketoapi.SubjectSet, depth int) *ketoapi.Tree[*ketoapi.RelationTuple]
|
||||
oplCheckSyntax(t testing.TB, content []byte) []*ketoapi.ParseError
|
||||
waitUntilLive(t testing.TB)
|
||||
queryNamespaces(t testing.TB) ketoapi.GetNamespacesResponse
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
promLogLine = "promhttp_metric_handler_requests_total"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, dsn := range dbx.GetDSNs(t) {
|
||||
t.Run(fmt.Sprintf("dsn=%s", dsn.Name), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, reg, namespaceTestMgr, getAddr := newInitializedReg(t, dsn, nil)
|
||||
|
||||
closeServer := startServer(ctx, t, reg)
|
||||
t.Cleanup(closeServer)
|
||||
|
||||
_, _, readAddr := getAddr(t, "read")
|
||||
_, _, writeAddr := getAddr(t, "write")
|
||||
_, _, oplAddr := getAddr(t, "opl")
|
||||
_, _, metricsAddr := getAddr(t, "metrics")
|
||||
|
||||
// The test cases start here
|
||||
// We execute every test with all clients available
|
||||
for _, cl := range []client{
|
||||
newGrpcClient(t, ctx,
|
||||
readAddr,
|
||||
writeAddr,
|
||||
oplAddr,
|
||||
),
|
||||
&restClient{
|
||||
readURL: "http://" + readAddr,
|
||||
writeURL: "http://" + writeAddr,
|
||||
oplSyntaxURL: "http://" + oplAddr,
|
||||
},
|
||||
&cliClient{c: &cmdx.CommandExecuter{
|
||||
New: func() *cobra.Command {
|
||||
return cmd.NewRootCmd(nil)
|
||||
},
|
||||
Ctx: ctx,
|
||||
PersistentArgs: []string{
|
||||
"--" + cliclient.FlagReadRemote, readAddr,
|
||||
"--" + cliclient.FlagWriteRemote, writeAddr,
|
||||
"--insecure-disable-transport-security=true",
|
||||
"--" + cmdx.FlagFormat, string(cmdx.FormatJSON),
|
||||
},
|
||||
}},
|
||||
&sdkClient{
|
||||
readRemote: readAddr,
|
||||
writeRemote: writeAddr,
|
||||
syntaxRemote: oplAddr,
|
||||
},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("client=%T", cl), runCases(cl, namespaceTestMgr))
|
||||
|
||||
if tc, ok := cl.(transactClient); ok {
|
||||
t.Run(fmt.Sprintf("transactClient=%T", cl), runTransactionCases(tc, namespaceTestMgr))
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("case=metrics are served", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
newGrpcClient(t, ctx,
|
||||
readAddr,
|
||||
writeAddr,
|
||||
oplAddr,
|
||||
).waitUntilLive(t)
|
||||
|
||||
t.Run("case=on "+prometheus.MetricsPrometheusPath, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp, err := http.Get(fmt.Sprintf("http://%s%s", metricsAddr, prometheus.MetricsPrometheusPath))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, resp.StatusCode, http.StatusOK)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, string(body), promLogLine)
|
||||
})
|
||||
|
||||
t.Run("case=not on /", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp, err := http.Get(fmt.Sprintf("http://%s", metricsAddr))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, resp.StatusCode, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeCORS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, reg, _, getAddr := newInitializedReg(t, dbx.GetSqlite(t), map[string]any{
|
||||
"serve.read.cors.enabled": true,
|
||||
"serve.read.cors.debug": true,
|
||||
"serve.read.cors.allowed_methods": []string{http.MethodGet},
|
||||
"serve.read.cors.allowed_origins": []string{"https://ory.sh"},
|
||||
})
|
||||
|
||||
closeServer := startServer(ctx, t, reg)
|
||||
t.Cleanup(closeServer)
|
||||
|
||||
_, _, readAddr := getAddr(t, "read")
|
||||
waitUntilLive(t, "http://"+readAddr)
|
||||
t.Log("Health check is ready")
|
||||
|
||||
req, err := http.NewRequest(http.MethodOptions, "http://"+readAddr+relationtuple.ReadRouteBase, nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Origin", "https://ory.sh")
|
||||
req.Header.Set("Access-Control-Request-Method", "GET")
|
||||
resp, err := http.DefaultClient.Do(req) //nolint:gosec // Test code with controlled URL.
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusNoContent, resp.StatusCode)
|
||||
assert.Equalf(t, "https://ory.sh", resp.Header.Get("Access-Control-Allow-Origin"), "%+v", resp.Header)
|
||||
}
|
||||
Reference in New Issue
Block a user