caller_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright 2019 Yunion
  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 db
  15. import (
  16. "context"
  17. "fmt"
  18. "reflect"
  19. "testing"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/log"
  22. api "yunion.io/x/onecloud/pkg/apis/compute"
  23. )
  24. func Test_valueToJSONObject(t *testing.T) {
  25. tests := []struct {
  26. name string
  27. args interface{}
  28. want jsonutils.JSONObject
  29. }{
  30. {
  31. name: "json2json",
  32. args: jsonutils.NewDict(),
  33. want: jsonutils.NewDict(),
  34. },
  35. {
  36. name: "struct2json",
  37. args: &api.ServerRebuildRootInput{Image: "image"},
  38. want: jsonutils.Marshal(api.ServerRebuildRootInput{Image: "image"}),
  39. },
  40. }
  41. for _, tt := range tests {
  42. t.Run(tt.name, func(t *testing.T) {
  43. if got := ValueToJSONObject(reflect.ValueOf(tt.args)); !reflect.DeepEqual(got, tt.want) {
  44. t.Errorf("toJSONObject() = %v, want %v", got, tt.want)
  45. }
  46. })
  47. }
  48. }
  49. type fakeModel struct{}
  50. func (m *fakeModel) PerformAction(ctx context.Context, input *api.ServerRebuildRootInput) *api.SGuest {
  51. log.Infof("input: %#v", input)
  52. out := new(api.SGuest)
  53. out.Id = input.ImageId
  54. return out
  55. }
  56. func Test_call(t *testing.T) {
  57. type args struct {
  58. modelVal reflect.Value
  59. fName string
  60. inputs []interface{}
  61. }
  62. fModel := new(fakeModel)
  63. c1Out := new(api.SGuest)
  64. c1Out.Id = "id"
  65. tests := []struct {
  66. name string
  67. args args
  68. want []reflect.Value
  69. wantErr bool
  70. }{
  71. {
  72. name: "input struct",
  73. args: args{
  74. modelVal: reflect.ValueOf(fModel),
  75. fName: "PerformAction",
  76. inputs: []interface{}{context.TODO(), &api.ServerRebuildRootInput{ImageId: "id"}},
  77. },
  78. want: []reflect.Value{reflect.ValueOf(c1Out)},
  79. wantErr: false,
  80. },
  81. {
  82. name: "input json object",
  83. args: args{
  84. modelVal: reflect.ValueOf(fModel),
  85. fName: "PerformAction",
  86. inputs: []interface{}{context.TODO(), jsonutils.Marshal(api.ServerRebuildRootInput{ImageId: "id"})},
  87. },
  88. want: []reflect.Value{reflect.ValueOf(c1Out)},
  89. wantErr: false,
  90. },
  91. }
  92. for _, tt := range tests {
  93. t.Run(tt.name, func(t *testing.T) {
  94. got, err := callObject(tt.args.modelVal, tt.args.fName, tt.args.inputs...)
  95. if (err != nil) != tt.wantErr {
  96. t.Errorf("call() error = %v, wantErr %v", err, tt.wantErr)
  97. return
  98. }
  99. log.Infof("out1 %s", jsonutils.Marshal(got[0].Interface()))
  100. for i := range got {
  101. gi := got[i].Interface()
  102. wt := tt.want[i].Interface()
  103. if !reflect.DeepEqual(gi, wt) {
  104. t.Errorf("call() = %v, want %v", got, tt.want)
  105. }
  106. }
  107. })
  108. }
  109. }
  110. type Embeded struct {
  111. }
  112. func (e *Embeded) Method() {
  113. fmt.Println("Embeded Method")
  114. }
  115. type Struct0 struct {
  116. Embeded
  117. }
  118. type Struct1 struct {
  119. Embeded
  120. }
  121. type Struct2 struct {
  122. }
  123. func (e *Struct0) Method() {
  124. fmt.Println("Struct0 Method")
  125. }
  126. type Top0 struct {
  127. Struct0
  128. Struct1
  129. Struct2
  130. }
  131. type Top1 struct {
  132. Struct0
  133. Struct1
  134. Struct2
  135. }
  136. func (e *Top1) Method() {
  137. fmt.Println("Top1 Method")
  138. }
  139. func TestFindFunc(t *testing.T) {
  140. cases := []struct {
  141. obj interface{}
  142. want bool
  143. }{
  144. {
  145. obj: &Embeded{},
  146. want: true,
  147. },
  148. {
  149. obj: &Struct0{},
  150. want: true,
  151. },
  152. {
  153. obj: &Struct1{},
  154. want: true,
  155. },
  156. {
  157. obj: &Struct2{},
  158. want: false,
  159. },
  160. {
  161. obj: &Top0{},
  162. want: true,
  163. },
  164. {
  165. obj: &Top1{},
  166. want: true,
  167. },
  168. }
  169. for _, c := range cases {
  170. t.Logf("%s is called", reflect.TypeOf(c.obj))
  171. funcVal, err := findFunc(reflect.ValueOf(c.obj), "Method")
  172. if funcVal.IsValid() {
  173. funcVal.Call(nil)
  174. }
  175. if (c.want && err != nil) || (!c.want && err == nil) {
  176. t.Errorf("%s want %v but err==nil %v", reflect.TypeOf(c.obj), c.want, err == nil)
  177. }
  178. }
  179. }