schema_test.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Copyright 2021-2023 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. "reflect"
  17. "testing"
  18. "github.com/lf-edge/ekuiper/internal/testx"
  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. tresult []byte
  44. err string
  45. }{
  46. { // 0
  47. method: "SayHello",
  48. params: []interface{}{
  49. "world",
  50. },
  51. iresult: []interface{}{
  52. "world",
  53. },
  54. jresult: []byte(`{"name":"world"}`),
  55. tresult: []byte(`name:"world"`),
  56. },
  57. { // 1
  58. method: "SayHello",
  59. params: []interface{}{
  60. map[string]interface{}{
  61. "name": "world",
  62. },
  63. },
  64. iresult: []interface{}{
  65. "world",
  66. },
  67. jresult: []byte(`{"name":"world"}`),
  68. tresult: []byte(`name:"world"`),
  69. },
  70. { // 2
  71. method: "SayHello",
  72. params: []interface{}{
  73. map[string]interface{}{
  74. "arbitrary": "world",
  75. },
  76. },
  77. err: "invalid type for string type field 'name': cannot convert map[string]interface {}(map[arbitrary:world]) to string",
  78. },
  79. { // 3
  80. method: "Compute",
  81. params: []interface{}{
  82. "rid", "uuid", "outlet", "path", []byte("data"), "extra",
  83. },
  84. iresult: []interface{}{
  85. "rid", "uuid", "outlet", "path", []byte("data"), "extra",
  86. },
  87. jresult: []byte(`{"rid":"rid","uuid":"uuid","outlet":"outlet","path":"path","data":"ZGF0YQ==","extra":"extra"}`),
  88. tresult: []byte(`rid:"rid" uuid:"uuid" outlet:"outlet" path:"path" data:"data" extra:"extra"`),
  89. },
  90. { // 4
  91. method: "get_feature",
  92. params: []interface{}{
  93. []byte("golang"),
  94. },
  95. iresult: []interface{}{
  96. []byte("golang"),
  97. },
  98. jresult: []byte(`"Z29sYW5n"`),
  99. tresult: []byte(`value:"golang"`),
  100. },
  101. //{ //5
  102. // method: "get_similarity",
  103. // params: []interface{}{
  104. // []float64{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  105. // []float64{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  106. // },
  107. // iresult: []interface{}{
  108. // []float32{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  109. // []float32{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  110. // },
  111. // 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]}`),
  112. //},
  113. { // 6
  114. method: "RestEncodedJson",
  115. params: []interface{}{
  116. []byte("{\"name\":\"encoded json\",\"size\":1}"),
  117. },
  118. iresult: []interface{}{
  119. "{\"name\":\"encoded json\",\"size\":1}",
  120. },
  121. jresult: []byte("{\"name\":\"encoded json\",\"size\":1}"),
  122. tresult: []byte(`value:"{\"name\":\"encoded json\",\"size\":1}"`),
  123. },
  124. }
  125. for i, descriptor := range descriptors {
  126. for j, tt := range tests {
  127. r, err := descriptor.(interfaceDescriptor).ConvertParams(tt.method, tt.params)
  128. if !reflect.DeepEqual(tt.err, testx.Errstring(err)) {
  129. t.Errorf("%d.%d : interface error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.err, err)
  130. } else if tt.err == "" && !reflect.DeepEqual(tt.iresult, r) {
  131. t.Errorf("%d.%d \n\ninterface result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.iresult, r)
  132. }
  133. rj, err := descriptor.(jsonDescriptor).ConvertParamsToJson(tt.method, tt.params)
  134. if !reflect.DeepEqual(tt.err, testx.Errstring(err)) {
  135. t.Errorf("%d.%d : json error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.err, err)
  136. } else if tt.err == "" && !reflect.DeepEqual(tt.jresult, rj) {
  137. t.Errorf("%d.%d \n\njson result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.jresult, rj)
  138. }
  139. tj, err := descriptor.(textDescriptor).ConvertParamsToText(tt.method, tt.params)
  140. if !reflect.DeepEqual(tt.err, testx.Errstring(err)) {
  141. t.Errorf("%d.%d : text error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.err, err)
  142. } else if tt.err == "" && !reflect.DeepEqual(tt.tresult, tj) {
  143. t.Errorf("%d.%d \n\ntext result mismatch:\n\nexp=%s\n\ngot=%s\n\n", i, j, tt.tresult, tj)
  144. }
  145. }
  146. }
  147. }
  148. func TestConvertReturns(t *testing.T) {
  149. tests := []struct {
  150. method string
  151. ireturn interface{}
  152. iresult interface{}
  153. ierr string
  154. jreturn []byte
  155. jresult interface{}
  156. jerr string
  157. }{
  158. { // 0
  159. method: "SayHello",
  160. ireturn: map[string]interface{}{"message": "world"},
  161. iresult: map[string]interface{}{"message": "world"},
  162. jreturn: []byte(`{"message":"world"}`),
  163. jresult: map[string]interface{}{"message": "world"},
  164. },
  165. { // 1
  166. method: "SayHello",
  167. ireturn: map[string]interface{}{"message": 65},
  168. ierr: "invalid type of return value for 'message': cannot convert int(65) to string",
  169. jreturn: []byte(`{"message":65}`),
  170. jerr: "invalid type of return value for 'message': cannot convert float64(65) to string",
  171. },
  172. //{
  173. // method: "SayHello",
  174. // ireturn: map[string]interface{}{
  175. // "mess":"world",
  176. // },
  177. // jreturn: []byte(`{"mess":"world"}`),
  178. //err: "invalid type for field 'message', expect string but got int)",
  179. //},
  180. { // 2
  181. method: "Compute",
  182. ireturn: map[string]interface{}{
  183. "code": int64(200),
  184. "msg": "success",
  185. },
  186. iresult: map[string]interface{}{
  187. "code": int64(200),
  188. "msg": "success",
  189. },
  190. jreturn: []byte(`{"code":200,"msg":"success"}`),
  191. jresult: map[string]interface{}{
  192. "code": int64(200),
  193. "msg": "success",
  194. },
  195. },
  196. {
  197. method: "get_feature",
  198. ireturn: map[string]interface{}{"feature": []interface{}{ // TODO check msgpack result
  199. map[string]interface{}{
  200. "box": map[string]interface{}{"x": int32(55), "y": int32(65), "w": int32(33), "h": int32(69)},
  201. "features": []float32{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  202. },
  203. map[string]interface{}{
  204. "box": map[string]interface{}{"x": int32(987), "y": int32(66), "w": int32(66), "h": int32(55)},
  205. "features": []float32{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  206. },
  207. }},
  208. iresult: map[string]interface{}{
  209. "feature": []map[string]interface{}{
  210. {
  211. "box": map[string]interface{}{"x": int64(55), "y": int64(65), "w": int64(33), "h": int64(69)},
  212. "features": []float64{float64(float32(0.031646)), float64(float32(-0.800592)), float64(float32(-1.101858)), float64(float32(-0.354359)), float64(float32(0.656587))},
  213. },
  214. {
  215. "box": map[string]interface{}{"x": int64(987), "y": int64(66), "w": int64(66), "h": int64(55)},
  216. "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))},
  217. },
  218. },
  219. },
  220. 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]}]}`),
  221. jresult: map[string]interface{}{
  222. "feature": []map[string]interface{}{
  223. {
  224. "box": map[string]interface{}{"x": int64(55), "y": int64(65), "w": int64(33), "h": int64(69)},
  225. "features": []float64{0.031646, -0.800592, -1.101858, -0.354359, 0.656587},
  226. },
  227. {
  228. "box": map[string]interface{}{"x": int64(987), "y": int64(66), "w": int64(66), "h": int64(55)},
  229. "features": []float64{0.354359, 0.656587, -0.327047, 0.198284, -2.142494, 0.760160, 1.680131},
  230. },
  231. },
  232. },
  233. },
  234. //{
  235. // method: "get_similarity",
  236. // ireturn: float32(0.987),
  237. // iresult: float64(float32(0.987)),
  238. // jreturn: []byte(`{"response":0.987}`),
  239. // jresult: map[string]interface{}{
  240. // "response": 0.987,
  241. // },
  242. //},
  243. }
  244. for i, descriptor := range descriptors {
  245. for j, tt := range tests {
  246. r, err := descriptor.(interfaceDescriptor).ConvertReturn(tt.method, tt.ireturn)
  247. if !reflect.DeepEqual(tt.ierr, testx.Errstring(err)) {
  248. t.Errorf("%d.%d : interface error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.ierr, err)
  249. } else if tt.ierr == "" && !reflect.DeepEqual(tt.iresult, r) {
  250. t.Errorf("%d.%d \n\ninterface result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.iresult, r)
  251. }
  252. rj, err := descriptor.(jsonDescriptor).ConvertReturnJson(tt.method, tt.jreturn)
  253. if !reflect.DeepEqual(tt.jerr, testx.Errstring(err)) {
  254. t.Errorf("%d.%d : json error mismatch:\n exp=%s\n got=%s\n\n", i, j, tt.jerr, err)
  255. } else if tt.jerr == "" && !reflect.DeepEqual(tt.jresult, rj) {
  256. t.Errorf("%d.%d \n\njson result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.jresult, rj)
  257. }
  258. }
  259. }
  260. }