Skip to content

Commit 159cd85

Browse files
Added UT in telemetry code to fix code coverage (#310)
* added UT to fix code coverage * added check before closing client connection * replaced fmt.Printf with t.Errorf * Calling cancel to exit server thread and close connection * updated comments * fixed an issue in telemtry server code if server closes client connection before * fixed removing tb connection from array * removed dead code * removed duplicate logs * added a check for removing element from tb.connections * added mutex lock as multiple threads accessing tb.connections slice * moved the condition before client close * added one more UT to fix code coverage * fixed the ut. shud not write after close
1 parent 3ddb72c commit 159cd85

File tree

3 files changed

+91
-7
lines changed

3 files changed

+91
-7
lines changed

telemetry/cnstelemetry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ CONNECT:
8080
if err == nil {
8181
// If write fails, try to re-establish connections as server/client
8282
if _, err = telemetryBuffer.Write(report); err != nil {
83+
log.Printf("[CNS-Telemetry] Telemetry write failed: %v", err)
8384
telemetryBuffer.Cancel()
8485
goto CONNECT
8586
}

telemetry/telemetry_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,63 @@ func TestCloseTelemetryConnection(t *testing.T) {
175175
}
176176
}
177177

178+
func TestServerCloseTelemetryConnection(t *testing.T) {
179+
// create server telemetrybuffer and start server
180+
tb = NewTelemetryBuffer(hostAgentUrl)
181+
err := tb.StartServer()
182+
if err == nil {
183+
go tb.BufferAndPushData(0)
184+
}
185+
186+
// create client telemetrybuffer and connect to server
187+
tb1 := NewTelemetryBuffer(hostAgentUrl)
188+
if err := tb1.Connect(); err != nil {
189+
t.Errorf("connection to telemetry server failed %v", err)
190+
}
191+
192+
// Exit server thread and close server connection
193+
tb.Cancel()
194+
time.Sleep(300 * time.Millisecond)
195+
196+
b := []byte("tamil")
197+
if _, err := tb1.Write(b); err == nil {
198+
t.Errorf("Client couldn't recognise server close")
199+
}
200+
201+
if len(tb.connections) != 0 {
202+
t.Errorf("All connections not closed as expected")
203+
}
204+
205+
// Close client connection
206+
tb1.Close()
207+
}
208+
209+
func TestClientCloseTelemetryConnection(t *testing.T) {
210+
// create server telemetrybuffer and start server
211+
tb = NewTelemetryBuffer(hostAgentUrl)
212+
err := tb.StartServer()
213+
if err == nil {
214+
go tb.BufferAndPushData(0)
215+
}
216+
217+
// create client telemetrybuffer and connect to server
218+
tb1 := NewTelemetryBuffer(hostAgentUrl)
219+
if err := tb1.Connect(); err != nil {
220+
t.Errorf("connection to telemetry server failed %v", err)
221+
}
222+
223+
// Close client connection
224+
tb1.Close()
225+
time.Sleep(300 * time.Millisecond)
226+
227+
if len(tb.connections) != 0 {
228+
t.Errorf("All connections not closed as expected")
229+
}
230+
231+
// Exit server thread and close server connection
232+
tb.Cancel()
233+
}
234+
178235
func TestSetReportState(t *testing.T) {
179236
err := reportManager.SetReportState("a.json")
180237
if err != nil {

telemetry/telemetrybuffer.go

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"net"
1313
"net/http"
1414
"strings"
15+
"sync"
1516
"time"
1617

1718
"github.com/Azure/azure-container-networking/common"
@@ -52,6 +53,7 @@ type TelemetryBuffer struct {
5253
Connected bool
5354
data chan interface{}
5455
cancel chan bool
56+
mutex sync.Mutex
5557
}
5658

5759
// Payload object holds the different types of reports
@@ -87,8 +89,13 @@ func NewTelemetryBuffer(hostReportURL string) *TelemetryBuffer {
8789
}
8890

8991
func remove(s []net.Conn, i int) []net.Conn {
90-
s[i] = s[len(s)-1]
91-
return s[:len(s)-1]
92+
if len(s) > 0 && i < len(s) {
93+
s[i] = s[len(s)-1]
94+
return s[:len(s)-1]
95+
}
96+
97+
telemetryLogger.Printf("tb connections remove failed index %v len %v", i, len(s))
98+
return s
9299
}
93100

94101
// Starts Telemetry server listening on unix domain socket
@@ -107,7 +114,9 @@ func (tb *TelemetryBuffer) StartServer() error {
107114
// Spawn worker goroutines to communicate with client
108115
conn, err := tb.listener.Accept()
109116
if err == nil {
117+
tb.mutex.Lock()
110118
tb.connections = append(tb.connections, conn)
119+
tb.mutex.Unlock()
111120
go func() {
112121
for {
113122
reportStr, err := read(conn)
@@ -132,18 +141,32 @@ func (tb *TelemetryBuffer) StartServer() error {
132141
tb.data <- cnsReport
133142
}
134143
} else {
135-
telemetryLogger.Printf("Server closing client connection")
136-
for index, value := range tb.connections {
144+
var index int
145+
var value net.Conn
146+
var found bool
147+
148+
tb.mutex.Lock()
149+
defer tb.mutex.Unlock()
150+
151+
for index, value = range tb.connections {
137152
if value == conn {
153+
telemetryLogger.Printf("Server closing client connection")
138154
conn.Close()
139-
tb.connections = remove(tb.connections, index)
140-
return
155+
found = true
156+
break
141157
}
142158
}
159+
160+
if found {
161+
tb.connections = remove(tb.connections, index)
162+
}
163+
164+
return
143165
}
144166
}
145167
}()
146168
} else {
169+
telemetryLogger.Printf("Telemetry Server accept error %v", err)
147170
return
148171
}
149172
}
@@ -239,9 +262,12 @@ func (tb *TelemetryBuffer) Close() {
239262
tb.listener = nil
240263
}
241264

265+
tb.mutex.Lock()
266+
defer tb.mutex.Unlock()
267+
242268
for _, conn := range tb.connections {
243269
if conn != nil {
244-
telemetryLogger.Printf("connection close")
270+
telemetryLogger.Printf("connection close as server closed")
245271
conn.Close()
246272
}
247273
}

0 commit comments

Comments
 (0)