xref: /DADK/dadk-user/src/context.rs (revision 5129c63bfab60a54627def29dc1b53c722677e4e)
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::{global::BaseGlobalTestContext, test_context::TestContext};
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<BaseGlobalTestContext>,
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.config_dir().is_none() {
59             error!("Config dir is required for action: {:?}", self.action());
60             exit(1);
61         }
62 
63         if self.sysroot_dir().is_none() {
64             error!(
65                 "dragonos sysroot dir is required for action: {:?}",
66                 self.action()
67             );
68             exit(1);
69         }
70     }
71 
72     #[allow(dead_code)]
73     pub fn self_ref(&self) -> Option<Arc<Self>> {
74         self.self_ref.lock().unwrap().upgrade()
75     }
76 
77     fn set_self_ref(&self, self_ref: Weak<Self>) {
78         *self.self_ref.lock().unwrap() = self_ref;
79     }
80 
81     pub fn target_arch(&self) -> &TargetArch {
82         &self.target_arch
83     }
84 
85     pub fn sysroot_dir(&self) -> Option<&PathBuf> {
86         self.sysroot_dir.as_ref()
87     }
88 
89     pub fn config_dir(&self) -> Option<&PathBuf> {
90         self.config_dir.as_ref()
91     }
92 
93     pub fn action(&self) -> &Action {
94         &self.action
95     }
96 
97     pub fn thread_num(&self) -> Option<usize> {
98         self.thread_num
99     }
100 
101     pub fn cache_dir(&self) -> Option<&PathBuf> {
102         self.cache_dir.as_ref()
103     }
104 }
105 
106 #[cfg(test)]
107 pub trait TestContextExt: TestContext {
108     fn base_context(&self) -> &BaseGlobalTestContext;
109 
110     fn execute_context(&self) -> &DadkUserExecuteContext;
111 }
112 
113 impl DadkUserExecuteContextBuilder {
114     /// 用于测试的默认构建器
115     #[cfg(test)]
116     fn default_test_execute_context_builder(base_context: &BaseGlobalTestContext) -> Self {
117         Self::default()
118             .sysroot_dir(Some(base_context.fake_dragonos_sysroot()))
119             .action(Action::Build)
120             .thread_num(None)
121             .cache_dir(Some(base_context.fake_dadk_cache_root()))
122             .base_test_context(Some(base_context.clone()))
123             .clone()
124     }
125 }
126 
127 #[cfg(test)]
128 pub struct DadkExecuteContextTestBuildX86_64V1 {
129     context: Arc<DadkUserExecuteContext>,
130 }
131 
132 #[cfg(test)]
133 impl TestContext for DadkExecuteContextTestBuildX86_64V1 {
134     fn setup() -> Self {
135         let base_context = BaseGlobalTestContext::setup();
136         let context =
137             DadkUserExecuteContextBuilder::default_test_execute_context_builder(&base_context)
138                 .target_arch(TargetArch::X86_64)
139                 .config_dir(Some(base_context.config_v1_dir()))
140                 .build()
141                 .expect("Failed to build DadkExecuteContextTestBuildX86_64V1");
142         let context = Arc::new(context);
143         context.init(context.clone());
144         DadkExecuteContextTestBuildX86_64V1 { context }
145     }
146 }
147 
148 #[cfg(test)]
149 pub struct DadkExecuteContextTestBuildRiscV64V1 {
150     context: Arc<DadkUserExecuteContext>,
151 }
152 
153 #[cfg(test)]
154 impl TestContext for DadkExecuteContextTestBuildRiscV64V1 {
155     fn setup() -> Self {
156         let base_context = BaseGlobalTestContext::setup();
157         let context =
158             DadkUserExecuteContextBuilder::default_test_execute_context_builder(&base_context)
159                 .target_arch(TargetArch::RiscV64)
160                 .config_dir(Some(base_context.config_v1_dir()))
161                 .build()
162                 .expect("Failed to build DadkExecuteContextTestBuildRiscV64V1");
163         let context = Arc::new(context);
164         context.init(context.clone());
165         DadkExecuteContextTestBuildRiscV64V1 { context }
166     }
167 }
168 
169 macro_rules! impl_for_test_context {
170     ($context:ty) => {
171         #[cfg(test)]
172         impl std::ops::Deref for $context {
173             type Target = DadkUserExecuteContext;
174 
175             fn deref(&self) -> &Self::Target {
176                 &self.context
177             }
178         }
179 
180         #[cfg(test)]
181         impl TestContextExt for $context {
182             fn base_context(&self) -> &BaseGlobalTestContext {
183                 self.base_test_context.as_ref().unwrap()
184             }
185 
186             fn execute_context(&self) -> &DadkUserExecuteContext {
187                 &self.context
188             }
189         }
190     };
191 }
192 
193 impl_for_test_context!(DadkExecuteContextTestBuildX86_64V1);
194 impl_for_test_context!(DadkExecuteContextTestBuildRiscV64V1);
195