|
8 | 8 | "context"
|
9 | 9 | "fmt"
|
10 | 10 | "os"
|
| 11 | + "strings" |
11 | 12 | "testing"
|
| 13 | + "time" |
12 | 14 |
|
13 | 15 | "github.com/open-policy-agent/opa/v1/ast"
|
14 | 16 | "github.com/open-policy-agent/opa/v1/topdown/cache"
|
@@ -889,3 +891,74 @@ func TestGraphQLParseSchema(t *testing.T) {
|
889 | 891 | })
|
890 | 892 | }
|
891 | 893 | }
|
| 894 | + |
| 895 | +func TestGraphQLParseSchemaDuration(t *testing.T) { |
| 896 | + |
| 897 | + maxDuration, _ := time.ParseDuration("10s") |
| 898 | + t.Parallel() |
| 899 | + |
| 900 | + cases := []struct { |
| 901 | + note string |
| 902 | + schema *ast.Term |
| 903 | + duration time.Duration |
| 904 | + }{ |
| 905 | + { |
| 906 | + note: "default schema", |
| 907 | + schema: ast.NewTerm(ast.String(employeeGQLSchema)), |
| 908 | + duration: maxDuration, |
| 909 | + }, |
| 910 | + { |
| 911 | + note: "default schema plus 100 additional types", |
| 912 | + schema: ast.NewTerm(ast.String(bigSchema(100))), |
| 913 | + duration: maxDuration, |
| 914 | + }, |
| 915 | + { |
| 916 | + note: "default schema plus 1,000 additional types", |
| 917 | + schema: ast.NewTerm(ast.String(bigSchema(1000))), |
| 918 | + duration: maxDuration, |
| 919 | + }, |
| 920 | + // Uncomment when https://github.com/open-policy-agent/opa/pull/7509 is merged |
| 921 | + //{ |
| 922 | + // note: "default schema plus 10,000 additional types", |
| 923 | + // schema: ast.NewTerm(ast.String(bigSchema(10000))), |
| 924 | + // duration: maxDuration, |
| 925 | + //}, |
| 926 | + } |
| 927 | + |
| 928 | + for _, tc := range cases { |
| 929 | + |
| 930 | + t.Run(tc.note, func(t *testing.T) { |
| 931 | + t.Parallel() |
| 932 | + start := time.Now() |
| 933 | + _ = builtinGraphQLParseSchema( |
| 934 | + BuiltinContext{ |
| 935 | + InterQueryBuiltinValueCache: nil, |
| 936 | + }, |
| 937 | + []*ast.Term{tc.schema}, |
| 938 | + func(term *ast.Term) error { |
| 939 | + return nil |
| 940 | + }, |
| 941 | + ) |
| 942 | + finish := time.Now() |
| 943 | + elapsedTime := finish.Sub(start) |
| 944 | + if tc.duration < elapsedTime { |
| 945 | + t.Errorf("Parsing schema '%s' cannot exceed %s, but took %s", tc.note, tc.duration, elapsedTime) |
| 946 | + return |
| 947 | + } |
| 948 | + }) |
| 949 | + } |
| 950 | +} |
| 951 | + |
| 952 | +// Inflate GraphQL schema size with `count` extra types |
| 953 | +func bigSchema(count int) string { |
| 954 | + |
| 955 | + // build up `count` more types on basic schema |
| 956 | + var builder strings.Builder |
| 957 | + builder.WriteString(employeeGQLSchema) |
| 958 | + |
| 959 | + for range count { |
| 960 | + fmt.Fprintf(&builder, "\ntype Employee%d {\n id: String!\n salary: Int!\n}\n", count) |
| 961 | + } |
| 962 | + |
| 963 | + return builder.String() |
| 964 | +} |
0 commit comments