Skip to content

Instantly share code, notes, and snippets.

@antonsoroko
Last active June 2, 2020 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antonsoroko/db160e36551d61dfdc844f7c614753b2 to your computer and use it in GitHub Desktop.
Save antonsoroko/db160e36551d61dfdc844f7c614753b2 to your computer and use it in GitHub Desktop.
мой main_test.go для задачи E https://contest.yandex.ru/contest/17728
package main
import (
"log"
"math/rand"
"runtime"
"sync"
"testing"
"time"
)
func init() {
log.Println("GOMAXPROCS was", runtime.GOMAXPROCS(0))
runtime.GOMAXPROCS(1)
}
func TestNil(t *testing.T) {
repeats := -999
var in1 chan int
var in2 chan int
var out chan int
log.Println("Run Merge2Channels")
Merge2Channels(fRandomSpeed, in1, in2, out, repeats)
}
func TestMerge2Channels3TimesSameChannelsFillInAfterRun(t *testing.T) {
rand.Seed(time.Now().UnixNano())
// repeats := rand.Intn(400)
repeats := 999999
log.Printf("Repeats=%d", repeats)
in1 := make(chan int, repeats)
in2 := make(chan int, repeats)
out := make(chan int, repeats)
log.Println("Run Merge2Channels 2 times with half of N")
Merge2Channels(fRandomSpeed, in1, in2, out, repeats/3)
Merge2Channels(fRandomSpeed, in1, in2, out, repeats/3)
Merge2Channels(fRandomSpeed, in1, in2, out, repeats/3)
results := make([]int, repeats)
go func() {
for i := 1; i < repeats+1; i++ {
i1 := rand.Intn(200)
i2 := rand.Intn(200)
// to avoid data race in next range
results[i-1] = fFast(i1) + fFast(i2)
in1 <- i1
in2 <- i2
}
log.Println("Sent all inputs, closing channel")
close(in1)
close(in2)
}()
log.Println("Reading through out channel")
for i := 0; i < repeats; i++ {
got, ok := <-out
if !ok {
t.Fatal("out channel is closed!")
}
if results[i] != got {
t.Errorf("got %d, want %d", got, results[i])
}
//log.Println("result =", results[i])
//log.Println("out =", got)
}
log.Println("Got all results, closing out channel")
//close(out)
// log.Println("results =", results)
}
func TestMerge2ChannelsNTimesDefferentChannelsFillInBeforeRun(t *testing.T) {
rand.Seed(time.Now().UnixNano())
repeats := 10000
log.Printf("Repeats=%d", repeats)
runTimes := 100
//done := make(chan struct{}, runTimes)
var wg sync.WaitGroup
for r := 0; r < runTimes; r++ {
wg.Add(1)
rr := r
go func() {
in1 := make(chan int, repeats*2)
in2 := make(chan int, repeats*2)
out := make(chan int, repeats*2)
results := make([]int, repeats)
for i := 1; i < repeats+1; i++ {
in1 <- i
in2 <- i
results[i-1] = fFast(i) * 2
//log.Println("Wrote input", rr, i)
}
// add extra input
for i := repeats + 1; i < repeats*2+1; i++ {
in1 <- 1
in2 <- 1
}
log.Println("Run Merge2Channels")
Merge2Channels(fFast, in1, in2, out, repeats)
go func(wg *sync.WaitGroup) {
log.Println("Reading through out channel", rr)
for i := 0; i < repeats; i++ {
v := results[i]
r := <-out
if v != r {
t.Errorf("got %d, want %d", r, v)
}
}
log.Println("Done reading through out channel", rr)
wg.Done()
//done <- struct{}{}
}(&wg)
}()
}
wg.Wait()
/*for i := 0; i < runTimes; i++ {
<-done
}*/
}
func fFast(n int) int {
return n + n
}
func fRandomSpeed(n int) int {
time.Sleep(time.Duration(rand.Int31n(500)) * time.Millisecond)
return fFast(n)
}
func fSlow(n int) int {
time.Sleep(1000 * time.Millisecond)
return fFast(n)
}
func TestNonBlocking(t *testing.T) {
capacity := 100
portion := capacity / 10
ch1 := make(chan int, capacity)
ch2 := make(chan int, capacity)
chOut := make(chan int, capacity)
// fill only portion in case if function blocks on channels read
for i := 0; i < portion; i++ {
ch1 <- i
ch2 <- i
}
done := make(chan struct{})
go func() {
Merge2Channels(fSlow, ch1, ch2, chOut, capacity)
close(done)
}()
select {
case <-done:
close(ch1)
close(ch2)
//close(chOut)
return
case <-time.After(time.Millisecond * 100):
t.Fatal("Function should be non-blocking")
}
}
//check for reading extra input
//check for returning extra output
func TestMerge2ChannelsExtraData(t *testing.T) {
capacity := 100
portion := capacity / 2
ch1 := make(chan int, capacity)
ch2 := make(chan int, capacity)
chOut := make(chan int, capacity)
results := make([]int, capacity)
i := 0
for i < capacity {
ch1 <- i + 42
ch2 <- i * 42
results[i] = fFast(i+42) + fFast(i*42)
i++
}
done := make(chan struct{})
go func() {
Merge2Channels(fSlow, ch1, ch2, chOut, portion)
close(done)
}()
<-done
i = 0
for i < portion {
ans, ok := <-chOut
if !ok {
t.Fatal("Output channel should not be closed")
}
if ans != results[i] {
t.Fatalf("Got %d from output channel, should be %d", ans, results[i])
}
i++
}
if len(ch1) != capacity-portion {
t.Fatalf("First channel has %d numbers in it, should have %d", len(ch1), capacity-portion)
}
if len(ch2) != capacity-portion {
t.Fatalf("Second channel has %d numbers in it, should have %d", len(ch2), capacity-portion)
}
if len(chOut) != 0 {
t.Fatalf("Output channel has %d numbers in it, should have %d", len(chOut), 0)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment