context.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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.config_dir().is_none() {
  49. error!("Config dir is required for action: {:?}", self.action());
  50. exit(1);
  51. }
  52. if self.sysroot_dir().is_none() {
  53. error!(
  54. "dragonos sysroot dir is required for action: {:?}",
  55. self.action()
  56. );
  57. exit(1);
  58. }
  59. }
  60. #[allow(dead_code)]
  61. pub fn self_ref(&self) -> Option<Arc<Self>> {
  62. self.self_ref.lock().unwrap().upgrade()
  63. }
  64. fn set_self_ref(&self, self_ref: Weak<Self>) {
  65. *self.self_ref.lock().unwrap() = self_ref;
  66. }
  67. pub fn target_arch(&self) -> &TargetArch {
  68. &self.target_arch
  69. }
  70. pub fn sysroot_dir(&self) -> Option<&PathBuf> {
  71. self.sysroot_dir.as_ref()
  72. }
  73. pub fn config_dir(&self) -> Option<&PathBuf> {
  74. self.config_dir.as_ref()
  75. }
  76. pub fn action(&self) -> &Action {
  77. &self.action
  78. }
  79. pub fn thread_num(&self) -> Option<usize> {
  80. self.thread_num
  81. }
  82. pub fn cache_dir(&self) -> Option<&PathBuf> {
  83. self.cache_dir.as_ref()
  84. }
  85. }
  86. #[cfg(test)]
  87. pub trait TestContextExt: TestContext {
  88. fn base_context(&self) -> &BaseTestContext;
  89. fn execute_context(&self) -> &DadkUserExecuteContext;
  90. }
  91. impl DadkUserExecuteContextBuilder {
  92. /// 用于测试的默认构建器
  93. #[cfg(test)]
  94. fn default_test_execute_context_builder(base_context: &BaseTestContext) -> Self {
  95. Self::default()
  96. .sysroot_dir(Some(base_context.fake_dragonos_sysroot()))
  97. .action(Action::Build)
  98. .thread_num(None)
  99. .cache_dir(Some(base_context.fake_dadk_cache_root()))
  100. .base_test_context(Some(base_context.clone()))
  101. .clone()
  102. }
  103. }
  104. #[cfg(test)]
  105. pub struct DadkExecuteContextTestBuildX86_64V1 {
  106. context: Arc<DadkUserExecuteContext>,
  107. }
  108. #[cfg(test)]
  109. impl TestContext for DadkExecuteContextTestBuildX86_64V1 {
  110. fn setup() -> Self {
  111. let base_context = BaseTestContext::setup();
  112. let context =
  113. DadkUserExecuteContextBuilder::default_test_execute_context_builder(&base_context)
  114. .target_arch(TargetArch::X86_64)
  115. .config_dir(Some(base_context.config_v1_dir()))
  116. .build()
  117. .expect("Failed to build DadkExecuteContextTestBuildX86_64V1");
  118. let context = Arc::new(context);
  119. context.init(context.clone());
  120. DadkExecuteContextTestBuildX86_64V1 { context }
  121. }
  122. }
  123. #[cfg(test)]
  124. pub struct DadkExecuteContextTestBuildRiscV64V1 {
  125. context: Arc<DadkUserExecuteContext>,
  126. }
  127. #[cfg(test)]
  128. impl TestContext for DadkExecuteContextTestBuildRiscV64V1 {
  129. fn setup() -> Self {
  130. let base_context = BaseTestContext::setup();
  131. let context =
  132. DadkUserExecuteContextBuilder::default_test_execute_context_builder(&base_context)
  133. .target_arch(TargetArch::RiscV64)
  134. .config_dir(Some(base_context.config_v1_dir()))
  135. .build()
  136. .expect("Failed to build DadkExecuteContextTestBuildRiscV64V1");
  137. let context = Arc::new(context);
  138. context.init(context.clone());
  139. DadkExecuteContextTestBuildRiscV64V1 { context }
  140. }
  141. }
  142. macro_rules! impl_for_test_context {
  143. ($context:ty) => {
  144. #[cfg(test)]
  145. impl std::ops::Deref for $context {
  146. type Target = DadkUserExecuteContext;
  147. fn deref(&self) -> &Self::Target {
  148. &self.context
  149. }
  150. }
  151. #[cfg(test)]
  152. impl TestContextExt for $context {
  153. fn base_context(&self) -> &BaseTestContext {
  154. self.base_test_context.as_ref().unwrap()
  155. }
  156. fn execute_context(&self) -> &DadkUserExecuteContext {
  157. &self.context
  158. }
  159. }
  160. };
  161. }
  162. impl_for_test_context!(DadkExecuteContextTestBuildX86_64V1);
  163. impl_for_test_context!(DadkExecuteContextTestBuildRiscV64V1);