Files
dolt/go/spec/dataspec_test.go

271 lines
8.4 KiB
Go

// Copyright 2016 Attic Labs, Inc. All rights reserved.
// Licensed under the Apache License, version 2.0:
// http://www.apache.org/licenses/LICENSE-2.0
package spec
import (
"fmt"
"io/ioutil"
"os"
"path"
"testing"
"github.com/attic-labs/noms/go/chunks"
"github.com/attic-labs/noms/go/datas"
"github.com/attic-labs/noms/go/dataset"
"github.com/attic-labs/noms/go/types"
"github.com/attic-labs/testify/assert"
)
func TestLDBDatabase(t *testing.T) {
assert := assert.New(t)
d1 := os.TempDir()
dir, err := ioutil.TempDir(d1, "flags")
assert.NoError(err)
ldbDir := path.Join(dir, "store")
spec := fmt.Sprintf("ldb:%s", path.Join(dir, "store"))
cs := chunks.NewLevelDBStoreUseFlags(ldbDir, "")
ds := datas.NewDatabase(cs)
s1 := types.String("A String")
s1Hash := ds.WriteValue(s1)
ds.Commit("testDs", datas.NewCommit().Set(datas.ValueField, s1Hash))
ds.Close()
sp, errRead := parseDatabaseSpec(spec)
assert.NoError(errRead)
store, err := sp.Database()
assert.NoError(err)
assert.Equal(s1, store.ReadValue(s1.Hash()))
store.Close()
os.Remove(dir)
}
func TestMemDatabase(t *testing.T) {
assert := assert.New(t)
spec := "mem"
sp, err := parseDatabaseSpec(spec)
assert.NoError(err)
store, err := sp.Database()
assert.NoError(err)
r := store.WriteValue(types.Bool(true))
assert.NoError(err)
assert.Equal(types.Bool(true), store.ReadValue(r.TargetHash()))
}
func TestMemDataset(t *testing.T) {
assert := assert.New(t)
spec := "mem::datasetTest"
sp1, err := parseDatasetSpec(spec)
assert.NoError(err)
dataset1, err := sp1.Dataset()
assert.NoError(err)
commit := types.String("Commit Value")
dsTest, err := dataset1.Commit(commit)
assert.NoError(err)
assert.EqualValues(commit, dsTest.HeadValue())
}
func TestLDBDataset(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(os.TempDir(), "")
assert.NoError(err)
ldbPath := path.Join(dir, "name")
cs := chunks.NewLevelDBStoreUseFlags(ldbPath, "")
ds := datas.NewDatabase(cs)
id := "dsName"
set := dataset.NewDataset(ds, id)
commit := types.String("Commit Value")
set, err = set.Commit(commit)
assert.NoError(err)
ds.Close()
spec := fmt.Sprintf("ldb:%s::%s", ldbPath, id)
sp, err := parseDatasetSpec(spec)
assert.NoError(err)
dataset, err := sp.Dataset()
assert.NoError(err)
assert.EqualValues(commit, dataset.HeadValue())
os.Remove(dir)
}
func TestLDBObject(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(os.TempDir(), "")
assert.NoError(err)
ldbpath := path.Join(dir, "xx-yy")
dsId := "dsId"
cs1 := chunks.NewLevelDBStoreUseFlags(ldbpath, "")
store1 := datas.NewDatabase(cs1)
dataset1 := dataset.NewDataset(store1, dsId)
s1 := types.String("Commit Value")
r1 := store1.WriteValue(s1)
_, err = dataset1.Commit(r1)
assert.NoError(err)
store1.Close()
spec2 := fmt.Sprintf("ldb:%s::%s", ldbpath, dsId)
assert.NoError(err)
sp1, err := parseDatasetSpec(spec2)
assert.NoError(err)
dataset2, err := sp1.Dataset()
assert.NoError(err)
r2 := dataset2.HeadValue()
s2 := r2.(types.Ref).TargetValue(dataset2.Database())
assert.Equal(s1, s2)
dataset2.Database().Close()
spec3 := fmt.Sprintf("ldb:%s::#%s", ldbpath, s1.Hash().String())
sp3, err := parsePathSpec(spec3)
assert.NoError(err)
database, v3, err := sp3.Value()
assert.NoError(err)
assert.Equal(s1, v3)
database.Close()
}
func TestReadHash(t *testing.T) {
assert := assert.New(t)
dir, err := ioutil.TempDir(os.TempDir(), "")
assert.NoError(err)
datasetId := "dsName"
ldbPath := path.Join(dir, "/name")
cs1 := chunks.NewLevelDBStoreUseFlags(ldbPath, "")
database1 := datas.NewDatabase(cs1)
dataset1 := dataset.NewDataset(database1, datasetId)
commit := types.String("Commit Value")
dataset1, err = dataset1.Commit(commit)
assert.NoError(err)
r1 := dataset1.Head().Hash()
dataset1.Database().Close()
spec2 := fmt.Sprintf("ldb:%s::#%s", ldbPath, r1.String())
sp2, err := parsePathSpec(spec2)
assert.NoError(err)
database, v2, err := sp2.Value()
assert.NoError(err)
assert.EqualValues(r1.String(), v2.Hash().String())
database.Close()
}
func TestDatabaseSpecs(t *testing.T) {
assert := assert.New(t)
badSpecs := []string{"mem:stuff", "mem:", "http:", "https:", "random:", "random:random", "/file/ba:d"}
for _, spec := range badSpecs {
_, err := parseDatabaseSpec(spec)
assert.Error(err, spec)
}
type testCase struct {
spec, scheme, path, accessToken string
}
testCases := []testCase{
testCase{"http://localhost:8000", "http", "//localhost:8000", ""},
testCase{"http://localhost:8000/fff", "http", "//localhost:8000/fff", ""},
testCase{"https://local.attic.io/john/doe", "https", "//local.attic.io/john/doe", ""},
testCase{"ldb:/filesys/john/doe", "ldb", "/filesys/john/doe", ""},
testCase{"./john/doe", "ldb", "./john/doe", ""},
testCase{"john/doe", "ldb", "john/doe", ""},
testCase{"/john/doe", "ldb", "/john/doe", ""},
testCase{"mem", "mem", "", ""},
testCase{"http://server.com/john/doe?access_token=jane", "http", "//server.com/john/doe?access_token=jane", "jane"},
testCase{"https://server.com/john/doe/?arg=2&qp1=true&access_token=jane", "https", "//server.com/john/doe/?arg=2&qp1=true&access_token=jane", "jane"},
}
for _, tc := range testCases {
dbSpec, err := parseDatabaseSpec(tc.spec)
assert.NoError(err)
assert.Equal(databaseSpec{Protocol: tc.scheme, Path: tc.path, accessToken: tc.accessToken}, dbSpec)
}
}
func TestDatasetSpecs(t *testing.T) {
assert := assert.New(t)
badSpecs := []string{"mem", "mem:", "mem:::ds", "http", "http:", "http://foo", "monkey", "monkey:balls", "mem:/a/bogus/path:dsname", "http://localhost:8000/one"}
for _, spec := range badSpecs {
_, err := parseDatasetSpec(spec)
assert.Error(err, spec)
}
invalidDatasetNames := []string{" ", "", "$", "#", ":", "\n", "💩"}
for _, s := range invalidDatasetNames {
_, err := parseDatasetSpec("mem::" + s)
assert.Error(err)
}
validDatasetNames := []string{"a", "Z", "0", "/", "-", "_"}
for _, s := range validDatasetNames {
_, err := parseDatasetSpec("mem::" + s)
assert.NoError(err)
}
type testCase struct {
spec, scheme, path, ds, accessToken string
}
testCases := []testCase{
testCase{"http://localhost:8000::ds1", "http", "//localhost:8000", "ds1", ""},
testCase{"http://localhost:8000/john/doe/::ds2", "http", "//localhost:8000/john/doe/", "ds2", ""},
testCase{"https://local.attic.io/john/doe::ds3", "https", "//local.attic.io/john/doe", "ds3", ""},
testCase{"http://local.attic.io/john/doe::ds1", "http", "//local.attic.io/john/doe", "ds1", ""},
testCase{"ldb:/filesys/john/doe::ds/one", "ldb", "/filesys/john/doe", "ds/one", ""},
testCase{"http://localhost:8000/john/doe?access_token=abc::ds/one", "http", "//localhost:8000/john/doe?access_token=abc", "ds/one", "abc"},
testCase{"https://localhost:8000?qp1=x&access_token=abc&qp2=y::ds/one", "https", "//localhost:8000?qp1=x&access_token=abc&qp2=y", "ds/one", "abc"},
}
for _, tc := range testCases {
dsSpec, err := parseDatasetSpec(tc.spec)
assert.NoError(err)
dbSpec1 := databaseSpec{Protocol: tc.scheme, Path: tc.path, accessToken: tc.accessToken}
assert.Equal(datasetSpec{DbSpec: dbSpec1, DatasetName: tc.ds}, dsSpec)
}
}
func TestPathSpec(t *testing.T) {
assert := assert.New(t)
badSpecs := []string{"mem::#", "mem::#s", "mem::#sha1-foobarbaz", "mem::#sha1-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"}
for _, bs := range badSpecs {
_, err := parsePathSpec(bs)
assert.Error(err)
}
type testCase struct {
spec, scheme, dbPath, pathStr string
}
testCases := []testCase{
testCase{"http://local.attic.io/john/doe::#sha1-0123456789012345678901234567890123456789", "http", "//local.attic.io/john/doe", "#sha1-0123456789012345678901234567890123456789"},
testCase{"ldb:/filesys/john/doe::#sha1-0123456789012345678901234567890123456789", "ldb", "/filesys/john/doe", "#sha1-0123456789012345678901234567890123456789"},
testCase{"mem::#sha1-0123456789012345678901234567890123456789", "mem", "", "#sha1-0123456789012345678901234567890123456789"},
testCase{"http://local.attic.io/john/doe::#sha1-0123456789012345678901234567890123456789", "http", "//local.attic.io/john/doe", "#sha1-0123456789012345678901234567890123456789"},
testCase{"http://localhost:8000/john/doe/::ds1", "http", "//localhost:8000/john/doe/", "ds1"},
}
for _, tc := range testCases {
dbSpec := databaseSpec{Protocol: tc.scheme, Path: tc.dbPath, accessToken: ""}
path, err := NewAbsolutePath(tc.pathStr)
assert.NoError(err)
expected := pathSpec{dbSpec, path}
actual, err := parsePathSpec(tc.spec)
assert.NoError(err)
assert.Equal(expected, actual)
}
}