github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/iextengine/wazero/impl_helpers_test.go (about) 1 /* 2 - Copyright (c) 2023-present unTill Software Development Group B.V. 3 @author Michael Saigachenko 4 */ 5 6 package iextenginewazero 7 8 import ( 9 "encoding/json" 10 "errors" 11 "fmt" 12 "net/url" 13 "path/filepath" 14 15 "github.com/voedger/voedger/pkg/appdef" 16 "github.com/voedger/voedger/pkg/istructs" 17 "github.com/voedger/voedger/pkg/state" 18 coreutils "github.com/voedger/voedger/pkg/utils" 19 ) 20 21 var errTestIOError = errors.New("test i/o error") 22 23 var storageTest = appdef.NewQName("sys", "Test") 24 var storageTest2 = appdef.NewQName("sys", "Test2") 25 var storageTest3 = appdef.NewQName("sys", "Test3") 26 var storageTestQname = appdef.NewQName("sys", "TestQName") 27 var storageIoError = appdef.NewQName("sys", "IoErrorStorage") 28 var projectorMode bool 29 30 const testPackageLocalPath = "testpkg1" 31 const testPackageFullPath = "github.com/voedger/testpkg1" 32 33 type mockIo struct { 34 istructs.IState 35 istructs.IIntents 36 istructs.IPkgNameResolver 37 intents []intent 38 } 39 40 func (s *mockIo) PackageFullPath(localName string) string { 41 if localName == testPackageLocalPath { 42 return testPackageFullPath 43 } 44 return localName 45 46 } 47 func (s *mockIo) PackageLocalName(fullPath string) string { 48 if fullPath == testPackageFullPath { 49 return testPackageLocalPath 50 } 51 return fullPath 52 } 53 54 func testModuleURL(path string) (u *url.URL) { 55 56 path, err := filepath.Abs(path) 57 if err != nil { 58 panic(err) 59 } 60 61 u, err = url.Parse("file:///" + filepath.ToSlash(path)) 62 if err != nil { 63 panic(err) 64 } 65 66 return 67 68 } 69 70 func (s *mockIo) KeyBuilder(storage, entity appdef.QName) (builder istructs.IStateKeyBuilder, err error) { 71 return &mockKeyBuilder{ 72 entity: entity, 73 storage: storage, 74 data: map[string]interface{}{}, 75 }, nil 76 } 77 78 func mockedValue(name string, value interface{}) istructs.IStateValue { 79 mv := mockValue{ 80 TestObject: coreutils.TestObject{Data: map[string]interface{}{}}, 81 } 82 mv.Data[name] = value 83 return &mv 84 } 85 86 func (s *mockIo) CanExist(key istructs.IStateKeyBuilder) (value istructs.IStateValue, ok bool, err error) { 87 k := key.(*mockKeyBuilder) 88 mv := mockValue{ 89 TestObject: coreutils.TestObject{Data: map[string]interface{}{}}, 90 } 91 if k.storage == storageIoError { 92 return nil, false, errTestIOError 93 } 94 if k.storage == state.Event { 95 if projectorMode { 96 mv.Data["offs"] = int32(12345) 97 mv.Data["qname"] = "air.UpdateSubscription" 98 mv.Data["arg"] = newJsonValue(` 99 { 100 "subscription": { 101 "status": "active" 102 }, 103 "customer": { 104 "email": "customer@test.com" 105 } 106 } 107 `) 108 return &mv, true, nil 109 110 } 111 mv.Data["qname"] = "sys.InvitationAccepted" 112 mv.Data["arg"] = mockedValue("UserEmail", "email@user.com") 113 mv.Data["offs"] = int32(12345) 114 return &mv, true, nil 115 } 116 if k.storage == storageTest { 117 mv.Data["500c"] = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" 118 mv.Data["bytes"] = make([]byte, WasmPreallocatedBufferSize*2) 119 return &mv, true, nil 120 } 121 if k.storage == storageTest3 { 122 mv.index = make([]interface{}, 4) 123 mv.index[0] = int32(123) 124 mv.index[1] = "test string" 125 mv.index[2] = make([]byte, 1024) 126 mv.index[3] = appdef.NewQName(testPackageLocalPath, "test") 127 return &mv, true, nil 128 } 129 if k.storage == storageTest2 { 130 const vvv = "012345678901234567890" 131 mv.Data["а10"] = vvv 132 mv.Data["а11"] = vvv 133 mv.Data["а12"] = vvv 134 mv.Data["а13"] = vvv 135 mv.Data["а14"] = vvv 136 mv.Data["а15"] = vvv 137 mv.Data["а16"] = vvv 138 mv.Data["а17"] = vvv 139 mv.Data["а18"] = vvv 140 mv.Data["а19"] = vvv 141 mv.Data["а20"] = vvv 142 mv.Data["а21"] = vvv 143 mv.Data["а22"] = vvv 144 mv.Data["а23"] = vvv 145 mv.Data["а24"] = vvv 146 mv.Data["а25"] = vvv 147 mv.Data["а26"] = vvv 148 mv.Data["а27"] = vvv 149 mv.Data["а28"] = vvv 150 mv.Data["а29"] = vvv 151 mv.Data["а30"] = vvv 152 mv.Data["а31"] = vvv 153 mv.Data["а32"] = vvv 154 mv.Data["а33"] = vvv 155 mv.Data["а34"] = vvv 156 mv.Data["а35"] = vvv 157 mv.Data["а36"] = vvv 158 mv.Data["а37"] = vvv 159 mv.Data["а38"] = vvv 160 mv.Data["а39"] = vvv 161 return &mv, true, nil 162 } 163 if k.storage == storageTestQname { 164 qn := k.data["qname"].(appdef.QName) 165 if qn.Pkg() != testPackageLocalPath { 166 return nil, false, errors.New("unexpected package: " + qn.Pkg()) 167 } 168 return &mv, true, nil 169 } 170 if k.storage == state.SendMail { 171 return &mv, true, nil 172 } 173 if k.storage == state.Record { 174 return &mv, false, nil 175 } 176 return nil, false, errors.New("unsupported storage: " + k.storage.Pkg() + "." + k.storage.Entity()) 177 } 178 179 func (s *mockIo) CanExistAll(keys []istructs.IStateKeyBuilder, callback istructs.StateValueCallback) (err error) { 180 return nil 181 } 182 183 func (s *mockIo) MustExist(key istructs.IStateKeyBuilder) (value istructs.IStateValue, err error) { 184 k := key.(*mockKeyBuilder) 185 if k.storage == storageIoError { 186 return nil, errTestIOError 187 } 188 if k.storage == state.Record { 189 return nil, state.ErrNotExists 190 } 191 v, ok, err := s.CanExist(key) 192 if err != nil { 193 return v, err 194 } 195 if !ok { 196 panic("not exists") 197 } 198 199 return v, nil 200 } 201 202 func (s *mockIo) MustExistAll(keys []istructs.IStateKeyBuilder, callback istructs.StateValueCallback) (err error) { 203 return nil 204 } 205 206 func (s *mockIo) MustNotExist(key istructs.IStateKeyBuilder) (err error) { 207 return nil 208 } 209 210 func (s *mockIo) MustNotExistAll(keys []istructs.IStateKeyBuilder) (err error) { 211 return nil 212 } 213 214 func (s *mockIo) Read(key istructs.IStateKeyBuilder, callback istructs.ValueCallback) (err error) { 215 k := key.(*mockKeyBuilder) 216 if k.storage == storageIoError { 217 return errTestIOError 218 } 219 if k.storage == storageTest { 220 for i := 1; i <= 3; i++ { 221 mk := coreutils.TestObject{Data: map[string]interface{}{}} 222 mk.Data["i32"] = int32(i) 223 mk.Data["i64"] = 10 + int64(i) 224 mk.Data["f32"] = float32(i) + 0.1 225 mk.Data["f64"] = float64(i) + 0.01 226 mk.Data["str"] = fmt.Sprintf("key%d", i) 227 mk.Data["bytes"] = []byte{byte(i), 2, 3} 228 mk.Data["qname"] = appdef.NewQName(testPackageLocalPath, fmt.Sprintf("e%d", i)) 229 mk.Data["bool"] = true 230 231 mv := mockValue{ 232 TestObject: coreutils.TestObject{Data: map[string]interface{}{}}, 233 } 234 mv.Data["i32"] = 100 + int32(i) 235 mv.Data["i64"] = 1000 + int64(i) 236 mv.Data["f32"] = float32(i) + 0.001 237 mv.Data["f64"] = float64(i) + 0.0001 238 mv.Data["str"] = fmt.Sprintf("value%d", i) 239 mv.Data["bytes"] = []byte{3, 2, 1} 240 mv.Data["qname"] = appdef.NewQName(testPackageLocalPath, fmt.Sprintf("ee%d", i)) 241 mv.Data["bool"] = false 242 if err := callback(&mk, &mv); err != nil { 243 return err 244 } 245 } 246 247 } 248 return nil 249 } 250 251 type mockKeyBuilder struct { 252 entity appdef.QName 253 storage appdef.QName 254 data map[string]interface{} 255 } 256 257 func (kb *mockKeyBuilder) Storage() appdef.QName { return kb.storage } 258 func (kb *mockKeyBuilder) Entity() appdef.QName { return kb.entity } 259 func (kb *mockKeyBuilder) PartitionKey() istructs.IRowWriter { return nil } 260 func (kb *mockKeyBuilder) ClusteringColumns() istructs.IRowWriter { return nil } 261 func (kb *mockKeyBuilder) Equals(src istructs.IKeyBuilder) bool { return false } 262 func (kb *mockKeyBuilder) PutInt32(name string, value int32) {} 263 func (kb *mockKeyBuilder) PutInt64(name string, value int64) {} 264 func (kb *mockKeyBuilder) PutFloat32(name string, value float32) {} 265 func (kb *mockKeyBuilder) PutFloat64(name string, value float64) {} 266 func (kb *mockKeyBuilder) PutBytes(name string, value []byte) {} 267 func (kb *mockKeyBuilder) PutString(name, value string) {} 268 func (kb *mockKeyBuilder) PutQName(name string, value appdef.QName) { kb.data[name] = value } 269 func (kb *mockKeyBuilder) PutBool(name string, value bool) {} 270 func (kb *mockKeyBuilder) PutRecordID(name string, value istructs.RecordID) {} 271 func (kb *mockKeyBuilder) ToBytes(istructs.WSID) ([]byte, []byte, error) { return nil, nil, nil } 272 273 // Tries to make conversion from value to a name type 274 func (kb *mockKeyBuilder) PutNumber(name string, value float64) {} 275 276 // Tries to make conversion from value to a name type 277 func (kb *mockKeyBuilder) PutChars(name string, value string) {} 278 279 func (kb *mockKeyBuilder) PutFromJSON(map[string]any) {} 280 281 func newJsonValue(jsonString string) istructs.IStateValue { 282 v := mockValue{TestObject: coreutils.TestObject{Data: map[string]interface{}{}}} 283 err := json.Unmarshal([]byte(jsonString), &v.Data) 284 if err != nil { 285 panic(err) 286 } 287 return &v 288 } 289 290 type mockValue struct { 291 coreutils.TestObject 292 index []interface{} 293 } 294 295 func (v *mockValue) ToJSON(opts ...interface{}) (string, error) { return "", nil } 296 func (v *mockValue) AsRecord(name string) (record istructs.IRecord) { return nil } 297 func (v *mockValue) AsEvent(name string) (event istructs.IDbEvent) { return nil } 298 299 func (v *mockValue) GetAsInt32(index int) int32 { return v.index[index].(int32) } 300 func (v *mockValue) GetAsInt64(index int) int64 { return 0 } 301 func (v *mockValue) GetAsFloat32(index int) float32 { return 0 } 302 func (v *mockValue) GetAsFloat64(index int) float64 { return 0 } 303 func (v *mockValue) GetAsBytes(index int) []byte { return v.index[index].([]byte) } 304 func (v *mockValue) GetAsString(index int) string { return v.index[index].(string) } 305 func (v *mockValue) GetAsQName(index int) appdef.QName { return v.index[index].(appdef.QName) } 306 func (v *mockValue) GetAsBool(index int) bool { return false } 307 308 func (v *mockValue) Length() int { return 0 } 309 func (v *mockValue) AsRecordID(name string) istructs.RecordID { return 0 } 310 func (v *mockValue) GetAsValue(index int) istructs.IStateValue { 311 iv, ok := v.index[index].(istructs.IStateValue) 312 if ok { 313 return iv 314 } 315 mv, ok := v.index[index].([]interface{}) 316 if ok { 317 return &mockValue{ 318 index: mv, 319 } 320 } 321 panic(fmt.Sprintf("unsupported value stored under index: %d", index)) 322 } 323 func (v *mockValue) AsValue(name string) istructs.IStateValue { 324 iv, ok := v.Data[name].(istructs.IStateValue) 325 if ok { 326 return iv 327 } 328 mv, ok := v.Data[name].(map[string]interface{}) 329 if ok { 330 return &mockValue{ 331 TestObject: coreutils.TestObject{Data: mv}, 332 } 333 } 334 panic("unsupported value stored under key: " + name) 335 } 336 func (v *mockValue) RecordIDs(includeNulls bool, cb func(name string, value istructs.RecordID)) {} 337 func (v *mockValue) FieldNames(cb func(fieldName string)) { 338 v.TestObject.FieldNames(cb) 339 } 340 341 type intent struct { 342 key istructs.IStateKeyBuilder 343 value istructs.IStateValueBuilder 344 } 345 346 func (s *mockIo) NewValue(key istructs.IStateKeyBuilder) (builder istructs.IStateValueBuilder, err error) { 347 k := key.(*mockKeyBuilder) 348 if k.storage == storageIoError { 349 return nil, errTestIOError 350 } 351 vb := mockValueBuilder{ 352 items: make(map[string]interface{}), 353 } 354 s.intents = append(s.intents, intent{ 355 key: key, 356 value: &vb, 357 }) 358 return &vb, nil 359 } 360 361 func (s *mockIo) UpdateValue(key istructs.IStateKeyBuilder, existingValue istructs.IStateValue) (builder istructs.IStateValueBuilder, err error) { 362 k := key.(*mockKeyBuilder) 363 if k.storage == storageIoError { 364 return nil, errTestIOError 365 } 366 vb := mockValueBuilder{ 367 items: make(map[string]interface{}), 368 } 369 mv := existingValue.(*mockValue) 370 for k, v := range mv.Data { 371 vb.items[k] = v 372 } 373 s.intents = append(s.intents, intent{ 374 key: key, 375 value: &vb, 376 }) 377 return &vb, nil 378 } 379 380 type mockValueBuilder struct { 381 items map[string]interface{} 382 } 383 384 func (vb *mockValueBuilder) Equal(src istructs.IStateValueBuilder) bool { return false } 385 func (vb *mockValueBuilder) BuildValue() istructs.IStateValue { return nil } 386 func (vb *mockValueBuilder) PutRecord(name string, record istructs.IRecord) {} 387 func (vb *mockValueBuilder) PutEvent(name string, event istructs.IDbEvent) {} 388 func (vb *mockValueBuilder) Build() istructs.IValue { return nil } 389 func (vb *mockValueBuilder) PutInt32(name string, value int32) { vb.items[name] = value } 390 func (vb *mockValueBuilder) PutInt64(name string, value int64) {} 391 func (vb *mockValueBuilder) PutFloat32(name string, value float32) {} 392 func (vb *mockValueBuilder) PutFloat64(name string, value float64) {} 393 func (vb *mockValueBuilder) PutBytes(name string, value []byte) { vb.items[name] = value } 394 func (vb *mockValueBuilder) PutString(name, value string) { vb.items[name] = value } 395 func (vb *mockValueBuilder) PutQName(name string, value appdef.QName) { vb.items[name] = value } 396 func (vb *mockValueBuilder) PutBool(name string, value bool) {} 397 func (vb *mockValueBuilder) PutRecordID(name string, value istructs.RecordID) {} 398 func (vb *mockValueBuilder) PutFromJSON(map[string]any) {} 399 func (vb *mockValueBuilder) ToBytes() ([]byte, error) { return nil, nil } 400 func (vb *mockValueBuilder) PutNumber(name string, value float64) {} 401 func (vb *mockValueBuilder) PutChars(name string, value string) {}