diff --git a/go/store/chunks/chunk_serializer.go b/go/store/chunks/chunk_serializer.go deleted file mode 100644 index efc1366287..0000000000 --- a/go/store/chunks/chunk_serializer.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2019 Dolthub, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// This file incorporates work covered by the following copyright and -// permission notice: -// -// 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 chunks - -import ( - "bytes" - "encoding/binary" - "io" - - "github.com/dolthub/dolt/go/store/d" - "github.com/dolthub/dolt/go/store/hash" -) - -/* - Chunk Serialization: - Chunk 0 - Chunk 1 - .. - Chunk N - - Chunk: - Hash // 20-byte hash - Len // 4-byte int - Data // len(Data) == Len -*/ - -// Serialize a single Chunk to writer. -func Serialize(chunk Chunk, writer io.Writer) { - d.PanicIfFalse(chunk.data != nil) - - h := chunk.Hash() - n, err := io.Copy(writer, bytes.NewReader(h[:])) - d.Chk.NoError(err) - d.PanicIfFalse(int64(hash.ByteLen) == n) - - // Because of chunking at higher levels, no chunk should never be more than 4GB - chunkSize := uint32(len(chunk.Data())) - err = binary.Write(writer, binary.BigEndian, chunkSize) - d.Chk.NoError(err) - - n, err = io.Copy(writer, bytes.NewReader(chunk.Data())) - d.Chk.NoError(err) - d.PanicIfFalse(uint32(n) == chunkSize) -} - -// Deserialize reads off of |reader| until EOF, sending chunks to -// chunkChan in the order they are read. Objects sent over chunkChan are -// *Chunk. -func Deserialize(reader io.Reader, chunkChan chan<- *Chunk) (err error) { - for { - var c Chunk - c, err = deserializeChunk(reader) - if err != nil { - break - } - d.Chk.NotEqual(EmptyChunk.Hash(), c.Hash()) - chunkChan <- &c - } - if err == io.EOF { - err = nil - } - return -} - -// DeserializeData deserializes a chunk from a byte array -func DeserializeData(data []byte) (Chunk, error) { - reader := bytes.NewReader(data) - return deserializeChunk(reader) -} - -func deserializeChunk(reader io.Reader) (Chunk, error) { - h := hash.Hash{} - n, err := io.ReadFull(reader, h[:]) - if err != nil { - return EmptyChunk, err - } - d.PanicIfFalse(int(hash.ByteLen) == n) - - chunkSize := uint32(0) - if err = binary.Read(reader, binary.BigEndian, &chunkSize); err != nil { - return EmptyChunk, err - } - - data := make([]byte, int(chunkSize)) - if n, err = io.ReadFull(reader, data); err != nil { - return EmptyChunk, err - } - d.PanicIfFalse(int(chunkSize) == n) - c := NewChunk(data) - if h != c.Hash() { - d.Panic("%s != %s", h, c.Hash().String()) - } - return c, nil -} diff --git a/go/store/chunks/chunk_serializer_test.go b/go/store/chunks/chunk_serializer_test.go deleted file mode 100644 index 936dac61e7..0000000000 --- a/go/store/chunks/chunk_serializer_test.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2019 Dolthub, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// This file incorporates work covered by the following copyright and -// permission notice: -// -// 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 chunks - -import ( - "bytes" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSerializeRoundTrip(t *testing.T) { - assert := assert.New(t) - inputs := [][]byte{[]byte("abc"), []byte("def")} - chnx := make([]Chunk, len(inputs)) - for i, data := range inputs { - chnx[i] = NewChunk(data) - } - - buf := &bytes.Buffer{} - Serialize(chnx[0], buf) - Serialize(chnx[1], buf) - - chunkChan := make(chan *Chunk) - go func() { - defer close(chunkChan) - err := Deserialize(bytes.NewReader(buf.Bytes()), chunkChan) - assert.NoError(err) - }() - - for c := range chunkChan { - assert.Equal(chnx[0].Hash(), c.Hash()) - chnx = chnx[1:] - } - assert.Len(chnx, 0) -} - -func TestBadSerialization(t *testing.T) { - bad := []byte{0, 1} // Not enough bytes to read first length - ch := make(chan *Chunk) - defer close(ch) - assert.Error(t, Deserialize(bytes.NewReader(bad), ch)) -} diff --git a/go/store/d/try.go b/go/store/d/try.go index 256332e09c..efb0944f14 100644 --- a/go/store/d/try.go +++ b/go/store/d/try.go @@ -25,155 +25,58 @@ package d import ( "errors" "fmt" - "reflect" - - "github.com/stretchr/testify/assert" ) -// d.Chk.() -- used in test cases and as assertions +// Assertion is an interface that provides convenient methods for asserting invariants. +// Methods panic if the invariant isn't met. +type Assertion interface { + NoError(err error) + True(b bool) +} + +// Chk will panic if an assertion made on it fails var ( - Chk = assert.New(&panicker{}) + Chk Assertion = &panicker{} ) -type panicker struct { +type panicker struct {} + +func (s *panicker) NoError(err error) { + PanicIfError(err) } -func (s panicker) Errorf(format string, args ...interface{}) { - panic(fmt.Sprintf(format, args...)) +func (s *panicker) True(b bool) { + PanicIfFalse(b) } -// Panic(err) creates an error using format and args and wraps it in a +// Panic creates an error using format and args and wraps it in a // WrappedError which can be handled using Try() and TryCatch() func Panic(format string, args ...interface{}) { - if len(args) == 0 { err := errors.New(format) - panic(Wrap(err)) + panic(err) } err := fmt.Errorf(format, args...) - panic(Wrap(err)) + panic(err) } -// PanicIfError(err) && PanicIfTrue(expr) can be used to panic in a way that's -// easily handled by Try() and TryCatch() +// PanicIfError panics if the err given is not nil func PanicIfError(err error) { if err != nil { - panic(Wrap(err)) + panic(err) } } -// If b is true, creates a default error, wraps it and panics. +// PanicIfTrue panics if the bool given is true func PanicIfTrue(b bool) { if b { - panic(Wrap(errors.New("expected true"))) + panic(errors.New("expected true")) } } -// If b is false, creates a default error, wraps it and panics. +// PanicIfFalse panics if the bool given is false func PanicIfFalse(b bool) { if !b { - panic(Wrap(errors.New("expected false"))) + panic(errors.New("expected false")) } -} - -type WrappedError interface { - Error() string - Cause() error -} - -// Wraps an error. The enclosing error has a default Error() that contains the error msg along -// with a backtrace. The original error can be retrieved by calling err.Cause(). -func Wrap(err error) WrappedError { - if err == nil { - return nil - } - if we, ok := err.(WrappedError); ok { - return we - } - - st := stackTracer{} - assert := assert.New(&st) - assert.Fail(err.Error()) - - return wrappedError{st.stackTrace, err} -} - -// If err is a WrappedError, then Cause() is returned, otherwise returns err. -func Unwrap(err error) error { - cause := err - we, ok := err.(WrappedError) - if ok { - cause = we.Cause() - } - return cause -} - -func causeInTypes(err error, types ...interface{}) bool { - cause := Unwrap(err) - typ := reflect.TypeOf(cause) - for _, t := range types { - if typ == reflect.TypeOf(t) { - return true - } - } - return false -} - -// Utility method, that checks type of error and panics with wrapped error not one of the listed types. -func PanicIfNotType(err error, types ...interface{}) error { - if err == nil { - return nil - } - if !causeInTypes(err, types...) { - we, ok := err.(WrappedError) - if !ok { - we = Wrap(err) - } - panic(we) - } - return Unwrap(err) -} - -type wrappedError struct { - msg string - cause error -} - -func (we wrappedError) Error() string { return we.msg } -func (we wrappedError) Cause() error { return we.cause } - -type stackTracer struct { - stackTrace string -} - -func (s *stackTracer) Errorf(format string, args ...interface{}) { - s.stackTrace = fmt.Sprintf(format, args...) -} - -func recoverWrappedTypes(errp *error, types []interface{}) { - if r := recover(); r != nil { - if wrapper, ok := r.(wrappedError); !ok { - panic(r) - } else if len(types) > 0 && !causeInTypes(wrapper, types...) { - panic(r) - } else if len(types) > 0 { - *errp = wrapper.Cause() - } else { - *errp = wrapper - } - } -} - -func recoverWrapped(errp *error, catch func(err error) error) { - if r := recover(); r != nil { - we, ok := r.(wrappedError) - if !ok { - panic(r) - } - if catch != nil { - *errp = catch(we) - } else { - *errp = Unwrap(we) - } - } -} +} \ No newline at end of file diff --git a/go/store/d/try_test.go b/go/store/d/try_test.go index bd74941229..8a4d9459d3 100644 --- a/go/store/d/try_test.go +++ b/go/store/d/try_test.go @@ -22,7 +22,6 @@ package d import ( - "errors" "testing" "github.com/stretchr/testify/assert" @@ -45,15 +44,6 @@ type testError2 struct { func (e testError2) Error() string { return e.s } -func TestUnwrap(t *testing.T) { - assert := assert.New(t) - - err := errors.New("test") - we := wrappedError{"test msg", err} - assert.Equal(err, Unwrap(err)) - assert.Equal(err, Unwrap(we)) -} - func TestPanicIfTrue(t *testing.T) { assert := assert.New(t) @@ -84,42 +74,4 @@ func TestPanicIfFalse(t *testing.T) { assert.NotPanics(func() { PanicIfFalse(true) }) -} - -func TestPanicIfNotType(t *testing.T) { - assert := assert.New(t) - - te := testError{"te"} - te2 := testError2{"te2"} - - assert.Panics(func() { - PanicIfNotType(te, te2) - }) - - assert.Equal(te, PanicIfNotType(te, te)) - assert.Equal(te2, PanicIfNotType(te2, te, te2)) -} - -func TestCauseInTypes(t *testing.T) { - assert := assert.New(t) - - te := testError{"te"} - te2 := testError2{"te2"} - - assert.True(causeInTypes(te, te)) - assert.True(causeInTypes(te, te2, te)) - assert.False(causeInTypes(te, te2)) - assert.False(causeInTypes(te)) -} - -func TestWrap(t *testing.T) { - assert := assert.New(t) - - te := testError{"te"} - we := Wrap(te) - assert.Equal(te, we.Cause()) - assert.IsType(wrappedError{}, we) - assert.Equal(we, Wrap(we)) - //fmt.Printf("st: %s, cause: %s\n", we.Error(), we.Cause()) - assert.Nil(Wrap(nil)) -} +} \ No newline at end of file diff --git a/go/store/datas/commit.go b/go/store/datas/commit.go index 61f5f04d35..1329227eb3 100644 --- a/go/store/datas/commit.go +++ b/go/store/datas/commit.go @@ -684,10 +684,6 @@ func firstError(l, r error) error { return r } -func IsCommitType(nbf *types.NomsBinFormat, t *types.Type) bool { - return types.IsSubtype(nbf, valueCommitType, t) -} - func IsCommit(v types.Value) (bool, error) { if s, ok := v.(types.Struct); ok { return types.IsValueSubtypeOf(s.Format(), v, valueCommitType) diff --git a/go/store/types/struct.go b/go/store/types/struct.go index 4956fd604d..d8ffdd60eb 100644 --- a/go/store/types/struct.go +++ b/go/store/types/struct.go @@ -617,7 +617,7 @@ func verifyFields(fs structTypeFields) { for i, f := range fs { verifyFieldName(f.Name) if i > 0 && strings.Compare(fs[i-1].Name, f.Name) >= 0 { - d.Chk.Fail("Field names must be unique and ordered alphabetically") + d.Panic("Field names must be unique and ordered alphabetically") } } } diff --git a/go/store/types/subtype_test.go b/go/store/types/subtype_test.go index b3b8c50195..c1ad94c2c8 100644 --- a/go/store/types/subtype_test.go +++ b/go/store/types/subtype_test.go @@ -582,7 +582,7 @@ func makeTestStructTypeFromFieldNames(s string) (*Type, error) { return MakeStructType("", fields...) } -func makeTestStructFromFieldNames(nbf *NomsBinFormat, s string) (Struct, error) { +func makeTestStructFromFieldNames(tt *testing.T, nbf *NomsBinFormat, s string) (Struct, error) { t, err := makeTestStructTypeFromFieldNames(s) if err != nil { @@ -590,7 +590,7 @@ func makeTestStructFromFieldNames(nbf *NomsBinFormat, s string) (Struct, error) } fields := t.Desc.(StructDesc).fields - d.Chk.NotEmpty(fields) + require.NotEmpty(tt, fields) fieldNames := make([]string, len(fields)) for i, field := range fields { @@ -967,7 +967,7 @@ func TestIsValueSubtypeOfDetails(tt *testing.T) { a := assert.New(tt) test := func(vString, tString string, exp1, exp2 bool) { - v, err := makeTestStructFromFieldNames(vs.Format(), vString) + v, err := makeTestStructFromFieldNames(tt, vs.Format(), vString) require.NoError(tt, err) t, err := makeTestStructTypeFromFieldNames(tString) require.NoError(tt, err) diff --git a/go/store/types/tuple.go b/go/store/types/tuple.go index 2c24dba846..56cf40bad2 100644 --- a/go/store/types/tuple.go +++ b/go/store/types/tuple.go @@ -25,7 +25,6 @@ import ( "bytes" "context" "errors" - "fmt" "io" "strings" "sync" @@ -559,7 +558,7 @@ func (t Tuple) Get(n uint64) (Value, error) { dec, count := t.decoderSkipToFields() if n >= count { - d.Chk.Fail(fmt.Sprintf(`tuple index "%d" out of range`, n)) + d.Panic(`tuple index "%d" out of range`, n) } for i := uint64(0); i < n; i++ { diff --git a/go/store/types/util_test.go b/go/store/types/util_test.go index 2db5c99922..828387c66d 100644 --- a/go/store/types/util_test.go +++ b/go/store/types/util_test.go @@ -66,8 +66,8 @@ func generateNumbersAsValueSlice(nbf *NomsBinFormat, n int) ValueSlice { } func generateNumbersAsValuesFromToBy(nbf *NomsBinFormat, from, to, by int) ValueSlice { - d.Chk.True(to >= from, "to must be greater than or equal to from") - d.Chk.True(by > 0, "must be an integer greater than zero") + d.Chk.True(to >= from) + d.Chk.True(by > 0) nums := []Value{} for i := from; i < to; i += by { nums = append(nums, Float(i)) @@ -76,8 +76,8 @@ func generateNumbersAsValuesFromToBy(nbf *NomsBinFormat, from, to, by int) Value } func generateNumbersAsStructsFromToBy(nbf *NomsBinFormat, from, to, by int) ValueSlice { - d.Chk.True(to >= from, "to must be greater than or equal to from") - d.Chk.True(by > 0, "must be an integer greater than zero") + d.Chk.True(to >= from) + d.Chk.True(by > 0) nums := []Value{} for i := from; i < to; i += by { nums = append(nums, mustValue(NewStruct(nbf, "num", StructData{"n": Float(i)})))