github.com/pion/webrtc/v4@v4.0.1/pkg/media/rtpdump/reader_test.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  package rtpdump
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"io"
    10  	"net"
    11  	"reflect"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  func TestReader(t *testing.T) {
    17  	validPreamble := []byte("#!rtpplay1.0 224.2.0.1/3456\n")
    18  
    19  	for _, test := range []struct {
    20  		Name        string
    21  		Data        []byte
    22  		WantHeader  Header
    23  		WantPackets []Packet
    24  		WantErr     error
    25  	}{
    26  		{
    27  			Name:    "empty",
    28  			Data:    nil,
    29  			WantErr: errMalformed,
    30  		},
    31  		{
    32  			Name: "hashbang missing ip/port",
    33  			Data: append(
    34  				[]byte("#!rtpplay1.0 \n"),
    35  				0x00, 0x00, 0x00, 0x00,
    36  				0x00, 0x00, 0x00, 0x00,
    37  				0x00, 0x00, 0x00, 0x00,
    38  				0x00, 0x00, 0x00, 0x00,
    39  			),
    40  			WantErr: errMalformed,
    41  		},
    42  		{
    43  			Name: "hashbang missing port",
    44  			Data: append(
    45  				[]byte("#!rtpplay1.0 0.0.0.0\n"),
    46  				0x00, 0x00, 0x00, 0x00,
    47  				0x00, 0x00, 0x00, 0x00,
    48  				0x00, 0x00, 0x00, 0x00,
    49  				0x00, 0x00, 0x00, 0x00,
    50  			),
    51  			WantErr: errMalformed,
    52  		},
    53  		{
    54  			Name: "valid empty file",
    55  			Data: append(
    56  				validPreamble,
    57  				0x00, 0x00, 0x00, 0x01,
    58  				0x00, 0x00, 0x00, 0x00,
    59  				0x01, 0x01, 0x01, 0x01,
    60  				0x22, 0xB8, 0x00, 0x00,
    61  			),
    62  			WantHeader: Header{
    63  				Start:  time.Unix(1, 0).UTC(),
    64  				Source: net.IPv4(1, 1, 1, 1),
    65  				Port:   8888,
    66  			},
    67  		},
    68  		{
    69  			Name: "malformed packet header",
    70  			Data: append(
    71  				validPreamble,
    72  				// header
    73  				0x00, 0x00, 0x00, 0x00,
    74  				0x00, 0x00, 0x00, 0x00,
    75  				0x00, 0x00, 0x00, 0x00,
    76  				0x00, 0x00, 0x00, 0x00,
    77  				// packet header
    78  				0x00,
    79  			),
    80  			WantHeader: Header{
    81  				Start:  time.Unix(0, 0).UTC(),
    82  				Source: net.IPv4(0, 0, 0, 0),
    83  				Port:   0,
    84  			},
    85  			WantErr: errMalformed,
    86  		},
    87  		{
    88  			Name: "short packet payload",
    89  			Data: append(
    90  				validPreamble,
    91  				// header
    92  				0x00, 0x00, 0x00, 0x00,
    93  				0x00, 0x00, 0x00, 0x00,
    94  				0x00, 0x00, 0x00, 0x00,
    95  				0x00, 0x00, 0x00, 0x00,
    96  				// packet header len=1048575
    97  				0xFF, 0xFF, 0x00, 0x00,
    98  				0x00, 0x00, 0x00, 0x00,
    99  				// packet payload
   100  				0x00,
   101  			),
   102  			WantHeader: Header{
   103  				Start:  time.Unix(0, 0).UTC(),
   104  				Source: net.IPv4(0, 0, 0, 0),
   105  				Port:   0,
   106  			},
   107  			WantErr: errMalformed,
   108  		},
   109  		{
   110  			Name: "empty packet payload",
   111  			Data: append(
   112  				validPreamble,
   113  				// header
   114  				0x00, 0x00, 0x00, 0x00,
   115  				0x00, 0x00, 0x00, 0x00,
   116  				0x00, 0x00, 0x00, 0x00,
   117  				0x00, 0x00, 0x00, 0x00,
   118  				// packet header len=0
   119  				0x00, 0x00, 0x00, 0x00,
   120  				0x00, 0x00, 0x00, 0x00,
   121  			),
   122  			WantHeader: Header{
   123  				Start:  time.Unix(0, 0).UTC(),
   124  				Source: net.IPv4(0, 0, 0, 0),
   125  				Port:   0,
   126  			},
   127  			WantErr: errMalformed,
   128  		},
   129  		{
   130  			Name: "valid rtcp packet",
   131  			Data: append(
   132  				validPreamble,
   133  				// header
   134  				0x00, 0x00, 0x00, 0x00,
   135  				0x00, 0x00, 0x00, 0x00,
   136  				0x00, 0x00, 0x00, 0x00,
   137  				0x00, 0x00, 0x00, 0x00,
   138  				// packet header len=20, pLen=0, off=1
   139  				0x00, 0x14, 0x00, 0x00,
   140  				0x00, 0x00, 0x00, 0x01,
   141  				// packet payload (BYE)
   142  				0x81, 0xcb, 0x00, 0x0c,
   143  				0x90, 0x2f, 0x9e, 0x2e,
   144  				0x03, 0x46, 0x4f, 0x4f,
   145  			),
   146  			WantHeader: Header{
   147  				Start:  time.Unix(0, 0).UTC(),
   148  				Source: net.IPv4(0, 0, 0, 0),
   149  				Port:   0,
   150  			},
   151  			WantPackets: []Packet{
   152  				{
   153  					Offset: time.Millisecond,
   154  					IsRTCP: true,
   155  					Payload: []byte{
   156  						0x81, 0xcb, 0x00, 0x0c,
   157  						0x90, 0x2f, 0x9e, 0x2e,
   158  						0x03, 0x46, 0x4f, 0x4f,
   159  					},
   160  				},
   161  			},
   162  			WantErr: nil,
   163  		},
   164  		{
   165  			Name: "truncated rtcp packet",
   166  			Data: append(
   167  				validPreamble,
   168  				// header
   169  				0x00, 0x00, 0x00, 0x00,
   170  				0x00, 0x00, 0x00, 0x00,
   171  				0x00, 0x00, 0x00, 0x00,
   172  				0x00, 0x00, 0x00, 0x00,
   173  				// packet header len=9, pLen=0, off=1
   174  				0x00, 0x09, 0x00, 0x00,
   175  				0x00, 0x00, 0x00, 0x01,
   176  				// invalid payload
   177  				0x81,
   178  			),
   179  			WantHeader: Header{
   180  				Start:  time.Unix(0, 0).UTC(),
   181  				Source: net.IPv4(0, 0, 0, 0),
   182  				Port:   0,
   183  			},
   184  			WantPackets: []Packet{
   185  				{
   186  					Offset:  time.Millisecond,
   187  					IsRTCP:  true,
   188  					Payload: []byte{0x81},
   189  				},
   190  			},
   191  		},
   192  		{
   193  			Name: "two valid packets",
   194  			Data: append(
   195  				validPreamble,
   196  				// header
   197  				0x00, 0x00, 0x00, 0x00,
   198  				0x00, 0x00, 0x00, 0x00,
   199  				0x00, 0x00, 0x00, 0x00,
   200  				0x00, 0x00, 0x00, 0x00,
   201  				// packet header len=20, pLen=0, off=1
   202  				0x00, 0x14, 0x00, 0x00,
   203  				0x00, 0x00, 0x00, 0x01,
   204  				// packet payload (BYE)
   205  				0x81, 0xcb, 0x00, 0x0c,
   206  				0x90, 0x2f, 0x9e, 0x2e,
   207  				0x03, 0x46, 0x4f, 0x4f,
   208  				// packet header len=33, pLen=0, off=2
   209  				0x00, 0x21, 0x00, 0x19,
   210  				0x00, 0x00, 0x00, 0x02,
   211  				// packet payload (RTP)
   212  				0x90, 0x60, 0x69, 0x8f,
   213  				0xd9, 0xc2, 0x93, 0xda,
   214  				0x1c, 0x64, 0x27, 0x82,
   215  				0x00, 0x01, 0x00, 0x01,
   216  				0xFF, 0xFF, 0xFF, 0xFF,
   217  				0x98, 0x36, 0xbe, 0x88,
   218  				0x9e,
   219  			),
   220  			WantHeader: Header{
   221  				Start:  time.Unix(0, 0).UTC(),
   222  				Source: net.IPv4(0, 0, 0, 0),
   223  				Port:   0,
   224  			},
   225  			WantPackets: []Packet{
   226  				{
   227  					Offset: time.Millisecond,
   228  					IsRTCP: true,
   229  					Payload: []byte{
   230  						0x81, 0xcb, 0x00, 0x0c,
   231  						0x90, 0x2f, 0x9e, 0x2e,
   232  						0x03, 0x46, 0x4f, 0x4f,
   233  					},
   234  				},
   235  				{
   236  					Offset: 2 * time.Millisecond,
   237  					IsRTCP: false,
   238  					Payload: []byte{
   239  						0x90, 0x60, 0x69, 0x8f,
   240  						0xd9, 0xc2, 0x93, 0xda,
   241  						0x1c, 0x64, 0x27, 0x82,
   242  						0x00, 0x01, 0x00, 0x01,
   243  						0xFF, 0xFF, 0xFF, 0xFF,
   244  						0x98, 0x36, 0xbe, 0x88,
   245  						0x9e,
   246  					},
   247  				},
   248  			},
   249  			WantErr: nil,
   250  		},
   251  	} {
   252  		r, hdr, err := NewReader(bytes.NewReader(test.Data))
   253  		if err != nil {
   254  			if got, want := err, test.WantErr; !errors.Is(got, want) {
   255  				t.Fatalf("NewReader(%s) err=%v want %v", test.Name, got, want)
   256  			}
   257  			continue
   258  		}
   259  
   260  		if got, want := hdr, test.WantHeader; !reflect.DeepEqual(got, want) {
   261  			t.Fatalf("%q Header = %#v, want %#v", test.Name, got, want)
   262  		}
   263  
   264  		var nextErr error
   265  		var packets []Packet
   266  		for {
   267  			pkt, err := r.Next()
   268  			if errors.Is(err, io.EOF) {
   269  				break
   270  			}
   271  			if err != nil {
   272  				nextErr = err
   273  				break
   274  			}
   275  
   276  			packets = append(packets, pkt)
   277  		}
   278  
   279  		if got, want := nextErr, test.WantErr; !errors.Is(got, want) {
   280  			t.Fatalf("%s err=%v want %v", test.Name, got, want)
   281  		}
   282  		if got, want := packets, test.WantPackets; !reflect.DeepEqual(got, want) {
   283  			t.Fatalf("%q packets=%#v, want %#v", test.Name, got, want)
   284  		}
   285  	}
   286  }