Skip to content

Commit 46f285c

Browse files
committed
feat: use new trait but keep previous behavior
1 parent 6961d8e commit 46f285c

File tree

3 files changed

+76
-66
lines changed

3 files changed

+76
-66
lines changed

agent-control/src/sub_agent/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ pub enum SupervisorCreationError {
4646
SupervisorAssemble(#[from] SubAgentBuilderError),
4747
#[error("could not start the supervisor: {0}")]
4848
SupervisorStart(#[from] SupervisorStarterError),
49+
#[error("could not build the supervisor: {0}")]
50+
SupervisorBuild(String),
51+
#[error("could not start the supervisor: {0}")]
52+
SupervisorStartGeneric(String),
4953
}
5054

5155
#[derive(Error, Debug)]

agent-control/src/sub_agent/supervisor.rs

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -146,57 +146,63 @@ pub trait Supervisor: Sized {
146146
/// * `Err(Self::StopError)` - If shutdown encountered errors (resources may be partially cleaned)
147147
fn stop(self) -> Result<(), Self::StopError>;
148148
}
149+
149150
#[cfg(test)]
150-
pub mod tests {
151+
pub(crate) mod tests {
151152
use super::*;
152-
use crate::event::{SubAgentInternalEvent, channel::EventPublisher};
153-
use mockall::mock;
154-
use thiserror::Error;
153+
use mockall::{mock, predicate};
154+
155+
#[derive(Debug, thiserror::Error)]
156+
#[error("{0}")]
157+
pub struct TestingSupervisorError(pub String);
158+
159+
mock! {
160+
pub SupervisorBuilder<A> where A: SupervisorStarter {}
161+
162+
impl<A> SupervisorBuilder for SupervisorBuilder<A> where A: SupervisorStarter {
163+
type Starter = A;
164+
type Error = TestingSupervisorError;
165+
166+
fn build_supervisor(&self, effective_agent: EffectiveAgent) -> Result<A, TestingSupervisorError>;
167+
}
155168

156-
#[derive(Debug, Error)]
157-
#[error("mock error: {0}")]
158-
pub struct MockError(String);
169+
}
170+
171+
mock! {
172+
pub SupervisorStarter<A> where A: Supervisor {}
159173

160-
impl From<String> for MockError {
161-
fn from(value: String) -> Self {
162-
Self(value)
174+
impl<A> SupervisorStarter for SupervisorStarter<A> where A: Supervisor {
175+
type Supervisor = A;
176+
type Error = TestingSupervisorError;
177+
fn start(self, sub_agent_internal_publisher: EventPublisher<SubAgentInternalEvent>) -> Result<A, TestingSupervisorError>;
163178
}
164179
}
165180

166181
mock! {
167182
pub Supervisor {}
183+
168184
impl Supervisor for Supervisor {
169-
type ApplyError = MockError;
170-
type StopError = MockError;
185+
type ApplyError = TestingSupervisorError;
186+
type StopError = TestingSupervisorError;
171187

172-
fn apply(self, effective_agent: EffectiveAgent) -> Result<Self, MockError>;
173-
fn stop(self) -> Result<(), <Self as Supervisor>::StopError>;
188+
fn apply(self, effective_agent: EffectiveAgent) -> Result<Self, TestingSupervisorError>;
189+
190+
fn stop(self) -> Result<(), TestingSupervisorError>;
174191
}
175192
}
176193

177-
mock! {
178-
pub SupervisorStarter<S> where S: Supervisor + 'static {}
179-
impl<S> SupervisorStarter for SupervisorStarter<S> where S: Supervisor + 'static {
180-
type Supervisor = S;
181-
type Error = MockError;
182-
183-
fn start(
184-
self,
185-
sub_agent_internal_publisher: EventPublisher<SubAgentInternalEvent>,
186-
) -> Result<S, <Self as SupervisorStarter>::Error>;
194+
impl<A: Supervisor + Send + Sync + 'static> MockSupervisorStarter<A> {
195+
pub fn should_start(&mut self, supervisor: A) {
196+
self.expect_start()
197+
.with(predicate::always()) // we cannot do eq with a publisher
198+
.once()
199+
.return_once(|_| Ok(supervisor));
187200
}
188201
}
189202

190-
mock! {
191-
pub SupervisorBuilder<S> where S: SupervisorStarter + 'static {}
192-
impl<S> SupervisorBuilder for SupervisorBuilder<S> where S: SupervisorStarter + 'static {
193-
type Starter = S;
194-
type Error = MockError;
195-
196-
fn build_supervisor(
197-
&self,
198-
effective_agent: EffectiveAgent,
199-
) -> Result<S, <Self as SupervisorBuilder>::Error>;
203+
impl MockSupervisor {
204+
pub fn should_stop(&mut self) {
205+
self.expect_stop().once().return_once(|| Ok(()));
200206
}
201207
}
202208
}

agent-control/src/sub_agent_new.rs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use super::sub_agent::{
1818
event_handler::on_health::on_health,
1919
identity::AgentIdentity,
2020
remote_config_parser::{RemoteConfigParser, RemoteConfigParserError},
21-
supervisor::builder::SupervisorBuilder,
22-
supervisor::starter::SupervisorStarter,
23-
supervisor::stopper::SupervisorStopper,
21+
supervisor::SupervisorBuilder,
22+
supervisor::SupervisorStarter,
23+
supervisor::Supervisor,
2424
};
2525
use opamp_client::StartedClient;
2626

@@ -76,8 +76,8 @@ pub trait SubAgentBuilder {
7676
) -> Result<Self::NotStartedSubAgent, SubAgentBuilderError>;
7777
}
7878

79-
type BuilderSupervisorStopper<B> =
80-
<<B as SupervisorBuilder>::SupervisorStarter as SupervisorStarter>::SupervisorStopper;
79+
type BuilderSupervisor<B> =
80+
<<B as SupervisorBuilder>::Starter as SupervisorStarter>::Supervisor;
8181

8282
/// SubAgentStopper is implementing the StartedSubAgent trait.
8383
///
@@ -165,7 +165,7 @@ where
165165
/// Any failure to assemble the effective agent or the supervisor, or failure to start the
166166
/// supervisor will be mark the existing hash as failed and report the error if there's an
167167
/// OpAMP client present in the sub-agent.
168-
fn init_supervisor(&self) -> Option<BuilderSupervisorStopper<B>> {
168+
fn init_supervisor(&self) -> Option<BuilderSupervisor<B>> {
169169
// An earlier run of Agent Control might have data for this agent identity, so we
170170
// attempt to retrieve an existing remote config,
171171
// falling back to a local config if there's no remote config.
@@ -199,7 +199,7 @@ where
199199
let not_started_supervisor = effective_agent.and_then(|effective_agent| {
200200
self.supervisor_builder
201201
.build_supervisor(effective_agent)
202-
.map_err(SupervisorCreationError::from)
202+
.map_err(|e| SupervisorCreationError::SupervisorBuild(e.to_string()))
203203
.inspect_err(|e| error!("Failed to create supervisor: {e}"))
204204
});
205205

@@ -221,7 +221,7 @@ where
221221

222222
stopped_supervisor
223223
.start(self.sub_agent_internal_publisher.clone())
224-
.map_err(SupervisorCreationError::from)
224+
.map_err(|e| SupervisorCreationError::SupervisorStartGeneric(e.to_string()))
225225
.inspect_err(|e| error!("Failed to start supervisor: {e}"))
226226
});
227227

@@ -394,8 +394,8 @@ where
394394
&self,
395395
opamp_client: &C,
396396
config: OpampRemoteConfig,
397-
old_supervisor: Option<BuilderSupervisorStopper<B>>,
398-
) -> Option<BuilderSupervisorStopper<B>> {
397+
old_supervisor: Option<BuilderSupervisor<B>>,
398+
) -> Option<BuilderSupervisor<B>> {
399399
// If hash is same as the stored and is not on status applying (processing was incomplete),
400400
// the previous working supervisor will keep running but the status will be reported again.
401401
if let Ok(Some(rc)) = self.config_repository.get_remote_config(&self.identity.id)
@@ -508,9 +508,9 @@ where
508508
&self,
509509
opamp_client: &C,
510510
hash: &Hash,
511-
old_supervisor: Option<BuilderSupervisorStopper<B>>,
512-
new_supervisor: <B as SupervisorBuilder>::SupervisorStarter,
513-
) -> Option<BuilderSupervisorStopper<B>> {
511+
old_supervisor: Option<BuilderSupervisor<B>>,
512+
new_supervisor: <B as SupervisorBuilder>::Starter,
513+
) -> Option<BuilderSupervisor<B>> {
514514
let _ = opamp_client
515515
.update_effective_config()
516516
.inspect_err(|e| error!("Effective config update failed: {e}"));
@@ -564,7 +564,7 @@ where
564564
fn create_supervisor_from_remote_config(
565565
&self,
566566
parsed_remote: &Option<RemoteConfig>,
567-
) -> Result<<B as SupervisorBuilder>::SupervisorStarter, SupervisorCreationError> {
567+
) -> Result<<B as SupervisorBuilder>::Starter, SupervisorCreationError> {
568568
match parsed_remote {
569569
// Apply the remote config:
570570
// - Build supervisor
@@ -574,6 +574,7 @@ where
574574

575575
self.supervisor_builder
576576
.build_supervisor(effective_agent)
577+
.map_err(|e| SupervisorCreationError::SupervisorBuild(e.to_string()))
577578
.inspect(|_| {
578579
let _ = self
579580
.config_repository
@@ -602,10 +603,11 @@ where
602603
let effective_agent =
603604
self.effective_agent(remote_config.get_yaml_config().clone())?;
604605

605-
self.supervisor_builder.build_supervisor(effective_agent)
606+
self.supervisor_builder
607+
.build_supervisor(effective_agent)
608+
.map_err(|e| SupervisorCreationError::SupervisorBuild(e.to_string()))
606609
}
607610
}
608-
.map_err(SupervisorCreationError::from)
609611
}
610612

611613
fn effective_agent(
@@ -684,7 +686,7 @@ impl StartedSubAgent for SubAgentStopper {
684686

685687
pub fn stop_supervisor<S>(maybe_started_supervisor: Option<S>)
686688
where
687-
S: SupervisorStopper,
689+
S: Supervisor,
688690
{
689691
if let Some(s) = maybe_started_supervisor {
690692
let _ = s.stop().inspect_err(|err| {
@@ -720,9 +722,7 @@ pub mod tests {
720722
// TODO: remove when un-used
721723
use super::super::sub_agent::effective_agents_assembler::LocalEffectiveAgentsAssembler;
722724
use super::super::sub_agent::remote_config_parser::AgentRemoteConfigParser;
723-
use super::super::sub_agent::supervisor::builder::tests::MockSupervisorBuilder;
724-
use super::super::sub_agent::supervisor::starter::tests::MockSupervisorStarter;
725-
use super::super::sub_agent::supervisor::stopper::tests::MockSupervisorStopper;
725+
use super::super::sub_agent::supervisor::tests::{MockSupervisorBuilder, MockSupervisorStarter, MockSupervisor, TestingSupervisorError};
726726
use crate::agent_control::agent_id::AgentID;
727727
use crate::agent_control::run::on_host::AGENT_CONTROL_MODE_ON_HOST;
728728
use crate::agent_type::definition::AgentTypeDefinition;
@@ -750,7 +750,7 @@ pub mod tests {
750750

751751
type TestSubAgent = SubAgent<
752752
MockStartedOpAMPClient,
753-
MockSupervisorBuilder<MockSupervisorStarter>,
753+
MockSupervisorBuilder<MockSupervisorStarter<MockSupervisor>>,
754754
AgentRemoteConfigParser<MockRemoteConfigValidator>,
755755
InMemoryConfigRepository,
756756
LocalEffectiveAgentsAssembler<EmbeddedRegistry>,
@@ -936,7 +936,7 @@ deployment:
936936
status: RemoteConfigStatuses::Failed as i32,
937937
last_remote_config_hash: Self::hash().to_string().into_bytes(),
938938
error_message:
939-
"could not build the supervisor from an effective agent: no configuration found"
939+
"could not build the supervisor: no configuration found"
940940
.into(),
941941
}
942942
}
@@ -991,7 +991,7 @@ deployment:
991991

992992
fn sub_agent(
993993
opamp_client: Option<MockStartedOpAMPClient>,
994-
supervisor_builder: MockSupervisorBuilder<MockSupervisorStarter>,
994+
supervisor_builder: MockSupervisorBuilder<MockSupervisorStarter<MockSupervisor>>,
995995
config_repository: Arc<InMemoryConfigRepository>,
996996
) -> TestSubAgent {
997997
let (sub_agent_internal_publisher, sub_agent_internal_consumer) = pub_sub();
@@ -1021,34 +1021,34 @@ deployment:
10211021
)
10221022
}
10231023

1024-
fn expect_supervisor_shut_down() -> MockSupervisorStopper {
1025-
let mut supervisor = MockSupervisorStopper::new();
1024+
fn expect_supervisor_shut_down() -> MockSupervisor {
1025+
let mut supervisor = MockSupervisor::new();
10261026
supervisor.should_stop();
10271027
supervisor
10281028
}
1029-
fn expect_supervisor_does_not_stop() -> MockSupervisorStopper {
1030-
let mut supervisor = MockSupervisorStopper::new();
1029+
fn expect_supervisor_does_not_stop() -> MockSupervisor {
1030+
let mut supervisor = MockSupervisor::new();
10311031
supervisor.expect_stop().never();
10321032
supervisor
10331033
}
1034-
fn expect_fail_to_build_supervisor() -> MockSupervisorBuilder<MockSupervisorStarter> {
1034+
fn expect_fail_to_build_supervisor() -> MockSupervisorBuilder<MockSupervisorStarter<MockSupervisor>> {
10351035
let mut supervisor_builder = MockSupervisorBuilder::new();
10361036
supervisor_builder
10371037
.expect_build_supervisor()
10381038
.once()
1039-
.return_once(|_| Err(SubAgentError::NoConfiguration.into()));
1039+
.return_once(|_| Err(TestingSupervisorError("no configuration found".to_string())));
10401040
supervisor_builder
10411041
}
1042-
fn expect_supervisor_do_not_build() -> MockSupervisorBuilder<MockSupervisorStarter> {
1042+
fn expect_supervisor_do_not_build() -> MockSupervisorBuilder<MockSupervisorStarter<MockSupervisor>> {
10431043
let mut supervisor_builder = MockSupervisorBuilder::new();
10441044
supervisor_builder.expect_build_supervisor().never();
10451045
supervisor_builder
10461046
}
10471047
fn expect_build_supervisor_with(
10481048
expected_config_value: String,
1049-
) -> MockSupervisorBuilder<MockSupervisorStarter> {
1049+
) -> MockSupervisorBuilder<MockSupervisorStarter<MockSupervisor>> {
10501050
let mut supervisor_builder = MockSupervisorBuilder::new();
1051-
let started_supervisor = MockSupervisorStopper::new();
1051+
let started_supervisor = MockSupervisor::new();
10521052
let mut stopped_supervisor = MockSupervisorStarter::new();
10531053
stopped_supervisor.should_start(started_supervisor);
10541054
supervisor_builder

0 commit comments

Comments
 (0)