go-micro.dev/v5@v5.12.0/broker/http_test.go (about)

     1  package broker_test
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/google/uuid"
     9  	"go-micro.dev/v5/broker"
    10  	"go-micro.dev/v5/registry"
    11  )
    12  
    13  var (
    14  	// mock data.
    15  	testData = map[string][]*registry.Service{
    16  		"foo": {
    17  			{
    18  				Name:    "foo",
    19  				Version: "1.0.0",
    20  				Nodes: []*registry.Node{
    21  					{
    22  						Id:      "foo-1.0.0-123",
    23  						Address: "localhost:9999",
    24  					},
    25  					{
    26  						Id:      "foo-1.0.0-321",
    27  						Address: "localhost:9999",
    28  					},
    29  				},
    30  			},
    31  			{
    32  				Name:    "foo",
    33  				Version: "1.0.1",
    34  				Nodes: []*registry.Node{
    35  					{
    36  						Id:      "foo-1.0.1-321",
    37  						Address: "localhost:6666",
    38  					},
    39  				},
    40  			},
    41  			{
    42  				Name:    "foo",
    43  				Version: "1.0.3",
    44  				Nodes: []*registry.Node{
    45  					{
    46  						Id:      "foo-1.0.3-345",
    47  						Address: "localhost:8888",
    48  					},
    49  				},
    50  			},
    51  		},
    52  	}
    53  )
    54  
    55  func newTestRegistry() registry.Registry {
    56  	return registry.NewMemoryRegistry(registry.Services(testData))
    57  }
    58  
    59  func sub(b *testing.B, c int) {
    60  	b.StopTimer()
    61  	m := newTestRegistry()
    62  
    63  	brker := broker.NewHttpBroker(broker.Registry(m))
    64  	topic := uuid.New().String()
    65  
    66  	if err := brker.Init(); err != nil {
    67  		b.Fatalf("Unexpected init error: %v", err)
    68  	}
    69  
    70  	if err := brker.Connect(); err != nil {
    71  		b.Fatalf("Unexpected connect error: %v", err)
    72  	}
    73  
    74  	msg := &broker.Message{
    75  		Header: map[string]string{
    76  			"Content-Type": "application/json",
    77  		},
    78  		Body: []byte(`{"message": "Hello World"}`),
    79  	}
    80  
    81  	var subs []broker.Subscriber
    82  	done := make(chan bool, c)
    83  
    84  	for i := 0; i < c; i++ {
    85  		sub, err := brker.Subscribe(topic, func(p broker.Event) error {
    86  			done <- true
    87  			m := p.Message()
    88  
    89  			if string(m.Body) != string(msg.Body) {
    90  				b.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
    91  			}
    92  
    93  			return nil
    94  		}, broker.Queue("shared"))
    95  		if err != nil {
    96  			b.Fatalf("Unexpected subscribe error: %v", err)
    97  		}
    98  		subs = append(subs, sub)
    99  	}
   100  
   101  	for i := 0; i < b.N; i++ {
   102  		b.StartTimer()
   103  		if err := brker.Publish(topic, msg); err != nil {
   104  			b.Fatalf("Unexpected publish error: %v", err)
   105  		}
   106  		<-done
   107  		b.StopTimer()
   108  	}
   109  
   110  	for _, sub := range subs {
   111  		if err := sub.Unsubscribe(); err != nil {
   112  			b.Fatalf("Unexpected unsubscribe error: %v", err)
   113  		}
   114  	}
   115  
   116  	if err := brker.Disconnect(); err != nil {
   117  		b.Fatalf("Unexpected disconnect error: %v", err)
   118  	}
   119  }
   120  
   121  func pub(b *testing.B, c int) {
   122  	b.StopTimer()
   123  	m := newTestRegistry()
   124  	brk := broker.NewHttpBroker(broker.Registry(m))
   125  	topic := uuid.New().String()
   126  
   127  	if err := brk.Init(); err != nil {
   128  		b.Fatalf("Unexpected init error: %v", err)
   129  	}
   130  
   131  	if err := brk.Connect(); err != nil {
   132  		b.Fatalf("Unexpected connect error: %v", err)
   133  	}
   134  
   135  	msg := &broker.Message{
   136  		Header: map[string]string{
   137  			"Content-Type": "application/json",
   138  		},
   139  		Body: []byte(`{"message": "Hello World"}`),
   140  	}
   141  
   142  	done := make(chan bool, c*4)
   143  
   144  	sub, err := brk.Subscribe(topic, func(p broker.Event) error {
   145  		done <- true
   146  		m := p.Message()
   147  		if string(m.Body) != string(msg.Body) {
   148  			b.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
   149  		}
   150  		return nil
   151  	}, broker.Queue("shared"))
   152  	if err != nil {
   153  		b.Fatalf("Unexpected subscribe error: %v", err)
   154  	}
   155  
   156  	var wg sync.WaitGroup
   157  	ch := make(chan int, c*4)
   158  	b.StartTimer()
   159  
   160  	for i := 0; i < c; i++ {
   161  		go func() {
   162  			for range ch {
   163  				if err := brk.Publish(topic, msg); err != nil {
   164  					b.Fatalf("Unexpected publish error: %v", err)
   165  				}
   166  				select {
   167  				case <-done:
   168  				case <-time.After(time.Second):
   169  				}
   170  				wg.Done()
   171  			}
   172  		}()
   173  	}
   174  
   175  	for i := 0; i < b.N; i++ {
   176  		wg.Add(1)
   177  		ch <- i
   178  	}
   179  
   180  	wg.Wait()
   181  	b.StopTimer()
   182  	sub.Unsubscribe()
   183  	close(ch)
   184  	close(done)
   185  
   186  	if err := brk.Disconnect(); err != nil {
   187  		b.Fatalf("Unexpected disconnect error: %v", err)
   188  	}
   189  }
   190  
   191  func TestBroker(t *testing.T) {
   192  	m := newTestRegistry()
   193  	b := broker.NewHttpBroker(broker.Registry(m))
   194  
   195  	if err := b.Init(); err != nil {
   196  		t.Fatalf("Unexpected init error: %v", err)
   197  	}
   198  
   199  	if err := b.Connect(); err != nil {
   200  		t.Fatalf("Unexpected connect error: %v", err)
   201  	}
   202  
   203  	msg := &broker.Message{
   204  		Header: map[string]string{
   205  			"Content-Type": "application/json",
   206  		},
   207  		Body: []byte(`{"message": "Hello World"}`),
   208  	}
   209  
   210  	done := make(chan bool)
   211  
   212  	sub, err := b.Subscribe("test", func(p broker.Event) error {
   213  		m := p.Message()
   214  
   215  		if string(m.Body) != string(msg.Body) {
   216  			t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
   217  		}
   218  
   219  		close(done)
   220  		return nil
   221  	})
   222  	if err != nil {
   223  		t.Fatalf("Unexpected subscribe error: %v", err)
   224  	}
   225  
   226  	if err := b.Publish("test", msg); err != nil {
   227  		t.Fatalf("Unexpected publish error: %v", err)
   228  	}
   229  
   230  	<-done
   231  	if err := sub.Unsubscribe(); err != nil {
   232  		t.Fatalf("Unexpected unsubscribe error: %v", err)
   233  	}
   234  
   235  	if err := b.Disconnect(); err != nil {
   236  		t.Fatalf("Unexpected disconnect error: %v", err)
   237  	}
   238  }
   239  
   240  func TestConcurrentSubBroker(t *testing.T) {
   241  	m := newTestRegistry()
   242  	b := broker.NewHttpBroker(broker.Registry(m))
   243  
   244  	if err := b.Init(); err != nil {
   245  		t.Fatalf("Unexpected init error: %v", err)
   246  	}
   247  
   248  	if err := b.Connect(); err != nil {
   249  		t.Fatalf("Unexpected connect error: %v", err)
   250  	}
   251  
   252  	msg := &broker.Message{
   253  		Header: map[string]string{
   254  			"Content-Type": "application/json",
   255  		},
   256  		Body: []byte(`{"message": "Hello World"}`),
   257  	}
   258  
   259  	var subs []broker.Subscriber
   260  	var wg sync.WaitGroup
   261  
   262  	for i := 0; i < 10; i++ {
   263  		sub, err := b.Subscribe("test", func(p broker.Event) error {
   264  			defer wg.Done()
   265  
   266  			m := p.Message()
   267  
   268  			if string(m.Body) != string(msg.Body) {
   269  				t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
   270  			}
   271  
   272  			return nil
   273  		})
   274  		if err != nil {
   275  			t.Fatalf("Unexpected subscribe error: %v", err)
   276  		}
   277  
   278  		wg.Add(1)
   279  		subs = append(subs, sub)
   280  	}
   281  
   282  	if err := b.Publish("test", msg); err != nil {
   283  		t.Fatalf("Unexpected publish error: %v", err)
   284  	}
   285  
   286  	wg.Wait()
   287  
   288  	for _, sub := range subs {
   289  		if err := sub.Unsubscribe(); err != nil {
   290  			t.Fatalf("Unexpected unsubscribe error: %v", err)
   291  		}
   292  	}
   293  
   294  	if err := b.Disconnect(); err != nil {
   295  		t.Fatalf("Unexpected disconnect error: %v", err)
   296  	}
   297  }
   298  
   299  func TestConcurrentPubBroker(t *testing.T) {
   300  	m := newTestRegistry()
   301  	b := broker.NewHttpBroker(broker.Registry(m))
   302  
   303  	if err := b.Init(); err != nil {
   304  		t.Fatalf("Unexpected init error: %v", err)
   305  	}
   306  
   307  	if err := b.Connect(); err != nil {
   308  		t.Fatalf("Unexpected connect error: %v", err)
   309  	}
   310  
   311  	msg := &broker.Message{
   312  		Header: map[string]string{
   313  			"Content-Type": "application/json",
   314  		},
   315  		Body: []byte(`{"message": "Hello World"}`),
   316  	}
   317  
   318  	var wg sync.WaitGroup
   319  
   320  	sub, err := b.Subscribe("test", func(p broker.Event) error {
   321  		defer wg.Done()
   322  
   323  		m := p.Message()
   324  
   325  		if string(m.Body) != string(msg.Body) {
   326  			t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
   327  		}
   328  
   329  		return nil
   330  	})
   331  	if err != nil {
   332  		t.Fatalf("Unexpected subscribe error: %v", err)
   333  	}
   334  
   335  	for i := 0; i < 10; i++ {
   336  		wg.Add(1)
   337  
   338  		if err := b.Publish("test", msg); err != nil {
   339  			t.Fatalf("Unexpected publish error: %v", err)
   340  		}
   341  	}
   342  
   343  	wg.Wait()
   344  
   345  	if err := sub.Unsubscribe(); err != nil {
   346  		t.Fatalf("Unexpected unsubscribe error: %v", err)
   347  	}
   348  
   349  	if err := b.Disconnect(); err != nil {
   350  		t.Fatalf("Unexpected disconnect error: %v", err)
   351  	}
   352  }
   353  
   354  func BenchmarkSub1(b *testing.B) {
   355  	sub(b, 1)
   356  }
   357  func BenchmarkSub8(b *testing.B) {
   358  	sub(b, 8)
   359  }
   360  
   361  func BenchmarkSub32(b *testing.B) {
   362  	sub(b, 32)
   363  }
   364  
   365  func BenchmarkPub1(b *testing.B) {
   366  	pub(b, 1)
   367  }
   368  
   369  func BenchmarkPub8(b *testing.B) {
   370  	pub(b, 8)
   371  }
   372  
   373  func BenchmarkPub32(b *testing.B) {
   374  	pub(b, 32)
   375  }