blob: 86c7224f13dde295cfe088f560e8365b989bdd4d [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ble
import (
"encoding/hex"
"math/rand"
"reflect"
"testing"
"v.io/v23/discovery"
idiscovery "v.io/x/ref/lib/discovery"
)
func TestEncode(t *testing.T) {
rand := rand.New(rand.NewSource(0))
randBytes := func(n int) []byte {
p := make([]byte, rand.Intn(n))
rand.Read(p)
return p
}
randString := func(n int) string {
return string(randBytes(n))
}
for i := 0; i < 10; i++ {
encodedAdinfos := make(map[discovery.AdId][]byte)
expectedAdinfos := make(map[discovery.AdId]idiscovery.AdInfo)
for j, n := 0, rand.Intn(maxNumPackedServices); j < n; j++ {
adinfo := idiscovery.AdInfo{}
// Populate adinfo manually to test large payloads. testing.quick.Value()
// fills only with small values.
copy(adinfo.Ad.Id[:], randBytes(32))
adinfo.Ad.InterfaceName = randString(128)
adinfo.Ad.Addresses = make([]string, rand.Intn(3)+1)
for i, _ := range adinfo.Ad.Addresses {
adinfo.Ad.Addresses[i] = randString(128)
}
if n := rand.Intn(5); n > 0 {
adinfo.Ad.Attributes = make(discovery.Attributes, n)
for i := 0; i < n; i++ {
adinfo.Ad.Attributes[randString(16)] = randString(256)
}
}
if n := rand.Intn(5); n > 0 {
adinfo.Ad.Attachments = make(discovery.Attachments, n)
for i := 0; i < n; i++ {
adinfo.Ad.Attachments[randString(16)] = randBytes(256)
}
}
adinfo.EncryptionAlgorithm = idiscovery.EncryptionAlgorithm(rand.Intn(3))
if adinfo.EncryptionAlgorithm != idiscovery.NoEncryption {
adinfo.EncryptionKeys = make([]idiscovery.EncryptionKey, rand.Intn(3)+1)
for i, _ := range adinfo.EncryptionKeys {
adinfo.EncryptionKeys[i] = randBytes(128)
}
}
copy(adinfo.Hash[:], randBytes(16))
adinfo.TimestampNs = rand.Int63()
adinfo.DirAddrs = make([]string, rand.Intn(3)+1)
for i, _ := range adinfo.DirAddrs {
adinfo.DirAddrs[i] = randString(128)
}
encoded, err := encodeAdInfo(&adinfo)
if err != nil {
t.Errorf("encode failed: %v", err)
continue
}
encodedAdinfos[adinfo.Ad.Id] = encoded
if len(adinfo.Ad.Attachments) > 0 {
adinfo.Status = idiscovery.AdPartiallyReady
} else {
adinfo.DirAddrs = nil
adinfo.Status = idiscovery.AdReady
}
adinfo.Ad.Attachments = nil
expectedAdinfos[adinfo.Ad.Id] = adinfo
}
cs := packToCharacteristics(encodedAdinfos)
unpacked, err := unpackFromCharacteristics(cs)
if err != nil {
t.Errorf("unpack failed: %v", err)
continue
}
for _, encoded := range unpacked {
adinfo, err := decodeAdInfo(encoded)
if err != nil {
t.Errorf("decode failed: %v", err)
continue
}
if !reflect.DeepEqual(*adinfo, expectedAdinfos[adinfo.Ad.Id]) {
t.Errorf("decoded to %#v, but want %#v", *adinfo, expectedAdinfos[adinfo.Ad.Id])
}
}
}
}
func TestDecodeInvalid(t *testing.T) {
tests := []map[string]string{
{"1234": "00"}, // Invalid uuid.
{"31ca10d5-0195-54fa-9344-25fcd7072f00": "00"}, // Invalid characteristic uuid.
{"31ca10d5-0195-54fa-9344-25fcd7072e10": "00"}, // Invalid characteristic uuid sequence.
{ // Invalid characteristic split.
"31ca10d5-0195-54fa-9344-25fcd7072e00": "08eff4d54d979febed94a1b551b0316733762e696f2f782f7265662f73657276696365732f73796e63626173652f7365727665722f696e74657266616365732f53796e63fd01d4ce4d4ec33010c57171205c3b76c633b3321b2e8158f8b30db471459cf4442c90e00270390a4854e204416ff7167ffd5eaf360e5c68ee46322906622296926fe5069c030c9474510a7456bdf15afa10256934600329e92697f222163154ae0c12c92894d8f5706df4d2ca98729b2c3d967ee7230e797e6815515b0029fcf138896daddb7d9ea7fc14ebd8f2d844ac074efe348ac58f3e0df3c16d0f7ed87ffdcebd7c6b4fd3cea9ce0a799e627deee1faa86f172a7542010a044176addce75fee1db3ba5f2bf3e3c22c1925b3c13eb189a570c9bab0eda85b2dfefd2f1e2044feb11bc3d123fc1f7bc8bde5dc81e292348309b85afb67000000ffff01050164026462026462536465762e762e696f3a6f3a3630383934313830383235362d34337674666e6465747337396b6635686163386965756a746f383833373636302e617070732e676f6f676c6575736572636f6e74656e742e636f6d01730c73675f3535313632333837380273626b6465762e762e696f3a6f3a3630383934313830383235362d34337674666e6465747337396b6635686163386965756a746f383833373636302e617070732e676f6f676c6575736572636f6e74",
"31ca10d5-0195-54fa-9344-25fcd7072e01": "656e742e636f6d3a6461776e2e76616e616469756d40676d61696c2e636f6d0376697390016465762e762e696f3a6f3a3630383934313830383235362d34337674666e6465747337396b6635686163386965756a746f383833373636302e617070732e676f6f676c6575736572636f6e74656e742e636f6d3a6461776e2e76616e616469756d40676d61696c2e636f6d2c6465762e762e696f3a753a616c657866616e647269616e746f40676f6f676c652e636f6d005cb840d035a10ceaa1e9b7f238c057140000",
},
{ // Invalid characteristic value.
"31ca10d5-0195-54fa-9344-25fcd7072e00": "7337396b6635686163386965756a746f383833373636302e617070732e676f6f676c6575736572636f6e74656e742e636f6d3a6461776e2e76616e616469756d40676d61696c2e636f6d0164026462026462536465762e762e696f3a6f3a3630383934313830383235362d34337674666e6465747337396b6635686163386965756a746f383833373636302e617070732e676f6f676c6575736572636f6e74656e742e636f6d01732c6c6973745f6c697374735f4a4d786659727655694d364f596d4f706b356b797350425048324e366b77536f480013c6163e316e5359a9d3ca49fbbc57140000",
},
}
for i, test := range tests {
cs := make(map[string][]byte)
for k, v := range test {
c, err := hex.DecodeString(v)
if err != nil {
t.Fatal(err)
}
cs[k] = c
}
if unpacked, err := unpackFromCharacteristics(cs); err == nil {
for _, encoded := range unpacked {
_, err := decodeAdInfo(encoded)
if err == nil {
t.Errorf("[%d]: expect an error; but got none", i)
}
}
}
}
}