github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/pkg/index/mysql/mysql_test.go (about) 1 /* 2 Copyright 2012 The Camlistore Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package mysql_test 18 19 import ( 20 "database/sql" 21 "errors" 22 "fmt" 23 "log" 24 "sync" 25 "testing" 26 27 "camlistore.org/pkg/index" 28 "camlistore.org/pkg/index/indextest" 29 "camlistore.org/pkg/osutil" 30 "camlistore.org/pkg/sorted" 31 "camlistore.org/pkg/sorted/kvtest" 32 "camlistore.org/pkg/sorted/mysql" 33 "camlistore.org/pkg/test" 34 35 _ "camlistore.org/third_party/github.com/ziutek/mymysql/godrv" 36 ) 37 38 var ( 39 once sync.Once 40 dbAvailable bool 41 rootdb *sql.DB 42 ) 43 44 func checkDB() { 45 var err error 46 rootdb, err = sql.Open("mymysql", "mysql/root/root") 47 if err != nil { 48 log.Printf("Could not open rootdb: %v", err) 49 return 50 } 51 var n int 52 err = rootdb.QueryRow("SELECT COUNT(*) FROM user").Scan(&n) 53 if err == nil { 54 dbAvailable = true 55 } 56 } 57 58 func skipOrFailIfNoMySQL(t *testing.T) { 59 once.Do(checkDB) 60 if !dbAvailable { 61 // TODO(bradfitz): accept somehow other passwords than 62 // 'root', and/or try localhost unix socket 63 // connections rather than using TCP localhost? 64 err := errors.New("Not running; start a MySQL daemon on the standard port (3306) with root password 'root'") 65 test.DependencyErrorOrSkip(t) 66 t.Fatalf("MySQL not available locally for testing: %v", err) 67 } 68 } 69 70 func do(db *sql.DB, sql string) { 71 _, err := db.Exec(sql) 72 if err == nil { 73 return 74 } 75 log.Fatalf("Error %v running SQL: %s", err, sql) 76 } 77 78 func newSorted(t *testing.T) (kv sorted.KeyValue, clean func()) { 79 skipOrFailIfNoMySQL(t) 80 dbname := "camlitest_" + osutil.Username() 81 do(rootdb, "DROP DATABASE IF EXISTS "+dbname) 82 do(rootdb, "CREATE DATABASE "+dbname) 83 84 db, err := sql.Open("mymysql", dbname+"/root/root") 85 if err != nil { 86 t.Fatalf("opening test database: " + err.Error()) 87 } 88 for _, tableSql := range mysql.SQLCreateTables() { 89 do(db, tableSql) 90 } 91 do(db, fmt.Sprintf(`REPLACE INTO meta VALUES ('version', '%d')`, mysql.SchemaVersion())) 92 93 kv, err = mysql.NewKeyValue(mysql.Config{ 94 Database: dbname, 95 User: "root", 96 Password: "root", 97 }) 98 if err != nil { 99 t.Fatal(err) 100 } 101 return kv, func() { 102 kv.Close() 103 } 104 } 105 106 func TestSortedKV(t *testing.T) { 107 kv, clean := newSorted(t) 108 defer clean() 109 kvtest.TestSorted(t, kv) 110 } 111 112 type mysqlTester struct{} 113 114 func (mysqlTester) test(t *testing.T, tfn func(*testing.T, func() *index.Index)) { 115 var mu sync.Mutex // guards cleanups 116 var cleanups []func() 117 defer func() { 118 mu.Lock() // never unlocked 119 for _, fn := range cleanups { 120 fn() 121 } 122 }() 123 makeIndex := func() *index.Index { 124 s, cleanup := newSorted(t) 125 mu.Lock() 126 cleanups = append(cleanups, cleanup) 127 mu.Unlock() 128 return index.New(s) 129 } 130 tfn(t, makeIndex) 131 } 132 133 func TestIndex_MySQL(t *testing.T) { 134 mysqlTester{}.test(t, indextest.Index) 135 } 136 137 func TestPathsOfSignerTarget_MySQL(t *testing.T) { 138 mysqlTester{}.test(t, indextest.PathsOfSignerTarget) 139 } 140 141 func TestFiles_MySQL(t *testing.T) { 142 mysqlTester{}.test(t, indextest.Files) 143 } 144 145 func TestEdgesTo_MySQL(t *testing.T) { 146 mysqlTester{}.test(t, indextest.EdgesTo) 147 } 148 149 func TestDelete_MySQL(t *testing.T) { 150 mysqlTester{}.test(t, indextest.Delete) 151 }