github.com/mholt/caddy-l4@v0.0.0-20241104153248-ec8fae209322/modules/l4clock/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 l4clock
    16  
    17  import (
    18  	"context"
    19  	"io"
    20  	"net"
    21  	"testing"
    22  	"time"
    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 {
    33  		t.Fatalf("Unexpected error: %s\n", err)
    34  	}
    35  }
    36  
    37  func Test_MatchClock_Match(t *testing.T) {
    38  	type test struct {
    39  		matcher     *MatchClock
    40  		data        []byte
    41  		shouldMatch bool
    42  	}
    43  
    44  	tNowMinus5Minutes := time.Now().UTC().Add(time.Minute * 5 * (-1)).Format(time.TimeOnly)
    45  	tNowPlus5Minutes := time.Now().UTC().Add(time.Minute * 5).Format(time.TimeOnly)
    46  
    47  	tests := []test{
    48  		{matcher: &MatchClock{}, data: []byte{}, shouldMatch: true},
    49  		{matcher: &MatchClock{After: tNowMinus5Minutes}, data: []byte{}, shouldMatch: true},
    50  		{matcher: &MatchClock{Before: tNowPlus5Minutes}, data: []byte{}, shouldMatch: true},
    51  		{matcher: &MatchClock{After: tNowMinus5Minutes, Before: tNowPlus5Minutes}, data: []byte{}, shouldMatch: true},
    52  		{matcher: &MatchClock{After: tNowPlus5Minutes, Before: tNowMinus5Minutes}, data: []byte{}, shouldMatch: true},
    53  
    54  		{matcher: &MatchClock{After: tNowPlus5Minutes}, data: []byte{}, shouldMatch: false},
    55  		{matcher: &MatchClock{Before: tNowMinus5Minutes}, data: []byte{}, shouldMatch: false},
    56  	}
    57  
    58  	ctx, cancel := caddy.NewContext(caddy.Context{Context: context.Background()})
    59  	defer cancel()
    60  
    61  	for i, tc := range tests {
    62  		func() {
    63  			err := tc.matcher.Provision(ctx)
    64  			assertNoError(t, err)
    65  
    66  			in, out := net.Pipe()
    67  			defer func() {
    68  				_, _ = io.Copy(io.Discard, out)
    69  				_ = out.Close()
    70  			}()
    71  
    72  			cx := layer4.WrapConnection(out, []byte{}, zap.NewNop())
    73  			go func() {
    74  				_, err := in.Write(tc.data)
    75  				assertNoError(t, err)
    76  				_ = in.Close()
    77  			}()
    78  
    79  			matched, err := tc.matcher.Match(cx)
    80  			assertNoError(t, err)
    81  
    82  			if matched != tc.shouldMatch {
    83  				if tc.shouldMatch {
    84  					t.Fatalf("test %d: matcher did not match | %+v\n", i, tc.matcher)
    85  				} else {
    86  					t.Fatalf("test %d: matcher should not match | %+v\n", i, tc.matcher)
    87  				}
    88  			}
    89  		}()
    90  	}
    91  }