nautilus_testkit/
components.rs1use indexmap::IndexMap;
19use nautilus_common::{
20 actor::{DataActor, DataActorCore, data_actor::DataActorConfig},
21 nautilus_actor,
22};
23use nautilus_model::identifiers::{ActorId, StrategyId};
24use nautilus_trading::{
25 nautilus_strategy,
26 strategy::{config::StrategyConfig, core::StrategyCore},
27};
28
29use crate::cache::TestCacheDatabaseControl;
30
31#[derive(Debug)]
33pub struct StateActor {
34 core: DataActorCore,
35 control: TestCacheDatabaseControl,
36 state_load: Option<IndexMap<String, Vec<u8>>>,
37 state_save: IndexMap<String, Vec<u8>>,
38 fail_load: bool,
39 fail_save: bool,
40 fail_start: bool,
41}
42
43impl StateActor {
44 #[must_use]
46 pub fn new(
47 actor_id: ActorId,
48 control: TestCacheDatabaseControl,
49 state_save: IndexMap<String, Vec<u8>>,
50 ) -> Self {
51 Self {
52 core: DataActorCore::new(DataActorConfig {
53 actor_id: Some(actor_id),
54 ..Default::default()
55 }),
56 control,
57 state_load: None,
58 state_save,
59 fail_load: false,
60 fail_save: false,
61 fail_start: false,
62 }
63 }
64
65 #[must_use]
67 pub const fn with_fail_load(mut self) -> Self {
68 self.fail_load = true;
69 self
70 }
71
72 #[must_use]
74 pub const fn with_fail_save(mut self) -> Self {
75 self.fail_save = true;
76 self
77 }
78
79 #[must_use]
81 pub const fn with_fail_start(mut self) -> Self {
82 self.fail_start = true;
83 self
84 }
85
86 #[must_use]
88 pub const fn state_load(&self) -> Option<&IndexMap<String, Vec<u8>>> {
89 self.state_load.as_ref()
90 }
91}
92
93impl DataActor for StateActor {
94 fn on_load(&mut self, state: IndexMap<String, Vec<u8>>) -> anyhow::Result<()> {
95 self.control.record("actor.on_load");
96 if self.fail_load {
97 anyhow::bail!("test actor on_load failure");
98 }
99 self.state_load = Some(state);
100 Ok(())
101 }
102
103 fn on_start(&mut self) -> anyhow::Result<()> {
104 self.control.record("actor.on_start");
105 if self.fail_start {
106 anyhow::bail!("test actor on_start failure");
107 }
108 Ok(())
109 }
110
111 fn on_stop(&mut self) -> anyhow::Result<()> {
112 self.control.record("actor.on_stop");
113 Ok(())
114 }
115
116 fn on_save(&self) -> anyhow::Result<IndexMap<String, Vec<u8>>> {
117 self.control.record("actor.on_save");
118 if self.fail_save {
119 anyhow::bail!("test actor on_save failure");
120 }
121 Ok(self.state_save.clone())
122 }
123}
124
125nautilus_actor!(StateActor);
126
127#[derive(Debug)]
129pub struct StateStrategy {
130 core: StrategyCore,
131 control: TestCacheDatabaseControl,
132 state_load: Option<IndexMap<String, Vec<u8>>>,
133 state_save: IndexMap<String, Vec<u8>>,
134 fail_load: bool,
135 fail_save: bool,
136 fail_start: bool,
137}
138
139impl StateStrategy {
140 #[must_use]
142 pub fn new(
143 strategy_id: StrategyId,
144 control: TestCacheDatabaseControl,
145 state_save: IndexMap<String, Vec<u8>>,
146 ) -> Self {
147 Self {
148 core: StrategyCore::new(StrategyConfig {
149 strategy_id: Some(strategy_id),
150 ..Default::default()
151 }),
152 control,
153 state_load: None,
154 state_save,
155 fail_load: false,
156 fail_save: false,
157 fail_start: false,
158 }
159 }
160
161 #[must_use]
163 pub const fn with_fail_load(mut self) -> Self {
164 self.fail_load = true;
165 self
166 }
167
168 #[must_use]
170 pub const fn with_fail_save(mut self) -> Self {
171 self.fail_save = true;
172 self
173 }
174
175 #[must_use]
177 pub const fn with_fail_start(mut self) -> Self {
178 self.fail_start = true;
179 self
180 }
181
182 #[must_use]
184 pub const fn state_load(&self) -> Option<&IndexMap<String, Vec<u8>>> {
185 self.state_load.as_ref()
186 }
187}
188
189impl DataActor for StateStrategy {
190 fn on_load(&mut self, state: IndexMap<String, Vec<u8>>) -> anyhow::Result<()> {
191 self.control.record("strategy.on_load");
192 if self.fail_load {
193 anyhow::bail!("test strategy on_load failure");
194 }
195 self.state_load = Some(state);
196 Ok(())
197 }
198
199 fn on_start(&mut self) -> anyhow::Result<()> {
200 self.control.record("strategy.on_start");
201 if self.fail_start {
202 anyhow::bail!("test strategy on_start failure");
203 }
204 Ok(())
205 }
206
207 fn on_stop(&mut self) -> anyhow::Result<()> {
208 self.control.record("strategy.on_stop");
209 Ok(())
210 }
211
212 fn on_save(&self) -> anyhow::Result<IndexMap<String, Vec<u8>>> {
213 self.control.record("strategy.on_save");
214 if self.fail_save {
215 anyhow::bail!("test strategy on_save failure");
216 }
217 Ok(self.state_save.clone())
218 }
219}
220
221nautilus_strategy!(StateStrategy);