go-hep.org/x/hep@v0.38.1/xrootd/internal/mux/mux_test.go (about)

     1  // Copyright ©2018 The go-hep 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 mux // import "go-hep.org/x/hep/xrootd/internal/mux"
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"testing"
    11  
    12  	"go-hep.org/x/hep/xrootd/xrdproto"
    13  )
    14  
    15  func TestMux_Claim(t *testing.T) {
    16  	m := New()
    17  	defer m.Close()
    18  	claimedIds := map[xrdproto.StreamID]bool{}
    19  
    20  	for range streamIDPoolSize {
    21  		id, channel, err := m.Claim()
    22  
    23  		if err != nil {
    24  			t.Fatalf("could not Claim streamID: %v", err)
    25  		}
    26  
    27  		if channel == nil {
    28  			t.Fatal("channel should not be nil")
    29  		}
    30  
    31  		if claimedIds[id] {
    32  			t.Fatalf("should not claim id %s, which was already claimed", id)
    33  		}
    34  
    35  		claimedIds[id] = true
    36  	}
    37  
    38  	for id := range claimedIds {
    39  		m.Unclaim(id)
    40  	}
    41  }
    42  
    43  func TestMux_Claim_AfterUnclaim(t *testing.T) {
    44  	m := New()
    45  	defer m.Close()
    46  	claimedIds := map[xrdproto.StreamID]bool{}
    47  
    48  	for range streamIDPoolSize {
    49  		id, _, _ := m.Claim()
    50  		claimedIds[id] = true
    51  	}
    52  
    53  	wantID := xrdproto.StreamID{13, 14}
    54  	m.Unclaim(wantID)
    55  
    56  	gotID, channel, err := m.Claim()
    57  
    58  	if err != nil {
    59  		t.Fatalf("could not Claim streamID: %v", err)
    60  	}
    61  
    62  	if channel == nil {
    63  		t.Fatal("channel should not be nil")
    64  	}
    65  
    66  	if !reflect.DeepEqual(gotID, wantID) {
    67  		t.Fatalf("invalid claim\ngot = %v\nwant = %v", gotID, wantID)
    68  	}
    69  
    70  	for id := range claimedIds {
    71  		m.Unclaim(id)
    72  	}
    73  }
    74  
    75  func TestMux_ClaimWithID_WhenIDIsFree(t *testing.T) {
    76  	m := New()
    77  	defer m.Close()
    78  
    79  	streamID := xrdproto.StreamID{13, 14}
    80  	channel, err := m.ClaimWithID(streamID)
    81  
    82  	if err != nil {
    83  		t.Fatalf("could not Claim streamID: %v", err)
    84  	}
    85  
    86  	if channel == nil {
    87  		t.Fatal("channel should not be nil")
    88  	}
    89  
    90  	m.Unclaim(streamID)
    91  }
    92  
    93  func TestMux_ClaimWithID_WhenIDIsTakenByClaimWithID(t *testing.T) {
    94  	m := New()
    95  	defer m.Close()
    96  	streamID := xrdproto.StreamID{13, 14}
    97  	_, err := m.ClaimWithID(streamID)
    98  	if err != nil {
    99  		t.Fatalf("could not claim stream %v: %+v", streamID, err)
   100  	}
   101  
   102  	_, err = m.ClaimWithID(streamID)
   103  	if err == nil {
   104  		t.Fatal("should not be able to ClaimWithID when that id is already claimed")
   105  	}
   106  
   107  	m.Unclaim(streamID)
   108  }
   109  
   110  func TestMux_ClaimWithID_WhenIDIsTakenByClaim(t *testing.T) {
   111  	m := New()
   112  	defer m.Close()
   113  	id, _, _ := m.Claim()
   114  
   115  	_, err := m.ClaimWithID(id)
   116  
   117  	if err == nil {
   118  		t.Fatal("should not be able to ClaimWithID when that id is already claimed")
   119  	}
   120  
   121  	m.Unclaim(id)
   122  }
   123  
   124  func TestMux_Claim_WhenIDIsTakenByClaimWithID(t *testing.T) {
   125  	m := New()
   126  	defer m.Close()
   127  	takenID := xrdproto.StreamID{0, 0}
   128  	_, err := m.ClaimWithID(takenID)
   129  	if err != nil {
   130  		t.Fatalf("could not claim stream %v: %+v", takenID, err)
   131  	}
   132  
   133  	id, channel, err := m.Claim()
   134  
   135  	if err != nil {
   136  		t.Fatalf("could not Claim streamID: %v", err)
   137  	}
   138  
   139  	if channel == nil {
   140  		t.Fatal("channel should not be nil")
   141  	}
   142  
   143  	if reflect.DeepEqual(id, takenID) {
   144  		t.Fatalf("invalid claim: id %v was already taken", takenID)
   145  	}
   146  
   147  	m.Unclaim(takenID)
   148  	m.Unclaim(id)
   149  }
   150  
   151  func TestMux_SendData_WhenIDIsTaken(t *testing.T) {
   152  	m := New()
   153  	defer m.Close()
   154  	takenID := xrdproto.StreamID{0, 0}
   155  	want := ServerResponse{}
   156  	var got ServerResponse
   157  
   158  	errch := make(chan error)
   159  	channel, _ := m.ClaimWithID(takenID)
   160  	go func() {
   161  		err := m.SendData(takenID, want)
   162  		if err != nil {
   163  			errch <- fmt.Errorf("could not SendData: %w", err)
   164  		}
   165  	}()
   166  
   167  	select {
   168  	case got = <-channel:
   169  	case err := <-errch:
   170  		if err != nil {
   171  			t.Fatalf("error: %+v", err)
   172  		}
   173  	}
   174  	if !reflect.DeepEqual(got, want) {
   175  		t.Fatalf("invalid data\ngot = %v\nwant = %v", got, want)
   176  	}
   177  
   178  	m.Unclaim(takenID)
   179  }
   180  
   181  func TestMux_SendData_WhenIDIsNotTaken(t *testing.T) {
   182  	m := New()
   183  	defer m.Close()
   184  	notTakenID := xrdproto.StreamID{0, 0}
   185  
   186  	err := m.SendData(notTakenID, ServerResponse{})
   187  
   188  	if err == nil {
   189  		t.Fatal("should not be able to SenData when id is unclaimed")
   190  	}
   191  }
   192  
   193  func TestMux_Close_WhenAlreadyClosed(t *testing.T) {
   194  	m := New()
   195  	m.Close()
   196  	m.Close()
   197  }
   198  
   199  func TestMux_Unclaim_WhenNotClaimed(t *testing.T) {
   200  	m := New()
   201  	defer m.Close()
   202  	m.Unclaim(xrdproto.StreamID{0, 0})
   203  }
   204  
   205  func TestMux_Claim_WhenClosed(t *testing.T) {
   206  	m := New()
   207  	m.Close()
   208  	_, _, err := m.Claim()
   209  	if err == nil {
   210  		t.Fatal("should not be able to Claim when mux is closed")
   211  	}
   212  }
   213  
   214  func TestMux_ClaimWithID_WhenClosed(t *testing.T) {
   215  	m := New()
   216  	m.Close()
   217  	_, err := m.ClaimWithID(xrdproto.StreamID{0, 0})
   218  	if err == nil {
   219  		t.Fatal("should not be able to ClaimWithID when mux is closed")
   220  	}
   221  }
   222  
   223  func BenchmarkMux_Claim(b *testing.B) {
   224  	m := New()
   225  	defer m.Close()
   226  
   227  	b.ResetTimer()
   228  	for i := 0; i < b.N; i++ {
   229  		id, _, err := m.Claim()
   230  		if err != nil {
   231  			b.Error(err)
   232  		}
   233  		m.Unclaim(id)
   234  	}
   235  }
   236  
   237  func BenchmarkMux_SendData(b *testing.B) {
   238  	m := New()
   239  	defer m.Close()
   240  	id, ch, _ := m.Claim()
   241  	done := make(chan struct{})
   242  	response := ServerResponse{Data: []byte{0, 1, 2, 3, 4, 5}}
   243  
   244  	go func() {
   245  		for {
   246  			select {
   247  			case <-ch:
   248  			case <-done:
   249  				return
   250  			}
   251  		}
   252  	}()
   253  
   254  	b.ResetTimer()
   255  	for i := 0; i < b.N; i++ {
   256  		err := m.SendData(id, response)
   257  		if err != nil {
   258  			b.Error(err)
   259  		}
   260  	}
   261  
   262  	m.Unclaim(id)
   263  	close(done)
   264  }