github.com/xmidt-org/webpa-common@v1.11.9/device/metadata_test.go (about) 1 package device 2 3 import ( 4 "bytes" 5 "math/rand" 6 "sync" 7 "testing" 8 9 "github.com/spf13/viper" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 // claims is a convenient base claims structurally repre to use in tests. 15 // If you need to modify it, make a copy using deepCopyMap() 16 var claims map[string]interface{} 17 18 func init() { 19 // This is an easy way to catch unmarshalling surprises for claims 20 // which come from config values. 21 rawYamlConfig := []byte(` 22 claims: 23 aud: XMiDT 24 capabilities: [xmidt, webpa] 25 custom: rbl 26 exp: 1594248706 27 iat: 1591656706 28 id: 1234 29 iss: themis 30 jti: 5LnpSTsPnuh4TA 31 nbf: 1591656691 32 partner-id: comcast 33 sub: "client:supplied" 34 trust: 100 35 `) 36 v := viper.New() 37 v.SetConfigType("yaml") 38 err := v.ReadConfig(bytes.NewBuffer(rawYamlConfig)) 39 if err != nil { 40 panic(err) 41 } 42 v.UnmarshalKey("claims", &claims) 43 } 44 45 func TestDeviceMetadataDefaultValues(t *testing.T) { 46 assert := assert.New(t) 47 m := new(Metadata) 48 49 assert.Empty(m.Claims()) 50 assert.Empty(m.SessionID()) 51 assert.Equal(UnknownPartner, m.PartnerIDClaim()) 52 assert.Zero(m.TrustClaim()) 53 assert.Nil(m.Load("not-exists")) 54 } 55 56 func TestDeviceMetadataInitClaims(t *testing.T) { 57 assert := assert.New(t) 58 inputClaims := deepCopyMap(claims) 59 m := new(Metadata) 60 m.SetClaims(inputClaims) 61 62 assert.Equal(inputClaims, m.Claims()) 63 assert.Equal("comcast", m.PartnerIDClaim()) 64 assert.Equal(100, m.TrustClaim()) 65 66 // test defensive copy 67 inputClaims[TrustClaimKey] = 200 68 assert.NotEqual(inputClaims, m.Claims()) 69 } 70 func TestDeviceMetadataSessionID(t *testing.T) { 71 assert := assert.New(t) 72 m := new(Metadata) 73 74 assert.Empty(m.SessionID()) 75 m.SetSessionID("uuid:123abc") 76 m.SetSessionID("oopsiesCalledAgain") 77 assert.Equal("uuid:123abc", m.SessionID()) 78 } 79 80 func TestDeviceMetadataReadUpdateClaims(t *testing.T) { 81 assert := assert.New(t) 82 m := new(Metadata) 83 m.SetClaims(claims) 84 85 assert.Equal(claims, m.Claims()) 86 assert.Equal("comcast", m.PartnerIDClaim()) 87 assert.Equal(100, m.TrustClaim()) 88 89 myClaimsCopy := m.ClaimsCopy() 90 myClaimsCopy[TrustClaimKey] = 200 91 m.SetClaims(myClaimsCopy) 92 assert.Equal(myClaimsCopy, m.Claims()) 93 } 94 95 func TestDeviceMetadataUpdateCustomReferenceValue(t *testing.T) { 96 assert := assert.New(t) 97 require := require.New(t) 98 m := new(Metadata) 99 accountInfo := map[string]interface{}{ 100 "user-id": 4500, 101 "user-name": "Talaria XMiDT", 102 } 103 require.True(m.Store("account-info", accountInfo)) 104 105 oldAccountInfo := m.Load("account-info").(map[string]interface{}) 106 newAccountInfo := deepCopyMap(oldAccountInfo) 107 newAccountInfo["user-id"] = 4501 108 require.True(m.Store("account-info", newAccountInfo)) 109 latestAccountInfo := m.Load("account-info").(map[string]interface{}) 110 assert.Equal(newAccountInfo, latestAccountInfo) 111 assert.NotEqual(oldAccountInfo, latestAccountInfo) 112 } 113 114 func TestDeviceMetadataReservedKeys(t *testing.T) { 115 assert := assert.New(t) 116 m := new(Metadata) 117 for reservedKey := range reservedMetadataKeys { 118 before := m.Load(reservedKey) 119 assert.False(m.Store(reservedKey, "poison")) 120 after := m.Load(reservedKey) 121 assert.Equal(before, after) 122 } 123 } 124 125 func BenchmarkMetadataClaimsCopyParallel(b *testing.B) { 126 assert := assert.New(b) 127 m := new(Metadata) 128 m.SetClaims(claims) 129 b.RunParallel(func(pb *testing.PB) { 130 for pb.Next() { 131 assert.Equal(claims, m.ClaimsCopy()) 132 } 133 }) 134 } 135 func BenchmarkMetadataClaimsUsageParallel(b *testing.B) { 136 b.Run("99PercentReads", benchmarkMetadataClaimsUsageParallel99PercentRead) 137 b.Run("80PercentReads", benchmarkMetadataClaimsUsageParallel80PercentRead) 138 b.Run("70PercentReads", benchmarkMetadataClaimsUsageParallel70PercentRead) 139 } 140 141 func benchmarkMetadataClaimsUsageParallel99PercentRead(b *testing.B) { 142 benchmarkMetadataClaimsUsageParallel(99, b) 143 } 144 145 func benchmarkMetadataClaimsUsageParallel80PercentRead(b *testing.B) { 146 benchmarkMetadataClaimsUsageParallel(80, b) 147 } 148 149 func benchmarkMetadataClaimsUsageParallel70PercentRead(b *testing.B) { 150 benchmarkMetadataClaimsUsageParallel(70, b) 151 } 152 153 func benchmarkMetadataClaimsUsageParallel(readPercentage int, b *testing.B) { 154 var mux sync.Mutex 155 assert := assert.New(b) 156 m := new(Metadata) 157 m.SetClaims(claims) 158 159 b.RunParallel(func(pb *testing.PB) { 160 for pb.Next() { 161 v := rand.Intn(100) 162 if v < readPercentage { 163 m.Claims() 164 m.TrustClaim() 165 } else { 166 mux.Lock() 167 myClaimsCopy := m.ClaimsCopy() 168 myTrustLevel := myClaimsCopy[TrustClaimKey].(int) + 1 169 myClaimsCopy[TrustClaimKey] = myTrustLevel 170 m.SetClaims(myClaimsCopy) 171 assert.Equal(myTrustLevel, m.TrustClaim()) 172 mux.Unlock() 173 } 174 } 175 }) 176 } 177 178 func TestDeepCopyMap(t *testing.T) { 179 testCases := []struct { 180 Name string 181 Input map[string]interface{} 182 Expected map[string]interface{} 183 }{ 184 { 185 Name: "Nil", 186 Expected: make(map[string]interface{}), 187 }, 188 { 189 Name: "Empty", 190 Input: make(map[string]interface{}), 191 Expected: make(map[string]interface{}), 192 }, 193 { 194 Name: "Simple", 195 Input: map[string]interface{}{"k0": 0, "k1": 1}, 196 Expected: map[string]interface{}{"k0": 0, "k1": 1}, 197 }, 198 { 199 Name: "Complex", 200 Input: map[string]interface{}{ 201 "nested": map[string]interface{}{ 202 "nestedKey": "nestedVal", 203 }, 204 "nestedToCast": map[interface{}]interface{}{ 205 3: "nestedVal3", 206 }, 207 }, 208 Expected: map[string]interface{}{ 209 "nested": map[string]interface{}{ 210 "nestedKey": "nestedVal", 211 }, 212 "nestedToCast": map[string]interface{}{ 213 "3": "nestedVal3", 214 }, 215 }, 216 }, 217 } 218 219 for _, testCase := range testCases { 220 t.Run(testCase.Name, func(t *testing.T) { 221 assert := assert.New(t) 222 cpy := deepCopyMap(testCase.Input) 223 assert.Equal(cpy, testCase.Expected) 224 }) 225 } 226 }