1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-21 23:55:13 -05:00

FileRecord improvement: unit test for the rescue program

This commit is contained in:
f4exb 2018-10-09 18:28:59 +02:00
parent 38aa1a8e77
commit bfb7583544
3 changed files with 90 additions and 60 deletions

View File

@ -12,9 +12,9 @@ The header is composed as follows:
- Sample size as 16 or 24 bits (4 bytes, 32 bits)
- filler with all zeroes (4 bytes, 32 bits)
- CRC32 (IEEE) of the 28 bytes above (4 bytes, 32 bits)
The header size is 32 bytes in total which is a multiple of 8 bytes thus occupies an integer number of samples whether in 16 or 24 bits mode. When migrating from a pre version 4.2.1 header you may crunch a very small amount of samples.
The header size is 32 bytes in total which is a multiple of 8 bytes thus occupies an integer number of samples whether in 16 or 24 bits mode. When migrating from a pre version 4.2.1 header you may crunch a very small amount of samples.
You can replace values in the header with the following options:
- -sr uint
@ -28,21 +28,21 @@ You can replace values in the header with the following options:
- -sz uint
Sample size (16 or 24) (default 16)
You need to specify an input file. If no output file is specified the current header values are printed to the console and the program exits:
You need to specify an input file. If no output file is specified the current header values are printed to the console and the program exits:
- -in string
input file (default "foo")
To convert to a new file you need to specify the output file:
- -out string
output file (default "foo")
You can specify a block size in multiples of 4k for the copy. Large blocks will yield a faster copy but a larger output file. With the default of 1 (4k) the copy does not take much time anyway:
You can specify a block size in multiples of 4k for the copy. Large blocks will yield a faster copy but a larger output file. With the default of 1 (4k) the copy does not take much time anyway:
- -bz uint
Copy block size in multiple of 4k (default 1)
<h2>Build</h2>
The program is written in go and is provided only in source code form. Compiling it is very easy:
@ -55,5 +55,11 @@ You will usually find a `golang` package in your distribution. For example in Ub
In this directory just do `go build`
<h3>Unit testing</h3>
Unit test (very simple) is located in `rescuesdriq_test.go`. It uses the [Go Convey](https://github.com/smartystreets/goconvey) framework. You should first install it with:
`go get github.com/smartystreets/goconvey`
You can run unit test from command line with: `go test`
Or with the Go Convey server that you start from this directory with: `$GOPATH/bin/goconvey` where `$GOPATH` is the path to your go installation.

View File

@ -1,41 +1,39 @@
package main
import (
"bufio"
"bytes"
"encoding/binary"
"flag"
"fmt"
"bufio"
"io"
"os"
"bytes"
"encoding/binary"
"time"
"hash/crc32"
"hash/crc32"
"io"
"os"
"time"
)
type HeaderStd struct {
SampleRate uint32
CenterFrequency uint64
StartTimestamp int64
SampleSize uint32
Filler uint32
CRC32 uint32
SampleRate uint32
CenterFrequency uint64
StartTimestamp int64
SampleSize uint32
Filler uint32
CRC32 uint32
}
func check(e error) {
if e != nil {
panic(e)
}
if e != nil {
panic(e)
}
}
func analyze(r *bufio.Reader) HeaderStd {
headerbuf := make([]byte, 32) // This is a full header with CRC
headerbuf := make([]byte, 32) // This is a full header with CRC
n, err := r.Read(headerbuf)
if err != nil && err != io.EOF {
panic(err)
}
if (n != 32) {
if n != 32 {
panic("Header too small")
}
@ -44,7 +42,7 @@ func analyze(r *bufio.Reader) HeaderStd {
err = binary.Read(headerr, binary.LittleEndian, &header)
check(err)
return header
return header
}
func writeHeader(writer *bufio.Writer, header *HeaderStd) {
@ -62,7 +60,7 @@ func setCRC(header *HeaderStd) {
header.CRC32 = crc32.ChecksumIEEE(bin_buf.Bytes()[0:28])
}
func getCRC(header *HeaderStd) uint32 {
func GetCRC(header *HeaderStd) uint32 {
var bin_buf bytes.Buffer
header.Filler = 0
binary.Write(&bin_buf, binary.LittleEndian, header)
@ -70,13 +68,13 @@ func getCRC(header *HeaderStd) uint32 {
}
func printHeader(header *HeaderStd) {
fmt.Println("Sample rate:", header.SampleRate)
fmt.Println("Frequency :", header.CenterFrequency)
fmt.Println("Sample Size:", header.SampleSize)
tm := time.Unix(header.StartTimestamp, 0)
fmt.Println("Start :", tm)
fmt.Println("Sample rate:", header.SampleRate)
fmt.Println("Frequency :", header.CenterFrequency)
fmt.Println("Sample Size:", header.SampleSize)
tm := time.Unix(header.StartTimestamp, 0)
fmt.Println("Start :", tm)
fmt.Println("CRC32 :", header.CRC32)
fmt.Println("CRC32 OK :", getCRC(header))
fmt.Println("CRC32 OK :", GetCRC(header))
}
func copyContent(reader *bufio.Reader, writer *bufio.Writer, blockSize uint) {
@ -97,7 +95,7 @@ func copyContent(reader *bufio.Reader, writer *bufio.Writer, blockSize uint) {
}
} else {
writer.Write(p)
sz += int64(blockSize)*4096
sz += int64(blockSize) * 4096
}
fmt.Printf("Wrote %d bytes\r", sz)
@ -107,14 +105,14 @@ func copyContent(reader *bufio.Reader, writer *bufio.Writer, blockSize uint) {
}
func main() {
inFileStr := flag.String("in", "foo", "input file")
inFileStr := flag.String("in", "foo", "input file")
outFileStr := flag.String("out", "foo", "output file")
sampleRate := flag.Uint("sr", 0, "Sample rate (S/s)")
centerFreq := flag.Uint64("cf", 0, "Center frequency (Hz)")
sampleSize := flag.Uint("sz", 16, "Sample size (16 or 24)")
timeStr := flag.String("ts", "", "start time RFC3339 (ex: 2006-01-02T15:04:05Z)")
timeNow := flag.Bool("now", false , "use now for start time")
blockSize := flag.Uint("bz", 1, "Copy block size in multiple of 4k")
timeStr := flag.String("ts", "", "start time RFC3339 (ex: 2006-01-02T15:04:05Z)")
timeNow := flag.Bool("now", false, "use now for start time")
blockSize := flag.Uint("bz", 1, "Copy block size in multiple of 4k")
flag.Parse()
flagSeen := make(map[string]bool)
@ -123,16 +121,16 @@ func main() {
if flagSeen["in"] {
fmt.Println("input file :", *inFileStr)
// open input file
fi, err := os.Open(*inFileStr)
check(err)
// close fi on exit and check for its returned error
defer func() {
err := fi.Close();
check(err)
}()
// make a read buffer
reader := bufio.NewReader(fi)
// open input file
fi, err := os.Open(*inFileStr)
check(err)
// close fi on exit and check for its returned error
defer func() {
err := fi.Close()
check(err)
}()
// make a read buffer
reader := bufio.NewReader(fi)
var headerOrigin HeaderStd = analyze(reader)
printHeader(&headerOrigin)
@ -150,7 +148,7 @@ func main() {
}
} else if flagSeen["ts"] {
t, err := time.Parse(time.RFC3339, *timeStr)
if (err == nil) {
if err == nil {
headerOrigin.StartTimestamp = t.Unix()
} else {
fmt.Println("Incorrect time specified. Defaulting to now")
@ -169,10 +167,10 @@ func main() {
fo, err := os.Create(*outFileStr)
check(err)
defer func() {
err := fo.Close();
check(err)
}()
defer func() {
err := fo.Close()
check(err)
}()
writer := bufio.NewWriter(fo)

View File

@ -0,0 +1,26 @@
package main
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestSpec(t *testing.T) {
// Only pass t into top-level Convey calls
Convey("Given a header structure", t, func() {
var header HeaderStd
header.SampleRate = 75000
header.CenterFrequency = 435000000
header.StartTimestamp = 1539083921
header.SampleSize = 16
header.Filler = 0
crc32 := GetCRC(&header)
Convey("The CRC32 value should be 2294957931", func() {
So(crc32, ShouldEqual, 2294957931)
})
})
}