td-797: support SQL argument from command line
This commit is contained in:
parent
c115bb3dd4
commit
72ddf72b01
|
@ -5,7 +5,7 @@ Stress test tool for TDengine. It run a set of test cases randomly and show stat
|
||||||
## COMMAND LINE
|
## COMMAND LINE
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
$ ./stress [-h=<localhost>] [-P=<0>] [-d=<test>] [-u=<root>] [-p=<taosdata>] [-c=<4>] [-f=<true>] [test case file]
|
$ ./stress [-h=<localhost>] [-P=<0>] [-d=<test>] [-u=<root>] [-p=<taosdata>] [-c=<4>] [-f=<true>] [path_or_sql]
|
||||||
```
|
```
|
||||||
|
|
||||||
* **-h**: host name or IP address of TDengine server (default: localhost).
|
* **-h**: host name or IP address of TDengine server (default: localhost).
|
||||||
|
@ -14,7 +14,7 @@ $ ./stress [-h=<localhost>] [-P=<0>] [-d=<test>] [-u=<root>] [-p=<taosdata>] [-c
|
||||||
* **-p**: password (default: taosdata).
|
* **-p**: password (default: taosdata).
|
||||||
* **-c**: concurrency, number of concurrent goroutines for query (default: 4).
|
* **-c**: concurrency, number of concurrent goroutines for query (default: 4).
|
||||||
* **-f**: fetch data or not (default: true).
|
* **-f**: fetch data or not (default: true).
|
||||||
* **test case file**: the path of a JSON file which contains the test cases (default: cases.json).
|
* **path_or_sql**: a SQL statement or path of a JSON file which contains the test cases (default: cases.json).
|
||||||
|
|
||||||
## TEST CASE FILE
|
## TEST CASE FILE
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ type testCase struct {
|
||||||
isQuery bool `json:"-"`
|
isQuery bool `json:"-"`
|
||||||
numArgs int `json:"-"`
|
numArgs int `json:"-"`
|
||||||
Weight int `json:"weight"`
|
Weight int `json:"weight"`
|
||||||
Sql string `json:"sql"`
|
SQL string `json:"sql"`
|
||||||
Args []argument `json:"args"`
|
Args []argument `json:"args"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ func (tc *testCase) buildSql() string {
|
||||||
for i := 0; i < len(tc.Args); i++ {
|
for i := 0; i < len(tc.Args); i++ {
|
||||||
args = tc.Args[i].generate(args)
|
args = tc.Args[i].generate(args)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(tc.Sql, args...)
|
return fmt.Sprintf(tc.SQL, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
type statitics struct {
|
type statitics struct {
|
||||||
|
@ -129,22 +129,19 @@ var (
|
||||||
cases []testCase
|
cases []testCase
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadTestCase(path string) error {
|
func loadTestCaseFromFile(file *os.File) error {
|
||||||
f, e := os.Open(path)
|
if e := json.NewDecoder(file).Decode(&cases); e != nil {
|
||||||
if e != nil {
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
e = json.NewDecoder(f).Decode(&cases)
|
if len(cases) == 0 {
|
||||||
if e != nil {
|
return fmt.Errorf("no test case loaded.")
|
||||||
return e
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(cases); i++ {
|
for i := 0; i < len(cases); i++ {
|
||||||
c := &cases[i]
|
c := &cases[i]
|
||||||
c.Sql = strings.TrimSpace(c.Sql)
|
c.SQL = strings.TrimSpace(c.SQL)
|
||||||
c.isQuery = strings.ToLower(c.Sql[:6]) == "select"
|
c.isQuery = strings.ToLower(c.SQL[:6]) == "select"
|
||||||
if c.Weight < 0 {
|
if c.Weight < 0 {
|
||||||
return fmt.Errorf("test %d: negative weight", i)
|
return fmt.Errorf("test %d: negative weight", i)
|
||||||
}
|
}
|
||||||
|
@ -171,6 +168,28 @@ func loadTestCase(path string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadTestCase(pathOrSQL string) error {
|
||||||
|
if f, e := os.Open(pathOrSQL); e == nil {
|
||||||
|
defer f.Close()
|
||||||
|
return loadTestCaseFromFile(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
pathOrSQL = strings.TrimSpace(pathOrSQL)
|
||||||
|
if strings.ToLower(pathOrSQL[:6]) != "select" {
|
||||||
|
return fmt.Errorf("'%s' is not a valid file or SQL statement", pathOrSQL)
|
||||||
|
}
|
||||||
|
|
||||||
|
cases = append(cases, testCase{
|
||||||
|
isQuery: true,
|
||||||
|
Weight: 1,
|
||||||
|
numArgs: 0,
|
||||||
|
SQL: pathOrSQL,
|
||||||
|
})
|
||||||
|
totalWeight = 1
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func selectTestCase() *testCase {
|
func selectTestCase() *testCase {
|
||||||
sum, target := 0, rand.Intn(totalWeight)
|
sum, target := 0, rand.Intn(totalWeight)
|
||||||
var c *testCase
|
var c *testCase
|
||||||
|
@ -297,16 +316,13 @@ func main() {
|
||||||
flag.UintVar(&concurrency, "c", 4, "concurrency, number of goroutines for query")
|
flag.UintVar(&concurrency, "c", 4, "concurrency, number of goroutines for query")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
caseFile := flag.Arg(0)
|
pathOrSQL := flag.Arg(0)
|
||||||
if caseFile == "" {
|
if len(pathOrSQL) == 0 {
|
||||||
caseFile = "cases.json"
|
pathOrSQL = "cases.json"
|
||||||
}
|
}
|
||||||
if e := loadTestCase(caseFile); e != nil {
|
if e := loadTestCase(pathOrSQL); e != nil {
|
||||||
fmt.Println("failed to load test cases:", e.Error())
|
fmt.Println("failed to load test cases:", e.Error())
|
||||||
return
|
return
|
||||||
} else if len(cases) == 0 {
|
|
||||||
fmt.Println("there's no test case")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
Loading…
Reference in New Issue