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

     1  package http
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	gun "github.com/yandex/pandora/components/guns/http_scenario"
     8  	"github.com/yandex/pandora/components/providers/scenario/config"
     9  	"github.com/yandex/pandora/components/providers/scenario/http/templater"
    10  	"github.com/yandex/pandora/components/providers/scenario/vs"
    11  	"github.com/yandex/pandora/lib/mp"
    12  )
    13  
    14  type IteratorIniter interface {
    15  	InitIterator(iter mp.Iterator)
    16  }
    17  
    18  func decodeAmmo(cfg *config.AmmoConfig, storage *vs.SourceStorage) ([]*gun.Scenario, error) {
    19  	reqRegistry := make(map[string]config.RequestConfig, len(cfg.Requests))
    20  
    21  	for _, req := range cfg.Requests {
    22  		reqRegistry[req.Name] = req
    23  	}
    24  
    25  	scenarioRegistry := map[string]config.ScenarioConfig{}
    26  	for _, sc := range cfg.Scenarios {
    27  		scenarioRegistry[sc.Name] = sc
    28  	}
    29  
    30  	names, size := config.SpreadNames(cfg.Scenarios)
    31  	result := make([]*gun.Scenario, 0, size)
    32  	for _, sc := range cfg.Scenarios {
    33  		a, err := convertScenarioToAmmo(sc, reqRegistry)
    34  		if err != nil {
    35  			return nil, fmt.Errorf("failed to convert scenario %s: %w", sc.Name, err)
    36  		}
    37  		a.VariableStorage = storage
    38  		ns, ok := names[sc.Name]
    39  		if !ok {
    40  			return nil, fmt.Errorf("scenario %s is not found", sc.Name)
    41  		}
    42  		for i := 0; i < ns; i++ {
    43  			result = append(result, a)
    44  		}
    45  	}
    46  
    47  	return result, nil
    48  }
    49  
    50  func convertScenarioToAmmo(sc config.ScenarioConfig, reqs map[string]config.RequestConfig) (*gun.Scenario, error) {
    51  	iter := mp.NewNextIterator(time.Now().UnixNano())
    52  	result := &gun.Scenario{Name: sc.Name, MinWaitingTime: time.Millisecond * time.Duration(sc.MinWaitingTime)}
    53  	for _, sh := range sc.Requests {
    54  		name, cnt, sleep, err := config.ParseShootName(sh)
    55  		if err != nil {
    56  			return nil, fmt.Errorf("failed to parse shoot %s: %w", sh, err)
    57  		}
    58  		if name == "sleep" {
    59  			result.Requests[len(result.Requests)-1].Sleep += time.Millisecond * time.Duration(cnt)
    60  			continue
    61  		}
    62  		req, ok := reqs[name]
    63  		if !ok {
    64  			return nil, fmt.Errorf("request %s not found", name)
    65  		}
    66  		r := convertConfigToRequest(req, iter)
    67  		if sleep > 0 {
    68  			r.Sleep += time.Millisecond * time.Duration(sleep)
    69  		}
    70  		for i := 0; i < cnt; i++ {
    71  			result.Requests = append(result.Requests, r)
    72  		}
    73  	}
    74  
    75  	return result, nil
    76  }
    77  
    78  func convertConfigToRequest(req config.RequestConfig, iter mp.Iterator) gun.Request {
    79  	templ := req.Templater
    80  	if templ == nil {
    81  		templ = templater.NewTextTemplater()
    82  	}
    83  	result := gun.Request{
    84  		Method:         req.Method,
    85  		Headers:        req.Headers,
    86  		Tag:            req.Tag,
    87  		Body:           req.Body,
    88  		Name:           req.Name,
    89  		URI:            req.URI,
    90  		Preprocessor:   req.Preprocessor,
    91  		Postprocessors: req.Postprocessors,
    92  		Templater:      templ,
    93  	}
    94  	if p, ok := result.Preprocessor.(IteratorIniter); ok {
    95  		p.InitIterator(iter)
    96  	}
    97  
    98  	return result
    99  }