Add benchmarks

This commit is contained in:
yosssi 2014-06-18 14:16:41 +09:00
parent 1d950008e0
commit 083b82a0f1
2 changed files with 260 additions and 35 deletions

View file

@ -1,26 +1,81 @@
package store
import (
"fmt"
"net/http"
"net/http/httptest"
"strconv"
"testing"
"time"
"code.google.com/p/gogoprotobuf/proto"
"github.com/boltdb/bolt"
"github.com/gorilla/securecookie"
"github.com/gorilla/sessions"
"github.com/yosssi/boltstore/shared"
)
var benchmarkDB = fmt.Sprintf("benchmark_store_%d.db", time.Now().Unix())
func init() {
// Put data to the database for the benchmark.
db, err := bolt.Open(benchmarkDB, 0666)
if err != nil {
panic(err)
}
defer db.Close()
err = db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucket([]byte(shared.DefaultBucketName))
if err != nil {
return err
}
return nil
})
if err != nil {
panic(err)
}
data, err := proto.Marshal(shared.NewSession([]byte{}, shared.DefaultMaxAge))
if err != nil {
panic(err)
}
fmt.Printf("Start putting data for the benchmark %+v\n", time.Now())
for i := 0; i < 100; i++ {
err = db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(shared.DefaultBucketName))
for j := 0; j < 100000; j++ {
if err := bucket.Put([]byte(strconv.Itoa(100000*i+j)), data); err != nil {
return err
}
}
return nil
})
if err != nil {
panic(err)
}
if (i+1)%10 == 0 {
fmt.Printf("%d key-values were put.\n", (i+1)*100000)
}
}
fmt.Printf("End putting data for the benchmark %+v\n", time.Now())
if err != nil {
panic(err)
}
}
func TestStore_Get(t *testing.T) {
db, err := bolt.Open("./sessions.db", 0666)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
defer db.Close()
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
str, err := New(
@ -29,12 +84,12 @@ func TestStore_Get(t *testing.T) {
[]byte("secret-key"),
)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
session, err := str.Get(req, "test")
if err != nil {
t.Error(err.Error())
t.Error(err)
}
if session.IsNew != true {
@ -45,7 +100,7 @@ func TestStore_Get(t *testing.T) {
func TestStore_New(t *testing.T) {
db, err := bolt.Open("./sessions.db", 0666)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
defer db.Close()
@ -55,12 +110,12 @@ func TestStore_New(t *testing.T) {
[]byte("secret-key"),
)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
encoded, err := securecookie.EncodeMulti("test", "1", str.codecs...)
@ -71,7 +126,7 @@ func TestStore_New(t *testing.T) {
session, err := str.New(req, "test")
if err != nil {
t.Error(err.Error())
t.Error(err)
}
if session.IsNew != true {
@ -83,7 +138,7 @@ func TestStore_Save(t *testing.T) {
// When session.Options.MaxAge < 0
db, err := bolt.Open("./sessions.db", 0666)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
defer db.Close()
@ -93,54 +148,62 @@ func TestStore_Save(t *testing.T) {
[]byte("secret-key"),
)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
session, err := str.Get(req, "test")
if err != nil {
t.Error(err.Error())
t.Error(err)
}
session.Options.MaxAge = -1
w := httptest.NewRecorder()
str.Save(req, w, session)
if err := str.Save(req, w, session); err != nil {
t.Error(err)
}
// When session.Options.MaxAge >= 0
session, err = str.Get(req, "test")
if err != nil {
t.Error(err.Error())
t.Error(err)
}
session.Options.MaxAge = 1
w = httptest.NewRecorder()
str.Save(req, w, session)
if err := str.Save(req, w, session); err != nil {
t.Error(err)
}
// When session.Options.MaxAge >= 0 and
// s.save returns an error
session.Values = make(map[interface{}]interface{})
session.Values[make(chan int)] = make(chan int)
str.Save(req, w, session)
if err := str.Save(req, w, session); err == nil || err.Error() != "gob: type not registered for interface: chan int" {
t.Error(`str.Save should return an error "%s" (actual: %+v)`, "gob: type not registered for interface: chan int", err)
}
// When session.Options.MaxAge >= 0 and
// securecookie.EncodeMulti returns an error
session.Values = make(map[interface{}]interface{})
str.codecs = nil
str.Save(req, w, session)
if err := str.Save(req, w, session); err == nil || err.Error() != "securecookie: no codecs provided" {
t.Error(`str.Save should return an error "%s" (actual: %+v)`, "securecookie: no codecs provided", err)
}
}
func TestStore_load(t *testing.T) {
db, err := bolt.Open("./sessions.db", 0666)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
defer db.Close()
@ -150,26 +213,28 @@ func TestStore_load(t *testing.T) {
[]byte("secret-key"),
)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
session, err := str.Get(req, "test")
if err != nil {
t.Error(err.Error())
t.Error(err)
}
w := httptest.NewRecorder()
str.Save(req, w, session)
if err := str.Save(req, w, session); err != nil {
t.Error(err)
}
exists, err := str.load(session)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
if exists != true {
@ -180,7 +245,7 @@ func TestStore_load(t *testing.T) {
session.ID = "x"
exists, err = str.load(session)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
if exists != false {
@ -192,7 +257,7 @@ func TestStore_load(t *testing.T) {
return tx.Bucket(str.config.DBOptions.BucketName).Put([]byte("x"), []byte("test"))
})
if err != nil {
t.Error(err.Error())
t.Error(err)
}
_, err = str.load(session)
if err == nil || err.Error() != "proto: field/encoding mismatch: wrong type for field" {
@ -202,21 +267,24 @@ func TestStore_load(t *testing.T) {
// When the target session data is expired
session, err = str.Get(req, "test")
if err != nil {
t.Error(err.Error())
t.Error(err)
}
session.Options.MaxAge = 0
str.Save(req, w, session)
if err := str.Save(req, w, session); err != nil {
t.Error(err)
}
time.Sleep(time.Second)
_, err = str.load(session)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
}
func TestSession_delete(t *testing.T) {
db, err := bolt.Open("./sessions.db", 0666)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
defer db.Close()
@ -226,17 +294,17 @@ func TestSession_delete(t *testing.T) {
[]byte("secret-key"),
)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
session, err := str.Get(req, "test")
if err != nil {
t.Error(err.Error())
t.Error(err)
}
db.Close()
@ -252,7 +320,7 @@ func TestNew(t *testing.T) {
// When db.Update returns an error
db, err := bolt.Open("./sessions.db", 0666)
if err != nil {
t.Error(err.Error())
t.Error(err)
}
db.Close()
@ -372,3 +440,161 @@ func ExampleNew() {
// Add a value on the session.
session.Values["foo"] = "bar"
}
func BenchmarkNew(b *testing.B) {
db, err := bolt.Open(benchmarkDB, 0666)
if err != nil {
b.Error(err)
}
defer db.Close()
for i := 0; i < b.N; i++ {
_, err = New(
db,
Config{},
[]byte("secret-key"),
)
if err != nil {
b.Error(err)
}
}
}
func BenchmarkStore_Get(b *testing.B) {
db, err := bolt.Open(benchmarkDB, 0666)
if err != nil {
b.Error(err)
}
defer db.Close()
str, err := New(
db,
Config{},
[]byte("secret-key"),
)
if err != nil {
b.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
b.Error(err)
}
for i := 0; i < b.N; i++ {
_, err := str.Get(req, "test")
if err != nil {
b.Error(err)
}
}
}
func BenchmarkStore_New(b *testing.B) {
db, err := bolt.Open(benchmarkDB, 0666)
if err != nil {
b.Error(err)
}
defer db.Close()
str, err := New(
db,
Config{},
[]byte("secret-key"),
)
if err != nil {
b.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
b.Error(err)
}
for i := 0; i < b.N; i++ {
_, err := str.New(req, "test")
if err != nil {
b.Error(err)
}
}
}
func BenchmarkStore_Save(b *testing.B) {
db, err := bolt.Open(benchmarkDB, 0666)
if err != nil {
b.Error(err)
}
defer db.Close()
str, err := New(
db,
Config{},
[]byte("secret-key"),
)
if err != nil {
b.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
b.Error(err)
}
w := httptest.NewRecorder()
session, err := str.Get(req, "test")
if err != nil {
b.Error(err)
}
session.Values["foo"] = "bar"
for i := 0; i < b.N; i++ {
if err := str.Save(req, w, session); err != nil {
b.Error(err)
}
}
}
func BenchmarkStore_Save_delete(b *testing.B) {
db, err := bolt.Open(benchmarkDB, 0666)
if err != nil {
b.Error(err)
}
defer db.Close()
str, err := New(
db,
Config{},
[]byte("secret-key"),
)
if err != nil {
b.Error(err)
}
req, err := http.NewRequest("GET", "http://localhost:3000/", nil)
if err != nil {
b.Error(err)
}
w := httptest.NewRecorder()
session, err := str.Get(req, "test")
if err != nil {
b.Error(err)
}
session.Values["foo"] = "bar"
session.Options.MaxAge = -1
for i := 0; i < b.N; i++ {
if err := str.Save(req, w, session); err != nil {
b.Error(err)
}
}
}

View file

@ -25,8 +25,7 @@ build:
- script:
name: go test
code: |
go test --cover ./...
go test -bench . -benchmem -cover ./...
# Invoke goveralls
- script:
name: goveralls