|
|
@@ -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)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|