golang 使用github.com/cznic/ql进行测试
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 使用github.com/cznic/ql进行测试相关的知识,希望对你有一定的参考价值。
package main
import (
"fmt"
"github.com/cznic/ql"
"log"
"math/rand"
"os"
"sort"
)
var (
stmCreateTables = ql.MustCompile(`
BEGIN TRANSACTION;
CREATE TABLE products (
n int32,
s string
);
COMMIT;`)
stmInsertIntStr = ql.MustCompile(`INSERT INTO products VALUES($1, $2);`)
stmCount = ql.MustCompile(`SELECT count() FROM products;`)
stmSelect = ql.MustCompile(`SELECT n, s FROM products ORDER BY n;`)
)
func genRandomIntStr() (int32, string) {
n := rand.Int31()
return int32(n), fmt.Sprintf("s_%d", n)
}
func PathExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}
type IntStr struct {
n int32
s string
}
type IntStrByInt []IntStr
func (s IntStrByInt) Len() int {
return len(s)
}
func (s IntStrByInt) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s IntStrByInt) Less(i, j int) bool {
return s[i].n < s[j].n
}
var (
insertedData []IntStr
)
func getCountFromRecordSet(rs []ql.Recordset) int {
var count int64
err := rs[0].Do(false, func(rec []interface{}) (bool, error) {
//fmt.Printf("rec: %#v\n", rec)
count = rec[0].(int64)
return true, nil
})
if err != nil {
log.Fatalf("rs[0].Do() failed with '%s'\n", err.Error())
}
fmt.Printf("count: %d\n", count)
return int(count)
}
func verifyCount(db *ql.DB) {
rs, _, err := db.Execute(ql.NewRWCtx(), stmCount)
if err != nil {
log.Fatalf("db.Execute('%s') failed with '%s'\n", stmCount, err.Error())
}
//fmt.Printf("len(rs) for stmCount: %d\n", len(rs))
nRecords := getCountFromRecordSet(rs)
if nRecords != 1024 {
log.Fatalf("nRecords (%d) != 1024\n", nRecords)
}
}
func readDatabase(db *ql.DB) []IntStr {
verifyCount(db)
rs, _, err := db.Execute(ql.NewRWCtx(), stmSelect)
if err != nil {
log.Fatalf("db.Execute('%s') failed with '%s'\n", stmSelect, err.Error())
}
var res []IntStr
for _, rec := range rs {
err := rec.Do(false, func(fields []interface{}) (bool, error) {
n := fields[0].(int32)
s := fields[1].(string)
res = append(res, IntStr{n: n, s: s})
return true, nil
})
if err != nil {
log.Fatalf("rec.Do() failed with '%s'\n", err.Error())
}
}
fmt.Printf("len(res) = %d\n", len(res))
return res
}
func populateDatabase(db *ql.DB) {
_, _, err := db.Execute(ql.NewRWCtx(), stmCreateTables)
if err != nil {
log.Fatalf("db.Execute('%s') failed with '%s'\n", stmCreateTables, err.Error())
}
rand.Seed(666) // ensure consistent numbers
ctx := ql.NewRWCtx()
_, _, err = db.Run(ctx, "BEGIN TRANSACTION;")
if err != nil {
log.Fatalf("db.Run('%s') failed with '%s'\n", "BEGIN TRANSACTION;", err.Error())
}
for i := 0; i < 1024; i++ {
n, s := genRandomIntStr()
_, _, err = db.Execute(ctx, stmInsertIntStr, n, s)
if err != nil {
log.Fatalf("db.Execute('%s') failed with '%s'\n", stmInsertIntStr, err.Error())
}
el := IntStr{n: n, s: s}
insertedData = append(insertedData, el)
}
_, _, err = db.Run(ctx, "COMMIT;")
if err != nil {
log.Fatalf("db.Run('%s') failed with '%s'\n", "COMMIT;", err.Error())
}
}
func generateInsertedData() {
rand.Seed(666) // ensure consistent numbers
for i := 0; i < 1024; i++ {
n, s := genRandomIntStr()
el := IntStr{n: n, s: s}
insertedData = append(insertedData, el)
}
}
func verifySelectResults(res []IntStr) {
for i, el := range res {
//fmt.Printf("i=%d\n", i)
expected := insertedData[i]
if el.n != expected.n {
log.Fatalf("i=%d, el.n != expected.n (%d != %d)\n", i, el.n, expected.n)
}
if el.s != expected.s {
log.Fatalf("i=%d, el.s != expected.s (%s != %s)\n", i, el.s, expected.s)
}
}
fmt.Printf("select results verified!\n")
}
func dumpFirst(n int, arr []IntStr) {
if n > len(arr) {
n = len(arr)
}
for i := 0; i < n; i++ {
el := arr[i]
fmt.Printf("n=%d, s=%s\n", el.n, el.s)
}
}
func main() {
fmt.Printf("Testing ql database.\n")
dbFileName := "test.db"
exists := PathExists(dbFileName)
opt := &ql.Options{CanCreate: true}
db, err := ql.OpenFile(dbFileName, opt)
if err != nil {
log.Fatalf("ql.OpenFile() failed with '%s'\n", err.Error())
}
defer db.Close()
if !exists {
populateDatabase(db)
} else {
generateInsertedData()
}
res := readDatabase(db)
//dumpFirst(10, res)
//fmt.Printf("\n")
//dumpFirst(10, insertedData)
//fmt.Printf("\n")
sort.Sort(IntStrByInt(insertedData))
//dumpFirst(10, insertedData)
//fmt.Printf("\n")
verifySelectResults(res)
}
golang 使用Golang生成随机字符串
package main
import (
"math/rand"
"testing"
"time"
)
// Implementations
func init() {
rand.Seed(time.Now().UnixNano())
}
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func RandStringRunes(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
func RandStringBytes(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
}
return string(b)
}
func RandStringBytesRmndr(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))]
}
return string(b)
}
func RandStringBytesMask(n int) string {
b := make([]byte, n)
for i := 0; i < n; {
if idx := int(rand.Int63() & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i++
}
}
return string(b)
}
func RandStringBytesMaskImpr(n int) string {
b := make([]byte, n)
// A rand.Int63() generates 63 random bits, enough for letterIdxMax letters!
for i, cache, remain := n-1, rand.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = rand.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}
var src = rand.NewSource(time.Now().UnixNano())
func RandStringBytesMaskImprSrc(n int) string {
b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}
// Benchmark functions
const n = 16
func BenchmarkRunes(b *testing.B) {
for i := 0; i < b.N; i++ {
RandStringRunes(n)
}
}
func BenchmarkBytes(b *testing.B) {
for i := 0; i < b.N; i++ {
RandStringBytes(n)
}
}
func BenchmarkBytesRmndr(b *testing.B) {
for i := 0; i < b.N; i++ {
RandStringBytesRmndr(n)
}
}
func BenchmarkBytesMask(b *testing.B) {
for i := 0; i < b.N; i++ {
RandStringBytesMask(n)
}
}
func BenchmarkBytesMaskImpr(b *testing.B) {
for i := 0; i < b.N; i++ {
RandStringBytesMaskImpr(n)
}
}
func BenchmarkBytesMaskImprSrc(b *testing.B) {
for i := 0; i < b.N; i++ {
RandStringBytesMaskImprSrc(n)
}
}
以上是关于golang 使用github.com/cznic/ql进行测试的主要内容,如果未能解决你的问题,请参考以下文章