test(tracker): fuzz testing of ID collisions and file read/writes

This commit is contained in:
5684185+vsariola@users.noreply.github.com 2024-09-07 15:16:53 +03:00
parent 61e7da5dab
commit 9da6c2216c
2 changed files with 43 additions and 1 deletions

View File

@ -461,7 +461,7 @@ func (m *Model) fixIDCollisions() {
} }
} }
if needsFix { if needsFix {
m.Alerts().Add("Some units had duplicate IDs, they were fixed", Error) m.Alerts().AddNamed("IDCollision", "Some units had duplicate IDs, they were fixed", Error)
for i, instr := range m.d.Song.Patch { for i, instr := range m.d.Song.Patch {
for j, unit := range instr.Units { for j, unit := range instr.Units {
if unit.ID == 0 { if unit.ID == 0 {

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io"
"testing" "testing"
"github.com/vsariola/sointu/tracker" "github.com/vsariola/sointu/tracker"
@ -23,6 +24,16 @@ func (NullContext) BPM() (bpm float64, ok bool) {
type modelFuzzState struct { type modelFuzzState struct {
model *tracker.Model model *tracker.Model
clipboard []byte clipboard []byte
file []byte
}
type myWriteCloser struct {
*bytes.Buffer
}
func (mwc *myWriteCloser) Close() error {
// Noop
return nil
} }
func (s *modelFuzzState) Iterate(yield func(string, func(p string, t *testing.T)) bool, seed int) { func (s *modelFuzzState) Iterate(yield func(string, func(p string, t *testing.T)) bool, seed int) {
@ -81,6 +92,32 @@ func (s *modelFuzzState) Iterate(yield func(string, func(p string, t *testing.T)
// Tables // Tables
s.IterateTable("Order", s.model.Order().Table(), yield, seed) s.IterateTable("Order", s.model.Order().Table(), yield, seed)
s.IterateTable("Notes", s.model.Notes().Table(), yield, seed) s.IterateTable("Notes", s.model.Notes().Table(), yield, seed)
// File reading
if s.file != nil {
yield("ReadSong", func(p string, t *testing.T) {
reader := bytes.NewReader(s.file)
readCloser := io.NopCloser(reader)
s.model.ReadSong(readCloser)
})
yield("LoadInstrument", func(p string, t *testing.T) {
reader := bytes.NewReader(s.file)
readCloser := io.NopCloser(reader)
s.model.LoadInstrument(readCloser)
})
}
// File saving
yield("WriteSong", func(p string, t *testing.T) {
writer := bytes.NewBuffer(nil)
writeCloser := &myWriteCloser{writer}
s.model.WriteSong(writeCloser)
s.file = writer.Bytes()
})
yield("SaveInstrument", func(p string, t *testing.T) {
writer := bytes.NewBuffer(nil)
writeCloser := &myWriteCloser{writer}
s.model.SaveInstrument(writeCloser)
s.file = writer.Bytes()
})
} }
func (s *modelFuzzState) IterateInt(name string, i tracker.Int, yield func(string, func(p string, t *testing.T)) bool, seed int) { func (s *modelFuzzState) IterateInt(name string, i tracker.Int, yield func(string, func(p string, t *testing.T)) bool, seed int) {
@ -248,6 +285,11 @@ func FuzzModel(f *testing.F) {
index-- index--
return index > 0 return index > 0
}, seed) }, seed)
state.model.Alerts().Iterate(func(a tracker.Alert) {
if a.Name == "IDCollision" {
t.Errorf("Path: %s Model has ID collisions", totalPath)
}
})
} }
closeChan <- struct{}{} closeChan <- struct{}{}
}) })