@@ -282,7 +282,7 @@ impl Resource {
282
282
for resource in resources {
283
283
if let Resource :: Port ( address, protocol) = & resource {
284
284
if address. ip ( ) . is_unspecified ( ) {
285
- unspecified. push ( ( key. clone ( ) , address. port ( ) , * protocol) ) ;
285
+ unspecified. push ( ( key. clone ( ) , * address, * protocol) ) ;
286
286
}
287
287
}
288
288
@@ -296,10 +296,13 @@ impl Resource {
296
296
// Port with unspecified address will bind to all network interfaces
297
297
// so we have to check for all Port resources if they share the same
298
298
// port.
299
- for ( key, port , protocol0) in unspecified {
299
+ for ( key, address0 , protocol0) in unspecified {
300
300
for ( resource, components) in resource_map. iter_mut ( ) {
301
301
if let Resource :: Port ( address, protocol) = resource {
302
- if address. port ( ) == port && & protocol0 == protocol {
302
+ // IP addresses can either be v4 or v6.
303
+ // Therefore we check if the ip version matches, the port matches and if the protocol (TCP/UDP) matches
304
+ // when checking for equality.
305
+ if & address0 == address && & protocol0 == protocol {
303
306
components. insert ( key. clone ( ) ) ;
304
307
}
305
308
}
@@ -1259,20 +1262,38 @@ mod acknowledgements_tests {
1259
1262
}
1260
1263
}
1261
1264
1262
- #[ cfg( all ( test, feature = "sources-stdin" , feature = "sinks-console" ) ) ]
1265
+ #[ cfg( test) ]
1263
1266
mod resource_tests {
1264
1267
use std:: {
1265
1268
collections:: { HashMap , HashSet } ,
1266
- net:: { Ipv4Addr , SocketAddr } ,
1269
+ net:: { IpAddr , Ipv4Addr , Ipv6Addr , SocketAddr } ,
1267
1270
} ;
1268
1271
1269
- use indoc:: indoc;
1270
- use vector_config:: schema:: generate_root_schema;
1272
+ use proptest:: prelude:: * ;
1273
+
1274
+ use super :: Resource ;
1275
+
1276
+ fn tcp ( addr : impl Into < IpAddr > , port : u16 ) -> Resource {
1277
+ Resource :: tcp ( SocketAddr :: new ( addr. into ( ) , port) )
1278
+ }
1279
+
1280
+ fn udp ( addr : impl Into < IpAddr > , port : u16 ) -> Resource {
1281
+ Resource :: udp ( SocketAddr :: new ( addr. into ( ) , port) )
1282
+ }
1271
1283
1272
- use super :: { load_from_str, Format , Resource } ;
1284
+ fn unspecified ( ) -> impl Strategy < Value = IpAddr > {
1285
+ prop_oneof ! [
1286
+ Just ( Ipv4Addr :: UNSPECIFIED . into( ) ) ,
1287
+ Just ( Ipv6Addr :: UNSPECIFIED . into( ) ) ,
1288
+ ]
1289
+ }
1290
+
1291
+ fn specaddr ( ) -> impl Strategy < Value = IpAddr > {
1292
+ any :: < IpAddr > ( ) . prop_filter ( "Must be specific address" , |addr| !addr. is_unspecified ( ) )
1293
+ }
1273
1294
1274
- fn localhost ( port : u16 ) -> Resource {
1275
- Resource :: tcp ( SocketAddr :: new ( Ipv4Addr :: LOCALHOST . into ( ) , port) )
1295
+ fn specport ( ) -> impl Strategy < Value = u16 > {
1296
+ any :: < u16 > ( ) . prop_filter ( "Must be specific port" , | & port| port > 0 )
1276
1297
}
1277
1298
1278
1299
fn hashmap ( conflicts : Vec < ( Resource , Vec < & str > ) > ) -> HashMap < Resource , HashSet < & str > > {
@@ -1282,104 +1303,98 @@ mod resource_tests {
1282
1303
. collect ( )
1283
1304
}
1284
1305
1285
- #[ test]
1286
- fn valid ( ) {
1287
- let components = vec ! [
1288
- ( "sink_0" , vec![ localhost( 0 ) ] ) ,
1289
- ( "sink_1" , vec![ localhost( 1 ) ] ) ,
1290
- ( "sink_2" , vec![ localhost( 2 ) ] ) ,
1291
- ] ;
1292
- let conflicting = Resource :: conflicts ( components) ;
1293
- assert_eq ! ( conflicting, HashMap :: new( ) ) ;
1294
- }
1306
+ proptest ! {
1307
+ #[ test]
1308
+ fn valid( addr: IpAddr , port1 in specport( ) , port2 in specport( ) ) {
1309
+ let components = vec![
1310
+ ( "sink_0" , vec![ tcp( addr, 0 ) ] ) ,
1311
+ ( "sink_1" , vec![ tcp( addr, port1) ] ) ,
1312
+ ( "sink_2" , vec![ tcp( addr, port2) ] ) ,
1313
+ ] ;
1314
+ let conflicting = Resource :: conflicts( components) ;
1315
+ assert_eq!( conflicting, HashMap :: new( ) ) ;
1316
+ }
1295
1317
1296
- #[ test]
1297
- fn conflicting_pair ( ) {
1298
- let components = vec ! [
1299
- ( "sink_0" , vec![ localhost ( 0 ) ] ) ,
1300
- ( "sink_1" , vec![ localhost ( 2 ) ] ) ,
1301
- ( "sink_2" , vec![ localhost ( 2 ) ] ) ,
1302
- ] ;
1303
- let conflicting = Resource :: conflicts ( components) ;
1304
- assert_eq ! (
1305
- conflicting,
1306
- hashmap( vec![ ( localhost ( 2 ) , vec![ "sink_1" , "sink_2" ] ) ] )
1307
- ) ;
1308
- }
1318
+ #[ test]
1319
+ fn conflicting_pair( addr : IpAddr , port in specport ( ) ) {
1320
+ let components = vec![
1321
+ ( "sink_0" , vec![ tcp ( addr , 0 ) ] ) ,
1322
+ ( "sink_1" , vec![ tcp ( addr , port ) ] ) ,
1323
+ ( "sink_2" , vec![ tcp ( addr , port ) ] ) ,
1324
+ ] ;
1325
+ let conflicting = Resource :: conflicts( components) ;
1326
+ assert_eq!(
1327
+ conflicting,
1328
+ hashmap( vec![ ( tcp ( addr , port ) , vec![ "sink_1" , "sink_2" ] ) ] )
1329
+ ) ;
1330
+ }
1309
1331
1310
- #[ test]
1311
- fn conflicting_multi ( ) {
1312
- let components = vec ! [
1313
- ( "sink_0" , vec![ localhost ( 0 ) ] ) ,
1314
- ( "sink_1" , vec![ localhost ( 2 ) , localhost ( 0 ) ] ) ,
1315
- ( "sink_2" , vec![ localhost ( 2 ) ] ) ,
1316
- ] ;
1317
- let conflicting = Resource :: conflicts ( components) ;
1318
- assert_eq ! (
1319
- conflicting,
1320
- hashmap( vec![
1321
- ( localhost ( 0 ) , vec![ "sink_0" , "sink_1" ] ) ,
1322
- ( localhost ( 2 ) , vec![ "sink_1" , "sink_2" ] )
1323
- ] )
1324
- ) ;
1325
- }
1332
+ #[ test]
1333
+ fn conflicting_multi( addr : IpAddr , port in specport ( ) ) {
1334
+ let components = vec![
1335
+ ( "sink_0" , vec![ tcp ( addr , 0 ) ] ) ,
1336
+ ( "sink_1" , vec![ tcp ( addr , port ) , tcp ( addr , 0 ) ] ) ,
1337
+ ( "sink_2" , vec![ tcp ( addr , port ) ] ) ,
1338
+ ] ;
1339
+ let conflicting = Resource :: conflicts( components) ;
1340
+ assert_eq!(
1341
+ conflicting,
1342
+ hashmap( vec![
1343
+ ( tcp ( addr , 0 ) , vec![ "sink_0" , "sink_1" ] ) ,
1344
+ ( tcp ( addr , port ) , vec![ "sink_1" , "sink_2" ] )
1345
+ ] )
1346
+ ) ;
1347
+ }
1326
1348
1327
- #[ test]
1328
- fn different_network_interface ( ) {
1329
- let components = vec ! [
1330
- ( "sink_0" , vec![ localhost( 0 ) ] ) ,
1331
- (
1332
- "sink_1" ,
1333
- vec![ Resource :: tcp( SocketAddr :: new(
1334
- Ipv4Addr :: new( 127 , 0 , 0 , 2 ) . into( ) ,
1335
- 0 ,
1336
- ) ) ] ,
1337
- ) ,
1338
- ] ;
1339
- let conflicting = Resource :: conflicts ( components) ;
1340
- assert_eq ! ( conflicting, HashMap :: new( ) ) ;
1341
- }
1349
+ #[ test]
1350
+ fn different_network_interface( addr1: IpAddr , addr2: IpAddr , port: u16 ) {
1351
+ prop_assume!( addr1 != addr2) ;
1352
+ let components = vec![
1353
+ ( "sink_0" , vec![ tcp( addr1, port) ] ) ,
1354
+ ( "sink_1" , vec![ tcp( addr2, port) ] ) ,
1355
+ ] ;
1356
+ let conflicting = Resource :: conflicts( components) ;
1357
+ assert_eq!( conflicting, HashMap :: new( ) ) ;
1358
+ }
1342
1359
1343
- #[ test]
1344
- fn unspecified_network_interface ( ) {
1345
- let components = vec ! [
1346
- ( "sink_0" , vec![ localhost( 0 ) ] ) ,
1347
- (
1348
- "sink_1" ,
1349
- vec![ Resource :: tcp( SocketAddr :: new(
1350
- Ipv4Addr :: UNSPECIFIED . into( ) ,
1351
- 0 ,
1352
- ) ) ] ,
1353
- ) ,
1354
- ] ;
1355
- let conflicting = Resource :: conflicts ( components) ;
1356
- assert_eq ! (
1357
- conflicting,
1358
- hashmap( vec![ ( localhost( 0 ) , vec![ "sink_0" , "sink_1" ] ) ] )
1359
- ) ;
1360
+ #[ test]
1361
+ fn unspecified_network_interface( addr in specaddr( ) , unspec in unspecified( ) , port: u16 ) {
1362
+ let components = vec![
1363
+ ( "sink_0" , vec![ tcp( addr, port) ] ) ,
1364
+ ( "sink_1" , vec![ tcp( unspec, port) ] ) ,
1365
+ ] ;
1366
+ let conflicting = Resource :: conflicts( components) ;
1367
+ assert_eq!( conflicting, HashMap :: new( ) ) ;
1368
+ }
1369
+
1370
+ #[ test]
1371
+ fn different_protocol( addr: IpAddr ) {
1372
+ let components = vec![
1373
+ ( "sink_0" , vec![ tcp( addr, 0 ) ] ) ,
1374
+ ( "sink_1" , vec![ udp( addr, 0 ) ] ) ,
1375
+ ] ;
1376
+ let conflicting = Resource :: conflicts( components) ;
1377
+ assert_eq!( conflicting, HashMap :: new( ) ) ;
1378
+ }
1360
1379
}
1361
1380
1362
1381
#[ test]
1363
- fn different_protocol ( ) {
1382
+ fn different_unspecified_ip_version ( ) {
1364
1383
let components = vec ! [
1365
- (
1366
- "sink_0" ,
1367
- vec![ Resource :: tcp( SocketAddr :: new(
1368
- Ipv4Addr :: LOCALHOST . into( ) ,
1369
- 0 ,
1370
- ) ) ] ,
1371
- ) ,
1372
- (
1373
- "sink_1" ,
1374
- vec![ Resource :: udp( SocketAddr :: new(
1375
- Ipv4Addr :: LOCALHOST . into( ) ,
1376
- 0 ,
1377
- ) ) ] ,
1378
- ) ,
1384
+ ( "sink_0" , vec![ tcp( Ipv4Addr :: UNSPECIFIED , 0 ) ] ) ,
1385
+ ( "sink_1" , vec![ tcp( Ipv6Addr :: UNSPECIFIED , 0 ) ] ) ,
1379
1386
] ;
1380
1387
let conflicting = Resource :: conflicts ( components) ;
1381
1388
assert_eq ! ( conflicting, HashMap :: new( ) ) ;
1382
1389
}
1390
+ }
1391
+
1392
+ #[ cfg( all( test, feature = "sources-stdin" , feature = "sinks-console" ) ) ]
1393
+ mod resource_config_tests {
1394
+ use indoc:: indoc;
1395
+ use vector_config:: schema:: generate_root_schema;
1396
+
1397
+ use super :: { load_from_str, Format } ;
1383
1398
1384
1399
#[ test]
1385
1400
fn config_conflict_detected ( ) {
0 commit comments