setup_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // Copyright 2012-present Oliver Eilhard. All rights reserved.
  2. // Use of this source code is governed by a MIT-license.
  3. // See http://olivere.mit-license.org/license.txt for details.
  4. package elastic
  5. import (
  6. "context"
  7. "fmt"
  8. "log"
  9. "math/rand"
  10. "os"
  11. "time"
  12. )
  13. const (
  14. testIndexName = "elastic-test"
  15. testIndexName2 = "elastic-test2"
  16. testMapping = `
  17. {
  18. "settings":{
  19. "number_of_shards":1,
  20. "number_of_replicas":0
  21. },
  22. "mappings":{
  23. "_default_": {
  24. "_all": {
  25. "enabled": true
  26. }
  27. },
  28. "tweet":{
  29. "properties":{
  30. "user":{
  31. "type":"keyword"
  32. },
  33. "message":{
  34. "type":"text",
  35. "store": true,
  36. "fielddata": true
  37. },
  38. "tags":{
  39. "type":"keyword"
  40. },
  41. "location":{
  42. "type":"geo_point"
  43. },
  44. "suggest_field":{
  45. "type":"completion"
  46. }
  47. }
  48. },
  49. "comment":{
  50. "_parent": {
  51. "type": "tweet"
  52. }
  53. },
  54. "order":{
  55. "properties":{
  56. "article":{
  57. "type":"text"
  58. },
  59. "manufacturer":{
  60. "type":"keyword"
  61. },
  62. "price":{
  63. "type":"float"
  64. },
  65. "time":{
  66. "type":"date",
  67. "format": "YYYY-MM-dd"
  68. }
  69. }
  70. },
  71. "doctype":{
  72. "properties":{
  73. "message":{
  74. "type":"text",
  75. "store": true,
  76. "fielddata": true
  77. }
  78. }
  79. },
  80. "queries":{
  81. "properties": {
  82. "query": {
  83. "type": "percolator"
  84. }
  85. }
  86. }
  87. }
  88. }
  89. `
  90. )
  91. type tweet struct {
  92. User string `json:"user"`
  93. Message string `json:"message"`
  94. Retweets int `json:"retweets"`
  95. Image string `json:"image,omitempty"`
  96. Created time.Time `json:"created,omitempty"`
  97. Tags []string `json:"tags,omitempty"`
  98. Location string `json:"location,omitempty"`
  99. Suggest *SuggestField `json:"suggest_field,omitempty"`
  100. }
  101. func (t tweet) String() string {
  102. return fmt.Sprintf("tweet{User:%q,Message:%q,Retweets:%d}", t.User, t.Message, t.Retweets)
  103. }
  104. type comment struct {
  105. User string `json:"user"`
  106. Comment string `json:"comment"`
  107. Created time.Time `json:"created,omitempty"`
  108. }
  109. func (c comment) String() string {
  110. return fmt.Sprintf("comment{User:%q,Comment:%q}", c.User, c.Comment)
  111. }
  112. type order struct {
  113. Article string `json:"article"`
  114. Manufacturer string `json:"manufacturer"`
  115. Price float64 `json:"price"`
  116. Time string `json:"time,omitempty"`
  117. }
  118. func (o order) String() string {
  119. return fmt.Sprintf("order{Article:%q,Manufacturer:%q,Price:%v,Time:%v}", o.Article, o.Manufacturer, o.Price, o.Time)
  120. }
  121. // doctype is required for Percolate tests.
  122. type doctype struct {
  123. Message string `json:"message"`
  124. }
  125. // queries is required for Percolate tests.
  126. type queries struct {
  127. Query string `json:"query"`
  128. }
  129. func isTravis() bool {
  130. return os.Getenv("TRAVIS") != ""
  131. }
  132. func travisGoVersion() string {
  133. return os.Getenv("TRAVIS_GO_VERSION")
  134. }
  135. type logger interface {
  136. Error(args ...interface{})
  137. Errorf(format string, args ...interface{})
  138. Fatal(args ...interface{})
  139. Fatalf(format string, args ...interface{})
  140. Fail()
  141. FailNow()
  142. Log(args ...interface{})
  143. Logf(format string, args ...interface{})
  144. }
  145. func setupTestClient(t logger, options ...ClientOptionFunc) (client *Client) {
  146. var err error
  147. client, err = NewClient(options...)
  148. if err != nil {
  149. t.Fatal(err)
  150. }
  151. client.DeleteIndex(testIndexName).Do(context.TODO())
  152. client.DeleteIndex(testIndexName2).Do(context.TODO())
  153. return client
  154. }
  155. func setupTestClientAndCreateIndex(t logger, options ...ClientOptionFunc) *Client {
  156. client := setupTestClient(t, options...)
  157. // Create index
  158. createIndex, err := client.CreateIndex(testIndexName).Body(testMapping).Do(context.TODO())
  159. if err != nil {
  160. t.Fatal(err)
  161. }
  162. if createIndex == nil {
  163. t.Errorf("expected result to be != nil; got: %v", createIndex)
  164. }
  165. // Create second index
  166. createIndex2, err := client.CreateIndex(testIndexName2).Body(testMapping).Do(context.TODO())
  167. if err != nil {
  168. t.Fatal(err)
  169. }
  170. if createIndex2 == nil {
  171. t.Errorf("expected result to be != nil; got: %v", createIndex2)
  172. }
  173. return client
  174. }
  175. func setupTestClientAndCreateIndexAndLog(t logger, options ...ClientOptionFunc) *Client {
  176. return setupTestClientAndCreateIndex(t, SetTraceLog(log.New(os.Stdout, "", 0)))
  177. }
  178. func setupTestClientAndCreateIndexAndAddDocs(t logger, options ...ClientOptionFunc) *Client {
  179. client := setupTestClientAndCreateIndex(t, options...)
  180. // Add tweets
  181. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  182. tweet2 := tweet{User: "olivere", Message: "Another unrelated topic."}
  183. tweet3 := tweet{User: "sandrae", Message: "Cycling is fun."}
  184. comment1 := comment{User: "nico", Comment: "You bet."}
  185. _, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyJson(&tweet1).Do(context.TODO())
  186. if err != nil {
  187. t.Fatal(err)
  188. }
  189. _, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyJson(&tweet2).Do(context.TODO())
  190. if err != nil {
  191. t.Fatal(err)
  192. }
  193. _, err = client.Index().Index(testIndexName).Type("tweet").Id("3").Routing("someroutingkey").BodyJson(&tweet3).Do(context.TODO())
  194. if err != nil {
  195. t.Fatal(err)
  196. }
  197. _, err = client.Index().Index(testIndexName).Type("comment").Id("1").Parent("3").BodyJson(&comment1).Do(context.TODO())
  198. if err != nil {
  199. t.Fatal(err)
  200. }
  201. // Add orders
  202. var orders []order
  203. orders = append(orders, order{Article: "Apple MacBook", Manufacturer: "Apple", Price: 1290, Time: "2015-01-18"})
  204. orders = append(orders, order{Article: "Paper", Manufacturer: "Canon", Price: 100, Time: "2015-03-01"})
  205. orders = append(orders, order{Article: "Apple iPad", Manufacturer: "Apple", Price: 499, Time: "2015-04-12"})
  206. orders = append(orders, order{Article: "Dell XPS 13", Manufacturer: "Dell", Price: 1600, Time: "2015-04-18"})
  207. orders = append(orders, order{Article: "Apple Watch", Manufacturer: "Apple", Price: 349, Time: "2015-04-29"})
  208. orders = append(orders, order{Article: "Samsung TV", Manufacturer: "Samsung", Price: 790, Time: "2015-05-03"})
  209. orders = append(orders, order{Article: "Hoodie", Manufacturer: "h&m", Price: 49, Time: "2015-06-03"})
  210. orders = append(orders, order{Article: "T-Shirt", Manufacturer: "h&m", Price: 19, Time: "2015-06-18"})
  211. for i, o := range orders {
  212. id := fmt.Sprintf("%d", i)
  213. _, err = client.Index().Index(testIndexName).Type("order").Id(id).BodyJson(&o).Do(context.TODO())
  214. if err != nil {
  215. t.Fatal(err)
  216. }
  217. }
  218. // Flush
  219. _, err = client.Flush().Index(testIndexName).Do(context.TODO())
  220. if err != nil {
  221. t.Fatal(err)
  222. }
  223. return client
  224. }
  225. var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
  226. func randomString(n int) string {
  227. b := make([]rune, n)
  228. for i := range b {
  229. b[i] = letters[rand.Intn(len(letters))]
  230. }
  231. return string(b)
  232. }