github.com/vmware/transport-go@v1.3.4/service/fabric_core_test.go (about)

     1  // Copyright 2019-2020 VMware, Inc.
     2  // SPDX-License-Identifier: BSD-2-Clause
     3  
     4  package service
     5  
     6  import (
     7  	"errors"
     8  	"github.com/google/uuid"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/vmware/transport-go/bus"
    11  	"github.com/vmware/transport-go/model"
    12  	"sync"
    13  	"testing"
    14  )
    15  
    16  func newTestFabricCore(channelName string) FabricServiceCore {
    17  	eventBus := bus.NewEventBusInstance()
    18  	eventBus.GetChannelManager().CreateChannel(channelName)
    19  	return &fabricCore{
    20  		channelName: channelName,
    21  		bus:         eventBus,
    22  	}
    23  }
    24  
    25  func TestFabricCore_Bus(t *testing.T) {
    26  	core := newTestFabricCore("test-channel")
    27  	assert.NotNil(t, core.Bus())
    28  }
    29  
    30  func TestFabricCore_SendMethods(t *testing.T) {
    31  	core := newTestFabricCore("test-channel")
    32  
    33  	mh, _ := core.Bus().ListenStream("test-channel")
    34  
    35  	wg := sync.WaitGroup{}
    36  
    37  	var count = 0
    38  	var lastMessage *model.Message
    39  
    40  	mh.Handle(func(message *model.Message) {
    41  		count++
    42  		lastMessage = message
    43  		wg.Done()
    44  	}, func(e error) {
    45  		assert.Fail(t, "unexpected error")
    46  	})
    47  
    48  	id := uuid.New()
    49  	req := model.Request{
    50  		Id:      &id,
    51  		Request: "test-request",
    52  		BrokerDestination: &model.BrokerDestinationConfig{
    53  			Destination: "test",
    54  		},
    55  	}
    56  
    57  	wg.Add(1)
    58  	core.SendResponse(&req, "test-response")
    59  	wg.Wait()
    60  
    61  	assert.Equal(t, count, 1)
    62  
    63  	response, ok := lastMessage.Payload.(*model.Response)
    64  	assert.True(t, ok)
    65  	assert.Equal(t, response.Id, req.Id)
    66  	assert.Equal(t, response.Payload, "test-response")
    67  	assert.False(t, response.Error)
    68  	assert.Equal(t, response.BrokerDestination.Destination, "test")
    69  
    70  	wg.Add(1)
    71  	h := make(map[string]string)
    72  	h["hello"] = "there"
    73  	core.SendResponseWithHeaders(&req, "test-response-with-headers", h)
    74  	wg.Wait()
    75  
    76  	assert.Equal(t, count, 2)
    77  
    78  	response, ok = lastMessage.Payload.(*model.Response)
    79  	assert.True(t, ok)
    80  	assert.Equal(t, response.Id, req.Id)
    81  	assert.Equal(t, response.Payload, "test-response-with-headers")
    82  	assert.False(t, response.Error)
    83  	assert.Equal(t, response.BrokerDestination.Destination, "test")
    84  	assert.Equal(t, response.Headers["hello"], "there")
    85  
    86  	wg.Add(1)
    87  	core.SendErrorResponse(&req, 404, "test-error")
    88  	wg.Wait()
    89  
    90  	assert.Equal(t, count, 3)
    91  	response = lastMessage.Payload.(*model.Response)
    92  
    93  	assert.Equal(t, response.Id, req.Id)
    94  	assert.Nil(t, response.Payload)
    95  	assert.True(t, response.Error)
    96  	assert.Equal(t, response.ErrorCode, 404)
    97  	assert.Equal(t, response.ErrorMessage, "test-error")
    98  
    99  	wg.Add(1)
   100  
   101  	h = make(map[string]string)
   102  	h["chicken"] = "nugget"
   103  	core.SendErrorResponseWithHeaders(&req, 422, "test-header-error", h)
   104  	wg.Wait()
   105  
   106  	assert.Equal(t, count, 4)
   107  	response = lastMessage.Payload.(*model.Response)
   108  
   109  	assert.Equal(t, response.Id, req.Id)
   110  	assert.Equal(t, response.Headers["chicken"], "nugget")
   111  	assert.Nil(t, response.Payload)
   112  	assert.True(t, response.Error)
   113  	assert.Equal(t, response.ErrorCode, 422)
   114  	assert.Equal(t, response.ErrorMessage, "test-header-error")
   115  
   116  	wg.Add(1)
   117  
   118  	h = make(map[string]string)
   119  	h["potato"] = "dog"
   120  	core.SendErrorResponseWithHeadersAndPayload(&req, 500, "test-header-payload-error", "oh my!", h)
   121  	wg.Wait()
   122  
   123  	assert.Equal(t, count, 5)
   124  	response = lastMessage.Payload.(*model.Response)
   125  
   126  	assert.Equal(t, response.Id, req.Id)
   127  	assert.Equal(t, "dog", response.Headers["potato"])
   128  	assert.Equal(t, "oh my!", response.Payload.(string))
   129  	assert.True(t, response.Error)
   130  	assert.Equal(t, response.ErrorCode, 500)
   131  	assert.Equal(t, response.ErrorMessage, "test-header-payload-error")
   132  
   133  	wg.Add(1)
   134  	core.HandleUnknownRequest(&req)
   135  	wg.Wait()
   136  
   137  	assert.Equal(t, count, 6)
   138  	response = lastMessage.Payload.(*model.Response)
   139  
   140  	assert.Equal(t, response.Id, req.Id)
   141  	assert.True(t, response.Error)
   142  	assert.Equal(t, 403, response.ErrorCode)
   143  	assert.Equal(t, nil, response.Payload)
   144  }
   145  
   146  func TestFabricCore_RestServiceRequest(t *testing.T) {
   147  
   148  	core := newTestFabricCore("test-channel")
   149  
   150  	core.Bus().GetChannelManager().CreateChannel(restServiceChannel)
   151  
   152  	var lastRequest *model.Request
   153  
   154  	wg := sync.WaitGroup{}
   155  
   156  	mh, _ := core.Bus().ListenRequestStream(restServiceChannel)
   157  	mh.Handle(
   158  		func(message *model.Message) {
   159  			lastRequest = message.Payload.(*model.Request)
   160  			wg.Done()
   161  		},
   162  		func(e error) {})
   163  
   164  	var lastSuccess, lastError *model.Response
   165  
   166  	restRequest := &RestServiceRequest{
   167  		Uri:     "test",
   168  		Headers: map[string]string{"h1": "value1"},
   169  	}
   170  
   171  	wg.Add(1)
   172  	core.RestServiceRequest(restRequest, func(response *model.Response) {
   173  		lastSuccess = response
   174  		wg.Done()
   175  	}, func(response *model.Response) {
   176  		lastError = response
   177  		wg.Done()
   178  	})
   179  
   180  	wg.Wait()
   181  
   182  	wg.Add(1)
   183  	core.Bus().SendResponseMessage(restServiceChannel, &model.Response{
   184  		Payload: "test",
   185  	}, lastRequest.Id)
   186  	wg.Wait()
   187  
   188  	assert.NotNil(t, lastSuccess)
   189  	assert.Nil(t, lastError)
   190  
   191  	assert.Equal(t, lastRequest.Payload, restRequest)
   192  	assert.Equal(t, len(lastRequest.Payload.(*RestServiceRequest).Headers), 1)
   193  	assert.Equal(t, lastRequest.Payload.(*RestServiceRequest).Headers["h1"], "value1")
   194  	assert.Equal(t, lastSuccess.Payload, "test")
   195  
   196  	lastSuccess, lastError = nil, nil
   197  
   198  	core.SetHeaders(map[string]string{"h2": "value2", "h1": "new-value"})
   199  
   200  	wg.Add(1)
   201  	core.RestServiceRequest(restRequest, func(response *model.Response) {
   202  		lastSuccess = response
   203  		wg.Done()
   204  	}, func(response *model.Response) {
   205  		lastError = response
   206  		wg.Done()
   207  	})
   208  
   209  	wg.Wait()
   210  
   211  	wg.Add(1)
   212  	core.Bus().SendResponseMessage(restServiceChannel, &model.Response{
   213  		ErrorMessage: "error",
   214  		Error:        true,
   215  		ErrorCode:    1,
   216  	}, lastRequest.Id)
   217  	wg.Wait()
   218  
   219  	assert.Nil(t, lastSuccess)
   220  	assert.NotNil(t, lastError)
   221  	assert.Equal(t, lastError.ErrorMessage, "error")
   222  	assert.Equal(t, lastError.ErrorCode, 1)
   223  
   224  	assert.Equal(t, len(lastRequest.Payload.(*RestServiceRequest).Headers), 2)
   225  	assert.Equal(t, lastRequest.Payload.(*RestServiceRequest).Headers["h1"], "value1")
   226  	assert.Equal(t, lastRequest.Payload.(*RestServiceRequest).Headers["h2"], "value2")
   227  
   228  	lastSuccess, lastError = nil, nil
   229  	wg.Add(1)
   230  	core.RestServiceRequest(restRequest, func(response *model.Response) {
   231  		lastSuccess = response
   232  		wg.Done()
   233  	}, func(response *model.Response) {
   234  		lastError = response
   235  		wg.Done()
   236  	})
   237  
   238  	wg.Wait()
   239  
   240  	wg.Add(1)
   241  	core.Bus().SendErrorMessage(restServiceChannel, errors.New("test-error"), lastRequest.Id)
   242  	wg.Wait()
   243  
   244  	assert.Nil(t, lastSuccess)
   245  	assert.NotNil(t, lastError)
   246  	assert.Equal(t, lastError.ErrorMessage, "test-error")
   247  	assert.Equal(t, lastError.ErrorCode, 500)
   248  }
   249  
   250  func TestFabricCore_GenerateJSONHeaders(t *testing.T) {
   251  	core := newTestFabricCore("test-channel")
   252  	h := core.GenerateJSONHeaders()
   253  	assert.EqualValues(t, "application/json", h["Content-Type"])
   254  }
   255  
   256  func TestFabricCore_SetDefaultJSONHeaders(t *testing.T) {
   257  	core := newTestFabricCore("test-channel")
   258  	core.SetDefaultJSONHeaders()
   259  
   260  	mh, _ := core.Bus().ListenStream("test-channel")
   261  
   262  	wg := sync.WaitGroup{}
   263  
   264  	var lastMessage *model.Message
   265  
   266  	mh.Handle(func(message *model.Message) {
   267  		lastMessage = message
   268  		wg.Done()
   269  	}, func(e error) {
   270  		assert.Fail(t, "unexpected error")
   271  	})
   272  
   273  	id := uuid.New()
   274  	req := model.Request{
   275  		Id:      &id,
   276  		Payload: "test-headers",
   277  	}
   278  
   279  	wg.Add(1)
   280  	core.SendResponse(&req, "test-response")
   281  	wg.Wait()
   282  
   283  	response := lastMessage.Payload.(*model.Response)
   284  
   285  	// content-type and accept should have been set.
   286  	assert.Len(t, response.Headers, 1)
   287  	assert.EqualValues(t, "application/json", response.Headers["Content-Type"])
   288  }
   289  
   290  func TestFabricCore_SetDefaultJSONHeadersEmpty(t *testing.T) {
   291  	core := newTestFabricCore("test-channel")
   292  
   293  	// set empty headers
   294  	core.SetHeaders(nil)
   295  
   296  	mh, _ := core.Bus().ListenStream("test-channel")
   297  
   298  	wg := sync.WaitGroup{}
   299  
   300  	var lastMessage *model.Message
   301  
   302  	mh.Handle(func(message *model.Message) {
   303  		lastMessage = message
   304  		wg.Done()
   305  	}, func(e error) {
   306  		assert.Fail(t, "unexpected error")
   307  	})
   308  
   309  	id := uuid.New()
   310  	req := model.Request{
   311  		Id:      &id,
   312  		Payload: "test-headers",
   313  	}
   314  
   315  	wg.Add(1)
   316  	core.SendResponseWithHeaders(&req, "test-response", map[string]string{"Content-Type": "pizza/cake"})
   317  	wg.Wait()
   318  
   319  	response := lastMessage.Payload.(*model.Response)
   320  
   321  	// content-type and accept should have been set.
   322  	assert.Len(t, response.Headers, 1)
   323  	assert.EqualValues(t, "pizza/cake", response.Headers["Content-Type"])
   324  }