github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/cmd/noms/noms_sync_test.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2016 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package main 23 24 import ( 25 "context" 26 "os" 27 "testing" 28 29 "github.com/stretchr/testify/suite" 30 31 "github.com/dolthub/dolt/go/store/datas" 32 "github.com/dolthub/dolt/go/store/nbs" 33 "github.com/dolthub/dolt/go/store/spec" 34 "github.com/dolthub/dolt/go/store/types" 35 "github.com/dolthub/dolt/go/store/util/clienttest" 36 ) 37 38 func TestSync(t *testing.T) { 39 suite.Run(t, &nomsSyncTestSuite{}) 40 } 41 42 type nomsSyncTestSuite struct { 43 clienttest.ClientTestSuite 44 } 45 46 func (s *nomsSyncTestSuite) TestSyncValidation() { 47 cs, err := nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir, clienttest.DefaultMemTableSize) 48 s.NoError(err) 49 sourceDB := datas.NewDatabase(cs) 50 source1, err := sourceDB.GetDataset(context.Background(), "src") 51 s.NoError(err) 52 source1, err = sourceDB.CommitValue(context.Background(), source1, types.Float(42)) 53 s.NoError(err) 54 source1HeadRef, err := mustHead(source1).Hash(types.Format_7_18) 55 s.NoError(err) 56 source1.Database().Close() 57 sourceSpecMissingHashSymbol := spec.CreateValueSpecString("nbs", s.DBDir, source1HeadRef.String()) 58 59 sinkDatasetSpec := spec.CreateValueSpecString("nbs", s.DBDir2, "dest") 60 61 defer func() { 62 err := recover() 63 s.Equal(clienttest.ExitError{Code: 1}, err) 64 }() 65 66 s.MustRun(main, []string{"sync", sourceSpecMissingHashSymbol, sinkDatasetSpec}) 67 } 68 69 func (s *nomsSyncTestSuite) TestSync() { 70 defer s.NoError(os.RemoveAll(s.DBDir2)) 71 72 cs, err := nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir, clienttest.DefaultMemTableSize) 73 s.NoError(err) 74 sourceDB := datas.NewDatabase(cs) 75 source1, err := sourceDB.GetDataset(context.Background(), "src") 76 s.NoError(err) 77 source1, err = sourceDB.CommitValue(context.Background(), source1, types.Float(42)) 78 s.NoError(err) 79 source1HeadRef, err := mustHead(source1).Hash(types.Format_7_18) // Remember first head, so we can sync to it. 80 s.NoError(err) 81 source1, err = sourceDB.CommitValue(context.Background(), source1, types.Float(43)) 82 s.NoError(err) 83 sourceDB.Close() 84 85 // Pull from a hash to a not-yet-existing dataset in a new DB 86 sourceSpec := spec.CreateValueSpecString("nbs", s.DBDir, "#"+source1HeadRef.String()) 87 sinkDatasetSpec := spec.CreateValueSpecString("nbs", s.DBDir2, "dest") 88 sout, _ := s.MustRun(main, []string{"sync", sourceSpec, sinkDatasetSpec}) 89 s.Regexp("Synced", sout) 90 91 cs, err = nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir2, clienttest.DefaultMemTableSize) 92 s.NoError(err) 93 db := datas.NewDatabase(cs) 94 dest, err := db.GetDataset(context.Background(), "dest") 95 s.NoError(err) 96 s.True(types.Float(42).Equals(mustHeadValue(dest))) 97 db.Close() 98 99 // Pull from a dataset in one DB to an existing dataset in another 100 sourceDataset := spec.CreateValueSpecString("nbs", s.DBDir, "src") 101 sout, _ = s.MustRun(main, []string{"sync", sourceDataset, sinkDatasetSpec}) 102 s.Regexp("Synced", sout) 103 104 cs, err = nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir2, clienttest.DefaultMemTableSize) 105 s.NoError(err) 106 db = datas.NewDatabase(cs) 107 dest, err = db.GetDataset(context.Background(), "dest") 108 s.NoError(err) 109 s.True(types.Float(43).Equals(mustHeadValue(dest))) 110 db.Close() 111 112 // Pull when sink dataset is already up to date 113 sout, _ = s.MustRun(main, []string{"sync", sourceDataset, sinkDatasetSpec}) 114 s.Regexp("up to date", sout) 115 116 // Pull from a source dataset to a not-yet-existing dataset in another DB, BUT all the needed chunks already exists in the sink. 117 sinkDatasetSpec = spec.CreateValueSpecString("nbs", s.DBDir2, "dest2") 118 sout, _ = s.MustRun(main, []string{"sync", sourceDataset, sinkDatasetSpec}) 119 s.Regexp("Created", sout) 120 121 cs, err = nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir2, clienttest.DefaultMemTableSize) 122 s.NoError(err) 123 db = datas.NewDatabase(cs) 124 dest, err = db.GetDataset(context.Background(), "dest2") 125 s.NoError(err) 126 s.True(types.Float(43).Equals(mustHeadValue(dest))) 127 db.Close() 128 } 129 130 func (s *nomsSyncTestSuite) TestSync_Issue2598() { 131 defer s.NoError(os.RemoveAll(s.DBDir2)) 132 133 cs, err := nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir, clienttest.DefaultMemTableSize) 134 s.NoError(err) 135 sourceDB := datas.NewDatabase(cs) 136 // Create dataset "src1", which has a lineage of two commits. 137 source1, err := sourceDB.GetDataset(context.Background(), "src1") 138 s.NoError(err) 139 source1, err = sourceDB.CommitValue(context.Background(), source1, types.Float(42)) 140 s.NoError(err) 141 source1, err = sourceDB.CommitValue(context.Background(), source1, types.Float(43)) 142 s.NoError(err) 143 144 // Create dataset "src2", with a lineage of one commit. 145 source2, err := sourceDB.GetDataset(context.Background(), "src2") 146 s.NoError(err) 147 source2, err = sourceDB.CommitValue(context.Background(), source2, types.Float(1)) 148 s.NoError(err) 149 150 sourceDB.Close() // Close Database backing both Datasets 151 152 // Sync over "src1" 153 sourceDataset := spec.CreateValueSpecString("nbs", s.DBDir, "src1") 154 sinkDatasetSpec := spec.CreateValueSpecString("nbs", s.DBDir2, "dest") 155 sout, _ := s.MustRun(main, []string{"sync", sourceDataset, sinkDatasetSpec}) 156 cs, err = nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir2, clienttest.DefaultMemTableSize) 157 s.NoError(err) 158 db := datas.NewDatabase(cs) 159 dest, err := db.GetDataset(context.Background(), "dest") 160 s.NoError(err) 161 s.True(types.Float(43).Equals(mustHeadValue(dest))) 162 db.Close() 163 164 // Now, try syncing a second dataset. This crashed in issue #2598 165 sourceDataset2 := spec.CreateValueSpecString("nbs", s.DBDir, "src2") 166 sinkDatasetSpec2 := spec.CreateValueSpecString("nbs", s.DBDir2, "dest2") 167 sout, _ = s.MustRun(main, []string{"sync", sourceDataset2, sinkDatasetSpec2}) 168 cs, err = nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir2, clienttest.DefaultMemTableSize) 169 s.NoError(err) 170 db = datas.NewDatabase(cs) 171 dest, err = db.GetDataset(context.Background(), "dest2") 172 s.NoError(err) 173 s.True(types.Float(1).Equals(mustHeadValue(dest))) 174 db.Close() 175 176 sout, _ = s.MustRun(main, []string{"sync", sourceDataset, sinkDatasetSpec}) 177 s.Regexp("up to date", sout) 178 } 179 180 func (s *nomsSyncTestSuite) TestRewind() { 181 var err error 182 cs, err := nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir, clienttest.DefaultMemTableSize) 183 s.NoError(err) 184 sourceDB := datas.NewDatabase(cs) 185 src, err := sourceDB.GetDataset(context.Background(), "foo") 186 s.NoError(err) 187 src, err = sourceDB.CommitValue(context.Background(), src, types.Float(42)) 188 s.NoError(err) 189 rewindRef := mustHeadRef(src).TargetHash() 190 src, err = sourceDB.CommitValue(context.Background(), src, types.Float(43)) 191 s.NoError(err) 192 sourceDB.Close() // Close Database backing both Datasets 193 194 sourceSpec := spec.CreateValueSpecString("nbs", s.DBDir, "#"+rewindRef.String()) 195 sinkDatasetSpec := spec.CreateValueSpecString("nbs", s.DBDir, "foo") 196 s.MustRun(main, []string{"sync", sourceSpec, sinkDatasetSpec}) 197 198 cs, err = nbs.NewLocalStore(context.Background(), types.Format_Default.VersionString(), s.DBDir, clienttest.DefaultMemTableSize) 199 s.NoError(err) 200 db := datas.NewDatabase(cs) 201 dest, err := db.GetDataset(context.Background(), "foo") 202 s.NoError(err) 203 s.True(types.Float(42).Equals(mustHeadValue(dest))) 204 db.Close() 205 }