Start testing simulated extra-infos

This commit is contained in:
Vecna 2024-04-27 17:28:33 -04:00
parent c38b182cb7
commit 45a6339c4c
2 changed files with 113 additions and 4 deletions

View File

@ -5,10 +5,13 @@ Note, this is NOT a complete implementation of the document format.
use chrono::DateTime;
use julianday::JulianDay;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::{
collections::{BTreeMap, HashMap, HashSet},
fmt,
};
/// Fields we need from extra-info document
#[derive(Eq, PartialEq, Hash, Serialize, Deserialize)]
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ExtraInfo {
/// Bridge nickname, probably unused
pub nickname: String,
@ -137,3 +140,36 @@ impl ExtraInfo {
set
}
}
/// Convert the ExtraInfo object to a string record, as in a downloaded file
impl fmt::Display for ExtraInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut str = String::from("@type bridge-extra-info 1.3");
str.push_str(
format!(
"\nextra-info {} {}",
self.nickname,
array_bytes::bytes2hex("", self.fingerprint).to_uppercase()
)
.as_str(),
);
let date = JulianDay::new(self.date.try_into().unwrap()).to_date();
str.push_str(format!("\nbridge-stats-end {} 23:59:59 (86400 s)", date).as_str());
str.push_str(format!("\npublished {} 23:59:59", date).as_str());
// These should be sorted in descending order by count, but that's not
// necessary for our purposes.
str.push_str("\nbridge-ips ");
let mut first_cc = true;
for (cc, count) in &self.bridge_ips {
if !first_cc {
str.push(',');
}
str.push_str(format!("{}={}", cc, count,).as_str());
first_cc = false;
}
str.push_str("\n");
write!(f, "{}", str)
}
}

View File

@ -150,12 +150,12 @@ pub fn random() -> BridgeLine {
}
#[tokio::test]
async fn test_extra_infos() {
async fn test_download_extra_infos() {
let bridge_to_test =
array_bytes::hex2array("72E12B89136B45BBC81D1EF0AC7DDDBB91B148DB").unwrap();
// Open test database
let db: Db = sled::open("test_db_ei").unwrap();
let db: Db = sled::open("test_db_dei").unwrap();
// Delete all data in test DB
db.clear().unwrap();
@ -180,6 +180,79 @@ async fn test_extra_infos() {
bincode::deserialize(&db.get(bridge_to_test).unwrap().unwrap()).unwrap();
}
#[test]
fn test_simulate_extra_infos() {
let extra_info_str = r#"@type bridge-extra-info 1.3
extra-info ElephantBridgeDE2 72E12B89136B45BBC81D1EF0AC7DDDBB91B148DB
master-key-ed25519 eWxjRwAWW7n8BGG9fNa6rApmBFbe3f0xcD7dqwOICW8
published 2024-04-06 03:51:04
transport obfs4
write-history 2024-04-05 04:55:22 (86400 s) 31665735680,14918491136,15423603712,36168353792,40396827648
read-history 2024-04-05 04:55:22 (86400 s) 31799622656,15229917184,15479115776,36317251584,40444155904
ipv6-write-history 2024-04-05 04:55:22 (86400 s) 5972127744,610078720,516897792,327949312,640708608
ipv6-read-history 2024-04-05 04:55:22 (86400 s) 4156158976,4040448000,2935756800,4263080960,6513532928
dirreq-write-history 2024-04-05 04:55:22 (86400 s) 625217536,646188032,618014720,584386560,600778752
dirreq-read-history 2024-04-05 04:55:22 (86400 s) 18816000,19000320,18484224,17364992,18443264
geoip-db-digest 44073997E1ED63E183B79DE2A1757E9997A834E3
geoip6-db-digest C0BF46880C6C132D746683279CC90DD4B2D31786
dirreq-stats-end 2024-04-05 06:51:23 (86400 s)
dirreq-v3-ips ru=16,au=8,by=8,cn=8,gb=8,ir=8,mt=8,nl=8,pl=8,tn=8,tr=8,us=8
dirreq-v3-reqs ru=72,gb=64,pl=32,cn=16,ir=16,us=16,au=8,by=8,mt=8,nl=8,tn=8,tr=8
dirreq-v3-resp ok=216,not-enough-sigs=0,unavailable=0,not-found=0,not-modified=328,busy=0
dirreq-v3-direct-dl complete=0,timeout=0,running=0
dirreq-v3-tunneled-dl complete=212,timeout=4,running=0,min=21595,d1=293347,d2=1624137,q1=1911800,d3=2066929,d4=2415000,md=2888500,d6=3264000,d7=3851333,q3=41>
hidserv-stats-end 2024-04-05 06:51:23 (86400 s)
hidserv-rend-relayed-cells 7924 delta_f=2048 epsilon=0.30 bin_size=1024
hidserv-dir-onions-seen -12 delta_f=8 epsilon=0.30 bin_size=8
hidserv-v3-stats-end 2024-04-05 12:00:00 (86400 s)
hidserv-rend-v3-relayed-cells -4785 delta_f=2048 epsilon=0.30 bin_size=1024
hidserv-dir-v3-onions-seen 5 delta_f=8 epsilon=0.30 bin_size=8
padding-counts 2024-04-05 06:51:42 (86400 s) bin-size=10000 write-drop=0 write-pad=80000 write-total=79980000 read-drop=0 read-pad=1110000 read-total=7989000>
bridge-stats-end 2024-04-05 06:51:44 (86400 s)
bridge-ips ru=40,us=32,??=8,au=8,br=8,by=8,cn=8,de=8,eg=8,eu=8,gb=8,ge=8,hr=8,ie=8,ir=8,kp=8,lt=8,mt=8,nl=8,pl=8,ro=8,sg=8,tn=8,tr=8,vn=8
bridge-ip-versions v4=104,v6=8
bridge-ip-transports <OR>=56,obfs4=56
router-digest-sha256 zK0VMl3i0B2eaeQTR03e2hZ0i8ytkuhK/psgD2J1/lQ
router-digest F30B38390C375E1EE74BFED844177804442569E0"#;
let extra_info_set = ExtraInfo::parse_file(&extra_info_str);
assert_eq!(extra_info_set.len(), 1);
let extra_info = extra_info_set.iter().next().unwrap().clone();
let extra_info_str = extra_info.to_string();
let extra_info_2 = ExtraInfo::parse_file(&extra_info_str)
.into_iter()
.next()
.unwrap()
.clone();
assert_eq!(extra_info, extra_info_2);
let bridge_to_test: [u8; 20] =
array_bytes::hex2array("72E12B89136B45BBC81D1EF0AC7DDDBB91B148DB").unwrap();
// Open test database
let db: Db = sled::open("test_db_sei").unwrap();
// Delete all data in test DB
db.clear().unwrap();
assert!(!db.contains_key("bridges").unwrap());
assert!(!db.contains_key(bridge_to_test).unwrap());
// TODO: Run local web server and change this to update_extra_infos
add_extra_info_to_db(&db, extra_info_2);
// Check that DB contains information on a bridge with high uptime
assert!(db.contains_key("bridges").unwrap());
let bridges: HashSet<[u8; 20]> =
bincode::deserialize(&db.get("bridges").unwrap().unwrap()).unwrap();
assert!(bridges.contains(&bridge_to_test));
assert!(db.contains_key(bridge_to_test).unwrap());
let _bridge_info: BridgeInfo =
bincode::deserialize(&db.get(bridge_to_test).unwrap().unwrap()).unwrap();
}
#[test]
fn test_negative_reports() {
let mut th = TestHarness::new();