1 use std::{path::PathBuf, process::exit}; 2 3 use derive_builder::Builder; 4 use log::error; 5 #[cfg(test)] 6 use test_base::{test_context::TestContext, BaseTestContext}; 7 8 use crate::{console::Action, executor::cache::cache_root_init, scheduler::task_deque::TASK_DEQUE}; 9 10 #[derive(Debug, Builder)] 11 #[builder(setter(into))] 12 pub struct DadkExecuteContext { 13 /// DragonOS sysroot在主机上的路径 14 sysroot_dir: Option<PathBuf>, 15 /// DADK任务配置文件所在目录 16 config_dir: Option<PathBuf>, 17 /// 要执行的操作 18 action: Action, 19 /// 并行线程数量 20 thread_num: Option<usize>, 21 /// dadk缓存根目录 22 cache_dir: Option<PathBuf>, 23 24 #[cfg(test)] 25 base_test_context: Option<BaseTestContext>, 26 } 27 28 impl DadkExecuteContext { 29 pub fn init(&self) { 30 // 初始化缓存目录 31 let r: Result<(), crate::executor::ExecutorError> = 32 cache_root_init(self.cache_dir().cloned()); 33 if r.is_err() { 34 error!("Failed to init cache root: {:?}", r.unwrap_err()); 35 exit(1); 36 } 37 38 if let Some(thread) = self.thread_num() { 39 TASK_DEQUE.lock().unwrap().set_thread(thread); 40 } 41 42 if self.action() == &Action::New { 43 return; 44 } 45 46 if self.config_dir().is_none() { 47 error!("Config dir is required for action: {:?}", self.action()); 48 exit(1); 49 } 50 51 if self.sysroot_dir().is_none() { 52 error!( 53 "dragonos sysroot dir is required for action: {:?}", 54 self.action() 55 ); 56 exit(1); 57 } 58 } 59 pub fn sysroot_dir(&self) -> Option<&PathBuf> { 60 self.sysroot_dir.as_ref() 61 } 62 63 pub fn config_dir(&self) -> Option<&PathBuf> { 64 self.config_dir.as_ref() 65 } 66 67 pub fn action(&self) -> &Action { 68 &self.action 69 } 70 71 pub fn thread_num(&self) -> Option<usize> { 72 self.thread_num 73 } 74 75 pub fn cache_dir(&self) -> Option<&PathBuf> { 76 self.cache_dir.as_ref() 77 } 78 } 79 80 #[cfg(test)] 81 pub trait TestContextExt: TestContext { 82 fn base_context(&self) -> &BaseTestContext; 83 84 fn execute_context(&self) -> &DadkExecuteContext; 85 } 86 87 #[cfg(test)] 88 pub struct DadkExecuteContextTestBuildV1 { 89 context: DadkExecuteContext, 90 } 91 92 #[cfg(test)] 93 impl TestContext for DadkExecuteContextTestBuildV1 { 94 fn setup() -> Self { 95 let base_context = BaseTestContext::setup(); 96 let context = DadkExecuteContextBuilder::default() 97 .sysroot_dir(Some(base_context.fake_dragonos_sysroot())) 98 .config_dir(Some(base_context.config_v1_dir())) 99 .action(Action::Build) 100 .thread_num(None) 101 .cache_dir(Some(base_context.fake_dadk_cache_root())) 102 .base_test_context(Some(base_context)) 103 .build() 104 .expect("Failed to build DadkExecuteContextTestBuildV1"); 105 context.init(); 106 DadkExecuteContextTestBuildV1 { context } 107 } 108 } 109 110 #[cfg(test)] 111 impl TestContextExt for DadkExecuteContextTestBuildV1 { 112 fn base_context(&self) -> &BaseTestContext { 113 self.base_test_context.as_ref().unwrap() 114 } 115 116 fn execute_context(&self) -> &DadkExecuteContext { 117 &self.context 118 } 119 } 120 121 macro_rules! impl_deref_for_test_context { 122 ($context:ty) => { 123 #[cfg(test)] 124 impl std::ops::Deref for $context { 125 type Target = DadkExecuteContext; 126 127 fn deref(&self) -> &Self::Target { 128 &self.context 129 } 130 } 131 132 #[cfg(test)] 133 impl std::ops::DerefMut for $context { 134 fn deref_mut(&mut self) -> &mut Self::Target { 135 &mut self.context 136 } 137 } 138 }; 139 } 140 141 impl_deref_for_test_context!(DadkExecuteContextTestBuildV1); 142