@@ -10,9 +10,11 @@ import (
|
10 | 10 | "testing"
|
11 | 11 | "time"
|
12 | 12 |
|
| 13 | +".com/expr-lang/expr/conf" |
13 | 14 | ".com/expr-lang/expr/internal/testify/assert"
|
14 | 15 | ".com/expr-lang/expr/internal/testify/require"
|
15 | 16 | ".com/expr-lang/expr/types"
|
| 17 | +".com/expr-lang/expr/vm" |
16 | 18 |
|
17 | 19 | ".com/expr-lang/expr"
|
18 | 20 | ".com/expr-lang/expr/ast"
|
@@ -2225,26 +2227,6 @@ func TestEval_slices_out_of_bound(t *testing.T) {
|
2225 | 2227 | }
|
2226 | 2228 | }
|
2227 | 2229 |
|
2228 |
| -func TestMemoryBudget(t *testing.T) { |
2229 |
| -tests := []struct { |
2230 |
| -code string |
2231 |
| -}{ |
2232 |
| -{`map(1..100, {map(1..100, {map(1..100, {0})})})`}, |
2233 |
| -{`len(1..10000000)`}, |
2234 |
| -} |
2235 |
| - |
2236 |
| -for _, tt := range tests { |
2237 |
| -t.Run(tt.code, func(t *testing.T) { |
2238 |
| -program, err := expr.Compile(tt.code) |
2239 |
| -require.NoError(t, err, "compile error") |
2240 |
| - |
2241 |
| -_, err = expr.Run(program, nil) |
2242 |
| -assert.Error(t, err, "run error") |
2243 |
| -assert.Contains(t, err.Error(), "memory budget exceeded") |
2244 |
| -}) |
2245 |
| -} |
2246 |
| -} |
2247 |
| - |
2248 | 2230 | func TestExpr_custom_tests(t *testing.T) {
|
2249 | 2231 | f, err := os.Open("custom_tests.json")
|
2250 | 2232 | if os.IsNotExist(err) {
|
@@ -2731,3 +2713,55 @@ func TestIssue785_get_nil(t *testing.T) {
|
2731 | 2713 | })
|
2732 | 2714 | }
|
2733 | 2715 | }
|
| 2716 | + |
| 2717 | +func TestMaxNodes(t *testing.T) { |
| 2718 | +maxNodes := uint(100) |
| 2719 | + |
| 2720 | +code := "" |
| 2721 | +for i := 0; i < int(maxNodes); i++ { |
| 2722 | +code += "1; " |
| 2723 | +} |
| 2724 | + |
| 2725 | +_, err := expr.Compile(code, expr.MaxNodes(maxNodes)) |
| 2726 | +require.Error(t, err) |
| 2727 | +assert.Contains(t, err.Error(), "exceeds maximum allowed nodes") |
| 2728 | + |
| 2729 | +_, err = expr.Compile(code, expr.MaxNodes(maxNodes+1)) |
| 2730 | +require.NoError(t, err) |
| 2731 | +} |
| 2732 | + |
| 2733 | +func TestMaxNodesDisabled(t *testing.T) { |
| 2734 | +code := "" |
| 2735 | +for i := 0; i < 2*int(conf.DefaultMaxNodes); i++ { |
| 2736 | +code += "1; " |
| 2737 | +} |
| 2738 | + |
| 2739 | +_, err := expr.Compile(code, expr.MaxNodes(0)) |
| 2740 | +require.NoError(t, err) |
| 2741 | +} |
| 2742 | + |
| 2743 | +func TestMemoryBudget(t *testing.T) { |
| 2744 | +tests := []struct { |
| 2745 | +code string |
| 2746 | +max int |
| 2747 | +}{ |
| 2748 | +{`map(1..100, {map(1..100, {map(1..100, {0})})})`, -1}, |
| 2749 | +{`len(1..10000000)`, -1}, |
| 2750 | +{`1..100`, 100}, |
| 2751 | +} |
| 2752 | + |
| 2753 | +for _, tt := range tests { |
| 2754 | +t.Run(tt.code, func(t *testing.T) { |
| 2755 | +program, err := expr.Compile(tt.code) |
| 2756 | +require.NoError(t, err, "compile error") |
| 2757 | + |
| 2758 | +vm := vm.VM{} |
| 2759 | +if tt.max > 0 { |
| 2760 | +vm.MemoryBudget = uint(tt.max) |
| 2761 | +} |
| 2762 | +_, err = vm.Run(program, nil) |
| 2763 | +require.Error(t, err, "run error") |
| 2764 | +assert.Contains(t, err.Error(), "memory budget exceeded") |
| 2765 | +}) |
| 2766 | +} |
| 2767 | +} |
0 commit comments