1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
package dedup
import (
"testing"
"testing/quick"
"time"
)
const expiresAfter = time.Millisecond
func TestPacketDeduplicatorSeen(t *testing.T) {
dedup := NewDeduplicator(expiresAfter)
sender := uint32(1)
packetID := uint32(1)
// Test Seen with new packetID
if dedup.Seen(sender, packetID) {
t.Error("Expected the packet to not have been seen")
}
// Test Seen with same packetID again
if !dedup.Seen(sender, packetID) {
t.Error("Expected the packet to have been seen")
}
// Wait for expiration
time.Sleep(expiresAfter + time.Millisecond)
// Test Seen with same packetID after expiration
if dedup.Seen(sender, packetID) {
t.Error("Expected the packet to not have been seen after expiration")
}
}
func TestDuplicatorProp(t *testing.T) {
// Some arbitrary time. Ideally the generator would provide one, but the go quickcheck generators aren't very good
now := time.Now()
if err := quick.Check(func(s, p uint32) bool {
dedup := NewDeduplicator(expiresAfter)
// Test Seen with new packetID
if dedup.seenAt(now, s, p) {
t.Error("Expected the packet to not have been seen")
return false
}
// Test Seen with same packetID again
if !dedup.seenAt(now, s, p) {
t.Error("Expected the packet to have been seen")
return false
}
// Even up to expiry
if !dedup.seenAt(now.Add(expiresAfter), s, p) {
t.Error("Expected the packet to have been seen all the way to expiry")
return false
}
// But not in The Future
if dedup.seenAt(now.Add(expiresAfter+time.Nanosecond), s, p) {
t.Error("Expected the packet to not have been seen after expiry")
return false
}
return true
}, nil); err != nil {
t.Error(err)
}
}
func FuzzDup(f *testing.F) {
now := time.Now()
f.Fuzz(func(t *testing.T, s1 uint32, s2 uint32, p1 uint32, p2 uint32) {
dedup := NewDeduplicator(expiresAfter)
// Test Seen with new packetID
if dedup.seenAt(now, s1, p1) {
t.Error("Expected the packet to not have been seen")
}
// Test Seen with same packetID again
if !dedup.seenAt(now, s1, p1) {
t.Error("Expected the packet to have been seen")
}
// Even up to expiry
if !dedup.seenAt(now.Add(expiresAfter), s1, p1) {
t.Error("Expected the packet to have been seen all the way to expiry")
}
// But not in The Future
if dedup.seenAt(now.Add(expiresAfter+time.Nanosecond), s1, p1) {
t.Error("Expected the packet to not have been seen after expiry")
}
//
// This remaining bits of this property are not valid if s1 == s2 and p1 == p2
//
if s1 == s2 && p1 == p2 {
return
}
if dedup.seenAt(now, s2, p2) {
t.Error("Expected a different packet to not have been seen")
}
// Test Seen with same packetID again
if !dedup.seenAt(now, s2, p2) {
t.Error("Expected a different packet to have been seen")
}
// Even up to expiry
if !dedup.seenAt(now.Add(expiresAfter), s2, p2) {
t.Error("Expected a different packet to have been seen all the way to expiry")
}
// But not in The Future
if dedup.seenAt(now.Add(expiresAfter+time.Nanosecond), s2, p2) {
t.Error("Expected a different packet to not have been seen after expiry")
}
})
}
func TestPacketDeduplicatorSeenData(t *testing.T) {
dedup := NewDeduplicator(expiresAfter)
data := []byte("test data")
// Test SeenData with new data
if dedup.SeenData(data) {
t.Error("Expected the data to not have been seen")
}
// Test SeenData with same data again
if !dedup.SeenData(data) {
t.Error("Expected the data to have been seen")
}
// Wait for expiration
time.Sleep(expiresAfter + time.Millisecond)
// Test SeenData with same data after expiration
if dedup.SeenData(data) {
t.Error("Expected the data to not have been seen after expiration")
}
}
|