github.com/google/fleetspeak@v0.1.15-0.20240426164851-4f31f62c1aea/fleetspeak/src/admin/history/history_test.go (about) 1 // Copyright 2017 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package history 16 17 import ( 18 "testing" 19 "time" 20 21 spb "github.com/google/fleetspeak/fleetspeak/src/server/proto/fleetspeak_server" 22 tspb "google.golang.org/protobuf/types/known/timestamppb" 23 ) 24 25 func TestSummary(t *testing.T) { 26 for _, tc := range []struct { 27 name string 28 in []*spb.ClientContact 29 want Summary 30 wantErr bool 31 }{ 32 { // An empty list shouldn't break anything. 33 name: "nil", 34 in: nil, 35 want: Summary{}, 36 }, 37 { // A single contact. 38 name: "single", 39 in: []*spb.ClientContact{ 40 { 41 SentNonce: 1, 42 ReceivedNonce: 0, 43 ObservedAddress: "192.168.1.1:50000", 44 Timestamp: &tspb.Timestamp{Seconds: 1514303404, Nanos: 0}, 45 }, 46 }, 47 want: Summary{ 48 Start: time.Unix(1514303404, 0).UTC(), 49 End: time.Unix(1514303404, 0).UTC(), 50 Count: 1, 51 IPCount: 1, 52 }, 53 }, 54 { // Approximate startup sequence - nonces chained with increasing ts. 55 name: "normalStartup", 56 in: []*spb.ClientContact{ 57 { 58 ReceivedNonce: 0, 59 SentNonce: 1, 60 ObservedAddress: "192.168.1.1:50000", 61 Timestamp: &tspb.Timestamp{Seconds: 1514303404, Nanos: 0}, 62 }, 63 { 64 ReceivedNonce: 1, 65 SentNonce: 2, 66 ObservedAddress: "192.168.1.1:50001", 67 Timestamp: &tspb.Timestamp{Seconds: 1514303405, Nanos: 0}, 68 }, 69 { 70 ReceivedNonce: 2, 71 SentNonce: 3, 72 ObservedAddress: "192.168.1.1:50002", 73 Timestamp: &tspb.Timestamp{Seconds: 1514303406, Nanos: 0}, 74 }, 75 { 76 ReceivedNonce: 3, 77 SentNonce: 4, 78 ObservedAddress: "192.168.1.1:50003", 79 Timestamp: &tspb.Timestamp{Seconds: 1514303407, Nanos: 0}, 80 }, 81 { 82 ReceivedNonce: 4, 83 SentNonce: 5, 84 ObservedAddress: "192.168.1.2:50004", 85 Timestamp: &tspb.Timestamp{Seconds: 1514303408, Nanos: 0}, 86 }, 87 { 88 ReceivedNonce: 5, 89 SentNonce: 6, 90 ObservedAddress: "192.168.1.2:50005", 91 Timestamp: &tspb.Timestamp{Seconds: 1514303409, Nanos: 0}, 92 }, 93 }, 94 want: Summary{ 95 Start: time.Unix(1514303404, 0).UTC(), 96 End: time.Unix(1514303409, 0).UTC(), 97 Count: 6, 98 IPCount: 2, 99 }, 100 }, 101 { 102 name: "duplicateTimestamp", 103 in: []*spb.ClientContact{ 104 { 105 ReceivedNonce: 0, 106 SentNonce: 1, 107 ObservedAddress: "192.168.1.1:50000", 108 Timestamp: &tspb.Timestamp{Seconds: 1514303404, Nanos: 0}, 109 }, 110 { 111 ReceivedNonce: 1, 112 SentNonce: 2, 113 ObservedAddress: "192.168.1.1:50001", 114 Timestamp: &tspb.Timestamp{Seconds: 1514303404, Nanos: 0}, 115 }, 116 }, 117 wantErr: true, 118 }, 119 { 120 name: "duplicateNonce", 121 in: []*spb.ClientContact{ 122 { 123 ReceivedNonce: 0, 124 SentNonce: 1, 125 ObservedAddress: "192.168.1.1:50000", 126 Timestamp: &tspb.Timestamp{Seconds: 1514303404, Nanos: 0}, 127 }, 128 { 129 ReceivedNonce: 1, 130 SentNonce: 1, 131 ObservedAddress: "192.168.1.1:50001", 132 Timestamp: &tspb.Timestamp{Seconds: 1514303405, Nanos: 0}, 133 }, 134 }, 135 wantErr: true, 136 }, 137 { // Client is restored twice from a backup. 138 name: "backupRestore", 139 in: []*spb.ClientContact{ 140 { 141 ReceivedNonce: 0, 142 SentNonce: 1, 143 ObservedAddress: "192.168.1.1:50000", 144 Timestamp: &tspb.Timestamp{Seconds: 1514303404, Nanos: 0}, 145 }, 146 { 147 ReceivedNonce: 1, 148 SentNonce: 2, 149 ObservedAddress: "192.168.1.1:50001", 150 Timestamp: &tspb.Timestamp{Seconds: 1514303405, Nanos: 0}, 151 }, 152 { 153 ReceivedNonce: 2, 154 SentNonce: 3, 155 ObservedAddress: "192.168.1.1:50002", 156 Timestamp: &tspb.Timestamp{Seconds: 1514303406, Nanos: 0}, 157 }, 158 { 159 ReceivedNonce: 3, 160 SentNonce: 4, 161 ObservedAddress: "192.168.1.1:50003", 162 Timestamp: &tspb.Timestamp{Seconds: 1514303407, Nanos: 0}, 163 }, 164 { 165 ReceivedNonce: 2, 166 SentNonce: 5, 167 ObservedAddress: "192.168.1.1:50004", 168 Timestamp: &tspb.Timestamp{Seconds: 1514303408, Nanos: 0}, 169 }, 170 { 171 ReceivedNonce: 2, 172 SentNonce: 6, 173 ObservedAddress: "192.168.1.1:50005", 174 Timestamp: &tspb.Timestamp{Seconds: 1514303409, Nanos: 0}, 175 }, 176 }, 177 want: Summary{ 178 Start: time.Unix(1514303404, 0).UTC(), 179 End: time.Unix(1514303409, 0).UTC(), 180 Count: 6, 181 IPCount: 1, 182 Splits: 2, 183 SplitPoints: 1, 184 Skips: 2, 185 }, 186 }, 187 { // Client is cloned 2 ways after second contact. 188 name: "2wayClone", 189 in: []*spb.ClientContact{ 190 { 191 ReceivedNonce: 1, 192 SentNonce: 2, 193 ObservedAddress: "192.168.1.1:50000", 194 Timestamp: &tspb.Timestamp{Seconds: 1514303000, Nanos: 0}, 195 }, 196 { 197 ReceivedNonce: 2, 198 SentNonce: 3, 199 ObservedAddress: "192.168.1.1:50001", 200 Timestamp: &tspb.Timestamp{Seconds: 1514303001, Nanos: 0}, 201 }, 202 { 203 ReceivedNonce: 3, 204 SentNonce: 4, 205 ObservedAddress: "192.168.1.1:50002", 206 Timestamp: &tspb.Timestamp{Seconds: 1514303002, Nanos: 10}, 207 }, 208 { 209 ReceivedNonce: 3, 210 SentNonce: 5, 211 ObservedAddress: "192.168.1.2:50003", 212 Timestamp: &tspb.Timestamp{Seconds: 1514303002, Nanos: 20}, 213 }, 214 { 215 ReceivedNonce: 4, 216 SentNonce: 6, 217 ObservedAddress: "192.168.1.1:50004", 218 Timestamp: &tspb.Timestamp{Seconds: 1514303003, Nanos: 10}, 219 }, 220 { 221 ReceivedNonce: 5, 222 SentNonce: 7, 223 ObservedAddress: "192.168.1.2:50005", 224 Timestamp: &tspb.Timestamp{Seconds: 1514303003, Nanos: 20}, 225 }, 226 { 227 ReceivedNonce: 6, 228 SentNonce: 8, 229 ObservedAddress: "192.168.1.1:50000", 230 Timestamp: &tspb.Timestamp{Seconds: 1514303004, Nanos: 10}, 231 }, 232 { 233 ReceivedNonce: 7, 234 SentNonce: 9, 235 ObservedAddress: "192.168.1.2:50001", 236 Timestamp: &tspb.Timestamp{Seconds: 1514303004, Nanos: 20}, 237 }, 238 { 239 ReceivedNonce: 8, 240 SentNonce: 10, 241 ObservedAddress: "192.168.1.1:50002", 242 Timestamp: &tspb.Timestamp{Seconds: 1514303005, Nanos: 10}, 243 }, 244 { 245 ReceivedNonce: 9, 246 SentNonce: 11, 247 ObservedAddress: "192.168.1.2:50003", 248 Timestamp: &tspb.Timestamp{Seconds: 1514303005, Nanos: 20}, 249 }, 250 { 251 ReceivedNonce: 10, 252 SentNonce: 12, 253 ObservedAddress: "192.168.1.1:50004", 254 Timestamp: &tspb.Timestamp{Seconds: 1514303006, Nanos: 10}, 255 }, 256 { 257 ReceivedNonce: 11, 258 SentNonce: 13, 259 ObservedAddress: "192.168.1.2:50005", 260 Timestamp: &tspb.Timestamp{Seconds: 1514303006, Nanos: 20}, 261 }, 262 }, 263 want: Summary{ 264 Start: time.Unix(1514303000, 0).UTC(), 265 End: time.Unix(1514303006, 20).UTC(), 266 Count: 12, 267 IPCount: 2, 268 Splits: 1, 269 SplitPoints: 1, 270 Skips: 9, 271 }, 272 }, 273 } { 274 got, err := Summarize(tc.in) 275 if tc.wantErr { 276 if err == nil { 277 t.Errorf("Summarize(%s) succeeded, but want error.", tc.name) 278 } 279 } else { 280 if err != nil { 281 t.Errorf("Summarize(%s) returned error: %v", tc.name, err) 282 } 283 if *got != tc.want { 284 t.Errorf("Summarize(%s) = %+v, but want %+v", tc.name, got, tc.want) 285 } 286 } 287 } 288 }