Source file test/typeparam/chansimp.dir/main.go

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"./a"
     9  	"context"
    10  	"fmt"
    11  	"runtime"
    12  	"sort"
    13  	"sync"
    14  	"time"
    15  )
    16  
    17  func TestReadAll() {
    18  	c := make(chan int)
    19  	go func() {
    20  		c <- 4
    21  		c <- 2
    22  		c <- 5
    23  		close(c)
    24  	}()
    25  	got := a.ReadAll(context.Background(), c)
    26  	want := []int{4, 2, 5}
    27  	if !a.SliceEqual(got, want) {
    28  		panic(fmt.Sprintf("ReadAll returned %v, want %v", got, want))
    29  	}
    30  }
    31  
    32  func TestMerge() {
    33  	c1 := make(chan int)
    34  	c2 := make(chan int)
    35  	go func() {
    36  		c1 <- 1
    37  		c1 <- 3
    38  		c1 <- 5
    39  		close(c1)
    40  	}()
    41  	go func() {
    42  		c2 <- 2
    43  		c2 <- 4
    44  		c2 <- 6
    45  		close(c2)
    46  	}()
    47  	ctx := context.Background()
    48  	got := a.ReadAll(ctx, a.Merge(ctx, c1, c2))
    49  	sort.Ints(got)
    50  	want := []int{1, 2, 3, 4, 5, 6}
    51  	if !a.SliceEqual(got, want) {
    52  		panic(fmt.Sprintf("Merge returned %v, want %v", got, want))
    53  	}
    54  }
    55  
    56  func TestFilter() {
    57  	c := make(chan int)
    58  	go func() {
    59  		c <- 1
    60  		c <- 2
    61  		c <- 3
    62  		close(c)
    63  	}()
    64  	even := func(i int) bool { return i%2 == 0 }
    65  	ctx := context.Background()
    66  	got := a.ReadAll(ctx, a.Filter(ctx, c, even))
    67  	want := []int{2}
    68  	if !a.SliceEqual(got, want) {
    69  		panic(fmt.Sprintf("Filter returned %v, want %v", got, want))
    70  	}
    71  }
    72  
    73  func TestSink() {
    74  	c := a.Sink[int](context.Background())
    75  	after := time.NewTimer(time.Minute)
    76  	defer after.Stop()
    77  	send := func(v int) {
    78  		select {
    79  		case c <- v:
    80  		case <-after.C:
    81  			panic("timed out sending to Sink")
    82  		}
    83  	}
    84  	send(1)
    85  	send(2)
    86  	send(3)
    87  	close(c)
    88  }
    89  
    90  func TestExclusive() {
    91  	val := 0
    92  	ex := a.MakeExclusive(&val)
    93  
    94  	var wg sync.WaitGroup
    95  	f := func() {
    96  		defer wg.Done()
    97  		for i := 0; i < 10; i++ {
    98  			p := ex.Acquire()
    99  			(*p)++
   100  			ex.Release(p)
   101  		}
   102  	}
   103  
   104  	wg.Add(2)
   105  	go f()
   106  	go f()
   107  
   108  	wg.Wait()
   109  	if val != 20 {
   110  		panic(fmt.Sprintf("after Acquire/Release loop got %d, want 20", val))
   111  	}
   112  }
   113  
   114  func TestExclusiveTry() {
   115  	s := ""
   116  	ex := a.MakeExclusive(&s)
   117  	p, ok := ex.TryAcquire()
   118  	if !ok {
   119  		panic("TryAcquire failed")
   120  	}
   121  	*p = "a"
   122  
   123  	var wg sync.WaitGroup
   124  	wg.Add(1)
   125  	go func() {
   126  		defer wg.Done()
   127  		_, ok := ex.TryAcquire()
   128  		if ok {
   129  			panic(fmt.Sprintf("TryAcquire succeeded unexpectedly"))
   130  		}
   131  	}()
   132  	wg.Wait()
   133  
   134  	ex.Release(p)
   135  
   136  	p, ok = ex.TryAcquire()
   137  	if !ok {
   138  		panic(fmt.Sprintf("TryAcquire failed"))
   139  	}
   140  }
   141  
   142  func TestRanger() {
   143  	s, r := a.Ranger[int]()
   144  
   145  	ctx := context.Background()
   146  	go func() {
   147  		// Receive one value then exit.
   148  		v, ok := r.Next(ctx)
   149  		if !ok {
   150  			panic(fmt.Sprintf("did not receive any values"))
   151  		} else if v != 1 {
   152  			panic(fmt.Sprintf("received %d, want 1", v))
   153  		}
   154  	}()
   155  
   156  	c1 := make(chan bool)
   157  	c2 := make(chan bool)
   158  	go func() {
   159  		defer close(c2)
   160  		if !s.Send(ctx, 1) {
   161  			panic(fmt.Sprintf("Send failed unexpectedly"))
   162  		}
   163  		close(c1)
   164  		if s.Send(ctx, 2) {
   165  			panic(fmt.Sprintf("Send succeeded unexpectedly"))
   166  		}
   167  	}()
   168  
   169  	<-c1
   170  
   171  	// Force a garbage collection to try to get the finalizers to run.
   172  	runtime.GC()
   173  
   174  	select {
   175  	case <-c2:
   176  	case <-time.After(time.Minute):
   177  		panic("Ranger Send should have failed, but timed out")
   178  	}
   179  }
   180  
   181  func main() {
   182  	TestReadAll()
   183  	TestMerge()
   184  	TestFilter()
   185  	TestSink()
   186  	TestExclusive()
   187  	TestExclusiveTry()
   188  	TestRanger()
   189  }
   190  

View as plain text