github.com/tetratelabs/proxy-wasm-go-sdk@v0.23.1-0.20240517021853-021aa9cf78e8/proxywasm/proxytest/http_test.go (about) 1 package proxytest 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 9 "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm" 10 "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/internal" 11 "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types" 12 ) 13 14 type testPlugin struct { 15 types.DefaultVMContext 16 buffered bool 17 } 18 19 type testPluginContext struct { 20 types.DefaultPluginContext 21 buffered bool 22 } 23 24 type testHttpContext struct { 25 types.DefaultHttpContext 26 buffered bool 27 } 28 29 // NewPluginContext implements the same method on types.VMContext. 30 func (p *testPlugin) NewPluginContext(uint32) types.PluginContext { 31 return &testPluginContext{buffered: p.buffered} 32 } 33 34 // NewPluginContext implements the same method on types.PluginContext. 35 func (p *testPluginContext) NewHttpContext(uint32) types.HttpContext { 36 return &testHttpContext{buffered: p.buffered} 37 } 38 39 // OnHttpRequestBody implements the same method on types.HttpContext. 40 func (h *testHttpContext) OnHttpRequestBody(bodySize int, endOfStream bool) types.Action { 41 if !endOfStream { 42 if h.buffered { 43 return types.ActionPause 44 } else { 45 return types.ActionContinue 46 } 47 } 48 49 body, err := proxywasm.GetHttpRequestBody(0, bodySize) 50 if err != nil { 51 panic(err) 52 } 53 proxywasm.LogInfo(fmt.Sprintf("request body:%s", string(body))) 54 55 return types.ActionContinue 56 } 57 58 // OnHttpResponseBody implements the same method on types.HttpContext. 59 func (h *testHttpContext) OnHttpResponseBody(bodySize int, endOfStream bool) types.Action { 60 if !endOfStream { 61 if h.buffered { 62 return types.ActionPause 63 } else { 64 return types.ActionContinue 65 } 66 } 67 68 body, err := proxywasm.GetHttpResponseBody(0, bodySize) 69 if err != nil { 70 panic(err) 71 } 72 proxywasm.LogInfo(fmt.Sprintf("response body:%s", string(body))) 73 74 return types.ActionContinue 75 } 76 77 func TestBodyBuffering(t *testing.T) { 78 tests := []struct { 79 name string 80 buffered bool 81 action types.Action 82 logged string 83 }{ 84 { 85 name: "buffered", 86 buffered: true, 87 action: types.ActionPause, 88 // The first chunk has been buffered, therefore it will be retrieved when calling GetHttpRequestBody at the end of stream. 89 logged: "1111122222", 90 }, 91 { 92 name: "unbuffered", 93 buffered: false, 94 action: types.ActionContinue, 95 // The first chunk has not been buffered, therefore it will not be retrieved when calling GetHttpRequestBody at the end of stream. 96 logged: "22222", 97 }, 98 } 99 100 for _, tc := range tests { 101 tt := tc 102 t.Run(tt.name, func(t *testing.T) { 103 host, reset := NewHostEmulator(NewEmulatorOption().WithVMContext(&testPlugin{buffered: tt.buffered})) 104 defer reset() 105 106 id := host.InitializeHttpContext() 107 108 action := host.CallOnRequestBody(id, []byte("11111"), false) 109 require.Equal(t, tt.action, action) 110 111 action = host.CallOnRequestBody(id, []byte("22222"), true) 112 require.Equal(t, types.ActionContinue, action) 113 114 action = host.CallOnResponseBody(id, []byte("11111"), false) 115 require.Equal(t, tt.action, action) 116 117 action = host.CallOnResponseBody(id, []byte("22222"), true) 118 require.Equal(t, types.ActionContinue, action) 119 120 logs := host.GetInfoLogs() 121 require.Contains(t, logs, fmt.Sprintf("request body:%s", tt.logged)) 122 require.Contains(t, logs, fmt.Sprintf("response body:%s", tt.logged)) 123 }) 124 } 125 } 126 127 func TestProperties(t *testing.T) { 128 t.Run("Set and get properties", func(t *testing.T) { 129 host, reset := NewHostEmulator(NewEmulatorOption().WithVMContext(&testPlugin{})) 130 defer reset() 131 132 _ = host.InitializeHttpContext() 133 134 propertyPath := []string{ 135 "route_metadata", 136 "filter_metadata", 137 "envoy.filters.http.wasm", 138 "hello", 139 } 140 propertyData := []byte("world") 141 142 err := host.SetProperty(propertyPath, propertyData) 143 require.Equal(t, err, nil) 144 145 data, err := host.GetProperty(propertyPath) 146 require.Equal(t, err, nil) 147 require.Equal(t, data, propertyData) 148 149 _, err = host.GetProperty([]string{"non-existent path"}) 150 require.Equal(t, err, internal.StatusToError(internal.StatusNotFound)) 151 }) 152 }