github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/datas/dataset_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 datas 23 24 import ( 25 "context" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 30 "github.com/dolthub/dolt/go/store/chunks" 31 "github.com/dolthub/dolt/go/store/d" 32 "github.com/dolthub/dolt/go/store/types" 33 ) 34 35 func mustGetValue(v types.Value, found bool, err error) types.Value { 36 d.PanicIfError(err) 37 d.PanicIfFalse(found) 38 return v 39 } 40 41 func TestExplicitBranchUsingDatasets(t *testing.T) { 42 assert := assert.New(t) 43 id1 := "testdataset" 44 id2 := "othertestdataset" 45 stg := &chunks.MemoryStorage{} 46 store := NewDatabase(stg.NewView()) 47 defer store.Close() 48 49 ds1, err := store.GetDataset(context.Background(), id1) 50 assert.NoError(err) 51 52 // ds1: |a| 53 a := types.String("a") 54 ds1, err = store.CommitValue(context.Background(), ds1, a) 55 assert.NoError(err) 56 assert.True(mustGetValue(mustHead(ds1).MaybeGet(ValueField)).Equals(a)) 57 58 // ds1: |a| 59 // \ds2 60 ds2, err := store.GetDataset(context.Background(), id2) 61 assert.NoError(err) 62 ds2, err = store.Commit(context.Background(), ds2, mustHeadValue(ds1), CommitOptions{ParentsList: mustList(types.NewList(context.Background(), store, mustHeadRef(ds1)))}) 63 assert.NoError(err) 64 assert.True(mustGetValue(mustHead(ds2).MaybeGet(ValueField)).Equals(a)) 65 66 // ds1: |a| <- |b| 67 b := types.String("b") 68 ds1, err = store.CommitValue(context.Background(), ds1, b) 69 assert.NoError(err) 70 assert.True(mustGetValue(mustHead(ds1).MaybeGet(ValueField)).Equals(b)) 71 72 // ds1: |a| <- |b| 73 // \ds2 <- |c| 74 c := types.String("c") 75 ds2, err = store.CommitValue(context.Background(), ds2, c) 76 assert.NoError(err) 77 assert.True(mustGetValue(mustHead(ds2).MaybeGet(ValueField)).Equals(c)) 78 79 // ds1: |a| <- |b| <--|d| 80 // \ds2 <- |c| <--/ 81 mergeParents, err := types.NewList(context.Background(), store, mustRef(types.NewRef(mustHead(ds1), types.Format_7_18)), mustRef(types.NewRef(mustHead(ds2), types.Format_7_18))) 82 assert.NoError(err) 83 d := types.String("d") 84 ds2, err = store.Commit(context.Background(), ds2, d, CommitOptions{ParentsList: mergeParents}) 85 assert.NoError(err) 86 assert.True(mustGetValue(mustHead(ds2).MaybeGet(ValueField)).Equals(d)) 87 88 ds1, err = store.Commit(context.Background(), ds1, d, CommitOptions{ParentsList: mergeParents}) 89 assert.NoError(err) 90 assert.True(mustGetValue(mustHead(ds1).MaybeGet(ValueField)).Equals(d)) 91 } 92 93 func TestTwoClientsWithEmptyDataset(t *testing.T) { 94 assert := assert.New(t) 95 id1 := "testdataset" 96 stg := &chunks.MemoryStorage{} 97 store := NewDatabase(stg.NewView()) 98 defer store.Close() 99 100 dsx, err := store.GetDataset(context.Background(), id1) 101 assert.NoError(err) 102 dsy, err := store.GetDataset(context.Background(), id1) 103 assert.NoError(err) 104 105 // dsx: || -> |a| 106 a := types.String("a") 107 dsx, err = store.CommitValue(context.Background(), dsx, a) 108 assert.NoError(err) 109 assert.True(mustGetValue(mustHead(dsx).MaybeGet(ValueField)).Equals(a)) 110 111 // dsy: || -> |b| 112 _, ok := dsy.MaybeHead() 113 assert.False(ok) 114 b := types.String("b") 115 _, err = store.CommitValue(context.Background(), dsy, b) 116 assert.Error(err) 117 118 // Commit failed, but dsy now has latest head, so we should be able to just try again. 119 // dsy: |a| -> |b| 120 dsy, err = store.GetDataset(context.Background(), id1) 121 assert.NoError(err) 122 dsy, err = store.CommitValue(context.Background(), dsy, b) 123 assert.NoError(err) 124 headVal := mustHeadValue(dsy) 125 assert.True(headVal.Equals(b)) 126 } 127 128 func TestTwoClientsWithNonEmptyDataset(t *testing.T) { 129 assert := assert.New(t) 130 id1 := "testdataset" 131 stg := &chunks.MemoryStorage{} 132 store := NewDatabase(stg.NewView()) 133 defer store.Close() 134 135 a := types.String("a") 136 { 137 // ds1: || -> |a| 138 ds1, err := store.GetDataset(context.Background(), id1) 139 assert.NoError(err) 140 ds1, err = store.CommitValue(context.Background(), ds1, a) 141 assert.NoError(err) 142 assert.True(mustGetValue(mustHead(ds1).MaybeGet(ValueField)).Equals(a)) 143 } 144 145 dsx, err := store.GetDataset(context.Background(), id1) 146 assert.NoError(err) 147 dsy, err := store.GetDataset(context.Background(), id1) 148 assert.NoError(err) 149 150 // dsx: |a| -> |b| 151 assert.True(mustGetValue(mustHead(dsx).MaybeGet(ValueField)).Equals(a)) 152 b := types.String("b") 153 dsx, err = store.CommitValue(context.Background(), dsx, b) 154 assert.NoError(err) 155 assert.True(mustGetValue(mustHead(dsx).MaybeGet(ValueField)).Equals(b)) 156 157 // dsy: |a| -> |c| 158 assert.True(mustGetValue(mustHead(dsy).MaybeGet(ValueField)).Equals(a)) 159 c := types.String("c") 160 _, err = store.CommitValue(context.Background(), dsy, c) 161 assert.Error(err) 162 // Commit failed, but dsy now has latest head, so we should be able to just try again. 163 // dsy: |b| -> |c| 164 dsy, err = store.GetDataset(context.Background(), id1) 165 assert.NoError(err) 166 dsy, err = store.CommitValue(context.Background(), dsy, c) 167 assert.NoError(err) 168 assert.True(mustGetValue(mustHead(dsy).MaybeGet(ValueField)).Equals(c)) 169 } 170 171 func TestIdValidation(t *testing.T) { 172 assert := assert.New(t) 173 stg := &chunks.MemoryStorage{} 174 store := NewDatabase(stg.NewView()) 175 176 invalidDatasetNames := []string{" ", "", "a ", " a", "$", "#", ":", "\n", "💩"} 177 for _, id := range invalidDatasetNames { 178 _, err := store.GetDataset(context.Background(), id) 179 assert.Error(err) 180 } 181 } 182 183 func TestHeadValueFunctions(t *testing.T) { 184 assert := assert.New(t) 185 186 id1 := "testdataset" 187 id2 := "otherdataset" 188 stg := &chunks.MemoryStorage{} 189 store := NewDatabase(stg.NewView()) 190 defer store.Close() 191 192 ds1, err := store.GetDataset(context.Background(), id1) 193 assert.NoError(err) 194 assert.False(ds1.HasHead()) 195 196 // ds1: |a| 197 a := types.String("a") 198 ds1, err = store.CommitValue(context.Background(), ds1, a) 199 assert.NoError(err) 200 assert.True(ds1.HasHead()) 201 202 hv, ok, err := mustHead(ds1).MaybeGet(ValueField) 203 assert.True(ok) 204 assert.NoError(err) 205 assert.Equal(a, hv) 206 assert.Equal(a, mustHeadValue(ds1)) 207 208 hv, ok, err = ds1.MaybeHeadValue() 209 assert.NoError(err) 210 assert.True(ok) 211 assert.Equal(a, hv) 212 213 ds2, err := store.GetDataset(context.Background(), id2) 214 assert.NoError(err) 215 _, ok, err = ds2.MaybeHeadValue() 216 assert.NoError(err) 217 assert.False(ok) 218 } 219 220 func TestIsValidDatasetName(t *testing.T) { 221 assert := assert.New(t) 222 cases := []struct { 223 name string 224 valid bool 225 }{ 226 {"foo", true}, 227 {"foo/bar", true}, 228 {"f1", true}, 229 {"1f", true}, 230 {"", false}, 231 {"f!!", false}, 232 } 233 for _, c := range cases { 234 assert.Equal(c.valid, IsValidDatasetName(c.name), 235 "Expected %s validity to be %t", c.name, c.valid) 236 } 237 }