github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/cmd/testUtil.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/onflow/flow-go/module/irrecoverable" 8 ) 9 10 type testLog struct { 11 logs []string 12 mux sync.Mutex 13 } 14 15 // handle concurrent logging 16 func (l *testLog) Logf(msg string, args ...interface{}) { 17 l.Log(fmt.Sprintf(msg, args...)) 18 } 19 20 func (l *testLog) Log(msg string) { 21 l.mux.Lock() 22 defer l.mux.Unlock() 23 24 l.logs = append(l.logs, msg) 25 } 26 27 func (l *testLog) Reset() { 28 l.mux.Lock() 29 defer l.mux.Unlock() 30 31 l.logs = []string{} 32 } 33 34 func newMockReadyDone(logger *testLog, name string) *mockReadyDone { 35 return &mockReadyDone{ 36 name: name, 37 logger: logger, 38 readyFn: func(string) {}, 39 doneFn: func(string) {}, 40 ready: make(chan struct{}), 41 done: make(chan struct{}), 42 } 43 } 44 45 type mockReadyDone struct { 46 name string 47 logger *testLog 48 49 readyFn func(string) 50 doneFn func(string) 51 52 ready chan struct{} 53 done chan struct{} 54 55 startOnce sync.Once 56 stopOnce sync.Once 57 } 58 59 func (c *mockReadyDone) Ready() <-chan struct{} { 60 c.startOnce.Do(func() { 61 go func() { 62 c.readyFn(c.name) 63 64 c.logger.Logf("%s ready", c.name) 65 close(c.ready) 66 }() 67 }) 68 69 return c.ready 70 } 71 72 func (c *mockReadyDone) Done() <-chan struct{} { 73 c.stopOnce.Do(func() { 74 go func() { 75 c.doneFn(c.name) 76 77 c.logger.Logf("%s done", c.name) 78 close(c.done) 79 }() 80 }) 81 82 return c.done 83 } 84 85 func newMockComponent(logger *testLog, name string) *mockComponent { 86 return &mockComponent{ 87 name: name, 88 logger: logger, 89 readyFn: func(string) {}, 90 doneFn: func(string) {}, 91 startFn: func(irrecoverable.SignalerContext, string) {}, 92 ready: make(chan struct{}), 93 done: make(chan struct{}), 94 } 95 } 96 97 type mockComponent struct { 98 name string 99 logger *testLog 100 101 readyFn func(string) 102 doneFn func(string) 103 startFn func(irrecoverable.SignalerContext, string) 104 105 ready chan struct{} 106 done chan struct{} 107 } 108 109 func (c *mockComponent) Start(ctx irrecoverable.SignalerContext) { 110 c.startFn(ctx, c.name) 111 c.logger.Logf("%s started", c.name) 112 113 go func() { 114 c.readyFn(c.name) 115 c.logger.Logf("%s ready", c.name) 116 close(c.ready) 117 }() 118 119 go func() { 120 <-ctx.Done() 121 122 c.doneFn(c.name) 123 c.logger.Logf("%s done", c.name) 124 close(c.done) 125 }() 126 } 127 128 func (c *mockComponent) Ready() <-chan struct{} { 129 return c.ready 130 } 131 132 func (c *mockComponent) Done() <-chan struct{} { 133 return c.done 134 }