context.rs 5.5 KB

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