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 }