app-init
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
package navicat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBlockRoundTripShortAndLong(t *testing.T) {
|
||||
cases := [][]byte{
|
||||
{},
|
||||
[]byte("a"),
|
||||
bytes.Repeat([]byte("x"), 253),
|
||||
bytes.Repeat([]byte("y"), 254),
|
||||
bytes.Repeat([]byte("z"), 1024),
|
||||
[]byte("你好世界"),
|
||||
}
|
||||
for _, in := range cases {
|
||||
enc := AppendBlock(nil, in)
|
||||
r := newReader(enc)
|
||||
got, isNull, err := r.block(false)
|
||||
if err != nil {
|
||||
t.Fatalf("len=%d: %v", len(in), err)
|
||||
}
|
||||
if isNull {
|
||||
t.Fatal("null")
|
||||
}
|
||||
if !bytes.Equal(got, in) {
|
||||
t.Fatalf("mismatch len=%d", len(in))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNullCell(t *testing.T) {
|
||||
enc := AppendNull(nil)
|
||||
r := newReader(enc)
|
||||
_, isNull, err := r.block(true)
|
||||
if err != nil || !isNull {
|
||||
t.Fatalf("err=%v null=%v", err, isNull)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeader202And206(t *testing.T) {
|
||||
for _, ver := range []uint16{Version202, Version206} {
|
||||
body := AppendHeader(nil, ver, 0)
|
||||
h, _, err := ParseHeader(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if h.Version != ver || !h.OK() {
|
||||
t.Fatalf("%+v", h)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaderError204(t *testing.T) {
|
||||
body := encodeHeaderError(ErrnoInvalidToken, "invalid access token")
|
||||
h, _, err := ParseHeader(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if h.Errno != ErrnoInvalidToken || h.Message != "invalid access token" {
|
||||
t.Fatalf("%+v", h)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectParse(t *testing.T) {
|
||||
body := encodeConnectOK("127.0.0.1 via TCP/IP", "10", "8.0.36")
|
||||
resp, err := ParseConnect(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp.Conn.ProtoInfo != "10" || resp.Conn.ServerInfo != "8.0.36" {
|
||||
t.Fatalf("%+v", resp.Conn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuerySelect1(t *testing.T) {
|
||||
body := encodeQueryResults([]Result{selectLiteral("1", "1", 8, 20)})
|
||||
resp, err := ParseQuery(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(resp.Results) != 1 {
|
||||
t.Fatalf("results=%d", len(resp.Results))
|
||||
}
|
||||
r := resp.Results[0]
|
||||
if !r.IsResultSet() || r.NumRows != 1 {
|
||||
t.Fatalf("%+v", r)
|
||||
}
|
||||
if r.Rows[0][0].Null || r.Rows[0][0].Text() != "1" {
|
||||
t.Fatalf("cell=%+v", r.Rows[0][0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestNullDecimalBigintUTF8(t *testing.T) {
|
||||
body := encodeQueryResults([]Result{
|
||||
{
|
||||
NumFields: 4,
|
||||
NumRows: 1,
|
||||
Fields: []Field{
|
||||
{Name: "n", Type: 6},
|
||||
{Name: "b", Type: 8, Length: 20},
|
||||
{Name: "d", Type: 246, Length: 32},
|
||||
{Name: "z", Type: 253, Length: 12},
|
||||
},
|
||||
Rows: [][]Cell{{
|
||||
{Null: true},
|
||||
{Bytes: []byte("18446744073709551615")},
|
||||
{Bytes: []byte("1234567890.123456789")},
|
||||
{Bytes: []byte("你好世界")},
|
||||
}},
|
||||
},
|
||||
})
|
||||
resp, err := ParseQuery(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
row := resp.Results[0].Rows[0]
|
||||
if !row[0].Null {
|
||||
t.Fatal("expected NULL")
|
||||
}
|
||||
if row[1].Text() != "18446744073709551615" {
|
||||
t.Fatalf("bigint parsed badly: %q", row[1].Text())
|
||||
}
|
||||
if row[2].Text() != "1234567890.123456789" {
|
||||
t.Fatalf("decimal parsed badly: %q", row[2].Text())
|
||||
}
|
||||
if row[3].Text() != "你好世界" {
|
||||
t.Fatalf("utf8: %q", row[3].Text())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLError(t *testing.T) {
|
||||
body := encodeQueryResults([]Result{{Errno: 1064, Message: "You have an error in your SQL syntax"}})
|
||||
resp, err := ParseQuery(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !resp.Results[0].IsError() || !strings.Contains(resp.Results[0].Message, "syntax") {
|
||||
t.Fatalf("%+v", resp.Results[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDMLOk(t *testing.T) {
|
||||
body := encodeQueryResults([]Result{{AffectedRows: 3, InsertID: 9, Info: "Rows matched: 3"}})
|
||||
resp, err := ParseQuery(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := resp.Results[0]
|
||||
if r.IsResultSet() || r.AffectedRows != 3 || r.InsertID != 9 {
|
||||
t.Fatalf("%+v", r)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTMLRejected(t *testing.T) {
|
||||
_, err := ParseConnect([]byte("<html>nope</html>"))
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestOmitsEmptyQueriesAndEncodesArray(t *testing.T) {
|
||||
enc := Request{
|
||||
Action: ActionQuery,
|
||||
Host: "mysql",
|
||||
Port: 3306,
|
||||
Login: "root",
|
||||
Queries: []string{"SELECT 1", "", "SELECT 2"},
|
||||
}.Encode()
|
||||
if strings.Contains(enc, "password=secret") {
|
||||
t.Fatal("unexpected")
|
||||
}
|
||||
if !strings.Contains(enc, "q%5B%5D=SELECT+1") && !strings.Contains(enc, "q%5B%5D=SELECT%201") {
|
||||
t.Fatalf("q[] missing: %s", enc)
|
||||
}
|
||||
if strings.Count(enc, "q%5B%5D=") != 2 {
|
||||
t.Fatalf("empty query not skipped: %s", enc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestBase64(t *testing.T) {
|
||||
enc := Request{
|
||||
Action: ActionQuery,
|
||||
Host: "mysql",
|
||||
Port: 3306,
|
||||
Login: "root",
|
||||
Queries: []string{"SELECT 1"},
|
||||
EncodeBase64: true,
|
||||
}.Encode()
|
||||
if !strings.Contains(enc, "encodeBase64=1") {
|
||||
t.Fatal(enc)
|
||||
}
|
||||
if strings.Contains(enc, "SELECT+1") {
|
||||
t.Fatalf("sql should be base64: %s", enc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorDoesNotEmbedPassword(t *testing.T) {
|
||||
e := &Error{Kind: "mysql", Errno: 1045, Message: "Access denied for user 'root'@'localhost'"}
|
||||
if strings.Contains(e.Error(), "password") && strings.Contains(e.Error(), "=") {
|
||||
t.Fatal(e.Error())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user