2021-04-29 16:12:53 -04:00
/*! Unit tests that require access to the testing-only function
BridgeLine ::random ( ) or private fields * /
2023-03-27 12:36:57 -04:00
use super ::bridge_table ::{ BridgeLine , BRIDGE_BYTES } ;
2021-05-01 15:21:50 -04:00
use super ::proto ::* ;
2021-04-29 16:12:53 -04:00
use super ::* ;
2023-07-10 17:03:10 -04:00
use chrono ::{ DateTime , NaiveTime , Timelike , Utc } ;
2021-07-06 18:08:52 -04:00
use rand ::Rng ;
2023-07-10 17:03:10 -04:00
use std ::thread ;
2021-06-02 12:18:58 -04:00
use std ::time ::{ Duration , Instant } ;
struct PerfStat {
// Report performance metrics for each test
req_len : usize ,
resp_len : usize ,
req_t : Duration ,
resp_t : Duration ,
resp_handle_t : Duration ,
}
2021-04-29 16:12:53 -04:00
2021-05-04 18:26:58 -04:00
struct TestHarness {
bdb : BridgeDb ,
pub ba : BridgeAuth ,
}
impl TestHarness {
fn new ( ) -> Self {
2021-06-15 02:01:24 -04:00
TestHarness ::new_buckets ( 5 , 5 )
}
2021-11-22 22:56:48 -05:00
fn new_buckets ( num_buckets : u16 , hot_spare : u16 ) -> Self {
2021-05-04 18:26:58 -04:00
// Create a BridegDb
2021-05-05 13:58:43 -04:00
let mut bdb = BridgeDb ::new ( ) ;
2021-05-04 18:26:58 -04:00
// Create a BridgeAuth
let mut ba = BridgeAuth ::new ( bdb . pubkey ) ;
2021-06-21 12:05:35 -04:00
// Make 3 x num_buckets open invitation bridges, in sets of 3
2021-06-15 02:01:24 -04:00
for _ in 0 .. num_buckets {
2021-05-05 13:58:43 -04:00
let bucket = [
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
] ;
ba . add_openinv_bridges ( bucket , & mut bdb ) ;
2021-05-04 18:26:58 -04:00
}
2021-06-21 12:05:35 -04:00
// Add hot_spare more hot spare buckets
2021-06-15 02:01:24 -04:00
for _ in 0 .. hot_spare {
2021-05-05 13:58:43 -04:00
let bucket = [
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
2021-05-04 18:26:58 -04:00
] ;
2021-05-05 13:58:43 -04:00
ba . add_spare_bucket ( bucket ) ;
2021-05-04 18:26:58 -04:00
}
// Create the encrypted bridge table
ba . enc_bridge_table ( ) ;
Self { bdb , ba }
2021-04-29 16:12:53 -04:00
}
2021-05-04 18:26:58 -04:00
fn advance_days ( & mut self , days : u16 ) {
self . ba . advance_days ( days ) ;
}
2021-04-29 16:12:53 -04:00
2021-06-02 12:18:58 -04:00
fn open_invite ( & mut self ) -> ( PerfStat , ( cred ::Lox , bridge_table ::BridgeLine ) ) {
2021-05-04 18:26:58 -04:00
// Issue an open invitation
let inv = self . bdb . invite ( ) ;
2021-04-29 16:12:53 -04:00
2021-06-02 12:18:58 -04:00
let req_start = Instant ::now ( ) ;
2021-05-04 18:26:58 -04:00
// Use it to get a Lox credential
let ( req , state ) = open_invite ::request ( & inv ) ;
2021-06-01 15:07:28 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & req ) . unwrap ( ) ;
2021-06-02 12:18:58 -04:00
let req_t = req_start . elapsed ( ) ;
2021-06-01 15:07:28 -04:00
let req_len = encoded . len ( ) ;
2021-06-02 12:18:58 -04:00
let resp_start = Instant ::now ( ) ;
2021-06-02 12:56:43 -04:00
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
2021-06-01 15:07:28 -04:00
let resp = self . ba . handle_open_invite ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & resp ) . unwrap ( ) ;
2021-06-02 12:18:58 -04:00
let resp_t = resp_start . elapsed ( ) ;
2021-06-01 15:07:28 -04:00
let resp_len = encoded_resp . len ( ) ;
2021-06-02 12:18:58 -04:00
let resp_handle_start = Instant ::now ( ) ;
2021-06-02 12:56:43 -04:00
let decode_resp = bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
2021-06-02 12:18:58 -04:00
let ( cred , bridgeline ) =
open_invite ::handle_response ( state , decode_resp , & self . ba . lox_pub ) . unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-02 12:18:58 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
( cred , bridgeline ) ,
2021-07-06 18:08:52 -04:00
)
2021-05-04 18:26:58 -04:00
}
2021-04-29 16:12:53 -04:00
2021-06-03 01:07:35 -04:00
fn trust_promotion ( & mut self , cred : & cred ::Lox ) -> ( PerfStat , cred ::Migration ) {
let req_start = Instant ::now ( ) ;
2021-05-04 18:26:58 -04:00
let ( promreq , promstate ) =
2022-10-18 00:51:17 -04:00
trust_promotion ::request ( cred , & self . ba . lox_pub , self . ba . today ( ) ) . unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & promreq ) . unwrap ( ) ;
let req_t = req_start . elapsed ( ) ;
let req_len = encoded . len ( ) ;
let resp_start = Instant ::now ( ) ;
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
let promresp = self . ba . handle_trust_promotion ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & promresp ) . unwrap ( ) ;
let resp_t = resp_start . elapsed ( ) ;
let resp_len = encoded_resp . len ( ) ;
let resp_handle_start = Instant ::now ( ) ;
let decode_resp = bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
let migcred = trust_promotion ::handle_response ( promstate , decode_resp ) . unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-03 01:07:35 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
migcred ,
2021-07-06 18:08:52 -04:00
)
2021-04-29 16:12:53 -04:00
}
2021-05-04 18:26:58 -04:00
2021-06-03 01:07:35 -04:00
fn level0_migration (
& mut self ,
loxcred : & cred ::Lox ,
migcred : & cred ::Migration ,
) -> ( PerfStat , cred ::Lox ) {
let req_start = Instant ::now ( ) ;
2021-05-04 18:26:58 -04:00
let ( migreq , migstate ) =
migration ::request ( loxcred , migcred , & self . ba . lox_pub , & self . ba . migration_pub ) . unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & migreq ) . unwrap ( ) ;
let req_t = req_start . elapsed ( ) ;
let req_len = encoded . len ( ) ;
let resp_start = Instant ::now ( ) ;
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
let migresp = self . ba . handle_migration ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & migresp ) . unwrap ( ) ;
let resp_t = resp_start . elapsed ( ) ;
let resp_len = encoded_resp . len ( ) ;
let resp_handle_start = Instant ::now ( ) ;
let decode_resp : migration ::Response = bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
let cred = migration ::handle_response ( migstate , decode_resp , & self . ba . lox_pub ) . unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-03 01:07:35 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
cred ,
2021-07-06 18:08:52 -04:00
)
2021-04-29 16:12:53 -04:00
}
2021-06-03 01:07:35 -04:00
fn level_up ( & mut self , cred : & cred ::Lox ) -> ( PerfStat , cred ::Lox ) {
2021-05-04 18:26:58 -04:00
// Read the bucket in the credential to get today's Bucket
// Reachability credential
2021-06-03 01:07:35 -04:00
2021-05-04 18:26:58 -04:00
let ( id , key ) = bridge_table ::from_scalar ( cred . bucket ) . unwrap ( ) ;
let encbuckets = self . ba . enc_bridge_table ( ) ;
let bucket =
2023-07-19 10:30:35 -04:00
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , encbuckets . get ( & id ) . unwrap ( ) )
. unwrap ( ) ;
2023-07-10 17:03:10 -04:00
2021-05-04 18:26:58 -04:00
let reachcred = bucket . 1. unwrap ( ) ;
// Use the Bucket Reachability credential to advance to the next
// level
2021-06-03 01:07:35 -04:00
let req_start = Instant ::now ( ) ;
2021-05-04 18:26:58 -04:00
let ( req , state ) = level_up ::request (
2022-10-18 00:51:17 -04:00
cred ,
2021-05-04 18:26:58 -04:00
& reachcred ,
& self . ba . lox_pub ,
& self . ba . reachability_pub ,
self . ba . today ( ) ,
)
. unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & req ) . unwrap ( ) ;
let req_t = req_start . elapsed ( ) ;
let req_len = encoded . len ( ) ;
let resp_start = Instant ::now ( ) ;
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
let resp = self . ba . handle_level_up ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & resp ) . unwrap ( ) ;
let resp_t = resp_start . elapsed ( ) ;
let resp_len = encoded_resp . len ( ) ;
let resp_handle_start = Instant ::now ( ) ;
let decode_resp = bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
let cred = level_up ::handle_response ( state , decode_resp , & self . ba . lox_pub ) . unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-03 01:07:35 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
cred ,
2021-07-06 18:08:52 -04:00
)
2021-05-04 18:26:58 -04:00
}
2021-04-30 16:24:42 -04:00
2021-06-03 01:07:35 -04:00
fn issue_invite ( & mut self , cred : & cred ::Lox ) -> ( PerfStat , ( cred ::Lox , cred ::Invitation ) ) {
2021-05-04 18:26:58 -04:00
// Read the bucket in the credential to get today's Bucket
// Reachability credential
let ( id , key ) = bridge_table ::from_scalar ( cred . bucket ) . unwrap ( ) ;
let encbuckets = self . ba . enc_bridge_table ( ) ;
let bucket =
2023-07-19 10:30:35 -04:00
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , encbuckets . get ( & id ) . unwrap ( ) )
. unwrap ( ) ;
2021-05-04 18:26:58 -04:00
let reachcred = bucket . 1. unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let req_start = Instant ::now ( ) ;
2021-05-04 18:26:58 -04:00
let ( req , state ) = issue_invite ::request (
2022-10-18 00:51:17 -04:00
cred ,
2021-05-04 18:26:58 -04:00
& reachcred ,
& self . ba . lox_pub ,
& self . ba . reachability_pub ,
self . ba . today ( ) ,
)
. unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & req ) . unwrap ( ) ;
let req_t = req_start . elapsed ( ) ;
let req_len = encoded . len ( ) ;
let resp_start = Instant ::now ( ) ;
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
let resp = self . ba . handle_issue_invite ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & resp ) . unwrap ( ) ;
let resp_t = resp_start . elapsed ( ) ;
let resp_len = encoded_resp . len ( ) ;
let resp_handle_start = Instant ::now ( ) ;
let decode_resp = bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
let ( cred , invite ) = issue_invite ::handle_response (
state ,
decode_resp ,
& self . ba . lox_pub ,
& self . ba . invitation_pub ,
)
. unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-03 01:07:35 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
( cred , invite ) ,
2021-07-06 18:08:52 -04:00
)
2021-05-04 18:26:58 -04:00
}
2021-04-29 16:12:53 -04:00
2021-06-03 01:07:35 -04:00
fn redeem_invite ( & mut self , inv : & cred ::Invitation ) -> ( PerfStat , cred ::Lox ) {
let req_start = Instant ::now ( ) ;
2021-05-04 18:26:58 -04:00
let ( req , state ) =
2022-10-18 00:51:17 -04:00
redeem_invite ::request ( inv , & self . ba . invitation_pub , self . ba . today ( ) ) . unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & req ) . unwrap ( ) ;
let req_t = req_start . elapsed ( ) ;
let req_len = encoded . len ( ) ;
let resp_start = Instant ::now ( ) ;
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
let resp = self . ba . handle_redeem_invite ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & resp ) . unwrap ( ) ;
let resp_t = resp_start . elapsed ( ) ;
let resp_len = encoded_resp . len ( ) ;
let resp_handle_start = Instant ::now ( ) ;
let decode_resp = bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
let cred = redeem_invite ::handle_response ( state , decode_resp , & self . ba . lox_pub ) . unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-03 01:07:35 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
cred ,
2021-07-06 18:08:52 -04:00
)
2021-05-04 18:26:58 -04:00
}
2021-05-05 16:28:56 -04:00
2021-06-03 01:07:35 -04:00
fn check_blockage ( & mut self , cred : & cred ::Lox ) -> ( PerfStat , cred ::Migration ) {
let req_start = Instant ::now ( ) ;
2022-10-18 00:51:17 -04:00
let ( req , state ) = check_blockage ::request ( cred , & self . ba . lox_pub ) . unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & req ) . unwrap ( ) ;
let req_t = req_start . elapsed ( ) ;
let req_len = encoded . len ( ) ;
let resp_start = Instant ::now ( ) ;
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
let resp = self . ba . handle_check_blockage ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & resp ) . unwrap ( ) ;
let resp_t = resp_start . elapsed ( ) ;
let resp_len = encoded_resp . len ( ) ;
let resp_handle_start = Instant ::now ( ) ;
let decode_resp = bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
let migcred = check_blockage ::handle_response ( state , decode_resp ) . unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-03 01:07:35 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
migcred ,
2021-07-06 18:08:52 -04:00
)
2021-05-05 16:28:56 -04:00
}
2021-05-05 18:21:09 -04:00
2021-06-03 01:07:35 -04:00
fn blockage_migration (
& mut self ,
cred : & cred ::Lox ,
mig : & cred ::Migration ,
) -> ( PerfStat , cred ::Lox ) {
let req_start = Instant ::now ( ) ;
2021-05-05 18:21:09 -04:00
let ( req , state ) =
2022-10-18 00:51:17 -04:00
blockage_migration ::request ( cred , mig , & self . ba . lox_pub , & self . ba . migration_pub )
2021-05-05 18:21:09 -04:00
. unwrap ( ) ;
2021-06-03 01:07:35 -04:00
let encoded : Vec < u8 > = bincode ::serialize ( & req ) . unwrap ( ) ;
let req_t = req_start . elapsed ( ) ;
let req_len = encoded . len ( ) ;
let resp_start = Instant ::now ( ) ;
let decoded = bincode ::deserialize ( & encoded [ .. ] ) . unwrap ( ) ;
let resp = self . ba . handle_blockage_migration ( decoded ) . unwrap ( ) ;
let encoded_resp : Vec < u8 > = bincode ::serialize ( & resp ) . unwrap ( ) ;
let resp_t = resp_start . elapsed ( ) ;
let resp_len = encoded_resp . len ( ) ;
let resp_handle_start = Instant ::now ( ) ;
let decode_resp : blockage_migration ::Response =
bincode ::deserialize ( & encoded_resp [ .. ] ) . unwrap ( ) ;
let cred =
blockage_migration ::handle_response ( state , decode_resp , & self . ba . lox_pub ) . unwrap ( ) ;
let resp_handle_t = resp_handle_start . elapsed ( ) ;
2021-07-06 18:08:52 -04:00
(
2021-06-03 01:07:35 -04:00
PerfStat {
req_len ,
resp_len ,
req_t ,
resp_t ,
resp_handle_t ,
} ,
cred ,
2021-07-06 18:08:52 -04:00
)
2021-05-05 18:21:09 -04:00
}
2021-05-04 18:26:58 -04:00
}
2021-04-29 16:12:53 -04:00
2022-04-03 01:54:53 -04:00
#[ test ]
2021-05-04 18:26:58 -04:00
fn test_open_invite ( ) {
let mut th = TestHarness ::new ( ) ;
2021-04-29 18:22:06 -04:00
2021-05-04 18:26:58 -04:00
// Join an untrusted user
2021-06-02 12:18:58 -04:00
let ( perf_stat , ( cred , bridgeline ) ) = th . open_invite ( ) ;
2021-04-30 16:24:42 -04:00
2021-05-04 18:26:58 -04:00
// Check that we can use the credential to read a bucket
let ( id , key ) = bridge_table ::from_scalar ( cred . bucket ) . unwrap ( ) ;
let encbuckets = th . ba . enc_bridge_table ( ) ;
let bucket =
2023-06-20 20:04:17 -04:00
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , encbuckets . get ( & id ) . unwrap ( ) ) . unwrap ( ) ;
2021-06-22 14:43:15 -04:00
print_test_results ( perf_stat ) ;
2021-05-04 18:26:58 -04:00
println! ( " cred = {:?} " , cred ) ;
println! ( " bucket = {:?} " , bucket ) ;
2021-05-18 14:46:35 -04:00
println! ( " bridgeline = {:?} " , bridgeline ) ;
2021-05-04 18:26:58 -04:00
assert! ( bucket . 1. is_none ( ) ) ;
assert! ( th . ba . verify_lox ( & cred ) ) ;
2021-05-18 14:46:35 -04:00
assert! ( bridgeline = = bucket . 0 [ 0 ] ) ;
2021-04-30 16:24:42 -04:00
}
2022-04-03 01:54:53 -04:00
#[ test ]
2021-04-30 16:24:42 -04:00
fn test_trust_promotion ( ) {
2021-05-04 18:26:58 -04:00
let mut th = TestHarness ::new ( ) ;
2021-04-30 16:24:42 -04:00
2021-06-02 12:18:58 -04:00
let cred = th . open_invite ( ) . 1 . 0 ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred ) ) ;
// Time passes
th . advance_days ( 47 ) ;
2021-06-03 01:07:35 -04:00
let ( perf_stat , migcred ) = th . trust_promotion ( & cred ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_migration ( & migcred ) ) ;
2021-04-30 16:24:42 -04:00
2021-04-30 13:30:20 -04:00
// Check that we can use the to_bucket in the Migration credenital
// to read a bucket
let ( id , key ) = bridge_table ::from_scalar ( migcred . to_bucket ) . unwrap ( ) ;
2021-05-04 18:26:58 -04:00
let encbuckets = th . ba . enc_bridge_table ( ) ;
2021-05-01 17:12:03 -04:00
let bucket =
2023-06-20 20:04:17 -04:00
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , encbuckets . get ( & id ) . unwrap ( ) ) . unwrap ( ) ;
2021-06-22 14:43:15 -04:00
print_test_results ( perf_stat ) ;
2021-04-30 13:30:20 -04:00
println! ( " bucket = {:?} " , bucket ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_reachability ( & bucket . 1. unwrap ( ) ) ) ;
2021-05-01 22:25:32 -04:00
}
2022-04-03 01:54:53 -04:00
#[ test ]
2021-05-01 22:25:32 -04:00
fn test_level0_migration ( ) {
2021-05-04 18:26:58 -04:00
let mut th = TestHarness ::new ( ) ;
2021-06-02 12:18:58 -04:00
let cred = th . open_invite ( ) . 1 . 0 ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred ) ) ;
// Time passes
th . advance_days ( 47 ) ;
2021-05-01 22:25:32 -04:00
2021-06-03 01:07:35 -04:00
let ( perf_stat , migcred ) = th . trust_promotion ( & cred ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_migration ( & migcred ) ) ;
2021-06-22 14:43:15 -04:00
println! ( " --Trust Promotion to 1-- \n " ) ;
print_test_results ( perf_stat ) ;
2021-06-03 01:07:35 -04:00
let ( mperf_stat , newloxcred ) = th . level0_migration ( & cred , & migcred ) ;
2021-06-22 14:43:15 -04:00
println! ( " --Level 0 migration-- \n " ) ;
print_test_results ( mperf_stat ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & newloxcred ) ) ;
2021-04-30 16:24:42 -04:00
println! ( " newloxcred = {:?} " , newloxcred ) ;
// Check that we can use the credenital to read a bucket
let ( id , key ) = bridge_table ::from_scalar ( newloxcred . bucket ) . unwrap ( ) ;
2021-05-04 18:26:58 -04:00
let encbuckets = th . ba . enc_bridge_table ( ) ;
2021-05-01 17:12:03 -04:00
let bucket =
2023-06-20 20:04:17 -04:00
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , encbuckets . get ( & id ) . unwrap ( ) ) . unwrap ( ) ;
2021-04-30 16:24:42 -04:00
println! ( " bucket = {:?} " , bucket ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_reachability ( & bucket . 1. unwrap ( ) ) ) ;
2021-05-02 21:44:33 -04:00
}
2022-04-03 01:54:53 -04:00
#[ test ]
2021-05-02 21:44:33 -04:00
fn test_level_up ( ) {
2021-05-04 18:26:58 -04:00
let mut th = TestHarness ::new ( ) ;
// Join an untrusted user
2021-06-02 12:18:58 -04:00
let cred = th . open_invite ( ) . 1 . 0 ;
2021-05-04 18:26:58 -04:00
// Time passes
th . advance_days ( 47 ) ;
// Go up to level 1
2021-06-03 01:07:35 -04:00
let ( perf_stat , migcred ) = th . trust_promotion ( & cred ) ;
2021-06-22 14:43:15 -04:00
println! ( " --Trust Promotion to 1-- \n " ) ;
print_test_results ( perf_stat ) ;
2021-06-03 01:07:35 -04:00
let ( mperf_stat , cred1 ) = th . level0_migration ( & cred , & migcred ) ;
2021-06-22 14:43:15 -04:00
println! ( " --New Level 1 Credential-- \n " ) ;
print_test_results ( mperf_stat ) ;
2021-06-03 01:07:35 -04:00
2021-05-02 21:44:33 -04:00
assert! ( scalar_u32 ( & cred1 . trust_level ) . unwrap ( ) = = 1 ) ;
// Time passes
2021-05-04 18:26:58 -04:00
th . advance_days ( 20 ) ;
2021-05-02 21:44:33 -04:00
2021-06-03 01:07:35 -04:00
let ( two_perf_stat , cred2 ) = th . level_up ( & cred1 ) ;
2021-05-02 21:44:33 -04:00
assert! ( scalar_u32 ( & cred2 . trust_level ) . unwrap ( ) = = 2 ) ;
2021-06-22 14:43:15 -04:00
println! ( " --Upgrade to Level 2-- \n " ) ;
print_test_results ( two_perf_stat ) ;
2021-05-02 21:44:33 -04:00
println! ( " cred2 = {:?} " , cred2 ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred2 ) ) ;
2021-05-02 21:44:33 -04:00
// Time passes
2021-05-04 18:26:58 -04:00
th . advance_days ( 30 ) ;
2021-05-02 21:44:33 -04:00
2021-06-03 01:07:35 -04:00
let ( three_perf_stat , cred3 ) = th . level_up ( & cred2 ) ;
2021-05-02 21:44:33 -04:00
assert! ( scalar_u32 ( & cred3 . trust_level ) . unwrap ( ) = = 3 ) ;
2021-06-22 14:43:15 -04:00
println! ( " --Upgrade to Level 3-- \n " ) ;
print_test_results ( three_perf_stat ) ;
2021-05-02 21:44:33 -04:00
println! ( " cred3 = {:?} " , cred3 ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred3 ) ) ;
2021-05-02 21:44:33 -04:00
// Time passes
2021-05-04 18:26:58 -04:00
th . advance_days ( 60 ) ;
2021-05-02 21:44:33 -04:00
2021-06-03 01:07:35 -04:00
let ( four_perf_stat , cred4 ) = th . level_up ( & cred3 ) ;
2021-05-02 21:44:33 -04:00
assert! ( scalar_u32 ( & cred3 . trust_level ) . unwrap ( ) = = 3 ) ;
2021-06-22 14:43:15 -04:00
println! ( " --Upgrade to Level 4-- \n " ) ;
print_test_results ( four_perf_stat ) ;
2021-05-02 21:44:33 -04:00
println! ( " cred4 = {:?} " , cred4 ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred4 ) ) ;
2021-05-04 15:47:37 -04:00
}
2022-04-03 01:54:53 -04:00
#[ test ]
2021-05-04 15:47:37 -04:00
fn test_issue_invite ( ) {
2021-05-04 18:26:58 -04:00
let mut th = TestHarness ::new ( ) ;
// Join an untrusted user
2021-06-02 12:18:58 -04:00
let cred = th . open_invite ( ) . 1 . 0 ;
2021-05-04 18:26:58 -04:00
// Time passes
th . advance_days ( 47 ) ;
// Go up to level 1
2021-06-22 14:43:15 -04:00
let ( perf_stat , migcred ) = th . trust_promotion ( & cred ) ;
println! ( " --Trust Promotion to 1-- \n " ) ;
print_test_results ( perf_stat ) ;
let ( mperf_stat , cred1 ) = th . level0_migration ( & cred , & migcred ) ;
println! ( " --New Level 1 Credential-- \n " ) ;
print_test_results ( mperf_stat ) ;
2021-05-04 15:47:37 -04:00
assert! ( scalar_u32 ( & cred1 . trust_level ) . unwrap ( ) = = 1 ) ;
// Time passes
2021-05-04 18:26:58 -04:00
th . advance_days ( 20 ) ;
2021-05-04 15:47:37 -04:00
2021-05-04 18:26:58 -04:00
// Go up to level 2
2021-06-22 14:43:15 -04:00
let ( two_perf_stat , cred2 ) = th . level_up ( & cred1 ) ;
println! ( " --Upgrade to Level 2-- \n " ) ;
print_test_results ( two_perf_stat ) ;
2021-05-04 15:47:37 -04:00
assert! ( scalar_u32 ( & cred2 . trust_level ) . unwrap ( ) = = 2 ) ;
println! ( " cred2 = {:?} " , cred2 ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred2 ) ) ;
2021-05-04 15:47:37 -04:00
2021-05-04 18:26:58 -04:00
// Issue an invitation
2021-06-22 14:43:15 -04:00
let ( invite_perf_stat , ( cred2a , invite ) ) = th . issue_invite ( & cred2 ) ;
println! ( " --Issue Invitation-- \n " ) ;
print_test_results ( invite_perf_stat ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred2a ) ) ;
assert! ( th . ba . verify_invitation ( & invite ) ) ;
println! ( " cred2a = {:?} " , cred2a ) ;
2021-05-04 14:21:38 -04:00
println! ( " invite = {:?} " , invite ) ;
2021-05-03 19:05:42 -04:00
}
2021-05-04 15:47:37 -04:00
2022-04-03 01:54:53 -04:00
#[ test ]
2021-05-04 15:47:37 -04:00
fn test_redeem_invite ( ) {
2021-05-04 18:26:58 -04:00
let mut th = TestHarness ::new ( ) ;
// Join an untrusted user
2021-06-02 12:18:58 -04:00
let cred = th . open_invite ( ) . 1 . 0 ;
2021-05-04 18:26:58 -04:00
// Time passes
th . advance_days ( 47 ) ;
// Go up to level 1
2021-06-22 14:43:15 -04:00
let ( perf_stat , migcred ) = th . trust_promotion ( & cred ) ;
println! ( " --Trust Promotion to 1-- \n " ) ;
print_test_results ( perf_stat ) ;
let ( mperf_stat , cred1 ) = th . level0_migration ( & cred , & migcred ) ;
println! ( " --New Level 1 Credential-- \n " ) ;
print_test_results ( mperf_stat ) ;
2021-05-04 15:47:37 -04:00
assert! ( scalar_u32 ( & cred1 . trust_level ) . unwrap ( ) = = 1 ) ;
// Time passes
2021-05-04 18:26:58 -04:00
th . advance_days ( 20 ) ;
2021-05-04 15:47:37 -04:00
2021-05-04 18:26:58 -04:00
// Go up to level 2
2021-06-22 14:43:15 -04:00
let ( two_perf_stat , cred2 ) = th . level_up ( & cred1 ) ;
println! ( " --Upgrade to Level 2-- \n " ) ;
print_test_results ( two_perf_stat ) ;
2021-05-04 15:47:37 -04:00
assert! ( scalar_u32 ( & cred2 . trust_level ) . unwrap ( ) = = 2 ) ;
println! ( " cred2 = {:?} " , cred2 ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred2 ) ) ;
2021-05-04 15:47:37 -04:00
2021-05-04 18:26:58 -04:00
// Issue an invitation to Bob
2021-06-22 14:43:15 -04:00
let ( invite_perf_stat , ( cred2a , bob_invite ) ) = th . issue_invite ( & cred2 ) ;
println! ( " --Issue Invitation-- \n " ) ;
print_test_results ( invite_perf_stat ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & cred2a ) ) ;
assert! ( th . ba . verify_invitation ( & bob_invite ) ) ;
println! ( " cred2a = {:?} " , cred2a ) ;
println! ( " bob_invite = {:?} " , bob_invite ) ;
2021-05-04 15:47:37 -04:00
2021-05-04 17:48:15 -04:00
// Time passes
2021-05-04 18:26:58 -04:00
th . advance_days ( 12 ) ;
2021-05-04 17:48:15 -04:00
2021-05-04 18:26:58 -04:00
// Bob joins the system
2021-06-22 14:43:15 -04:00
let ( bob_perf_stat , bob_cred ) = th . redeem_invite ( & bob_invite ) ;
println! ( " --Bob joins the system-- \n " ) ;
print_test_results ( bob_perf_stat ) ;
2021-05-04 18:26:58 -04:00
assert! ( th . ba . verify_lox ( & bob_cred ) ) ;
println! ( " bob_cred = {:?} " , bob_cred ) ;
2021-05-04 15:47:37 -04:00
}
2021-05-05 13:58:43 -04:00
2023-07-10 17:03:10 -04:00
#[ test ]
fn test_clean_up_blocked ( ) {
let mut th = TestHarness ::new_buckets ( 50 , 50 ) ;
let mut credentials : Vec < cred ::Lox > = Vec ::new ( ) ;
// Users
for _ in 0 .. 100 {
let h : NaiveTime = DateTime ::time ( & Utc ::now ( ) ) ;
if h . hour ( ) = = 23 & & h . minute ( ) = = 59 {
println! ( " Wait for UTC 00:00 " ) ;
thread ::sleep ( Duration ::new ( 60 , 0 ) ) ;
println! ( " Ready to work again " ) ;
}
let cred = th . open_invite ( ) . 1 . 0 ;
th . advance_days ( 30 ) ;
let ( _ , migcred ) = th . trust_promotion ( & cred ) ;
let ( _ , cred1 ) = th . level0_migration ( & cred , & migcred ) ;
th . advance_days ( 14 ) ;
let ( _ , cred2 ) = th . level_up ( & cred1 ) ;
let ( _ , ( cred2a , invite ) ) = th . issue_invite ( & cred2 ) ;
let ( _ , bob_cred ) = th . redeem_invite ( & invite ) ;
th . advance_days ( 28 ) ;
let ( _ , _ ) = th . level_up ( & bob_cred ) ;
let ( _ , cred3 ) = th . level_up ( & cred2a ) ;
credentials . push ( cred3 ) ;
}
// Block 25% == 25 bridges
let blocked = block_bridges ( & mut th , 25 , credentials ) ;
println! ( " \n **AFTER 25% BLOCKING EVENT** \n " ) ;
assert! (
blocked = = th . ba . bridge_table . blocked_keys . len ( ) ,
" Blocked keys does not equal the number of blocked buckets "
) ;
assert! ( th . ba . bridge_table . recycleable_keys . is_empty ( ) , " " ) ;
// Each open invitation bucket creates 4 buckets -> 50*4 = 200 + 50 hotspare buckets = 250 total
assert! (
th . ba . bridge_table . counter = = 250 ,
" Total number of buckets should be 250 "
) ;
// Advance beyond the time that blocked buckets expire
th . advance_days ( 512 ) ;
th . ba . clean_up_blocked ( ) ;
assert! (
th . ba . bridge_table . blocked_keys . is_empty ( ) ,
" Blocked keys should be empty after cleanup "
) ;
assert! ( th . ba . bridge_table . recycleable_keys . len ( ) = = blocked , " The number of recycleable keys should be equal to the number of previously blocked buckets " ) ;
// Each open invitation bucket creates 4 buckets -> 50*4 = 200 + 50 hotspare buckets = 250 total
assert! (
th . ba . bridge_table . counter = = 250 ,
" Total number of buckets should be 250 "
) ;
for _ in 0 .. 10 {
let bucket = [
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
] ;
// Add new bridges to trigger bucket cleanup
th . ba . add_openinv_bridges ( bucket , & mut th . bdb ) ;
}
println! (
" Size of recyclable keys: {:?} " ,
th . ba . bridge_table . recycleable_keys . len ( )
) ;
println! ( " Counter: {:?} " , th . ba . bridge_table . counter ) ;
println! ( " \n **AFTER NEW BUCKETS ADDED** \n " ) ;
assert! (
th . ba . bridge_table . blocked_keys . is_empty ( ) ,
" After adding new buckets, blocked keys should be empty "
) ;
assert! (
th . ba . bridge_table . recycleable_keys . is_empty ( ) ,
" After adding new buckets, recycleable keys should be empty "
) ;
// Because of open-entry buckets added and open-entry cleanup, the counter increases to 278
println! ( " Counter: {:?} " , th . ba . bridge_table . counter ) ;
}
#[ test ]
fn test_clean_up_open_entry ( ) { }
#[ test ]
fn find_next_available_key ( ) { }
/// Blocks a percentage of the bridges for the passed Test Harness
/// excluding the hot spare buckets as they will not have been handed out.
/// The logic assumes hot spare buckets are appended to the end of the bridge_table
/// bucket list.
fn block_bridges ( th : & mut TestHarness , percentage : usize , credentials : Vec < cred ::Lox > ) -> usize {
let blockable_num = th . ba . bridge_table . buckets . len ( )
- th . ba . bridge_table . spares . len ( )
- th . bdb . openinv_buckets . len ( ) ;
let blockable_range = th . ba . bridge_table . buckets . len ( ) - th . ba . bridge_table . spares . len ( ) ;
let to_block : usize = blockable_num * percentage / 100 ;
let mut block_index : HashSet < usize > = HashSet ::new ( ) ;
let mut rng = rand ::thread_rng ( ) ;
while block_index . len ( ) < to_block {
let rand_num = rng . gen_range ( 0 , blockable_range ) ;
if ! th . bdb . openinv_buckets . contains ( & ( rand_num as u32 ) ) {
block_index . insert ( rand_num ) ;
}
}
for index in block_index {
let ba_clone = th . ba . bridge_table . buckets . clone ( ) ;
if let Some ( bridgelines ) = ba_clone . get ( & u32 ::try_from ( index ) . unwrap ( ) ) {
for bridgeline in bridgelines {
th . ba . bridge_unreachable ( & bridgeline , & mut th . bdb ) ;
}
}
}
for cred in credentials {
let ( id , key ) = bridge_table ::from_scalar ( cred . bucket ) . unwrap ( ) ;
let encbuckets = th . ba . enc_bridge_table ( ) ;
let bucket =
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , & encbuckets . get ( & id ) . unwrap ( ) )
. unwrap ( ) ;
let mut count = 0 ;
for bridge_line in & bucket . 0 {
if th . ba . bridge_table . reachable . contains_key ( bridge_line ) {
count + = 1 ;
}
}
if count < 2 {
let ( _perf_stat , migration ) = th . check_blockage ( & cred ) ;
let ( _block_perf_stat , _ ) = th . blockage_migration ( & cred , & migration ) ;
}
}
to_block
}
2023-05-10 20:26:08 -04:00
#[ test ]
fn test_allocate_bridges ( ) {
let mut th = TestHarness ::new ( ) ;
2023-05-15 18:57:23 -04:00
let distributor_bridges : & mut Vec < BridgeLine > = & mut Vec ::new ( ) ;
let table_size = th . ba . bridge_table . buckets . len ( ) ;
for _ in 0 .. 3 {
distributor_bridges . push ( BridgeLine ::random ( ) ) ;
}
2023-06-06 14:42:32 -04:00
assert! (
! distributor_bridges . is_empty ( ) ,
" No BridgeLines in distributor_bridges "
) ;
2023-05-15 18:57:23 -04:00
th . ba . allocate_bridges ( distributor_bridges , & mut th . bdb ) ;
2023-06-06 14:42:32 -04:00
assert! (
distributor_bridges . is_empty ( ) ,
" BridgeLines in distributor_bridges were not allocated "
) ;
assert! (
th . ba . bridge_table . buckets . len ( ) > table_size ,
" Size of bridge table did not increase "
) ;
2023-05-15 18:57:23 -04:00
let table_size = th . ba . bridge_table . buckets . len ( ) ;
for _ in 0 .. 2 {
distributor_bridges . push ( BridgeLine ::random ( ) ) ;
2023-06-06 14:42:32 -04:00
th . ba
. bridge_table
. unallocated_bridges
. push ( BridgeLine ::random ( ) ) ;
2023-05-15 18:57:23 -04:00
}
2023-06-06 14:42:32 -04:00
assert! (
! th . ba . bridge_table . unallocated_bridges . is_empty ( ) ,
" No BridgeLines in unallocated bridges "
) ;
assert! (
! distributor_bridges . is_empty ( ) ,
" No BridgeLines in distributor_bridges "
) ;
2023-05-15 18:57:23 -04:00
th . ba . allocate_bridges ( distributor_bridges , & mut th . bdb ) ;
2023-06-06 14:42:32 -04:00
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 1 ,
" Incorrect number of bridges remain unallocated "
) ;
assert! (
distributor_bridges . is_empty ( ) ,
" BridgeLines in distributor_bridges were not allocated "
) ;
assert! (
th . ba . bridge_table . buckets . len ( ) > table_size ,
" Size of bridge table did not increase "
) ;
2023-05-10 20:26:08 -04:00
}
2023-03-27 12:36:57 -04:00
#[ test ]
fn test_update_bridge ( ) {
let mut th = TestHarness ::new ( ) ;
// Add new bridge to table with known values,
// check that I can find and update the values and that everything else stays the same
// Create 3 bridges to test harness
let bucket = [
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
BridgeLine ::random ( ) ,
] ;
// Store first bridgeline to update later
let bridgeline_to_update = bucket [ 0 ] ;
2023-05-10 20:26:08 -04:00
// Create changed info for bridgeline to be updated to
2023-03-27 12:36:57 -04:00
let infostr : String = format! (
2023-04-03 11:47:11 -04:00
" type={} blocked_in={:?} protocol={} distribution={} " ,
2023-03-27 12:36:57 -04:00
" obfs2 test bridge " . to_string ( ) ,
{ } ,
" obfs2 " . to_string ( ) ,
" moat " . to_string ( ) ,
) ;
2023-04-04 18:39:28 -04:00
let mut updated_info_bytes : [ u8 ; BRIDGE_BYTES - 26 ] = [ 0 ; BRIDGE_BYTES - 26 ] ;
2023-03-27 12:36:57 -04:00
updated_info_bytes [ .. infostr . len ( ) ] . copy_from_slice ( infostr . as_bytes ( ) ) ;
let updated_bridgeline = BridgeLine {
addr : bridgeline_to_update . addr ,
port : bridgeline_to_update . port ,
2023-04-04 18:39:28 -04:00
uid_fingerprint : bridgeline_to_update . uid_fingerprint ,
2023-03-27 12:36:57 -04:00
info : updated_info_bytes ,
} ;
assert! (
2023-04-04 18:39:28 -04:00
updated_bridgeline . uid_fingerprint = = bridgeline_to_update . uid_fingerprint ,
2023-04-03 11:47:11 -04:00
" Bridge entering the bridgepool {:?} did not have the same fingerprint as the updating bridge {:?} " ,
2023-03-27 12:36:57 -04:00
bridgeline_to_update ,
2023-04-04 18:39:28 -04:00
updated_bridgeline . uid_fingerprint
2023-03-27 12:36:57 -04:00
) ;
assert! ( updated_bridgeline . info ! = bridgeline_to_update . info ) ;
println! (
" Bridge entering the bridgepool {:?} has different info than the updating bridge {:?} " ,
bridgeline_to_update . info , updated_bridgeline . info
) ;
assert! ( updated_bridgeline ! = bridgeline_to_update ) ;
println! ( " The two bridgelines are not equal before the update " ) ;
// Add 3 bridges to test harness
th . ba . add_openinv_bridges ( bucket , & mut th . bdb ) ;
println! ( " Before update spares = {:?} " , th . ba . bridge_table . spares ) ;
println! (
" Before update tmig = {:?} " ,
th . ba . trustup_migration_table . table
) ;
println! (
" Before update bmig = {:?} " ,
th . ba . blockage_migration_table . table
) ;
println! ( " Before update openinv = {:?} \n " , th . bdb . openinv_buckets ) ;
// Update the info of a bridge with matching IP and Port to a bridge in the bridge table
let result = th . ba . bridge_update ( & updated_bridgeline ) ;
assert! ( result , " Bridge failed to update successfully!! " ) ;
let found_bridge = th
. ba
. bridge_table
. reachable
. get_key_value ( & updated_bridgeline ) ;
assert! ( * found_bridge . unwrap ( ) . 0 ! = bridgeline_to_update ) ;
assert! ( * found_bridge . unwrap ( ) . 0 = = updated_bridgeline ) ;
println! ( " After update spares = {:?} " , th . ba . bridge_table . spares ) ;
println! (
" After update tmig = {:?} " ,
th . ba . trustup_migration_table . table
) ;
println! (
" After update bmig = {:?} " ,
th . ba . blockage_migration_table . table
) ;
println! ( " After update openinv = {:?} \n " , th . bdb . openinv_buckets ) ;
}
2023-05-08 19:44:36 -04:00
#[ test ]
fn test_bridge_replace ( ) {
2023-05-10 20:26:08 -04:00
// Create 3 open invitation buckets and 3 spare buckets
2023-06-22 16:21:06 -04:00
let cases = vec! [ " not found " , " available " , " unallocated " , " failed " , " spare " ] ;
2023-05-10 20:26:08 -04:00
for case in cases {
let mut th : TestHarness ;
if case ! = " failed " {
th = TestHarness ::new ( ) ;
} else {
th = TestHarness ::new_buckets ( 5 , 0 ) ;
}
2023-06-16 13:56:30 -04:00
2023-05-10 20:26:08 -04:00
// Randomly select a bridge to replace
let table_size = th . ba . bridge_table . buckets . len ( ) ;
2023-06-22 16:21:06 -04:00
let mut num = 100000 ;
while ! th . ba . bridge_table . buckets . contains_key ( & num ) {
num = rand ::thread_rng ( ) . gen_range ( 0 , th . ba . bridge_table . counter ) as u32 ;
2023-07-19 10:30:35 -04:00
}
2023-06-20 17:07:51 -04:00
let replaceable_bucket = th . ba . bridge_table . buckets . get ( & num ) . unwrap ( ) . clone ( ) ;
2023-05-10 20:26:08 -04:00
let replacement_bridge = & replaceable_bucket [ 0 ] ;
assert! (
th . ba
. bridge_table
. reachable
. contains_key ( replacement_bridge ) ,
" Random bridge to replace not in reachable bridges "
) ;
2023-06-16 13:56:30 -04:00
2023-05-10 20:26:08 -04:00
match case {
2023-06-16 13:56:30 -04:00
" not found " = > {
// Case zero: bridge to be replaced is not in the bridgetable
let random_bridgeline = & BridgeLine ::random ( ) ;
assert! (
! th . ba . bridge_table . reachable . contains_key ( random_bridgeline ) ,
" Random bridgeline happens to be in the bridge_table (and should not be) "
) ;
assert! (
th . ba
. bridge_replace ( random_bridgeline , Some ( random_bridgeline ) )
= = ReplaceSuccess ::NotFound ,
" Bridge should be marked as NotFound "
) ;
}
2023-05-10 20:26:08 -04:00
" available " = > {
// Case one: available_bridge != null
let random_bridgeline = & BridgeLine ::random ( ) ;
let unallocated_bridgeline = & BridgeLine ::random ( ) ;
th . ba
. bridge_table
. unallocated_bridges
. push ( * unallocated_bridgeline ) ;
assert! (
th . ba
. bridge_table
. reachable
. get ( random_bridgeline )
. is_none ( ) ,
" Random bridge already in table "
) ;
assert! (
th . ba
2023-06-16 13:56:30 -04:00
. bridge_replace ( replacement_bridge , Some ( random_bridgeline ) )
= = ReplaceSuccess ::Replaced ,
2023-05-10 20:26:08 -04:00
" Bridge was not replaced with available bridge "
) ;
assert! (
th . ba
. bridge_table
. reachable
. get ( random_bridgeline )
. is_some ( ) ,
" Replacement bridge not added to reachable bridges "
) ;
assert! (
table_size = = th . ba . bridge_table . buckets . len ( ) ,
" Number of buckets changed size "
) ;
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 1 ,
" Extra bridge added to unallocated bridges "
) ;
println! ( " Successfully added passed bridgeline " ) ;
}
// Case two: available_bridge == null and unallocated_bridges !=null
" unallocated " = > {
let unallocated_bridgeline = & BridgeLine ::random ( ) ;
th . ba
. bridge_table
. unallocated_bridges
. push ( * unallocated_bridgeline ) ;
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 1 ,
" Not enough bridges in unallocated bridges "
) ;
assert! (
th . ba
. bridge_table
. reachable
. get ( unallocated_bridgeline )
. is_none ( ) ,
" Unallocated bridge already marked as reachable "
) ;
assert! (
2023-06-16 13:56:30 -04:00
th . ba . bridge_replace ( replacement_bridge , None ) = = ReplaceSuccess ::Replaced ,
2023-05-10 20:26:08 -04:00
" Bridge was not replaced with available bridge "
) ;
assert! (
th . ba
. bridge_table
. reachable
. get ( unallocated_bridgeline )
. is_some ( ) ,
" Replacement bridge not added to reachable bridges "
) ;
assert! (
table_size = = th . ba . bridge_table . buckets . len ( ) ,
" Number of buckets changed size "
) ;
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 0 ,
" Allocated bridge still in unallocated bridges "
) ;
println! ( " Successfully added unallocated bridgeline " ) ;
}
" spare " = > {
2023-06-16 13:56:30 -04:00
// Case three: available_bridge == null and unallocated_bridges == null
2023-05-10 20:26:08 -04:00
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 0 ,
" Unallocated bridges should have a length of 0 "
) ;
assert! (
2023-06-16 13:56:30 -04:00
th . ba . bridge_replace ( replacement_bridge , None ) = = ReplaceSuccess ::Replaced ,
2023-05-10 20:26:08 -04:00
" Bridge was not replaced with available spare bridge "
) ;
assert! (
th . ba
. bridge_table
. reachable
. get ( replacement_bridge )
. is_none ( ) ,
" Replacement bridge still marked as reachable "
) ;
2023-06-22 16:21:06 -04:00
// Remove a spare bucket to replace bridge, buckets decrease by 1
2023-05-10 20:26:08 -04:00
assert! (
2023-07-19 10:30:35 -04:00
( table_size - 1 ) = = th . ba . bridge_table . buckets . len ( ) ,
2023-05-10 20:26:08 -04:00
" Number of buckets changed size "
) ;
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 2 ,
" Extra spare bridges not added to unallocated bridges "
) ;
println! ( " Successfully added unallocated bridgeline " ) ;
}
" failed " = > {
// Case four: available_bridge == None and unallocated_bridges == None and spare buckets == None
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 0 ,
" Unallocated bridges should have a length of 0 "
) ;
assert! (
2023-06-16 13:56:30 -04:00
th . ba . bridge_replace ( replacement_bridge , None ) = = ReplaceSuccess ::NotReplaced ,
2023-05-10 20:26:08 -04:00
" Bridge was somehow marked as replaced despite no replaceable bridges "
) ;
assert! (
th . ba
. bridge_table
. reachable
. get ( replacement_bridge )
. is_some ( ) ,
" Replacement bridge marked as unreachable despite not being replaced "
) ;
assert! (
table_size = = th . ba . bridge_table . buckets . len ( ) ,
" Number of buckets changed size "
) ;
assert! (
th . ba . bridge_table . unallocated_bridges . len ( ) = = 0 ,
" Unallocated bridges changed size "
) ;
println! ( " No bridges available to replace bridge so replacement gracefully failed " ) ;
}
_ = > { }
}
}
2023-05-08 19:44:36 -04:00
}
2022-04-03 01:54:53 -04:00
#[ test ]
2021-05-05 13:58:43 -04:00
fn test_mark_unreachable ( ) {
let mut th = TestHarness ::new ( ) ;
println! ( " spares = {:?} " , th . ba . bridge_table . spares ) ;
println! ( " tmig = {:?} " , th . ba . trustup_migration_table . table ) ;
println! ( " bmig = {:?} " , th . ba . blockage_migration_table . table ) ;
println! ( " openinv = {:?} \n " , th . bdb . openinv_buckets ) ;
// Mark a bridge in an untrusted bucket as unreachable
2023-06-20 17:07:51 -04:00
let bucket6 = th . ba . bridge_table . buckets . get ( & 6 u32 ) . unwrap ( ) ;
let b6 = bucket6 [ 0 ] ;
2021-05-05 13:58:43 -04:00
th . ba . bridge_unreachable ( & b6 , & mut th . bdb ) ;
println! ( " spares = {:?} " , th . ba . bridge_table . spares ) ;
println! ( " tmig = {:?} " , th . ba . trustup_migration_table . table ) ;
println! ( " bmig = {:?} " , th . ba . blockage_migration_table . table ) ;
println! ( " openinv = {:?} \n " , th . bdb . openinv_buckets ) ;
// Mark another bridge grouped to the same trusted bucket as
// unreachable
2023-06-20 17:07:51 -04:00
let bucket7 = th . ba . bridge_table . buckets . get ( & 7 u32 ) . unwrap ( ) ;
let b7 = bucket7 [ 0 ] ;
2021-05-05 13:58:43 -04:00
th . ba . bridge_unreachable ( & b7 , & mut th . bdb ) ;
println! ( " spares = {:?} " , th . ba . bridge_table . spares ) ;
println! ( " tmig = {:?} " , th . ba . trustup_migration_table . table ) ;
println! ( " bmig = {:?} " , th . ba . blockage_migration_table . table ) ;
println! ( " openinv = {:?} \n " , th . bdb . openinv_buckets ) ;
// That will have introduced a blockage migration. Get the target
let target : u32 = * th
. ba
. blockage_migration_table
. table
. iter ( )
. next ( )
. unwrap ( )
. 1 ;
// Block two of the bridges in that target bucket
2023-06-20 17:07:51 -04:00
let bucket1 = th . ba . bridge_table . buckets . get ( & target ) . unwrap ( ) ;
let bt1 = bucket1 [ 1 ] ;
let bucket2 = th . ba . bridge_table . buckets . get ( & target ) . unwrap ( ) ;
let bt2 = bucket2 [ 2 ] ;
2021-05-05 13:58:43 -04:00
th . ba . bridge_unreachable ( & bt1 , & mut th . bdb ) ;
th . ba . bridge_unreachable ( & bt2 , & mut th . bdb ) ;
println! ( " spares = {:?} " , th . ba . bridge_table . spares ) ;
println! ( " tmig = {:?} " , th . ba . trustup_migration_table . table ) ;
println! ( " bmig = {:?} " , th . ba . blockage_migration_table . table ) ;
println! ( " openinv = {:?} \n " , th . bdb . openinv_buckets ) ;
}
2021-05-05 16:28:56 -04:00
2022-04-03 01:54:53 -04:00
#[ test ]
2021-05-05 18:21:09 -04:00
fn test_blockage_migration ( ) {
2021-05-05 16:28:56 -04:00
let mut th = TestHarness ::new ( ) ;
// Join an untrusted user
2021-06-02 12:18:58 -04:00
let cred = th . open_invite ( ) . 1 . 0 ;
2021-05-05 16:28:56 -04:00
// Time passes
th . advance_days ( 47 ) ;
// Go up to level 1
2021-06-15 02:01:24 -04:00
let ( _mperf_stat , migcred ) = th . trust_promotion ( & cred ) ;
let ( _perf_stat , cred1 ) = th . level0_migration ( & cred , & migcred ) ;
2021-05-05 16:28:56 -04:00
assert! ( scalar_u32 ( & cred1 . trust_level ) . unwrap ( ) = = 1 ) ;
// Time passes
th . advance_days ( 20 ) ;
// Go up to level 2
2021-06-15 02:01:24 -04:00
let ( _two_perf_stat , cred2 ) = th . level_up ( & cred1 ) ;
2021-05-05 16:28:56 -04:00
assert! ( scalar_u32 ( & cred2 . trust_level ) . unwrap ( ) = = 2 ) ;
println! ( " cred2 = {:?} " , cred2 ) ;
assert! ( th . ba . verify_lox ( & cred2 ) ) ;
// Time passes
th . advance_days ( 29 ) ;
// Go up to level 3
2021-06-15 02:01:24 -04:00
let ( _three_perf_stat , cred3 ) = th . level_up ( & cred2 ) ;
2021-05-05 16:28:56 -04:00
assert! ( scalar_u32 ( & cred3 . trust_level ) . unwrap ( ) = = 3 ) ;
println! ( " cred3 = {:?} " , cred3 ) ;
assert! ( th . ba . verify_lox ( & cred3 ) ) ;
// Get our bridges
let ( id , key ) = bridge_table ::from_scalar ( cred3 . bucket ) . unwrap ( ) ;
let encbuckets = th . ba . enc_bridge_table ( ) ;
let bucket =
2023-06-20 20:04:17 -04:00
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , encbuckets . get ( & id ) . unwrap ( ) ) . unwrap ( ) ;
2021-05-05 16:28:56 -04:00
// We should have a Bridge Reachability credential
assert! ( bucket . 1. is_some ( ) ) ;
// Oh, no! Two of our bridges are blocked!
th . ba . bridge_unreachable ( & bucket . 0 [ 0 ] , & mut th . bdb ) ;
th . ba . bridge_unreachable ( & bucket . 0 [ 2 ] , & mut th . bdb ) ;
println! ( " spares = {:?} " , th . ba . bridge_table . spares ) ;
println! ( " tmig = {:?} " , th . ba . trustup_migration_table . table ) ;
println! ( " bmig = {:?} " , th . ba . blockage_migration_table . table ) ;
println! ( " openinv = {:?} \n " , th . bdb . openinv_buckets ) ;
// Time passes
th . advance_days ( 1 ) ;
let encbuckets2 = th . ba . enc_bridge_table ( ) ;
let bucket2 =
2023-06-20 20:04:17 -04:00
bridge_table ::BridgeTable ::decrypt_bucket ( id , & key , encbuckets2 . get ( & id ) . unwrap ( ) ) . unwrap ( ) ;
2021-05-05 16:28:56 -04:00
// We should no longer have a Bridge Reachability credential
assert! ( bucket2 . 1. is_none ( ) ) ;
// See about getting a Migration credential for the blockage
2021-06-15 02:01:24 -04:00
let ( _block_perf_stat , migration ) = th . check_blockage ( & cred3 ) ;
2021-05-05 16:28:56 -04:00
println! ( " migration = {:?} " , migration ) ;
2021-05-05 18:21:09 -04:00
// Migrate
2021-06-15 02:01:24 -04:00
let ( _four_perf_stat , cred4 ) = th . blockage_migration ( & cred3 , & migration ) ;
2021-05-05 18:21:09 -04:00
println! ( " cred4 = {:?} " , cred4 ) ;
assert! ( th . ba . verify_lox ( & cred4 ) ) ;
2021-05-05 16:28:56 -04:00
}
2021-06-15 02:01:24 -04:00
2021-06-22 14:43:15 -04:00
fn print_test_results ( perf_stat : PerfStat ) {
2021-07-07 11:28:17 -04:00
println! ( " Request size = {:?} bytes " , perf_stat . req_len ) ;
2021-06-22 14:43:15 -04:00
println! ( " Request time = {:?} " , perf_stat . req_t ) ;
2021-07-07 11:28:17 -04:00
println! ( " Response size = {:?} bytes " , perf_stat . resp_len ) ;
2021-06-22 14:43:15 -04:00
println! ( " Response time = {:?} " , perf_stat . resp_t ) ;
println! ( " Response handle time = {:?} " , perf_stat . resp_handle_t ) ;
2023-06-06 14:42:32 -04:00
}