gorgonia.org/gorgonia@v0.9.17/x/vm/pubsub_test.go (about)

     1  package xvm
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"sync"
     7  	"testing"
     8  
     9  	"gorgonia.org/gorgonia"
    10  )
    11  
    12  func Test_merge(t *testing.T) {
    13  	fortyTwo := gorgonia.F32(42.0)
    14  	fortyThree := gorgonia.F32(43.0)
    15  	t.Run("context cancel without value", func(t *testing.T) {
    16  		var wg sync.WaitGroup
    17  		wg.Add(1)
    18  		ctx, cancel := context.WithCancel(context.Background())
    19  		c := make(<-chan gorgonia.Value, 0)
    20  		output := make(chan ioValue, 0)
    21  		merge(ctx, &wg, output, c)
    22  		cancel()
    23  		//<-output
    24  	})
    25  	t.Run("context cancel with one value", func(t *testing.T) {
    26  		var wg sync.WaitGroup
    27  		wg.Add(1)
    28  		ctx, cancel := context.WithCancel(context.Background())
    29  		c := make(chan gorgonia.Value, 1)
    30  		output := make(chan ioValue, 0)
    31  		merge(ctx, &wg, output, c)
    32  		c <- &fortyTwo
    33  		out := <-output
    34  		if !reflect.DeepEqual(fortyTwo.Data(), out.v.Data()) {
    35  			t.Errorf("Expected %v, got %v", fortyTwo, out)
    36  		}
    37  		c <- &fortyTwo
    38  		cancel()
    39  	})
    40  	t.Run("with one value", func(t *testing.T) {
    41  		var wg sync.WaitGroup
    42  		wg.Add(1)
    43  		ctx := context.Background()
    44  		c := make(chan gorgonia.Value, 1)
    45  		output := make(chan ioValue, 0)
    46  		merge(ctx, &wg, output, c)
    47  		c <- &fortyTwo
    48  		out := <-output
    49  		if !reflect.DeepEqual(fortyTwo.Data(), out.v.Data()) {
    50  			t.Errorf("Expected %v, got %v", fortyTwo, out)
    51  		}
    52  	})
    53  	t.Run("2 channels with two values", func(t *testing.T) {
    54  		var wg sync.WaitGroup
    55  		wg.Add(1)
    56  		ctx := context.Background()
    57  		lenChan := 2
    58  		// The size of the channels buffer controls how far behind the receivers
    59  		// of the fanOut channels can lag the other channels.
    60  		c0 := make(chan gorgonia.Value, 0)
    61  		c1 := make(chan gorgonia.Value, 0)
    62  		output := make(chan ioValue, 0)
    63  		merge(ctx, &wg, output, c0, c1)
    64  		c1 <- &fortyThree
    65  		c0 <- &fortyTwo
    66  		missFortyTwo := true
    67  		missFortyThree := true
    68  		for i := 0; i < lenChan; i++ {
    69  			out := <-output
    70  			switch {
    71  			case out.pos == 0 && out.v.Data().(float32) == 42.0:
    72  				missFortyTwo = false
    73  			case out.pos == 1 && out.v.Data().(float32) == 43.0:
    74  				missFortyThree = false
    75  			default:
    76  				t.Errorf("bad conbination %v/%v", out.pos, out.v.Data())
    77  			}
    78  		}
    79  		if missFortyThree || missFortyTwo {
    80  			t.Error("Missing value")
    81  		}
    82  	})
    83  }
    84  
    85  func Test_broadcast(t *testing.T) {
    86  	t.Run("context cancel without value", func(t *testing.T) {
    87  		var wg sync.WaitGroup
    88  		wg.Add(1)
    89  		ctx, cancel := context.WithCancel(context.Background())
    90  		// The size of the channels buffer controls how far behind the receivers
    91  		// of the fanOut channels can lag the other channels.
    92  		cs := make(chan gorgonia.Value, 0)
    93  		c := make(<-chan gorgonia.Value, 0)
    94  		go broadcast(ctx, &wg, c, cs)
    95  		cancel()
    96  	})
    97  	t.Run("context cancel without value", func(t *testing.T) {
    98  		var wg sync.WaitGroup
    99  		wg.Add(1)
   100  		ctx, cancel := context.WithCancel(context.Background())
   101  		cs := make(chan gorgonia.Value, 0)
   102  		c := make(chan gorgonia.Value, 0)
   103  		go broadcast(ctx, &wg, c, cs)
   104  		c <- nil
   105  		cancel()
   106  	})
   107  	t.Run("broadcast ", func(t *testing.T) {
   108  		var wg sync.WaitGroup
   109  		wg.Add(1)
   110  		fortyTwo := gorgonia.F32(42.0)
   111  		ctx := context.Background()
   112  		// The size of the channels buffer controls how far behind the receivers
   113  		// of the fanOut channels can lag the other channels.
   114  		cs0 := make(chan gorgonia.Value, 0)
   115  		cs1 := make(chan gorgonia.Value, 0)
   116  		c := make(chan gorgonia.Value, 0)
   117  		go broadcast(ctx, &wg, c, cs0, cs1)
   118  		c <- &fortyTwo
   119  		v0 := <-cs0
   120  		v1 := <-cs1
   121  		if !reflect.DeepEqual(v0, &fortyTwo) {
   122  			t.Errorf("broadcast want %v, got %v", &fortyTwo, v0)
   123  		}
   124  		if !reflect.DeepEqual(v1, &fortyTwo) {
   125  			t.Errorf("broadcast want %v, got %v", &fortyTwo, v1)
   126  		}
   127  	})
   128  }
   129  
   130  func Test_pubsub_run(t *testing.T) {
   131  	i0 := make(chan gorgonia.Value, 0)
   132  	m0 := make(chan gorgonia.Value, 0)
   133  	m1 := make(chan gorgonia.Value, 0)
   134  	o0 := make(chan ioValue, 0)
   135  	type fields struct {
   136  		publishers  []*publisher
   137  		subscribers []*subscriber
   138  	}
   139  	type args struct {
   140  		ctx context.Context
   141  	}
   142  	tests := []struct {
   143  		name   string
   144  		fields fields
   145  		args   args
   146  	}{
   147  		{
   148  			"i0 -> m0 ; i0 -> m1; m0 -> o0; m1 -> o0",
   149  			fields{
   150  				publishers: []*publisher{
   151  					{
   152  						publisher: i0,
   153  						subscribers: []chan<- gorgonia.Value{
   154  							m0, m1,
   155  						},
   156  					},
   157  				},
   158  				subscribers: []*subscriber{
   159  					{
   160  						publishers: []<-chan gorgonia.Value{
   161  							m0, m1,
   162  						},
   163  						subscriber: o0,
   164  					},
   165  				},
   166  			},
   167  			args{
   168  				context.TODO(),
   169  			},
   170  		},
   171  	}
   172  	for _, tt := range tests {
   173  		t.Run(tt.name, func(t *testing.T) {
   174  			p := &pubsub{
   175  				publishers:  tt.fields.publishers,
   176  				subscribers: tt.fields.subscribers,
   177  			}
   178  			fortyTwo := gorgonia.F32(42.0)
   179  			cancel, _ := p.run(tt.args.ctx)
   180  			i0 <- &fortyTwo
   181  			v1 := <-o0
   182  			v2 := <-o0
   183  			if v1.v.Data().(float32) != 42 {
   184  				t.Fail()
   185  			}
   186  			if v2.v.Data().(float32) != 42 {
   187  				t.Fail()
   188  			}
   189  			if v2.pos+v1.pos != 1 {
   190  				t.Fail()
   191  			}
   192  			//wg.Wait()
   193  
   194  			cancel()
   195  		})
   196  	}
   197  }