package kwg import ( "context" "testing" "time" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/alias" . "gitp78su.ipnodns.ru/svi/kern/v4/lev0/ktypes" ) type tester struct { t *testing.T ctx context.Context fnCancel func() wg IKernelWg } func TestKernelWG(t *testing.T) { ctxBg := context.Background() ctx, fnCancel := context.WithCancel(ctxBg) defer fnCancel() sf := &tester{ t: t, ctx: ctx, fnCancel: fnCancel, } sf.new() sf.add() sf.done() sf.wait() sf.addBad3() } var ( qName = alias.NewAStreamName("test_stream") ) // Попытка добавления после закрытия ожидателя. func (sf *tester) addBad3() { sf.t.Log("addBad3") sf.wg.Add(qName) _len := sf.wg.Len() if _len != 0 { sf.t.Fatalf("addBad3(): len(%v)!=0", _len) } sf.fnCancel() kernWg.close() } // Убирает имя потока из ожидателя. func (sf *tester) done() { sf.t.Log("done") sf.wg.Done(qName) lst := sf.wg.List() if len(lst) != 0 { sf.t.Fatalf("addBad1(): len(lst)!=0, lst=%#v", lst) } } // Добавление потока ожидания. func (sf *tester) add() { sf.t.Log("add") sf.addGood1() sf.addBad2() } // Уже есть такое имя потока. func (sf *tester) addBad2() { sf.t.Log("addBad2") defer func() { if _panic := recover(); _panic == nil { sf.t.Fatalf("addBad1(): panic==nil") } lst := sf.wg.List() if len(lst) != 1 { sf.t.Fatalf("addBad1(): len(lst)!=1, lst=%#v", lst) } }() sf.wg.Add(qName) } func (sf *tester) addGood1() { sf.t.Log("addGood1") sf.wg.Add(qName) } // Ожидание завершения ожидателя потоков. func (sf *tester) wait() { sf.t.Log("wait") go sf.wg.Wait() time.Sleep(time.Millisecond * 5) sf.fnCancel() for { time.Sleep(time.Millisecond * 10) if !sf.wg.IsWork() { break } } } // Создаёт ожидатель потоков ядра. func (sf *tester) new() { sf.t.Log("new") sf.newBad1() sf.newGood1() } func (sf *tester) newGood1() { sf.t.Log("newGood1") defer func() { if _panic := recover(); _panic != nil { sf.t.Fatalf("newGood1(): panic=%v", _panic) } }() sf.wg = GetKernelWg(sf.ctx) if sf.wg == nil { sf.t.Fatalf("newGood1(): KernelWg==nil") } if !sf.wg.IsWork() { sf.t.Fatalf("wait(): isWork==false") } wg := GetKernelWg(sf.ctx) if sf.wg != wg { sf.t.Fatalf("newGood1(): bad IKernelWg") } if log := sf.wg.Log(); log == nil { sf.t.Fatalf("newGood1(): log==nil") } } // Нет контекста ядра. func (sf *tester) newBad1() { sf.t.Log("newBad1") defer func() { if _panic := recover(); _panic == nil { sf.t.Fatalf("newBad1(): panic=nil") } }() // defer sf.panicUse("newBad1(): ") var ctx context.Context _ = GetKernelWg(ctx) }