mirror of
https://github.com/nikdoof/vsphere-influxdb-go.git
synced 2025-12-19 05:29:21 +00:00
add vendoring with go dep
This commit is contained in:
32
vendor/github.com/influxdata/influxdb/stress/v2/statement/exec.go
generated
vendored
Normal file
32
vendor/github.com/influxdata/influxdb/stress/v2/statement/exec.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// ExecStatement run outside scripts. This functionality is not built out
|
||||
// TODO: Wire up!
|
||||
type ExecStatement struct {
|
||||
StatementID string
|
||||
Script string
|
||||
|
||||
runtime time.Duration
|
||||
}
|
||||
|
||||
// SetID statisfies the Statement Interface
|
||||
func (i *ExecStatement) SetID(s string) {
|
||||
i.StatementID = s
|
||||
}
|
||||
|
||||
// Run statisfies the Statement Interface
|
||||
func (i *ExecStatement) Run(s *stressClient.StressTest) {
|
||||
runtime := time.Now()
|
||||
i.runtime = time.Since(runtime)
|
||||
}
|
||||
|
||||
// Report statisfies the Statement Interface
|
||||
func (i *ExecStatement) Report(s *stressClient.StressTest) string {
|
||||
return ""
|
||||
}
|
||||
41
vendor/github.com/influxdata/influxdb/stress/v2/statement/exec_test.go
generated
vendored
Normal file
41
vendor/github.com/influxdata/influxdb/stress/v2/statement/exec_test.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
func TestExecSetID(t *testing.T) {
|
||||
e := newTestExec()
|
||||
newID := "oaijnifo"
|
||||
e.SetID(newID)
|
||||
if e.StatementID != newID {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", newID, e.StatementID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecRun(t *testing.T) {
|
||||
e := newTestExec()
|
||||
s, _, _ := stressClient.NewTestStressTest()
|
||||
e.Run(s)
|
||||
if e == nil {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecReport(t *testing.T) {
|
||||
e := newTestExec()
|
||||
s, _, _ := stressClient.NewTestStressTest()
|
||||
rep := e.Report(s)
|
||||
if rep != "" {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func newTestExec() *ExecStatement {
|
||||
return &ExecStatement{
|
||||
StatementID: "fooID",
|
||||
Script: "fooscript.txt",
|
||||
}
|
||||
}
|
||||
176
vendor/github.com/influxdata/influxdb/stress/v2/statement/function.go
generated
vendored
Normal file
176
vendor/github.com/influxdata/influxdb/stress/v2/statement/function.go
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
crypto "crypto/rand"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// ################
|
||||
// # Function #
|
||||
// ################
|
||||
|
||||
// Function is a struct that holds information for generating values in templated points
|
||||
type Function struct {
|
||||
Type string
|
||||
Fn string
|
||||
Argument int
|
||||
Count int
|
||||
}
|
||||
|
||||
// NewStringer creates a new Stringer
|
||||
func (f *Function) NewStringer(series int) Stringer {
|
||||
var fn Stringer
|
||||
switch f.Type {
|
||||
case "int":
|
||||
fn = NewIntFunc(f.Fn, f.Argument)
|
||||
case "float":
|
||||
fn = NewFloatFunc(f.Fn, f.Argument)
|
||||
case "str":
|
||||
fn = NewStrFunc(f.Fn, f.Argument)
|
||||
default:
|
||||
fn = func() string { return "STRINGER ERROR" }
|
||||
}
|
||||
|
||||
if int(f.Count) != 0 {
|
||||
return cycle(f.Count, fn)
|
||||
}
|
||||
|
||||
return nTimes(series, fn)
|
||||
|
||||
}
|
||||
|
||||
// ################
|
||||
// # Stringers #
|
||||
// ################
|
||||
|
||||
// Stringers is a collection of Stringer
|
||||
type Stringers []Stringer
|
||||
|
||||
// Eval returns an array of all the Stringer functions evaluated once
|
||||
func (s Stringers) Eval(time func() int64) []interface{} {
|
||||
arr := make([]interface{}, len(s)+1)
|
||||
|
||||
for i, st := range s {
|
||||
arr[i] = st()
|
||||
}
|
||||
|
||||
arr[len(s)] = time()
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
// Stringer is a function that returns a string
|
||||
type Stringer func() string
|
||||
|
||||
func randStr(n int) func() string {
|
||||
return func() string {
|
||||
b := make([]byte, n/2)
|
||||
|
||||
_, _ = crypto.Read(b)
|
||||
|
||||
return fmt.Sprintf("%x", b)
|
||||
}
|
||||
}
|
||||
|
||||
// NewStrFunc reates a new striger to create strings for templated writes
|
||||
func NewStrFunc(fn string, arg int) Stringer {
|
||||
switch fn {
|
||||
case "rand":
|
||||
return randStr(arg)
|
||||
default:
|
||||
return func() string { return "STR ERROR" }
|
||||
}
|
||||
}
|
||||
|
||||
func randFloat(n int) func() string {
|
||||
return func() string {
|
||||
return fmt.Sprintf("%v", rand.Intn(n))
|
||||
}
|
||||
}
|
||||
|
||||
func incFloat(n int) func() string {
|
||||
i := n
|
||||
return func() string {
|
||||
s := fmt.Sprintf("%v", i)
|
||||
i++
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
// NewFloatFunc reates a new striger to create float values for templated writes
|
||||
func NewFloatFunc(fn string, arg int) Stringer {
|
||||
switch fn {
|
||||
case "rand":
|
||||
return randFloat(arg)
|
||||
case "inc":
|
||||
return incFloat(arg)
|
||||
default:
|
||||
return func() string { return "FLOAT ERROR" }
|
||||
}
|
||||
}
|
||||
|
||||
func randInt(n int) Stringer {
|
||||
return func() string {
|
||||
return fmt.Sprintf("%vi", rand.Intn(n))
|
||||
}
|
||||
}
|
||||
|
||||
func incInt(n int) Stringer {
|
||||
i := n
|
||||
return func() string {
|
||||
s := fmt.Sprintf("%vi", i)
|
||||
i++
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
// NewIntFunc reates a new striger to create int values for templated writes
|
||||
func NewIntFunc(fn string, arg int) Stringer {
|
||||
switch fn {
|
||||
case "rand":
|
||||
return randInt(arg)
|
||||
case "inc":
|
||||
return incInt(arg)
|
||||
default:
|
||||
return func() string { return "INT ERROR" }
|
||||
}
|
||||
}
|
||||
|
||||
// nTimes will return the previous return value of a function
|
||||
// n-many times before calling the function again
|
||||
func nTimes(n int, fn Stringer) Stringer {
|
||||
i := 0
|
||||
t := fn()
|
||||
return func() string {
|
||||
i++
|
||||
if i > n {
|
||||
t = fn()
|
||||
i = 1
|
||||
}
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
// cycle will cycle through a list of values before repeating them
|
||||
|
||||
func cycle(n int, fn Stringer) Stringer {
|
||||
if n == 0 {
|
||||
return fn
|
||||
}
|
||||
i := 0
|
||||
cache := make([]string, n)
|
||||
t := fn()
|
||||
cache[i] = t
|
||||
|
||||
return func() string {
|
||||
i++
|
||||
|
||||
if i < n {
|
||||
cache[i] = fn()
|
||||
}
|
||||
|
||||
t = cache[(i-1)%n]
|
||||
return t
|
||||
}
|
||||
}
|
||||
143
vendor/github.com/influxdata/influxdb/stress/v2/statement/function_test.go
generated
vendored
Normal file
143
vendor/github.com/influxdata/influxdb/stress/v2/statement/function_test.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewStrRandStringer(t *testing.T) {
|
||||
function := newStrRandFunction()
|
||||
strRandStringer := function.NewStringer(10)
|
||||
s := strRandStringer()
|
||||
if len(s) != function.Argument {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", function.Argument, len(s))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewIntIncStringer(t *testing.T) {
|
||||
function := newIntIncFunction()
|
||||
intIncStringer := function.NewStringer(10)
|
||||
s := intIncStringer()
|
||||
if s != "0i" {
|
||||
t.Errorf("Expected: 0i\nGot: %v\n", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewIntRandStringer(t *testing.T) {
|
||||
function := newIntRandFunction()
|
||||
intRandStringer := function.NewStringer(10)
|
||||
s := intRandStringer()
|
||||
if parseInt(s[:len(s)-1]) > function.Argument {
|
||||
t.Errorf("Expected value below: %v\nGot value: %v\n", function.Argument, s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewFloatIncStringer(t *testing.T) {
|
||||
function := newFloatIncFunction()
|
||||
floatIncStringer := function.NewStringer(10)
|
||||
s := floatIncStringer()
|
||||
if parseFloat(s) != function.Argument {
|
||||
t.Errorf("Expected value: %v\nGot: %v\n", function.Argument, s)
|
||||
}
|
||||
}
|
||||
func TestNewFloatRandStringer(t *testing.T) {
|
||||
function := newFloatRandFunction()
|
||||
floatRandStringer := function.NewStringer(10)
|
||||
s := floatRandStringer()
|
||||
if parseFloat(s) > function.Argument {
|
||||
t.Errorf("Expected value below: %v\nGot value: %v\n", function.Argument, s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringersEval(t *testing.T) {
|
||||
// Make the *Function(s)
|
||||
strRandFunction := newStrRandFunction()
|
||||
intIncFunction := newIntIncFunction()
|
||||
intRandFunction := newIntRandFunction()
|
||||
floatIncFunction := newFloatIncFunction()
|
||||
floatRandFunction := newFloatRandFunction()
|
||||
// Make the *Stringer(s)
|
||||
strRandStringer := strRandFunction.NewStringer(10)
|
||||
intIncStringer := intIncFunction.NewStringer(10)
|
||||
intRandStringer := intRandFunction.NewStringer(10)
|
||||
floatIncStringer := floatIncFunction.NewStringer(10)
|
||||
floatRandStringer := floatRandFunction.NewStringer(10)
|
||||
// Make the *Stringers
|
||||
stringers := Stringers([]Stringer{strRandStringer, intIncStringer, intRandStringer, floatIncStringer, floatRandStringer})
|
||||
// Spoff the Time function
|
||||
// Call *Stringers.Eval
|
||||
values := stringers.Eval(spoofTime)
|
||||
// Check the strRandFunction
|
||||
if len(values[0].(string)) != strRandFunction.Argument {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", strRandFunction.Argument, len(values[0].(string)))
|
||||
}
|
||||
// Check the intIncFunction
|
||||
if values[1].(string) != "0i" {
|
||||
t.Errorf("Expected: 0i\nGot: %v\n", values[1].(string))
|
||||
}
|
||||
// Check the intRandFunction
|
||||
s := values[2].(string)
|
||||
if parseInt(s[:len(s)-1]) > intRandFunction.Argument {
|
||||
t.Errorf("Expected value below: %v\nGot value: %v\n", intRandFunction.Argument, s)
|
||||
}
|
||||
// Check the floatIncFunction
|
||||
if parseFloat(values[3].(string)) != floatIncFunction.Argument {
|
||||
t.Errorf("Expected value: %v\nGot: %v\n", floatIncFunction.Argument, values[3])
|
||||
}
|
||||
// Check the floatRandFunction
|
||||
if parseFloat(values[4].(string)) > floatRandFunction.Argument {
|
||||
t.Errorf("Expected value below: %v\nGot value: %v\n", floatRandFunction.Argument, values[4])
|
||||
}
|
||||
// Check the spoofTime func
|
||||
if values[5] != 8 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func spoofTime() int64 {
|
||||
return int64(8)
|
||||
}
|
||||
|
||||
func newStrRandFunction() *Function {
|
||||
return &Function{
|
||||
Type: "str",
|
||||
Fn: "rand",
|
||||
Argument: 8,
|
||||
Count: 1000,
|
||||
}
|
||||
}
|
||||
|
||||
func newIntIncFunction() *Function {
|
||||
return &Function{
|
||||
Type: "int",
|
||||
Fn: "inc",
|
||||
Argument: 0,
|
||||
Count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func newIntRandFunction() *Function {
|
||||
return &Function{
|
||||
Type: "int",
|
||||
Fn: "rand",
|
||||
Argument: 100,
|
||||
Count: 1000,
|
||||
}
|
||||
}
|
||||
|
||||
func newFloatIncFunction() *Function {
|
||||
return &Function{
|
||||
Type: "float",
|
||||
Fn: "inc",
|
||||
Argument: 0,
|
||||
Count: 1000,
|
||||
}
|
||||
}
|
||||
|
||||
func newFloatRandFunction() *Function {
|
||||
return &Function{
|
||||
Type: "float",
|
||||
Fn: "rand",
|
||||
Argument: 100,
|
||||
Count: 1000,
|
||||
}
|
||||
}
|
||||
40
vendor/github.com/influxdata/influxdb/stress/v2/statement/go.go
generated
vendored
Normal file
40
vendor/github.com/influxdata/influxdb/stress/v2/statement/go.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// GoStatement is a Statement Implementation to allow other statements to be run concurrently
|
||||
type GoStatement struct {
|
||||
Statement
|
||||
|
||||
StatementID string
|
||||
}
|
||||
|
||||
// SetID statisfies the Statement Interface
|
||||
func (i *GoStatement) SetID(s string) {
|
||||
i.StatementID = s
|
||||
}
|
||||
|
||||
// Run statisfies the Statement Interface
|
||||
func (i *GoStatement) Run(s *stressClient.StressTest) {
|
||||
// TODO: remove
|
||||
switch i.Statement.(type) {
|
||||
case *QueryStatement:
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
s.Add(1)
|
||||
go func() {
|
||||
i.Statement.Run(s)
|
||||
s.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
// Report statisfies the Statement Interface
|
||||
func (i *GoStatement) Report(s *stressClient.StressTest) string {
|
||||
return fmt.Sprintf("Go %v", i.Statement.Report(s))
|
||||
}
|
||||
41
vendor/github.com/influxdata/influxdb/stress/v2/statement/go_test.go
generated
vendored
Normal file
41
vendor/github.com/influxdata/influxdb/stress/v2/statement/go_test.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
func TestGoSetID(t *testing.T) {
|
||||
e := newTestGo()
|
||||
newID := "oaijnifo"
|
||||
e.SetID(newID)
|
||||
if e.StatementID != newID {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", newID, e.StatementID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoRun(t *testing.T) {
|
||||
e := newTestGo()
|
||||
s, _, _ := stressClient.NewTestStressTest()
|
||||
e.Run(s)
|
||||
if e == nil {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoReport(t *testing.T) {
|
||||
e := newTestGo()
|
||||
s, _, _ := stressClient.NewTestStressTest()
|
||||
report := e.Report(s)
|
||||
if report != "Go " {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", "Go ", report)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestGo() *GoStatement {
|
||||
return &GoStatement{
|
||||
Statement: newTestExec(),
|
||||
StatementID: "fooID",
|
||||
}
|
||||
}
|
||||
69
vendor/github.com/influxdata/influxdb/stress/v2/statement/influxql.go
generated
vendored
Normal file
69
vendor/github.com/influxdata/influxdb/stress/v2/statement/influxql.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// InfluxqlStatement is a Statement Implementation that allows statements that parse in InfluxQL to be passed directly to the target instance
|
||||
type InfluxqlStatement struct {
|
||||
StatementID string
|
||||
Query string
|
||||
Tracer *stressClient.Tracer
|
||||
}
|
||||
|
||||
func (i *InfluxqlStatement) tags() map[string]string {
|
||||
tags := make(map[string]string)
|
||||
return tags
|
||||
}
|
||||
|
||||
// SetID statisfies the Statement Interface
|
||||
func (i *InfluxqlStatement) SetID(s string) {
|
||||
i.StatementID = s
|
||||
}
|
||||
|
||||
// Run statisfies the Statement Interface
|
||||
func (i *InfluxqlStatement) Run(s *stressClient.StressTest) {
|
||||
|
||||
// Set the tracer
|
||||
i.Tracer = stressClient.NewTracer(i.tags())
|
||||
|
||||
// Make the Package
|
||||
p := stressClient.NewPackage(stressClient.Query, []byte(i.Query), i.StatementID, i.Tracer)
|
||||
|
||||
// Increment the tracer
|
||||
i.Tracer.Add(1)
|
||||
|
||||
// Send the Package
|
||||
s.SendPackage(p)
|
||||
|
||||
// Wait for all operations to finish
|
||||
i.Tracer.Wait()
|
||||
}
|
||||
|
||||
// Report statisfies the Statement Interface
|
||||
// No test coverage, fix
|
||||
func (i *InfluxqlStatement) Report(s *stressClient.StressTest) (out string) {
|
||||
allData := s.GetStatementResults(i.StatementID, "query")
|
||||
|
||||
iqlr := &influxQlReport{
|
||||
statement: i.Query,
|
||||
columns: allData[0].Series[0].Columns,
|
||||
values: allData[0].Series[0].Values,
|
||||
}
|
||||
|
||||
iqlr.responseTime = time.Duration(responseTimes(iqlr.columns, iqlr.values)[0].Value)
|
||||
|
||||
switch countSuccesses(iqlr.columns, iqlr.values) {
|
||||
case 0:
|
||||
iqlr.success = false
|
||||
case 1:
|
||||
iqlr.success = true
|
||||
default:
|
||||
log.Fatal("Error fetching response for InfluxQL statement")
|
||||
}
|
||||
|
||||
return iqlr.String()
|
||||
}
|
||||
44
vendor/github.com/influxdata/influxdb/stress/v2/statement/influxql_test.go
generated
vendored
Normal file
44
vendor/github.com/influxdata/influxdb/stress/v2/statement/influxql_test.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
func TestInfluxQlSetID(t *testing.T) {
|
||||
e := newTestInfluxQl()
|
||||
newID := "oaijnifo"
|
||||
e.SetID(newID)
|
||||
if e.StatementID != newID {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", newID, e.StatementID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfluxQlRun(t *testing.T) {
|
||||
e := newTestInfluxQl()
|
||||
s, packageCh, _ := stressClient.NewTestStressTest()
|
||||
go func() {
|
||||
for pkg := range packageCh {
|
||||
if pkg.T != stressClient.Query {
|
||||
t.Errorf("Expected package to be Query\nGot: %v", pkg.T)
|
||||
}
|
||||
if string(pkg.Body) != e.Query {
|
||||
t.Errorf("Expected query: %v\nGot: %v", e.Query, string(pkg.Body))
|
||||
}
|
||||
if pkg.StatementID != e.StatementID {
|
||||
t.Errorf("Expected statementID: %v\nGot: %v", e.StatementID, pkg.StatementID)
|
||||
}
|
||||
pkg.Tracer.Done()
|
||||
}
|
||||
}()
|
||||
e.Run(s)
|
||||
}
|
||||
|
||||
func newTestInfluxQl() *InfluxqlStatement {
|
||||
return &InfluxqlStatement{
|
||||
Query: "CREATE DATABASE foo",
|
||||
Tracer: stressClient.NewTracer(make(map[string]string)),
|
||||
StatementID: "fooID",
|
||||
}
|
||||
}
|
||||
214
vendor/github.com/influxdata/influxdb/stress/v2/statement/insert.go
generated
vendored
Normal file
214
vendor/github.com/influxdata/influxdb/stress/v2/statement/insert.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// InsertStatement is a Statement Implementation that creates points to be written to the target InfluxDB instance
|
||||
type InsertStatement struct {
|
||||
TestID string
|
||||
StatementID string
|
||||
|
||||
// Statement Name
|
||||
Name string
|
||||
|
||||
// Template string for points. Filled by the output of stringers
|
||||
TemplateString string
|
||||
|
||||
// TagCount is used to find the number of series in the dataset
|
||||
TagCount int
|
||||
|
||||
// The Tracer prevents InsertStatement.Run() from returning early
|
||||
Tracer *stressClient.Tracer
|
||||
|
||||
// Timestamp is #points to write and percision
|
||||
Timestamp *Timestamp
|
||||
|
||||
// Templates turn into stringers
|
||||
Templates Templates
|
||||
stringers Stringers
|
||||
|
||||
// Number of series in this insert Statement
|
||||
series int
|
||||
|
||||
// Returns the proper time for the next point
|
||||
time func() int64
|
||||
|
||||
// Concurrency utiliities
|
||||
sync.WaitGroup
|
||||
sync.Mutex
|
||||
|
||||
// Timer for runtime and pps calculation
|
||||
runtime time.Duration
|
||||
}
|
||||
|
||||
func (i *InsertStatement) tags() map[string]string {
|
||||
tags := map[string]string{
|
||||
"number_fields": i.numFields(),
|
||||
"number_series": fmtInt(i.series),
|
||||
"number_points_write": fmtInt(i.Timestamp.Count),
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
// SetID statisfies the Statement Interface
|
||||
func (i *InsertStatement) SetID(s string) {
|
||||
i.StatementID = s
|
||||
}
|
||||
|
||||
// SetVars sets up the environment for InsertStatement to call it's Run function
|
||||
func (i *InsertStatement) SetVars(s *stressClient.StressTest) chan<- string {
|
||||
// Set the #series at 1 to start
|
||||
i.series = 1
|
||||
|
||||
// Num series is the product of the cardinality of the tags
|
||||
for _, tmpl := range i.Templates[0:i.TagCount] {
|
||||
i.series *= tmpl.numSeries()
|
||||
}
|
||||
|
||||
// make stringers from the templates
|
||||
i.stringers = i.Templates.Init(i.series)
|
||||
|
||||
// Set the time function, keeps track of 'time' of the points being created
|
||||
i.time = i.Timestamp.Time(s.StartDate, i.series, s.Precision)
|
||||
|
||||
// Set a commune on the StressTest
|
||||
s.Lock()
|
||||
comCh := s.SetCommune(i.Name)
|
||||
s.Unlock()
|
||||
|
||||
// Set the tracer
|
||||
i.Tracer = stressClient.NewTracer(i.tags())
|
||||
|
||||
return comCh
|
||||
}
|
||||
|
||||
// Run statisfies the Statement Interface
|
||||
func (i *InsertStatement) Run(s *stressClient.StressTest) {
|
||||
|
||||
// Set variables on the InsertStatement and make the comCh
|
||||
comCh := i.SetVars(s)
|
||||
|
||||
// TODO: Refactor to eleminate the ctr
|
||||
// Start the counter
|
||||
ctr := 0
|
||||
|
||||
// Create the first bytes buffer
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
|
||||
runtime := time.Now()
|
||||
|
||||
for k := 0; k < i.Timestamp.Count; k++ {
|
||||
|
||||
// Increment the counter. ctr == k + 1?
|
||||
ctr++
|
||||
|
||||
// Make the point from the template string and the stringers
|
||||
point := fmt.Sprintf(i.TemplateString, i.stringers.Eval(i.time)...)
|
||||
|
||||
// Add the string to the buffer
|
||||
buf.WriteString(point)
|
||||
// Add a newline char to seperate the points
|
||||
buf.WriteString("\n")
|
||||
|
||||
// If len(batch) == batchSize then send it
|
||||
if ctr%s.BatchSize == 0 && ctr != 0 {
|
||||
b := buf.Bytes()
|
||||
// Trimming the trailing newline character
|
||||
b = b[0 : len(b)-1]
|
||||
|
||||
// Create the package
|
||||
p := stressClient.NewPackage(stressClient.Write, b, i.StatementID, i.Tracer)
|
||||
|
||||
// Use Tracer to wait for all operations to finish
|
||||
i.Tracer.Add(1)
|
||||
|
||||
// Send the package
|
||||
s.SendPackage(p)
|
||||
|
||||
// Reset the bytes Buffer
|
||||
temp := bytes.NewBuffer([]byte{})
|
||||
buf = temp
|
||||
}
|
||||
|
||||
// TODO: Racy
|
||||
// Has to do with InsertStatement and QueryStatement communication
|
||||
if len(comCh) < cap(comCh) {
|
||||
select {
|
||||
case comCh <- point:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If There are additional points remaining in the buffer send them before exiting
|
||||
if buf.Len() != 0 {
|
||||
b := buf.Bytes()
|
||||
// Trimming the trailing newline character
|
||||
b = b[0 : len(b)-1]
|
||||
|
||||
// Create the package
|
||||
p := stressClient.NewPackage(stressClient.Write, b, i.StatementID, i.Tracer)
|
||||
|
||||
// Use Tracer to wait for all operations to finish
|
||||
i.Tracer.Add(1)
|
||||
|
||||
// Send the package
|
||||
s.SendPackage(p)
|
||||
}
|
||||
|
||||
// Wait for all tracers to decrement
|
||||
i.Tracer.Wait()
|
||||
|
||||
// Stop the timer
|
||||
i.runtime = time.Since(runtime)
|
||||
}
|
||||
|
||||
// Report statisfies the Statement Interface
|
||||
func (i *InsertStatement) Report(s *stressClient.StressTest) string {
|
||||
// Pull data via StressTest client
|
||||
allData := s.GetStatementResults(i.StatementID, "write")
|
||||
|
||||
if allData == nil || allData[0].Series == nil {
|
||||
log.Fatalf("No data returned for write report\n Statement Name: %v\n Statement ID: %v\n", i.Name, i.StatementID)
|
||||
}
|
||||
|
||||
ir := &insertReport{
|
||||
name: i.Name,
|
||||
columns: allData[0].Series[0].Columns,
|
||||
values: allData[0].Series[0].Values,
|
||||
}
|
||||
|
||||
responseTimes := responseTimes(ir.columns, ir.values)
|
||||
|
||||
ir.percentile = percentile(responseTimes)
|
||||
ir.avgResponseTime = avgDuration(responseTimes)
|
||||
ir.stdDevResponseTime = stddevDuration(responseTimes)
|
||||
ir.pointsPerSecond = int(float64(i.Timestamp.Count) / i.runtime.Seconds())
|
||||
ir.numRetries = countRetries(ir.columns, ir.values)
|
||||
ir.successfulWrites = countSuccesses(ir.columns, ir.values)
|
||||
ir.avgRequestBytes = numberBytes(ir.columns, ir.values)
|
||||
|
||||
return ir.String()
|
||||
}
|
||||
|
||||
func (i *InsertStatement) numFields() string {
|
||||
pt := strings.Split(i.TemplateString, " ")
|
||||
fields := strings.Split(pt[1], ",")
|
||||
return fmtInt(len(fields))
|
||||
}
|
||||
|
||||
func fmtInt(i int) string {
|
||||
return strconv.FormatInt(int64(i), 10)
|
||||
}
|
||||
50
vendor/github.com/influxdata/influxdb/stress/v2/statement/insert_test.go
generated
vendored
Normal file
50
vendor/github.com/influxdata/influxdb/stress/v2/statement/insert_test.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
func TestInsertSetID(t *testing.T) {
|
||||
e := newTestInsert()
|
||||
newID := "oaijnifo"
|
||||
e.SetID(newID)
|
||||
if e.StatementID != newID {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", newID, e.StatementID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInsertRun(t *testing.T) {
|
||||
i := newTestInsert()
|
||||
s, packageCh, _ := stressClient.NewTestStressTest()
|
||||
// Listen to the other side of the directiveCh
|
||||
go func() {
|
||||
for pkg := range packageCh {
|
||||
countPoints := i.Timestamp.Count
|
||||
batchSize := s.BatchSize
|
||||
got := len(strings.Split(string(pkg.Body), "\n"))
|
||||
switch got {
|
||||
case countPoints % batchSize:
|
||||
case batchSize:
|
||||
default:
|
||||
t.Errorf("countPoints: %v\nbatchSize: %v\ngot: %v\n", countPoints, batchSize, got)
|
||||
}
|
||||
pkg.Tracer.Done()
|
||||
}
|
||||
}()
|
||||
i.Run(s)
|
||||
}
|
||||
|
||||
func newTestInsert() *InsertStatement {
|
||||
return &InsertStatement{
|
||||
TestID: "foo_test",
|
||||
StatementID: "foo_ID",
|
||||
Name: "foo_name",
|
||||
TemplateString: "cpu,%v %v %v",
|
||||
Timestamp: newTestTimestamp(),
|
||||
Templates: newTestTemplates(),
|
||||
TagCount: 1,
|
||||
}
|
||||
}
|
||||
161
vendor/github.com/influxdata/influxdb/stress/v2/statement/query.go
generated
vendored
Normal file
161
vendor/github.com/influxdata/influxdb/stress/v2/statement/query.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/models"
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// QueryStatement is a Statement Implementation to run queries on the target InfluxDB instance
|
||||
type QueryStatement struct {
|
||||
StatementID string
|
||||
Name string
|
||||
|
||||
// TemplateString is a query template that can be filled in by Args
|
||||
TemplateString string
|
||||
Args []string
|
||||
|
||||
// Number of queries to run
|
||||
Count int
|
||||
|
||||
// Tracer for tracking returns
|
||||
Tracer *stressClient.Tracer
|
||||
|
||||
// track time for all queries
|
||||
runtime time.Duration
|
||||
}
|
||||
|
||||
// This function adds tags to the recording points
|
||||
func (i *QueryStatement) tags() map[string]string {
|
||||
tags := make(map[string]string)
|
||||
return tags
|
||||
}
|
||||
|
||||
// SetID statisfies the Statement Interface
|
||||
func (i *QueryStatement) SetID(s string) {
|
||||
i.StatementID = s
|
||||
}
|
||||
|
||||
// Run statisfies the Statement Interface
|
||||
func (i *QueryStatement) Run(s *stressClient.StressTest) {
|
||||
|
||||
i.Tracer = stressClient.NewTracer(i.tags())
|
||||
|
||||
vals := make(map[string]interface{})
|
||||
|
||||
var point models.Point
|
||||
|
||||
runtime := time.Now()
|
||||
|
||||
for j := 0; j < i.Count; j++ {
|
||||
|
||||
// If the query is a simple query, send it.
|
||||
if len(i.Args) == 0 {
|
||||
b := []byte(i.TemplateString)
|
||||
|
||||
// Make the package
|
||||
p := stressClient.NewPackage(stressClient.Query, b, i.StatementID, i.Tracer)
|
||||
|
||||
// Increment the tracer
|
||||
i.Tracer.Add(1)
|
||||
|
||||
// Send the package
|
||||
s.SendPackage(p)
|
||||
|
||||
} else {
|
||||
// Otherwise cherry pick field values from the commune?
|
||||
|
||||
// TODO: Currently the program lock up here if s.GetPoint
|
||||
// cannot return a value, which can happen.
|
||||
// See insert.go
|
||||
s.Lock()
|
||||
point = s.GetPoint(i.Name, s.Precision)
|
||||
s.Unlock()
|
||||
|
||||
setMapValues(vals, point)
|
||||
|
||||
// Set the template string with args from the commune
|
||||
b := []byte(fmt.Sprintf(i.TemplateString, setArgs(vals, i.Args)...))
|
||||
|
||||
// Make the package
|
||||
p := stressClient.NewPackage(stressClient.Query, b, i.StatementID, i.Tracer)
|
||||
|
||||
// Increment the tracer
|
||||
i.Tracer.Add(1)
|
||||
|
||||
// Send the package
|
||||
s.SendPackage(p)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all operations to finish
|
||||
i.Tracer.Wait()
|
||||
|
||||
// Stop time timer
|
||||
i.runtime = time.Since(runtime)
|
||||
}
|
||||
|
||||
// Report statisfies the Statement Interface
|
||||
func (i *QueryStatement) Report(s *stressClient.StressTest) string {
|
||||
// Pull data via StressTest client
|
||||
allData := s.GetStatementResults(i.StatementID, "query")
|
||||
|
||||
if len(allData) == 0 || allData[0].Series == nil {
|
||||
log.Fatalf("No data returned for query report\n Statement Name: %v\n Statement ID: %v\n", i.Name, i.StatementID)
|
||||
}
|
||||
|
||||
qr := &queryReport{
|
||||
name: i.Name,
|
||||
columns: allData[0].Series[0].Columns,
|
||||
values: allData[0].Series[0].Values,
|
||||
}
|
||||
|
||||
responseTimes := responseTimes(qr.columns, qr.values)
|
||||
|
||||
qr.percentile = percentile(responseTimes)
|
||||
qr.avgResponseTime = avgDuration(responseTimes)
|
||||
qr.stdDevResponseTime = stddevDuration(responseTimes)
|
||||
qr.successfulReads = countSuccesses(qr.columns, qr.values)
|
||||
qr.responseBytes = numberBytes(qr.columns, qr.values)
|
||||
|
||||
return qr.String()
|
||||
}
|
||||
|
||||
func getRandomTagPair(m models.Tags) string {
|
||||
for k, v := range m {
|
||||
return fmt.Sprintf("%v='%v'", k, v)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func getRandomFieldKey(m map[string]interface{}) string {
|
||||
for k := range m {
|
||||
return fmt.Sprintf("%v", k)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func setMapValues(m map[string]interface{}, p models.Point) {
|
||||
fields, err := p.Fields()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m["%f"] = getRandomFieldKey(fields)
|
||||
m["%m"] = string(p.Name())
|
||||
m["%t"] = getRandomTagPair(p.Tags())
|
||||
m["%a"] = p.UnixNano()
|
||||
}
|
||||
|
||||
func setArgs(m map[string]interface{}, args []string) []interface{} {
|
||||
values := make([]interface{}, len(args))
|
||||
for i, arg := range args {
|
||||
values[i] = m[arg]
|
||||
}
|
||||
return values
|
||||
}
|
||||
42
vendor/github.com/influxdata/influxdb/stress/v2/statement/query_test.go
generated
vendored
Normal file
42
vendor/github.com/influxdata/influxdb/stress/v2/statement/query_test.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
func TestQuerySetID(t *testing.T) {
|
||||
e := newTestQuery()
|
||||
newID := "oaijnifo"
|
||||
e.SetID(newID)
|
||||
if e.StatementID != newID {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", newID, e.StatementID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryRun(t *testing.T) {
|
||||
i := newTestQuery()
|
||||
s, packageCh, _ := stressClient.NewTestStressTest()
|
||||
// Listen to the other side of the directiveCh
|
||||
go func() {
|
||||
for pkg := range packageCh {
|
||||
if i.TemplateString != string(pkg.Body) {
|
||||
t.Fail()
|
||||
}
|
||||
pkg.Tracer.Done()
|
||||
}
|
||||
}()
|
||||
i.Run(s)
|
||||
}
|
||||
|
||||
func newTestQuery() *QueryStatement {
|
||||
return &QueryStatement{
|
||||
StatementID: "foo_ID",
|
||||
Name: "foo_name",
|
||||
TemplateString: "SELECT count(value) FROM cpu",
|
||||
Args: []string{},
|
||||
Count: 5,
|
||||
Tracer: stressClient.NewTracer(map[string]string{}),
|
||||
}
|
||||
}
|
||||
237
vendor/github.com/influxdata/influxdb/stress/v2/statement/report.go
generated
vendored
Normal file
237
vendor/github.com/influxdata/influxdb/stress/v2/statement/report.go
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
influx "github.com/influxdata/influxdb/client/v2"
|
||||
)
|
||||
|
||||
// TODO: Refactor this file to utilize a common interface
|
||||
// This will make adding new reports easier in the future
|
||||
|
||||
// Runs performance numbers for insert statements
|
||||
type insertReport struct {
|
||||
name string
|
||||
numRetries int
|
||||
pointsPerSecond int
|
||||
successfulWrites int
|
||||
avgRequestBytes int
|
||||
avgResponseTime time.Duration
|
||||
stdDevResponseTime time.Duration
|
||||
percentile time.Duration
|
||||
|
||||
columns []string
|
||||
values [][]interface{}
|
||||
}
|
||||
|
||||
// Returns the version of the report that is output to STDOUT
|
||||
func (ir *insertReport) String() string {
|
||||
tmplString := `Write Statement: %v
|
||||
Points/Sec: %v
|
||||
Resp Time Average: %v
|
||||
Resp Time Standard Deviation: %v
|
||||
95th Percentile Write Response: %v
|
||||
Average Request Bytes: %v
|
||||
Successful Write Reqs: %v
|
||||
Retries: %v`
|
||||
|
||||
return fmt.Sprintf(tmplString,
|
||||
ir.name,
|
||||
ir.pointsPerSecond,
|
||||
ir.avgResponseTime,
|
||||
ir.stdDevResponseTime,
|
||||
ir.percentile,
|
||||
ir.avgRequestBytes,
|
||||
ir.successfulWrites,
|
||||
ir.numRetries)
|
||||
}
|
||||
|
||||
// Returns a point representation of the report to be written to the ResultsDB
|
||||
func (ir *insertReport) Point() *influx.Point {
|
||||
measurement := "testDefault"
|
||||
tags := map[string]string{}
|
||||
fields := map[string]interface{}{"field": "blank"}
|
||||
point, err := influx.NewPoint(measurement, tags, fields, time.Now())
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating insertReport point\n measurement: %v\n tags: %v\n fields: %v\n error: %v\n", measurement, tags, fields, err)
|
||||
}
|
||||
return point
|
||||
}
|
||||
|
||||
// Runs performance numbers for query statements
|
||||
type queryReport struct {
|
||||
name string
|
||||
successfulReads int
|
||||
responseBytes int
|
||||
stddevResponseBytes int
|
||||
avgResponseTime time.Duration
|
||||
stdDevResponseTime time.Duration
|
||||
percentile time.Duration
|
||||
|
||||
columns []string
|
||||
values [][]interface{}
|
||||
}
|
||||
|
||||
// Returns the version of the report that is output to STDOUT
|
||||
func (qr *queryReport) String() string {
|
||||
tmplString := `Query Statement: %v
|
||||
Resp Time Average: %v
|
||||
Resp Time Standard Deviation: %v
|
||||
95th Percentile Read Response: %v
|
||||
Query Resp Bytes Average: %v bytes
|
||||
Successful Queries: %v`
|
||||
|
||||
return fmt.Sprintf(tmplString,
|
||||
qr.name,
|
||||
qr.avgResponseTime,
|
||||
qr.stdDevResponseTime,
|
||||
qr.percentile,
|
||||
qr.responseBytes,
|
||||
qr.successfulReads)
|
||||
}
|
||||
|
||||
// Returns a point representation of the report to be written to the ResultsDB
|
||||
func (qr *queryReport) Point() *influx.Point {
|
||||
measurement := "testDefault"
|
||||
tags := map[string]string{}
|
||||
fields := map[string]interface{}{"field": "blank"}
|
||||
point, err := influx.NewPoint(measurement, tags, fields, time.Now())
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating queryReport point\n measurement: %v\n tags: %v\n fields: %v\n error: %v\n", measurement, tags, fields, err)
|
||||
}
|
||||
return point
|
||||
}
|
||||
|
||||
// Runs performance numbers for InfluxQL statements
|
||||
type influxQlReport struct {
|
||||
statement string
|
||||
responseTime time.Duration
|
||||
success bool
|
||||
|
||||
columns []string
|
||||
values [][]interface{}
|
||||
}
|
||||
|
||||
// Returns the version of the report that is output to STDOUT
|
||||
func (iqlr *influxQlReport) String() string {
|
||||
// Fancy format success
|
||||
var success string
|
||||
switch iqlr.success {
|
||||
case true:
|
||||
success = "[√]"
|
||||
case false:
|
||||
success = "[X]"
|
||||
}
|
||||
return fmt.Sprintf("%v '%v' -> %v", success, iqlr.statement, iqlr.responseTime)
|
||||
}
|
||||
|
||||
// Returns a point representation of the report to be written to the ResultsDB
|
||||
func (iqlr *influxQlReport) Point() *influx.Point {
|
||||
measurement := "testDefault"
|
||||
tags := map[string]string{}
|
||||
fields := map[string]interface{}{"field": "blank"}
|
||||
point, err := influx.NewPoint(measurement, tags, fields, time.Now())
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating influxQL point\n measurement: %v\n tags: %v\n fields: %v\n error: %v\n", measurement, tags, fields, err)
|
||||
}
|
||||
return point
|
||||
}
|
||||
|
||||
// Given a field or tag name this function returns the index where the values are found
|
||||
func getColumnIndex(col string, columns []string) int {
|
||||
index := -1
|
||||
for i, column := range columns {
|
||||
if column == col {
|
||||
index = i
|
||||
}
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// Given a full set of results pulls the average num_bytes
|
||||
func numberBytes(columns []string, values [][]interface{}) int {
|
||||
out := 0
|
||||
index := getColumnIndex("num_bytes", columns)
|
||||
for _, val := range values {
|
||||
reqBytes, err := val[index].(json.Number).Int64()
|
||||
if err != nil {
|
||||
log.Fatalf("Error coercing json.Number to Int64\n json.Number:%v\n error: %v\n", val[index], err)
|
||||
}
|
||||
out += int(reqBytes)
|
||||
}
|
||||
return out / len(values)
|
||||
}
|
||||
|
||||
// Counts the number of 200(query) or 204(write) responses and returns them
|
||||
func countSuccesses(columns []string, values [][]interface{}) (out int) {
|
||||
index := getColumnIndex("status_code", columns)
|
||||
for _, val := range values {
|
||||
status, err := val[index].(json.Number).Int64()
|
||||
if err != nil {
|
||||
log.Fatalf("Error coercing json.Number to Int64\n json.Number:%v\n error: %v\n", val[index], err)
|
||||
}
|
||||
if status == 204 || status == 200 {
|
||||
out++
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Counts number of 500 status codes
|
||||
func countRetries(columns []string, values [][]interface{}) (out int) {
|
||||
index := getColumnIndex("status_code", columns)
|
||||
for _, val := range values {
|
||||
status, err := val[index].(json.Number).Int64()
|
||||
if err != nil {
|
||||
log.Fatalf("Error coercing json.Number to Int64\n json.Number:%v\n error: %v\n", val[index], err)
|
||||
}
|
||||
if status == 500 {
|
||||
out++
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Pulls out the response_time_ns values and formats them into ResponseTimes for reporting
|
||||
func responseTimes(columns []string, values [][]interface{}) (rs ResponseTimes) {
|
||||
rs = make([]ResponseTime, 0)
|
||||
index := getColumnIndex("response_time_ns", columns)
|
||||
for _, val := range values {
|
||||
respTime, err := val[index].(json.Number).Int64()
|
||||
if err != nil {
|
||||
log.Fatalf("Error coercing json.Number to Int64\n json.Number:%v\n error: %v\n", val[index], err)
|
||||
}
|
||||
rs = append(rs, NewResponseTime(int(respTime)))
|
||||
}
|
||||
return rs
|
||||
}
|
||||
|
||||
// Returns the 95th perecntile response time
|
||||
func percentile(rs ResponseTimes) time.Duration {
|
||||
sort.Sort(rs)
|
||||
return time.Duration(rs[(len(rs) * 19 / 20)].Value)
|
||||
}
|
||||
|
||||
// Returns the average response time
|
||||
func avgDuration(rs ResponseTimes) (out time.Duration) {
|
||||
for _, t := range rs {
|
||||
out += time.Duration(t.Value)
|
||||
}
|
||||
return out / time.Duration(len(rs))
|
||||
}
|
||||
|
||||
// Returns the standard deviation of a sample of response times
|
||||
func stddevDuration(rs ResponseTimes) (out time.Duration) {
|
||||
avg := avgDuration(rs)
|
||||
|
||||
for _, t := range rs {
|
||||
out += (avg - time.Duration(t.Value)) * (avg - time.Duration(t.Value))
|
||||
}
|
||||
|
||||
return time.Duration(int64(math.Sqrt(float64(out) / float64(len(rs)))))
|
||||
}
|
||||
210
vendor/github.com/influxdata/influxdb/stress/v2/statement/report_test.go
generated
vendored
Normal file
210
vendor/github.com/influxdata/influxdb/stress/v2/statement/report_test.go
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestInsertReportString(t *testing.T) {
|
||||
ir := newTestInsertReport()
|
||||
tmplString := `Write Statement: %v
|
||||
Points/Sec: %v
|
||||
Resp Time Average: %v
|
||||
Resp Time Standard Deviation: %v
|
||||
95th Percentile Write Response: %v
|
||||
Average Request Bytes: %v
|
||||
Successful Write Reqs: %v
|
||||
Retries: %v`
|
||||
expected := fmt.Sprintf(tmplString,
|
||||
ir.name,
|
||||
ir.pointsPerSecond,
|
||||
ir.avgResponseTime,
|
||||
ir.stdDevResponseTime,
|
||||
ir.percentile,
|
||||
ir.avgRequestBytes,
|
||||
ir.successfulWrites,
|
||||
ir.numRetries)
|
||||
got := ir.String()
|
||||
if expected != got {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestInsertReportPoint(t *testing.T) {
|
||||
ir := newTestInsertReport()
|
||||
expected := "testDefault"
|
||||
got := strings.Split(ir.Point().String(), " ")[0]
|
||||
if expected != got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryReportString(t *testing.T) {
|
||||
qr := newTestQueryReport()
|
||||
tmplString := `Query Statement: %v
|
||||
Resp Time Average: %v
|
||||
Resp Time Standard Deviation: %v
|
||||
95th Percentile Read Response: %v
|
||||
Query Resp Bytes Average: %v bytes
|
||||
Successful Queries: %v`
|
||||
expected := fmt.Sprintf(tmplString,
|
||||
qr.name,
|
||||
qr.avgResponseTime,
|
||||
qr.stdDevResponseTime,
|
||||
qr.percentile,
|
||||
qr.responseBytes,
|
||||
qr.successfulReads)
|
||||
got := qr.String()
|
||||
if expected != got {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryReportPoint(t *testing.T) {
|
||||
qr := newTestQueryReport()
|
||||
expected := "testDefault"
|
||||
got := strings.Split(qr.Point().String(), " ")[0]
|
||||
if expected != got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfluxQLReportString(t *testing.T) {
|
||||
iqlr := newTestInfluxQLReport()
|
||||
expected := fmt.Sprintf("[X] '%v' -> %v", iqlr.statement, iqlr.responseTime)
|
||||
got := iqlr.String()
|
||||
if expected != got {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfluxQLReportPoint(t *testing.T) {
|
||||
iqlr := newTestInfluxQLReport()
|
||||
expected := "testDefault"
|
||||
got := strings.Split(iqlr.Point().String(), " ")[0]
|
||||
if expected != got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestInsertReport() *insertReport {
|
||||
return &insertReport{
|
||||
name: "foo_name",
|
||||
numRetries: 0,
|
||||
pointsPerSecond: 500000,
|
||||
successfulWrites: 20000,
|
||||
avgRequestBytes: 18932,
|
||||
avgResponseTime: time.Duration(int64(20000)),
|
||||
stdDevResponseTime: time.Duration(int64(20000)),
|
||||
percentile: time.Duration(int64(20000)),
|
||||
}
|
||||
}
|
||||
|
||||
func newTestQueryReport() *queryReport {
|
||||
return &queryReport{
|
||||
name: "foo_name",
|
||||
successfulReads: 2000,
|
||||
responseBytes: 39049,
|
||||
stddevResponseBytes: 9091284,
|
||||
avgResponseTime: 139082,
|
||||
stdDevResponseTime: 29487,
|
||||
percentile: 8273491,
|
||||
}
|
||||
}
|
||||
|
||||
func newTestInfluxQLReport() *influxQlReport {
|
||||
return &influxQlReport{
|
||||
statement: "foo_name",
|
||||
responseTime: time.Duration(int64(20000)),
|
||||
success: false,
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetColumnIndex(t *testing.T) {
|
||||
col := "thing"
|
||||
columns := []string{"thing"}
|
||||
expected := 0
|
||||
got := getColumnIndex(col, columns)
|
||||
if expected != got {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumberBytes(t *testing.T) {
|
||||
columns := []string{"num_bytes"}
|
||||
values := [][]interface{}{[]interface{}{json.Number("1")}}
|
||||
expected := 1
|
||||
got := numberBytes(columns, values)
|
||||
if expected != got {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestCountSuccesses(t *testing.T) {
|
||||
columns := []string{"status_code"}
|
||||
values := [][]interface{}{[]interface{}{json.Number("200")}}
|
||||
expected := 1
|
||||
got := countSuccesses(columns, values)
|
||||
if expected != got {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestCountRetries(t *testing.T) {
|
||||
columns := []string{"status_code"}
|
||||
values := [][]interface{}{[]interface{}{json.Number("500")}}
|
||||
expected := 1
|
||||
got := countRetries(columns, values)
|
||||
if expected != got {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestResponseTimes(t *testing.T) {
|
||||
columns := []string{"response_time_ns"}
|
||||
values := [][]interface{}{[]interface{}{json.Number("380")}}
|
||||
expected := ResponseTimes([]ResponseTime{NewResponseTime(380)})
|
||||
got := responseTimes(columns, values)
|
||||
if expected[0].Value != got[0].Value {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestPercentile(t *testing.T) {
|
||||
rs := createTestResponseTimes()
|
||||
expected := time.Duration(21)
|
||||
got := percentile(rs)
|
||||
if expected != got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAvgDuration(t *testing.T) {
|
||||
rs := createTestResponseTimes()
|
||||
expected := time.Duration(11)
|
||||
got := avgDuration(rs)
|
||||
if expected != got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStddevDuration(t *testing.T) {
|
||||
rs := createTestResponseTimes()
|
||||
expected := time.Duration(6)
|
||||
got := stddevDuration(rs)
|
||||
if expected != got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func createTestResponseTimes() ResponseTimes {
|
||||
rstms := []int{1, 2, 3, 4, 5, 6, 7, 13, 14, 15, 16, 17, 18, 19, 8, 9, 10, 11, 12, 20, 21, 22}
|
||||
rs := []ResponseTime{}
|
||||
for _, rst := range rstms {
|
||||
rs = append(rs, NewResponseTime(rst))
|
||||
}
|
||||
return rs
|
||||
}
|
||||
40
vendor/github.com/influxdata/influxdb/stress/v2/statement/response_time.go
generated
vendored
Normal file
40
vendor/github.com/influxdata/influxdb/stress/v2/statement/response_time.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ResponseTime is a struct that contains `Value`
|
||||
// `Time` pairing.
|
||||
type ResponseTime struct {
|
||||
Value int
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
// NewResponseTime returns a new response time
|
||||
// with value `v` and time `time.Now()`.
|
||||
func NewResponseTime(v int) ResponseTime {
|
||||
r := ResponseTime{Value: v, Time: time.Now()}
|
||||
return r
|
||||
}
|
||||
|
||||
// ResponseTimes is a slice of response times
|
||||
type ResponseTimes []ResponseTime
|
||||
|
||||
// Implements the `Len` method for the
|
||||
// sort.Interface type
|
||||
func (rs ResponseTimes) Len() int {
|
||||
return len(rs)
|
||||
}
|
||||
|
||||
// Implements the `Less` method for the
|
||||
// sort.Interface type
|
||||
func (rs ResponseTimes) Less(i, j int) bool {
|
||||
return rs[i].Value < rs[j].Value
|
||||
}
|
||||
|
||||
// Implements the `Swap` method for the
|
||||
// sort.Interface type
|
||||
func (rs ResponseTimes) Swap(i, j int) {
|
||||
rs[i], rs[j] = rs[j], rs[i]
|
||||
}
|
||||
45
vendor/github.com/influxdata/influxdb/stress/v2/statement/response_time_test.go
generated
vendored
Normal file
45
vendor/github.com/influxdata/influxdb/stress/v2/statement/response_time_test.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewResponseTime(t *testing.T) {
|
||||
value := 100000
|
||||
rs := NewResponseTime(value)
|
||||
if rs.Value != value {
|
||||
t.Errorf("expected: %v\ngot: %v\n", value, rs.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func newResponseTimes() ResponseTimes {
|
||||
return []ResponseTime{
|
||||
NewResponseTime(100),
|
||||
NewResponseTime(10),
|
||||
}
|
||||
}
|
||||
|
||||
func TestResponseTimeLen(t *testing.T) {
|
||||
rs := newResponseTimes()
|
||||
if rs.Len() != 2 {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestResponseTimeLess(t *testing.T) {
|
||||
rs := newResponseTimes()
|
||||
less := rs.Less(1, 0)
|
||||
if !less {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestResponseTimeSwap(t *testing.T) {
|
||||
rs := newResponseTimes()
|
||||
rs0 := rs[0]
|
||||
rs1 := rs[1]
|
||||
rs.Swap(0, 1)
|
||||
if rs0 != rs[1] || rs1 != rs[0] {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
59
vendor/github.com/influxdata/influxdb/stress/v2/statement/set.go
generated
vendored
Normal file
59
vendor/github.com/influxdata/influxdb/stress/v2/statement/set.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// SetStatement set state variables for the test
|
||||
type SetStatement struct {
|
||||
Var string
|
||||
Value string
|
||||
|
||||
StatementID string
|
||||
|
||||
Tracer *stressClient.Tracer
|
||||
}
|
||||
|
||||
// SetID statisfies the Statement Interface
|
||||
func (i *SetStatement) SetID(s string) {
|
||||
i.StatementID = s
|
||||
}
|
||||
|
||||
// Run statisfies the Statement Interface
|
||||
func (i *SetStatement) Run(s *stressClient.StressTest) {
|
||||
i.Tracer = stressClient.NewTracer(make(map[string]string))
|
||||
d := stressClient.NewDirective(strings.ToLower(i.Var), strings.ToLower(i.Value), i.Tracer)
|
||||
switch d.Property {
|
||||
// Needs to be set on both StressTest and stressClient
|
||||
// Set the write percison for points generated
|
||||
case "precision":
|
||||
s.Precision = d.Value
|
||||
i.Tracer.Add(1)
|
||||
s.SendDirective(d)
|
||||
// Lives on StressTest
|
||||
// Set the date for the first point entered into the database
|
||||
case "startdate":
|
||||
s.Lock()
|
||||
s.StartDate = d.Value
|
||||
s.Unlock()
|
||||
// Lives on StressTest
|
||||
// Set the BatchSize for writes
|
||||
case "batchsize":
|
||||
s.Lock()
|
||||
s.BatchSize = parseInt(d.Value)
|
||||
s.Unlock()
|
||||
// All other variables live on stressClient
|
||||
default:
|
||||
i.Tracer.Add(1)
|
||||
s.SendDirective(d)
|
||||
}
|
||||
i.Tracer.Wait()
|
||||
}
|
||||
|
||||
// Report statisfies the Statement Interface
|
||||
func (i *SetStatement) Report(s *stressClient.StressTest) string {
|
||||
return fmt.Sprintf("SET %v = '%v'", i.Var, i.Value)
|
||||
}
|
||||
92
vendor/github.com/influxdata/influxdb/stress/v2/statement/set_test.go
generated
vendored
Normal file
92
vendor/github.com/influxdata/influxdb/stress/v2/statement/set_test.go
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
func TestSetSetID(t *testing.T) {
|
||||
e := newTestSet("database", "foo")
|
||||
newID := "oaijnifo"
|
||||
e.SetID(newID)
|
||||
if e.StatementID != newID {
|
||||
t.Errorf("Expected: %v\nGot: %v\n", newID, e.StatementID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetRun(t *testing.T) {
|
||||
properties := []string{
|
||||
"precision",
|
||||
"startdate",
|
||||
"batchsize",
|
||||
"resultsaddress",
|
||||
"testname",
|
||||
"addresses",
|
||||
"writeinterval",
|
||||
"queryinterval",
|
||||
"database",
|
||||
"writeconcurrency",
|
||||
"queryconcurrency",
|
||||
}
|
||||
for _, prop := range properties {
|
||||
testSetRunUtl(t, prop, "1")
|
||||
}
|
||||
}
|
||||
|
||||
func testSetRunUtl(t *testing.T, property string, value string) {
|
||||
i := newTestSet(property, value)
|
||||
s, _, directiveCh := stressClient.NewTestStressTest()
|
||||
// Listen to the other side of the directiveCh
|
||||
go func() {
|
||||
for d := range directiveCh {
|
||||
if i.Var != d.Property {
|
||||
t.Errorf("wrong property sent to stressClient\n expected: %v\n got: %v\n", i.Var, d.Property)
|
||||
}
|
||||
if i.Value != d.Value {
|
||||
t.Errorf("wrong value sent to stressClient\n expected: %v\n got: %v\n", i.Value, d.Value)
|
||||
}
|
||||
d.Tracer.Done()
|
||||
}
|
||||
}()
|
||||
// Run the statement
|
||||
i.Run(s)
|
||||
// Check the result
|
||||
switch i.Var {
|
||||
case "precision":
|
||||
if i.Value != s.Precision {
|
||||
t.Errorf("Failed to set %v\n", i.Var)
|
||||
}
|
||||
case "startdate":
|
||||
if i.Value != s.StartDate {
|
||||
t.Errorf("Failed to set %v\n", i.Var)
|
||||
}
|
||||
case "batchsize":
|
||||
if parseInt(i.Value) != s.BatchSize {
|
||||
t.Errorf("Failed to set %v\n", i.Var)
|
||||
}
|
||||
// TODO: Actually test this
|
||||
case "resultsaddress":
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetReport(t *testing.T) {
|
||||
set := newTestSet("this", "that")
|
||||
s, _, _ := stressClient.NewTestStressTest()
|
||||
rpt := set.Report(s)
|
||||
expected := fmt.Sprintf("SET %v = '%v'", set.Var, set.Value)
|
||||
if rpt != expected {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, rpt)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestSet(toSet, value string) *SetStatement {
|
||||
return &SetStatement{
|
||||
Var: toSet,
|
||||
Value: value,
|
||||
Tracer: stressClient.NewTracer(make(map[string]string)),
|
||||
StatementID: "fooID",
|
||||
}
|
||||
}
|
||||
32
vendor/github.com/influxdata/influxdb/stress/v2/statement/statement.go
generated
vendored
Normal file
32
vendor/github.com/influxdata/influxdb/stress/v2/statement/statement.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// Statement is the common interface to shape the testing environment and prepare database requests
|
||||
// The parser turns the 'statements' in the config file into Statements
|
||||
type Statement interface {
|
||||
Run(s *stressClient.StressTest)
|
||||
Report(s *stressClient.StressTest) string
|
||||
SetID(s string)
|
||||
}
|
||||
|
||||
func parseInt(s string) int {
|
||||
i, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing integer:\n String: %v\n Error: %v\n", s, err)
|
||||
}
|
||||
return int(i)
|
||||
}
|
||||
|
||||
func parseFloat(s string) int {
|
||||
i, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing integer:\n String: %v\n Error: %v\n", s, err)
|
||||
}
|
||||
return int(i)
|
||||
}
|
||||
47
vendor/github.com/influxdata/influxdb/stress/v2/statement/template.go
generated
vendored
Normal file
47
vendor/github.com/influxdata/influxdb/stress/v2/statement/template.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
package statement
|
||||
|
||||
// A Template contains all information to fill in templated variables in inset and query statements
|
||||
type Template struct {
|
||||
Tags []string
|
||||
Function *Function
|
||||
}
|
||||
|
||||
// Templates are a collection of Template
|
||||
type Templates []*Template
|
||||
|
||||
// Init makes Stringers out of the Templates for quick point creation
|
||||
func (t Templates) Init(seriesCount int) Stringers {
|
||||
arr := make([]Stringer, len(t))
|
||||
for i, tmp := range t {
|
||||
if len(tmp.Tags) == 0 {
|
||||
arr[i] = tmp.Function.NewStringer(seriesCount)
|
||||
continue
|
||||
}
|
||||
arr[i] = tmp.NewTagFunc()
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// Calculates the number of series implied by a template
|
||||
func (t *Template) numSeries() int {
|
||||
// If !t.Tags then tag cardinality is t.Function.Count
|
||||
if len(t.Tags) == 0 {
|
||||
return t.Function.Count
|
||||
}
|
||||
// Else tag cardinality is len(t.Tags)
|
||||
return len(t.Tags)
|
||||
}
|
||||
|
||||
// NewTagFunc returns a Stringer that loops through the given tags
|
||||
func (t *Template) NewTagFunc() Stringer {
|
||||
if len(t.Tags) == 0 {
|
||||
return func() string { return "EMPTY TAGS" }
|
||||
}
|
||||
|
||||
i := 0
|
||||
return func() string {
|
||||
s := t.Tags[i]
|
||||
i = (i + 1) % len(t.Tags)
|
||||
return s
|
||||
}
|
||||
}
|
||||
72
vendor/github.com/influxdata/influxdb/stress/v2/statement/template_test.go
generated
vendored
Normal file
72
vendor/github.com/influxdata/influxdb/stress/v2/statement/template_test.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewTagFunc(t *testing.T) {
|
||||
wtags := newTestTagsTemplate()
|
||||
wfunc := newTestFunctionTemplate()
|
||||
|
||||
expected := wtags.Tags[0]
|
||||
got := wtags.NewTagFunc()()
|
||||
if got != expected {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
expected = "EMPTY TAGS"
|
||||
got = wfunc.NewTagFunc()()
|
||||
if got != expected {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumSeries(t *testing.T) {
|
||||
wtags := newTestTagsTemplate()
|
||||
wfunc := newTestFunctionTemplate()
|
||||
|
||||
expected := len(wtags.Tags)
|
||||
got := wtags.numSeries()
|
||||
if got != expected {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
expected = wfunc.Function.Count
|
||||
got = wfunc.numSeries()
|
||||
if got != expected {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplatesInit(t *testing.T) {
|
||||
tmpls := newTestTemplates()
|
||||
s := tmpls.Init(5)
|
||||
vals := s.Eval(spoofTime)
|
||||
expected := tmpls[0].Tags[0]
|
||||
got := vals[0]
|
||||
if got != expected {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
expected = "0i"
|
||||
got = vals[1]
|
||||
if got != expected {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestTemplates() Templates {
|
||||
return []*Template{
|
||||
newTestTagsTemplate(),
|
||||
newTestFunctionTemplate(),
|
||||
}
|
||||
}
|
||||
|
||||
func newTestTagsTemplate() *Template {
|
||||
return &Template{
|
||||
Tags: []string{"thing", "other_thing"},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestFunctionTemplate() *Template {
|
||||
return &Template{
|
||||
Function: newIntIncFunction(),
|
||||
}
|
||||
}
|
||||
51
vendor/github.com/influxdata/influxdb/stress/v2/statement/timestamp.go
generated
vendored
Normal file
51
vendor/github.com/influxdata/influxdb/stress/v2/statement/timestamp.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Timestamp contains all informaiton needed to generate timestamps for points created by InsertStatements
|
||||
type Timestamp struct {
|
||||
Count int
|
||||
Duration time.Duration
|
||||
Jitter bool
|
||||
}
|
||||
|
||||
// Time returns the next timestamp needed by the InsertStatement
|
||||
func (t *Timestamp) Time(startDate string, series int, precision string) func() int64 {
|
||||
var start time.Time
|
||||
var err error
|
||||
|
||||
if startDate == "now" {
|
||||
start = time.Now()
|
||||
} else {
|
||||
start, err = time.Parse("2006-01-02", startDate)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing start time from StartDate\n string: %v\n error: %v\n", startDate, err)
|
||||
}
|
||||
|
||||
return nextTime(start, t.Duration, series, precision)
|
||||
}
|
||||
|
||||
func nextTime(ti time.Time, step time.Duration, series int, precision string) func() int64 {
|
||||
t := ti
|
||||
count := 0
|
||||
return func() int64 {
|
||||
count++
|
||||
if count > series {
|
||||
t = t.Add(step)
|
||||
count = 1
|
||||
}
|
||||
|
||||
var timestamp int64
|
||||
if precision == "s" {
|
||||
timestamp = t.Unix()
|
||||
} else {
|
||||
timestamp = t.UnixNano()
|
||||
}
|
||||
return timestamp
|
||||
}
|
||||
}
|
||||
31
vendor/github.com/influxdata/influxdb/stress/v2/statement/timestamp_test.go
generated
vendored
Normal file
31
vendor/github.com/influxdata/influxdb/stress/v2/statement/timestamp_test.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTimestampTime(t *testing.T) {
|
||||
tstp := newTestTimestamp()
|
||||
function := tstp.Time("2016-01-01", 100, "s")
|
||||
expected := int64(1451606400)
|
||||
got := function()
|
||||
if expected != got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
function = tstp.Time("now", 100, "ns")
|
||||
expected = time.Now().UnixNano()
|
||||
got = function()
|
||||
if expected < got {
|
||||
t.Errorf("expected: %v\ngot: %v\n", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func newTestTimestamp() *Timestamp {
|
||||
duration, _ := time.ParseDuration("10s")
|
||||
return &Timestamp{
|
||||
Count: 5001,
|
||||
Duration: duration,
|
||||
Jitter: false,
|
||||
}
|
||||
}
|
||||
32
vendor/github.com/influxdata/influxdb/stress/v2/statement/wait.go
generated
vendored
Normal file
32
vendor/github.com/influxdata/influxdb/stress/v2/statement/wait.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
// WaitStatement is a Statement Implementation to prevent the test from returning to early when running GoStatements
|
||||
type WaitStatement struct {
|
||||
StatementID string
|
||||
|
||||
runtime time.Duration
|
||||
}
|
||||
|
||||
// SetID statisfies the Statement Interface
|
||||
func (w *WaitStatement) SetID(s string) {
|
||||
w.StatementID = s
|
||||
}
|
||||
|
||||
// Run statisfies the Statement Interface
|
||||
func (w *WaitStatement) Run(s *stressClient.StressTest) {
|
||||
runtime := time.Now()
|
||||
s.Wait()
|
||||
w.runtime = time.Since(runtime)
|
||||
}
|
||||
|
||||
// Report statisfies the Statement Interface
|
||||
func (w *WaitStatement) Report(s *stressClient.StressTest) string {
|
||||
return fmt.Sprintf("WAIT -> %v", w.runtime)
|
||||
}
|
||||
41
vendor/github.com/influxdata/influxdb/stress/v2/statement/wait_test.go
generated
vendored
Normal file
41
vendor/github.com/influxdata/influxdb/stress/v2/statement/wait_test.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package statement
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/stress/v2/stress_client"
|
||||
)
|
||||
|
||||
func TestWaitSetID(t *testing.T) {
|
||||
e := newTestWait()
|
||||
newID := "oaijnifo"
|
||||
e.SetID(newID)
|
||||
if e.StatementID != newID {
|
||||
t.Errorf("Expected: %v\ngott: %v\n", newID, e.StatementID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitRun(t *testing.T) {
|
||||
e := newTestWait()
|
||||
s, _, _ := stressClient.NewTestStressTest()
|
||||
e.Run(s)
|
||||
if e == nil {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitReport(t *testing.T) {
|
||||
e := newTestWait()
|
||||
s, _, _ := stressClient.NewTestStressTest()
|
||||
rpt := e.Report(s)
|
||||
if !strings.Contains(rpt, "WAIT") {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func newTestWait() *WaitStatement {
|
||||
return &WaitStatement{
|
||||
StatementID: "fooID",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user