dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts@v1.0.2/dtos/reading_test.go (about) 1 // 2 // Copyright (C) 2020-2023 IOTech Ltd 3 // 4 // SPDX-License-Identifier: Apache-2.0 5 6 package dtos 7 8 import ( 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 13 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/common" 14 "dev.azure.com/aidainnovazione0090/DeviceManager/_git/go-mod-core-contracts/models" 15 16 "github.com/stretchr/testify/assert" 17 ) 18 19 var testSimpleReading = BaseReading{ 20 Id: TestUUID, 21 DeviceName: TestDeviceName, 22 ResourceName: TestReadingName, 23 ProfileName: TestDeviceProfileName, 24 Origin: TestTimestamp, 25 ValueType: TestValueType, 26 Units: TestUnit, 27 Tags: testTags, 28 SimpleReading: SimpleReading{ 29 Value: TestValue, 30 }, 31 } 32 33 func Test_ToReadingModel(t *testing.T) { 34 valid := testSimpleReading 35 expectedSimpleReading := models.SimpleReading{ 36 BaseReading: models.BaseReading{ 37 Id: TestUUID, 38 DeviceName: TestDeviceName, 39 ResourceName: TestReadingName, 40 ProfileName: TestDeviceProfileName, 41 Origin: TestTimestamp, 42 ValueType: TestValueType, 43 Units: TestUnit, 44 Tags: testTags, 45 }, 46 Value: TestValue, 47 } 48 tests := []struct { 49 name string 50 reading BaseReading 51 }{ 52 {"valid Reading", valid}, 53 } 54 for _, tt := range tests { 55 t.Run(tt.name, func(t *testing.T) { 56 readingModel := ToReadingModel(tt.reading) 57 assert.Equal(t, expectedSimpleReading, readingModel, "ToReadingModel did not result in expected Reading model.") 58 }) 59 } 60 } 61 62 func TestFromReadingModelToDTO(t *testing.T) { 63 valid := models.SimpleReading{ 64 BaseReading: models.BaseReading{ 65 Id: TestUUID, 66 Origin: TestTimestamp, 67 DeviceName: TestDeviceName, 68 ResourceName: TestReadingName, 69 ProfileName: TestDeviceProfileName, 70 ValueType: TestValueType, 71 Units: TestUnit, 72 Tags: testTags, 73 }, 74 Value: TestValue, 75 } 76 expectedDTO := BaseReading{ 77 Id: TestUUID, 78 Origin: TestTimestamp, 79 DeviceName: TestDeviceName, 80 ResourceName: TestReadingName, 81 ProfileName: TestDeviceProfileName, 82 ValueType: TestValueType, 83 Units: TestUnit, 84 Tags: testTags, 85 SimpleReading: SimpleReading{ 86 Value: TestValue, 87 }, 88 } 89 90 tests := []struct { 91 name string 92 reading models.Reading 93 }{ 94 {"success to convert from reading model to DTO ", valid}, 95 } 96 for _, tt := range tests { 97 t.Run(tt.name, func(t *testing.T) { 98 result := FromReadingModelToDTO(tt.reading) 99 assert.Equal(t, expectedDTO, result, "FromReadingModelToDTO did not result in expected Reading DTO.") 100 }) 101 } 102 } 103 104 func TestNewSimpleReading(t *testing.T) { 105 expectedDeviceName := TestDeviceName 106 expectedProfileName := TestDeviceProfileName 107 expectedResourceName := TestDeviceResourceName 108 109 tests := []struct { 110 name string 111 expectedValueType string 112 value interface{} 113 expectedValue string 114 }{ 115 {"Simple Boolean (true)", common.ValueTypeBool, true, "true"}, 116 {"Simple Boolean (false)", common.ValueTypeBool, false, "false"}, 117 {"Simple String", common.ValueTypeString, "hello world", "hello world"}, 118 {"Simple Uint8", common.ValueTypeUint8, uint8(123), "123"}, 119 {"Simple Uint16", common.ValueTypeUint16, uint16(12345), "12345"}, 120 {"Simple Uint32", common.ValueTypeUint32, uint32(1234567890), "1234567890"}, 121 {"Simple uint64", common.ValueTypeUint64, uint64(1234567890987654321), "1234567890987654321"}, 122 {"Simple int8", common.ValueTypeInt8, int8(-123), "-123"}, 123 {"Simple int16", common.ValueTypeInt16, int16(-12345), "-12345"}, 124 {"Simple int32", common.ValueTypeInt32, int32(-1234567890), "-1234567890"}, 125 {"Simple int64", common.ValueTypeInt64, int64(-1234567890987654321), "-1234567890987654321"}, 126 {"Simple Float32", common.ValueTypeFloat32, float32(123.456), "1.234560e+02"}, 127 {"Simple Float64", common.ValueTypeFloat64, float64(123456789.0987654321), "1.234568e+08"}, 128 {"Simple Boolean Array", common.ValueTypeBoolArray, []bool{true, false}, "[true, false]"}, 129 {"Simple String Array", common.ValueTypeStringArray, []string{"hello", "world"}, "[hello, world]"}, 130 {"Simple Uint8 Array", common.ValueTypeUint8Array, []uint8{123, 21}, "[123, 21]"}, 131 {"Simple Uint16 Array", common.ValueTypeUint16Array, []uint16{12345, 4321}, "[12345, 4321]"}, 132 {"Simple Uint32 Array", common.ValueTypeUint32Array, []uint32{1234567890, 87654321}, "[1234567890, 87654321]"}, 133 {"Simple Uint64 Array", common.ValueTypeUint64Array, []uint64{1234567890987654321, 10987654321}, "[1234567890987654321, 10987654321]"}, 134 {"Simple Int8 Array", common.ValueTypeInt8Array, []int8{-123, 123}, "[-123, 123]"}, 135 {"Simple Int16 Array", common.ValueTypeInt16Array, []int16{-12345, 12345}, "[-12345, 12345]"}, 136 {"Simple Int32 Array", common.ValueTypeInt32Array, []int32{-1234567890, 1234567890}, "[-1234567890, 1234567890]"}, 137 {"Simple Int64 Array", common.ValueTypeInt64Array, []int64{-1234567890987654321, 1234567890987654321}, "[-1234567890987654321, 1234567890987654321]"}, 138 {"Simple Float32 Array", common.ValueTypeFloat32Array, []float32{123.456, -654.321}, "[1.234560e+02, -6.543210e+02]"}, 139 {"Simple Float64 Array", common.ValueTypeFloat64Array, []float64{123456789.0987654321, -987654321.123456789}, "[1.234568e+08, -9.876543e+08]"}, 140 } 141 142 for _, tt := range tests { 143 t.Run(tt.name, func(t *testing.T) { 144 actual, err := NewSimpleReading(expectedProfileName, expectedDeviceName, expectedResourceName, tt.expectedValueType, tt.value) 145 require.NoError(t, err) 146 assert.NotEmpty(t, actual.Id) 147 assert.Equal(t, expectedProfileName, actual.ProfileName) 148 assert.Equal(t, expectedDeviceName, actual.DeviceName) 149 assert.Equal(t, expectedResourceName, actual.ResourceName) 150 assert.Equal(t, tt.expectedValueType, actual.ValueType) 151 assert.Equal(t, tt.expectedValue, actual.Value) 152 assert.NotZero(t, actual.Origin) 153 }) 154 } 155 } 156 157 func TestNewSimpleReadingError(t *testing.T) { 158 tests := []struct { 159 name string 160 expectedValueType string 161 value interface{} 162 }{ 163 {"Invalid Simple Boolean", common.ValueTypeBool, 123}, 164 {"Invalid Simple String", common.ValueTypeString, 234}, 165 {"Invalid Simple Uint8", common.ValueTypeUint8, uint32(1234567890)}, 166 {"Invalid Simple Uint16", common.ValueTypeUint16, uint32(1234567890)}, 167 {"Invalid Simple Uint32", common.ValueTypeUint32, uint64(1234567890987654321)}, 168 {"Invalid Simple uint64", common.ValueTypeUint64, int64(1234567890987654321)}, 169 {"Invalid Simple int8", common.ValueTypeInt8, uint8(123)}, 170 {"Invalid Simple int16", common.ValueTypeInt16, uint16(12345)}, 171 {"Invalid Simple int32", common.ValueTypeInt32, uint32(1234567890)}, 172 {"Invalid Simple int64", common.ValueTypeInt64, uint64(1234567890987654321)}, 173 {"Invalid Simple Float32", common.ValueTypeFloat32, float64(123.456)}, 174 {"Invalid Simple Float64", common.ValueTypeFloat64, float32(123456789.0987654321)}, 175 {"Invalid Simple Boolean Array", common.ValueTypeBoolArray, []string{"true", "false"}}, 176 {"Invalid Simple String Array", common.ValueTypeStringArray, []bool{false, true}}, 177 {"Invalid Simple Uint8 Array", common.ValueTypeUint8Array, []int8{123, 21}}, 178 {"Invalid Simple Uint16 Array", common.ValueTypeUint16Array, []int16{12345, 4321}}, 179 {"Invalid Simple Uint32 Array", common.ValueTypeUint32Array, []int32{1234567890, 87654321}}, 180 {"Invalid Simple Uint64 Array", common.ValueTypeUint64Array, []int64{1234567890987654321, 10987654321}}, 181 {"Invalid Simple Int8 Array", common.ValueTypeInt8Array, []uint8{123, 123}}, 182 {"Invalid Simple Int16 Array", common.ValueTypeInt16Array, []uint16{12345, 12345}}, 183 {"Invalid Simple Int32 Array", common.ValueTypeInt32Array, []uint32{1234567890, 1234567890}}, 184 {"Invalid Simple Int64 Array", common.ValueTypeInt64Array, []uint64{1234567890987654321, 1234567890987654321}}, 185 {"Invalid Simple Float32 Array", common.ValueTypeFloat32Array, []float64{123.456, -654.321}}, 186 {"Invalid Simple Float64 Array", common.ValueTypeFloat64Array, []float32{123456789.0987654321, -987654321.123456789}}, 187 } 188 189 for _, tt := range tests { 190 t.Run(tt.name, func(t *testing.T) { 191 _, err := NewSimpleReading(TestDeviceProfileName, TestDeviceName, TestDeviceResourceName, tt.expectedValueType, tt.value) 192 require.Error(t, err) 193 }) 194 } 195 } 196 197 func TestNewBinaryReading(t *testing.T) { 198 expectedDeviceName := TestDeviceName 199 expectedProfileName := TestDeviceProfileName 200 expectedResourceName := TestDeviceResourceName 201 202 expectedValueType := common.ValueTypeBinary 203 expectedBinaryValue := []byte("hello word, any one out there?") 204 expectedMediaType := "application/text" 205 206 actual := NewBinaryReading(expectedProfileName, expectedDeviceName, expectedResourceName, expectedBinaryValue, expectedMediaType) 207 208 assert.NotEmpty(t, actual.Id) 209 assert.Equal(t, expectedProfileName, actual.ProfileName) 210 assert.Equal(t, expectedDeviceName, actual.DeviceName) 211 assert.Equal(t, expectedResourceName, actual.ResourceName) 212 assert.Equal(t, expectedValueType, actual.ValueType) 213 assert.Equal(t, expectedBinaryValue, actual.BinaryValue) 214 assert.NotZero(t, actual.Origin) 215 } 216 217 func TestNewObjectReading(t *testing.T) { 218 expectedDeviceName := TestDeviceName 219 expectedProfileName := TestDeviceProfileName 220 expectedResourceName := TestDeviceResourceName 221 expectedValueType := common.ValueTypeObject 222 expectedValue := map[string]interface{}{ 223 "Attr1": "yyz", 224 "Attr2": -45, 225 "Attr3": []interface{}{255, 1, 0}, 226 } 227 228 actual := NewObjectReading(expectedProfileName, expectedDeviceName, expectedResourceName, expectedValue) 229 230 assert.NotEmpty(t, actual.Id) 231 assert.Equal(t, expectedProfileName, actual.ProfileName) 232 assert.Equal(t, expectedDeviceName, actual.DeviceName) 233 assert.Equal(t, expectedResourceName, actual.ResourceName) 234 assert.Equal(t, expectedValueType, actual.ValueType) 235 assert.Equal(t, expectedValue, actual.ObjectValue) 236 assert.NotZero(t, actual.Origin) 237 } 238 239 func TestValidateValue(t *testing.T) { 240 tests := []struct { 241 name string 242 valueType string 243 value string 244 }{ 245 {"Simple Boolean (true)", common.ValueTypeBool, "True"}, 246 {"Simple String", common.ValueTypeString, "hello world"}, 247 {"Simple Uint8", common.ValueTypeUint8, "123"}, 248 {"Simple Uint16", common.ValueTypeUint16, "12345"}, 249 {"Simple Uint32", common.ValueTypeUint32, "1234567890"}, 250 {"Simple uint64", common.ValueTypeUint64, "1234567890987654321"}, 251 {"Simple int8", common.ValueTypeInt8, "-123"}, 252 {"Simple int16", common.ValueTypeInt16, "-12345"}, 253 {"Simple int32", common.ValueTypeInt32, "-1234567890"}, 254 {"Simple int64", common.ValueTypeInt64, "-1234567890987654321"}, 255 {"Simple Float32", common.ValueTypeFloat32, "123.456"}, 256 {"Simple Float64", common.ValueTypeFloat64, "123456789.0987654321"}, 257 {"Simple Boolean Array", common.ValueTypeBoolArray, "[true, false]"}, 258 {"Simple String Array", common.ValueTypeStringArray, "[\"hello\", \"world\"]"}, 259 {"Simple Uint8 Array", common.ValueTypeUint8Array, "[123, 21]"}, 260 {"Simple Uint16 Array", common.ValueTypeUint16Array, "[12345, 4321]"}, 261 {"Simple Uint32 Array", common.ValueTypeUint32Array, "[1234567890, 87654321]"}, 262 {"Simple Uint64 Array", common.ValueTypeUint64Array, "[1234567890987654321, 10987654321]"}, 263 {"Simple Int8 Array", common.ValueTypeInt8Array, "[-123, 123]"}, 264 {"Simple Int16 Array", common.ValueTypeInt16Array, "[-12345, 12345]"}, 265 {"Simple Int32 Array", common.ValueTypeInt32Array, "[-1234567890, 1234567890]"}, 266 {"Simple Int64 Array", common.ValueTypeInt64Array, "[-1234567890987654321, 1234567890987654321]"}, 267 {"Simple Float32 Array", common.ValueTypeFloat32Array, "[123.456, -654.321]"}, 268 {"Simple Float64 Array", common.ValueTypeFloat64Array, "[123456789.0987654321, -987654321.123456789]"}, 269 } 270 271 for _, tt := range tests { 272 t.Run(tt.name, func(t *testing.T) { 273 err := ValidateValue(tt.valueType, tt.value) 274 require.NoError(t, err) 275 }) 276 } 277 } 278 279 func TestValidateArrayValue(t *testing.T) { 280 tests := []struct { 281 name string 282 valueType string 283 value string 284 expectError bool 285 }{ 286 {"Valid separator (comma followed by a space)", common.ValueTypeBoolArray, "[true, false]", false}, 287 {"Valid separator (comma)", common.ValueTypeBoolArray, "[true,false]", false}, 288 {"Invalid separator", common.ValueTypeBoolArray, "[true@false]", true}, 289 } 290 291 for _, tt := range tests { 292 t.Run(tt.name, func(t *testing.T) { 293 err := ValidateValue(tt.valueType, tt.value) 294 if tt.expectError { 295 require.Error(t, err) 296 } else { 297 require.NoError(t, err) 298 } 299 }) 300 } 301 } 302 303 func TestValidateValueError(t *testing.T) { 304 invalidValue := "invalid" 305 tests := []struct { 306 name string 307 valueType string 308 }{ 309 {"Invalid Simple Boolean (true)", common.ValueTypeBool}, 310 {"Invalid Simple Uint8", common.ValueTypeUint8}, 311 {"Invalid Simple Uint16", common.ValueTypeUint16}, 312 {"Invalid Simple Uint32", common.ValueTypeUint32}, 313 {"Invalid Simple uint64", common.ValueTypeUint64}, 314 {"Invalid Simple int8", common.ValueTypeInt8}, 315 {"Invalid Simple int16", common.ValueTypeInt16}, 316 {"Invalid Simple int32", common.ValueTypeInt32}, 317 {"Invalid Simple int64", common.ValueTypeInt64}, 318 {"Invalid Simple Float32", common.ValueTypeFloat32}, 319 {"Invalid Simple Float64", common.ValueTypeFloat64}, 320 {"Invalid Simple Boolean Array", common.ValueTypeBoolArray}, 321 {"Invalid Simple Uint8 Array", common.ValueTypeUint8Array}, 322 {"Invalid Simple Uint16 Array", common.ValueTypeUint16Array}, 323 {"Invalid Simple Uint32 Array", common.ValueTypeUint32Array}, 324 {"Invalid Simple Uint64 Array", common.ValueTypeUint64Array}, 325 {"Invalid Simple Int8 Array", common.ValueTypeInt8Array}, 326 {"Invalid Simple Int16 Array", common.ValueTypeInt16Array}, 327 {"Invalid Simple Int32 Array", common.ValueTypeInt32Array}, 328 {"Invalid Simple Int64 Array", common.ValueTypeInt64Array}, 329 {"Invalid Simple Float32 Array", common.ValueTypeFloat32Array}, 330 {"Invalid Simple Float64 Array", common.ValueTypeFloat64Array}, 331 } 332 for _, tt := range tests { 333 t.Run(tt.name, func(t *testing.T) { 334 err := ValidateValue(tt.valueType, invalidValue) 335 require.Error(t, err) 336 }) 337 } 338 } 339 340 func TestUnmarshalObjectValue(t *testing.T) { 341 expectedDeviceName := TestDeviceName 342 expectedProfileName := TestDeviceProfileName 343 expectedResourceName := TestDeviceResourceName 344 expectedValueType := common.ValueTypeObject 345 type testObjectType struct { 346 StringField string 347 BoolField bool 348 IntField int 349 UintField uint 350 Float32Field float32 351 Float64Field float64 352 BoolArrayField []bool 353 IntArrayField []int 354 UintArrayField []uint 355 Float32ArrayField []float32 356 Float64ArrayField []float64 357 } 358 testObject := testObjectType{ 359 StringField: "yyz", 360 BoolField: true, 361 IntField: -45, 362 UintField: 45, 363 Float32Field: float32(123.456), 364 Float64Field: 456.789, 365 BoolArrayField: []bool{true, false, true}, 366 IntArrayField: []int{-1, 1, -1}, 367 UintArrayField: []uint{1, 1, 1}, 368 Float32ArrayField: []float32{float32(111.222), float32(333.444), float32(555.666)}, 369 Float64ArrayField: []float64{111.222, 333.444, 555.666}, 370 } 371 372 actual := NewObjectReading(expectedProfileName, expectedDeviceName, expectedResourceName, testObject) 373 374 assert.NotEmpty(t, actual.Id) 375 assert.Equal(t, expectedProfileName, actual.ProfileName) 376 assert.Equal(t, expectedDeviceName, actual.DeviceName) 377 assert.Equal(t, expectedResourceName, actual.ResourceName) 378 assert.Equal(t, expectedValueType, actual.ValueType) 379 380 target := testObjectType{} 381 assert.NoError(t, actual.UnmarshalObjectValue(&target)) 382 assert.Equal(t, testObject, target) 383 assert.NotZero(t, actual.Origin) 384 } 385 386 func TestUnmarshalObjectValueError(t *testing.T) { 387 expectedDeviceName := TestDeviceName 388 expectedProfileName := TestDeviceProfileName 389 expectedResourceName := TestDeviceResourceName 390 391 tests := []struct { 392 name string 393 valueType string 394 value interface{} 395 }{ 396 {"Invalid Simple Boolean", common.ValueTypeBool, true}, 397 {"Invalid Simple Uint8", common.ValueTypeUint8, uint8(1)}, 398 {"Invalid Simple Uint16", common.ValueTypeUint16, uint16(1)}, 399 {"Invalid Simple Uint32", common.ValueTypeUint32, uint32(1)}, 400 {"Invalid Simple uint64", common.ValueTypeUint64, uint64(1)}, 401 {"Invalid Simple int8", common.ValueTypeInt8, int8(-1)}, 402 {"Invalid Simple int16", common.ValueTypeInt16, int16(-1)}, 403 {"Invalid Simple int32", common.ValueTypeInt32, int32(-1)}, 404 {"Invalid Simple int64", common.ValueTypeInt64, int64(-1)}, 405 {"Invalid Simple Float32", common.ValueTypeFloat32, float32(123.456)}, 406 {"Invalid Simple Float64", common.ValueTypeFloat64, 123.456}, 407 {"Invalid Simple Boolean Array", common.ValueTypeBoolArray, []bool{}}, 408 {"Invalid Simple Uint8 Array", common.ValueTypeUint8Array, []uint8{}}, 409 {"Invalid Simple Uint16 Array", common.ValueTypeUint16Array, []uint16{}}, 410 {"Invalid Simple Uint32 Array", common.ValueTypeUint32Array, []uint32{}}, 411 {"Invalid Simple Uint64 Array", common.ValueTypeUint64Array, []uint64{}}, 412 {"Invalid Simple Int8 Array", common.ValueTypeInt8Array, []int8{}}, 413 {"Invalid Simple Int16 Array", common.ValueTypeInt16Array, []int16{}}, 414 {"Invalid Simple Int32 Array", common.ValueTypeInt32Array, []int32{}}, 415 {"Invalid Simple Int64 Array", common.ValueTypeInt64Array, []int64{}}, 416 {"Invalid Simple Float32 Array", common.ValueTypeFloat32Array, []float32{}}, 417 {"Invalid Simple Float64 Array", common.ValueTypeFloat64Array, []float64{}}, 418 } 419 for _, tt := range tests { 420 t.Run(tt.name, func(t *testing.T) { 421 reading, err := NewSimpleReading(expectedProfileName, expectedDeviceName, expectedResourceName, tt.valueType, tt.value) 422 require.NoError(t, err) 423 target := "" 424 err = reading.UnmarshalObjectValue(&target) 425 require.Error(t, err) 426 }) 427 } 428 }