wa-lang.org/wazero@v1.0.2/imports/proxywasm/internal/_abi_callback_l7_test.go (about)

     1  // Copyright 2021 Tetrate
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package internal
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
    23  )
    24  
    25  type l7Context struct {
    26  	types.DefaultHttpContext
    27  	onHttpRequestHeaders,
    28  	onHttpRequestBody,
    29  	onHttpRequestTrailers,
    30  	onHttpResponseHeaders,
    31  	onHttpResponseBody,
    32  	onHttpResponseTrailers,
    33  	onHttpCallResponse bool
    34  }
    35  
    36  func (ctx *l7Context) OnHttpRequestHeaders(int, bool) types.Action {
    37  	ctx.onHttpRequestHeaders = true
    38  	return types.ActionContinue
    39  }
    40  
    41  func (ctx *l7Context) OnHttpRequestBody(int, bool) types.Action {
    42  	ctx.onHttpRequestBody = true
    43  	return types.ActionContinue
    44  }
    45  
    46  func (ctx *l7Context) OnHttpRequestTrailers(int) types.Action {
    47  	ctx.onHttpRequestTrailers = true
    48  	return types.ActionContinue
    49  }
    50  
    51  func (ctx *l7Context) OnHttpResponseHeaders(int, bool) types.Action {
    52  	ctx.onHttpResponseHeaders = true
    53  	return types.ActionContinue
    54  }
    55  
    56  func (ctx *l7Context) OnHttpResponseBody(int, bool) types.Action {
    57  	ctx.onHttpResponseBody = true
    58  	return types.ActionContinue
    59  }
    60  
    61  func (ctx *l7Context) OnHttpResponseTrailers(int) types.Action {
    62  	ctx.onHttpResponseTrailers = true
    63  	return types.ActionContinue
    64  }
    65  
    66  func (ctx *l7Context) OnHttpCallResponse(int, int, int) {
    67  	ctx.onHttpCallResponse = true
    68  }
    69  
    70  func Test_l7(t *testing.T) {
    71  	var cID uint32 = 100
    72  	currentStateMux.Lock()
    73  	defer currentStateMux.Unlock()
    74  
    75  	currentState = &state{httpContexts: map[uint32]types.HttpContext{cID: &l7Context{}}}
    76  	ctx, ok := currentState.httpContexts[cID].(*l7Context)
    77  	require.True(t, ok)
    78  
    79  	proxyOnRequestHeaders(cID, 0, false)
    80  	require.True(t, ctx.onHttpRequestHeaders)
    81  	proxyOnRequestBody(cID, 0, false)
    82  	require.True(t, ctx.onHttpRequestBody)
    83  	proxyOnRequestTrailers(cID, 0)
    84  	require.True(t, ctx.onHttpRequestTrailers)
    85  	proxyOnResponseHeaders(cID, 0, false)
    86  	require.True(t, ctx.onHttpResponseHeaders)
    87  	proxyOnResponseBody(cID, 0, false)
    88  	require.True(t, ctx.onHttpResponseBody)
    89  	proxyOnResponseTrailers(cID, 0)
    90  	require.True(t, ctx.onHttpResponseTrailers)
    91  }
    92  
    93  func Test_proxyOnHttpCallResponse(t *testing.T) {
    94  	release := RegisterMockWasmHost(DefaultProxyWAMSHost{})
    95  	defer release()
    96  
    97  	var (
    98  		pluginContextID uint32 = 1
    99  		callerContextID uint32 = 100
   100  		callOutID       uint32 = 10
   101  	)
   102  
   103  	currentStateMux.Lock()
   104  	defer currentStateMux.Unlock()
   105  
   106  	t.Run("normal", func(t *testing.T) {
   107  		ctx := &l7Context{}
   108  		currentState = &state{
   109  			pluginContexts: map[uint32]*pluginContextState{pluginContextID: {
   110  				httpCallbacks: map[uint32]*httpCallbackAttribute{callOutID: {callback: ctx.OnHttpCallResponse, callerContextID: callerContextID}},
   111  			}},
   112  			contextIDToRootID: map[uint32]uint32{callerContextID: pluginContextID},
   113  		}
   114  
   115  		proxyOnHttpCallResponse(pluginContextID, callOutID, 0, 0, 0)
   116  		_, ok := currentState.pluginContexts[pluginContextID].httpCallbacks[callOutID]
   117  		require.False(t, ok)
   118  		require.True(t, ctx.onHttpCallResponse)
   119  	})
   120  
   121  	t.Run("delete before callback", func(t *testing.T) {
   122  		ctx := &l7Context{}
   123  		currentState = &state{
   124  			pluginContexts: map[uint32]*pluginContextState{pluginContextID: {
   125  				httpCallbacks: map[uint32]*httpCallbackAttribute{callOutID: {callback: ctx.OnHttpCallResponse, callerContextID: callerContextID}},
   126  			}},
   127  			httpContexts:      map[uint32]types.HttpContext{callerContextID: nil},
   128  			contextIDToRootID: map[uint32]uint32{callerContextID: pluginContextID},
   129  		}
   130  
   131  		proxyOnDelete(callerContextID)
   132  
   133  		proxyOnHttpCallResponse(pluginContextID, callOutID, 0, 0, 0)
   134  		_, ok := currentState.pluginContexts[pluginContextID].httpCallbacks[callOutID]
   135  		require.False(t, ok)
   136  
   137  		// If the caller context is deleted before callback is called, then
   138  		// the callback shouldn't be called.
   139  		require.False(t, ctx.onHttpCallResponse)
   140  	})
   141  
   142  }