mirror of https://github.com/etcd-io/bbolt.git
Add test case inline documentation.
parent
aa13f7f94f
commit
df52bd0803
8
db.go
8
db.go
|
@ -102,10 +102,12 @@ type DB struct {
|
||||||
statlock sync.RWMutex // Protects stats access.
|
statlock sync.RWMutex // Protects stats access.
|
||||||
|
|
||||||
ops struct {
|
ops struct {
|
||||||
writeAt func(b []byte, off int64) (n int, err error)
|
writeAt func(b []byte, off int64) (n int, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
readOnly bool // Read only mode. Update()/Begin(true) would return ErrDatabaseReadOnly immediately.
|
// Read only mode.
|
||||||
|
// When true, Update() and Begin(true) return ErrDatabaseReadOnly immediately.
|
||||||
|
readOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path returns the path to currently open database file.
|
// Path returns the path to currently open database file.
|
||||||
|
@ -440,9 +442,11 @@ func (db *DB) beginTx() (*Tx, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) beginRWTx() (*Tx, error) {
|
func (db *DB) beginRWTx() (*Tx, error) {
|
||||||
|
// If the database was opened with Options.ReadOnly, return an error.
|
||||||
if db.readOnly {
|
if db.readOnly {
|
||||||
return nil, ErrDatabaseReadOnly
|
return nil, ErrDatabaseReadOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain writer lock. This is released by the transaction when it closes.
|
// Obtain writer lock. This is released by the transaction when it closes.
|
||||||
// This enforces only one writer transaction at a time.
|
// This enforces only one writer transaction at a time.
|
||||||
db.rwlock.Lock()
|
db.rwlock.Lock()
|
||||||
|
|
20
db_test.go
20
db_test.go
|
@ -228,11 +228,12 @@ func TestDB_Open_FileTooSmall(t *testing.T) {
|
||||||
// and that a database can not be opened in read-write mode and in read-only
|
// and that a database can not be opened in read-write mode and in read-only
|
||||||
// mode at the same time.
|
// mode at the same time.
|
||||||
func TestOpen_ReadOnly(t *testing.T) {
|
func TestOpen_ReadOnly(t *testing.T) {
|
||||||
var bucket = []byte(`bucket`)
|
bucket, key, value := []byte(`bucket`), []byte(`key`), []byte(`value`)
|
||||||
var key = []byte(`key`)
|
|
||||||
var value = []byte(`value`)
|
|
||||||
path := tempfile()
|
path := tempfile()
|
||||||
defer os.Remove(path)
|
defer os.Remove(path)
|
||||||
|
|
||||||
|
// Open in read-write mode.
|
||||||
db, err := bolt.Open(path, 0666, nil)
|
db, err := bolt.Open(path, 0666, nil)
|
||||||
ok(t, db.Update(func(tx *bolt.Tx) error {
|
ok(t, db.Update(func(tx *bolt.Tx) error {
|
||||||
b, err := tx.CreateBucket(bucket)
|
b, err := tx.CreateBucket(bucket)
|
||||||
|
@ -245,33 +246,44 @@ func TestOpen_ReadOnly(t *testing.T) {
|
||||||
assert(t, !db.IsReadOnly(), "")
|
assert(t, !db.IsReadOnly(), "")
|
||||||
ok(t, err)
|
ok(t, err)
|
||||||
ok(t, db.Close())
|
ok(t, db.Close())
|
||||||
|
|
||||||
// Open in read-only mode.
|
// Open in read-only mode.
|
||||||
db0, err := bolt.Open(path, 0666, &bolt.Options{ReadOnly: true})
|
db0, err := bolt.Open(path, 0666, &bolt.Options{ReadOnly: true})
|
||||||
ok(t, err)
|
ok(t, err)
|
||||||
defer db0.Close()
|
defer db0.Close()
|
||||||
// Try opening in regular mode.
|
|
||||||
|
// Opening in read-write mode should return an error.
|
||||||
_, err = bolt.Open(path, 0666, &bolt.Options{Timeout: time.Millisecond * 100})
|
_, err = bolt.Open(path, 0666, &bolt.Options{Timeout: time.Millisecond * 100})
|
||||||
assert(t, err != nil, "")
|
assert(t, err != nil, "")
|
||||||
|
|
||||||
// And again (in read-only mode).
|
// And again (in read-only mode).
|
||||||
db1, err := bolt.Open(path, 0666, &bolt.Options{ReadOnly: true})
|
db1, err := bolt.Open(path, 0666, &bolt.Options{ReadOnly: true})
|
||||||
ok(t, err)
|
ok(t, err)
|
||||||
defer db1.Close()
|
defer db1.Close()
|
||||||
|
|
||||||
|
// Verify both read-only databases are accessible.
|
||||||
for _, db := range []*bolt.DB{db0, db1} {
|
for _, db := range []*bolt.DB{db0, db1} {
|
||||||
// Verify is is in read only mode indeed.
|
// Verify is is in read only mode indeed.
|
||||||
assert(t, db.IsReadOnly(), "")
|
assert(t, db.IsReadOnly(), "")
|
||||||
|
|
||||||
|
// Read-only databases should not allow updates.
|
||||||
assert(t,
|
assert(t,
|
||||||
bolt.ErrDatabaseReadOnly == db.Update(func(*bolt.Tx) error {
|
bolt.ErrDatabaseReadOnly == db.Update(func(*bolt.Tx) error {
|
||||||
panic(`should never get here`)
|
panic(`should never get here`)
|
||||||
}),
|
}),
|
||||||
"")
|
"")
|
||||||
|
|
||||||
|
// Read-only databases should not allow beginning writable txns.
|
||||||
_, err = db.Begin(true)
|
_, err = db.Begin(true)
|
||||||
assert(t, bolt.ErrDatabaseReadOnly == err, "")
|
assert(t, bolt.ErrDatabaseReadOnly == err, "")
|
||||||
|
|
||||||
// Verify the data.
|
// Verify the data.
|
||||||
ok(t, db.View(func(tx *bolt.Tx) error {
|
ok(t, db.View(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket(bucket)
|
b := tx.Bucket(bucket)
|
||||||
if b == nil {
|
if b == nil {
|
||||||
return fmt.Errorf("expected bucket `%s`", string(bucket))
|
return fmt.Errorf("expected bucket `%s`", string(bucket))
|
||||||
}
|
}
|
||||||
|
|
||||||
got := string(b.Get(key))
|
got := string(b.Get(key))
|
||||||
expected := string(value)
|
expected := string(value)
|
||||||
if got != expected {
|
if got != expected {
|
||||||
|
|
Loading…
Reference in New Issue