xref: /DADK/dadk-user/src/context.rs (revision 73779f3d0abacaf05aae9b67820e68f4bb9cf53f)
1 use std::{
2     path::PathBuf,
3     process::exit,
4     sync::{Arc, Mutex, Weak},
5 };
6 
7 use derive_builder::Builder;
8 use log::error;
9 #[cfg(test)]
10 use test_base::{test_context::TestContext, BaseTestContext};
11 
12 use crate::{
13     console::Action, executor::cache::cache_root_init, parser::task::TargetArch,
14     scheduler::task_deque::TASK_DEQUE,
15 };
16 
17 #[derive(Debug, Builder)]
18 #[builder(setter(into))]
19 pub struct DadkUserExecuteContext {
20     /// DragonOS sysroot在主机上的路径
21     sysroot_dir: Option<PathBuf>,
22     /// DADK任务配置文件所在目录
23     config_dir: Option<PathBuf>,
24     /// 要执行的操作
25     action: Action,
26     /// 并行线程数量
27     thread_num: Option<usize>,
28     /// dadk缓存根目录
29     cache_dir: Option<PathBuf>,
30 
31     /// 目标架构
32     #[builder(default = "crate::DADKTask::default_target_arch()")]
33     target_arch: TargetArch,
34 
35     #[cfg(test)]
36     base_test_context: Option<BaseTestContext>,
37 
38     #[builder(setter(skip), default = "Mutex::new(Weak::new())")]
39     self_ref: Mutex<Weak<Self>>,
40 }
41 
42 impl DadkUserExecuteContext {
43     pub fn init(&self, self_arc: Arc<Self>) {
44         self.set_self_ref(Arc::downgrade(&self_arc));
45 
46         // 初始化缓存目录
47         let r: Result<(), crate::executor::ExecutorError> =
48             cache_root_init(self.cache_dir().cloned());
49         if r.is_err() {
50             error!("Failed to init cache root: {:?}", r.unwrap_err());
51             exit(1);
52         }
53 
54         if let Some(thread) = self.thread_num() {
55             TASK_DEQUE.lock().unwrap().set_thread(thread);
56         }
57 
58         if self.action() == &Action::New {
59             return;
60         }
61 
62         if self.config_dir().is_none() {
63             error!("Config dir is required for action: {:?}", self.action());
64             exit(1);
65         }
66 
67         if self.sysroot_dir().is_none() {
68             error!(
69                 "dragonos sysroot dir is required for action: {:?}",
70                 self.action()
71             );
72             exit(1);
73         }
74     }
75 
76     #[allow(dead_code)]
77     pub fn self_ref(&self) -> Option<Arc<Self>> {
78         self.self_ref.lock().unwrap().upgrade()
79     }
80 
81     fn set_self_ref(&self, self_ref: Weak<Self>) {
82         *self.self_ref.lock().unwrap() = self_ref;
83     }
84 
85     pub fn target_arch(&self) -> &TargetArch {
86         &self.target_arch
87     }
88 
89     pub fn sysroot_dir(&self) -> Option<&PathBuf> {
90         self.sysroot_dir.as_ref()
91     }
92 
93     pub fn config_dir(&self) -> Option<&PathBuf> {
94         self.config_dir.as_ref()
95     }
96 
97     pub fn action(&self) -> &Action {
98         &self.action
99     }
100 
101     pub fn thread_num(&self) -> Option<usize> {
102         self.thread_num
103     }
104 
105     pub fn cache_dir(&self) -> Option<&PathBuf> {
106         self.cache_dir.as_ref()
107     }
108 }
109 
110 #[cfg(test)]
111 pub trait TestContextExt: TestContext {
112     fn base_context(&self) -> &BaseTestContext;
113 
114     fn execute_context(&self) -> &DadkUserExecuteContext;
115 }
116 
117 impl DadkUserExecuteContextBuilder {
118     /// 用于测试的默认构建器
119     #[cfg(test)]
120     fn default_test_execute_context_builder(base_context: &BaseTestContext) -> Self {
121         Self::default()
122             .sysroot_dir(Some(base_context.fake_dragonos_sysroot()))
123             .action(Action::Build)
124             .thread_num(None)
125             .cache_dir(Some(base_context.fake_dadk_cache_root()))
126             .base_test_context(Some(base_context.clone()))
127             .clone()
128     }
129 }
130 
131 #[cfg(test)]
132 pub struct DadkExecuteContextTestBuildX86_64V1 {
133     context: Arc<DadkUserExecuteContext>,
134 }
135 
136 #[cfg(test)]
137 impl TestContext for DadkExecuteContextTestBuildX86_64V1 {
138     fn setup() -> Self {
139         let base_context = BaseTestContext::setup();
140         let context =
141             DadkUserExecuteContextBuilder::default_test_execute_context_builder(&base_context)
142                 .target_arch(TargetArch::X86_64)
143                 .config_dir(Some(base_context.config_v1_dir()))
144                 .build()
145                 .expect("Failed to build DadkExecuteContextTestBuildX86_64V1");
146         let context = Arc::new(context);
147         context.init(context.clone());
148         DadkExecuteContextTestBuildX86_64V1 { context }
149     }
150 }
151 
152 #[cfg(test)]
153 pub struct DadkExecuteContextTestBuildRiscV64V1 {
154     context: Arc<DadkUserExecuteContext>,
155 }
156 
157 #[cfg(test)]
158 impl TestContext for DadkExecuteContextTestBuildRiscV64V1 {
159     fn setup() -> Self {
160         let base_context = BaseTestContext::setup();
161         let context =
162             DadkUserExecuteContextBuilder::default_test_execute_context_builder(&base_context)
163                 .target_arch(TargetArch::RiscV64)
164                 .config_dir(Some(base_context.config_v1_dir()))
165                 .build()
166                 .expect("Failed to build DadkExecuteContextTestBuildRiscV64V1");
167         let context = Arc::new(context);
168         context.init(context.clone());
169         DadkExecuteContextTestBuildRiscV64V1 { context }
170     }
171 }
172 
173 macro_rules! impl_for_test_context {
174     ($context:ty) => {
175         #[cfg(test)]
176         impl std::ops::Deref for $context {
177             type Target = DadkUserExecuteContext;
178 
179             fn deref(&self) -> &Self::Target {
180                 &self.context
181             }
182         }
183 
184         #[cfg(test)]
185         impl TestContextExt for $context {
186             fn base_context(&self) -> &BaseTestContext {
187                 self.base_test_context.as_ref().unwrap()
188             }
189 
190             fn execute_context(&self) -> &DadkUserExecuteContext {
191                 &self.context
192             }
193         }
194     };
195 }
196 
197 impl_for_test_context!(DadkExecuteContextTestBuildX86_64V1);
198 impl_for_test_context!(DadkExecuteContextTestBuildRiscV64V1);
199