github.com/getgauge/gauge@v1.6.9/conn/network_test.go (about)

     1  /*----------------------------------------------------------------
     2   *  Copyright (c) ThoughtWorks, Inc.
     3   *  Licensed under the Apache License, Version 2.0
     4   *  See LICENSE in the project root for license information.
     5   *----------------------------------------------------------------*/
     6  
     7  package conn
     8  
     9  import (
    10  	"fmt"
    11  	"net"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/getgauge/gauge-proto/go/gauge_messages"
    16  
    17  	// github.com/golang/protobuf/proto is deprecated, however this package is used by the legacy API
    18  	// which is consumed only by IntelliJ IDEA presently. Since IDEA does not plan to implement LSP
    19  	// gauge will have to keep this alive. Upgrading to google.golang.org/protobuf/proto is not a drop in change
    20  	// since the newer library does not support DecodeVarint. The whole message handling will need to be refactored.
    21  	"github.com/golang/protobuf/proto" //nolint:staticcheck
    22  )
    23  
    24  var id int64
    25  
    26  type mockConn struct {
    27  	sleepDuration time.Duration
    28  }
    29  
    30  var responseMessage *gauge_messages.Message
    31  
    32  func (m mockConn) Read(b []byte) (n int, err error) {
    33  	time.Sleep(m.sleepDuration)
    34  	if responseMessage.MessageId == 0 {
    35  		responseMessage.MessageId = id
    36  	}
    37  	messageBytes, err := proto.Marshal(responseMessage)
    38  	if err != nil {
    39  		return 0, err
    40  	}
    41  
    42  	data := append(proto.EncodeVarint(uint64(len(messageBytes))), messageBytes...)
    43  	copy(b, data)
    44  	return len(data), nil
    45  }
    46  
    47  func (m mockConn) Write(b []byte) (n int, err error) {
    48  	message := &gauge_messages.Message{}
    49  	messageLength, bytesRead := proto.DecodeVarint(b)
    50  	b = b[bytesRead : messageLength+uint64(bytesRead)]
    51  	err = proto.Unmarshal(b, message)
    52  	if err != nil {
    53  		return -1, err
    54  	}
    55  	if id == 0 {
    56  		id = message.MessageId
    57  	}
    58  	return 0, nil
    59  }
    60  
    61  func (m mockConn) Close() error {
    62  	return nil
    63  }
    64  
    65  func (m mockConn) LocalAddr() net.Addr {
    66  	return nil
    67  }
    68  
    69  func (m mockConn) RemoteAddr() net.Addr {
    70  	return nil
    71  }
    72  
    73  func (m mockConn) SetDeadline(t time.Time) error {
    74  	return nil
    75  }
    76  
    77  func (m mockConn) SetReadDeadline(t time.Time) error {
    78  	return nil
    79  }
    80  
    81  func (m mockConn) SetWriteDeadline(t time.Time) error {
    82  	return nil
    83  }
    84  
    85  func TestGetResponseForGaugeMessageWithTimeout(t *testing.T) {
    86  	id = 0
    87  	responseMessage = &gauge_messages.Message{}
    88  	message := &gauge_messages.Message{
    89  		MessageType: gauge_messages.Message_StepNameRequest,
    90  		StepNameRequest: &gauge_messages.StepNameRequest{
    91  			StepValue: "The worrd {} has {} vowels.",
    92  		},
    93  	}
    94  
    95  	responseMessage = &gauge_messages.Message{
    96  		MessageType: gauge_messages.Message_StepNameResponse,
    97  		StepNameResponse: &gauge_messages.StepNameResponse{
    98  			FileName:      "foo.js",
    99  			HasAlias:      false,
   100  			IsStepPresent: true,
   101  			Span:          &gauge_messages.Span{Start: 2, End: 6, StartChar: 0, EndChar: 2},
   102  			StepName:      []string{"The word {} has {} vowels."},
   103  		},
   104  	}
   105  
   106  	conn := mockConn{}
   107  
   108  	res, err := GetResponseForMessageWithTimeout(message, conn, 3*time.Second)
   109  
   110  	if err != nil {
   111  		t.Errorf("expected err to be nil. got %v", err)
   112  	}
   113  	if !proto.Equal(res, responseMessage) {
   114  		t.Errorf("expected : %v\ngot : %v", responseMessage, res)
   115  	}
   116  }
   117  
   118  func TestGetResponseForGaugeMessageShoudGiveTheRightResponse(t *testing.T) {
   119  	id = 1234
   120  	r := response{
   121  		err:    make(chan error),
   122  		result: make(chan *gauge_messages.Message),
   123  	}
   124  
   125  	m.put(id, r)
   126  
   127  	message := &gauge_messages.Message{
   128  		MessageType: gauge_messages.Message_StepNameRequest,
   129  		StepNameRequest: &gauge_messages.StepNameRequest{
   130  			StepValue: "The worrd {} has {} vowels.",
   131  		},
   132  	}
   133  
   134  	responseMessage = &gauge_messages.Message{
   135  		MessageType: gauge_messages.Message_StepNameResponse,
   136  		StepNameResponse: &gauge_messages.StepNameResponse{
   137  			FileName:      "foo.js",
   138  			HasAlias:      false,
   139  			IsStepPresent: true,
   140  			Span:          &gauge_messages.Span{Start: 2, End: 2, StartChar: 0, EndChar: 2},
   141  			StepName:      []string{"The word {} has {} vowels."},
   142  		},
   143  	}
   144  
   145  	conn := mockConn{}
   146  
   147  	go getResponseForGaugeMessage(message, conn, response{}, 3*time.Second)
   148  
   149  	response := <-r.result
   150  	if !proto.Equal(response, responseMessage) {
   151  		t.Errorf("expected : %v\ngot : %v", responseMessage, response)
   152  	}
   153  }
   154  
   155  func TestGetResponseForGaugeMessageShoudGiveErrorForUnsupportedMessage(t *testing.T) {
   156  	id = 0
   157  	message := &gauge_messages.Message{
   158  		MessageType: gauge_messages.Message_StepNameRequest,
   159  		StepNameRequest: &gauge_messages.StepNameRequest{
   160  			StepValue: "The worrd {} has {} vowels.",
   161  		},
   162  	}
   163  
   164  	responseMessage = &gauge_messages.Message{
   165  		MessageType:                gauge_messages.Message_UnsupportedMessageResponse,
   166  		UnsupportedMessageResponse: &gauge_messages.UnsupportedMessageResponse{},
   167  	}
   168  
   169  	conn := mockConn{}
   170  
   171  	_, err := GetResponseForMessageWithTimeout(message, conn, 1*time.Second)
   172  
   173  	expected := "Unsupported Message response received. Message not supported. "
   174  
   175  	if err.Error() != expected {
   176  		t.Errorf("expected '%s'\n got '%s'", expected, err)
   177  	}
   178  
   179  }
   180  
   181  func TestGetResponseForGaugeMessageShoudErrorWithTimeOut(t *testing.T) {
   182  	id = 0
   183  	message := &gauge_messages.Message{
   184  		MessageType: gauge_messages.Message_StepNameRequest,
   185  		StepNameRequest: &gauge_messages.StepNameRequest{
   186  			StepValue: "The worrd {} has {} vowels.",
   187  		},
   188  	}
   189  
   190  	responseMessage = &gauge_messages.Message{
   191  		MessageType: gauge_messages.Message_StepNameResponse,
   192  		StepNameResponse: &gauge_messages.StepNameResponse{
   193  			FileName:      "foo.js",
   194  			HasAlias:      false,
   195  			IsStepPresent: true,
   196  			Span:          &gauge_messages.Span{Start: 2, End: 2, StartChar: 0, EndChar: 2},
   197  			StepName:      []string{"The word {} has {} vowels."},
   198  		},
   199  	}
   200  
   201  	conn := mockConn{sleepDuration: 2 * time.Second}
   202  	_, err := GetResponseForMessageWithTimeout(message, conn, 1*time.Second)
   203  
   204  	expected := fmt.Errorf("Request timed out for Message with ID => %v and Type => StepNameRequest", id)
   205  	if err.Error() != expected.Error() {
   206  		t.Errorf("expected %v\n got %v", expected, err)
   207  	}
   208  }
   209  
   210  func TestGetResponseForGaugeMessageShoudNotErrorIfNoTimeoutIsSpecified(t *testing.T) {
   211  	id = 0
   212  	message := &gauge_messages.Message{
   213  		MessageType: gauge_messages.Message_StepNameRequest,
   214  		StepNameRequest: &gauge_messages.StepNameRequest{
   215  			StepValue: "The worrd {} has {} vowels.",
   216  		},
   217  	}
   218  
   219  	responseMessage = &gauge_messages.Message{
   220  		MessageType: gauge_messages.Message_StepNameResponse,
   221  		StepNameResponse: &gauge_messages.StepNameResponse{
   222  			FileName:      "foo.js",
   223  			HasAlias:      false,
   224  			IsStepPresent: true,
   225  			Span:          &gauge_messages.Span{Start: 2, End: 6, StartChar: 0, EndChar: 2},
   226  			StepName:      []string{"The word {} has {} vowels."},
   227  		},
   228  	}
   229  
   230  	conn := mockConn{}
   231  
   232  	res, err := GetResponseForMessageWithTimeout(message, conn, 0)
   233  
   234  	if err != nil {
   235  		t.Errorf("expected err to be nil. got %v", err)
   236  	}
   237  	if !proto.Equal(res, responseMessage) {
   238  		t.Errorf("expected : %v\ngot : %v", responseMessage, res)
   239  	}
   240  }