MCPcopy
hub / github.com/rqlite/rqlite / Test_SingleNodeSnapshot_CheckpointFailures

Function Test_SingleNodeSnapshot_CheckpointFailures

store/store_snapshot_test.go:718–842  ·  view source on GitHub ↗

Test_SingleNodeSnapshot_CheckpointFailures tests the Store responds correctly when checkpoint of the underlying database returns an error. This can happen depending on active readers of the database. The Store should handle active readers fine, aborting the snapshot, and handling it next time. This

(t *testing.T)

Source from the content-addressed store, hash-verified

716// readers fine, aborting the snapshot, and handling it next time. This tests
717// critical code paths which are very rare, but are perfectly possible in production.
718func Test_SingleNodeSnapshot_CheckpointFailures(t *testing.T) {
719 s, ln := mustNewStore(t)
720 defer ln.Close()
721
722 if err := s.Open(); err != nil {
723 t.Fatalf("failed to open single-node store: %s", err.Error())
724 }
725 defer s.Close(true)
726 s.NoSnapshotOnClose = true
727 if err := s.Bootstrap(NewServer(s.ID(), s.Addr(), true)); err != nil {
728 t.Fatalf("failed to bootstrap single-node store: %s", err.Error())
729 }
730 if _, err := s.WaitForLeader(10 * time.Second); err != nil {
731 t.Fatalf("Error waiting for leader: %s", err)
732 }
733
734 queries := []string{
735 `CREATE TABLE foo (id INTEGER NOT NULL PRIMARY KEY, name TEXT)`,
736 `INSERT INTO foo(name) VALUES("fiona")`,
737 }
738 mustExecute(t, s, queries)
739
740 ////////////////////////////////////////////////////////////////////////////
741 // Start testing with stalled queries.
742
743 startStalledQuery := func(srcDB *db.DB) context.CancelFunc {
744 ctx, cancelFunc := context.WithCancel(context.Background())
745 go func() {
746 srcDB.QueryWithContext(ctx, mustCreateRequest(`SELECT * FROM foo`), false)
747 }()
748 time.Sleep(time.Second)
749 return cancelFunc
750 }
751
752 srcDB, err := db.Open(s.dbPath, false, true)
753 if err != nil {
754 t.Fatalf("failed to open database: %s", err)
755 }
756 defer srcDB.Close()
757
758 cancelFunc := startStalledQuery(srcDB)
759
760 // First snapshot, which will be full, will fail due to the reader.
761 if err := s.Snapshot(0); err == nil {
762 t.Fatalf("expected error due to blocking reader when attempting first snapshot")
763 }
764
765 // Release the reader, full snapshot should work.
766 cancelFunc()
767 if err := s.Snapshot(0); err != nil {
768 t.Fatalf("failed to snapshot after canceling reader: %s", err)
769 }
770
771 //////////////////////////////////////////////////////////////////////////////////
772 // Insert a bunch of records, which will be added to the WAL. Then start
773 // a reader which should be reading from the last page in the WAL. This will
774 // mean snapshot will be OK.
775 clear(queries)

Callers

nothing calls this directly

Calls 15

OpenFunction · 0.92
mustNewStoreFunction · 0.85
NewServerFunction · 0.85
mustCreateRequestFunction · 0.85
BootstrapMethod · 0.80
ForceSnapshotRestoreMethod · 0.80
mustExecuteFunction · 0.70
queryRequestFromStringFunction · 0.70
asJSONFunction · 0.70
CloseMethod · 0.65
OpenMethod · 0.65
ErrorMethod · 0.65

Tested by

no test coverage detected