|
@@ -840,7 +840,7 @@ fn test_analysis() {
|
|
|
|
|
|
bridge_info
|
|
|
.info_by_country
|
|
|
- .insert("ru".to_string(), BridgeCountryInfo::new());
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
let confidence = 0.95;
|
|
|
|
|
@@ -899,7 +899,7 @@ fn test_analysis() {
|
|
|
|
|
|
bridge_info
|
|
|
.info_by_country
|
|
|
- .insert("ru".to_string(), BridgeCountryInfo::new());
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
let confidence = 0.95;
|
|
|
|
|
@@ -973,7 +973,7 @@ fn test_analysis() {
|
|
|
|
|
|
bridge_info
|
|
|
.info_by_country
|
|
|
- .insert("ru".to_string(), BridgeCountryInfo::new());
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
let confidence = 0.95;
|
|
|
|
|
@@ -1025,7 +1025,7 @@ fn test_analysis() {
|
|
|
|
|
|
bridge_info
|
|
|
.info_by_country
|
|
|
- .insert("ru".to_string(), BridgeCountryInfo::new());
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
let confidence = 0.95;
|
|
|
|
|
@@ -1127,7 +1127,7 @@ fn test_analysis() {
|
|
|
|
|
|
bridge_info
|
|
|
.info_by_country
|
|
|
- .insert("ru".to_string(), BridgeCountryInfo::new());
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
let confidence = 0.95;
|
|
|
|
|
@@ -1230,7 +1230,7 @@ fn test_analysis() {
|
|
|
|
|
|
bridge_info
|
|
|
.info_by_country
|
|
|
- .insert("ru".to_string(), BridgeCountryInfo::new());
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
let confidence = 0.95;
|
|
|
|
|
@@ -1324,5 +1324,374 @@ fn test_analysis() {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- // TODO: Test stage 3 analysis
|
|
|
+ // Test stage 3 analysis
|
|
|
+
|
|
|
+ {
|
|
|
+ let mut date = get_date();
|
|
|
+
|
|
|
+ // New bridge info
|
|
|
+ let mut bridge_info = BridgeInfo::new([0; 20], &String::default());
|
|
|
+
|
|
|
+ bridge_info
|
|
|
+ .info_by_country
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
+ let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
+ let confidence = 0.95;
|
|
|
+
|
|
|
+ let mut blocking_countries = HashSet::<String>::new();
|
|
|
+
|
|
|
+ // No data today
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ for i in 1..30 {
|
|
|
+ // 9-32 connections, 0-3 negative reports, 16-20 positive reports each day
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 8 * (i % 3 + 2),
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ i % 4,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 16 + i % 5,
|
|
|
+ );
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // Data similar to previous days:
|
|
|
+ // 24 connections, 2 negative reports, 17 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 24,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 2,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 17,
|
|
|
+ );
|
|
|
+
|
|
|
+ // Should not be blocked because we have similar data.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ // Data different from previous days:
|
|
|
+ // 104 connections, 1 negative report, 100 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 104,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 1,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 100,
|
|
|
+ );
|
|
|
+
|
|
|
+ // This should not be blocked even though it's very different because
|
|
|
+ // it's different in the good direction.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ // Data different from previous days:
|
|
|
+ // 40 connections, 12 negative reports, 40 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 40,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 12,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 40,
|
|
|
+ );
|
|
|
+ blocking_countries.insert("ru".to_string());
|
|
|
+
|
|
|
+ // This should be blocked because it's different in the bad direction.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ let mut date = get_date();
|
|
|
+
|
|
|
+ // New bridge info
|
|
|
+ let mut bridge_info = BridgeInfo::new([0; 20], &String::default());
|
|
|
+
|
|
|
+ bridge_info
|
|
|
+ .info_by_country
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
+ let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
+ let confidence = 0.95;
|
|
|
+
|
|
|
+ let mut blocking_countries = HashSet::<String>::new();
|
|
|
+
|
|
|
+ // No data today
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ for i in 1..30 {
|
|
|
+ // 9-32 connections, 0-3 negative reports, 16-20 positive reports each day
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 8 * (i % 3 + 2),
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ i % 4,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 16 + i % 5,
|
|
|
+ );
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // Data similar to previous days:
|
|
|
+ // 24 connections, 2 negative reports, 17 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 24,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 2,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 17,
|
|
|
+ );
|
|
|
+
|
|
|
+ // Should not be blocked because we have similar data.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ // Data different from previous days:
|
|
|
+ // 104 connections, 1 negative report, 85 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 104,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 1,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 85,
|
|
|
+ );
|
|
|
+
|
|
|
+ // This should not be blocked even though it's very different because
|
|
|
+ // it's different in the good direction.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ // Data different from previous days:
|
|
|
+ // 800 connections, 12 negative reports, 750 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 800,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 12,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 750,
|
|
|
+ );
|
|
|
+
|
|
|
+ blocking_countries.insert("ru".to_string());
|
|
|
+
|
|
|
+ // The censor artificially inflated bridge stats to prevent detection.
|
|
|
+ // Ensure we still detect the censorship from negative reports.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ let mut date = get_date();
|
|
|
+
|
|
|
+ // New bridge info
|
|
|
+ let mut bridge_info = BridgeInfo::new([0; 20], &String::default());
|
|
|
+
|
|
|
+ bridge_info
|
|
|
+ .info_by_country
|
|
|
+ .insert("ru".to_string(), BridgeCountryInfo::new(date));
|
|
|
+ let analyzer = analysis::NormalAnalyzer::new(5, 0.25);
|
|
|
+ let confidence = 0.95;
|
|
|
+
|
|
|
+ let mut blocking_countries = HashSet::<String>::new();
|
|
|
+
|
|
|
+ // No data today
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ for i in 1..30 {
|
|
|
+ // 9-32 connections, 0-3 negative reports, 16-20 positive reports each day
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 8 * (i % 3 + 2),
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ i % 4,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 16 + i % 5,
|
|
|
+ );
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // Data similar to previous days:
|
|
|
+ // 24 connections, 2 negative reports, 17 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 24,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 2,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 17,
|
|
|
+ );
|
|
|
+
|
|
|
+ // Should not be blocked because we have similar data.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ // Data different from previous days:
|
|
|
+ // 104 connections, 1 negative report, 100 positive reports
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 104,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 1,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 100,
|
|
|
+ );
|
|
|
+
|
|
|
+ // This should not be blocked even though it's very different because
|
|
|
+ // it's different in the good direction.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+
|
|
|
+ // Data different from previous days:
|
|
|
+ // 24 connections, 1 negative report, 1 positive report
|
|
|
+ date += 1;
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::BridgeIps,
|
|
|
+ date,
|
|
|
+ 24,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::NegativeReports,
|
|
|
+ date,
|
|
|
+ 1,
|
|
|
+ );
|
|
|
+ bridge_info.info_by_country.get_mut("ru").unwrap().add_info(
|
|
|
+ BridgeInfoType::PositiveReports,
|
|
|
+ date,
|
|
|
+ 1,
|
|
|
+ );
|
|
|
+
|
|
|
+ blocking_countries.insert("ru".to_string());
|
|
|
+
|
|
|
+ // This should be blocked because it's different in the bad direction.
|
|
|
+ assert_eq!(
|
|
|
+ blocked_in(&analyzer, &bridge_info, confidence, date),
|
|
|
+ blocking_countries
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|