@@ -466,22 +466,25 @@ impl DerpNodeCache {
466466///
467467/// This uses the latencies from the last report to determine the order. Regions with no
468468/// data are at the end.
469- fn sort_regions < ' a > ( dm : & ' a DerpMap , last : & Report ) -> Vec < & ' a DerpRegion > {
470- let mut prev: Vec < _ > = dm . regions . values ( ) . filter ( |r| !r. avoid ) . collect ( ) ;
469+ fn sort_regions < ' a > ( derp_map : & ' a DerpMap , last_report : & Report ) -> Vec < & ' a DerpRegion > {
470+ let mut prev: Vec < _ > = derp_map . regions . values ( ) . filter ( |r| !r. avoid ) . collect ( ) ;
471471 prev. sort_by ( |a, b| {
472- let da = last . region_latency . get ( a. region_id ) ;
473- let db = last . region_latency . get ( b. region_id ) ;
474- match ( da , db ) {
472+ let latencies_a = last_report . region_latency . get ( a. region_id ) ;
473+ let latencies_b = last_report . region_latency . get ( b. region_id ) ;
474+ match ( latencies_a , latencies_b ) {
475475 ( Some ( _) , None ) => {
476476 // Non-zero sorts before zero.
477- std:: cmp:: Ordering :: Greater
477+ std:: cmp:: Ordering :: Less
478478 }
479479 ( None , Some ( _) ) => {
480480 // Zero can't sort before anything else.
481+ std:: cmp:: Ordering :: Greater
482+ }
483+ ( None , None ) => {
484+ // For both empty latencies sort by region_id.
481485 a. region_id . cmp ( & b. region_id )
482486 }
483- ( None , None ) => std:: cmp:: Ordering :: Equal ,
484- ( Some ( _) , Some ( _) ) => match da. cmp ( & db) {
487+ ( Some ( _) , Some ( _) ) => match latencies_a. cmp ( & latencies_b) {
485488 std:: cmp:: Ordering :: Equal => a. region_id . cmp ( & b. region_id ) ,
486489 x => x,
487490 } ,
@@ -883,4 +886,91 @@ mod tests {
883886 assert_eq ! ( plan. to_string( ) , expected_plan. to_string( ) , "{}" , i) ;
884887 }
885888 }
889+
890+ fn create_last_report ( latency_1 : Option < Duration > , latency_2 : Option < Duration > ) -> Report {
891+ let mut latencies = RegionLatencies :: new ( ) ;
892+ if let Some ( latency_1) = latency_1 {
893+ latencies. update_region ( 1 , latency_1) ;
894+ }
895+ if let Some ( latency_2) = latency_2 {
896+ latencies. update_region ( 2 , latency_2) ;
897+ }
898+ Report {
899+ udp : true ,
900+ ipv6 : true ,
901+ ipv4 : true ,
902+ ipv6_can_send : true ,
903+ ipv4_can_send : true ,
904+ os_has_ipv6 : true ,
905+ icmpv4 : true ,
906+ mapping_varies_by_dest_ip : Some ( false ) ,
907+ hair_pinning : Some ( true ) ,
908+ portmap_probe : None ,
909+ preferred_derp : 1 ,
910+ region_latency : latencies. clone ( ) ,
911+ region_v4_latency : latencies. clone ( ) ,
912+ region_v6_latency : latencies. clone ( ) ,
913+ global_v4 : None ,
914+ global_v6 : None ,
915+ captive_portal : None ,
916+ }
917+ }
918+
919+ #[ test]
920+ fn test_derp_region_sort_two_latencies ( ) {
921+ let derp_map = default_derp_map ( ) ;
922+ let last_report = create_last_report (
923+ Some ( Duration :: from_millis ( 1 ) ) ,
924+ Some ( Duration :: from_millis ( 2 ) ) ,
925+ ) ;
926+ let sorted: Vec < _ > = sort_regions ( & derp_map, & last_report)
927+ . iter ( )
928+ . map ( |reg| reg. region_id )
929+ . collect ( ) ;
930+ assert_eq ! ( sorted, vec![ 1 , 2 ] ) ;
931+ }
932+
933+ #[ test]
934+ fn test_derp_region_sort_equal_latencies ( ) {
935+ let derp_map = default_derp_map ( ) ;
936+ let last_report = create_last_report (
937+ Some ( Duration :: from_millis ( 2 ) ) ,
938+ Some ( Duration :: from_millis ( 2 ) ) ,
939+ ) ;
940+ let sorted: Vec < _ > = sort_regions ( & derp_map, & last_report)
941+ . iter ( )
942+ . map ( |reg| reg. region_id )
943+ . collect ( ) ;
944+ assert_eq ! ( sorted, vec![ 1 , 2 ] ) ;
945+ }
946+
947+ #[ test]
948+ fn test_derp_region_sort_missing_latency ( ) {
949+ let derp_map = default_derp_map ( ) ;
950+ let last_report = create_last_report ( None , Some ( Duration :: from_millis ( 2 ) ) ) ;
951+ let sorted: Vec < _ > = sort_regions ( & derp_map, & last_report)
952+ . iter ( )
953+ . map ( |reg| reg. region_id )
954+ . collect ( ) ;
955+ assert_eq ! ( sorted, vec![ 2 , 1 ] ) ;
956+
957+ let last_report = create_last_report ( Some ( Duration :: from_millis ( 2 ) ) , None ) ;
958+ let sorted: Vec < _ > = sort_regions ( & derp_map, & last_report)
959+ . iter ( )
960+ . map ( |reg| reg. region_id )
961+ . collect ( ) ;
962+ assert_eq ! ( sorted, vec![ 1 , 2 ] ) ;
963+ }
964+
965+ #[ test]
966+ fn test_derp_region_sort_no_latency ( ) {
967+ let derp_map = default_derp_map ( ) ;
968+ let last_report = create_last_report ( None , None ) ;
969+ let sorted: Vec < _ > = sort_regions ( & derp_map, & last_report)
970+ . iter ( )
971+ . map ( |reg| reg. region_id )
972+ . collect ( ) ;
973+ // sorted by region id only
974+ assert_eq ! ( sorted, vec![ 1 , 2 ] ) ;
975+ }
886976}
0 commit comments