You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
5.2 KiB
Go
154 lines
5.2 KiB
Go
package system
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/rqlite/rqlite/cluster"
|
|
"github.com/rqlite/rqlite/command"
|
|
"github.com/rqlite/rqlite/command/encoding"
|
|
"github.com/rqlite/rqlite/tcp"
|
|
)
|
|
|
|
// Test_StoreClientSideBySide operates on the same store directly, and via
|
|
// RPC, and ensures results are the same for basically the same operation.
|
|
func Test_StoreClientSideBySide(t *testing.T) {
|
|
node := mustNewLeaderNode()
|
|
defer node.Deprovision()
|
|
leaderAddr, err := node.Store.LeaderAddr()
|
|
if err != nil {
|
|
t.Fatalf("failed to get leader Raft address: %s", err.Error())
|
|
}
|
|
|
|
client := cluster.NewClient(mustNewDialer(cluster.MuxClusterHeader, false, false))
|
|
|
|
res, err := node.Store.Execute(executeRequestFromString("CREATE TABLE foo (id INTEGER NOT NULL PRIMARY KEY, name TEXT)"))
|
|
if err != nil {
|
|
t.Fatalf("failed to execute on local: %s", err.Error())
|
|
}
|
|
if exp, got := "[{}]", asJSON(res); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
res, err = client.Execute(leaderAddr, executeRequestFromString("CREATE TABLE bar (id INTEGER NOT NULL PRIMARY KEY, name TEXT)"))
|
|
if err != nil {
|
|
t.Fatalf("failed to execute via remote: %s", err.Error())
|
|
}
|
|
if exp, got := "[{}]", asJSON(res); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
|
|
res, err = node.Store.Execute(executeRequestFromString(`INSERT INTO foo(name) VALUES("fiona")`))
|
|
if err != nil {
|
|
t.Fatalf("failed to execute on local: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"last_insert_id":1,"rows_affected":1}]`, asJSON(res); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
res, err = client.Execute(leaderAddr, executeRequestFromString(`INSERT INTO bar(name) VALUES("fiona")`))
|
|
if err != nil {
|
|
t.Fatalf("failed to execute via remote: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"last_insert_id":1,"rows_affected":1}]`, asJSON(res); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
|
|
rows, err := node.Store.Query(queryRequestFromString(`SELECT * FROM foo`))
|
|
if err != nil {
|
|
t.Fatalf("failed to query on local: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"columns":["id","name"],"types":["integer","text"],"values":[[1,"fiona"]]}]`, asJSON(rows); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
rows, err = node.Store.Query(queryRequestFromString(`SELECT * FROM bar`))
|
|
if err != nil {
|
|
t.Fatalf("failed to query on local: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"columns":["id","name"],"types":["integer","text"],"values":[[1,"fiona"]]}]`, asJSON(rows); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
|
|
rows, err = client.Query(leaderAddr, queryRequestFromString(`SELECT * FROM foo`))
|
|
if err != nil {
|
|
t.Fatalf("failed to query via remote: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"columns":["id","name"],"types":["integer","text"],"values":[[1,"fiona"]]}]`, asJSON(rows); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
rows, err = client.Query(leaderAddr, queryRequestFromString(`SELECT * FROM bar`))
|
|
if err != nil {
|
|
t.Fatalf("failed to query via remote: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"columns":["id","name"],"types":["integer","text"],"values":[[1,"fiona"]]}]`, asJSON(rows); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
|
|
rows, err = node.Store.Query(queryRequestFromString(`SELECT * FROM qux`))
|
|
if err != nil {
|
|
t.Fatalf("failed to query on local: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"error":"no such table: qux"}]`, asJSON(rows); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
rows, err = client.Query(leaderAddr, queryRequestFromString(`SELECT * FROM qux`))
|
|
if err != nil {
|
|
t.Fatalf("failed to query via remote: %s", err.Error())
|
|
}
|
|
if exp, got := `[{"error":"no such table: qux"}]`, asJSON(rows); exp != got {
|
|
t.Fatalf("unexpected results, expt %s, got %s", exp, got)
|
|
}
|
|
}
|
|
|
|
func executeRequestFromString(s string) *command.ExecuteRequest {
|
|
return executeRequestFromStrings([]string{s})
|
|
}
|
|
|
|
// queryRequestFromStrings converts a slice of strings into a command.ExecuteRequest
|
|
func executeRequestFromStrings(s []string) *command.ExecuteRequest {
|
|
stmts := make([]*command.Statement, len(s))
|
|
for i := range s {
|
|
stmts[i] = &command.Statement{
|
|
Sql: s[i],
|
|
}
|
|
}
|
|
return &command.ExecuteRequest{
|
|
Request: &command.Request{
|
|
Statements: stmts,
|
|
Transaction: false,
|
|
},
|
|
Timings: false,
|
|
}
|
|
}
|
|
|
|
func queryRequestFromString(s string) *command.QueryRequest {
|
|
return queryRequestFromStrings([]string{s})
|
|
}
|
|
|
|
// queryRequestFromStrings converts a slice of strings into a command.QueryRequest
|
|
func queryRequestFromStrings(s []string) *command.QueryRequest {
|
|
stmts := make([]*command.Statement, len(s))
|
|
for i := range s {
|
|
stmts[i] = &command.Statement{
|
|
Sql: s[i],
|
|
}
|
|
}
|
|
return &command.QueryRequest{
|
|
Request: &command.Request{
|
|
Statements: stmts,
|
|
Transaction: false,
|
|
},
|
|
Timings: false,
|
|
}
|
|
}
|
|
|
|
func mustNewDialer(header byte, remoteEncrypted, skipVerify bool) *tcp.Dialer {
|
|
return tcp.NewDialer(header, remoteEncrypted, skipVerify)
|
|
}
|
|
|
|
func asJSON(v interface{}) string {
|
|
b, err := encoding.JSONMarshal(v)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("failed to JSON marshal value: %s", err.Error()))
|
|
}
|
|
return string(b)
|
|
}
|