1 package binary
2
3 import (
4 "bytes"
5 "fmt"
6 "testing"
7
8 "github.com/tetratelabs/wazero/internal/testing/binaryencoding"
9 "github.com/tetratelabs/wazero/internal/testing/require"
10 "github.com/tetratelabs/wazero/internal/wasm"
11 )
12
13 func Test_newMemorySizer(t *testing.T) {
14 zero := uint32(0)
15 ten := uint32(10)
16 defaultLimit := wasm.MemoryLimitPages
17
18 tests := []struct {
19 name string
20 memoryCapacityFromMax bool
21 limit uint32
22 min uint32
23 max *uint32
24 expectedMin, expectedCapacity, expectedMax uint32
25 }{
26 {
27 name: "min 0",
28 limit: defaultLimit,
29 min: zero,
30 max: &defaultLimit,
31 expectedMin: zero,
32 expectedCapacity: zero,
33 expectedMax: defaultLimit,
34 },
35 {
36 name: "min 0 defaults max to defaultLimit",
37 limit: defaultLimit,
38 min: zero,
39 expectedMin: zero,
40 expectedCapacity: zero,
41 expectedMax: defaultLimit,
42 },
43 {
44 name: "min 0, max 0",
45 limit: defaultLimit,
46 min: zero,
47 max: &zero,
48 expectedMin: zero,
49 expectedCapacity: zero,
50 expectedMax: zero,
51 },
52 {
53 name: "min 0, max 10",
54 limit: defaultLimit,
55 min: zero,
56 max: &ten,
57 expectedMin: zero,
58 expectedCapacity: zero,
59 expectedMax: ten,
60 },
61 {
62 name: "min 0, max 10 memoryCapacityFromMax",
63 limit: defaultLimit,
64 memoryCapacityFromMax: true,
65 min: zero,
66 max: &ten,
67 expectedMin: zero,
68 expectedCapacity: ten,
69 expectedMax: ten,
70 },
71 {
72 name: "min 10, no max",
73 limit: 200,
74 min: 10,
75 expectedMin: 10,
76 expectedCapacity: 10,
77 expectedMax: 200,
78 },
79 {
80 name: "min 10, no max memoryCapacityFromMax",
81 memoryCapacityFromMax: true,
82 limit: 200,
83 min: 10,
84 expectedMin: 10,
85 expectedCapacity: 200,
86 expectedMax: 200,
87 },
88 {
89 name: "min=max",
90 limit: defaultLimit,
91 min: ten,
92 max: &ten,
93 expectedMin: ten,
94 expectedCapacity: ten,
95 expectedMax: ten,
96 },
97 {
98 name: "max > memoryLimitPages",
99 limit: 5,
100 min: 0,
101 max: &ten,
102 expectedMin: 0,
103 expectedCapacity: 0,
104 expectedMax: 5,
105 },
106 }
107
108 for _, tt := range tests {
109 tc := tt
110 t.Run(tc.name, func(t *testing.T) {
111 sizer := newMemorySizer(tc.limit, tc.memoryCapacityFromMax)
112 min, capacity, max := sizer(tc.min, tc.max)
113 require.Equal(t, tc.expectedMin, min)
114 require.Equal(t, tc.expectedCapacity, capacity)
115 require.Equal(t, tc.expectedMax, max)
116 })
117 }
118 }
119
120 func TestMemoryType(t *testing.T) {
121 zero := uint32(0)
122 max := wasm.MemoryLimitPages
123
124 tests := []struct {
125 name string
126 input *wasm.Memory
127 memoryLimitPages uint32
128 expected []byte
129 }{
130 {
131 name: "min 0",
132 input: &wasm.Memory{Max: max, IsMaxEncoded: true},
133 expected: []byte{0x1, 0, 0x80, 0x80, 0x4},
134 },
135 {
136 name: "min 0 default max",
137 input: &wasm.Memory{Max: max},
138 expected: []byte{0x0, 0},
139 },
140 {
141 name: "min 0, max 0",
142 input: &wasm.Memory{Max: zero, IsMaxEncoded: true},
143 expected: []byte{0x1, 0, 0},
144 },
145 {
146 name: "min=max",
147 input: &wasm.Memory{Min: 1, Cap: 1, Max: 1, IsMaxEncoded: true},
148 expected: []byte{0x1, 1, 1},
149 },
150 {
151 name: "min 0, max largest",
152 input: &wasm.Memory{Max: max, IsMaxEncoded: true},
153 expected: []byte{0x1, 0, 0x80, 0x80, 0x4},
154 },
155 {
156 name: "min largest max largest",
157 input: &wasm.Memory{Min: max, Cap: max, Max: max, IsMaxEncoded: true},
158 expected: []byte{0x1, 0x80, 0x80, 0x4, 0x80, 0x80, 0x4},
159 },
160 {
161 name: "min 0, max largest, wazero limit",
162 input: &wasm.Memory{Max: max, IsMaxEncoded: true},
163 memoryLimitPages: 512,
164 expected: []byte{0x1, 0, 0x80, 0x80, 0x4},
165 },
166 }
167
168 for _, tt := range tests {
169 tc := tt
170
171 b := binaryencoding.EncodeMemory(tc.input)
172 t.Run(fmt.Sprintf("encode %s", tc.name), func(t *testing.T) {
173 require.Equal(t, tc.expected, b)
174 })
175
176 t.Run(fmt.Sprintf("decode %s", tc.name), func(t *testing.T) {
177 tmax := max
178 expectedDecoded := tc.input
179 if tc.memoryLimitPages != 0 {
180
181 tmax = tc.memoryLimitPages
182 expectedDecoded.Max = tmax
183 }
184
185 binary, err := decodeMemory(bytes.NewReader(b), newMemorySizer(tmax, false), tmax)
186 require.NoError(t, err)
187 require.Equal(t, binary, expectedDecoded)
188 })
189 }
190 }
191
192 func TestDecodeMemoryType_Errors(t *testing.T) {
193 max := wasm.MemoryLimitPages
194
195 tests := []struct {
196 name string
197 input []byte
198 expectedErr string
199 }{
200 {
201 name: "max < min",
202 input: []byte{0x1, 0x80, 0x80, 0x4, 0},
203 expectedErr: "min 65536 pages (4 Gi) > max 0 pages (0 Ki)",
204 },
205 {
206 name: "min > limit",
207 input: []byte{0x0, 0xff, 0xff, 0xff, 0xff, 0xf},
208 expectedErr: "min 4294967295 pages (3 Ti) over limit of 65536 pages (4 Gi)",
209 },
210 {
211 name: "max > limit",
212 input: []byte{0x1, 0, 0xff, 0xff, 0xff, 0xff, 0xf},
213 expectedErr: "max 4294967295 pages (3 Ti) over limit of 65536 pages (4 Gi)",
214 },
215 }
216
217 for _, tt := range tests {
218 tc := tt
219
220 t.Run(tc.name, func(t *testing.T) {
221 _, err := decodeMemory(bytes.NewReader(tc.input), newMemorySizer(max, false), max)
222 require.EqualError(t, err, tc.expectedErr)
223 })
224 }
225 }
226
View as plain text