TestDB_Concurrent_WriteTo checks that issuing WriteTo operations concurrently with commits does not produce corrupted db files. It also verifies that all readonly transactions, which are created based on the same data view, should always read the same data.
(t *testing.T)
| 707 | // readonly transactions, which are created based on the same data view, should |
| 708 | // always read the same data. |
| 709 | func TestDB_Concurrent_WriteTo_and_ConsistentRead(t *testing.T) { |
| 710 | o := &bolt.Options{ |
| 711 | NoFreelistSync: false, |
| 712 | PageSize: 4096, |
| 713 | } |
| 714 | db := btesting.MustCreateDBWithOption(t, o) |
| 715 | |
| 716 | wtxs, rtxs := 50, 5 |
| 717 | bucketName := []byte("data") |
| 718 | |
| 719 | var dataLock sync.Mutex |
| 720 | dataCache := make(map[int][]map[string]string) |
| 721 | |
| 722 | var wg sync.WaitGroup |
| 723 | wg.Add(wtxs * rtxs) |
| 724 | f := func(round int, tx *bolt.Tx) { |
| 725 | defer wg.Done() |
| 726 | time.Sleep(time.Duration(rand.Intn(200)+10) * time.Millisecond) |
| 727 | f := filepath.Join(t.TempDir(), fmt.Sprintf("%d-bolt-", round)) |
| 728 | err := tx.CopyFile(f, 0600) |
| 729 | require.NoError(t, err) |
| 730 | |
| 731 | // read all the data |
| 732 | b := tx.Bucket(bucketName) |
| 733 | data := make(map[string]string) |
| 734 | err = b.ForEach(func(k, v []byte) error { |
| 735 | data[string(k)] = string(v) |
| 736 | return nil |
| 737 | }) |
| 738 | require.NoError(t, err) |
| 739 | |
| 740 | // cache the data |
| 741 | dataLock.Lock() |
| 742 | dataSlice := dataCache[round] |
| 743 | dataSlice = append(dataSlice, data) |
| 744 | dataCache[round] = dataSlice |
| 745 | dataLock.Unlock() |
| 746 | |
| 747 | err = tx.Rollback() |
| 748 | require.NoError(t, err) |
| 749 | |
| 750 | copyOpt := *o |
| 751 | snap := btesting.MustOpenDBWithOption(t, f, ©Opt) |
| 752 | defer snap.MustClose() |
| 753 | snap.MustCheck() |
| 754 | } |
| 755 | |
| 756 | err := db.Update(func(tx *bolt.Tx) error { |
| 757 | _, err := tx.CreateBucket(bucketName) |
| 758 | return err |
| 759 | }) |
| 760 | require.NoError(t, err) |
| 761 | |
| 762 | for i := 0; i < wtxs; i++ { |
| 763 | tx, err := db.Begin(true) |
| 764 | require.NoError(t, err) |
| 765 | |
| 766 | b := tx.Bucket(bucketName) |
nothing calls this directly
no test coverage detected