mosn

Форк
0
/
proxywasm_test.go 
255 строк · 6.4 Кб
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17

18
package wasm_test
19

20
import (
21
	"errors"
22
	"fmt"
23
	"net"
24
	"net/http"
25
	"net/http/httptest"
26
	"os"
27
	"path/filepath"
28
	"testing"
29
	"time"
30

31
	"github.com/tetratelabs/wabin/binary"
32
	"github.com/tetratelabs/wabin/wasm"
33

34
	config "mosn.io/mosn/pkg/config/v2"
35
	_ "mosn.io/mosn/pkg/filter/network/proxy"
36
	_ "mosn.io/mosn/pkg/filter/stream/proxywasm"
37
	_ "mosn.io/mosn/pkg/stream/http"
38
	_ "mosn.io/mosn/pkg/stream/http2"
39
	_ "mosn.io/mosn/pkg/wasm/abi/proxywasm020"
40
	"mosn.io/mosn/test/util/mosn"
41
	"mosn.io/pkg/log"
42
)
43

44
func init() {
45
	log.DefaultLogger.SetLogLevel(log.ERROR)
46
}
47

48
type testMosn struct {
49
	url     string
50
	logPath string
51
	*mosn.MosnWrapper
52
}
53

54
const pathResponseHeaderV1 = "testdata/req-header-v1/main.wasm"
55

56
func test_ProxyWasmV1(t *testing.T, engine string) {
57
	// Ensure the module was compiled with the correct ABI as this is hard to verify at runtime.
58
	requireModuleExport(t, pathResponseHeaderV1, "proxy_abi_version_0_1_0")
59

60
	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
61
		if r.Header.Get("Wasm-Context") == "" {
62
			t.Fatalf("expected to see request header from wasm: %v", r.Header)
63
		}
64
	}))
65
	defer backend.Close()
66
	logPath := filepath.Join(t.TempDir(), "mosn.log")
67

68
	mosn, err := startMosn(backend.Listener.Addr().String(), engine, pathResponseHeaderV1, logPath)
69
	if err != nil {
70
		t.Fatal(err)
71
	}
72
	defer mosn.Close()
73

74
	resp, err := http.Get(mosn.url)
75
	if err != nil {
76
		t.Fatal(err)
77
	}
78
	defer resp.Body.Close()
79
}
80

81
func Benchmark_BaseCase(b *testing.B) {
82
	benchmark(b, "", "")
83
}
84

85
func benchmark_ProxyWasmV1(b *testing.B, engine string) {
86
	benchmark(b, engine, pathResponseHeaderV1)
87
}
88

89
func benchmark(b *testing.B, engine, wasmPath string) {
90
	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
91
	defer backend.Close()
92
	logPath := filepath.Join(b.TempDir(), "mosn.log")
93

94
	mosn, err := startMosn(backend.Listener.Addr().String(), engine, wasmPath, logPath)
95
	if err != nil {
96
		b.Fatal(err)
97
	}
98
	defer mosn.Close()
99

100
	b.ResetTimer()
101
	for i := 0; i < b.N; i++ {
102
		resp, err := http.Get(mosn.url)
103
		if err != nil {
104
			b.Fatal(err)
105
		}
106
		resp.Body.Close()
107
	}
108
}
109

110
func startMosn(backendAddr string, engine, wasmPath, logPath string) (testMosn, error) {
111
	port := freePort()
112
	adminPort := freePort()
113
	c := &config.MOSNConfig{
114
		Servers: []config.ServerConfig{
115
			{
116
				DefaultLogPath:  logPath,
117
				DefaultLogLevel: "ERROR",
118
				Routers: []*config.RouterConfiguration{
119
					{
120
						RouterConfigurationConfig: config.RouterConfigurationConfig{
121
							RouterConfigName: "server_router",
122
						},
123
						VirtualHosts: []config.VirtualHost{
124
							{
125
								Name:    "serverHost",
126
								Domains: []string{"*"},
127
								Routers: []config.Router{
128
									{
129
										RouterConfig: config.RouterConfig{
130
											Match: config.RouterMatch{
131
												Prefix: "/",
132
											},
133
											Route: config.RouteAction{
134
												RouterActionConfig: config.RouterActionConfig{
135
													ClusterName: "serverCluster",
136
												},
137
											},
138
										},
139
									},
140
								},
141
							},
142
						},
143
					},
144
				},
145
				Listeners: []config.Listener{
146
					{
147
						ListenerConfig: config.ListenerConfig{
148
							Name:       "serverListener",
149
							AddrConfig: fmt.Sprintf("127.0.0.1:%d", port),
150
							BindToPort: true,
151
							FilterChains: []config.FilterChain{
152
								{
153
									FilterChainConfig: config.FilterChainConfig{
154
										Filters: []config.Filter{
155
											{
156
												Type: "proxy",
157
												Config: map[string]interface{}{
158
													"downstream_protocol": "Http1",
159
													"upstream_protocol":   "Http1",
160
													"router_config_name":  "server_router",
161
												},
162
											},
163
										},
164
									},
165
								},
166
							},
167
						},
168
					},
169
				},
170
			},
171
		},
172
		ClusterManager: config.ClusterManagerConfig{
173
			Clusters: []config.Cluster{
174
				{
175
					Name:                 "serverCluster",
176
					ClusterType:          "SIMPLE",
177
					LbType:               "LB_RANDOM",
178
					MaxRequestPerConn:    1024,
179
					ConnBufferLimitBytes: 32768,
180
					Hosts: []config.Host{
181
						{
182
							HostConfig: config.HostConfig{
183
								Address: backendAddr,
184
							},
185
						},
186
					},
187
				},
188
			},
189
		},
190
		RawAdmin: &config.Admin{
191
			Address: &config.AddressInfo{
192
				SocketAddress: config.SocketAddress{
193
					Address:   "127.0.0.1",
194
					PortValue: uint32(adminPort),
195
				},
196
			},
197
		},
198
		DisableUpgrade: true,
199
	}
200
	if wasmPath != "" {
201
		c.Servers[0].Listeners[0].ListenerConfig.StreamFilters = []config.Filter{
202
			{
203
				Type: "proxywasm",
204
				Config: map[string]interface{}{
205
					"instance_num": 1,
206
					"vm_config": map[string]interface{}{
207
						"engine": engine,
208
						"path":   wasmPath,
209
					},
210
				},
211
			},
212
		}
213
	}
214
	app := mosn.NewMosn(c)
215
	app.Start()
216
	for i := 0; i < 100; i++ {
217
		time.Sleep(200 * time.Millisecond)
218
		resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d", adminPort))
219
		if err != nil {
220
			continue
221
		}
222
		defer resp.Body.Close()
223
		if resp.StatusCode == http.StatusOK {
224
			time.Sleep(1 * time.Second)
225
			return testMosn{
226
				url:         fmt.Sprintf("http://127.0.0.1:%d", port),
227
				logPath:     logPath,
228
				MosnWrapper: app,
229
			}, nil
230
		}
231
	}
232
	return testMosn{}, errors.New("mosn start failed")
233
}
234

235
func freePort() int {
236
	l, _ := net.Listen("tcp", ":0")
237
	defer l.Close()
238
	return l.Addr().(*net.TCPAddr).Port
239
}
240

241
func requireModuleExport(t *testing.T, wasmPath, want string) {
242
	bin, err := os.ReadFile(wasmPath)
243
	if err != nil {
244
		t.Fatal(err)
245
	}
246
	mod, err := binary.DecodeModule(bin, wasm.CoreFeaturesV2)
247
	var exports []string
248
	for _, e := range mod.ExportSection {
249
		if e.Name == want {
250
			return
251
		}
252
		exports = append(exports, e.Name)
253
	}
254
	t.Errorf("export not found, want: %v, have: %v", want, exports)
255
}
256

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.