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 }