123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /*
- * EliasDB
- *
- * Copyright 2016 Matthias Ladkau. All rights reserved.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
- package file
- import (
- "bytes"
- "fmt"
- "io"
- "reflect"
- "testing"
- "devt.de/krotik/common/bitutil"
- "devt.de/krotik/common/testutil"
- )
- func TestRecordInitialisation(t *testing.T) {
- r := new(Record)
- out := r.String()
- if out != "Record: 0 (dirty:false transCount:0 len:0 cap:0)\n"+
- "====\n"+
- "000000 \n"+
- "====\n" {
- t.Error("Unexpected output of empty record:", out)
- }
- rdata := []byte("This is a test")
- r = NewRecord(123, rdata)
- id := r.ID()
- if id != 123 {
- t.Error("Unexpected id:", id)
- }
- data := r.Data()
- if !bitutil.CompareByteArray(data, rdata) {
- t.Error("Unexpected initial data", data)
- }
- if r.Dirty() {
- t.Error("Record shouldn't be dirty right after it was created.")
- }
- // Test page view object storage
- dummyString := "TEST"
- r.SetPageView(dummyString)
- if r.PageView() != dummyString {
- t.Error("Unexpected page view object")
- }
- }
- func TestTransactionCounter(t *testing.T) {
- r := NewRecord(123, make([]byte, 20))
- if r.InTransaction() {
- t.Error("A fresh record should not be in a transaction.")
- }
- r.IncTransCount()
- if !r.InTransaction() {
- t.Error("Record should be in transaction after the transaction count was increased.")
- }
- if r.SetID(567) == nil {
- t.Error("It should not be possible to change the record id while in a transaction.")
- }
- r.DecTransCount()
- if r.SetID(789); r.ID() != 789 {
- t.Error("It should be possible to change the record id outside of a transaction.")
- }
- if r.InTransaction() {
- t.Error("Record should not be in transaction after the transaction count was decreased again.")
- }
- testTransactionCountPanic(t, r)
- }
- func testTransactionCountPanic(t *testing.T, r *Record) {
- defer func() {
- if r := recover(); r == nil {
- t.Error("Decreasing of transaction count did not cause a panic.")
- }
- }()
- r.DecTransCount()
- }
- func TestReadAndWrite(t *testing.T) {
- r := NewRecord(123, make([]byte, 20))
- r.WriteSingleByte(3, 0x42)
- if r.data[3] != 0x42 {
- t.Error("Unexpected value in read/write test", r.data[3], "expected: 0x42")
- }
- if !r.Dirty() {
- t.Error("Record should be marked as dirty after write operation.")
- }
- r.ClearDirty()
- if r.Dirty() {
- t.Error("Record should not be marked as dirty after clearing flag.")
- }
- r.WriteSingleByte(0, 0xff)
- showRWTestResult(t, r.ReadSingleByte(0) == byte(0xff), "a byte")
- r.WriteSingleByte(0, 0x01)
- showRWTestResult(t, r.ReadSingleByte(0) == byte(0x01), "a byte")
- r.WriteUInt16(0, 0x1234)
- showRWTestResult(t, r.ReadUInt16(0) == uint16(0x1234), "an uint16")
- r.WriteUInt16(0, 0xFFFF)
- showRWTestResult(t, r.ReadUInt16(0) == uint16(0xFFFF), "an uint16")
- r.WriteInt16(0, -0x1234)
- showRWTestResult(t, r.ReadInt16(0) == int16(-0x1234), "an int16")
- r.WriteInt16(0, -0x7FFF)
- showRWTestResult(t, r.ReadInt16(0) == int16(-0x7FFF), "an int16")
- r.WriteInt16(0, 0x7FFF)
- showRWTestResult(t, r.ReadInt16(0) == int16(0x7FFF), "an int16")
- r.WriteUInt32(0, 0x12345678)
- showRWTestResult(t, r.ReadUInt32(0) == uint32(0x12345678), "an uint32")
- r.WriteUInt32(0, 0xFFFFFFFF)
- showRWTestResult(t, r.ReadUInt32(0) == uint32(0xFFFFFFFF), "an uint32")
- r.WriteInt32(0, -0x12345678)
- showRWTestResult(t, r.ReadInt32(0) == int32(-0x12345678), "an int32")
- r.WriteInt32(0, -0x7FFFFFFF)
- showRWTestResult(t, r.ReadInt32(0) == int32(-0x7FFFFFFF), "an int32")
- r.WriteInt32(0, 0x7FFFFFFF)
- showRWTestResult(t, r.ReadInt32(0) == int32(0x7FFFFFFF), "an int32")
- r.WriteUInt64(0, 0x1234567891234567)
- showRWTestResult(t, r.ReadUInt64(0) == uint64(0x1234567891234567), "an uint64")
- r.WriteUInt64(0, 0xFFFFFFFFFFFFFFFF)
- showRWTestResult(t, r.ReadUInt64(0) == uint64(0xFFFFFFFFFFFFFFFF), "an uint64")
- r.ClearData()
- if r.ReadUInt64(0) != 0 || r.Dirty() {
- t.Error("Record should be clean and not marked as dirty after it was cleaned.")
- }
- }
- func showRWTestResult(t *testing.T, res bool, operation string) {
- if !res {
- t.Error("Unexpected result while reading/writing", operation)
- }
- }
- func TestMarshalBinary(t *testing.T) {
- r := NewRecord(123, make([]byte, 20))
- r.WriteSingleByte(0, 0x41)
- r.WriteSingleByte(3, 0x42)
- r.WriteSingleByte(19, 0x43)
- r.transCount = 19
- data, _ := r.MarshalBinary()
- r2 := NewRecord(0, make([]byte, 20))
- err := r2.UnmarshalBinary(data)
- if err != nil {
- t.Error(err)
- return
- }
- if !reflect.DeepEqual(r, r2) {
- t.Error("Unmarshaled record should be the same as the original record")
- }
- ior := new(bytes.Buffer)
- ior.Write(data)
- r3, err := ReadRecord(ior)
- if err != nil {
- t.Error(err)
- return
- }
- if !reflect.DeepEqual(r, r3) {
- t.Error("Unmarshaled record should be the same as the original record")
- }
- ior = new(bytes.Buffer)
- ior.Write(data[1:5])
- _, err = ReadRecord(ior)
- if err == nil {
- t.Error("ReadRecord should return an error when given invalid data")
- return
- }
- data2, _ := r2.MarshalBinary()
- if !reflect.DeepEqual(data, data2) {
- t.Error("Marshaled representation of records should be the same")
- }
- // Test errors of writing
- for i := 0; i < len(data); i++ {
- buf := &testutil.ErrorTestingBuffer{RemainingSize: i, WrittenSize: 0}
- err := r.WriteRecord(buf)
- if _, ok := err.(testutil.ErrorTestingBuffer); !ok {
- t.Error("Unexpected error return:", err)
- }
- }
- r.ClearDirty()
- data, _ = r.MarshalBinary()
- buf := &testutil.ErrorTestingBuffer{RemainingSize: 8, WrittenSize: 0}
- err = r.WriteRecord(buf)
- if _, ok := err.(testutil.ErrorTestingBuffer); !ok {
- t.Error("Unexpected error return:", err)
- }
- for i := 0; i < len(data); i++ {
- err := r.UnmarshalBinary(data[0:i])
- if err != io.EOF && err != io.ErrUnexpectedEOF {
- fmt.Println("fail")
- t.Error("Unexpected error return:", err)
- }
- }
- }
|