Skip to content
This repository has been archived by the owner on Sep 17, 2022. It is now read-only.

Add config LeadReader function and fix timings calculation #136

Merged
merged 3 commits into from Mar 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 17 additions & 6 deletions common/config/loader.go
Expand Up @@ -2,7 +2,7 @@ package config

import (
"fmt"
"io/ioutil"
"io"
"os"
"path/filepath"
"strings"
Expand All @@ -11,6 +11,10 @@ import (
"gopkg.in/yaml.v3"
)

func LoadReader(r io.Reader) (Config, error) {
return loadReader(r)
}

func Load(path string) (Config, error) {
return tryLoad(path)
}
Expand Down Expand Up @@ -53,15 +57,22 @@ func loadDir(path string) (Config, error) {
}

func loadFile(path string) (Config, error) {
cfg := config{}

contents, err := ioutil.ReadFile(path)
suiteFile, err := os.Open(path)
defer suiteFile.Close()
if err != nil {
return Config{}, err
}

err = yaml.Unmarshal(contents, &cfg)
return loadReader(suiteFile)
}

func loadReader(r io.Reader) (Config, error) {
cfg := &config{}
err := yaml.NewDecoder(r).Decode(cfg)
if err != nil {
if err == io.EOF {
return Config{}, nil
}
return Config{}, err
}

Expand All @@ -72,7 +83,7 @@ func loadFile(path string) (Config, error) {
APIKey: cfg.APIKey,
Variables: cfg.Variables,
Transactions: cfg.Transactions,
}, err
}, nil
}

func mergeConfigs(configs []Config) (Config, error) {
Expand Down
44 changes: 44 additions & 0 deletions common/config/loader_test.go
@@ -1,6 +1,8 @@
package config

import (
"bytes"
"io"
"io/ioutil"
"os"
"testing"
Expand Down Expand Up @@ -72,6 +74,48 @@ func (s *LoaderSuite) TestLoad() {
}
}

func (s *LoaderSuite) TestLoadReader() {
yamlCfg, internalCfg := newConfigPair()
stringCfg, _ := yaml.Marshal(yamlCfg)

validFile := bytes.NewBuffer(stringCfg)
emptyFile := bytes.NewReader(nil)
invalidYaml := bytes.NewReader([]byte("123"))

testCases := []struct {
reader io.Reader
expConfig Config
expErr bool
}{
{
reader: validFile,
expConfig: internalCfg,
expErr: false,
},
{
reader: emptyFile,
expConfig: Config{},
expErr: false,
},
{
reader: invalidYaml,
expErr: true,
},
}

for i, t := range testCases {
actualCfg, err := LoadReader(t.reader)

if t.expErr {
s.Error(err)
} else {
s.NoError(err)
}

s.Equalf(t.expConfig, actualCfg, "test case %d/%d", i+1, len(testCases))
}
}

func (s *LoaderSuite) TestApplySSLFlag_StepUnset() {
tx := transaction.Transaction{
Steps: []step.Step{
Expand Down
17 changes: 14 additions & 3 deletions common/http/client.go
Expand Up @@ -49,6 +49,9 @@ type TimedClient struct {
type Tracer interface {
Tracer() *httptrace.ClientTrace
Timings() Timings
// Done needs to be called when the request is finished.
// Without calling done the ContentTransfer in the Timings will be invalid.
Done()
}

// DefaultClient is the default HTTP client
Expand All @@ -63,7 +66,8 @@ type DefaultTracer struct {
tlsStart,
tlsDone,
firstResponseByte,
wroteRequest time.Time
wroteRequest,
finishedRequest time.Time
}

// NewTimedClient creates a default timed client
Expand Down Expand Up @@ -97,10 +101,14 @@ func (t *DefaultTracer) Timings() Timings {
TCPConnection: t.connectDone.Sub(t.connectStart),
TLSHandshake: t.tlsDone.Sub(t.tlsStart),
ServerProcessing: t.firstResponseByte.Sub(t.wroteRequest),
ContentTransfer: t.connectDone.Sub(t.firstResponseByte),
ContentTransfer: t.finishedRequest.Sub(t.firstResponseByte),
}
}

func (t *DefaultTracer) Done() {
t.finishedRequest = time.Now()
}

// Do executes a http request
func (c TimedClient) Do(ctx context.Context, req *Request) (*Response, error) {
var res = &Response{}
Expand All @@ -111,11 +119,14 @@ func (c TimedClient) Do(ctx context.Context, req *Request) (*Response, error) {
client = c.insecureClient
}
res.Response, err = client.Do(req.Request)
res.Timings = c.tracer.Timings()
if err != nil {
return res, err
}
c.tracer.Done()
res.Timings = c.tracer.Timings()

readBody, err := ioutil.ReadAll(res.Body)
_ = res.Body.Close() // prevents memory leaks
if err != nil {
return res, err
}
Expand Down
2 changes: 2 additions & 0 deletions common/http/client_test.go
Expand Up @@ -51,6 +51,8 @@ func (t *DummyTracer) Timings() Timings {
}
}

func (t *DummyTracer) Done() {}

func TestTimedClient_Do(t *testing.T) {
type fields struct {
code int
Expand Down