mirror of
https://github.com/aykhans/dodo.git
synced 2025-06-04 21:22:03 +00:00
Value generator initial commit
This commit is contained in:
parent
924bd819ee
commit
f248c2af96
1
go.mod
1
go.mod
@ -5,6 +5,7 @@ go 1.24.2
|
|||||||
require (
|
require (
|
||||||
github.com/jedib0t/go-pretty/v6 v6.6.7
|
github.com/jedib0t/go-pretty/v6 v6.6.7
|
||||||
github.com/valyala/fasthttp v1.62.0
|
github.com/valyala/fasthttp v1.62.0
|
||||||
|
github.com/brianvoe/gofakeit/v7 v7.2.1
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
2
go.sum
2
go.sum
@ -1,5 +1,7 @@
|
|||||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||||
|
github.com/brianvoe/gofakeit/v7 v7.2.1 h1:AGojgaaCdgq4Adzrd2uWdbGNDyX6MWNhHdQBraNfOHI=
|
||||||
|
github.com/brianvoe/gofakeit/v7 v7.2.1/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo=
|
github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo=
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
package requests
|
package requests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aykhans/dodo/config"
|
"github.com/aykhans/dodo/config"
|
||||||
"github.com/aykhans/dodo/types"
|
"github.com/aykhans/dodo/types"
|
||||||
"github.com/aykhans/dodo/utils"
|
"github.com/aykhans/dodo/utils"
|
||||||
|
"github.com/brianvoe/gofakeit/v7"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,6 +25,11 @@ type Request struct {
|
|||||||
getRequest RequestGeneratorFunc
|
getRequest RequestGeneratorFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type keyValueGenerator struct {
|
||||||
|
key func() string
|
||||||
|
value func() string
|
||||||
|
}
|
||||||
|
|
||||||
// Send sends the HTTP request using the fasthttp client with a specified timeout.
|
// Send sends the HTTP request using the fasthttp client with a specified timeout.
|
||||||
// It returns the HTTP response or an error if the request fails or times out.
|
// It returns the HTTP response or an error if the request fails or times out.
|
||||||
func (r *Request) Send(ctx context.Context, timeout time.Duration) (*fasthttp.Response, error) {
|
func (r *Request) Send(ctx context.Context, timeout time.Duration) (*fasthttp.Response, error) {
|
||||||
@ -101,17 +110,10 @@ func getRequestGeneratorFunc(
|
|||||||
bodies []string,
|
bodies []string,
|
||||||
localRand *rand.Rand,
|
localRand *rand.Rand,
|
||||||
) RequestGeneratorFunc {
|
) RequestGeneratorFunc {
|
||||||
bodiesLen := len(bodies)
|
|
||||||
getBody := func() string { return "" }
|
|
||||||
if bodiesLen == 1 {
|
|
||||||
getBody = func() string { return bodies[0] }
|
|
||||||
} else if bodiesLen > 1 {
|
|
||||||
getBody = utils.RandomValueCycle(bodies, localRand)
|
|
||||||
}
|
|
||||||
|
|
||||||
getParams := getKeyValueGeneratorFunc(params, localRand)
|
getParams := getKeyValueGeneratorFunc(params, localRand)
|
||||||
getHeaders := getKeyValueGeneratorFunc(headers, localRand)
|
getHeaders := getKeyValueGeneratorFunc(headers, localRand)
|
||||||
getCookies := getKeyValueGeneratorFunc(cookies, localRand)
|
getCookies := getKeyValueGeneratorFunc(cookies, localRand)
|
||||||
|
getBody := getValueFunc(bodies, newFuncMap(localRand), localRand)
|
||||||
|
|
||||||
return func() *fasthttp.Request {
|
return func() *fasthttp.Request {
|
||||||
return newFasthttpRequest(
|
return newFasthttpRequest(
|
||||||
@ -199,45 +201,75 @@ func getKeyValueGeneratorFunc[
|
|||||||
keyValueSlice []types.KeyValue[string, []string],
|
keyValueSlice []types.KeyValue[string, []string],
|
||||||
localRand *rand.Rand,
|
localRand *rand.Rand,
|
||||||
) func() T {
|
) func() T {
|
||||||
getKeyValueSlice := []map[string]func() string{}
|
keyValueGenerators := make([]keyValueGenerator, len(keyValueSlice))
|
||||||
isRandom := false
|
|
||||||
|
|
||||||
for _, kv := range keyValueSlice {
|
funcMap := newFuncMap(localRand)
|
||||||
if valuesLen := len(kv.Value); valuesLen > 1 {
|
|
||||||
isRandom = true
|
for i, kv := range keyValueSlice {
|
||||||
|
keyValueGenerators[i] = keyValueGenerator{
|
||||||
|
key: getKeyFunc(kv.Key, funcMap),
|
||||||
|
value: getValueFunc(kv.Value, funcMap, localRand),
|
||||||
}
|
}
|
||||||
|
|
||||||
getKeyValueSlice = append(
|
|
||||||
getKeyValueSlice,
|
|
||||||
map[string]func() string{
|
|
||||||
kv.Key: utils.RandomValueCycle(kv.Value, localRand),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if isRandom {
|
return func() T {
|
||||||
return func() T {
|
keyValues := make(T, len(keyValueGenerators))
|
||||||
keyValues := make(T, len(getKeyValueSlice))
|
for i, keyValue := range keyValueGenerators {
|
||||||
for i, keyValue := range getKeyValueSlice {
|
keyValues[i] = types.KeyValue[string, string]{
|
||||||
for key, value := range keyValue {
|
Key: keyValue.key(),
|
||||||
keyValues[i] = types.KeyValue[string, string]{
|
Value: keyValue.value(),
|
||||||
Key: key,
|
|
||||||
Value: value(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keyValues
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
keyValues := make(T, len(getKeyValueSlice))
|
|
||||||
for i, keyValue := range getKeyValueSlice {
|
|
||||||
for key, value := range keyValue {
|
|
||||||
keyValues[i] = types.KeyValue[string, string]{
|
|
||||||
Key: key,
|
|
||||||
Value: value(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return func() T { return keyValues }
|
return keyValues
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getKeyFunc(key string, funcMap template.FuncMap) func() string {
|
||||||
|
t, err := template.New("default").Funcs(funcMap).Parse(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
_ = t.Execute(&buf, nil)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getValueFunc(
|
||||||
|
values []string,
|
||||||
|
funcMap template.FuncMap,
|
||||||
|
localRand *rand.Rand,
|
||||||
|
) func() string {
|
||||||
|
templates := make([]*template.Template, len(values))
|
||||||
|
|
||||||
|
for i, value := range values {
|
||||||
|
t, err := template.New("default").Funcs(funcMap).Parse(value)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
templates[i] = t
|
||||||
|
}
|
||||||
|
|
||||||
|
randomTemplateFunc := utils.RandomValueCycle(templates, localRand)
|
||||||
|
|
||||||
|
return func() string {
|
||||||
|
if tmpl := randomTemplateFunc(); tmpl == nil {
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
_ = tmpl.Execute(&buf, nil)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFuncMap(localRand *rand.Rand) template.FuncMap {
|
||||||
|
localFaker := gofakeit.NewFaker(localRand, false)
|
||||||
|
|
||||||
|
return template.FuncMap{
|
||||||
|
"upper": strings.ToUpper,
|
||||||
|
"fakeit_Name": localFaker.Name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ func releaseDodos(
|
|||||||
|
|
||||||
wg.Add(int(dodosCount))
|
wg.Add(int(dodosCount))
|
||||||
streamWG.Add(1)
|
streamWG.Add(1)
|
||||||
streamCtx, streamCtxCancel := context.WithCancel(context.Background())
|
streamCtx, streamCtxCancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
go streamProgress(streamCtx, &streamWG, requestConfig.RequestCount, "Dodos Working🔥", increase)
|
go streamProgress(streamCtx, &streamWG, requestConfig.RequestCount, "Dodos Working🔥", increase)
|
||||||
|
|
||||||
|
@ -19,19 +19,15 @@ func Flatten[T any](nested [][]*T) []*T {
|
|||||||
// reset and start cycling through the values in a random order again.
|
// reset and start cycling through the values in a random order again.
|
||||||
// The returned function isn't thread-safe and should be used in a single-threaded context.
|
// The returned function isn't thread-safe and should be used in a single-threaded context.
|
||||||
func RandomValueCycle[T any](values []T, localRand *rand.Rand) func() T {
|
func RandomValueCycle[T any](values []T, localRand *rand.Rand) func() T {
|
||||||
var (
|
switch valuesLen := len(values); valuesLen {
|
||||||
valuesLen = len(values)
|
|
||||||
currentIndex = localRand.Intn(valuesLen)
|
|
||||||
stopIndex = currentIndex
|
|
||||||
)
|
|
||||||
|
|
||||||
switch valuesLen {
|
|
||||||
case 0:
|
case 0:
|
||||||
var zero T
|
var zero T
|
||||||
return func() T { return zero }
|
return func() T { return zero }
|
||||||
case 1:
|
case 1:
|
||||||
return func() T { return values[0] }
|
return func() T { return values[0] }
|
||||||
default:
|
default:
|
||||||
|
currentIndex := localRand.Intn(valuesLen)
|
||||||
|
stopIndex := currentIndex
|
||||||
return func() T {
|
return func() T {
|
||||||
value := values[currentIndex]
|
value := values[currentIndex]
|
||||||
currentIndex++
|
currentIndex++
|
||||||
|
Loading…
x
Reference in New Issue
Block a user