av/rtmp/amf/amf_test.go

264 lines
6.4 KiB
Go
Raw Normal View History

2019-01-12 01:27:53 +03:00
/*
NAME
amf_test.go
DESCRIPTION
2019-01-12 06:16:21 +03:00
AMF test suite.
2019-01-12 01:27:53 +03:00
AUTHORS
Saxon Nelson-Milton <saxon@ausocean.org>
Dan Kortschak <dan@ausocean.org>
Alan Noble <alan@ausocean.org>
LICENSE
amf_test.go is Copyright (C) 2017-2019 the Australian Ocean Lab (AusOcean)
It is free software: you can redistribute it and/or modify them
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package amf
import (
"testing"
)
2019-01-12 06:16:21 +03:00
// Test data.
var testStrings = [...]string{
"",
"foo",
"bar",
"bazz",
}
var testNumbers = [...]int32{
0,
1,
0xababab,
0xffffff,
}
// TestSanity checks that we haven't accidentally changed constants.
func TestSanity(t *testing.T) {
if TypeObjectEnd != 0x09 {
t.Errorf("TypeObjectEnd has wrong value; got %d, expected %d", TypeObjectEnd, 0x09)
2019-01-12 01:27:53 +03:00
}
2019-01-12 06:16:21 +03:00
}
2019-01-12 01:27:53 +03:00
2019-01-12 06:16:21 +03:00
// TestStrings tests string encoding and decoding.
func TestStrings(t *testing.T) {
2019-01-12 01:27:53 +03:00
for _, s := range testStrings {
2019-01-12 06:16:21 +03:00
// Short string encoding is as follows:
2019-01-12 01:27:53 +03:00
// enc[0] = data type (typeString)
// end[1:3] = size
// enc[3:] = data
buf := make([]byte, len(s)+5)
_, err := EncodeString(buf, s)
if err != nil {
2019-01-12 01:27:53 +03:00
t.Errorf("EncodeString failed")
}
if buf[0] != typeString {
t.Errorf("Expected typeString, got %v", buf[0])
}
ds := DecodeString(buf[1:])
if s != ds {
t.Errorf("DecodeString did not produce original string, got %v", ds)
}
}
}
// TestNumbers tests 24-bit encoding and encoding.
// We don't test the others as they are just wrappers for standard functions in encoding/binary.
func TestNumbers(t *testing.T) {
for _, n := range testNumbers {
buf := make([]byte, 4) // NB: encoder requires an extra byte for some reason
_, err := EncodeInt24(buf, n)
if err != nil {
2019-01-12 01:27:53 +03:00
t.Errorf("EncodeInt24 failed")
}
dn := int32(DecodeInt24(buf))
if n != dn {
t.Errorf("DecodeInt24 did not produce original Number, got %v", dn)
2019-01-12 01:27:53 +03:00
}
}
}
2019-01-12 06:16:21 +03:00
// TestProperties tests encoding and decoding of properties.
func TestProperties(t *testing.T) {
var buf [1024]byte
// Encode/decode Number properties.
2019-01-12 06:16:21 +03:00
enc := buf[:]
var err error
2019-01-12 06:16:21 +03:00
for i, _ := range testNumbers {
enc, err = PropEncode(&Property{Type: typeNumber, Number: float64(testNumbers[i])}, enc)
if err != nil {
t.Errorf("PropEncode of Number failed")
2019-01-12 06:16:21 +03:00
}
}
2019-01-12 06:16:21 +03:00
prop := Property{}
dec := buf[:]
for i, _ := range testNumbers {
n, err := PropDecode(&prop, dec, false)
if err != nil {
t.Errorf("PropDecode of Number failed")
2019-01-12 06:16:21 +03:00
}
if int32(prop.Number) != testNumbers[i] {
t.Errorf("PropEncode/PropDecode returned wrong Number; got %v, expected %v", int32(prop.Number), testNumbers[i])
2019-01-12 06:16:21 +03:00
}
dec = dec[n:]
}
// Encode/decode string properties.
enc = buf[:]
for i, _ := range testStrings {
enc, err = PropEncode(&Property{Type: typeString, String: testStrings[i]}, enc)
if err != nil {
2019-01-12 06:16:21 +03:00
t.Errorf("PropEncode of string failed")
}
}
prop = Property{}
dec = buf[:]
for i, _ := range testStrings {
n, err := PropDecode(&prop, dec, false)
if err != nil {
2019-01-12 06:16:21 +03:00
t.Errorf("PropDecode of string failed")
}
if prop.String != testStrings[i] {
t.Errorf("PropEncode/PropDecode returned wrong string; got %s, expected %s", prop.String, testStrings[i])
2019-01-12 06:16:21 +03:00
}
dec = dec[n:]
}
}
// TestObject tests encoding and decoding of objects.
func TestObject(t *testing.T) {
var buf [1024]byte
// Construct a simple object that has one property, the Number 42.
prop1 := Property{Type: typeNumber, Number: 42}
2019-01-12 06:16:21 +03:00
obj1 := Object{}
obj1.Props = append(obj1.Props, prop1)
// Encode it
enc := buf[:]
var err error
enc, err = Encode(&obj1, enc)
if err != nil {
2019-01-12 06:16:21 +03:00
t.Errorf("Encode of object failed")
}
// Check the encoding
if uint8(buf[0]) != TypeObject {
t.Errorf("Encoded wrong type; expected %d, got %v", TypeObject, uint8(buf[0]))
}
if uint8(buf[1]) != typeNumber {
t.Errorf("Encoded wrong type; expected %d, got %v", typeNumber, uint8(buf[0]))
}
num := DecodeNumber(buf[2:10])
if num != 42 {
t.Errorf("Encoded wrong Number")
2019-01-12 06:16:21 +03:00
}
end := int32(DecodeInt24(buf[10:13]))
if end != TypeObjectEnd {
t.Errorf("Did not encode TypeObjectEnd")
}
// Decode it
dec := buf[1:]
var dobj1 Object
_, err = Decode(&dobj1, dec, false)
if err != nil {
2019-01-12 06:16:21 +03:00
t.Errorf("Decode of object failed")
}
// Change the object's property to a boolean.
obj1.Props[0].Type = typeBoolean
obj1.Props[0].Number = 1
// Re-encode it
enc = buf[:]
enc, err = Encode(&obj1, enc)
if err != nil {
t.Errorf("Encode of object failed")
}
// Re-decode it.
dec = buf[1:]
_, err = Decode(&dobj1, dec, false)
if err != nil {
t.Errorf("Decode of object failed with error: %v", err)
}
if dobj1.Props[0].Number != 1 {
t.Errorf("Decoded wrong boolean value")
}
2019-01-12 06:16:21 +03:00
// Construct a more complicated object.
var obj2 Object
for i, _ := range testStrings {
obj2.Props = append(obj2.Props, Property{Type: typeString, String: testStrings[i]})
obj2.Props = append(obj2.Props, Property{Type: typeNumber, Number: float64(testNumbers[i])})
2019-01-12 06:16:21 +03:00
}
obj2.Props = append(obj2.Props, Property{Type: typeBoolean, Number: 0})
obj2.Props = append(obj2.Props, Property{Type: typeBoolean, Number: 1})
2019-01-12 06:16:21 +03:00
// Encode it.
enc = buf[:]
enc, err = Encode(&obj2, enc)
if err != nil {
2019-01-12 06:16:21 +03:00
t.Errorf("Encode of object failed")
}
// Decode it.
dec = buf[1:]
var dobj2 Object
_, err = Decode(&dobj2, dec, false)
if err != nil {
t.Errorf("Decode of object failed with error: %v", err)
2019-01-12 06:16:21 +03:00
}
// Find some properties that exist.
prop, err := obj2.GetProp("", 2)
if err != nil {
t.Errorf("GetProp(2) failed")
}
if prop.String != "foo" {
t.Errorf("GetProp(2) returned wrong Property")
}
prop, err = obj2.GetProp("", 3)
if err != nil {
t.Errorf("GetProp(1) failed")
}
if prop.Number != 1 {
t.Errorf("GetProp(1) returned wrong Property")
}
prop, err = obj2.GetProp("", 9)
if err != nil {
t.Errorf("GetProp(9) failed")
return
}
if prop.Type != typeBoolean && prop.Number != 1 {
t.Errorf("GetProp(9) returned wrong Property")
}
// Try to find one that doesn't exist.
prop, err = obj2.GetProp("", 10)
if err != ErrPropertyNotFound {
t.Errorf("GetProp(10) failed")
}
2019-01-12 06:16:21 +03:00
}