github.com/mholt/caddy-l4@v0.0.0-20241104153248-ec8fae209322/modules/l4regexp/matcher_test.go (about)

     1  // Copyright 2024 VNXME
     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 l4regexp
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"io"
    21  	"net"
    22  	"testing"
    23  
    24  	"github.com/caddyserver/caddy/v2"
    25  	"go.uber.org/zap"
    26  
    27  	"github.com/mholt/caddy-l4/layer4"
    28  )
    29  
    30  func assertNoError(t *testing.T, err error) {
    31  	t.Helper()
    32  	if err != nil && !errors.Is(err, io.EOF) && !errors.Is(err, io.ErrUnexpectedEOF) {
    33  		t.Fatalf("Unexpected error: %s\n", err)
    34  	}
    35  }
    36  
    37  func Test_MatchRegexp_Match(t *testing.T) {
    38  	type test struct {
    39  		matcher     *MatchRegexp
    40  		data        []byte
    41  		shouldMatch bool
    42  	}
    43  
    44  	tests := []test{
    45  		{matcher: &MatchRegexp{}, data: packet0123, shouldMatch: true},
    46  		{matcher: &MatchRegexp{Pattern: ""}, data: packet0123, shouldMatch: true},
    47  		{matcher: &MatchRegexp{Pattern: "12"}, data: packet0123, shouldMatch: true},
    48  		{matcher: &MatchRegexp{Pattern: "^0123$"}, data: packet0123, shouldMatch: true},
    49  		{matcher: &MatchRegexp{Pattern: "^012$"}, data: packet0123, shouldMatch: false},
    50  		{matcher: &MatchRegexp{Pattern: "^0123$", Count: 5}, data: packet0123, shouldMatch: false},
    51  		{matcher: &MatchRegexp{Pattern: "^012$", Count: 3}, data: packet0123, shouldMatch: true},
    52  		{matcher: &MatchRegexp{Pattern: "^\\d+$"}, data: packet0123, shouldMatch: true},
    53  		{matcher: &MatchRegexp{Pattern: "^\\d+$", Count: 0}, data: packet0123, shouldMatch: true},
    54  		{matcher: &MatchRegexp{Pattern: "^\x30\x31\x32(\x33|\x34)$", Count: 0}, data: packet0123, shouldMatch: true},
    55  	}
    56  
    57  	ctx, cancel := caddy.NewContext(caddy.Context{Context: context.Background()})
    58  	defer cancel()
    59  
    60  	for i, tc := range tests {
    61  		func() {
    62  			err := tc.matcher.Provision(ctx)
    63  			assertNoError(t, err)
    64  
    65  			in, out := net.Pipe()
    66  			defer func() {
    67  				_, _ = io.Copy(io.Discard, out)
    68  				_ = out.Close()
    69  			}()
    70  
    71  			cx := layer4.WrapConnection(out, []byte{}, zap.NewNop())
    72  			go func() {
    73  				_, err := in.Write(tc.data)
    74  				assertNoError(t, err)
    75  				_ = in.Close()
    76  			}()
    77  
    78  			matched, err := tc.matcher.Match(cx)
    79  			assertNoError(t, err)
    80  
    81  			if matched != tc.shouldMatch {
    82  				if tc.shouldMatch {
    83  					t.Fatalf("test %d: matcher did not match | %+v\n", i, tc.matcher)
    84  				} else {
    85  					t.Fatalf("test %d: matcher should not match | %+v\n", i, tc.matcher)
    86  				}
    87  			}
    88  		}()
    89  	}
    90  }
    91  
    92  var packet0123 = []byte{0x30, 0x31, 0x32, 0x33}