github.com/yandex/pandora@v0.5.32/components/providers/http/decoders/uri_test.go (about)

     1  package decoders
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/yandex/pandora/components/providers/http/config"
    13  	"github.com/yandex/pandora/components/providers/http/decoders/ammo"
    14  )
    15  
    16  func Test_uriDecoder_readLine(t *testing.T) {
    17  	var mustNewAmmo = func(t *testing.T, method string, url string, body []byte, header http.Header, tag string) *ammo.Ammo {
    18  		a := ammo.Ammo{}
    19  		err := a.Setup(method, url, body, header, tag)
    20  		require.NoError(t, err)
    21  		return &a
    22  	}
    23  
    24  	tests := []struct {
    25  		name                  string
    26  		data                  string
    27  		want                  *ammo.Ammo
    28  		wantErr               bool
    29  		expectedCommonHeaders http.Header
    30  	}{
    31  		{
    32  			name:    "Header line",
    33  			data:    "[Content-Type: application/json]",
    34  			want:    nil,
    35  			wantErr: false,
    36  			expectedCommonHeaders: http.Header{
    37  				"Content-Type": []string{"application/json"},
    38  				"User-Agent":   []string{"TestAgent"},
    39  			},
    40  		},
    41  		{
    42  			name: "Valid URI",
    43  			data: "http://example.com/test",
    44  			want: mustNewAmmo(t, "GET", "http://example.com/test", nil, http.Header{
    45  				"User-Agent":    []string{"TestAgent"},
    46  				"Authorization": []string{"Bearer xxx"},
    47  			}, ""),
    48  			wantErr: false,
    49  			expectedCommonHeaders: http.Header{
    50  				"User-Agent": []string{"TestAgent"},
    51  			},
    52  		},
    53  		{
    54  			name: "URI with tag",
    55  			data: "http://example.com/test tag\n",
    56  			want: mustNewAmmo(t, "GET", "http://example.com/test", nil, http.Header{
    57  				"User-Agent":    []string{"TestAgent"},
    58  				"Authorization": []string{"Bearer xxx"},
    59  			}, "tag"),
    60  			wantErr: false,
    61  			expectedCommonHeaders: http.Header{
    62  				"User-Agent": []string{"TestAgent"},
    63  			},
    64  		},
    65  		{
    66  			name:    "Invalid data",
    67  			data:    "1http://foo.com tag",
    68  			want:    nil,
    69  			wantErr: true,
    70  		},
    71  	}
    72  	for _, tt := range tests {
    73  		t.Run(tt.name, func(t *testing.T) {
    74  			commonHeader := http.Header{"User-Agent": []string{"TestAgent"}}
    75  			decodedConfigHeaders := http.Header{"Authorization": []string{"Bearer xxx"}}
    76  
    77  			decoder := newURIDecoder(nil, config.Config{}, decodedConfigHeaders)
    78  			a, err := decoder.readLine(tt.data, commonHeader)
    79  
    80  			if tt.wantErr {
    81  				assert.Error(t, err)
    82  				return
    83  			}
    84  			if tt.want == nil {
    85  				assert.Nil(t, a)
    86  			} else {
    87  				assert.Equal(t, tt.want, a)
    88  			}
    89  			assert.Equal(t, tt.expectedCommonHeaders, commonHeader)
    90  		})
    91  	}
    92  }
    93  
    94  const uriDecoderInput = ` /0
    95  [A:b]
    96  /1
    97  [Host : example.com]
    98  [ C : d ]
    99  /2
   100  [A:]
   101  [Host : other.net]
   102  
   103  /3
   104  /4 some tag`
   105  
   106  func getURIAmmoWants(t *testing.T) []DecodedAmmo {
   107  	var mustNewAmmo = func(t *testing.T, method string, url string, body []byte, header http.Header, tag string) *ammo.Ammo {
   108  		a := ammo.Ammo{}
   109  		err := a.Setup(method, url, body, header, tag)
   110  		require.NoError(t, err)
   111  		return &a
   112  	}
   113  	return []DecodedAmmo{
   114  		mustNewAmmo(t, "GET", "/0", nil, http.Header{"Content-Type": []string{"application/json"}}, ""),
   115  		mustNewAmmo(t, "GET", "/1", nil, http.Header{"A": []string{"b"}, "Content-Type": []string{"application/json"}}, ""),
   116  		mustNewAmmo(t, "GET", "/2", nil, http.Header{"Host": []string{"example.com"}, "A": []string{"b"}, "C": []string{"d"}, "Content-Type": []string{"application/json"}}, ""),
   117  		mustNewAmmo(t, "GET", "/3", nil, http.Header{"Host": []string{"other.net"}, "A": []string{""}, "C": []string{"d"}, "Content-Type": []string{"application/json"}}, ""),
   118  		mustNewAmmo(t, "GET", "/4", nil, http.Header{"Host": []string{"other.net"}, "A": []string{""}, "C": []string{"d"}, "Content-Type": []string{"application/json"}}, "some tag"),
   119  	}
   120  }
   121  
   122  func Test_uriDecoder_Scan(t *testing.T) {
   123  	decoder := newURIDecoder(strings.NewReader(uriDecoderInput), config.Config{
   124  		Limit: 10,
   125  	}, http.Header{"Content-Type": []string{"application/json"}})
   126  
   127  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   128  	defer cancel()
   129  
   130  	wants := getURIAmmoWants(t)
   131  	for j := 0; j < 2; j++ {
   132  		for i, want := range wants {
   133  			ammo, err := decoder.Scan(ctx)
   134  			assert.NoError(t, err, "iteration %d-%d", j, i)
   135  			assert.Equal(t, want, ammo, "iteration %d-%d", j, i)
   136  		}
   137  	}
   138  
   139  	_, err := decoder.Scan(ctx)
   140  	assert.Equal(t, err, ErrAmmoLimit)
   141  	assert.Equal(t, decoder.ammoNum, uint(len(wants)*2))
   142  	assert.Equal(t, decoder.passNum, uint(1))
   143  }
   144  
   145  func Test_uriDecoder_LoadAmmo(t *testing.T) {
   146  	decoder := newURIDecoder(strings.NewReader(uriDecoderInput), config.Config{
   147  		Limit: 10,
   148  	}, http.Header{"Content-Type": []string{"application/json"}})
   149  
   150  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   151  	defer cancel()
   152  
   153  	wants := getURIAmmoWants(t)
   154  
   155  	ammos, err := decoder.LoadAmmo(ctx)
   156  	assert.NoError(t, err)
   157  	assert.Equal(t, wants, ammos)
   158  	assert.Equal(t, decoder.config.Limit, uint(10))
   159  	assert.Equal(t, decoder.config.Passes, uint(0))
   160  }
   161  
   162  func Benchmark_uriDecoder_Scan(b *testing.B) {
   163  	decoder := newURIDecoder(
   164  		strings.NewReader(uriDecoderInput), config.Config{},
   165  		http.Header{"Content-Type": []string{"application/json"}},
   166  	)
   167  	ctx := context.Background()
   168  
   169  	b.ResetTimer()
   170  	for i := 0; i < b.N; i++ {
   171  		_, err := decoder.Scan(ctx)
   172  		require.NoError(b, err)
   173  	}
   174  }