Skip to content

Commit

Permalink
upsert: add tests for upsert operation
Browse files Browse the repository at this point in the history
Except tests for upsert operation in this commit changed travis-ci script
  • Loading branch information
pzhin committed Feb 18, 2017
1 parent 3b43a52 commit c9dc35b
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 67 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
language: go
sudo: false
go:
- 1.7
- tip
before_install:
- go get github.com/mattn/goveralls
- go get github.com/stretchr/testify
install:
- go version
- go build -v ./...
branches:
only:
- master
script:
- go test -v ./...
- go test -v ./... -bench=. -benchmem
after_success:
- $HOME/gopath/bin/goveralls -service=travis-ci
70 changes: 6 additions & 64 deletions database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"math/rand"
"os"
"testing"
"unsafe"

"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -384,70 +383,12 @@ func TestDatabaseDeleteNotExistingKey(t *testing.T) {
require.Nil(t, db.Delete(doc))
}

func TestDatabaseUpsert(t *testing.T) {
defer func() {
require.Nil(t, os.RemoveAll(DBPath))
}()
env, err := NewEnvironment()
require.Nil(t, err)
require.NotNil(t, env)

require.True(t, env.Set("sophia.path", DBPath))

schema := &Schema{}
require.Nil(t, schema.AddKey("key", FieldTypeUInt32))
require.Nil(t, schema.AddValue("id", FieldTypeUInt32))

db, err := env.NewDatabase(&DatabaseConfig{
Name: DBName,
Schema: schema,
Upsert: upsertCallback,
})
require.Nil(t, err)
require.NotNil(t, db)

require.Nil(t, env.Open())

/* increment key 10 times */
const key uint32 = 1234
const iterations = 10
var increment int64 = 1
for i := 0; i < iterations; i++ {
doc := db.Document()
doc.Set("key", key)
doc.Set("id", increment)
require.Nil(t, db.Upsert(doc))
}

/* get */
doc := db.Document()
doc.Set("key", key)

result, err := db.Get(doc)
require.Nil(t, err)
require.NotNil(t, result)
defer result.Destroy()

require.Equal(t, iterations*increment, result.GetInt("id"))
}

func upsertCallback(count int,
src []unsafe.Pointer, srcSize uint32,
upsert []unsafe.Pointer, upsertSize uint32,
result []unsafe.Pointer, resultSize uint32,
arg unsafe.Pointer) int {
var a uint32 = *(*uint32)(src[1])
var b uint32 = *(*uint32)(upsert[1])
ret := a + b
resPtr := (*uint32)(result[1])
*resPtr = ret
return 0
}

// ATTN - This benchmark don't show real performance
// It is just a long running tests
func BenchmarkDatabaseSet(b *testing.B) {
defer func() { require.Nil(b, os.RemoveAll(DBPath)) }()
defer func() {
require.Nil(b, os.RemoveAll(DBPath))
}()
env, err := NewEnvironment()
require.Nil(b, err)
require.NotNil(b, env)
Expand Down Expand Up @@ -484,7 +425,9 @@ func BenchmarkDatabaseSet(b *testing.B) {
// ATTN - This benchmark don't show real performance
// It is just a long running tests
func BenchmarkDatabaseGet(b *testing.B) {
defer func() { require.Nil(b, os.RemoveAll(DBPath)) }()
defer func() {
require.Nil(b, os.RemoveAll(DBPath))
}()
env, err := NewEnvironment()
require.Nil(b, err)
require.NotNil(b, env)
Expand Down Expand Up @@ -526,7 +469,6 @@ func BenchmarkDatabaseGet(b *testing.B) {
require.Nil(b, err)
require.Equal(b, value, d.GetString("value", &size))
doc.Free()
d.Free()
d.Destroy()
}
}
19 changes: 17 additions & 2 deletions upsert.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,26 @@ func getUpsertArg(index int) unsafe.Pointer {
func registerUpsertArg(index int, arg interface{}) {
upsertArgMu.Lock()
defer upsertArgMu.Unlock()
if arg == nil {
return
}
val := reflect.ValueOf(arg)
if arg == nil || val.IsNil() {
if val.CanAddr() {
upsertArgMap[index] = unsafe.Pointer(val.Pointer())
return
}
upsertArgMap[index] = unsafe.Pointer(val.Pointer())

switch val.Kind() {
case reflect.String:
str := val.String()
upsertArgMap[index] = unsafe.Pointer(&str)
case reflect.Int, reflect.Int64, reflect.Int8, reflect.Int16, reflect.Int32:
i := val.Int()
upsertArgMap[index] = unsafe.Pointer(&i)
case reflect.Uint, reflect.Uint64, reflect.Uint8, reflect.Uint16, reflect.Uint32:
i := val.Uint()
upsertArgMap[index] = unsafe.Pointer(&i)
}
}

func registerUpsert(upsertFunc UpsertFunc) (unsafe.Pointer, int) {
Expand Down
163 changes: 163 additions & 0 deletions upsert_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package sophia

import (
"os"
"testing"
"unsafe"

"github.com/stretchr/testify/require"
)

func TestDatabaseUpsert(t *testing.T) {
defer func() {
require.Nil(t, os.RemoveAll(DBPath))
}()
env, err := NewEnvironment()
require.Nil(t, err)
require.NotNil(t, env)

require.True(t, env.Set("sophia.path", DBPath))

schema := &Schema{}
require.Nil(t, schema.AddKey("key", FieldTypeUInt32))
require.Nil(t, schema.AddValue("id", FieldTypeUInt32))

db, err := env.NewDatabase(&DatabaseConfig{
Name: DBName,
Schema: schema,
Upsert: upsertCallback,
})
require.Nil(t, err)
require.NotNil(t, db)

require.Nil(t, env.Open())

/* increment key 10 times */
const key uint32 = 1234
const iterations = 10
var increment int64 = 1
for i := 0; i < iterations; i++ {
doc := db.Document()
doc.Set("key", key)
doc.Set("id", increment)
require.Nil(t, db.Upsert(doc))
}

/* get */
doc := db.Document()
doc.Set("key", key)

result, err := db.Get(doc)
require.Nil(t, err)
require.NotNil(t, result)
defer result.Destroy()

require.Equal(t, iterations*increment, result.GetInt("id"))
}

func TestDatabaseUpsertWithArg(t *testing.T) {
defer func() {
require.Nil(t, os.RemoveAll(DBPath))
}()
env, err := NewEnvironment()
require.Nil(t, err)
require.NotNil(t, env)

require.True(t, env.Set("sophia.path", DBPath))

schema := &Schema{}
require.Nil(t, schema.AddKey("key", FieldTypeUInt32))
require.Nil(t, schema.AddValue("id", FieldTypeUInt32))

const upsertArg = 5

db, err := env.NewDatabase(&DatabaseConfig{
Name: DBName,
Schema: schema,
Upsert: upsertCallbackWithArg,
UpsertArg: upsertArg,
})
require.Nil(t, err)
require.NotNil(t, db)

require.Nil(t, env.Open())

/* increment key 10 times */
const key uint32 = 1234
const iterations = 10
var increment int64 = 1
for i := 0; i < iterations; i++ {
doc := db.Document()
doc.Set("key", key)
doc.Set("id", increment)
require.Nil(t, db.Upsert(doc))
}

/* get */
doc := db.Document()
doc.Set("key", key)

result, err := db.Get(doc)
require.Nil(t, err)
require.NotNil(t, result)
defer result.Destroy()

expected := iterations*increment+upsertArg*(iterations-1)
require.Equal(t, expected, result.GetInt("id"))
}

func upsertCallback(count int,
src []unsafe.Pointer, srcSize uint32,
upsert []unsafe.Pointer, upsertSize uint32,
result []unsafe.Pointer, resultSize uint32,
arg unsafe.Pointer) int {
var a uint32 = *(*uint32)(src[1])
var b uint32 = *(*uint32)(upsert[1])
ret := a + b
resPtr := (*uint32)(result[1])
*resPtr = ret
return 0
}

func upsertCallbackWithArg(count int,
src []unsafe.Pointer, srcSize uint32,
upsert []unsafe.Pointer, upsertSize uint32,
result []unsafe.Pointer, resultSize uint32,
arg unsafe.Pointer) int {
var a uint32 = *(*uint32)(src[1])
var b uint32 = *(*uint32)(upsert[1])
var c uint32 = *(*uint32)(arg)
ret := a + b + c
resPtr := (*uint32)(result[1])
*resPtr = ret
return 0
}

func TestDatabaseUpsertError(t *testing.T) {
defer func() {
require.Nil(t, os.RemoveAll(DBPath))
}()
env, err := NewEnvironment()
require.Nil(t, err)
require.NotNil(t, env)

require.True(t, env.Set("sophia.path", DBPath))

schema := &Schema{}
require.Nil(t, schema.AddKey("key", FieldTypeUInt32))
require.Nil(t, schema.AddValue("id", FieldTypeUInt32))

db, err := env.NewDatabase(&DatabaseConfig{
Name: DBName,
Schema: schema,
})
require.Nil(t, err)
require.NotNil(t, db)

require.Nil(t, env.Open())
doc := db.Document()
require.NotNil(t, doc)
require.True(t, doc.Set("key", 1))
require.True(t, doc.Set("id", 1))
require.NotNil(t, db.Upsert(doc))
}
1 change: 1 addition & 0 deletions wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
)

/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -lrt
#include <sophia.h>
extern void *sp_env(void);
Expand Down

0 comments on commit c9dc35b

Please sign in to comment.