backend_test.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright (C) 2019 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package backend
  7. import "testing"
  8. // testBackendBehavior is the generic test suite that must be fulfilled by
  9. // every backend implementation. It should be called by each implementation
  10. // as (part of) their test suite.
  11. func testBackendBehavior(t *testing.T, open func() Backend) {
  12. t.Run("WriteIsolation", func(t *testing.T) { testWriteIsolation(t, open) })
  13. t.Run("DeleteNonexisten", func(t *testing.T) { testDeleteNonexistent(t, open) })
  14. t.Run("IteratorClosedDB", func(t *testing.T) { testIteratorClosedDB(t, open) })
  15. }
  16. func testWriteIsolation(t *testing.T, open func() Backend) {
  17. // Values written during a transaction should not be read back, our
  18. // updateGlobal depends on this.
  19. db := open()
  20. defer db.Close()
  21. // Sanity check
  22. _ = db.Put([]byte("a"), []byte("a"))
  23. v, _ := db.Get([]byte("a"))
  24. if string(v) != "a" {
  25. t.Fatal("read back should work")
  26. }
  27. // Now in a transaction we should still see the old value
  28. tx, _ := db.NewWriteTransaction()
  29. defer tx.Release()
  30. _ = tx.Put([]byte("a"), []byte("b"))
  31. v, _ = tx.Get([]byte("a"))
  32. if string(v) != "a" {
  33. t.Fatal("read in transaction should read the old value")
  34. }
  35. }
  36. func testDeleteNonexistent(t *testing.T, open func() Backend) {
  37. // Deleting a non-existent key is not an error
  38. db := open()
  39. defer db.Close()
  40. err := db.Delete([]byte("a"))
  41. if err != nil {
  42. t.Error(err)
  43. }
  44. }
  45. // Either creating the iterator or the .Error() method of the returned iterator
  46. // should return an error and IsClosed(err) == true.
  47. func testIteratorClosedDB(t *testing.T, open func() Backend) {
  48. db := open()
  49. _ = db.Put([]byte("a"), []byte("a"))
  50. db.Close()
  51. it, err := db.NewPrefixIterator(nil)
  52. if err != nil {
  53. if !IsClosed(err) {
  54. t.Error("NewPrefixIterator: IsClosed(err) == false:", err)
  55. }
  56. return
  57. }
  58. it.Next()
  59. if err := it.Error(); !IsClosed(err) {
  60. t.Error("Next: IsClosed(err) == false:", err)
  61. }
  62. }