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  }