1
0
mirror of https://github.com/Oxalide/vsphere-influxdb-go.git synced 2023-10-10 11:36:51 +00:00

add vendoring with go dep

This commit is contained in:
Adrian Todorov
2017-10-25 20:52:40 +00:00
parent 704f4d20d1
commit a59409f16b
1627 changed files with 489673 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
package stressql
import (
"bufio"
"bytes"
"io"
"log"
"os"
"strings"
"github.com/influxdata/influxdb/influxql"
"github.com/influxdata/influxdb/stress/v2/statement"
stressql "github.com/influxdata/influxdb/stress/v2/stressql/statement"
)
// Token represents a lexical token.
type Token int
// These are the lexical tokens used by the file parser
const (
ILLEGAL Token = iota
EOF
STATEMENT
BREAK
)
var eof = rune(0)
func check(e error) {
if e != nil {
log.Fatal(e)
}
}
func isNewline(r rune) bool {
return r == '\n'
}
// Scanner scans the file and tokenizes the raw text
type Scanner struct {
r *bufio.Reader
}
// NewScanner returns a Scanner
func NewScanner(r io.Reader) *Scanner {
return &Scanner{r: bufio.NewReader(r)}
}
func (s *Scanner) read() rune {
ch, _, err := s.r.ReadRune()
if err != nil {
return eof
}
return ch
}
func (s *Scanner) unread() { _ = s.r.UnreadRune() }
func (s *Scanner) peek() rune {
ch := s.read()
s.unread()
return ch
}
// Scan moves the Scanner forward one character
func (s *Scanner) Scan() (tok Token, lit string) {
ch := s.read()
if isNewline(ch) {
s.unread()
return s.scanNewlines()
} else if ch == eof {
return EOF, ""
} else {
s.unread()
return s.scanStatements()
}
// golint marks as unreachable code
// return ILLEGAL, string(ch)
}
func (s *Scanner) scanNewlines() (tok Token, lit string) {
var buf bytes.Buffer
buf.WriteRune(s.read())
for {
if ch := s.read(); ch == eof {
break
} else if !isNewline(ch) {
s.unread()
break
} else {
buf.WriteRune(ch)
}
}
return BREAK, buf.String()
}
func (s *Scanner) scanStatements() (tok Token, lit string) {
var buf bytes.Buffer
buf.WriteRune(s.read())
for {
if ch := s.read(); ch == eof {
break
} else if isNewline(ch) && isNewline(s.peek()) {
s.unread()
break
} else if isNewline(ch) {
s.unread()
buf.WriteRune(ch)
} else {
buf.WriteRune(ch)
}
}
return STATEMENT, buf.String()
}
// ParseStatements takes a configFile and returns a slice of Statements
func ParseStatements(file string) ([]statement.Statement, error) {
seq := []statement.Statement{}
f, err := os.Open(file)
check(err)
s := NewScanner(f)
for {
t, l := s.Scan()
if t == EOF {
break
}
_, err := influxql.ParseStatement(l)
if err == nil {
seq = append(seq, &statement.InfluxqlStatement{Query: l, StatementID: stressql.RandStr(10)})
} else if t == BREAK {
continue
} else {
f := strings.NewReader(l)
p := stressql.NewParser(f)
s, err := p.Parse()
if err != nil {
return nil, err
}
seq = append(seq, s)
}
}
f.Close()
return seq, nil
}

View File

@@ -0,0 +1,16 @@
package stressql
import "testing"
// Pulls the default configFile and makes sure it parses
func TestParseStatements(t *testing.T) {
stmts, err := ParseStatements("../iql/file.iql")
if err != nil {
t.Error(err)
}
expected := 15
got := len(stmts)
if expected != got {
t.Errorf("expected: %v\ngot: %v\n", expected, got)
}
}

View File

@@ -0,0 +1,682 @@
package statement
import (
"bufio"
"bytes"
"crypto/rand"
"fmt"
"io"
"log"
"strconv"
"strings"
"time"
"github.com/influxdata/influxdb/stress/v2/statement"
)
// Token represents a lexical token.
type Token int
// The following tokens represent the different values in the AST that make up stressql
const (
ILLEGAL Token = iota
EOF
WS
literalBeg
// IDENT and the following are InfluxQL literal tokens.
IDENT // main
NUMBER // 12345.67
DURATIONVAL // 13h
STRING // "abc"
BADSTRING // "abc
TEMPLATEVAR // %f
literalEnd
COMMA // ,
LPAREN // (
RPAREN // )
LBRACKET // [
RBRACKET // ]
PIPE // |
PERIOD // .
keywordBeg
SET
USE
QUERY
INSERT
GO
DO
WAIT
STR
INT
FLOAT
EXEC
keywordEnd
)
var eof = rune(1)
func isWhitespace(ch rune) bool { return ch == ' ' || ch == '\t' || ch == '\n' }
func isDigit(r rune) bool {
return r >= '0' && r <= '9'
}
func isLetter(ch rune) bool {
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '@')
}
// Scanner scans over the file and converts the raw text into tokens
type Scanner struct {
r *bufio.Reader
}
// NewScanner returns a Scanner
func NewScanner(r io.Reader) *Scanner {
return &Scanner{r: bufio.NewReader(r)}
}
func (s *Scanner) read() rune {
ch, _, err := s.r.ReadRune()
if err != nil {
return eof
}
return ch
}
func (s *Scanner) unread() { _ = s.r.UnreadRune() }
// Scan moves to the next character in the file and returns a tokenized version as well as the literal
func (s *Scanner) Scan() (tok Token, lit string) {
ch := s.read()
if isWhitespace(ch) {
s.unread()
return s.scanWhitespace()
} else if isLetter(ch) {
s.unread()
return s.scanIdent()
} else if isDigit(ch) {
s.unread()
return s.scanNumber()
}
switch ch {
case eof:
return EOF, ""
case '"':
s.unread()
return s.scanIdent()
case '%':
s.unread()
return s.scanTemplateVar()
case ',':
return COMMA, ","
case '.':
return PERIOD, "."
case '(':
return LPAREN, "("
case ')':
return RPAREN, ")"
case '[':
return LBRACKET, "["
case ']':
return RBRACKET, "]"
case '|':
return PIPE, "|"
}
return ILLEGAL, string(ch)
}
func (s *Scanner) scanWhitespace() (tok Token, lit string) {
var buf bytes.Buffer
buf.WriteRune(s.read())
for {
if ch := s.read(); ch == eof {
break
} else if !isWhitespace(ch) {
s.unread()
break
} else {
buf.WriteRune(ch)
}
}
return WS, buf.String()
}
func (s *Scanner) scanIdent() (tok Token, lit string) {
var buf bytes.Buffer
buf.WriteRune(s.read())
for {
if ch := s.read(); ch == eof {
break
} else if !isLetter(ch) && !isDigit(ch) && ch != '_' && ch != ':' && ch != '=' && ch != '-' {
s.unread()
break
} else {
_, _ = buf.WriteRune(ch)
}
}
switch strings.ToUpper(buf.String()) {
case "SET":
return SET, buf.String()
case "USE":
return USE, buf.String()
case "QUERY":
return QUERY, buf.String()
case "INSERT":
return INSERT, buf.String()
case "EXEC":
return EXEC, buf.String()
case "WAIT":
return WAIT, buf.String()
case "GO":
return GO, buf.String()
case "DO":
return DO, buf.String()
case "STR":
return STR, buf.String()
case "FLOAT":
return FLOAT, buf.String()
case "INT":
return INT, buf.String()
}
return IDENT, buf.String()
}
func (s *Scanner) scanTemplateVar() (tok Token, lit string) {
var buf bytes.Buffer
buf.WriteRune(s.read())
buf.WriteRune(s.read())
return TEMPLATEVAR, buf.String()
}
func (s *Scanner) scanNumber() (tok Token, lit string) {
var buf bytes.Buffer
buf.WriteRune(s.read())
for {
if ch := s.read(); ch == eof {
break
} else if ch == 'n' || ch == 's' || ch == 'm' {
_, _ = buf.WriteRune(ch)
return DURATIONVAL, buf.String()
} else if !isDigit(ch) {
s.unread()
break
} else {
_, _ = buf.WriteRune(ch)
}
}
return NUMBER, buf.String()
}
/////////////////////////////////
// PARSER ///////////////////////
/////////////////////////////////
// Parser turns the file from raw text into an AST
type Parser struct {
s *Scanner
buf struct {
tok Token
lit string
n int
}
}
// NewParser creates a new Parser
func NewParser(r io.Reader) *Parser {
return &Parser{s: NewScanner(r)}
}
// Parse returns a Statement
func (p *Parser) Parse() (statement.Statement, error) {
tok, lit := p.scanIgnoreWhitespace()
switch tok {
case QUERY:
p.unscan()
return p.ParseQueryStatement()
case INSERT:
p.unscan()
return p.ParseInsertStatement()
case EXEC:
p.unscan()
return p.ParseExecStatement()
case SET:
p.unscan()
return p.ParseSetStatement()
case GO:
p.unscan()
return p.ParseGoStatement()
case WAIT:
p.unscan()
return p.ParseWaitStatement()
}
return nil, fmt.Errorf("Improper syntax\n unknown token found between statements, token: %v\n", lit)
}
// ParseQueryStatement returns a QueryStatement
func (p *Parser) ParseQueryStatement() (*statement.QueryStatement, error) {
stmt := &statement.QueryStatement{
StatementID: RandStr(10),
}
if tok, lit := p.scanIgnoreWhitespace(); tok != QUERY {
return nil, fmt.Errorf("Error parsing Query Statement\n Expected: QUERY\n Found: %v\n", lit)
}
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT {
return nil, fmt.Errorf("Error parsing Query Statement\n Expected: IDENT\n Found: %v\n", lit)
}
stmt.Name = lit
for {
tok, lit := p.scan()
if tok == TEMPLATEVAR {
stmt.TemplateString += "%v"
stmt.Args = append(stmt.Args, lit)
} else if tok == DO {
tok, lit := p.scanIgnoreWhitespace()
if tok != NUMBER {
return nil, fmt.Errorf("Error parsing Query Statement\n Expected: NUMBER\n Found: %v\n", lit)
}
// Parse out the integer
i, err := strconv.ParseInt(lit, 10, 64)
if err != nil {
log.Fatalf("Error parsing integer in Query Statement:\n string: %v\n error: %v\n", lit, err)
}
stmt.Count = int(i)
break
} else if tok == WS && lit == "\n" {
continue
} else {
stmt.TemplateString += lit
}
}
return stmt, nil
}
// ParseInsertStatement returns a InsertStatement
func (p *Parser) ParseInsertStatement() (*statement.InsertStatement, error) {
// Initialize the InsertStatement with a statementId
stmt := &statement.InsertStatement{
StatementID: RandStr(10),
}
// If the first word is INSERT
if tok, lit := p.scanIgnoreWhitespace(); tok != INSERT {
return nil, fmt.Errorf("Error parsing Insert Statement\n Expected: INSERT\n Found: %v\n", lit)
}
// Next should come the NAME of the statement. It is IDENT type
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT {
return nil, fmt.Errorf("Error parsing Insert Statement\n Expected: IDENT\n Found: %v\n", lit)
}
// Set the Name
stmt.Name = lit
// Next char should be a newline
tok, lit = p.scan()
if tok != WS {
return nil, fmt.Errorf("Error parsing Insert Statement\n Expected: WS\n Found: %v\n", lit)
}
// We are now scanning the tags line
var prev Token
inTags := true
for {
// Start for loop by scanning
tok, lit = p.scan()
// If scaned is WS then we are just entering tags or leaving tags or fields
if tok == WS {
// If previous is COMMA then we are leaving measurement, continue
if prev == COMMA {
continue
}
// Otherwise we need to add a space to the template string and we are out of tags
stmt.TemplateString += " "
inTags = false
} else if tok == LBRACKET {
// If we are still inTags and there is a LBRACKET we are adding another template
if inTags {
stmt.TagCount++
}
// Add a space to fill template string with template result
stmt.TemplateString += "%v"
// parse template should return a template type
expr, err := p.ParseTemplate()
// If there is a Template parsing error return it
if err != nil {
return nil, err
}
// Add template to parsed select statement
stmt.Templates = append(stmt.Templates, expr)
// A number signifies that we are in the Timestamp section
} else if tok == NUMBER {
// Add a space to fill template string with timestamp
stmt.TemplateString += "%v"
p.unscan()
// Parse out the Timestamp
ts, err := p.ParseTimestamp()
// If there is a Timestamp parsing error return it
if err != nil {
return nil, err
}
// Set the Timestamp
stmt.Timestamp = ts
// Break loop as InsertStatement ends
break
} else if tok != IDENT && tok != COMMA {
return nil, fmt.Errorf("Error parsing Insert Statement\n Expected: IDENT or COMMA\n Found: %v\n", lit)
} else {
prev = tok
stmt.TemplateString += lit
}
}
return stmt, nil
}
// ParseTemplate returns a Template
func (p *Parser) ParseTemplate() (*statement.Template, error) {
// Blank template
tmplt := &statement.Template{}
for {
// Scan to start loop
tok, lit := p.scanIgnoreWhitespace()
// If the tok == IDENT explicit tags are passed. Add them to the list of tags
if tok == IDENT {
tmplt.Tags = append(tmplt.Tags, lit)
// Different flavors of functions
} else if tok == INT || tok == FLOAT || tok == STR {
p.unscan()
// Parse out the function
fn, err := p.ParseFunction()
// If there is a Function parsing error return it
if err != nil {
return nil, err
}
// Set the Function on the Template
tmplt.Function = fn
// End of Function
} else if tok == RBRACKET {
break
}
}
return tmplt, nil
}
// ParseExecStatement returns a ExecStatement
func (p *Parser) ParseExecStatement() (*statement.ExecStatement, error) {
// NEEDS TO PARSE ACTUAL PATH TO SCRIPT CURRENTLY ONLY DOES
// IDENT SCRIPT NAMES
stmt := &statement.ExecStatement{
StatementID: RandStr(10),
}
if tok, lit := p.scanIgnoreWhitespace(); tok != EXEC {
return nil, fmt.Errorf("Error parsing Exec Statement\n Expected: EXEC\n Found: %v\n", lit)
}
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT {
return nil, fmt.Errorf("Error parsing Exec Statement\n Expected: IDENT\n Found: %v\n", lit)
}
stmt.Script = lit
return stmt, nil
}
// ParseSetStatement returns a SetStatement
func (p *Parser) ParseSetStatement() (*statement.SetStatement, error) {
stmt := &statement.SetStatement{
StatementID: RandStr(10),
}
if tok, lit := p.scanIgnoreWhitespace(); tok != SET {
return nil, fmt.Errorf("Error parsing Set Statement\n Expected: SET\n Found: %v\n", lit)
}
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT {
return nil, fmt.Errorf("Error parsing Set Statement\n Expected: IDENT\n Found: %v\n", lit)
}
stmt.Var = lit
tok, lit = p.scanIgnoreWhitespace()
if tok != LBRACKET {
return nil, fmt.Errorf("Error parsing Set Statement\n Expected: RBRACKET\n Found: %v\n", lit)
}
for {
tok, lit = p.scanIgnoreWhitespace()
if tok == RBRACKET {
break
} else if lit != "-" && lit != ":" && tok != IDENT && tok != NUMBER && tok != DURATIONVAL && tok != PERIOD && tok != PIPE {
return nil, fmt.Errorf("Error parsing Set Statement\n Expected: IDENT || NUMBER || DURATION\n Found: %v\n", lit)
}
stmt.Value += lit
}
return stmt, nil
}
// ParseWaitStatement returns a WaitStatement
func (p *Parser) ParseWaitStatement() (*statement.WaitStatement, error) {
stmt := &statement.WaitStatement{
StatementID: RandStr(10),
}
if tok, lit := p.scanIgnoreWhitespace(); tok != WAIT {
return nil, fmt.Errorf("Error parsing Wait Statement\n Expected: WAIT\n Found: %v\n", lit)
}
return stmt, nil
}
// ParseGoStatement returns a GoStatement
func (p *Parser) ParseGoStatement() (*statement.GoStatement, error) {
stmt := &statement.GoStatement{}
stmt.StatementID = RandStr(10)
if tok, lit := p.scanIgnoreWhitespace(); tok != GO {
return nil, fmt.Errorf("Error parsing Go Statement\n Expected: GO\n Found: %v\n", lit)
}
var body statement.Statement
var err error
tok, _ := p.scanIgnoreWhitespace()
switch tok {
case QUERY:
p.unscan()
body, err = p.ParseQueryStatement()
case INSERT:
p.unscan()
body, err = p.ParseInsertStatement()
case EXEC:
p.unscan()
body, err = p.ParseExecStatement()
}
if err != nil {
return nil, err
}
stmt.Statement = body
return stmt, nil
}
// ParseFunction returns a Function
func (p *Parser) ParseFunction() (*statement.Function, error) {
fn := &statement.Function{}
_, lit := p.scanIgnoreWhitespace()
fn.Type = lit
_, lit = p.scanIgnoreWhitespace()
fn.Fn = lit
tok, lit := p.scanIgnoreWhitespace()
if tok != LPAREN {
return nil, fmt.Errorf("Error parsing Insert template function\n Expected: LPAREN\n Found: %v\n", lit)
}
tok, lit = p.scanIgnoreWhitespace()
if tok != NUMBER {
return nil, fmt.Errorf("Error parsing Insert template function\n Expected: NUMBER\n Found: %v\n", lit)
}
// Parse out the integer
i, err := strconv.ParseInt(lit, 10, 64)
if err != nil {
log.Fatalf("Error parsing integer in Insert template function:\n string: %v\n error: %v\n", lit, err)
}
fn.Argument = int(i)
tok, _ = p.scanIgnoreWhitespace()
if tok != RPAREN {
return nil, fmt.Errorf("Error parsing Insert template function\n Expected: RPAREN\n Found: %v\n", lit)
}
tok, lit = p.scanIgnoreWhitespace()
if tok != NUMBER {
return nil, fmt.Errorf("Error parsing Insert template function\n Expected: NUMBER\n Found: %v\n", lit)
}
// Parse out the integer
i, err = strconv.ParseInt(lit, 10, 64)
if err != nil {
log.Fatalf("Error parsing integer in Insert template function:\n string: %v\n error: %v\n", lit, err)
}
fn.Count = int(i)
return fn, nil
}
// ParseTimestamp returns a Timestamp
func (p *Parser) ParseTimestamp() (*statement.Timestamp, error) {
ts := &statement.Timestamp{}
tok, lit := p.scanIgnoreWhitespace()
if tok != NUMBER {
return nil, fmt.Errorf("Error parsing Insert timestamp\n Expected: NUMBER\n Found: %v\n", lit)
}
// Parse out the integer
i, err := strconv.ParseInt(lit, 10, 64)
if err != nil {
log.Fatalf("Error parsing integer in Insert timestamp:\n string: %v\n error: %v\n", lit, err)
}
ts.Count = int(i)
tok, lit = p.scanIgnoreWhitespace()
if tok != DURATIONVAL {
return nil, fmt.Errorf("Error parsing Insert timestamp\n Expected: DURATION\n Found: %v\n", lit)
}
// Parse out the duration
dur, err := time.ParseDuration(lit)
if err != nil {
log.Fatalf("Error parsing duration in Insert timestamp:\n string: %v\n error: %v\n", lit, err)
}
ts.Duration = dur
return ts, nil
}
func (p *Parser) scan() (tok Token, lit string) {
// If we have a token on the buffer, then return it.
if p.buf.n != 0 {
p.buf.n = 0
return p.buf.tok, p.buf.lit
}
// Otherwise read the next token from the scanner.
tok, lit = p.s.Scan()
// Save it to the buffer in case we unscan later.
p.buf.tok, p.buf.lit = tok, lit
return
}
// scanIgnoreWhitespace scans the next non-whitespace token.
func (p *Parser) scanIgnoreWhitespace() (tok Token, lit string) {
tok, lit = p.scan()
if tok == WS {
tok, lit = p.scan()
}
return
}
// unscan pushes the previously read token back onto the buffer.
func (p *Parser) unscan() { p.buf.n = 1 }
// RandStr returns a string of random characters with length n
func RandStr(n int) string {
b := make([]byte, n/2)
_, _ = rand.Read(b)
return fmt.Sprintf("%x", b)
}

View File

@@ -0,0 +1,243 @@
package statement
import (
// "fmt"
"reflect"
"strings"
"testing"
"time"
"github.com/influxdata/influxdb/stress/v2/statement"
)
func newParserFromString(s string) *Parser {
f := strings.NewReader(s)
p := NewParser(f)
return p
}
func TestParser_ParseStatement(t *testing.T) {
var tests = []struct {
skip bool
s string
stmt statement.Statement
err string
}{
// QUERY
{
s: "QUERY basicCount\nSELECT count(%f) FROM cpu\nDO 100",
stmt: &statement.QueryStatement{Name: "basicCount", TemplateString: "SELECT count(%v) FROM cpu", Args: []string{"%f"}, Count: 100},
},
{
s: "QUERY basicCount\nSELECT count(%f) FROM %m\nDO 100",
stmt: &statement.QueryStatement{Name: "basicCount", TemplateString: "SELECT count(%v) FROM %v", Args: []string{"%f", "%m"}, Count: 100},
},
{
skip: true, // SHOULD CAUSE AN ERROR
s: "QUERY\nSELECT count(%f) FROM %m\nDO 100",
err: "Missing Name",
},
// INSERT
{
s: "INSERT mockCpu\ncpu,\nhost=[us-west|us-east|eu-north],server_id=[str rand(7) 1000]\nbusy=[int rand(1000) 100],free=[float rand(10) 0]\n100000 10s",
stmt: &statement.InsertStatement{
Name: "mockCpu",
TemplateString: "cpu,host=%v,server_id=%v busy=%v,free=%v %v",
TagCount: 2,
Templates: []*statement.Template{
&statement.Template{
Tags: []string{"us-west", "us-east", "eu-north"},
},
&statement.Template{
Function: &statement.Function{Type: "str", Fn: "rand", Argument: 7, Count: 1000},
},
&statement.Template{
Function: &statement.Function{Type: "int", Fn: "rand", Argument: 1000, Count: 100},
},
&statement.Template{
Function: &statement.Function{Type: "float", Fn: "rand", Argument: 10, Count: 0},
},
},
Timestamp: &statement.Timestamp{
Count: 100000,
Duration: time.Duration(10 * time.Second),
},
},
},
{
s: "INSERT mockCpu\ncpu,host=[us-west|us-east|eu-north],server_id=[str rand(7) 1000]\nbusy=[int rand(1000) 100],free=[float rand(10) 0]\n100000 10s",
stmt: &statement.InsertStatement{
Name: "mockCpu",
TemplateString: "cpu,host=%v,server_id=%v busy=%v,free=%v %v",
TagCount: 2,
Templates: []*statement.Template{
&statement.Template{
Tags: []string{"us-west", "us-east", "eu-north"},
},
&statement.Template{
Function: &statement.Function{Type: "str", Fn: "rand", Argument: 7, Count: 1000},
},
&statement.Template{
Function: &statement.Function{Type: "int", Fn: "rand", Argument: 1000, Count: 100},
},
&statement.Template{
Function: &statement.Function{Type: "float", Fn: "rand", Argument: 10, Count: 0},
},
},
Timestamp: &statement.Timestamp{
Count: 100000,
Duration: time.Duration(10 * time.Second),
},
},
},
{
s: "INSERT mockCpu\n[str rand(1000) 10],\nhost=[us-west|us-east|eu-north],server_id=[str rand(7) 1000],other=x\nbusy=[int rand(1000) 100],free=[float rand(10) 0]\n100000 10s",
stmt: &statement.InsertStatement{
Name: "mockCpu",
TemplateString: "%v,host=%v,server_id=%v,other=x busy=%v,free=%v %v",
TagCount: 3,
Templates: []*statement.Template{
&statement.Template{
Function: &statement.Function{Type: "str", Fn: "rand", Argument: 1000, Count: 10},
},
&statement.Template{
Tags: []string{"us-west", "us-east", "eu-north"},
},
&statement.Template{
Function: &statement.Function{Type: "str", Fn: "rand", Argument: 7, Count: 1000},
},
&statement.Template{
Function: &statement.Function{Type: "int", Fn: "rand", Argument: 1000, Count: 100},
},
&statement.Template{
Function: &statement.Function{Type: "float", Fn: "rand", Argument: 10, Count: 0},
},
},
Timestamp: &statement.Timestamp{
Count: 100000,
Duration: time.Duration(10 * time.Second),
},
},
},
{
skip: true, // Expected error not working
s: "INSERT\ncpu,\nhost=[us-west|us-east|eu-north],server_id=[str rand(7) 1000]\nbusy=[int rand(1000) 100],free=[float rand(10) 0]\n100000 10s",
err: `found ",", expected WS`,
},
// EXEC
{
s: `EXEC other_script`,
stmt: &statement.ExecStatement{Script: "other_script"},
},
{
skip: true, // Implement
s: `EXEC other_script.sh`,
stmt: &statement.ExecStatement{Script: "other_script.sh"},
},
{
skip: true, // Implement
s: `EXEC ../other_script.sh`,
stmt: &statement.ExecStatement{Script: "../other_script.sh"},
},
{
skip: true, // Implement
s: `EXEC /path/to/some/other_script.sh`,
stmt: &statement.ExecStatement{Script: "/path/to/some/other_script.sh"},
},
// GO
{
skip: true,
s: "GO INSERT mockCpu\ncpu,\nhost=[us-west|us-east|eu-north],server_id=[str rand(7) 1000]\nbusy=[int rand(1000) 100],free=[float rand(10) 0]\n100000 10s",
stmt: &statement.GoStatement{
Statement: &statement.InsertStatement{
Name: "mockCpu",
TemplateString: "cpu,host=%v,server_id=%v busy=%v,free=%v %v",
Templates: []*statement.Template{
&statement.Template{
Tags: []string{"us-west", "us-east", "eu-north"},
},
&statement.Template{
Function: &statement.Function{Type: "str", Fn: "rand", Argument: 7, Count: 1000},
},
&statement.Template{
Function: &statement.Function{Type: "int", Fn: "rand", Argument: 1000, Count: 100},
},
&statement.Template{
Function: &statement.Function{Type: "float", Fn: "rand", Argument: 10, Count: 0},
},
},
Timestamp: &statement.Timestamp{
Count: 100000,
Duration: time.Duration(10 * time.Second),
},
},
},
},
{
skip: true,
s: "GO QUERY basicCount\nSELECT count(free) FROM cpu\nDO 100",
stmt: &statement.GoStatement{
Statement: &statement.QueryStatement{Name: "basicCount", TemplateString: "SELECT count(free) FROM cpu", Count: 100},
},
},
{
skip: true,
s: `GO EXEC other_script`,
stmt: &statement.GoStatement{
Statement: &statement.ExecStatement{Script: "other_script"},
},
},
// SET
{
s: `SET database [stress]`,
stmt: &statement.SetStatement{Var: "database", Value: "stress"},
},
// WAIT
{
s: `Wait`,
stmt: &statement.WaitStatement{},
},
}
for _, tst := range tests {
if tst.skip {
continue
}
stmt, err := newParserFromString(tst.s).Parse()
tst.stmt.SetID("x")
if err != nil && err.Error() != tst.err {
t.Errorf("REAL ERROR: %v\nExpected ERROR: %v\n", err, tst.err)
} else if err != nil && tst.err == err.Error() {
t.Errorf("REAL ERROR: %v\nExpected ERROR: %v\n", err, tst.err)
} else if stmt.SetID("x"); !reflect.DeepEqual(stmt, tst.stmt) {
t.Errorf("Expected\n%#v\n%#v", tst.stmt, stmt)
}
}
}