schema_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // Copyright 2021 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package service
  15. import (
  16. "github.com/lf-edge/ekuiper/internal/testx"
  17. "reflect"
  18. "testing"
  19. )
  20. var descriptors []descriptor
  21. func init() {
  22. schemas := []*schemaInfo{
  23. {
  24. SchemaType: PROTOBUFF,
  25. SchemaFile: "hw.proto",
  26. },
  27. }
  28. descriptors = make([]descriptor, len(schemas))
  29. for i, sch := range schemas {
  30. d, err := parse(sch.SchemaType, sch.SchemaFile)
  31. if err != nil {
  32. panic(err)
  33. }
  34. descriptors[i] = d
  35. }
  36. }
  37. func TestConvertParams(t *testing.T) {
  38. tests := []struct {
  39. method string
  40. params []interface{}
  41. iresult []interface{}
  42. jresult []byte
  43. err string
  44. }{
  45. { //0
  46. method: "SayHello",
  47. params: []interface{}{
  48. "world",
  49. },
  50. iresult: []interface{}{
  51. "world",
  52. },
  53. jresult: []byte(`{"name":"world"}`),
  54. },
  55. { //1
  56. method: "SayHello",
  57. params: []interface{}{
  58. map[string]interface{}{
  59. "name": "world",
  60. },
  61. },
  62. iresult: []interface{}{
  63. "world",
  64. },
  65. jresult: []byte(`{"name":"world"}`),
  66. },
  67. { //2
  68. method: "SayHello",
  69. params: []interface{}{
  70. map[string]interface{}{
  71. "arbitrary": "world",
  72. },
  73. },
  74. err: "invalid type for string type field 'name': cannot convert map[string]interface {}(map[arbitrary:world]) to string",
  75. },
  76. { //3
  77. method: "Compute",
  78. params: []interface{}{
  79. "rid", "uuid", "outlet", "path", []byte("data"), "extra",
  80. },
  81. iresult: []interface{}{
  82. "rid", "uuid", "outlet", "path", []byte("data"), "extra",
  83. },
  84. jresult: []byte(`{"rid":"rid","uuid":"uuid","outlet":"outlet","path":"path","data":"ZGF0YQ==","extra":"extra"}`),
  85. },
  86. { //4
  87. method: "get_feature",
  88. params: []interface{}{
  89. []byte("golang"),
  90. },
  91. iresult: []interface{}{
  92. []byte("golang"),
  93. },
  94. jresult: []byte(`"Z29sYW5n"`),
  95. },
  96. //{ //5
  97. // method: "get_similarity",
  98. // params: []interface{}{
  99. // []float64{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  100. // []float64{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  101. // },
  102. // iresult: []interface{}{
  103. // []float32{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  104. // []float32{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  105. // },
  106. // jresult: []byte(`{"featureA":[0.031646,-0.800592,-1.101858,-0.354359,0.656587],"featureB":[0.354359,0.656587,-0.327047,0.198284,-2.142494,0.76016,1.680131]}`),
  107. //},
  108. { // 6
  109. method: "RestEncodedJson",
  110. params: []interface{}{
  111. []byte("{\"name\":\"encoded json\",\"size\":1}"),
  112. },
  113. iresult: []interface{}{
  114. "{\"name\":\"encoded json\",\"size\":1}",
  115. },
  116. jresult: []byte("{\"name\":\"encoded json\",\"size\":1}"),
  117. },
  118. }
  119. for i, descriptor := range descriptors {
  120. for j, tt := range tests {
  121. r, err := descriptor.(interfaceDescriptor).ConvertParams(tt.method, tt.params)
  122. if !reflect.DeepEqual(tt.err, testx.Errstring(err)) {
  123. t.Errorf("%d.%d : interface error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.err, err)
  124. } else if tt.err == "" && !reflect.DeepEqual(tt.iresult, r) {
  125. t.Errorf("%d.%d \n\ninterface result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.iresult, r)
  126. }
  127. rj, err := descriptor.(jsonDescriptor).ConvertParamsToJson(tt.method, tt.params)
  128. if !reflect.DeepEqual(tt.err, testx.Errstring(err)) {
  129. t.Errorf("%d.%d : json error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.err, err)
  130. } else if tt.err == "" && !reflect.DeepEqual(tt.jresult, rj) {
  131. t.Errorf("%d.%d \n\njson result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.jresult, rj)
  132. }
  133. }
  134. }
  135. }
  136. func TestConvertReturns(t *testing.T) {
  137. tests := []struct {
  138. method string
  139. ireturn interface{}
  140. iresult interface{}
  141. ierr string
  142. jreturn []byte
  143. jresult interface{}
  144. jerr string
  145. }{
  146. { // 0
  147. method: "SayHello",
  148. ireturn: map[string]interface{}{"message": "world"},
  149. iresult: map[string]interface{}{"message": "world"},
  150. jreturn: []byte(`{"message":"world"}`),
  151. jresult: map[string]interface{}{"message": "world"},
  152. },
  153. { // 1
  154. method: "SayHello",
  155. ireturn: map[string]interface{}{"message": 65},
  156. ierr: "invalid type of return value for 'message': cannot convert int(65) to string",
  157. jreturn: []byte(`{"message":65}`),
  158. jerr: "invalid type of return value for 'message': cannot convert float64(65) to string",
  159. },
  160. //{
  161. // method: "SayHello",
  162. // ireturn: map[string]interface{}{
  163. // "mess":"world",
  164. // },
  165. // jreturn: []byte(`{"mess":"world"}`),
  166. //err: "invalid type for field 'message', expect string but got int)",
  167. //},
  168. { // 2
  169. method: "Compute",
  170. ireturn: map[string]interface{}{
  171. "code": int64(200),
  172. "msg": "success",
  173. },
  174. iresult: map[string]interface{}{
  175. "code": int64(200),
  176. "msg": "success",
  177. },
  178. jreturn: []byte(`{"code":200,"msg":"success"}`),
  179. jresult: map[string]interface{}{
  180. "code": int64(200),
  181. "msg": "success",
  182. },
  183. },
  184. {
  185. method: "get_feature",
  186. ireturn: map[string]interface{}{"feature": []interface{}{ //TODO check msgpack result
  187. map[string]interface{}{
  188. "box": map[string]interface{}{"x": int32(55), "y": int32(65), "w": int32(33), "h": int32(69)},
  189. "features": []float32{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  190. },
  191. map[string]interface{}{
  192. "box": map[string]interface{}{"x": int32(987), "y": int32(66), "w": int32(66), "h": int32(55)},
  193. "features": []float32{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  194. },
  195. }},
  196. iresult: map[string]interface{}{
  197. "feature": []map[string]interface{}{
  198. {
  199. "box": map[string]interface{}{"x": int64(55), "y": int64(65), "w": int64(33), "h": int64(69)},
  200. "features": []float64{float64(float32(0.031646)), float64(float32(-0.800592)), float64(float32(-1.101858)), float64(float32(-0.354359)), float64(float32(0.656587))},
  201. },
  202. {
  203. "box": map[string]interface{}{"x": int64(987), "y": int64(66), "w": int64(66), "h": int64(55)},
  204. "features": []float64{float64(float32(0.354359)), float64(float32(0.656587)), float64(float32(-0.327047)), float64(float32(0.198284)), float64(float32(-2.142494)), float64(float32(0.760160)), float64(float32(1.680131))},
  205. },
  206. },
  207. },
  208. jreturn: []byte(`{"feature":[{"box":{"x":55,"y":65,"w":33,"h":69},"features":[0.031646, -0.800592, -1.101858, -0.354359, 0.656587]},{"box":{"x":987,"y":66,"w":66,"h":55},"features":[0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131]}]}`),
  209. jresult: map[string]interface{}{
  210. "feature": []map[string]interface{}{
  211. {
  212. "box": map[string]interface{}{"x": int64(55), "y": int64(65), "w": int64(33), "h": int64(69)},
  213. "features": []float64{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  214. },
  215. {
  216. "box": map[string]interface{}{"x": int64(987), "y": int64(66), "w": int64(66), "h": int64(55)},
  217. "features": []float64{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  218. },
  219. },
  220. },
  221. },
  222. //{
  223. // method: "get_similarity",
  224. // ireturn: float32(0.987),
  225. // iresult: float64(float32(0.987)),
  226. // jreturn: []byte(`{"response":0.987}`),
  227. // jresult: map[string]interface{}{
  228. // "response": 0.987,
  229. // },
  230. //},
  231. }
  232. for i, descriptor := range descriptors {
  233. for j, tt := range tests {
  234. r, err := descriptor.(interfaceDescriptor).ConvertReturn(tt.method, tt.ireturn)
  235. if !reflect.DeepEqual(tt.ierr, testx.Errstring(err)) {
  236. t.Errorf("%d.%d : interface error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.ierr, err)
  237. } else if tt.ierr == "" && !reflect.DeepEqual(tt.iresult, r) {
  238. t.Errorf("%d.%d \n\ninterface result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.iresult, r)
  239. }
  240. rj, err := descriptor.(jsonDescriptor).ConvertReturnJson(tt.method, tt.jreturn)
  241. if !reflect.DeepEqual(tt.jerr, testx.Errstring(err)) {
  242. t.Errorf("%d.%d : json error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.jerr, err)
  243. } else if tt.jerr == "" && !reflect.DeepEqual(tt.jresult, rj) {
  244. t.Errorf("%d.%d \n\njson result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.jresult, rj)
  245. }
  246. }
  247. }
  248. }