wiki_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // +build all integration
  2. package gocql
  3. import (
  4. "fmt"
  5. "reflect"
  6. "sort"
  7. "speter.net/go/exp/math/dec/inf"
  8. "testing"
  9. "time"
  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. &WikiPage{
  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. &WikiPage{
  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. }
  47. func (w *WikiTest) CreateSchema() {
  48. if err := w.session.Query(`DROP TABLE wiki_page`).Exec(); err != nil && err.Error() != "unconfigured columnfamily wiki_page" {
  49. w.tb.Fatal("CreateSchema:", err)
  50. }
  51. err := createTable(w.session, `CREATE TABLE wiki_page (
  52. title varchar,
  53. revid timeuuid,
  54. body varchar,
  55. views bigint,
  56. protected boolean,
  57. modified timestamp,
  58. rating decimal,
  59. tags set<varchar>,
  60. attachments map<varchar, blob>,
  61. PRIMARY KEY (title, revid)
  62. )`)
  63. if *clusterSize > 1 {
  64. // wait for table definition to propogate
  65. time.Sleep(250 * time.Millisecond)
  66. }
  67. if err != nil {
  68. w.tb.Fatal("CreateSchema:", err)
  69. }
  70. }
  71. func (w *WikiTest) CreatePages(n int) {
  72. var page WikiPage
  73. t0 := time.Now()
  74. for i := 0; i < n; i++ {
  75. page.Title = fmt.Sprintf("generated_%d", (i&16)+1)
  76. page.Modified = t0.Add(time.Duration(i-n) * time.Minute)
  77. page.RevId = UUIDFromTime(page.Modified)
  78. page.Body = fmt.Sprintf("text %d", i)
  79. if err := w.InsertPage(&page); err != nil {
  80. w.tb.Error("CreatePages:", err)
  81. }
  82. }
  83. }
  84. func (w *WikiTest) InsertPage(page *WikiPage) error {
  85. return w.session.Query(`INSERT INTO wiki_page
  86. (title, revid, body, views, protected, modified, rating, tags, attachments)
  87. VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
  88. page.Title, page.RevId, page.Body, page.Views, page.Protected,
  89. page.Modified, page.Rating, page.Tags, page.Attachments).Exec()
  90. }
  91. func (w *WikiTest) SelectPage(page *WikiPage, title string, revid UUID) error {
  92. return w.session.Query(`SELECT title, revid, body, views, protected,
  93. modified,tags, attachments, rating
  94. FROM wiki_page WHERE title = ? AND revid = ? LIMIT 1`,
  95. title, revid).Scan(&page.Title, &page.RevId,
  96. &page.Body, &page.Views, &page.Protected, &page.Modified, &page.Tags,
  97. &page.Attachments, &page.Rating)
  98. }
  99. func (w *WikiTest) GetPageCount() int {
  100. var count int
  101. if err := w.session.Query(`SELECT COUNT(*) FROM wiki_page`).Scan(&count); err != nil {
  102. w.tb.Error("GetPageCount", err)
  103. }
  104. return count
  105. }
  106. func TestWikiCreateSchema(t *testing.T) {
  107. session := createSession(t)
  108. defer session.Close()
  109. w := WikiTest{session, t}
  110. w.CreateSchema()
  111. }
  112. func BenchmarkWikiCreateSchema(b *testing.B) {
  113. b.StopTimer()
  114. session := createSession(b)
  115. defer func() {
  116. b.StopTimer()
  117. session.Close()
  118. }()
  119. w := WikiTest{session, b}
  120. b.StartTimer()
  121. for i := 0; i < b.N; i++ {
  122. w.CreateSchema()
  123. }
  124. }
  125. func TestWikiCreatePages(t *testing.T) {
  126. session := createSession(t)
  127. defer session.Close()
  128. w := WikiTest{session, t}
  129. w.CreateSchema()
  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 := WikiTest{session, b}
  144. w.CreateSchema()
  145. b.StartTimer()
  146. w.CreatePages(b.N)
  147. }
  148. func BenchmarkWikiSelectAllPages(b *testing.B) {
  149. b.StopTimer()
  150. session := createSession(b)
  151. defer func() {
  152. b.StopTimer()
  153. session.Close()
  154. }()
  155. w := WikiTest{session, b}
  156. w.CreateSchema()
  157. w.CreatePages(100)
  158. b.StartTimer()
  159. var page WikiPage
  160. for i := 0; i < b.N; i++ {
  161. iter := session.Query(`SELECT title, revid, body, views, protected,
  162. modified, tags, attachments, rating
  163. FROM wiki_page`).Iter()
  164. for iter.Scan(&page.Title, &page.RevId, &page.Body, &page.Views,
  165. &page.Protected, &page.Modified, &page.Tags, &page.Attachments,
  166. &page.Rating) {
  167. // pass
  168. }
  169. if err := iter.Close(); err != nil {
  170. b.Error(err)
  171. }
  172. }
  173. }
  174. func BenchmarkWikiSelectSinglePage(b *testing.B) {
  175. b.StopTimer()
  176. session := createSession(b)
  177. defer func() {
  178. b.StopTimer()
  179. session.Close()
  180. }()
  181. w := WikiTest{session, b}
  182. w.CreateSchema()
  183. pages := make([]WikiPage, 100)
  184. w.CreatePages(len(pages))
  185. iter := session.Query(`SELECT title, revid FROM wiki_page`).Iter()
  186. for i := 0; i < len(pages); i++ {
  187. if !iter.Scan(&pages[i].Title, &pages[i].RevId) {
  188. pages = pages[:i]
  189. break
  190. }
  191. }
  192. if err := iter.Close(); err != nil {
  193. b.Error(err)
  194. }
  195. b.StartTimer()
  196. var page WikiPage
  197. for i := 0; i < b.N; i++ {
  198. p := &pages[i%len(pages)]
  199. if err := w.SelectPage(&page, p.Title, p.RevId); err != nil {
  200. b.Error(err)
  201. }
  202. }
  203. }
  204. func BenchmarkWikiSelectPageCount(b *testing.B) {
  205. b.StopTimer()
  206. session := createSession(b)
  207. defer func() {
  208. b.StopTimer()
  209. session.Close()
  210. }()
  211. w := WikiTest{session, b}
  212. w.CreateSchema()
  213. numPages := 10
  214. w.CreatePages(numPages)
  215. b.StartTimer()
  216. for i := 0; i < b.N; i++ {
  217. if count := w.GetPageCount(); count != numPages {
  218. b.Errorf("expected %d pages, got %d pages.", numPages, count)
  219. }
  220. }
  221. }
  222. func TestWikiTypicalCRUD(t *testing.T) {
  223. session := createSession(t)
  224. defer session.Close()
  225. w := WikiTest{session, t}
  226. w.CreateSchema()
  227. for _, page := range wikiTestData {
  228. if err := w.InsertPage(page); err != nil {
  229. t.Error("InsertPage:", err)
  230. }
  231. }
  232. if count := w.GetPageCount(); count != len(wikiTestData) {
  233. t.Errorf("count: expected %d, got %d\n", len(wikiTestData), count)
  234. }
  235. for _, original := range wikiTestData {
  236. page := new(WikiPage)
  237. if err := w.SelectPage(page, original.Title, original.RevId); err != nil {
  238. t.Error("SelectPage:", err)
  239. continue
  240. }
  241. sort.Sort(sort.StringSlice(page.Tags))
  242. sort.Sort(sort.StringSlice(original.Tags))
  243. if !reflect.DeepEqual(page, original) {
  244. t.Errorf("page: expected %#v, got %#v\n", original, page)
  245. }
  246. }
  247. }