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

     1  package decoders
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/http/httputil"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"github.com/yandex/pandora/components/providers/http/config"
    14  )
    15  
    16  const rawDecoderInput = `38 good50
    17  GET /?sleep=50 HTTP/1.0
    18  Host: ya.net
    19  
    20  
    21  74 bad
    22  GET /abra HTTP/1.0
    23  Host: xxx.tanks.example.com
    24  User-Agent: xxx (shell 1)
    25  
    26  599
    27  POST /upload/2 HTTP/1.0
    28  Content-Length: 496
    29  Host: xxxxxxxxx.dev.example.com
    30  User-Agent: xxx (shell 1)
    31  
    32  ^.^.1......W.j^1^.^.^.²..^^.i.^B.P..-!(.l/Y..V^.      ...L?...S'NR.^^vm...3Gg@s...d'.\^.5N.$NF^,.Z^.aTE^.
    33  ._.[..k#L^ƨ'\RE.J.<.!,.q5.F^՚iΔĬq..^6..P..тH.'..i2
    34  .".uuzs^^F2...Rh.&.U.^^.2J.P@.A......x..lǝy^?.u.p{4..g...m.,..R^.^.^.3....].^^.^J...p.ifTF0<.s.9V.o5<..%!6ļS.ƐǢ..㱋....C^&.....^.^y...v]^YT.1.#K.ibc...^.26...   ..7.
    35  b.$...j6.٨f...W.R7.^1.3....K'%.&^.4d..{{      l0..^\..^X.g.^.r.(!.^^.5.4.1.$\ .%.8$(.n&..^^q.,.Q..^.D^.].^.R9.kE.^.$^.I..<..B^.6^.h^^C.^E.|....3o^.@..Z.^.s.$[v.
    36  305
    37  POST /upload/3 HTTP/1.0
    38  Content-Length: 202
    39  Host: xxxxxxxxx.dev.example.com
    40  User-Agent: xxx (shell 1)
    41  
    42  ^.^.7......QMO.0^.++^zJw.ر^$^.^Ѣ.^V.J....vM.8r&.T+...{@pk%~C.G../z顲^.7....l...-.^W"cR..... .&^?u.U^^.^.8...{^.^.98.^.^.I.EĂ.p...'^.3.Tq..@R8....RAiBU..1.Bd*".7+.
    43  .Ol.j=^.3..n....wp..,Wg.y^.T..~^.0
    44  `
    45  
    46  func getRawDecoderWants() ([]string, []string) {
    47  	bodyWants := []string{
    48  		"GET /?sleep=50 HTTP/1.0\r\nHost: ya.net\r\nContent-Type: application/json\r\n\r\n",
    49  		"GET /abra HTTP/1.0\r\nHost: xxx.tanks.example.com\r\nContent-Type: application/json\r\nUser-Agent: xxx (shell 1)\r\n\r\n",
    50  		"POST /upload/2 HTTP/1.0\r\nHost: xxxxxxxxx.dev.example.com\r\nContent-Length: 496\r\nContent-Type: application/json\r\nUser-Agent: xxx (shell 1)\r\n\r\n^.^.1......W.j^1^.^.^.²..^^.i.^B.P..-!(.l/Y..V^.      ...L?...S'NR.^^vm...3Gg@s...d'.\\^.5N.$NF^,.Z^.aTE^.\n._.[..k#L^ƨ'\\RE.J.<.!,.q5.F^՚iΔĬq..^6..P..тH.'..i2\n.\".uuzs^^F2...Rh.&.U.^^.2J.P@.A......x..lǝy^?.u.p{4..g...m.,..R^.^.^.3....].^^.^J...p.ifTF0<.s.9V.o5<..%!6ļS.ƐǢ..㱋....C^&.....^.^y...v]^YT.1.#K.ibc...^.26...   ..7.\nb.$...j6.٨f...W.R7.^1.3....K'%.&^.4d..{{      l0..^\\..^X.g.^.r.(!.^^.5.4.1.$\\ .%.8$(.n&..^^q.,.Q..^.D^.].^.R9.kE.^.$^.I..<..B^.6^.h^^C.^E.|....3o^.@..Z.^.s.$[v.\n",
    51  		"POST /upload/3 HTTP/1.0\r\nHost: xxxxxxxxx.dev.example.com\r\nContent-Length: 202\r\nContent-Type: application/json\r\nUser-Agent: xxx (shell 1)\r\n\r\n^.^.7......QMO.0^.++^zJw.ر^$^.^Ѣ.^V.J....vM.8r&.T+...{@pk%~C.G../z顲^.7....l...-.^W\"cR..... .&^?u.U^^.^.8...{^.^.98.^.^.I.EĂ.p...'^.3.Tq..@R8....RAiBU..1.Bd*\".7+.\n.Ol.j=^.3..n....wp..,Wg.y^.T..~^.0\n",
    52  	}
    53  	tagWants := []string{
    54  		"good50",
    55  		"bad",
    56  		"",
    57  		"",
    58  	}
    59  	return bodyWants, tagWants
    60  }
    61  
    62  func Test_rawDecoder_Scan(t *testing.T) {
    63  	decoder := newRawDecoder(strings.NewReader(rawDecoderInput), config.Config{
    64  		Limit: 8,
    65  	}, http.Header{"Content-Type": []string{"application/json"}})
    66  
    67  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    68  	defer cancel()
    69  
    70  	bodyWants, tagWants := getRawDecoderWants()
    71  
    72  	for j := 0; j < 2; j++ {
    73  		for i, bodyWant := range bodyWants {
    74  			ammo, err := decoder.Scan(ctx)
    75  
    76  			assert.NoError(t, err, "iteration %d-%d", j, i)
    77  			assert.Equal(t, tagWants[i], ammo.Tag(), "iteration %d-%d", j, i)
    78  
    79  			req, err := ammo.BuildRequest()
    80  			assert.NoError(t, err)
    81  			req.Close = false
    82  			body, _ := httputil.DumpRequest(req, true)
    83  			assert.Equal(t, bodyWant, string(body), "iteration %d-%d", j, i)
    84  		}
    85  	}
    86  
    87  	_, err := decoder.Scan(ctx)
    88  	assert.Equal(t, err, ErrAmmoLimit)
    89  	assert.Equal(t, decoder.ammoNum, uint(len(bodyWants)*2))
    90  	assert.Equal(t, decoder.passNum, uint(1))
    91  }
    92  
    93  func Test_rawDecoder_LoadAmmo(t *testing.T) {
    94  	decoder := newRawDecoder(strings.NewReader(rawDecoderInput), config.Config{
    95  		Limit: 8,
    96  	}, http.Header{"Content-Type": []string{"application/json"}})
    97  
    98  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    99  	defer cancel()
   100  
   101  	bodyWants, tagWants := getRawDecoderWants()
   102  
   103  	ammos, err := decoder.LoadAmmo(ctx)
   104  	assert.NoError(t, err)
   105  	assert.Equal(t, len(bodyWants), len(ammos))
   106  
   107  	bodies := make([]string, len(bodyWants))
   108  	tags := make([]string, len(bodyWants))
   109  	for i, ammo := range ammos {
   110  		req, err := ammo.BuildRequest()
   111  		assert.NoError(t, err)
   112  		req.Close = false
   113  		body, _ := httputil.DumpRequest(req, true)
   114  		bodies[i] = string(body)
   115  		tags[i] = ammo.Tag()
   116  	}
   117  
   118  	assert.Equal(t, bodyWants, bodies)
   119  	assert.Equal(t, tagWants, tags)
   120  	assert.Equal(t, decoder.config.Limit, uint(8))
   121  	assert.Equal(t, decoder.config.Passes, uint(0))
   122  
   123  }
   124  
   125  func Benchmark_rawDecoder_Scan(b *testing.B) {
   126  	decoder := newRawDecoder(
   127  		strings.NewReader(rawDecoderInput), config.Config{},
   128  		http.Header{"Content-Type": []string{"application/json"}},
   129  	)
   130  	ctx := context.Background()
   131  
   132  	b.ResetTimer()
   133  	for i := 0; i < b.N; i++ {
   134  		_, err := decoder.Scan(ctx)
   135  		require.NoError(b, err)
   136  	}
   137  }