github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/web/stream/stream_test.go (about)

     1  package stream_test
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  
     7  	"github.com/google/go-cmp/cmp"
     8  	"github.com/quickfeed/quickfeed/internal/qtest"
     9  	"github.com/quickfeed/quickfeed/web/stream"
    10  )
    11  
    12  type Data struct {
    13  	Msg string
    14  }
    15  
    16  var messages = []*Data{
    17  	{Msg: "Hello"},
    18  	{Msg: "World"},
    19  	{Msg: "Foo"},
    20  	{Msg: "Bar"},
    21  	{Msg: "Gandalf"},
    22  	{Msg: "Frodo"},
    23  	{Msg: "Bilbo"},
    24  	{Msg: "Radagast"},
    25  	{Msg: "Sauron"},
    26  	{Msg: "Gollum"},
    27  }
    28  
    29  func TestStream(t *testing.T) {
    30  	service := stream.NewService[uint64, Data]()
    31  	streams := make([]*qtest.MockStream[Data], 0)
    32  
    33  	var counter uint32
    34  	wg := sync.WaitGroup{}
    35  	for i := 1; i < 10; i++ {
    36  		stream := qtest.NewMockStream[Data](t)
    37  		stream.SetCounter(&counter)
    38  		service.Add(stream, 1)
    39  		streams = append(streams, stream)
    40  		wg.Add(1)
    41  		go func() {
    42  			defer wg.Done()
    43  			err := stream.Run()
    44  			t.Log(err)
    45  		}()
    46  		for _, data := range messages {
    47  			data := data
    48  			service.SendTo(data, 1)
    49  		}
    50  	}
    51  
    52  	service.CloseBy(1)
    53  	wg.Wait()
    54  
    55  	// A total of 90 messages should have been sent.
    56  	if counter != 90 {
    57  		t.Errorf("expected 90, got %d", counter)
    58  	}
    59  
    60  	for _, s := range streams {
    61  		msgMsp := make(map[string]int)
    62  		for _, data := range s.Messages {
    63  			msgMsp[data.Msg]++
    64  		}
    65  		t.Log(msgMsp)
    66  		if len(s.Messages) != 10 {
    67  			t.Errorf("expected 10 messages, got %d", len(s.Messages))
    68  		}
    69  		if diff := cmp.Diff(messages, s.Messages); diff != "" {
    70  			t.Errorf("expected %v, got %v: %s", messages, s.Messages, diff)
    71  		}
    72  	}
    73  }
    74  
    75  // TestStreamClose tries to send messages to a stream that is closing.
    76  // This test should be run with the -race flag, e.g.,:
    77  // % go test -v -race -run TestStreamClose -test.count 10
    78  func TestStreamClose(t *testing.T) {
    79  	service := stream.NewService[uint64, Data]()
    80  
    81  	stream := qtest.NewMockStream[Data](t)
    82  	service.Add(stream, 1)
    83  	wg := sync.WaitGroup{}
    84  	wg.Add(1)
    85  	go func() {
    86  		for i := 0; i < 1_000_000; i++ {
    87  			stream.Send(messages[i%len(messages)])
    88  		}
    89  		wg.Done()
    90  	}()
    91  	wg.Add(1)
    92  	go func() {
    93  		defer wg.Done()
    94  		_ = stream.Run()
    95  	}()
    96  	stream.Close()
    97  	wg.Wait()
    98  }