1 package database_test
2 3 import (
4 "fmt"
5 "testing"
6 7 "github.com/p9c/p9/pkg/database"
8 _ "github.com/p9c/p9/pkg/database/ffldb"
9 )
10 11 var (
12 // ignoreDbTypes are types which should be ignored when running tests that iterate all supported DB types. This allows
13 // some tests to add bogus drivers for testing purposes while still allowing other tests to easily iterate all
14 // supported drivers.
15 ignoreDbTypes = map[string]bool{"createopenfail": true}
16 )
17 18 // checkDbError ensures the passed error is a database.DBError with an error code that matches the passed error code.
19 func checkDbError(t *testing.T, testName string, gotErr error, wantErrCode database.ErrorCode) bool {
20 dbErr, ok := gotErr.(database.DBError)
21 if !ok {
22 t.Errorf("%s: unexpected error type - got %T, want %T",
23 testName, gotErr, database.DBError{},
24 )
25 return false
26 }
27 if dbErr.ErrorCode != wantErrCode {
28 t.Errorf("%s: unexpected error code - got %s (%s), want %s",
29 testName, dbErr.ErrorCode, dbErr.Description,
30 wantErrCode,
31 )
32 return false
33 }
34 return true
35 }
36 37 // TestAddDuplicateDriver ensures that adding a duplicate driver does not overwrite an existing one.
38 func TestAddDuplicateDriver(t *testing.T) {
39 supportedDrivers := database.SupportedDrivers()
40 if len(supportedDrivers) == 0 {
41 t.Errorf("no backends to test")
42 return
43 }
44 dbType := supportedDrivers[0]
45 // bogusCreateDB is a function which acts as a bogus create and open driver function and intentionally returns a
46 // failure that can be detected if the interface allows a duplicate driver to overwrite an existing one.
47 bogusCreateDB := func(args ...interface{}) (database.DB, error) {
48 return nil, fmt.Errorf("duplicate driver allowed for database "+
49 "type [%v]", dbType,
50 )
51 }
52 // Create a driver that tries to replace an existing one. Set its create and open functions to a function that
53 // causes a test failure if they are invoked.
54 driver := database.Driver{
55 DbType: dbType,
56 Create: bogusCreateDB,
57 Open: bogusCreateDB,
58 }
59 testName := "duplicate driver registration"
60 e := database.RegisterDriver(driver)
61 if !checkDbError(t, testName, e, database.ErrDbTypeRegistered) {
62 return
63 }
64 }
65 66 // TestCreateOpenFail ensures that errors which occur while opening or closing a database are handled properly.
67 func TestCreateOpenFail(t *testing.T) {
68 // bogusCreateDB is a function which acts as a bogus create and open driver function that intentionally returns a
69 // failure which can be detected.
70 dbType := "createopenfail"
71 openError := fmt.Errorf("failed to create or open database for "+
72 "database type [%v]", dbType,
73 )
74 bogusCreateDB := func(args ...interface{}) (database.DB, error) {
75 return nil, openError
76 }
77 // Create and add driver that intentionally fails when created or opened to ensure errors on database open and
78 // create are handled properly.
79 driver := database.Driver{
80 DbType: dbType,
81 Create: bogusCreateDB,
82 Open: bogusCreateDB,
83 }
84 e := database.RegisterDriver(driver)
85 if e != nil {
86 t.Log(e)
87 }
88 // Ensure creating a database with the new type fails with the expected error.
89 _, e = database.Create(dbType)
90 if e != openError {
91 t.Errorf("expected error not received - got: %v, want %v", e,
92 openError,
93 )
94 return
95 }
96 // Ensure opening a database with the new type fails with the expected error.
97 _, e = database.Open(dbType)
98 if e != openError {
99 t.Errorf("expected error not received - got: %v, want %v", e,
100 openError,
101 )
102 return
103 }
104 }
105 106 // TestCreateOpenUnsupported ensures that attempting to create or open an unsupported database type is handled properly.
107 func TestCreateOpenUnsupported(t *testing.T) {
108 // Ensure creating a database with an unsupported type fails with the expected error.
109 testName := "create with unsupported database type"
110 dbType := "unsupported"
111 _, e := database.Create(dbType)
112 if !checkDbError(t, testName, e, database.ErrDbUnknownType) {
113 return
114 }
115 // Ensure opening a database with the an unsupported type fails with the expected error.
116 testName = "open with unsupported database type"
117 _, e = database.Open(dbType)
118 if !checkDbError(t, testName, e, database.ErrDbUnknownType) {
119 return
120 }
121 }
122