Sfoglia il codice sorgente

fix: stabilize flaky CI tests

1. Add sync.Mutex to ScoutConnCollected to eliminate data race between
   Add()/MarkWrite() in readLoop and learn() iterating results.
   Introduce Snapshot() for safe read access.

2. Increase bloom filter test size from 500 to 100000 to prevent
   false negatives from random eviction in the stable bloom filter.

3. Use Require().NoError() in TestHTTPSRequest to prevent nil-pointer
   panic on resp.Body.Close() when the request fails.

Fixes #425
tags/v2.2.7^2^2
Alexey Dolotov 1 mese fa
parent
commit
e54d9d60d3

+ 1
- 1
antireplay/stable_bloom_filter_test.go Vedi File

12
 }
12
 }
13
 
13
 
14
 func (suite *StableBloomFilterTestSuite) TestOp() {
14
 func (suite *StableBloomFilterTestSuite) TestOp() {
15
-	filter := antireplay.NewStableBloomFilter(500, 0.001)
15
+	filter := antireplay.NewStableBloomFilter(100000, 0.001)
16
 
16
 
17
 	suite.False(filter.SeenBefore([]byte{1, 2, 3}))
17
 	suite.False(filter.SeenBefore([]byte{1, 2, 3}))
18
 	suite.False(filter.SeenBefore([]byte{4, 5, 6}))
18
 	suite.False(filter.SeenBefore([]byte{4, 5, 6}))

+ 8
- 6
mtglib/internal/doppel/scout.go Vedi File

61
 		client.CloseIdleConnections()
61
 		client.CloseIdleConnections()
62
 	}
62
 	}
63
 
63
 
64
-	if err != nil || len(results.data) == 0 {
64
+	data, writeIndex := results.Snapshot()
65
+
66
+	if err != nil || len(data) == 0 {
65
 		return ScoutResult{}, err
67
 		return ScoutResult{}, err
66
 	}
68
 	}
67
 
69
 
70
 	// Compute inter-record durations (existing logic).
72
 	// Compute inter-record durations (existing logic).
71
 	lastTimestamp := time.Time{}
73
 	lastTimestamp := time.Time{}
72
 
74
 
73
-	for i, v := range results.data {
75
+	for i, v := range data {
74
 		if v.recordType != tls.TypeApplicationData {
76
 		if v.recordType != tls.TypeApplicationData {
75
 			continue
77
 			continue
76
 		}
78
 		}
77
 
79
 
78
 		if lastTimestamp.IsZero() {
80
 		if lastTimestamp.IsZero() {
79
 			if i > 0 {
81
 			if i > 0 {
80
-				lastTimestamp = results.data[i-1].timestamp
82
+				lastTimestamp = data[i-1].timestamp
81
 			} else {
83
 			} else {
82
 				lastTimestamp = v.timestamp
84
 				lastTimestamp = v.timestamp
83
 			}
85
 			}
90
 	// Compute cert size: sum of ApplicationData payload between CCS and
92
 	// Compute cert size: sum of ApplicationData payload between CCS and
91
 	// the first client Write (which marks the end of server handshake).
93
 	// the first client Write (which marks the end of server handshake).
92
 	seenCCS := false
94
 	seenCCS := false
93
-	boundary := results.writeIndex
95
+	boundary := writeIndex
94
 	if boundary < 0 {
96
 	if boundary < 0 {
95
-		boundary = len(results.data)
97
+		boundary = len(data)
96
 	}
98
 	}
97
 
99
 
98
-	for i, v := range results.data {
100
+	for i, v := range data {
99
 		if i >= boundary {
101
 		if i >= boundary {
100
 			break
102
 			break
101
 		}
103
 		}

+ 20
- 1
mtglib/internal/doppel/scout_conn_collected.go Vedi File

1
 package doppel
1
 package doppel
2
 
2
 
3
-import "time"
3
+import (
4
+	"sync"
5
+	"time"
6
+)
4
 
7
 
5
 const (
8
 const (
6
 	ScoutConnCollectedPreallocSize = 100
9
 	ScoutConnCollectedPreallocSize = 100
13
 }
16
 }
14
 
17
 
15
 type ScoutConnCollected struct {
18
 type ScoutConnCollected struct {
19
+	mu         sync.Mutex
16
 	data       []ScoutConnResult
20
 	data       []ScoutConnResult
17
 	writeIndex int // index at which client first wrote post-handshake data; -1 if not set
21
 	writeIndex int // index at which client first wrote post-handshake data; -1 if not set
18
 }
22
 }
19
 
23
 
20
 func (s *ScoutConnCollected) Add(record byte, payloadLen int) {
24
 func (s *ScoutConnCollected) Add(record byte, payloadLen int) {
25
+	s.mu.Lock()
21
 	s.data = append(s.data, ScoutConnResult{
26
 	s.data = append(s.data, ScoutConnResult{
22
 		timestamp:  time.Now(),
27
 		timestamp:  time.Now(),
23
 		recordType: record,
28
 		recordType: record,
24
 		payloadLen: payloadLen,
29
 		payloadLen: payloadLen,
25
 	})
30
 	})
31
+	s.mu.Unlock()
26
 }
32
 }
27
 
33
 
28
 // MarkWrite records the current data length as the handshake boundary.
34
 // MarkWrite records the current data length as the handshake boundary.
29
 func (s *ScoutConnCollected) MarkWrite() {
35
 func (s *ScoutConnCollected) MarkWrite() {
36
+	s.mu.Lock()
30
 	if s.writeIndex < 0 {
37
 	if s.writeIndex < 0 {
31
 		s.writeIndex = len(s.data)
38
 		s.writeIndex = len(s.data)
32
 	}
39
 	}
40
+	s.mu.Unlock()
41
+}
42
+
43
+// Snapshot returns a copy of the collected data and the write index.
44
+func (s *ScoutConnCollected) Snapshot() ([]ScoutConnResult, int) {
45
+	s.mu.Lock()
46
+	snapshot := make([]ScoutConnResult, len(s.data))
47
+	copy(snapshot, s.data)
48
+	writeIndex := s.writeIndex
49
+	s.mu.Unlock()
50
+
51
+	return snapshot, writeIndex
33
 }
52
 }
34
 
53
 
35
 func NewScoutConnCollected() *ScoutConnCollected {
54
 func NewScoutConnCollected() *ScoutConnCollected {

+ 1
- 1
mtglib/proxy_test.go Vedi File

175
 	addr := fmt.Sprintf("https://%s/headers", suite.ProxyAddress())
175
 	addr := fmt.Sprintf("https://%s/headers", suite.ProxyAddress())
176
 
176
 
177
 	resp, err := client.Get(addr) //nolint: noctx
177
 	resp, err := client.Get(addr) //nolint: noctx
178
-	suite.NoError(err)
178
+	suite.Require().NoError(err)
179
 
179
 
180
 	defer resp.Body.Close() //nolint: errcheck
180
 	defer resp.Body.Close() //nolint: errcheck
181
 
181
 

Loading…
Annulla
Salva