2022-01-22 19:52:24 +00:00
|
|
|
package system
|
|
|
|
|
|
|
|
import (
|
2022-01-23 23:31:53 +00:00
|
|
|
"math/rand"
|
2022-01-22 19:52:24 +00:00
|
|
|
"strings"
|
2022-01-30 18:58:36 +00:00
|
|
|
"sync"
|
2022-01-22 19:52:24 +00:00
|
|
|
"testing"
|
2022-01-23 23:31:53 +00:00
|
|
|
"time"
|
2022-01-22 19:52:24 +00:00
|
|
|
|
|
|
|
. "github.com/franela/goblin"
|
2022-01-30 18:58:36 +00:00
|
|
|
"github.com/goccy/go-json"
|
2022-01-22 19:52:24 +00:00
|
|
|
)
|
|
|
|
|
2022-01-23 23:31:53 +00:00
|
|
|
func Test_Utils(t *testing.T) {
|
2022-01-22 19:52:24 +00:00
|
|
|
g := Goblin(t)
|
|
|
|
|
|
|
|
g.Describe("ScanReader", func() {
|
|
|
|
g.BeforeEach(func() {
|
|
|
|
maxBufferSize = 10
|
|
|
|
})
|
|
|
|
|
|
|
|
g.It("should truncate and return long lines", func() {
|
|
|
|
reader := strings.NewReader("hello world this is a long line\nof text that should be truncated\nnot here\nbut definitely on this line")
|
|
|
|
|
|
|
|
var lines []string
|
|
|
|
err := ScanReader(reader, func(line []byte) {
|
|
|
|
lines = append(lines, string(line))
|
|
|
|
})
|
|
|
|
|
|
|
|
g.Assert(err).IsNil()
|
|
|
|
g.Assert(lines).Equal([]string{"hello worl", "of text th", "not here", "but defini"})
|
|
|
|
})
|
|
|
|
|
|
|
|
g.It("should replace cariage returns with newlines", func() {
|
|
|
|
reader := strings.NewReader("test\rstring\r\nanother\rline\nhodor\r\r\rheld the door\nmaterial gourl\n")
|
|
|
|
var lines []string
|
|
|
|
err := ScanReader(reader, func(line []byte) {
|
|
|
|
lines = append(lines, string(line))
|
|
|
|
})
|
|
|
|
|
|
|
|
g.Assert(err).IsNil()
|
|
|
|
g.Assert(lines).Equal([]string{"test\rstrin", "another\rli", "hodor\r\r\rhe", "material g"})
|
|
|
|
})
|
|
|
|
})
|
2022-01-30 18:58:36 +00:00
|
|
|
|
|
|
|
g.Describe("AtomicBool", func() {
|
|
|
|
var b *AtomicBool
|
|
|
|
g.BeforeEach(func() {
|
|
|
|
b = NewAtomicBool(false)
|
|
|
|
})
|
|
|
|
|
|
|
|
g.It("initalizes with the provided start value", func() {
|
|
|
|
b = NewAtomicBool(true)
|
|
|
|
g.Assert(b.Load()).IsTrue()
|
|
|
|
|
|
|
|
b = NewAtomicBool(false)
|
|
|
|
g.Assert(b.Load()).IsFalse()
|
|
|
|
})
|
|
|
|
|
|
|
|
g.Describe("AtomicBool#Store", func() {
|
|
|
|
g.It("stores the provided value", func() {
|
|
|
|
g.Assert(b.Load()).IsFalse()
|
|
|
|
b.Store(true)
|
|
|
|
g.Assert(b.Load()).IsTrue()
|
|
|
|
})
|
|
|
|
|
|
|
|
// This test makes no assertions, it just expects to not hit a race condition
|
|
|
|
// by having multiple things writing at the same time.
|
|
|
|
g.It("handles contention from multiple routines", func() {
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
|
|
|
wg.Add(100)
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
go func(i int) {
|
|
|
|
b.Store(i%2 == 0)
|
|
|
|
wg.Done()
|
|
|
|
}(i)
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
g.Describe("AtomicBool#SwapIf", func() {
|
|
|
|
g.It("swaps the value out if different than what is stored", func() {
|
|
|
|
o := b.SwapIf(false)
|
|
|
|
g.Assert(o).IsFalse()
|
|
|
|
g.Assert(b.Load()).IsFalse()
|
|
|
|
|
|
|
|
o = b.SwapIf(true)
|
|
|
|
g.Assert(o).IsTrue()
|
|
|
|
g.Assert(b.Load()).IsTrue()
|
|
|
|
|
|
|
|
o = b.SwapIf(true)
|
|
|
|
g.Assert(o).IsFalse()
|
|
|
|
g.Assert(b.Load()).IsTrue()
|
|
|
|
|
|
|
|
o = b.SwapIf(false)
|
|
|
|
g.Assert(o).IsTrue()
|
|
|
|
g.Assert(b.Load()).IsFalse()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
g.Describe("can be marshaled with JSON", func() {
|
|
|
|
type testStruct struct {
|
|
|
|
Value AtomicBool `json:"value"`
|
|
|
|
}
|
|
|
|
|
|
|
|
var o testStruct
|
|
|
|
err := json.Unmarshal([]byte(`{"value":true}`), &o)
|
|
|
|
|
|
|
|
g.Assert(err).IsNil()
|
|
|
|
g.Assert(o.Value.Load()).IsTrue()
|
|
|
|
|
|
|
|
b, err2 := json.Marshal(&o)
|
|
|
|
g.Assert(err2).IsNil()
|
|
|
|
g.Assert(b).Equal([]byte(`{"value":true}`))
|
|
|
|
})
|
|
|
|
})
|
2022-01-22 19:52:24 +00:00
|
|
|
}
|
2022-01-23 23:31:53 +00:00
|
|
|
|
|
|
|
func Benchmark_ScanReader(b *testing.B) {
|
|
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
var str string
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
str += strings.Repeat("hello \rworld", r.Intn(2000)) + "\n"
|
|
|
|
}
|
|
|
|
reader := strings.NewReader(str)
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
_ = ScanReader(reader, func(line []byte) {
|
|
|
|
// no op
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|