go-micro.dev/v5@v5.12.0/transport/http_transport_test.go (about)

     1  package transport
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"net"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  )
    11  
    12  func expectedPort(t *testing.T, expected string, lsn Listener) {
    13  	_, port, err := net.SplitHostPort(lsn.Addr())
    14  	if err != nil {
    15  		t.Errorf("Expected address to be `%s`, got error: %v", expected, err)
    16  	}
    17  
    18  	if port != expected {
    19  		lsn.Close()
    20  		t.Errorf("Expected address to be `%s`, got `%s`", expected, port)
    21  	}
    22  }
    23  
    24  func TestHTTPTransportCommunication(t *testing.T) {
    25  	tr := NewHTTPTransport()
    26  
    27  	l, err := tr.Listen("127.0.0.1:0")
    28  	if err != nil {
    29  		t.Errorf("Unexpected listen err: %v", err)
    30  	}
    31  	defer l.Close()
    32  
    33  	fn := func(sock Socket) {
    34  		defer sock.Close()
    35  
    36  		for {
    37  			var m Message
    38  			if err := sock.Recv(&m); err != nil {
    39  				return
    40  			}
    41  
    42  			if err := sock.Send(&m); err != nil {
    43  				return
    44  			}
    45  		}
    46  	}
    47  
    48  	done := make(chan bool)
    49  
    50  	go func() {
    51  		if err := l.Accept(fn); err != nil {
    52  			select {
    53  			case <-done:
    54  			default:
    55  				t.Errorf("Unexpected accept err: %v", err)
    56  			}
    57  		}
    58  	}()
    59  
    60  	c, err := tr.Dial(l.Addr())
    61  	if err != nil {
    62  		t.Errorf("Unexpected dial err: %v", err)
    63  	}
    64  	defer c.Close()
    65  
    66  	m := Message{
    67  		Header: map[string]string{
    68  			"Content-Type": "application/json",
    69  		},
    70  		Body: []byte(`{"message": "Hello World"}`),
    71  	}
    72  
    73  	if err := c.Send(&m); err != nil {
    74  		t.Errorf("Unexpected send err: %v", err)
    75  	}
    76  
    77  	var rm Message
    78  
    79  	if err := c.Recv(&rm); err != nil {
    80  		t.Errorf("Unexpected recv err: %v", err)
    81  	}
    82  
    83  	if string(rm.Body) != string(m.Body) {
    84  		t.Errorf("Expected %v, got %v", m.Body, rm.Body)
    85  	}
    86  
    87  	close(done)
    88  }
    89  
    90  func TestHTTPTransportError(t *testing.T) {
    91  	tr := NewHTTPTransport()
    92  
    93  	l, err := tr.Listen("127.0.0.1:0")
    94  	if err != nil {
    95  		t.Errorf("Unexpected listen err: %v", err)
    96  	}
    97  	defer l.Close()
    98  
    99  	fn := func(sock Socket) {
   100  		defer sock.Close()
   101  
   102  		for {
   103  			var m Message
   104  			if err := sock.Recv(&m); err != nil {
   105  				if errors.Is(err, io.EOF) {
   106  					return
   107  				}
   108  				t.Fatal(err)
   109  			}
   110  
   111  			sock.(*httpTransportSocket).error(&Message{
   112  				Body: []byte(`an error occurred`),
   113  			})
   114  		}
   115  	}
   116  
   117  	done := make(chan bool)
   118  
   119  	go func() {
   120  		if err := l.Accept(fn); err != nil {
   121  			select {
   122  			case <-done:
   123  			default:
   124  				t.Errorf("Unexpected accept err: %v", err)
   125  			}
   126  		}
   127  	}()
   128  
   129  	c, err := tr.Dial(l.Addr())
   130  	if err != nil {
   131  		t.Errorf("Unexpected dial err: %v", err)
   132  	}
   133  	defer c.Close()
   134  
   135  	m := Message{
   136  		Header: map[string]string{
   137  			"Content-Type": "application/json",
   138  		},
   139  		Body: []byte(`{"message": "Hello World"}`),
   140  	}
   141  
   142  	if err := c.Send(&m); err != nil {
   143  		t.Errorf("Unexpected send err: %v", err)
   144  	}
   145  
   146  	var rm Message
   147  
   148  	err = c.Recv(&rm)
   149  	if err == nil {
   150  		t.Fatal("Expected error but got nil")
   151  	}
   152  
   153  	if err.Error() != "500 Internal Server Error: an error occurred" {
   154  		t.Fatalf("Did not receive expected error, got: %v", err)
   155  	}
   156  
   157  	close(done)
   158  }
   159  
   160  func TestHTTPTransportTimeout(t *testing.T) {
   161  	tr := NewHTTPTransport(Timeout(time.Millisecond * 100))
   162  
   163  	l, err := tr.Listen("127.0.0.1:0")
   164  	if err != nil {
   165  		t.Errorf("Unexpected listen err: %v", err)
   166  	}
   167  	defer l.Close()
   168  
   169  	done := make(chan bool)
   170  
   171  	fn := func(sock Socket) {
   172  		defer func() {
   173  			sock.Close()
   174  			close(done)
   175  		}()
   176  
   177  		go func() {
   178  			select {
   179  			case <-done:
   180  				return
   181  			case <-time.After(time.Second):
   182  				t.Fatal("deadline not executed")
   183  			}
   184  		}()
   185  
   186  		for {
   187  			var m Message
   188  
   189  			if err := sock.Recv(&m); err != nil {
   190  				return
   191  			}
   192  		}
   193  	}
   194  
   195  	go func() {
   196  		if err := l.Accept(fn); err != nil {
   197  			select {
   198  			case <-done:
   199  			default:
   200  				t.Errorf("Unexpected accept err: %v", err)
   201  			}
   202  		}
   203  	}()
   204  
   205  	c, err := tr.Dial(l.Addr())
   206  	if err != nil {
   207  		t.Errorf("Unexpected dial err: %v", err)
   208  	}
   209  	defer c.Close()
   210  
   211  	m := Message{
   212  		Header: map[string]string{
   213  			"Content-Type": "application/json",
   214  		},
   215  		Body: []byte(`{"message": "Hello World"}`),
   216  	}
   217  
   218  	if err := c.Send(&m); err != nil {
   219  		t.Errorf("Unexpected send err: %v", err)
   220  	}
   221  
   222  	<-done
   223  }
   224  
   225  func TestHTTPTransportCloseWhenRecv(t *testing.T) {
   226  	tr := NewHTTPTransport()
   227  
   228  	l, err := tr.Listen("127.0.0.1:0")
   229  	if err != nil {
   230  		t.Errorf("Unexpected listen err: %v", err)
   231  	}
   232  	defer l.Close()
   233  
   234  	fn := func(sock Socket) {
   235  		defer sock.Close()
   236  
   237  		for {
   238  			var m Message
   239  			if err := sock.Recv(&m); err != nil {
   240  				return
   241  			}
   242  			if err := sock.Send(&m); err != nil {
   243  				return
   244  			}
   245  		}
   246  	}
   247  
   248  	done := make(chan bool)
   249  
   250  	go func() {
   251  		if err := l.Accept(fn); err != nil {
   252  			select {
   253  			case <-done:
   254  			default:
   255  				t.Errorf("Unexpected accept err: %v", err)
   256  			}
   257  		}
   258  	}()
   259  
   260  	c, err := tr.Dial(l.Addr())
   261  	if err != nil {
   262  		t.Errorf("Unexpected dial err: %v", err)
   263  	}
   264  	defer c.Close()
   265  
   266  	m := Message{
   267  		Header: map[string]string{
   268  			"Content-Type": "application/json",
   269  		},
   270  		Body: []byte(`{"message": "Hello World"}`),
   271  	}
   272  	var wg sync.WaitGroup
   273  	wg.Add(1)
   274  	go func() {
   275  		defer wg.Done()
   276  		for {
   277  			var rm Message
   278  
   279  			if err := c.Recv(&rm); err != nil {
   280  				if err == io.EOF {
   281  					return
   282  				}
   283  			}
   284  		}
   285  	}()
   286  	for i := 1; i < 3; i++ {
   287  		if err := c.Send(&m); err != nil {
   288  			t.Errorf("Unexpected send err: %v", err)
   289  		}
   290  	}
   291  	close(done)
   292  
   293  	c.Close()
   294  	wg.Wait()
   295  }
   296  
   297  func TestHTTPTransportMultipleSendWhenRecv(t *testing.T) {
   298  	tr := NewHTTPTransport()
   299  
   300  	l, err := tr.Listen("127.0.0.1:0")
   301  	if err != nil {
   302  		t.Errorf("Unexpected listen err: %v", err)
   303  	}
   304  	defer l.Close()
   305  
   306  	readyToSend := make(chan struct{})
   307  	m := Message{
   308  		Header: map[string]string{
   309  			"Content-Type": "application/json",
   310  		},
   311  		Body: []byte(`{"message": "Hello World"}`),
   312  	}
   313  
   314  	var wgSend sync.WaitGroup
   315  	fn := func(sock Socket) {
   316  		defer sock.Close()
   317  
   318  		for {
   319  			var mr Message
   320  			if err := sock.Recv(&mr); err != nil {
   321  				return
   322  			}
   323  			go func() {
   324  				defer wgSend.Done()
   325  				<-readyToSend
   326  				if err := sock.Send(&m); err != nil {
   327  					return
   328  				}
   329  			}()
   330  		}
   331  	}
   332  
   333  	done := make(chan bool)
   334  
   335  	go func() {
   336  		if err := l.Accept(fn); err != nil {
   337  			select {
   338  			case <-done:
   339  			default:
   340  				t.Errorf("Unexpected accept err: %v", err)
   341  			}
   342  		}
   343  	}()
   344  
   345  	c, err := tr.Dial(l.Addr(), WithStream())
   346  	if err != nil {
   347  		t.Errorf("Unexpected dial err: %v", err)
   348  	}
   349  	defer c.Close()
   350  
   351  	var wg sync.WaitGroup
   352  	wg.Add(1)
   353  	readyForRecv := make(chan struct{})
   354  	go func() {
   355  		defer wg.Done()
   356  		close(readyForRecv)
   357  		for {
   358  			var rm Message
   359  			if err := c.Recv(&rm); err != nil {
   360  				if err == io.EOF {
   361  					return
   362  				}
   363  			}
   364  		}
   365  	}()
   366  	wgSend.Add(3)
   367  	<-readyForRecv
   368  	for i := 0; i < 3; i++ {
   369  		if err := c.Send(&m); err != nil {
   370  			t.Errorf("Unexpected send err: %v", err)
   371  		}
   372  	}
   373  	close(readyToSend)
   374  	wgSend.Wait()
   375  	close(done)
   376  
   377  	c.Close()
   378  	wg.Wait()
   379  }
   380  
   381  func TestHttpTransportListenerNetListener(t *testing.T) {
   382  	address := "127.0.0.1:0"
   383  
   384  	customListener, err := net.Listen("tcp", address)
   385  	if err != nil {
   386  		return
   387  	}
   388  
   389  	tr := NewHTTPTransport(Timeout(time.Millisecond * 100))
   390  
   391  	// injection
   392  	l, err := tr.Listen(address, NetListener(customListener))
   393  	if err != nil {
   394  		t.Errorf("Unexpected listen err: %v", err)
   395  	}
   396  	defer l.Close()
   397  
   398  	done := make(chan bool)
   399  
   400  	fn := func(sock Socket) {
   401  		defer func() {
   402  			sock.Close()
   403  			close(done)
   404  		}()
   405  
   406  		go func() {
   407  			select {
   408  			case <-done:
   409  				return
   410  			case <-time.After(time.Second):
   411  				t.Fatal("deadline not executed")
   412  			}
   413  		}()
   414  
   415  		for {
   416  			var m Message
   417  
   418  			if err := sock.Recv(&m); err != nil {
   419  				return
   420  			}
   421  		}
   422  	}
   423  
   424  	go func() {
   425  		if err := l.Accept(fn); err != nil {
   426  			select {
   427  			case <-done:
   428  			default:
   429  				t.Errorf("Unexpected accept err: %v", err)
   430  			}
   431  		}
   432  	}()
   433  
   434  	c, err := tr.Dial(l.Addr())
   435  	if err != nil {
   436  		t.Errorf("Unexpected dial err: %v", err)
   437  	}
   438  	defer c.Close()
   439  
   440  	m := Message{
   441  		Header: map[string]string{
   442  			"Content-Type": "application/json",
   443  		},
   444  		Body: []byte(`{"message": "Hello World"}`),
   445  	}
   446  
   447  	if err := c.Send(&m); err != nil {
   448  		t.Errorf("Unexpected send err: %v", err)
   449  	}
   450  
   451  	<-done
   452  }