提交 300c087a 编写于 作者: aaronchen2k2k's avatar aaronchen2k2k

new features for 1.1

上级 1f46785a
# zendata
ZenData is an data generator for testing automation written in Golang.
zendata是一款通用的数据生成工具,您可以使用yaml文件来定义您的数据格式,然后交由zendata生成。
## Features
1. Generate massive test data by using yaml config files;
2. Customize your own definitions base on build-in generator;
3. Export database schema as yaml config files.
## 参数:
```shell
-d --default 默认的数据格式配置文件。
-c --config 当前场景的数据格式配置文件,可以覆盖默认文件里面的设置。
-o --output 生成的数据的文件名。可通过扩展名指定输出json|xml|sql格式的数据。默认输出原始格式的文本数据。
-n --lines 要生成的记录条数,默认为10条。
## QuickStart
### Run from release file
1. Download last release file from [here](https://github.com/easysoft/zendata/releases);
2. Type 'zd/zd.exe -h' to get the help.
-F --field 可通过该参数指定要输出的字段列表,用逗号分隔。 默认是所有的字段。
-t --table 输出格式为sql时,需通过该参数指定要插入数据的表名。
-H --human 输出可读格式,打印字段名,并使用tab键进行分割。
### Run from Golang codes
1. Enter 'git clone https://github.com/easysoft/zendata.git' to get the source codes;
3. Type 'go run src/zd.go -h' to get the help.
-p --port 在指定端口上运行HTTP服务。可通过http://ip/接口获得JSON格式的数据。服务模式下只支持数据生成。
-b --bind 监听的ip地址,默认监听所有的ip地址。
-r --root 运行HTTP服务时根目录。客户端可调用该根目录下面的配置文件。如果不指定,取zd可执行文件所在目录。
## Licenses
All source code is licensed under the [GPLv3 License](LICENSE.md).
-i --input 指定一个schema文件,输出每个表的yaml配置文件。需通过-o参数指定一个输出的目录。
-s --server 数据库服务器类型,支持mysql|oracle|sqlite|sqlserver,默认为mysql。可用于解析yaml文件或者生成SQL。
-D --decode 根据指定的配置文件,将通过-i参数指定的数据文件解析成json格式,可通过-H参数输出可读格式。
-e --example 打印示例的数据格式配置文件。
-l --list 列出所有支持的数据格式。
-v --view 查看某一个数据格式的详细定义。
-h --help 打印帮助。
```
## 命令行模式举例:
```shell
$>zd.exe -d demo\default.yaml 根据-d参数指定的配置文件生成10条记录。
$>zd.exe -c demo\default.yaml 根据-c参数指定的配置文件生成10条记录。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -c和-d两个文件的配置合并,输出100条记录。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.txt 输出原始格式的数据。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.json 输出json格式的数据。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.xml 输出xml格式的数据。
$>zd.exe -d demo\default.yaml -n 100 -o test.sql -t user -s mysql 输出插入到user表里面的sql。
$>zd.exe -i db.sql -s mysql -o db 根据db.sql的定义生成每个表的yaml文件,存储到db目录里面。
$>zd.exe -c demo\default.yaml -i test.txt --decode 将-i指定的文件根据-d参数的配置进行解析。
```
## 服务模式举例:
```shell
$zd.exe -p 80 -r d:\zd\config 监听80端口,以d:\zd\config为根目录。
```
## 客户端调用:
```shell
$curl http://loclahost/?d=default.yaml&c=config.yaml&n=100&o=test.sql&t=user 通过GET方式指定服务器端配置文件。
$curl http://loclahost/?default=default.yamloutput=test.sql&table=user 参数名可以用全拼。
$curl -d "default=...&config=...&lines=10" http://localhost/ 可以通过POST方式上传配置。
```
\ No newline at end of file
......@@ -6,6 +6,7 @@ require golang.org/x/text v0.3.2
require (
github.com/360EntSecGroup-Skylar/excelize/v2 v2.2.0
github.com/akavel/rsrc v0.9.0 // indirect
github.com/emirpasic/gods v1.12.0
github.com/fatih/color v1.9.0
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
......
$>zd.exe -h 查看使用帮助。
$>zd.exe -y demo/test.yaml -c 15 -field field1 -o demo/output.txt -f text
执行数据生成命令。使用配置文件demo/test.yaml,生成15行数据,以text格式的输出到demo/output.txt文件中。
$>zd.exe -y demo/test.yaml -head -sep , -s
执行数据生成命令。带逗号分隔的标题行,默认生成10行,以Map形式的JSON格式输出到http://127.0.0.1/data接口。
$>zd.exe -y demo/test.yaml -c 15 -field field1 -o demo/insert.sql -f sql -t table_name
执行数据生成命令。以SQL语句形式输出到demo/insert.sql文件中,表名为table_name。
$>zd.exe -d demo/base.yaml -y demo/test.yaml -c 15 -field field1 -o demo/output.txt
执行数据生成命令。使用文件demo/test.yaml覆盖默认配置demo/common.yaml中的内容。
$>zd.exe -i xdoc/test/zentao.sql -o out
从指定的数据库Schema,创建yaml定义文件,输出到out目录下。
\ No newline at end of file
title: test
desc: This is a test file.
author: zentao
version: 1.0
fields:
- field: field1
note: 字符区间步长、随机
range: a-f:R,0-9:2
format: "%3d"
loop: 3
loopfix: ","
prefix: "["
postfix: "] "
\ No newline at end of file
-h --help 查看帮助信息。
-s --set 设置工具语言属性。用户对当前目录需要有写权限。
默认根据定义文件生成数据。
-d --default 默认定义文件
-y --yaml 指定定义文件
-c --count 指定生成数据的条数
--field 需要输出的字段,用逗号分隔。未指定时,默认输出-yaml文件中的所有字段。
-o --out 指定输出文件
-f --format 输出格式,支持text、json、xml和sql语句,默认为text。
-t --table 输出格式为table时,用于指定insert语句的表名。
--head 生成标题行。文本格式增加标题行,JSON数据转化为Map格式(JSON默认为二维数组)。
--sep 生成标题行时,纸短见的分隔符,默认为逗号。
-s --service 启动http服务,用户可从http://<ip_address/data接口获取JSON格式的行列数据。
--verbose 增加此参数,显示详细调试信息。
为了方便在任意目录中执行%s命令,建议将其加入环境变量中,具体方法参照以下地址。
https://www.ztesting.net/book/ztf-doc/add-to-path-46.html
\ No newline at end of file
zendata是一款通用的数据生成工具,您可以使用yaml文件来定义您的数据格式,然后交由zendata生成。
参数:
-d --default 默认的数据格式配置文件。
-c --config 当前场景的数据格式配置文件,可以覆盖默认文件里面的设置。
-o --output 生成的数据的文件名。可通过扩展名指定输出json|xml|sql格式的数据。默认输出原始格式的文本数据。
-n --lines 要生成的记录条数,默认为10条。
-F --field 可通过该参数指定要输出的字段列表,用逗号分隔。 默认是所有的字段。
-t --table 输出格式为sql时,需通过该参数指定要插入数据的表名。
-H --human 输出可读格式,打印字段名,并使用tab键进行分割。
-p --port 在指定端口上运行HTTP服务。可通过http://ip/接口获得JSON格式的数据。服务模式下只支持数据生成。
-b --bind 监听的ip地址,默认监听所有的ip地址。
-r --root 运行HTTP服务时根目录。客户端可调用该根目录下面的配置文件。如果不指定,取zd可执行文件所在目录。
-i --input 指定一个schema文件,输出每个表的yaml配置文件。需通过-o参数指定一个输出的目录。
-s --server 数据库服务器类型,支持mysql|oracle|sqlite|sqlserver,默认为mysql。可用于解析yaml文件或者生成SQL。
-D --decode 根据指定的配置文件,将通过-i参数指定的数据文件解析成json格式,可通过-H参数输出可读格式。
-e --example 打印示例的数据格式配置文件。
-l --list 列出所有支持的数据格式。
-v --view 查看某一个数据格式的详细定义。
-h --help 打印帮助。
命令行模式举例:
$>zd.exe -d demo\default.yaml 根据-d参数指定的配置文件生成10条记录。
$>zd.exe -c demo\default.yaml 根据-c参数指定的配置文件生成10条记录。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -c和-d两个文件的配置合并,输出100条记录。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.txt 输出原始格式的数据。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.json 输出json格式的数据。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.xml 输出xml格式的数据。
$>zd.exe -d demo\default.yaml -n 100 -o test.sql -t user -s mysql 输出插入到user表里面的sql。
$>zd.exe -i db.sql -s mysql -o db 根据db.sql的定义生成每个表的yaml文件,存储到db目录里面。
$>zd.exe -c demo\default.yaml -i test.txt --decode 将-i指定的文件根据-d参数的配置进行解析。
服务模式举例:
$zd.exe -p 80 -r d:\zd\config 监听80端口,以d:\zd\config为根目录。
客户端调用:
$curl http://loclahost/?d=default.yaml&c=config.yaml&n=100&o=test.sql&t=user 通过GET方式指定服务器端配置文件。
$curl http://loclahost/?default=default.yamloutput=test.sql&table=user 参数名可以用全拼。
$curl -d "default=...&config=...&lines=10" http://localhost/ 可以通过POST方式上传配置。
\ No newline at end of file
......@@ -9,6 +9,7 @@ import (
constant "github.com/easysoft/zendata/src/utils/const"
i118Utils "github.com/easysoft/zendata/src/utils/i118"
logUtils "github.com/easysoft/zendata/src/utils/log"
stringUtils "github.com/easysoft/zendata/src/utils/string"
"github.com/easysoft/zendata/src/utils/vari"
"github.com/fatih/color"
"net/http"
......@@ -49,7 +50,6 @@ func Generate(deflt string, yml string, total int, fieldsToExportStr string, out
logUtils.PrintToWithColor(i118Utils.I118Prt.Sprintf("press_to_exist"), color.FgCyan)
http.HandleFunc("/", DataHandler)
http.HandleFunc("/data", DataHandler)
http.ListenAndServe(":58848", nil)
}
......@@ -82,7 +82,7 @@ func Print(rows [][]string, format string, table string, colTypes []bool, fields
valueList := ""
for j, col := range cols {
if j >0 && format == "sql" {
if j >0 && format == constant.FormatSql {
line = line + ","
valueList = valueList + ","
}
......@@ -91,11 +91,12 @@ func Print(rows [][]string, format string, table string, colTypes []bool, fields
row.Cols = append(row.Cols, col)
colVal := col
colVal = stringUtils.AddPad(colVal)
if !colTypes[j] { colVal = "'" + colVal + "'" }
valueList = valueList + colVal
}
if format == "text" && i < len(rows) {
if format == constant.FormatText && i < len(rows) {
content = content + line + "\n"
}
......@@ -103,7 +104,7 @@ func Print(rows [][]string, format string, table string, colTypes []bool, fields
testData.Table.Rows = append(testData.Table.Rows, row)
if format == "sql" {
if format == constant.FormatSql {
fieldNames := make([]string, 0)
for _, f := range fields {
......@@ -115,7 +116,7 @@ func Print(rows [][]string, format string, table string, colTypes []bool, fields
}
respJson := "[]"
if format == "json" || vari.HttpService {
if format == constant.FormatJson || vari.HttpService {
if vari.WithHead {
mapArr := RowsToMap(rows, fields)
jsonObj, _ := json.Marshal(mapArr)
......@@ -126,12 +127,12 @@ func Print(rows [][]string, format string, table string, colTypes []bool, fields
}
}
if format == "json" {
if format == constant.FormatJson {
content = respJson
} else if format == "xml" {
} else if format == constant.FormatJson {
xml, _ := xml.Marshal(testData)
content = string(xml)
} else if format == "sql" {
} else if format == constant.FormatSql {
content = sql
}
......
......@@ -31,6 +31,12 @@ var (
Def = model.DefData{}
Res = map[string]map[string][]string{}
FormatText = "text"
FormatJson = "json"
FormatXml = "xml"
FormatSql = "sql"
Formats = []string{FormatText, FormatJson, FormatXml, FormatSql}
LeftChar rune = '('
RightChar rune = ')'
......
......@@ -5,7 +5,6 @@ import (
"fmt"
commonUtils "github.com/easysoft/zendata/src/utils/common"
fileUtils "github.com/easysoft/zendata/src/utils/file"
i118Utils "github.com/easysoft/zendata/src/utils/i118"
"github.com/fatih/color"
"os"
"regexp"
......@@ -13,12 +12,17 @@ import (
)
var (
exampleFile = fmt.Sprintf("res%sdoc%ssample.yaml", string(os.PathSeparator), string(os.PathSeparator))
usageFile = fmt.Sprintf("res%sdoc%susage.txt", string(os.PathSeparator), string(os.PathSeparator))
sampleFile = fmt.Sprintf("res%sdoc%ssample.txt", string(os.PathSeparator), string(os.PathSeparator))
)
func PrintExample() {
content := fileUtils.ReadResData(exampleFile)
fmt.Printf("%s\n", content)
}
func PrintUsage() {
PrintToWithColor(i118Utils.I118Prt.Sprintf("usage"), color.FgCyan)
//PrintToWithColor(i118Utils.I118Prt.Sprintf("usage"), color.FgCyan)
usage := fileUtils.ReadResData(usageFile)
exeFile := "zd"
......@@ -26,24 +30,17 @@ func PrintUsage() {
exeFile += ".exe"
}
usage = fmt.Sprintf(usage, exeFile)
fmt.Printf("%s\n", usage)
PrintToWithColor("\n" + i118Utils.I118Prt.Sprintf("example"), color.FgCyan)
sample := fileUtils.ReadResData(sampleFile)
if !commonUtils.IsWin() {
regx, _ := regexp.Compile(`\\`)
sample = regx.ReplaceAllString(sample, "/")
regx, _ = regexp.Compile(`ztf.exe`)
sample = regx.ReplaceAllString(sample, "ztf")
usage = regx.ReplaceAllString(usage, "/")
regx, _ = regexp.Compile(`/bat/`)
sample = regx.ReplaceAllString(sample, "/shell/")
regx, _ = regexp.Compile(`zd.exe`)
usage = regx.ReplaceAllString(usage, "zd")
regx, _ = regexp.Compile(`\.bat\s{4}`)
sample = regx.ReplaceAllString(sample, ".shell")
regx, _ = regexp.Compile(`d:`)
usage = regx.ReplaceAllString(usage, "/home/user")
}
fmt.Printf("%s\n", sample)
fmt.Printf("%s\n", usage)
}
func PrintTo(str string) {
......
......@@ -6,6 +6,7 @@ import (
"encoding/hex"
"fmt"
constant "github.com/easysoft/zendata/src/utils/const"
"github.com/easysoft/zendata/src/utils/vari"
"github.com/mattn/go-runewidth"
"strconv"
"strings"
......@@ -97,4 +98,34 @@ func FormatStr(format string, val interface{}) (string, bool) {
}
return str, true
}
func InArray(need interface{}, arr []string) bool {
for _,v := range arr{
if need == v{
return true
}
}
return false
}
func AddPad(str string) string {
if vari.Length > 0 {
gap := vari.Length - len(str)
if vari.LeftPad != "" {
vari.LeftPad = vari.LeftPad[:1]
pads := strings.Repeat(vari.LeftPad, gap)
str = pads + str
} else if vari.RightPad != "" {
vari.RightPad = vari.RightPad[:1]
pads := strings.Repeat(vari.RightPad, gap)
str = str + pads
} else {
vari.LeftPad = " "
pads := strings.Repeat(vari.LeftPad, gap)
str = pads + str
}
}
return str
}
\ No newline at end of file
......@@ -24,6 +24,11 @@ var (
WithHead bool
HeadSep string
Length int
LeftPad string
RightPad string
HttpService bool
JsonResp string = "[]"
)
......@@ -4,29 +4,34 @@ import (
"flag"
"github.com/easysoft/zendata/src/action"
configUtils "github.com/easysoft/zendata/src/utils/config"
constant "github.com/easysoft/zendata/src/utils/const"
logUtils "github.com/easysoft/zendata/src/utils/log"
stringUtils "github.com/easysoft/zendata/src/utils/string"
"github.com/easysoft/zendata/src/utils/vari"
"github.com/fatih/color"
"io/ioutil"
"os"
"os/signal"
"path"
"strings"
"syscall"
)
var (
deflt string
yml string
deflt string
yaml string
count int
fields string
input string
output string
table = "text"
format = "text"
table string
format = constant.FormatText
viewRes string
viewDetail string
example bool
help bool
flagSet *flag.FlagSet
......@@ -46,34 +51,42 @@ func main() {
flagSet.StringVar(&deflt, "d", "", "")
flagSet.StringVar(&deflt, "default", "", "")
flagSet.StringVar(&yml, "y", "", "")
flagSet.StringVar(&yml, "yml", "", "")
flagSet.StringVar(&yaml, "c", "", "")
flagSet.StringVar(&yaml, "config", "", "")
flagSet.StringVar(&input, "i", "", "")
flagSet.StringVar(&input, "input", "", "")
flagSet.IntVar(&count, "c", 10, "")
flagSet.IntVar(&count, "count", 10, "")
flagSet.IntVar(&count, "n", 10, "")
flagSet.IntVar(&count, "lines", 10, "")
flagSet.StringVar(&fields, "F", "", "")
flagSet.StringVar(&fields, "field", "", "")
flagSet.StringVar(&output, "o", "", "")
flagSet.StringVar(&output, "output", "", "")
flagSet.StringVar(&table, "t", "", "")
flagSet.StringVar(&table, "table", "", "")
flagSet.StringVar(&format, "f", "text", "")
flagSet.StringVar(&format, "format", "text", "")
flagSet.StringVar(&table, "t", "table_name", "")
flagSet.StringVar(&table, "table", "table_name", "")
flagSet.StringVar(&viewRes, "v", "", "")
flagSet.StringVar(&viewDetail, "vv", "", "")
flagSet.BoolVar(&vari.WithHead, "head", false, "")
flagSet.StringVar(&vari.HeadSep, "sep", ",", "")
flagSet.StringVar(&vari.HeadSep, "H", "\t", "")
flagSet.StringVar(&vari.HeadSep, "human", "\t", "")
flagSet.IntVar(&vari.Length, "length", 0, "")
flagSet.StringVar(&vari.LeftPad, "leftPad", "", "")
flagSet.StringVar(&vari.RightPad, "rightPad", "", "")
flagSet.BoolVar(&vari.HttpService, "s", false, "")
flagSet.BoolVar(&example, "e", false, "")
flagSet.BoolVar(&example, "example", false, "")
flagSet.BoolVar(&help, "h", false, "")
flagSet.BoolVar(&help, "help", false, "")
flagSet.BoolVar(&vari.Verbose, "verbose", false, "")
if len(os.Args) == 1 {
......@@ -81,8 +94,10 @@ func main() {
}
switch os.Args[1] {
case "-e", "-example":
logUtils.PrintExample()
case "-h", "-help":
usage()
logUtils.PrintUsage()
default:
if os.Args[1][0:1] == "-" {
args := []string{os.Args[0], "gen"}
......@@ -97,20 +112,30 @@ func main() {
func gen(args []string) {
flagSet.SetOutput(ioutil.Discard)
if err := flagSet.Parse(args[2:]); err == nil {
if vari.HeadSep != "" {
vari.WithHead = true
}
if output != "" {
ext := strings.ToLower(path.Ext(output))
if len(ext) > 1 {
ext = strings.TrimLeft(ext,".")
}
if stringUtils.InArray(ext, constant.Formats) {
format = ext
}
}
if input != "" {
action.ParseSql(input, output)
} else {
action.Generate(deflt, yml, count, fields, output, format, table)
action.Generate(deflt, yaml, count, fields, output, format, table)
}
} else {
usage()
logUtils.PrintUsage()
}
}
func usage() {
logUtils.PrintUsage()
}
func init() {
cleanup()
......
文件已添加
rm -rf build
mkdir build
mkdir build/log
cp -r data build/
cp -r demo build/
......
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="x86"
name="controls"
type="win32"
></assemblyIdentity>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
\ No newline at end of file
go get -u github.com/jteeuwen/go-bindata/...
go run src/zd.go -y demo/article.yaml -c 3 -head -s
\ No newline at end of file
go run src/zd.go -y demo/article.yaml -c 3 -head -s
rsrc -manifest xdoc/main.exe.manifest -ico xdoc/fav.ico -o zd.syso
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册