av/protocol/rtcp/client_test.go

231 lines
5.2 KiB
Go

/*
NAME
client_test.go
DESCRIPTION
client_test.go contains testing utilities for functionality provided in client.go.
AUTHORS
Saxon A. Nelson-Milton <saxon@ausocean.org>
LICENSE
This is Copyright (C) 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
in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package rtcp
import (
"bytes"
"encoding/binary"
"fmt"
"math"
"net"
"strings"
"testing"
"time"
"bitbucket.org/ausocean/utils/logger"
)
// TestFromPayload checks that formPayload is working as expected.
func TestFormPayload(t *testing.T) {
// Expected data from a valid RTCP packet.
expect := []byte{
0x81, 0xc9, 0x00, 0x07,
0xd6, 0xe0, 0x98, 0xda,
0x6f, 0xad, 0x40, 0xc6,
0x00, 0xff, 0xff, 0xff,
0x00, 0x01, 0x83, 0x08,
0x00, 0x00, 0x00, 0x20,
0xb9, 0xe1, 0x25, 0x2a,
0x00, 0x00, 0x2b, 0xf9,
0x81, 0xca, 0x00, 0x04,
0xd6, 0xe0, 0x98, 0xda,
0x01, 0x08, 0x73, 0x61,
0x78, 0x6f, 0x6e, 0x2d,
0x70, 0x63, 0x00, 0x00,
}
report := ReceiverReport{
Header: Header{
Version: 2,
Padding: false,
ReportCount: 1,
Type: typeReceiverReport,
},
SenderSSRC: 3605043418,
Blocks: []ReportBlock{
ReportBlock{
SSRC: 1873625286,
FractionLost: 0,
PacketsLost: math.MaxUint32,
HighestSequence: 99080,
Jitter: 32,
LSR: 3118540074,
DLSR: 11257,
},
},
Extensions: nil,
}
description := SourceDescription{
Header: Header{
Version: 2,
Padding: false,
ReportCount: 1,
Type: typeSourceDescription,
},
Chunks: []Chunk{
Chunk{
SSRC: 3605043418,
Items: []SDESItem{
SDESItem{
Type: typeCName,
Text: []byte("saxon-pc"),
},
},
},
},
}
c := &client{}
p := c.formPayload(&report, &description)
if !bytes.Equal(p, expect) {
t.Fatalf("unexpected result.\nGot: %v\n Want: %v\n", p, expect)
}
bufAddr := fmt.Sprintf("%p", c.buf[:])
pAddr := fmt.Sprintf("%p", p)
if bufAddr != pAddr {
t.Errorf("unexpected result.\nGot: %v\n want: %v\n", pAddr, bufAddr)
}
}
// dummyLogger will allow logging to be done by the testing pkg.
type dummyLogger testing.T
func (dl *dummyLogger) log(lvl int8, msg string, args ...interface{}) {
var l string
switch lvl {
case logger.Warning:
l = "warning"
case logger.Debug:
l = "debug"
case logger.Info:
l = "info"
case logger.Error:
l = "error"
case logger.Fatal:
l = "fatal"
}
msg = l + ": " + msg
for i := 0; i < len(args); i++ {
msg += " %v"
}
if len(args) == 0 {
dl.Log(msg + "\n")
return
}
dl.Logf(msg+"\n", args)
}
// TestReceiveAndSend tests basic RTCP client behaviour with a basic RTCP server.
// The RTCP client will send through receiver reports, and the RTCP server will
// respond with sender reports.
func TestReceiveAndSend(t *testing.T) {
const clientAddr, serverAddr = "localhost:8000", "localhost:8001"
c, err := NewClient(
clientAddr,
serverAddr,
"testClient",
10*time.Millisecond,
12345,
(*dummyLogger)(t).log,
)
if err != nil {
t.Fatalf("unexpected error when creating client: %v\n", err)
}
go func() {
for {
select {
case err := <-c.ErrChan:
const errConnClosed = "use of closed network connection"
if !strings.Contains(err.Error(), errConnClosed) {
t.Fatalf("error received from client error chan: %v\n", err)
}
default:
}
}
}()
c.Start()
sAddr, err := net.ResolveUDPAddr("udp", serverAddr)
if err != nil {
t.Fatalf("could not resolve test server address, failed with error: %v", err)
}
cAddr, err := net.ResolveUDPAddr("udp", clientAddr)
if err != nil {
t.Fatalf("could not resolve client address, failed with error: %v", err)
}
conn, err := net.DialUDP("udp", sAddr, cAddr)
if err != nil {
t.Fatalf("could not dial, failed with error: %v\n", err)
}
buf := make([]byte, 4096)
for i := 0; i < 5; i++ {
t.Log("SERVER: waiting for receiver report\n")
n, _, _ := conn.ReadFromUDP(buf)
t.Logf("SERVER: receiver report received: \n%v\n", buf[:n])
c.UpdateSequence(uint32(i))
now := time.Now().Second()
var time [8]byte
binary.BigEndian.PutUint64(time[:], uint64(now))
msw := binary.BigEndian.Uint32(time[:4])
lsw := binary.BigEndian.Uint32(time[4:])
report := SenderReport{
Header: Header{
Version: rtcpVer,
Padding: false,
ReportCount: 0,
Type: typeSenderReport,
},
SSRC: 1234567,
TimestampMSW: msw,
TimestampLSW: lsw,
RTPTimestamp: 0,
PacketCount: 0,
OctetCount: 0,
}
r := report.Bytes()
t.Logf("SERVER: sending sender report: \n%v\n", r)
_, err := conn.Write(r)
if err != nil {
t.Errorf("did not expect error: %v\n", err)
}
}
c.Stop()
}