streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

parse_test.go (3111B)


      1 package cmcd
      2 
      3 import (
      4 	"bufio"
      5 	"fmt"
      6 	"net/http"
      7 	"net/url"
      8 	"os"
      9 	"path"
     10 	"reflect"
     11 	"sort"
     12 	"strings"
     13 	"testing"
     14 	"time"
     15 )
     16 
     17 var tests = map[string]Info{
     18 	"testdata/simple": {
     19 		Session: Session{ID: "6e2fb550-c457-11e9-bb97-0800200c9a66", PlayRate: RealTime},
     20 	},
     21 	"testdata/all_four": {
     22 		Request: Request{Throughput: 25400},
     23 		Object: Object{
     24 			Bitrate:    3200,
     25 			Duration:   4004 * time.Millisecond,
     26 			Type:       ObjTypeVideo,
     27 			TopBitrate: 6000,
     28 		},
     29 		Status:  Status{true, 15000},
     30 		Session: Session{ID: "6e2fb550-c457-11e9-bb97-0800200c9a66", PlayRate: RealTime},
     31 	},
     32 	"testdata/booleans": {
     33 		Status:  Status{true, 0},
     34 		Request: Request{Startup: true},
     35 		Session: Session{PlayRate: RealTime},
     36 	},
     37 	"testdata/range": {
     38 		Request: Request{NextRange: [2]int{12323, 48763}},
     39 		Object:  Object{Duration: 4004 * time.Millisecond},
     40 		Session: Session{PlayRate: RealTime},
     41 	},
     42 	"testdata/custom": {
     43 		Object:  Object{Duration: 4004 * time.Millisecond},
     44 		Session: Session{PlayRate: RealTime},
     45 		Custom: map[string]any{
     46 			"com.example.javasucks.int": 500,
     47 			"stringy":                   "yamum",
     48 			"aBool":                     true,
     49 		},
     50 	},
     51 }
     52 
     53 func TestParse(t *testing.T) {
     54 	for name, want := range tests {
     55 		t.Run(path.Base(name), func(t *testing.T) {
     56 			pt, err := readParseTest(name)
     57 			if err != nil {
     58 				t.Fatal(err)
     59 			}
     60 			info, err := ParseInfo(pt.query)
     61 			if err != nil {
     62 				t.Errorf("info from query: %v", err)
     63 			}
     64 			if !reflect.DeepEqual(want, info) {
     65 				t.Errorf("info from query: want %+v, got %+v", want, info)
     66 				t.Log(want.Encode())
     67 				t.Log(info.Encode())
     68 			}
     69 
     70 			// now try re-encoding to see if we get the same back again.
     71 			// trim stray commas used for testing parser.
     72 			swant := strings.Split(strings.Trim(pt.query, ","), ",")
     73 			sgot := strings.Split(info.Encode(), ",")
     74 			sort.Strings(swant)
     75 			sort.Strings(sgot)
     76 			if !reflect.DeepEqual(sgot, swant) {
     77 				t.Errorf("re-encode: got %v, want %v", sgot, swant)
     78 			}
     79 		})
     80 	}
     81 }
     82 
     83 type parseTest struct {
     84 	header http.Header
     85 	query  string
     86 	json   []byte
     87 }
     88 
     89 func readParseTest(name string) (parseTest, error) {
     90 	f, err := os.Open(name)
     91 	if err != nil {
     92 		return parseTest{}, err
     93 	}
     94 	defer f.Close()
     95 	var pt parseTest
     96 	pt.header = make(http.Header)
     97 	sc := bufio.NewScanner(f)
     98 	for sc.Scan() {
     99 		if sc.Text() == "" {
    100 			continue
    101 		} else if strings.HasPrefix(sc.Text(), "#") {
    102 			continue // skip comments
    103 		}
    104 		if strings.HasPrefix(sc.Text(), "?CMCD=") {
    105 			raw := strings.TrimPrefix(sc.Text(), "?CMCD=")
    106 			q, err := url.QueryUnescape(raw)
    107 			if err != nil {
    108 				return pt, fmt.Errorf("parse cmcd query: %w", err)
    109 			}
    110 			pt.query = q
    111 			continue
    112 		}
    113 		if strings.HasPrefix(sc.Text(), "{") {
    114 			pt.json = sc.Bytes()
    115 		}
    116 		before, after, found := strings.Cut(sc.Text(), ":")
    117 		if !found {
    118 			return pt, fmt.Errorf("invalid case: %s", sc.Text())
    119 		}
    120 		pt.header.Set(before, strings.TrimSpace(after))
    121 	}
    122 	return pt, sc.Err()
    123 }
    124 
    125 /*
    126 			custom := make(map[string]any) // TODO
    127 			if !reflect.DeepEqual(tt.want.Custom, custom) {
    128 				t.Errorf("custom attributes: want %+v, got %+v", tt.want.Custom, custom)
    129 			}
    130 		})
    131 	}
    132 }
    133 */