mapreduce_fuzz_test.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package mr
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "runtime"
  6. "strings"
  7. "testing"
  8. "time"
  9. "github.com/stretchr/testify/assert"
  10. "go.uber.org/goleak"
  11. )
  12. func FuzzMapReduce(f *testing.F) {
  13. rand.Seed(time.Now().UnixNano())
  14. f.Add(int64(10), runtime.NumCPU())
  15. f.Fuzz(func(t *testing.T, n int64, workers int) {
  16. n = n%5000 + 5000
  17. genPanic := rand.Intn(100) == 0
  18. mapperPanic := rand.Intn(100) == 0
  19. reducerPanic := rand.Intn(100) == 0
  20. genIdx := rand.Int63n(n)
  21. mapperIdx := rand.Int63n(n)
  22. reducerIdx := rand.Int63n(n)
  23. squareSum := (n - 1) * n * (2*n - 1) / 6
  24. fn := func() (int64, error) {
  25. defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
  26. return MapReduce(func(source chan<- int64) {
  27. for i := int64(0); i < n; i++ {
  28. source <- i
  29. if genPanic && i == genIdx {
  30. panic("foo")
  31. }
  32. }
  33. }, func(v int64, writer Writer[int64], cancel func(error)) {
  34. if mapperPanic && v == mapperIdx {
  35. panic("bar")
  36. }
  37. writer.Write(v * v)
  38. }, func(pipe <-chan int64, writer Writer[int64], cancel func(error)) {
  39. var idx int64
  40. var total int64
  41. for v := range pipe {
  42. if reducerPanic && idx == reducerIdx {
  43. panic("baz")
  44. }
  45. total += v
  46. idx++
  47. }
  48. writer.Write(total)
  49. }, WithWorkers(workers%50+runtime.NumCPU()))
  50. }
  51. if genPanic || mapperPanic || reducerPanic {
  52. var buf strings.Builder
  53. buf.WriteString(fmt.Sprintf("n: %d", n))
  54. buf.WriteString(fmt.Sprintf(", genPanic: %t", genPanic))
  55. buf.WriteString(fmt.Sprintf(", mapperPanic: %t", mapperPanic))
  56. buf.WriteString(fmt.Sprintf(", reducerPanic: %t", reducerPanic))
  57. buf.WriteString(fmt.Sprintf(", genIdx: %d", genIdx))
  58. buf.WriteString(fmt.Sprintf(", mapperIdx: %d", mapperIdx))
  59. buf.WriteString(fmt.Sprintf(", reducerIdx: %d", reducerIdx))
  60. assert.Panicsf(t, func() { fn() }, buf.String())
  61. } else {
  62. val, err := fn()
  63. assert.Nil(t, err)
  64. assert.Equal(t, squareSum, val)
  65. }
  66. })
  67. }