setup_test.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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. "contexts":[
  47. {
  48. "name": "user_name",
  49. "type": "category"
  50. }
  51. ]
  52. }
  53. }
  54. },
  55. "comment":{
  56. "_parent": {
  57. "type": "tweet"
  58. }
  59. },
  60. "order":{
  61. "properties":{
  62. "article":{
  63. "type":"text"
  64. },
  65. "manufacturer":{
  66. "type":"keyword"
  67. },
  68. "price":{
  69. "type":"float"
  70. },
  71. "time":{
  72. "type":"date",
  73. "format": "YYYY-MM-dd"
  74. }
  75. }
  76. },
  77. "doctype":{
  78. "properties":{
  79. "message":{
  80. "type":"text",
  81. "store": true,
  82. "fielddata": true
  83. }
  84. }
  85. },
  86. "queries":{
  87. "properties": {
  88. "query": {
  89. "type": "percolator"
  90. }
  91. }
  92. },
  93. "tweet-nosource":{
  94. "_source": {
  95. "enabled": false
  96. },
  97. "properties":{
  98. "user":{
  99. "type":"keyword"
  100. },
  101. "message":{
  102. "type":"text",
  103. "store": true,
  104. "fielddata": true
  105. },
  106. "tags":{
  107. "type":"keyword"
  108. },
  109. "location":{
  110. "type":"geo_point"
  111. },
  112. "suggest_field":{
  113. "type":"completion",
  114. "contexts":[
  115. {
  116. "name":"user_name",
  117. "type":"category"
  118. }
  119. ]
  120. }
  121. }
  122. }
  123. }
  124. }
  125. `
  126. )
  127. type tweet struct {
  128. User string `json:"user"`
  129. Message string `json:"message"`
  130. Retweets int `json:"retweets"`
  131. Image string `json:"image,omitempty"`
  132. Created time.Time `json:"created,omitempty"`
  133. Tags []string `json:"tags,omitempty"`
  134. Location string `json:"location,omitempty"`
  135. Suggest *SuggestField `json:"suggest_field,omitempty"`
  136. }
  137. func (t tweet) String() string {
  138. return fmt.Sprintf("tweet{User:%q,Message:%q,Retweets:%d}", t.User, t.Message, t.Retweets)
  139. }
  140. type comment struct {
  141. User string `json:"user"`
  142. Comment string `json:"comment"`
  143. Created time.Time `json:"created,omitempty"`
  144. }
  145. func (c comment) String() string {
  146. return fmt.Sprintf("comment{User:%q,Comment:%q}", c.User, c.Comment)
  147. }
  148. type order struct {
  149. Article string `json:"article"`
  150. Manufacturer string `json:"manufacturer"`
  151. Price float64 `json:"price"`
  152. Time string `json:"time,omitempty"`
  153. }
  154. func (o order) String() string {
  155. return fmt.Sprintf("order{Article:%q,Manufacturer:%q,Price:%v,Time:%v}", o.Article, o.Manufacturer, o.Price, o.Time)
  156. }
  157. // doctype is required for Percolate tests.
  158. type doctype struct {
  159. Message string `json:"message"`
  160. }
  161. // queries is required for Percolate tests.
  162. type queries struct {
  163. Query string `json:"query"`
  164. }
  165. func isTravis() bool {
  166. return os.Getenv("TRAVIS") != ""
  167. }
  168. func travisGoVersion() string {
  169. return os.Getenv("TRAVIS_GO_VERSION")
  170. }
  171. type logger interface {
  172. Error(args ...interface{})
  173. Errorf(format string, args ...interface{})
  174. Fatal(args ...interface{})
  175. Fatalf(format string, args ...interface{})
  176. Fail()
  177. FailNow()
  178. Log(args ...interface{})
  179. Logf(format string, args ...interface{})
  180. }
  181. func setupTestClient(t logger, options ...ClientOptionFunc) (client *Client) {
  182. var err error
  183. client, err = NewClient(options...)
  184. if err != nil {
  185. t.Fatal(err)
  186. }
  187. client.DeleteIndex(testIndexName).Do(context.TODO())
  188. client.DeleteIndex(testIndexName2).Do(context.TODO())
  189. return client
  190. }
  191. func setupTestClientAndCreateIndex(t logger, options ...ClientOptionFunc) *Client {
  192. client := setupTestClient(t, options...)
  193. // Create index
  194. createIndex, err := client.CreateIndex(testIndexName).Body(testMapping).Do(context.TODO())
  195. if err != nil {
  196. t.Fatal(err)
  197. }
  198. if createIndex == nil {
  199. t.Errorf("expected result to be != nil; got: %v", createIndex)
  200. }
  201. // Create second index
  202. createIndex2, err := client.CreateIndex(testIndexName2).Body(testMapping).Do(context.TODO())
  203. if err != nil {
  204. t.Fatal(err)
  205. }
  206. if createIndex2 == nil {
  207. t.Errorf("expected result to be != nil; got: %v", createIndex2)
  208. }
  209. return client
  210. }
  211. func setupTestClientAndCreateIndexAndLog(t logger, options ...ClientOptionFunc) *Client {
  212. return setupTestClientAndCreateIndex(t, SetTraceLog(log.New(os.Stdout, "", 0)))
  213. }
  214. func setupTestClientAndCreateIndexAndAddDocs(t logger, options ...ClientOptionFunc) *Client {
  215. client := setupTestClientAndCreateIndex(t, options...)
  216. // Add tweets
  217. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  218. tweet2 := tweet{User: "olivere", Message: "Another unrelated topic."}
  219. tweet3 := tweet{User: "sandrae", Message: "Cycling is fun."}
  220. comment1 := comment{User: "nico", Comment: "You bet."}
  221. _, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyJson(&tweet1).Do(context.TODO())
  222. if err != nil {
  223. t.Fatal(err)
  224. }
  225. _, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyJson(&tweet2).Do(context.TODO())
  226. if err != nil {
  227. t.Fatal(err)
  228. }
  229. _, err = client.Index().Index(testIndexName).Type("tweet").Id("3").Routing("someroutingkey").BodyJson(&tweet3).Do(context.TODO())
  230. if err != nil {
  231. t.Fatal(err)
  232. }
  233. _, err = client.Index().Index(testIndexName).Type("comment").Id("1").Parent("3").BodyJson(&comment1).Do(context.TODO())
  234. if err != nil {
  235. t.Fatal(err)
  236. }
  237. // Add orders
  238. var orders []order
  239. orders = append(orders, order{Article: "Apple MacBook", Manufacturer: "Apple", Price: 1290, Time: "2015-01-18"})
  240. orders = append(orders, order{Article: "Paper", Manufacturer: "Canon", Price: 100, Time: "2015-03-01"})
  241. orders = append(orders, order{Article: "Apple iPad", Manufacturer: "Apple", Price: 499, Time: "2015-04-12"})
  242. orders = append(orders, order{Article: "Dell XPS 13", Manufacturer: "Dell", Price: 1600, Time: "2015-04-18"})
  243. orders = append(orders, order{Article: "Apple Watch", Manufacturer: "Apple", Price: 349, Time: "2015-04-29"})
  244. orders = append(orders, order{Article: "Samsung TV", Manufacturer: "Samsung", Price: 790, Time: "2015-05-03"})
  245. orders = append(orders, order{Article: "Hoodie", Manufacturer: "h&m", Price: 49, Time: "2015-06-03"})
  246. orders = append(orders, order{Article: "T-Shirt", Manufacturer: "h&m", Price: 19, Time: "2015-06-18"})
  247. for i, o := range orders {
  248. id := fmt.Sprintf("%d", i)
  249. _, err = client.Index().Index(testIndexName).Type("order").Id(id).BodyJson(&o).Do(context.TODO())
  250. if err != nil {
  251. t.Fatal(err)
  252. }
  253. }
  254. // Flush
  255. _, err = client.Flush().Index(testIndexName).Do(context.TODO())
  256. if err != nil {
  257. t.Fatal(err)
  258. }
  259. return client
  260. }
  261. func setupTestClientAndCreateIndexAndAddDocsNoSource(t logger, options ...ClientOptionFunc) *Client {
  262. client := setupTestClientAndCreateIndex(t, options...)
  263. // Add tweets
  264. tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
  265. tweet2 := tweet{User: "olivere", Message: "Another unrelated topic."}
  266. _, err := client.Index().Index(testIndexName).Type("tweet-nosource").Id("1").BodyJson(&tweet1).Do(context.TODO())
  267. if err != nil {
  268. t.Fatal(err)
  269. }
  270. _, err = client.Index().Index(testIndexName).Type("tweet-nosource").Id("2").BodyJson(&tweet2).Do(context.TODO())
  271. if err != nil {
  272. t.Fatal(err)
  273. }
  274. // Flush
  275. _, err = client.Flush().Index(testIndexName).Do(context.TODO())
  276. if err != nil {
  277. t.Fatal(err)
  278. }
  279. return client
  280. }
  281. var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
  282. func randomString(n int) string {
  283. b := make([]rune, n)
  284. for i := range b {
  285. b[i] = letters[rand.Intn(len(letters))]
  286. }
  287. return string(b)
  288. }