浏览代码

Merge pull request #195 from tux21b/wikitest

wikitest: a small test-suite containing benchmarks
Christoph Hack 11 年之前
父节点
当前提交
fa0872fa5d
共有 2 个文件被更改,包括 275 次插入101 次删除
  1. 5 101
      cassandra_test.go
  2. 270 0
      wiki_test.go

+ 5 - 101
cassandra_test.go

@@ -8,7 +8,6 @@ import (
 	"bytes"
 	"flag"
 	"reflect"
-	"sort"
 	"speter.net/go/exp/math/dec/inf"
 	"strconv"
 	"strings"
@@ -25,7 +24,7 @@ var (
 
 var initOnce sync.Once
 
-func createSession(t *testing.T) *Session {
+func createSession(tb testing.TB) *Session {
 	cluster := NewCluster(strings.Split(*flagCluster, ",")...)
 	cluster.ProtoVersion = *flagProto
 	cluster.CQLVersion = *flagCQL
@@ -37,26 +36,26 @@ func createSession(t *testing.T) *Session {
 	initOnce.Do(func() {
 		session, err := cluster.CreateSession()
 		if err != nil {
-			t.Fatal("createSession:", err)
+			tb.Fatal("createSession:", err)
 		}
 		// Drop and re-create the keyspace once. Different tests should use their own
 		// individual tables, but can assume that the table does not exist before.
 		if err := session.Query(`DROP KEYSPACE gocql_test`).Exec(); err != nil {
-			t.Log("drop keyspace:", err)
+			tb.Log("drop keyspace:", err)
 		}
 		if err := session.Query(`CREATE KEYSPACE gocql_test
 			WITH replication = {
 				'class' : 'SimpleStrategy',
 				'replication_factor' : 1
 			}`).Exec(); err != nil {
-			t.Fatal("create keyspace:", err)
+			tb.Fatal("create keyspace:", err)
 		}
 		session.Close()
 	})
 	cluster.Keyspace = "gocql_test"
 	session, err := cluster.CreateSession()
 	if err != nil {
-		t.Fatal("createSession:", err)
+		tb.Fatal("createSession:", err)
 	}
 
 	return session
@@ -101,63 +100,6 @@ func TestInvalidKeyspace(t *testing.T) {
 	}
 }
 
-func TestCRUD(t *testing.T) {
-	session := createSession(t)
-	defer session.Close()
-
-	if err := session.Query(`CREATE TABLE page (
-			title       varchar,
-			revid       timeuuid,
-			body        varchar,
-			views       bigint,
-			protected   boolean,
-			modified    timestamp,
-			rating      decimal,
-			tags        set<varchar>,
-			attachments map<varchar, text>,
-			PRIMARY KEY (title, revid)
-		)`).Exec(); err != nil {
-		t.Fatal("create table:", err)
-	}
-
-	for _, page := range pageTestData {
-		if err := session.Query(`INSERT INTO page
-			(title, revid, body, views, protected, modified, rating, tags, attachments)
-			VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
-			page.Title, page.RevId, page.Body, page.Views, page.Protected,
-			page.Modified, page.Rating, page.Tags, page.Attachments).Exec(); err != nil {
-			t.Fatal("insert:", err)
-		}
-	}
-
-	var count int
-	if err := session.Query("SELECT COUNT(*) FROM page").Scan(&count); err != nil {
-		t.Error("select count:", err)
-	}
-	if count != len(pageTestData) {
-		t.Errorf("count: expected %d, got %d\n", len(pageTestData), count)
-	}
-
-	for _, original := range pageTestData {
-		page := new(Page)
-		err := session.Query(`SELECT title, revid, body, views, protected, modified,
-			tags, attachments, rating
-			FROM page WHERE title = ? AND revid = ? LIMIT 1`,
-			original.Title, original.RevId).Scan(&page.Title, &page.RevId,
-			&page.Body, &page.Views, &page.Protected, &page.Modified, &page.Tags,
-			&page.Attachments, &page.Rating)
-		if err != nil {
-			t.Error("select page:", err)
-			continue
-		}
-		sort.Sort(sort.StringSlice(page.Tags))
-		sort.Sort(sort.StringSlice(original.Tags))
-		if !reflect.DeepEqual(page, original) {
-			t.Errorf("page: expected %#v, got %#v\n", original, page)
-		}
-	}
-}
-
 func TestTracing(t *testing.T) {
 	session := createSession(t)
 	defer session.Close()
@@ -187,7 +129,6 @@ func TestTracing(t *testing.T) {
 }
 
 func TestPaging(t *testing.T) {
-
 	if *flagProto == 1 {
 		t.Skip("Paging not supported. Please use Cassandra >= 2.0")
 	}
@@ -399,43 +340,6 @@ func TestCreateSessionTimeout(t *testing.T) {
 	}
 }
 
-type Page struct {
-	Title       string
-	RevId       UUID
-	Body        string
-	Views       int64
-	Protected   bool
-	Modified    time.Time
-	Rating      *inf.Dec
-	Tags        []string
-	Attachments map[string]Attachment
-}
-
-type Attachment []byte
-
-var rating, _ = inf.NewDec(0, 0).SetString("0.131")
-
-var pageTestData = []*Page{
-	&Page{
-		Title:    "Frontpage",
-		RevId:    TimeUUID(),
-		Body:     "Welcome to this wiki page!",
-		Rating:   rating,
-		Modified: time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
-		Tags:     []string{"start", "important", "test"},
-		Attachments: map[string]Attachment{
-			"logo":    Attachment("\x00company logo\x00"),
-			"favicon": Attachment("favicon.ico"),
-		},
-	},
-	&Page{
-		Title:    "Foobar",
-		RevId:    TimeUUID(),
-		Body:     "foo::Foo f = new foo::Foo(foo::Foo::INIT);",
-		Modified: time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
-	},
-}
-
 func TestSliceMap(t *testing.T) {
 	session := createSession(t)
 	defer session.Close()

+ 270 - 0
wiki_test.go

@@ -0,0 +1,270 @@
+// Copyright (c) 2014 The gocql Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocql
+
+import (
+	"fmt"
+	"reflect"
+	"sort"
+	"speter.net/go/exp/math/dec/inf"
+	"testing"
+	"time"
+)
+
+type WikiPage struct {
+	Title       string
+	RevId       UUID
+	Body        string
+	Views       int64
+	Protected   bool
+	Modified    time.Time
+	Rating      *inf.Dec
+	Tags        []string
+	Attachments map[string]WikiAttachment
+}
+
+type WikiAttachment []byte
+
+var wikiTestData = []*WikiPage{
+	&WikiPage{
+		Title:    "Frontpage",
+		RevId:    TimeUUID(),
+		Body:     "Welcome to this wiki page!",
+		Rating:   inf.NewDec(131, 3),
+		Modified: time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
+		Tags:     []string{"start", "important", "test"},
+		Attachments: map[string]WikiAttachment{
+			"logo":    WikiAttachment("\x00company logo\x00"),
+			"favicon": WikiAttachment("favicon.ico"),
+		},
+	},
+	&WikiPage{
+		Title:    "Foobar",
+		RevId:    TimeUUID(),
+		Body:     "foo::Foo f = new foo::Foo(foo::Foo::INIT);",
+		Modified: time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
+	},
+}
+
+type WikiTest struct {
+	session *Session
+	tb      testing.TB
+}
+
+func (w *WikiTest) CreateSchema() {
+	if err := w.session.Query(`DROP TABLE IF EXISTS wiki_page`).Exec(); err != nil {
+		w.tb.Fatal("CreateSchema:", err)
+	}
+	if err := w.session.Query(`CREATE TABLE wiki_page (
+			title       varchar,
+			revid       timeuuid,
+			body        varchar,
+			views       bigint,
+			protected   boolean,
+			modified    timestamp,
+			rating      decimal,
+			tags        set<varchar>,
+			attachments map<varchar, blob>,
+			PRIMARY KEY (title, revid)
+		)`).Exec(); err != nil {
+		w.tb.Fatal("CreateSchema:", err)
+	}
+}
+
+func (w *WikiTest) CreatePages(n int) {
+	var page WikiPage
+	t0 := time.Now()
+	for i := 0; i < n; i++ {
+		page.Title = fmt.Sprintf("generated_%d", (i&16)+1)
+		page.Modified = t0.Add(time.Duration(i-n) * time.Minute)
+		page.RevId = UUIDFromTime(page.Modified)
+		page.Body = fmt.Sprintf("text %d", i)
+		if err := w.InsertPage(&page); err != nil {
+			w.tb.Error("CreatePages:", err)
+		}
+	}
+}
+
+func (w *WikiTest) InsertPage(page *WikiPage) error {
+	return w.session.Query(`INSERT INTO wiki_page
+		(title, revid, body, views, protected, modified, rating, tags, attachments)
+		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
+		page.Title, page.RevId, page.Body, page.Views, page.Protected,
+		page.Modified, page.Rating, page.Tags, page.Attachments).Exec()
+}
+
+func (w *WikiTest) SelectPage(page *WikiPage, title string, revid UUID) error {
+	return w.session.Query(`SELECT title, revid, body, views, protected,
+		modified,tags, attachments, rating
+		FROM wiki_page WHERE title = ? AND revid = ? LIMIT 1`,
+		title, revid).Scan(&page.Title, &page.RevId,
+		&page.Body, &page.Views, &page.Protected, &page.Modified, &page.Tags,
+		&page.Attachments, &page.Rating)
+}
+
+func (w *WikiTest) GetPageCount() int {
+	var count int
+	if err := w.session.Query(`SELECT COUNT(*) FROM wiki_page`).Scan(&count); err != nil {
+		w.tb.Error("GetPageCount", err)
+	}
+	return count
+}
+
+func TestWikiCreateSchema(t *testing.T) {
+	session := createSession(t)
+	defer session.Close()
+
+	w := WikiTest{session, t}
+	w.CreateSchema()
+}
+
+func BenchmarkWikiCreateSchema(b *testing.B) {
+	b.StopTimer()
+	session := createSession(b)
+	defer func() {
+		b.StopTimer()
+		session.Close()
+	}()
+	w := WikiTest{session, b}
+	b.StartTimer()
+
+	for i := 0; i < b.N; i++ {
+		w.CreateSchema()
+	}
+}
+
+func TestWikiCreatePages(t *testing.T) {
+	session := createSession(t)
+	defer session.Close()
+
+	w := WikiTest{session, t}
+	w.CreateSchema()
+	numPages := 5
+	w.CreatePages(numPages)
+	if count := w.GetPageCount(); count != numPages {
+		t.Errorf("expected %d pages, got %d pages.", numPages, count)
+	}
+}
+
+func BenchmarkWikiCreatePages(b *testing.B) {
+	b.StopTimer()
+	session := createSession(b)
+	defer func() {
+		b.StopTimer()
+		session.Close()
+	}()
+	w := WikiTest{session, b}
+	w.CreateSchema()
+	b.StartTimer()
+
+	w.CreatePages(b.N)
+}
+
+func BenchmarkWikiSelectAllPages(b *testing.B) {
+	b.StopTimer()
+	session := createSession(b)
+	defer func() {
+		b.StopTimer()
+		session.Close()
+	}()
+	w := WikiTest{session, b}
+	w.CreateSchema()
+	w.CreatePages(100)
+	b.StartTimer()
+
+	var page WikiPage
+	for i := 0; i < b.N; i++ {
+		iter := session.Query(`SELECT title, revid, body, views, protected,
+			modified, tags, attachments, rating
+			FROM wiki_page`).Iter()
+		for iter.Scan(&page.Title, &page.RevId, &page.Body, &page.Views,
+			&page.Protected, &page.Modified, &page.Tags, &page.Attachments,
+			&page.Rating) {
+			// pass
+		}
+		if err := iter.Close(); err != nil {
+			b.Error(err)
+		}
+	}
+}
+
+func BenchmarkWikiSelectSinglePage(b *testing.B) {
+	b.StopTimer()
+	session := createSession(b)
+	defer func() {
+		b.StopTimer()
+		session.Close()
+	}()
+	w := WikiTest{session, b}
+	w.CreateSchema()
+	pages := make([]WikiPage, 100)
+	w.CreatePages(len(pages))
+	iter := session.Query(`SELECT title, revid FROM wiki_page`).Iter()
+	for i := 0; i < len(pages); i++ {
+		if !iter.Scan(&pages[i].Title, &pages[i].RevId) {
+			pages = pages[:i]
+			break
+		}
+	}
+	if err := iter.Close(); err != nil {
+		b.Error(err)
+	}
+	b.StartTimer()
+
+	var page WikiPage
+	for i := 0; i < b.N; i++ {
+		p := &pages[i%len(pages)]
+		if err := w.SelectPage(&page, p.Title, p.RevId); err != nil {
+			b.Error(err)
+		}
+	}
+}
+
+func BenchmarkWikiSelectPageCount(b *testing.B) {
+	b.StopTimer()
+	session := createSession(b)
+	defer func() {
+		b.StopTimer()
+		session.Close()
+	}()
+	w := WikiTest{session, b}
+	w.CreateSchema()
+	numPages := 10
+	w.CreatePages(numPages)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		if count := w.GetPageCount(); count != numPages {
+			b.Errorf("expected %d pages, got %d pages.", numPages, count)
+		}
+	}
+}
+
+func TestWikiTypicalCRUD(t *testing.T) {
+	session := createSession(t)
+	defer session.Close()
+
+	w := WikiTest{session, t}
+	w.CreateSchema()
+	for _, page := range wikiTestData {
+		if err := w.InsertPage(page); err != nil {
+			t.Error("InsertPage:", err)
+		}
+	}
+	if count := w.GetPageCount(); count != len(wikiTestData) {
+		t.Errorf("count: expected %d, got %d\n", len(wikiTestData), count)
+	}
+	for _, original := range wikiTestData {
+		page := new(WikiPage)
+		if err := w.SelectPage(page, original.Title, original.RevId); err != nil {
+			t.Error("SelectPage:", err)
+			continue
+		}
+		sort.Sort(sort.StringSlice(page.Tags))
+		sort.Sort(sort.StringSlice(original.Tags))
+		if !reflect.DeepEqual(page, original) {
+			t.Errorf("page: expected %#v, got %#v\n", original, page)
+		}
+	}
+}