wiki_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // +build all integration
  2. package gocql
  3. import (
  4. "fmt"
  5. "reflect"
  6. "sort"
  7. "testing"
  8. "time"
  9. "gopkg.in/inf.v0"
  10. )
  11. type WikiPage struct {
  12. Title string
  13. RevId UUID
  14. Body string
  15. Views int64
  16. Protected bool
  17. Modified time.Time
  18. Rating *inf.Dec
  19. Tags []string
  20. Attachments map[string]WikiAttachment
  21. }
  22. type WikiAttachment []byte
  23. var wikiTestData = []*WikiPage{
  24. {
  25. Title: "Frontpage",
  26. RevId: TimeUUID(),
  27. Body: "Welcome to this wiki page!",
  28. Rating: inf.NewDec(131, 3),
  29. Modified: time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
  30. Tags: []string{"start", "important", "test"},
  31. Attachments: map[string]WikiAttachment{
  32. "logo": WikiAttachment("\x00company logo\x00"),
  33. "favicon": WikiAttachment("favicon.ico"),
  34. },
  35. },
  36. {
  37. Title: "Foobar",
  38. RevId: TimeUUID(),
  39. Body: "foo::Foo f = new foo::Foo(foo::Foo::INIT);",
  40. Modified: time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
  41. },
  42. }
  43. type WikiTest struct {
  44. session *Session
  45. tb testing.TB
  46. table string
  47. }
  48. func CreateSchema(session *Session, tb testing.TB, table string) *WikiTest {
  49. table = "wiki_" + table
  50. if err := createTable(session, fmt.Sprintf("DROP TABLE IF EXISTS gocql_test.%s", table)); err != nil {
  51. tb.Fatal("CreateSchema:", err)
  52. }
  53. err := createTable(session, fmt.Sprintf(`CREATE TABLE gocql_test.%s (
  54. title varchar,
  55. revid timeuuid,
  56. body varchar,
  57. views bigint,
  58. protected boolean,
  59. modified timestamp,
  60. rating decimal,
  61. tags set<varchar>,
  62. attachments map<varchar, blob>,
  63. PRIMARY KEY (title, revid)
  64. )`, table))
  65. if err != nil {
  66. tb.Fatal("CreateSchema:", err)
  67. }
  68. return &WikiTest{
  69. session: session,
  70. tb: tb,
  71. table: table,
  72. }
  73. }
  74. func (w *WikiTest) CreatePages(n int) {
  75. var page WikiPage
  76. t0 := time.Now()
  77. for i := 0; i < n; i++ {
  78. page.Title = fmt.Sprintf("generated_%d", (i&16)+1)
  79. page.Modified = t0.Add(time.Duration(i-n) * time.Minute)
  80. page.RevId = UUIDFromTime(page.Modified)
  81. page.Body = fmt.Sprintf("text %d", i)
  82. if err := w.InsertPage(&page); err != nil {
  83. w.tb.Error("CreatePages:", err)
  84. }
  85. }
  86. }
  87. func (w *WikiTest) InsertPage(page *WikiPage) error {
  88. return w.session.Query(fmt.Sprintf(`INSERT INTO %s
  89. (title, revid, body, views, protected, modified, rating, tags, attachments)
  90. VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, w.table),
  91. page.Title, page.RevId, page.Body, page.Views, page.Protected,
  92. page.Modified, page.Rating, page.Tags, page.Attachments).Exec()
  93. }
  94. func (w *WikiTest) SelectPage(page *WikiPage, title string, revid UUID) error {
  95. return w.session.Query(fmt.Sprintf(`SELECT title, revid, body, views, protected,
  96. modified,tags, attachments, rating
  97. FROM %s WHERE title = ? AND revid = ? LIMIT 1`, w.table),
  98. title, revid).Scan(&page.Title, &page.RevId,
  99. &page.Body, &page.Views, &page.Protected, &page.Modified, &page.Tags,
  100. &page.Attachments, &page.Rating)
  101. }
  102. func (w *WikiTest) GetPageCount() int {
  103. var count int
  104. if err := w.session.Query(fmt.Sprintf(`SELECT COUNT(*) FROM %s`, w.table)).Scan(&count); err != nil {
  105. w.tb.Error("GetPageCount", err)
  106. }
  107. return count
  108. }
  109. func TestWikiCreateSchema(t *testing.T) {
  110. session := createSession(t)
  111. defer session.Close()
  112. CreateSchema(session, t, "create")
  113. }
  114. func BenchmarkWikiCreateSchema(b *testing.B) {
  115. b.StopTimer()
  116. session := createSession(b)
  117. defer func() {
  118. b.StopTimer()
  119. session.Close()
  120. }()
  121. b.StartTimer()
  122. for i := 0; i < b.N; i++ {
  123. CreateSchema(session, b, "bench_create")
  124. }
  125. }
  126. func TestWikiCreatePages(t *testing.T) {
  127. session := createSession(t)
  128. defer session.Close()
  129. w := CreateSchema(session, t, "create_pages")
  130. numPages := 5
  131. w.CreatePages(numPages)
  132. if count := w.GetPageCount(); count != numPages {
  133. t.Errorf("expected %d pages, got %d pages.", numPages, count)
  134. }
  135. }
  136. func BenchmarkWikiCreatePages(b *testing.B) {
  137. b.StopTimer()
  138. session := createSession(b)
  139. defer func() {
  140. b.StopTimer()
  141. session.Close()
  142. }()
  143. w := CreateSchema(session, b, "bench_create_pages")
  144. b.StartTimer()
  145. w.CreatePages(b.N)
  146. }
  147. func BenchmarkWikiSelectAllPages(b *testing.B) {
  148. b.StopTimer()
  149. session := createSession(b)
  150. defer func() {
  151. b.StopTimer()
  152. session.Close()
  153. }()
  154. w := CreateSchema(session, b, "bench_select_all")
  155. w.CreatePages(100)
  156. b.StartTimer()
  157. var page WikiPage
  158. for i := 0; i < b.N; i++ {
  159. iter := session.Query(fmt.Sprintf(`SELECT title, revid, body, views, protected,
  160. modified, tags, attachments, rating
  161. FROM %s`, w.table)).Iter()
  162. for iter.Scan(&page.Title, &page.RevId, &page.Body, &page.Views,
  163. &page.Protected, &page.Modified, &page.Tags, &page.Attachments,
  164. &page.Rating) {
  165. // pass
  166. }
  167. if err := iter.Close(); err != nil {
  168. b.Error(err)
  169. }
  170. }
  171. }
  172. func BenchmarkWikiSelectSinglePage(b *testing.B) {
  173. b.StopTimer()
  174. session := createSession(b)
  175. defer func() {
  176. b.StopTimer()
  177. session.Close()
  178. }()
  179. w := CreateSchema(session, b, "bench_select_single")
  180. pages := make([]WikiPage, 100)
  181. w.CreatePages(len(pages))
  182. iter := session.Query(fmt.Sprintf(`SELECT title, revid FROM %s`, w.table)).Iter()
  183. for i := 0; i < len(pages); i++ {
  184. if !iter.Scan(&pages[i].Title, &pages[i].RevId) {
  185. pages = pages[:i]
  186. break
  187. }
  188. }
  189. if err := iter.Close(); err != nil {
  190. b.Error(err)
  191. }
  192. b.StartTimer()
  193. var page WikiPage
  194. for i := 0; i < b.N; i++ {
  195. p := &pages[i%len(pages)]
  196. if err := w.SelectPage(&page, p.Title, p.RevId); err != nil {
  197. b.Error(err)
  198. }
  199. }
  200. }
  201. func BenchmarkWikiSelectPageCount(b *testing.B) {
  202. b.StopTimer()
  203. session := createSession(b)
  204. defer func() {
  205. b.StopTimer()
  206. session.Close()
  207. }()
  208. w := CreateSchema(session, b, "bench_page_count")
  209. const numPages = 10
  210. w.CreatePages(numPages)
  211. b.StartTimer()
  212. for i := 0; i < b.N; i++ {
  213. if count := w.GetPageCount(); count != numPages {
  214. b.Errorf("expected %d pages, got %d pages.", numPages, count)
  215. }
  216. }
  217. }
  218. func TestWikiTypicalCRUD(t *testing.T) {
  219. session := createSession(t)
  220. defer session.Close()
  221. w := CreateSchema(session, t, "crud")
  222. for _, page := range wikiTestData {
  223. if err := w.InsertPage(page); err != nil {
  224. t.Error("InsertPage:", err)
  225. }
  226. }
  227. if count := w.GetPageCount(); count != len(wikiTestData) {
  228. t.Errorf("count: expected %d, got %d\n", len(wikiTestData), count)
  229. }
  230. for _, original := range wikiTestData {
  231. page := new(WikiPage)
  232. if err := w.SelectPage(page, original.Title, original.RevId); err != nil {
  233. t.Error("SelectPage:", err)
  234. continue
  235. }
  236. sort.Sort(sort.StringSlice(page.Tags))
  237. sort.Sort(sort.StringSlice(original.Tags))
  238. if !reflect.DeepEqual(page, original) {
  239. t.Errorf("page: expected %#v, got %#v\n", original, page)
  240. }
  241. }
  242. }