github.com/cilium/cilium@v1.16.2/pkg/hubble/filters/patterns_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package filters
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestCompileFQDNPattern(t *testing.T) {
    14  	tests := []struct {
    15  		name            string
    16  		fqdnPatterns    []string
    17  		wantErr         bool
    18  		wantErrContains string
    19  		want            string
    20  	}{
    21  		{
    22  			name:            "empty",
    23  			fqdnPatterns:    []string{""},
    24  			wantErr:         true,
    25  			wantErrContains: "empty pattern",
    26  		},
    27  		{
    28  			name:         "simple",
    29  			fqdnPatterns: []string{"cilium.io"},
    30  			want:         `\A(?:cilium\.io)\z`,
    31  		},
    32  		{
    33  			name:         "multiple",
    34  			fqdnPatterns: []string{"cilium.io", "ebpf.io"},
    35  			want:         `\A(?:cilium\.io|ebpf\.io)\z`,
    36  		},
    37  		{
    38  			name:         "star",
    39  			fqdnPatterns: []string{"*.cilium.io"},
    40  			want:         `\A(?:[-.0-9a-z]*\.cilium\.io)\z`,
    41  		},
    42  		{
    43  			name:         "trailing_dot",
    44  			fqdnPatterns: []string{"cilium.io."},
    45  			want:         `\A(?:cilium\.io)\z`,
    46  		},
    47  		{
    48  			name:         "spaces",
    49  			fqdnPatterns: []string{"  cilium.io  "},
    50  			want:         `\A(?:cilium\.io)\z`,
    51  		},
    52  		{
    53  			name:         "upper_case",
    54  			fqdnPatterns: []string{"CILIUM.IO"},
    55  			want:         `\A(?:cilium\.io)\z`,
    56  		},
    57  		{
    58  			name:         "spaces_trailing_dot_upper_case",
    59  			fqdnPatterns: []string{"  CILIUM.IO.  "},
    60  			want:         `\A(?:cilium\.io)\z`,
    61  		},
    62  		{
    63  			name:         "underscores",
    64  			fqdnPatterns: []string{"_ldap._tcp.example.com"},
    65  			want:         `\A(?:_ldap\._tcp\.example\.com)\z`,
    66  		},
    67  		{
    68  			name:            "empty_after_trim",
    69  			fqdnPatterns:    []string{"  .  "},
    70  			wantErr:         true,
    71  			wantErrContains: "empty pattern",
    72  		},
    73  		{
    74  			name:            "invalid rune",
    75  			fqdnPatterns:    []string{"?"},
    76  			wantErr:         true,
    77  			wantErrContains: "invalid rune in pattern",
    78  		},
    79  		{
    80  			name:            "multiple_trailing_dots",
    81  			fqdnPatterns:    []string{"cilium.io.."},
    82  			wantErr:         true,
    83  			wantErrContains: "multiple trailing dots",
    84  		},
    85  	}
    86  
    87  	for _, tt := range tests {
    88  		t.Run(tt.name, func(t *testing.T) {
    89  			got, err := compileFQDNPattern(tt.fqdnPatterns)
    90  			if tt.wantErr {
    91  				require.Error(t, err)
    92  				assert.Contains(t, err.Error(), tt.wantErrContains)
    93  				return
    94  			}
    95  
    96  			require.NoError(t, err)
    97  			assert.Equal(t, tt.want, got.String())
    98  		})
    99  	}
   100  }
   101  
   102  func TestCompileNodeNamePatterns(t *testing.T) {
   103  	type test struct {
   104  		name             string
   105  		nodeNamePatterns []string
   106  		wantErr          bool
   107  		wantErrContains  string
   108  		want             string
   109  	}
   110  
   111  	tests := []test{
   112  		{
   113  			name:             "all",
   114  			nodeNamePatterns: []string{"/"},
   115  			want:             `\A(?:(?:[-0-9_a-z]+(?:\.[-0-9_a-z]+)*)/(?:[-0-9_a-z]+(?:\.[-0-9_a-z]+)*))\z`,
   116  		},
   117  		{
   118  			name:             "node_pattern_only",
   119  			nodeNamePatterns: []string{"runtime1"},
   120  			want:             `\A(?:(?:[-0-9_a-z]+(?:\.[-0-9_a-z]+)*)/runtime1)\z`,
   121  		},
   122  		{
   123  			name:             "cluster_pattern_only",
   124  			nodeNamePatterns: []string{"cluster-name/"},
   125  			want:             `\A(?:cluster-name/(?:[-0-9_a-z]+(?:\.[-0-9_a-z]+)*))\z`,
   126  		},
   127  		{
   128  			name:             "wildcard_node_pattern",
   129  			nodeNamePatterns: []string{"k8s*"},
   130  			want:             `\A(?:(?:[-0-9_a-z]+(?:\.[-0-9_a-z]+)*)/k8s[-.0-9a-z]*)\z`,
   131  		},
   132  		{
   133  			name:             "multiple_patterns",
   134  			nodeNamePatterns: []string{"runtime1", "test-cluster/k8s1"},
   135  			want:             `\A(?:(?:[-0-9_a-z]+(?:\.[-0-9_a-z]+)*)/runtime1|test-cluster/k8s1)\z`,
   136  		},
   137  		{
   138  			name:             "empty_pattern",
   139  			nodeNamePatterns: []string{""},
   140  			wantErr:          true,
   141  			wantErrContains:  "empty pattern",
   142  		},
   143  		{
   144  			name:             "invalid_rune_in_node_pattern",
   145  			nodeNamePatterns: []string{"?"},
   146  			wantErr:          true,
   147  			wantErrContains:  "invalid rune in pattern",
   148  		},
   149  		{
   150  			name:             "invalid_rune_in_cluster_pattern",
   151  			nodeNamePatterns: []string{"?/"},
   152  			wantErr:          true,
   153  			wantErrContains:  "invalid rune in pattern",
   154  		},
   155  		{
   156  			name:             "too_many_slashes",
   157  			nodeNamePatterns: []string{"default/runtime1/k8s1"},
   158  			wantErr:          true,
   159  			wantErrContains:  "too many slashes in pattern",
   160  		},
   161  	}
   162  
   163  	for _, tt := range tests {
   164  		t.Run(tt.name, func(t *testing.T) {
   165  			got, err := compileNodeNamePattern(tt.nodeNamePatterns)
   166  			if tt.wantErr {
   167  				require.Error(t, err)
   168  				assert.Contains(t, err.Error(), tt.wantErrContains)
   169  				return
   170  			}
   171  			require.NoError(t, err)
   172  			assert.Equal(t, tt.want, got.String())
   173  		})
   174  	}
   175  }