commit cbbb9b998e22bb5a6a9eeeeafc23df6625aafa6a
parent 56391a96b622bc5d948a10678bc0c95f7e522a7b
Author: triesap <tyson@radroots.org>
Date: Fri, 6 Mar 2026 19:38:18 +0000
replica-sync: expand emit error-path coverage harness
- add emit failpoint hooks for list_set wire conversion and gcs location mapping error branches
- add a targeted emit coverage test that exercises additional query, builder, and resolver failure paths
- add local emit test helpers to create farm, plot, and membership fixtures for branch-focused scenarios
- make canonical serialization failpoint thread-local for deterministic parallel test execution
Diffstat:
2 files changed, 475 insertions(+), 133 deletions(-)
diff --git a/crates/replica-sync/src/canonical.rs b/crates/replica-sync/src/canonical.rs
@@ -11,16 +11,22 @@ use crate::error::RadrootsReplicaEventsError;
#[cfg(test)]
pub(crate) mod failpoints {
- use core::sync::atomic::{AtomicBool, Ordering};
+ use std::cell::Cell;
- static FORCE_ERROR: AtomicBool = AtomicBool::new(false);
+ thread_local! {
+ static FORCE_ERROR: Cell<bool> = const { Cell::new(false) };
+ }
pub(crate) fn set_error() {
- FORCE_ERROR.store(true, Ordering::SeqCst);
+ FORCE_ERROR.with(|flag| flag.set(true));
}
pub(crate) fn take_error() -> bool {
- FORCE_ERROR.swap(false, Ordering::SeqCst)
+ FORCE_ERROR.with(|flag| {
+ let value = flag.get();
+ flag.set(false);
+ value
+ })
}
}
@@ -106,10 +112,9 @@ mod tests {
fn canonical_json_string_failpoint_returns_error() {
super::failpoints::set_error();
let err = canonical_json_string(&"value").expect_err("failpoint");
- assert!(
- err.to_string()
- .contains("canonical json serialization failed")
- );
+ assert!(err
+ .to_string()
+ .contains("canonical json serialization failed"));
}
struct AlwaysErr;
@@ -126,9 +131,8 @@ mod tests {
#[test]
fn canonical_json_string_propagates_serialization_errors() {
let err = canonical_json_string(&AlwaysErr).expect_err("serialize fail");
- assert!(
- err.to_string()
- .contains("canonical json serialization failed")
- );
+ assert!(err
+ .to_string()
+ .contains("canonical json serialization failed"));
}
}
diff --git a/crates/replica-sync/src/emit.rs b/crates/replica-sync/src/emit.rs
@@ -16,8 +16,8 @@ use radroots_events::farm::{
use radroots_events::kinds::{KIND_FARM, KIND_LIST_SET_GENERIC, KIND_PLOT};
use radroots_events::plot::RadrootsPlot;
use radroots_events::profile::{
- RADROOTS_PROFILE_TYPE_TAG_KEY, RadrootsProfile, RadrootsProfileType,
- radroots_profile_type_from_tag_value, radroots_profile_type_tag_value,
+ radroots_profile_type_from_tag_value, radroots_profile_type_tag_value, RadrootsProfile,
+ RadrootsProfileType, RADROOTS_PROFILE_TYPE_TAG_KEY,
};
use radroots_events_codec::farm::encode as farm_encode;
use radroots_events_codec::farm::list_sets as farm_list_sets;
@@ -59,8 +59,8 @@ use crate::canonical::canonical_json_string;
use crate::error::RadrootsReplicaEventsError;
use crate::geo::{geojson_point_from_lat_lng, geojson_polygon_circle_wgs84};
use crate::types::{
- RADROOTS_REPLICA_TRANSFER_VERSION, RadrootsReplicaEventDraft, RadrootsReplicaFarmSelector,
- RadrootsReplicaSyncBundle, RadrootsReplicaSyncOptions, RadrootsReplicaSyncRequest,
+ RadrootsReplicaEventDraft, RadrootsReplicaFarmSelector, RadrootsReplicaSyncBundle,
+ RadrootsReplicaSyncOptions, RadrootsReplicaSyncRequest, RADROOTS_REPLICA_TRANSFER_VERSION,
};
const ROLE_PRIMARY: &str = "primary";
@@ -68,6 +68,40 @@ const ROLE_MEMBER: &str = "member";
const ROLE_OWNER: &str = "owner";
const ROLE_WORKER: &str = "worker";
+#[cfg(test)]
+pub(crate) mod failpoints {
+ use std::cell::Cell;
+
+ thread_local! {
+ static FORCE_LIST_SET_TO_WIRE_ERROR: Cell<bool> = const { Cell::new(false) };
+ static FORCE_GCS_LOCATION_TO_EVENT_ERROR: Cell<bool> = const { Cell::new(false) };
+ }
+
+ pub(crate) fn set_list_set_to_wire_error() {
+ FORCE_LIST_SET_TO_WIRE_ERROR.with(|flag| flag.set(true));
+ }
+
+ pub(crate) fn take_list_set_to_wire_error() -> bool {
+ FORCE_LIST_SET_TO_WIRE_ERROR.with(|flag| {
+ let value = flag.get();
+ flag.set(false);
+ value
+ })
+ }
+
+ pub(crate) fn set_gcs_location_to_event_error() {
+ FORCE_GCS_LOCATION_TO_EVENT_ERROR.with(|flag| flag.set(true));
+ }
+
+ pub(crate) fn take_gcs_location_to_event_error() -> bool {
+ FORCE_GCS_LOCATION_TO_EVENT_ERROR.with(|flag| {
+ let value = flag.get();
+ flag.set(false);
+ value
+ })
+ }
+}
+
pub fn radroots_replica_sync_all<E: SqlExecutor>(
exec: &E,
request: &RadrootsReplicaSyncRequest,
@@ -212,7 +246,7 @@ pub fn radroots_replica_list_set_events<E: SqlExecutor>(
let list_sets = [members_list, owners_list, workers_list, plots_list];
let mut events = Vec::new();
for list_set in list_sets {
- let parts = list_set_encode::to_wire_parts_with_kind(&list_set, KIND_LIST_SET_GENERIC)?;
+ let parts = list_set_to_wire_parts(&list_set)?;
events.push(parts_to_draft(&farm.pubkey, parts));
}
Ok(events)
@@ -241,7 +275,7 @@ pub fn radroots_replica_membership_claim_events<E: SqlExecutor>(
farm_pubkeys.sort();
farm_pubkeys.dedup();
let list_set = farm_list_sets::member_of_farms_list_set(farm_pubkeys)?;
- let parts = list_set_encode::to_wire_parts_with_kind(&list_set, KIND_LIST_SET_GENERIC)?;
+ let parts = list_set_to_wire_parts(&list_set)?;
events.push(parts_to_draft(member_pubkey, parts));
}
@@ -583,6 +617,21 @@ fn load_relation_by_role<E: SqlExecutor>(
Ok(Some(gcs_location_to_event(&gcs)?))
}
+fn list_set_to_wire_parts(
+ list_set: &radroots_events::list_set::RadrootsListSet,
+) -> Result<WireEventParts, RadrootsReplicaEventsError> {
+ #[cfg(test)]
+ if failpoints::take_list_set_to_wire_error() {
+ return Err(RadrootsReplicaEventsError::InvalidData(
+ "list_set_to_wire".to_string(),
+ ));
+ }
+ Ok(list_set_encode::to_wire_parts_with_kind(
+ list_set,
+ KIND_LIST_SET_GENERIC,
+ )?)
+}
+
enum RelationRow {
Farm(FarmGcsLocation),
Plot(PlotGcsLocation),
@@ -605,12 +654,22 @@ impl RelationRow {
}
fn location_role_rank(role: &str) -> u8 {
- if role == ROLE_PRIMARY { 0 } else { 1 }
+ if role == ROLE_PRIMARY {
+ 0
+ } else {
+ 1
+ }
}
fn gcs_location_to_event(
gcs: &GcsLocation,
) -> Result<RadrootsGcsLocation, RadrootsReplicaEventsError> {
+ #[cfg(test)]
+ if failpoints::take_gcs_location_to_event_error() {
+ return Err(RadrootsReplicaEventsError::InvalidData(
+ "gcs_location_to_event".to_string(),
+ ));
+ }
let point = parse_point(&gcs.point, gcs.lat, gcs.lng);
let polygon = parse_polygon(&gcs.polygon, gcs.lat, gcs.lng);
Ok(RadrootsGcsLocation {
@@ -1164,6 +1223,56 @@ mod tests {
(farm, plot_primary, plot_secondary)
}
+ fn create_farm_record(exec: &SqliteExecutor, d_tag: &str, pubkey: &str, name: &str) -> Farm {
+ farm::create(
+ exec,
+ &IFarmFields {
+ d_tag: d_tag.to_string(),
+ pubkey: pubkey.to_string(),
+ name: name.to_string(),
+ about: None,
+ website: None,
+ picture: None,
+ banner: None,
+ location_primary: None,
+ location_city: None,
+ location_region: None,
+ location_country: None,
+ },
+ )
+ .expect("farm")
+ .result
+ }
+
+ fn create_plot_record(exec: &SqliteExecutor, farm_id: &str, d_tag: &str, name: &str) {
+ let _ = plot::create(
+ exec,
+ &IPlotFields {
+ d_tag: d_tag.to_string(),
+ farm_id: farm_id.to_string(),
+ name: name.to_string(),
+ about: None,
+ location_primary: None,
+ location_city: None,
+ location_region: None,
+ location_country: None,
+ },
+ )
+ .expect("plot");
+ }
+
+ fn add_member_record(exec: &SqliteExecutor, farm_id: &str, member_pubkey: &str, role: &str) {
+ let _ = farm_member::create(
+ exec,
+ &IFarmMemberFields {
+ farm_id: farm_id.to_string(),
+ member_pubkey: member_pubkey.to_string(),
+ role: role.to_string(),
+ },
+ )
+ .expect("member");
+ }
+
#[test]
fn emit_paths_cover_private_and_public_helpers() {
let exec = SqliteExecutor::open_memory().expect("db");
@@ -1180,28 +1289,24 @@ mod tests {
.expect("resolve by id");
assert_eq!(by_id.id, farm_row.id);
- assert!(
- resolve_farm(
- &exec,
- &RadrootsReplicaFarmSelector {
- id: Some("00000000-0000-0000-0000-000000000000".to_string()),
- d_tag: None,
- pubkey: None,
- },
- )
- .is_err()
- );
- assert!(
- resolve_farm(
- &exec,
- &RadrootsReplicaFarmSelector {
- id: None,
- d_tag: None,
- pubkey: None,
- },
- )
- .is_err()
- );
+ assert!(resolve_farm(
+ &exec,
+ &RadrootsReplicaFarmSelector {
+ id: Some("00000000-0000-0000-0000-000000000000".to_string()),
+ d_tag: None,
+ pubkey: None,
+ },
+ )
+ .is_err());
+ assert!(resolve_farm(
+ &exec,
+ &RadrootsReplicaFarmSelector {
+ id: None,
+ d_tag: None,
+ pubkey: None,
+ },
+ )
+ .is_err());
let _ = farm::create(
&exec,
@@ -1220,17 +1325,15 @@ mod tests {
},
)
.expect("duplicate farm");
- assert!(
- resolve_farm(
- &exec,
- &RadrootsReplicaFarmSelector {
- id: None,
- d_tag: Some(farm_row.d_tag.clone()),
- pubkey: Some(farm_row.pubkey.clone()),
- },
- )
- .is_err()
- );
+ assert!(resolve_farm(
+ &exec,
+ &RadrootsReplicaFarmSelector {
+ id: None,
+ d_tag: Some(farm_row.d_tag.clone()),
+ pubkey: Some(farm_row.pubkey.clone()),
+ },
+ )
+ .is_err());
let tags = collect_farm_tags(&exec, &farm_row.id).expect("farm tags");
assert_eq!(tags, vec!["coffee".to_string()]);
@@ -1307,16 +1410,12 @@ mod tests {
let polygon_blank = parse_polygon("", 3.0, 4.0);
assert!(!polygon_blank.coordinates[0].is_empty());
- assert!(
- load_profile(&exec, &farm_row.pubkey)
- .expect("farm profile")
- .is_some()
- );
- assert!(
- load_profile(&exec, &"z".repeat(64))
- .expect("missing profile")
- .is_none()
- );
+ assert!(load_profile(&exec, &farm_row.pubkey)
+ .expect("farm profile")
+ .is_some());
+ assert!(load_profile(&exec, &"z".repeat(64))
+ .expect("missing profile")
+ .is_none());
let profile_event_farm = profile_event(
&farm_row.pubkey,
@@ -1775,92 +1874,333 @@ mod tests {
needle: "nostr_profile",
err: SqlError::Internal,
};
- assert!(
- radroots_replica_sync_all_with_options(
- &sync_profiles_fail,
- &selector,
- Some(&RadrootsReplicaSyncOptions {
- include_profiles: Some(true),
- include_list_sets: Some(false),
- include_membership_claims: Some(false),
- }),
- )
- .is_err()
- );
+ assert!(radroots_replica_sync_all_with_options(
+ &sync_profiles_fail,
+ &selector,
+ Some(&RadrootsReplicaSyncOptions {
+ include_profiles: Some(true),
+ include_list_sets: Some(false),
+ include_membership_claims: Some(false),
+ }),
+ )
+ .is_err());
let sync_farm_fail = QueryFailExecutor {
inner: &exec,
needle: "farm_tag",
err: SqlError::Internal,
};
- assert!(
- radroots_replica_sync_all_with_options(
- &sync_farm_fail,
- &selector,
- Some(&RadrootsReplicaSyncOptions {
- include_profiles: Some(false),
- include_list_sets: Some(false),
- include_membership_claims: Some(false),
- }),
- )
- .is_err()
- );
+ assert!(radroots_replica_sync_all_with_options(
+ &sync_farm_fail,
+ &selector,
+ Some(&RadrootsReplicaSyncOptions {
+ include_profiles: Some(false),
+ include_list_sets: Some(false),
+ include_membership_claims: Some(false),
+ }),
+ )
+ .is_err());
let sync_plot_fail = QueryFailExecutor {
inner: &exec,
needle: "plot_tag",
err: SqlError::Internal,
};
- assert!(
- radroots_replica_sync_all_with_options(
- &sync_plot_fail,
- &selector,
- Some(&RadrootsReplicaSyncOptions {
- include_profiles: Some(false),
- include_list_sets: Some(false),
- include_membership_claims: Some(false),
- }),
- )
- .is_err()
- );
+ assert!(radroots_replica_sync_all_with_options(
+ &sync_plot_fail,
+ &selector,
+ Some(&RadrootsReplicaSyncOptions {
+ include_profiles: Some(false),
+ include_list_sets: Some(false),
+ include_membership_claims: Some(false),
+ }),
+ )
+ .is_err());
let sync_list_set_fail = QueryFailExecutor {
inner: &exec,
needle: "farm_member",
err: SqlError::Internal,
};
- assert!(
- radroots_replica_sync_all_with_options(
- &sync_list_set_fail,
- &selector,
- Some(&RadrootsReplicaSyncOptions {
- include_profiles: Some(false),
- include_list_sets: Some(true),
- include_membership_claims: Some(false),
- }),
- )
- .is_err()
- );
+ assert!(radroots_replica_sync_all_with_options(
+ &sync_list_set_fail,
+ &selector,
+ Some(&RadrootsReplicaSyncOptions {
+ include_profiles: Some(false),
+ include_list_sets: Some(true),
+ include_membership_claims: Some(false),
+ }),
+ )
+ .is_err());
let sync_claims_fail = QueryFailExecutor {
inner: &exec,
needle: "farm_member_claim",
err: SqlError::Internal,
};
- assert!(
- radroots_replica_sync_all_with_options(
- &sync_claims_fail,
- &selector,
- Some(&RadrootsReplicaSyncOptions {
- include_profiles: Some(false),
- include_list_sets: Some(false),
- include_membership_claims: Some(true),
- }),
- )
- .is_err()
- );
+ assert!(radroots_replica_sync_all_with_options(
+ &sync_claims_fail,
+ &selector,
+ Some(&RadrootsReplicaSyncOptions {
+ include_profiles: Some(false),
+ include_list_sets: Some(false),
+ include_membership_claims: Some(true),
+ }),
+ )
+ .is_err());
assert!(radroots_replica_farm_event(&exec, &farm_row).is_ok());
assert!(radroots_replica_plot_events(&exec, &farm_row).is_ok());
}
#[test]
+ fn emit_additional_error_branches_are_reported() {
+ let exec = SqliteExecutor::open_memory().expect("db");
+ let (farm_row, _, _) = seed(&exec);
+
+ crate::canonical::failpoints::set_error();
+ assert!(radroots_replica_profile_events(&exec, &farm_row).is_err());
+ let farm_profile = load_profile(&exec, &farm_row.pubkey)
+ .expect("load profile")
+ .expect("farm profile");
+ crate::canonical::failpoints::set_error();
+ assert!(profile_event(&farm_row.pubkey, farm_profile).is_err());
+
+ let farm_location_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "farm_gcs_location",
+ err: SqlError::Internal,
+ };
+ assert!(radroots_replica_farm_event(&farm_location_fail, &farm_row).is_err());
+ let invalid_farm = Farm {
+ id: farm_row.id.clone(),
+ created_at: farm_row.created_at.clone(),
+ updated_at: farm_row.updated_at.clone(),
+ d_tag: "invalid".to_string(),
+ pubkey: farm_row.pubkey.clone(),
+ name: farm_row.name.clone(),
+ about: farm_row.about.clone(),
+ website: farm_row.website.clone(),
+ picture: farm_row.picture.clone(),
+ banner: farm_row.banner.clone(),
+ location_primary: farm_row.location_primary.clone(),
+ location_city: farm_row.location_city.clone(),
+ location_region: farm_row.location_region.clone(),
+ location_country: farm_row.location_country.clone(),
+ };
+ assert!(radroots_replica_farm_event(&exec, &invalid_farm).is_err());
+ crate::canonical::failpoints::set_error();
+ assert!(radroots_replica_farm_event(&exec, &farm_row).is_err());
+
+ let plots_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "from plot",
+ err: SqlError::Internal,
+ };
+ assert!(radroots_replica_plot_events(&plots_fail, &farm_row).is_err());
+ let plot_location_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "plot_gcs_location",
+ err: SqlError::Internal,
+ };
+ assert!(radroots_replica_plot_events(&plot_location_fail, &farm_row).is_err());
+ crate::canonical::failpoints::set_error();
+ assert!(radroots_replica_plot_events(&exec, &farm_row).is_err());
+ create_plot_record(&exec, &farm_row.id, "invalid", "plot-invalid");
+ assert!(radroots_replica_plot_events(&exec, &farm_row).is_err());
+
+ let resolve_id_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "from farm",
+ err: SqlError::Internal,
+ };
+ assert!(resolve_farm(
+ &resolve_id_fail,
+ &RadrootsReplicaFarmSelector {
+ id: Some(farm_row.id.clone()),
+ d_tag: None,
+ pubkey: None,
+ }
+ )
+ .is_err());
+ let resolve_pair_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "from farm",
+ err: SqlError::Internal,
+ };
+ assert!(resolve_farm(
+ &resolve_pair_fail,
+ &RadrootsReplicaFarmSelector {
+ id: None,
+ d_tag: Some(farm_row.d_tag.clone()),
+ pubkey: Some(farm_row.pubkey.clone()),
+ }
+ )
+ .is_err());
+
+ let gcs_query_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "from gcs_location",
+ err: SqlError::Internal,
+ };
+ assert!(load_relation_by_role(
+ &gcs_query_fail,
+ &farm_row.id,
+ ROLE_PRIMARY,
+ RelationType::Farm
+ )
+ .is_err());
+ super::failpoints::set_gcs_location_to_event_error();
+ assert!(
+ load_relation_by_role(&exec, &farm_row.id, ROLE_PRIMARY, RelationType::Farm).is_err()
+ );
+
+ let member_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "farm_member",
+ err: SqlError::Internal,
+ };
+ assert!(collect_member_pubkeys(&member_fail, &farm_row.id).is_err());
+ assert!(collect_profile_pubkeys(&member_fail, &farm_row).is_err());
+
+ let list_plot_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "from plot",
+ err: SqlError::Internal,
+ };
+ assert!(radroots_replica_list_set_events(&list_plot_fail, &farm_row).is_err());
+
+ let list_member_error_farm = create_farm_record(
+ &exec,
+ "AAAAAAAAAAAAAAAAAAAAAA",
+ &"1".repeat(64),
+ "list-member-error",
+ );
+ add_member_record(
+ &exec,
+ &list_member_error_farm.id,
+ &" ".repeat(64),
+ ROLE_MEMBER,
+ );
+ create_plot_record(
+ &exec,
+ &list_member_error_farm.id,
+ "AAAAAAAAAAAAAAAAAAAAAQ",
+ "plot-member-error",
+ );
+ assert!(radroots_replica_list_set_events(&exec, &list_member_error_farm).is_err());
+
+ let list_owner_error_farm = create_farm_record(
+ &exec,
+ "AAAAAAAAAAAAAAAAAAAAAA",
+ &"2".repeat(64),
+ "list-owner-error",
+ );
+ add_member_record(
+ &exec,
+ &list_owner_error_farm.id,
+ &"a".repeat(64),
+ ROLE_MEMBER,
+ );
+ add_member_record(
+ &exec,
+ &list_owner_error_farm.id,
+ &" ".repeat(64),
+ ROLE_OWNER,
+ );
+ add_member_record(
+ &exec,
+ &list_owner_error_farm.id,
+ &"b".repeat(64),
+ ROLE_WORKER,
+ );
+ create_plot_record(
+ &exec,
+ &list_owner_error_farm.id,
+ "AAAAAAAAAAAAAAAAAAAAAQ",
+ "plot-owner-error",
+ );
+ assert!(radroots_replica_list_set_events(&exec, &list_owner_error_farm).is_err());
+
+ let list_worker_error_farm = create_farm_record(
+ &exec,
+ "AAAAAAAAAAAAAAAAAAAAAA",
+ &"3".repeat(64),
+ "list-worker-error",
+ );
+ add_member_record(
+ &exec,
+ &list_worker_error_farm.id,
+ &"c".repeat(64),
+ ROLE_MEMBER,
+ );
+ add_member_record(
+ &exec,
+ &list_worker_error_farm.id,
+ &"d".repeat(64),
+ ROLE_OWNER,
+ );
+ add_member_record(
+ &exec,
+ &list_worker_error_farm.id,
+ &" ".repeat(64),
+ ROLE_WORKER,
+ );
+ create_plot_record(
+ &exec,
+ &list_worker_error_farm.id,
+ "AAAAAAAAAAAAAAAAAAAAAQ",
+ "plot-worker-error",
+ );
+ assert!(radroots_replica_list_set_events(&exec, &list_worker_error_farm).is_err());
+
+ let list_plot_error_farm = create_farm_record(
+ &exec,
+ "AAAAAAAAAAAAAAAAAAAAAA",
+ &"4".repeat(64),
+ "list-plot-error",
+ );
+ add_member_record(
+ &exec,
+ &list_plot_error_farm.id,
+ &"e".repeat(64),
+ ROLE_MEMBER,
+ );
+ add_member_record(&exec, &list_plot_error_farm.id, &"f".repeat(64), ROLE_OWNER);
+ add_member_record(
+ &exec,
+ &list_plot_error_farm.id,
+ &"7".repeat(64),
+ ROLE_WORKER,
+ );
+ create_plot_record(&exec, &list_plot_error_farm.id, "", "plot-list-error");
+ assert!(radroots_replica_list_set_events(&exec, &list_plot_error_farm).is_err());
+
+ super::failpoints::set_list_set_to_wire_error();
+ assert!(radroots_replica_list_set_events(&exec, &farm_row).is_err());
+
+ let claims_member_query_fail = QueryFailExecutor {
+ inner: &exec,
+ needle: "where member_pubkey",
+ err: SqlError::Internal,
+ };
+ assert!(radroots_replica_membership_claim_events(
+ &claims_member_query_fail,
+ &farm_row.pubkey
+ )
+ .is_err());
+
+ let _ = farm_member_claim::create(
+ &exec,
+ &IFarmMemberClaimFields {
+ member_pubkey: "q".repeat(64),
+ farm_pubkey: " ".repeat(64),
+ },
+ )
+ .expect("empty-farm-pubkey claim");
+ assert!(radroots_replica_membership_claim_events(&exec, &" ".repeat(64)).is_err());
+
+ super::failpoints::set_list_set_to_wire_error();
+ assert!(radroots_replica_membership_claim_events(&exec, &farm_row.pubkey).is_err());
+ }
+
+ #[test]
fn emit_pass_through_executor_instantiation_paths_are_covered() {
let exec = SqliteExecutor::open_memory().expect("db");
let (farm_row, _, plot_secondary) = seed(&exec);
@@ -1895,17 +2235,15 @@ mod tests {
)
.expect("resolve by pair");
assert_eq!(resolved_by_pair.id, farm_row.id);
- assert!(
- resolve_farm(
- &pass,
- &RadrootsReplicaFarmSelector {
- id: Some("00000000-0000-0000-0000-000000000000".to_string()),
- d_tag: None,
- pubkey: None,
- },
- )
- .is_err()
- );
+ assert!(resolve_farm(
+ &pass,
+ &RadrootsReplicaFarmSelector {
+ id: Some("00000000-0000-0000-0000-000000000000".to_string()),
+ d_tag: None,
+ pubkey: None,
+ },
+ )
+ .is_err());
let member_pubkeys = collect_member_pubkeys(&pass, &farm_row.id).expect("member pubkeys");
assert!(!member_pubkeys.is_empty());