main.go raw
1 package main
2
3 import "io"
4 import "moxie"
5
6 // B.0.4 stress test: sustained codec round-trip under load.
7 // 10000 messages with mixed-size variable payloads. Exercises the
8 // Codec serialization path repeatedly to catch GC/heap interactions
9 // that single-shot tests miss.
10
11 type Msg struct {
12 Seq uint32
13 Sum uint32
14 Body []byte
15 }
16
17 func (m Msg) EncodeTo(w io.Writer) error {
18 var hdr [8]byte
19 hdr[0] = byte(m.Seq)
20 hdr[1] = byte(m.Seq >> 8)
21 hdr[2] = byte(m.Seq >> 16)
22 hdr[3] = byte(m.Seq >> 24)
23 hdr[4] = byte(m.Sum)
24 hdr[5] = byte(m.Sum >> 8)
25 hdr[6] = byte(m.Sum >> 16)
26 hdr[7] = byte(m.Sum >> 24)
27 if _, err := w.Write(hdr[:]); err != nil {
28 return err
29 }
30 var sz [4]byte
31 l := uint32(len(m.Body))
32 sz[0] = byte(l)
33 sz[1] = byte(l >> 8)
34 sz[2] = byte(l >> 16)
35 sz[3] = byte(l >> 24)
36 if _, err := w.Write(sz[:]); err != nil {
37 return err
38 }
39 _, err := w.Write(m.Body)
40 return err
41 }
42
43 func (m *Msg) DecodeFrom(r io.Reader) error {
44 var hdr [8]byte
45 if _, err := io.ReadFull(r, hdr[:]); err != nil {
46 return err
47 }
48 m.Seq = uint32(hdr[0]) | uint32(hdr[1])<<8 | uint32(hdr[2])<<16 | uint32(hdr[3])<<24
49 m.Sum = uint32(hdr[4]) | uint32(hdr[5])<<8 | uint32(hdr[6])<<16 | uint32(hdr[7])<<24
50 var sz [4]byte
51 if _, err := io.ReadFull(r, sz[:]); err != nil {
52 return err
53 }
54 l := uint32(sz[0]) | uint32(sz[1])<<8 | uint32(sz[2])<<16 | uint32(sz[3])<<24
55 m.Body = make([]byte, l)
56 _, err := io.ReadFull(r, m.Body)
57 return err
58 }
59
60 func mirror(in chan Msg, out chan Msg, done chan moxie.Uint32) {
61 count := uint32(0)
62 for {
63 m := <-in
64 if m.Seq == 0xFFFFFFFF {
65 break
66 }
67 // Recompute sum on body to verify integrity.
68 s := uint32(0)
69 for i := 0; i < len(m.Body); i++ {
70 s += uint32(m.Body[i])
71 }
72 out <- Msg{Seq: m.Seq, Sum: s, Body: m.Body}
73 count++
74 }
75 done <- moxie.Uint32(count)
76 }
77
78 func main() {
79 in := make(chan Msg)
80 out := make(chan Msg)
81 done := make(chan moxie.Uint32)
82 spawn(mirror, in, out, done)
83
84 const N = uint32(10000)
85 for i := uint32(0); i < N; i++ {
86 // Varying body size: 0, 1, 2, ..., 1023, 0, 1, ...
87 bodyLen := int(i % 1024)
88 body := make([]byte, bodyLen)
89 expectedSum := uint32(0)
90 for j := 0; j < bodyLen; j++ {
91 body[j] = byte((i + uint32(j)) & 0xFF)
92 expectedSum += uint32(body[j])
93 }
94 in <- Msg{Seq: i, Sum: 0, Body: body}
95 got := <-out
96 if got.Seq != i || got.Sum != expectedSum {
97 println("FAIL:stress", "i", i, "got.Seq", got.Seq, "got.Sum", got.Sum, "want.Sum", expectedSum)
98 return
99 }
100 if i%1000 == 0 && i > 0 {
101 println("progress:", i)
102 }
103 }
104 in <- Msg{Seq: 0xFFFFFFFF, Sum: 0, Body: nil}
105 count := uint32(<-done)
106 if count != N {
107 println("FAIL:stress", "count", count, "want", N)
108 return
109 }
110 println("PASS:stress-codec", N, "msgs")
111 }
112