github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/asyncbuffer/buffer_test.go (about) 1 package asyncbuffer 2 3 import ( 4 "bytes" 5 "math/rand" 6 "runtime" 7 "strconv" 8 "sync" 9 "sync/atomic" 10 _ "syscall" 11 "testing" 12 "time" 13 "unsafe" 14 ) 15 16 var itemMap map[string]int = map[string]int{} 17 18 //var gItemMap sync.Map 19 var gCounter uint64 20 21 func (m *DemoBuffer) BatchDo(data [][]byte) { 22 //println("bufferLen:", len(data)) 23 bufferData := "" 24 for _, item := range data { 25 //println("getSendDataFrom item:", *(*string)(unsafe.Pointer(&item))) 26 //time.Sleep(300 * time.Millisecond) 27 28 //_, ok := gItemMap.Load(*(*string)(unsafe.Pointer(&item))) 29 _, ok := itemMap[*(*string)(unsafe.Pointer(&item))] 30 if !ok { 31 atomic.AddUint64(&gCounter, 1) 32 //gItemMap.Store(*(*string)(unsafe.Pointer(&item)), 1) 33 itemMap[*(*string)(unsafe.Pointer(&item))] = 1 34 //println("lenItemMap:", len(itemMap)) 35 } else { 36 println("repeat item:", *(*string)(unsafe.Pointer(&item))) 37 } 38 39 bufferData += *(*string)(unsafe.Pointer(&item)) + "\t" 40 if *(*string)(unsafe.Pointer(&item)) == "10" { 41 //panic("panic:" + string(item)) 42 } 43 } 44 45 //println("bufferData:", bufferData) 46 } 47 48 func (m *DemoBuffer) FormatInput() (err error, bytes []byte) { 49 return nil, []byte(m.Name) 50 } 51 52 func TestMain(m *testing.M) { 53 m.Run() 54 } 55 56 func TestFlushOne(t *testing.T) { 57 InitInstancesByConf() 58 time.Sleep(3 * time.Second) 59 60 type InputCase struct { 61 BufferName string 62 } 63 inputCases := []InputCase{{BufferName: "default"}, {BufferName: "default"}, {BufferName: "nmq_live_user"}} 64 65 for _, inputCase := range inputCases { 66 FlushOne(inputCase.BufferName) 67 time.Sleep(3 * time.Second) 68 } 69 } 70 71 func TestSendOneCh(t *testing.T) { 72 InitInstancesByConf() 73 time.Sleep(3 * time.Second) 74 75 type InputCase struct { 76 BufferName string 77 ChName string 78 Data IBuffer 79 } 80 inputCases := []InputCase{ 81 { 82 BufferName: "default", 83 ChName: "default", 84 Data: &DemoBuffer{Name: "testDefault1"}, 85 }, 86 { 87 BufferName: "default", 88 ChName: "default", 89 Data: &DemoBuffer{Name: "testDefault2"}, 90 }, 91 { 92 BufferName: "nmq_live_user", 93 ChName: "nmq", 94 Data: &DemoBuffer{Name: "testUser1"}, 95 }, 96 { 97 BufferName: "nmq_live_user", 98 ChName: "nmq", 99 Data: &DemoBuffer{Name: "testUser2"}, 100 }, 101 } 102 103 for _, inputCase := range inputCases { 104 err := SendOneCh(inputCase.BufferName, inputCase.ChName, inputCase.Data) 105 if err != nil { 106 t.Errorf("SendOneCh bufferName: %s chName: %s data: %v err: %s", inputCase.BufferName, inputCase.ChName, inputCase.Data, err.Error()) 107 } 108 } 109 110 FlushAll() 111 112 ch := make(chan int) 113 ch <- 1 114 115 } 116 117 func TestMultiWorkerSendOneCh(t *testing.T) { 118 InitInstancesByConf() 119 //time.Sleep(3 * time.Second) 120 121 var start time.Time 122 var end time.Time 123 124 type InputCase struct { 125 BufferName string 126 ChName string 127 Data IBuffer 128 } 129 start = time.Now() 130 //exitCh := make(chan int) 131 132 run: 133 // N+1 goroutine send D (N+1 * D) 134 var wg sync.WaitGroup 135 N := 9 136 D := 303 137 for i := 1; i <= N*D+1; i += D { 138 wg.Add(1) 139 go func(uid int) { 140 opCn := 0 141 for { 142 if opCn >= 3 { 143 end = time.Now() 144 // 执行时间 单位:微秒 145 _ = end.Sub(start).Nanoseconds() / 1e3 146 //println("gid:", getGID()) 147 //println("pid", syscall.Getpid()) 148 break 149 } 150 opCn += 1 151 testCases := []InputCase{} 152 for i := 1; i <= 101; i++ { 153 strUid := strconv.Itoa(uid) 154 testCase := InputCase{ 155 BufferName: "default", 156 ChName: "default", 157 Data: &DemoBuffer{Name: "" + strUid}, 158 } 159 testCases = append(testCases, testCase) 160 uid++ 161 } 162 r := rand.New(rand.NewSource(time.Now().UnixNano())) 163 randVal := r.Intn(10) 164 //println("sleep", randVal, "flush") 165 time.Sleep(time.Duration(randVal) * time.Second) 166 //FlushOne("default") 167 168 for _, testCase := range testCases { 169 err := SendOneCh(testCase.BufferName, testCase.ChName, testCase.Data) 170 if err != nil { 171 t.Errorf("SendOneCh bufferName: %s chName: %s data: %v err: %s", testCase.BufferName, testCase.ChName, testCase.Data, err.Error()) 172 } 173 } 174 //time.Sleep(200 * time.Millisecond) 175 } 176 //println("flushOne") 177 FlushOne("default") 178 time.Sleep(200 * time.Millisecond) 179 wg.Done() 180 }(i) 181 } 182 wg.Wait() 183 184 //println("flushAll") 185 //FlushAll() 186 //time.Sleep(200 * time.Millisecond) 187 188 cn := 0 189 /* 190 for i := 1; i <= (N+1) * D; i++ { 191 if _, ok := gItemMap.Load(strconv.Itoa(i)); !ok { 192 println("un send---->", i) 193 } else { 194 cn++ 195 } 196 } 197 */ 198 199 for i := 1; i <= (N+1)*D; i++ { 200 if _, ok := itemMap[strconv.Itoa(i)]; !ok { 201 println("un send---->", i) 202 } 203 } 204 cn = len(itemMap) 205 206 println("cn:", cn) 207 208 println("counter:", gCounter) 209 println("buffCounter:", gBufferSendDataInstances["default"].BufferDayCounter) 210 println("bufferIndex:", gBufferSendDataInstances["default"].BufferIndex) 211 for j := int64(0); j < gBufferSendDataInstances["default"].BufferIndex; j++ { 212 println("unSendBufferData:", string(gBufferSendDataInstances["default"].BufferData[j])) 213 } 214 215 time.Sleep(5000 * time.Millisecond) 216 println("bufferIndex:", gBufferSendDataInstances["default"].BufferIndex) 217 218 atomic.StoreUint64(&gCounter, 0) 219 itemMap = map[string]int{} 220 goto run 221 222 ch := make(chan int) 223 ch <- 1 224 //time.Sleep(10000 * time.Millisecond) 225 226 } 227 228 func getGID() uint64 { 229 b := make([]byte, 64) 230 b = b[:runtime.Stack(b, false)] 231 b = bytes.TrimPrefix(b, []byte("goroutine ")) 232 b = b[:bytes.IndexByte(b, ' ')] 233 n, _ := strconv.ParseUint(string(b), 10, 64) 234 return n 235 }