github.com/theQRL/go-zond@v0.1.1/event/multisub_test.go (about)

     1  // Copyright 2023 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package event
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  )
    23  
    24  func TestMultisub(t *testing.T) {
    25  	// Create a double subscription and ensure events propagate through
    26  	var (
    27  		feed1 Feed
    28  		feed2 Feed
    29  	)
    30  	sink1 := make(chan int, 1)
    31  	sink2 := make(chan int, 1)
    32  
    33  	sub1 := feed1.Subscribe(sink1)
    34  	sub2 := feed2.Subscribe(sink2)
    35  
    36  	sub := JoinSubscriptions(sub1, sub2)
    37  
    38  	feed1.Send(1)
    39  	select {
    40  	case n := <-sink1:
    41  		if n != 1 {
    42  			t.Errorf("sink 1 delivery mismatch: have %d, want %d", n, 1)
    43  		}
    44  	default:
    45  		t.Error("sink 1 missing delivery")
    46  	}
    47  
    48  	feed2.Send(2)
    49  	select {
    50  	case n := <-sink2:
    51  		if n != 2 {
    52  			t.Errorf("sink 2 delivery mismatch: have %d, want %d", n, 2)
    53  		}
    54  	default:
    55  		t.Error("sink 2 missing delivery")
    56  	}
    57  	// Unsubscribe and ensure no more events are delivered
    58  	sub.Unsubscribe()
    59  	select {
    60  	case <-sub.Err():
    61  	case <-time.After(50 * time.Millisecond):
    62  		t.Error("multisub didn't propagate closure")
    63  	}
    64  
    65  	feed1.Send(11)
    66  	select {
    67  	case n := <-sink1:
    68  		t.Errorf("sink 1 unexpected delivery: %d", n)
    69  	default:
    70  	}
    71  
    72  	feed2.Send(22)
    73  	select {
    74  	case n := <-sink2:
    75  		t.Errorf("sink 2 unexpected delivery: %d", n)
    76  	default:
    77  	}
    78  }
    79  
    80  func TestMutisubPartialUnsubscribe(t *testing.T) {
    81  	// Create a double subscription but terminate one half, ensuring no error
    82  	// is propagated yet up to the outer subscription
    83  	var (
    84  		feed1 Feed
    85  		feed2 Feed
    86  	)
    87  	sink1 := make(chan int, 1)
    88  	sink2 := make(chan int, 1)
    89  
    90  	sub1 := feed1.Subscribe(sink1)
    91  	sub2 := feed2.Subscribe(sink2)
    92  
    93  	sub := JoinSubscriptions(sub1, sub2)
    94  
    95  	sub1.Unsubscribe()
    96  	select {
    97  	case <-sub.Err():
    98  		t.Error("multisub propagated closure")
    99  	case <-time.After(50 * time.Millisecond):
   100  	}
   101  	// Ensure that events cross only the second feed
   102  	feed1.Send(1)
   103  	select {
   104  	case n := <-sink1:
   105  		t.Errorf("sink 1 unexpected delivery: %d", n)
   106  	default:
   107  	}
   108  
   109  	feed2.Send(2)
   110  	select {
   111  	case n := <-sink2:
   112  		if n != 2 {
   113  			t.Errorf("sink 2 delivery mismatch: have %d, want %d", n, 2)
   114  		}
   115  	default:
   116  		t.Error("sink 2 missing delivery")
   117  	}
   118  	// Unsubscribe and ensure no more events are delivered
   119  	sub.Unsubscribe()
   120  	select {
   121  	case <-sub.Err():
   122  	case <-time.After(50 * time.Millisecond):
   123  		t.Error("multisub didn't propagate closure")
   124  	}
   125  
   126  	feed1.Send(11)
   127  	select {
   128  	case n := <-sink1:
   129  		t.Errorf("sink 1 unexpected delivery: %d", n)
   130  	default:
   131  	}
   132  
   133  	feed2.Send(22)
   134  	select {
   135  	case n := <-sink2:
   136  		t.Errorf("sink 2 unexpected delivery: %d", n)
   137  	default:
   138  	}
   139  }
   140  
   141  func TestMultisubFullUnsubscribe(t *testing.T) {
   142  	// Create a double subscription and terminate the multi sub, ensuring an
   143  	// error is propagated up.
   144  	var (
   145  		feed1 Feed
   146  		feed2 Feed
   147  	)
   148  	sink1 := make(chan int, 1)
   149  	sink2 := make(chan int, 1)
   150  
   151  	sub1 := feed1.Subscribe(sink1)
   152  	sub2 := feed2.Subscribe(sink2)
   153  
   154  	sub := JoinSubscriptions(sub1, sub2)
   155  	sub.Unsubscribe()
   156  	select {
   157  	case <-sub.Err():
   158  	case <-time.After(50 * time.Millisecond):
   159  		t.Error("multisub didn't propagate closure")
   160  	}
   161  	// Ensure no more events are delivered
   162  	feed1.Send(1)
   163  	select {
   164  	case n := <-sink1:
   165  		t.Errorf("sink 1 unexpected delivery: %d", n)
   166  	default:
   167  	}
   168  
   169  	feed2.Send(2)
   170  	select {
   171  	case n := <-sink2:
   172  		t.Errorf("sink 2 unexpected delivery: %d", n)
   173  	default:
   174  	}
   175  }