1
0
Fork 0
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.

331 lines
10 KiB
Go

package db
import (
"encoding/json"
"io/ioutil"
"os"
"path"
"testing"
)
/*
* Lowest-layer database tests
*/
func Test_DbFileCreation(t *testing.T) {
dir, err := ioutil.TempDir("", "rqlite-test-")
defer os.RemoveAll(dir)
db, err := Open(path.Join(dir, "test_db"))
if err != nil {
t.Fatalf("failed to open new database: %s", err.Error())
}
if db == nil {
t.Fatal("database is nil")
}
err = db.Close()
if err != nil {
t.Fatalf("failed to close database: %s", err.Error())
}
}
func Test_TableCreation(t *testing.T) {
db, path := mustCreateDatabase()
defer db.Close()
defer os.Remove(path)
_, err := db.Execute([]string{"CREATE TABLE foo (id INTEGER NOT NULL PRIMARY KEY, name TEXT)"}, false)
if err != nil {
t.Fatalf("failed to create table: %s", err.Error())
}
r, err := db.Query([]string{"SELECT * FROM foo"}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name"]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query, expected %s, got %s", exp, got)
}
}
func Test_SimpleSingleStatements(t *testing.T) {
db, path := mustCreateDatabase()
defer db.Close()
defer os.Remove(path)
_, err := db.Execute([]string{"CREATE TABLE foo (id INTEGER NOT NULL PRIMARY KEY, name TEXT)"}, false)
if err != nil {
t.Fatalf("failed to create table: %s", err.Error())
}
_, err = db.Execute([]string{`INSERT INTO foo(name) VALUES("fiona")`}, false)
if err != nil {
t.Fatalf("failed to insert record: %s", err.Error())
}
r, err := db.Query([]string{`SELECT * FROM foo`}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name"],"values":[[1,"fiona"]]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query, expected %s, got %s", exp, got)
}
_, err = db.Execute([]string{`INSERT INTO foo(name) VALUES("aoife")`}, false)
if err != nil {
t.Fatalf("failed to insert record: %s", err.Error())
}
r, err = db.Query([]string{`SELECT * FROM foo`}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name"],"values":[[1,"fiona"],[2,"aoife"]]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query\nexp: %s\ngot: %s", exp, got)
}
r, err = db.Query([]string{`SELECT * FROM foo WHERE name="aoife"`}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name"],"values":[[2,"aoife"]]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query\nexp: %s\ngot: %s", exp, got)
}
r, err = db.Query([]string{`SELECT * FROM foo WHERE name="dana"`}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name"]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query\nexp: %s\ngot: %s", exp, got)
}
r, err = db.Query([]string{`SELECT * FROM foo ORDER BY name`}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name"],"values":[[2,"aoife"],[1,"fiona"]]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query\nexp: %s\ngot: %s", exp, got)
}
r, err = db.Query([]string{`SELECT *,name FROM foo`}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name","name"],"values":[[1,"fiona","fiona"],[2,"aoife","aoife"]]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query\nexp: %s\ngot: %s", exp, got)
}
}
func Test_SimpleMultiStatements(t *testing.T) {
db, path := mustCreateDatabase()
defer db.Close()
defer os.Remove(path)
_, err := db.Execute([]string{"CREATE TABLE foo (id INTEGER NOT NULL PRIMARY KEY, name TEXT)"}, false)
if err != nil {
t.Fatalf("failed to create table: %s", err.Error())
}
_, err = db.Execute([]string{`INSERT INTO foo(name) VALUES("fiona")`}, false)
if err != nil {
t.Fatalf("failed to insert record: %s", err.Error())
}
r, err := db.Query([]string{`SELECT * FROM foo`, `SELECT * FROM foo`}, false)
if err != nil {
t.Fatalf("failed to query empty table: %s", err.Error())
}
if exp, got := `[{"columns":["id","name"],"values":[[1,"fiona"]]},{"columns":["id","name"],"values":[[1,"fiona"]]}]`, asJson(r); exp != got {
t.Fatalf("unexpected results for query\nexp: %s\ngot: %s", exp, got)
}
}
// func Test_FailingSimpleStatements(t *testing.T) {
// db, path := mustCreateDatabase()
// defer db.Close()
// defer os.Remove(path)
// err := db.Execute(`INSERT INTO foo(name) VALUES("fiona")`)
// if err == nil {
// t.Fatal("inserted record into empty table OK")
// }
// if err.Error() != "no such table: foo" {
// t.Fatal("unexpected error returned")
// }
// if err = db.Execute("create table foo (id integer not null primary key, name text)"); err != nil {
// t.Fatalf("failed to create table: %s", err.Error())
// }
// if err = db.Execute("create table foo (id integer not null primary key, name text)"); err == nil {
// t.Fatal("duplicate table created OK")
// }
// if err.Error() != "table foo already exists" {
// t.Fatalf("unexpected error returned: %s", err.Error())
// }
// if err = db.Execute(`INSERT INTO foo(id, name) VALUES(11, "fiona")`); err != nil {
// t.Fatalf("failed to insert record: %s", err.Error())
// }
// if err = db.Execute(`INSERT INTO foo(id, name) VALUES(11, "fiona")`); err == nil {
// t.Fatal("duplicated record inserted OK")
// }
// if err.Error() != "UNIQUE constraint failed: foo.id" {
// t.Fatal("unexpected error returned")
// }
// if err = db.Execute("SELECT * FROM bar"); err == nil {
// t.Fatal("no error when querying non-existant table")
// }
// if err.Error() != "no such table: bar" {
// t.Fatal("unexpected error returned")
// }
// if err = db.Execute("utter nonsense"); err == nil {
// t.Fatal("no error when issuing nonsense query")
// }
// if err.Error() != `near "utter": syntax error` {
// t.Fatal("unexpected error returned")
// }
// }
// func Test_SimpleTransactions(t *testing.T) {
// db, path := mustCreateDatabase()
// defer db.Close()
// defer os.Remove(path)
// if err := db.Execute("create table foo (id integer not null primary key, name text)"); err != nil {
// t.Fatalf("failed to create table: %s", err.Error())
// }
// if err := db.StartTransaction(); err != nil {
// t.Fatalf("failed to start transaction: %s", err.Error())
// }
// for i := 0; i < 10; i++ {
// _ = db.Execute(`INSERT INTO foo(name) VALUES("philip")`)
// }
// if err := db.CommitTransaction(); err != nil {
// t.Fatalf("failed to commit transaction: %s", err.Error())
// }
// r, err := db.Query("SELECT name FROM foo")
// if err != nil {
// t.Fatalf("failed to query after commited transaction: %s", err.Error())
// }
// if len(r) != 10 {
// t.Fatalf("incorrect number of results returned: %d", len(r))
// }
// if err := db.StartTransaction(); err != nil {
// t.Fatalf("failed to start transaction: %s", err.Error())
// }
// for i := 0; i < 10; i++ {
// _ = db.Execute(`INSERT INTO foo(name) VALUES("philip")`)
// }
// if err := db.RollbackTransaction(); err != nil {
// t.Fatalf("failed to rollback transaction: %s", err.Error())
// }
// r, err = db.Query("SELECT name FROM foo")
// if err != nil {
// t.Fatalf("failed to query after commited transaction: %s", err.Error())
// }
// if len(r) != 10 {
// t.Fatalf("incorrect number of results returned: %d", len(r))
// }
// }
// func Test_TransactionsConstraintViolation(t *testing.T) {
// db, path := mustCreateDatabase()
// defer db.Close()
// defer os.Remove(path)
// var err error
// if err = db.Execute("create table foo (id integer not null primary key, name text)"); err != nil {
// t.Fatalf("failed to create table: %s", err.Error())
// }
// if err = db.StartTransaction(); err != nil {
// t.Fatalf("failed to start transaction: %s", err.Error())
// }
// if err = db.Execute(`INSERT INTO foo(id, name) VALUES(11, "fiona")`); err != nil {
// t.Fatalf("failed to insert record: %s", err.Error())
// }
// if err = db.Execute(`INSERT INTO foo(id, name) VALUES(11, "fiona")`); err == nil {
// t.Fatal("duplicated record inserted OK")
// }
// if err.Error() != "UNIQUE constraint failed: foo.id" {
// t.Fatal("unexpected error returned")
// }
// if err := db.RollbackTransaction(); err != nil {
// t.Fatalf("failed to rollback transaction: %s", err.Error())
// }
// r, err := db.Query("SELECT name FROM foo")
// if err != nil {
// t.Fatalf("failed to query after commited transaction: %s", err.Error())
// }
// if len(r) != 0 {
// t.Fatalf("incorrect number of results returned: %d", len(r))
// }
// }
// func Test_TransactionsHardFail(t *testing.T) {
// db, path := mustCreateDatabase()
// defer db.Close()
// defer os.Remove(path)
// var err error
// if err = db.Execute("create table foo (id integer not null primary key, name text)"); err != nil {
// t.Fatalf("failed to create table: %s", err.Error())
// }
// if err = db.Execute(`INSERT INTO foo(id, name) VALUES(1, "fiona")`); err != nil {
// t.Fatalf("failed to insert record: %s", err.Error())
// }
// if err = db.StartTransaction(); err != nil {
// t.Fatalf("failed to start transaction: %s", err.Error())
// }
// if err = db.Execute(`INSERT INTO foo(id, name) VALUES(2, "fiona")`); err != nil {
// t.Fatalf("failed to insert record: %s", err.Error())
// }
// if err = db.Close(); err != nil {
// t.Fatalf("failed to close database: %s", err.Error())
// }
// db, err = Open(path)
// if err != nil {
// t.Fatalf("failed to re-open database: %s", err.Error())
// }
// r, err := db.Query("SELECT * FROM foo")
// if err != nil {
// t.Fatalf("failed to query after hard close: %s", err.Error())
// }
// if len(r) != 1 {
// t.Fatalf("incorrect number of results returned: %d", len(r))
// }
// }
func mustCreateDatabase() (*DB, string) {
var err error
f, err := ioutil.TempFile("", "rqlilte-test-")
if err != nil {
panic("failed to create temp file")
}
f.Close()
db, err := Open(f.Name())
if err != nil {
panic("failed to open database")
}
return db, f.Name()
}
func asJson(v interface{}) string {
b, err := json.Marshal(v)
if err != nil {
panic("failed to JSON marshal value")
}
return string(b)
}