github.com/netdata/go.d.plugin@v0.58.1/agent/discovery/sd/pipeline/selector_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package pipeline
     4  
     5  import (
     6  	"regexp"
     7  	"testing"
     8  
     9  	"github.com/netdata/go.d.plugin/agent/discovery/sd/model"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  var reSrString = regexp.MustCompile(`^{[^{}]+}$`)
    15  
    16  func TestTrueSelector_String(t *testing.T) {
    17  	var sr trueSelector
    18  	assert.Equal(t, "{*}", sr.String())
    19  }
    20  
    21  func TestExactSelector_String(t *testing.T) {
    22  	sr := exactSelector("selector")
    23  
    24  	assert.True(t, reSrString.MatchString(sr.String()))
    25  }
    26  
    27  func TestNegSelector_String(t *testing.T) {
    28  	srs := []selector{
    29  		exactSelector("selector"),
    30  		negSelector{exactSelector("selector")},
    31  		orSelector{
    32  			lhs: exactSelector("selector"),
    33  			rhs: exactSelector("selector")},
    34  		orSelector{
    35  			lhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    36  			rhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    37  		},
    38  		andSelector{
    39  			lhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    40  			rhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    41  		},
    42  	}
    43  
    44  	for i, sr := range srs {
    45  		neg := negSelector{sr}
    46  		assert.True(t, reSrString.MatchString(neg.String()), "selector num %d", i+1)
    47  	}
    48  }
    49  
    50  func TestOrSelector_String(t *testing.T) {
    51  	sr := orSelector{
    52  		lhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    53  		rhs: orSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    54  	}
    55  
    56  	assert.True(t, reSrString.MatchString(sr.String()))
    57  }
    58  
    59  func TestAndSelector_String(t *testing.T) {
    60  	sr := andSelector{
    61  		lhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    62  		rhs: andSelector{lhs: exactSelector("selector"), rhs: negSelector{exactSelector("selector")}},
    63  	}
    64  
    65  	assert.True(t, reSrString.MatchString(sr.String()))
    66  }
    67  
    68  func TestExactSelector_Matches(t *testing.T) {
    69  	matchTests := struct {
    70  		tags model.Tags
    71  		srs  []exactSelector
    72  	}{
    73  		tags: model.Tags{"a": {}, "b": {}},
    74  		srs: []exactSelector{
    75  			"a",
    76  			"b",
    77  		},
    78  	}
    79  	notMatchTests := struct {
    80  		tags model.Tags
    81  		srs  []exactSelector
    82  	}{
    83  		tags: model.Tags{"a": {}, "b": {}},
    84  		srs: []exactSelector{
    85  			"c",
    86  			"d",
    87  		},
    88  	}
    89  
    90  	for i, sr := range matchTests.srs {
    91  		assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1)
    92  	}
    93  	for i, sr := range notMatchTests.srs {
    94  		assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1)
    95  	}
    96  }
    97  
    98  func TestNegSelector_Matches(t *testing.T) {
    99  	matchTests := struct {
   100  		tags model.Tags
   101  		srs  []negSelector
   102  	}{
   103  		tags: model.Tags{"a": {}, "b": {}},
   104  		srs: []negSelector{
   105  			{exactSelector("c")},
   106  			{exactSelector("d")},
   107  		},
   108  	}
   109  	notMatchTests := struct {
   110  		tags model.Tags
   111  		srs  []negSelector
   112  	}{
   113  		tags: model.Tags{"a": {}, "b": {}},
   114  		srs: []negSelector{
   115  			{exactSelector("a")},
   116  			{exactSelector("b")},
   117  		},
   118  	}
   119  
   120  	for i, sr := range matchTests.srs {
   121  		assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1)
   122  	}
   123  	for i, sr := range notMatchTests.srs {
   124  		assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1)
   125  	}
   126  }
   127  
   128  func TestOrSelector_Matches(t *testing.T) {
   129  	matchTests := struct {
   130  		tags model.Tags
   131  		srs  []orSelector
   132  	}{
   133  		tags: model.Tags{"a": {}, "b": {}},
   134  		srs: []orSelector{
   135  			{
   136  				lhs: orSelector{lhs: exactSelector("c"), rhs: exactSelector("d")},
   137  				rhs: orSelector{lhs: exactSelector("e"), rhs: exactSelector("b")},
   138  			},
   139  		},
   140  	}
   141  	notMatchTests := struct {
   142  		tags model.Tags
   143  		srs  []orSelector
   144  	}{
   145  		tags: model.Tags{"a": {}, "b": {}},
   146  		srs: []orSelector{
   147  			{
   148  				lhs: orSelector{lhs: exactSelector("c"), rhs: exactSelector("d")},
   149  				rhs: orSelector{lhs: exactSelector("e"), rhs: exactSelector("f")},
   150  			},
   151  		},
   152  	}
   153  
   154  	for i, sr := range matchTests.srs {
   155  		assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1)
   156  	}
   157  	for i, sr := range notMatchTests.srs {
   158  		assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1)
   159  	}
   160  }
   161  
   162  func TestAndSelector_Matches(t *testing.T) {
   163  	matchTests := struct {
   164  		tags model.Tags
   165  		srs  []andSelector
   166  	}{
   167  		tags: model.Tags{"a": {}, "b": {}, "c": {}, "d": {}},
   168  		srs: []andSelector{
   169  			{
   170  				lhs: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")},
   171  				rhs: andSelector{lhs: exactSelector("c"), rhs: exactSelector("d")},
   172  			},
   173  		},
   174  	}
   175  	notMatchTests := struct {
   176  		tags model.Tags
   177  		srs  []andSelector
   178  	}{
   179  		tags: model.Tags{"a": {}, "b": {}, "c": {}, "d": {}},
   180  		srs: []andSelector{
   181  			{
   182  				lhs: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")},
   183  				rhs: andSelector{lhs: exactSelector("c"), rhs: exactSelector("z")},
   184  			},
   185  		},
   186  	}
   187  
   188  	for i, sr := range matchTests.srs {
   189  		assert.Truef(t, sr.matches(matchTests.tags), "match selector num %d", i+1)
   190  	}
   191  	for i, sr := range notMatchTests.srs {
   192  		assert.Falsef(t, sr.matches(notMatchTests.tags), "not match selector num %d", i+1)
   193  	}
   194  }
   195  
   196  func TestParseSelector(t *testing.T) {
   197  	tests := map[string]struct {
   198  		wantSelector selector
   199  		wantErr      bool
   200  	}{
   201  		"":    {wantSelector: trueSelector{}},
   202  		"a":   {wantSelector: exactSelector("a")},
   203  		"Z":   {wantSelector: exactSelector("Z")},
   204  		"a_b": {wantSelector: exactSelector("a_b")},
   205  		"a=b": {wantSelector: exactSelector("a=b")},
   206  		"!a":  {wantSelector: negSelector{exactSelector("a")}},
   207  		"a b": {wantSelector: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")}},
   208  		"a|b": {wantSelector: orSelector{lhs: exactSelector("a"), rhs: exactSelector("b")}},
   209  		"*":   {wantSelector: trueSelector{}},
   210  		"!*":  {wantSelector: negSelector{trueSelector{}}},
   211  		"a b !c d|e f": {
   212  			wantSelector: andSelector{
   213  				lhs: andSelector{
   214  					lhs: andSelector{
   215  						lhs: andSelector{lhs: exactSelector("a"), rhs: exactSelector("b")},
   216  						rhs: negSelector{exactSelector("c")},
   217  					},
   218  					rhs: orSelector{
   219  						lhs: exactSelector("d"),
   220  						rhs: exactSelector("e"),
   221  					},
   222  				},
   223  				rhs: exactSelector("f"),
   224  			},
   225  		},
   226  		"!":      {wantErr: true},
   227  		"a !":    {wantErr: true},
   228  		"a!b":    {wantErr: true},
   229  		"0a":     {wantErr: true},
   230  		"a b c*": {wantErr: true},
   231  		"__":     {wantErr: true},
   232  		"a|b|c*": {wantErr: true},
   233  	}
   234  
   235  	for name, test := range tests {
   236  		t.Run(name, func(t *testing.T) {
   237  			sr, err := parseSelector(name)
   238  
   239  			if test.wantErr {
   240  				assert.Nil(t, sr)
   241  				assert.Error(t, err)
   242  			} else {
   243  				assert.NoError(t, err)
   244  				assert.Equal(t, test.wantSelector, sr)
   245  			}
   246  		})
   247  	}
   248  }