1use crate::{CheckUse, ExpectedResult, RoutingTestModel, RoutingTestModelBuilder};
6use cm_rust::*;
7use cm_rust_testing::*;
8use std::marker::PhantomData;
9use {fidl_fuchsia_io as fio, zx_status};
10
11pub struct CommonRightsTest<T: RoutingTestModelBuilder> {
12 builder: PhantomData<T>,
13}
14
15impl<T: RoutingTestModelBuilder> CommonRightsTest<T> {
16 pub fn new() -> Self {
17 Self { builder: PhantomData }
18 }
19
20 pub async fn test_offer_increasing_rights(&self) {
21 let components = vec![
22 (
23 "a",
24 ComponentDeclBuilder::new()
25 .offer(
26 OfferBuilder::directory()
27 .name("bar_data")
28 .target_name("baz_data")
29 .source_static_child("b")
30 .target_static_child("c")
31 .rights(fio::RW_STAR_DIR),
32 )
33 .child_default("b")
34 .child_default("c")
35 .build(),
36 ),
37 (
38 "b",
39 ComponentDeclBuilder::new()
40 .capability(
41 CapabilityBuilder::directory()
42 .name("foo_data")
43 .path("/data/foo")
44 .rights(fio::RW_STAR_DIR),
45 )
46 .expose(
47 ExposeBuilder::directory()
48 .name("foo_data")
49 .source(ExposeSource::Self_)
50 .target_name("bar_data")
51 .rights(fio::RW_STAR_DIR),
52 )
53 .build(),
54 ),
55 (
56 "c",
57 ComponentDeclBuilder::new()
58 .use_(UseBuilder::directory().name("baz_data").path("/data/hippo"))
59 .build(),
60 ),
61 ];
62 let model = T::new("a", components).build().await;
63 model
64 .check_use(["c"].try_into().unwrap(), CheckUse::default_directory(ExpectedResult::Ok))
65 .await;
66 }
67
68 pub async fn test_offer_incompatible_rights(&self) {
69 let components = vec![
70 (
71 "a",
72 ComponentDeclBuilder::new()
73 .offer(
74 OfferBuilder::directory()
75 .name("bar_data")
76 .target_name("baz_data")
77 .source_static_child("b")
78 .target_static_child("c")
79 .rights(fio::W_STAR_DIR),
80 )
81 .child_default("b")
82 .child_default("c")
83 .build(),
84 ),
85 (
86 "b",
87 ComponentDeclBuilder::new()
88 .capability(
89 CapabilityBuilder::directory()
90 .name("foo_data")
91 .path("/data/foo")
92 .rights(fio::RW_STAR_DIR),
93 )
94 .expose(
95 ExposeBuilder::directory()
96 .name("foo_data")
97 .source(ExposeSource::Self_)
98 .target_name("bar_data")
99 .rights(fio::RW_STAR_DIR),
100 )
101 .build(),
102 ),
103 (
104 "c",
105 ComponentDeclBuilder::new()
106 .use_(UseBuilder::directory().name("baz_data").path("/data/hippo"))
107 .build(),
108 ),
109 ];
110 let model = T::new("a", components).build().await;
111 model
112 .check_use(
113 ["c"].try_into().unwrap(),
114 CheckUse::default_directory(ExpectedResult::Err(zx_status::Status::ACCESS_DENIED)),
115 )
116 .await;
117 }
118
119 pub async fn test_expose_increasing_rights(&self) {
120 let components = vec![
121 (
122 "a",
123 ComponentDeclBuilder::new()
124 .offer(
125 OfferBuilder::directory()
126 .name("bar_data")
127 .target_name("baz_data")
128 .source_static_child("b")
129 .target_static_child("c")
130 .rights(fio::R_STAR_DIR),
131 )
132 .child_default("b")
133 .child_default("c")
134 .build(),
135 ),
136 (
137 "b",
138 ComponentDeclBuilder::new()
139 .capability(
140 CapabilityBuilder::directory()
141 .name("foo_data")
142 .path("/data/foo")
143 .rights(fio::RW_STAR_DIR),
144 )
145 .expose(
146 ExposeBuilder::directory()
147 .name("foo_data")
148 .source(ExposeSource::Self_)
149 .target_name("bar_data")
150 .rights(fio::RW_STAR_DIR),
151 )
152 .build(),
153 ),
154 (
155 "c",
156 ComponentDeclBuilder::new()
157 .use_(UseBuilder::directory().name("baz_data").path("/data/hippo"))
158 .build(),
159 ),
160 ];
161 let model = T::new("a", components).build().await;
162 model
163 .check_use(["c"].try_into().unwrap(), CheckUse::default_directory(ExpectedResult::Ok))
164 .await;
165 }
166
167 pub async fn test_expose_incompatible_rights(&self) {
168 let components = vec![
169 (
170 "a",
171 ComponentDeclBuilder::new()
172 .offer(
173 OfferBuilder::directory()
174 .name("bar_data")
175 .target_name("baz_data")
176 .source_static_child("b")
177 .target_static_child("c")
178 .rights(fio::RW_STAR_DIR),
179 )
180 .child_default("b")
181 .child_default("c")
182 .build(),
183 ),
184 (
185 "b",
186 ComponentDeclBuilder::new()
187 .capability(
188 CapabilityBuilder::directory()
189 .name("foo_data")
190 .path("/data/foo")
191 .rights(fio::RW_STAR_DIR),
192 )
193 .expose(
194 ExposeBuilder::directory()
195 .name("foo_data")
196 .source(ExposeSource::Self_)
197 .target_name("bar_data")
198 .rights(fio::W_STAR_DIR),
199 )
200 .build(),
201 ),
202 (
203 "c",
204 ComponentDeclBuilder::new()
205 .use_(UseBuilder::directory().name("baz_data").path("/data/hippo"))
206 .build(),
207 ),
208 ];
209 let model = T::new("a", components).build().await;
210 model
211 .check_use(
212 ["c"].try_into().unwrap(),
213 CheckUse::default_directory(ExpectedResult::Err(zx_status::Status::ACCESS_DENIED)),
214 )
215 .await;
216 }
217
218 pub async fn test_capability_increasing_rights(&self) {
219 let components = vec![
220 (
221 "a",
222 ComponentDeclBuilder::new()
223 .offer(
224 OfferBuilder::directory()
225 .name("bar_data")
226 .target_name("baz_data")
227 .source_static_child("b")
228 .target_static_child("c")
229 .rights(fio::R_STAR_DIR),
230 )
231 .child_default("b")
232 .child_default("c")
233 .build(),
234 ),
235 (
236 "b",
237 ComponentDeclBuilder::new()
238 .capability(
239 CapabilityBuilder::directory()
240 .name("foo_data")
241 .path("/data/foo")
242 .rights(fio::RW_STAR_DIR),
243 )
244 .expose(
245 ExposeBuilder::directory()
246 .name("foo_data")
247 .source(ExposeSource::Self_)
248 .target_name("bar_data")
249 .rights(fio::R_STAR_DIR),
250 )
251 .build(),
252 ),
253 (
254 "c",
255 ComponentDeclBuilder::new()
256 .use_(UseBuilder::directory().name("baz_data").path("/data/hippo"))
257 .build(),
258 ),
259 ];
260 let model = T::new("a", components).build().await;
261 model
262 .check_use(["c"].try_into().unwrap(), CheckUse::default_directory(ExpectedResult::Ok))
263 .await;
264 }
265
266 pub async fn test_capability_incompatible_rights(&self) {
267 let components = vec![
268 (
269 "a",
270 ComponentDeclBuilder::new()
271 .offer(
272 OfferBuilder::directory()
273 .name("bar_data")
274 .target_name("baz_data")
275 .source_static_child("b")
276 .target_static_child("c")
277 .rights(fio::RW_STAR_DIR),
278 )
279 .child_default("b")
280 .child_default("c")
281 .build(),
282 ),
283 (
284 "b",
285 ComponentDeclBuilder::new()
286 .capability(
287 CapabilityBuilder::directory()
288 .name("foo_data")
289 .path("/data/foo")
290 .rights(fio::W_STAR_DIR),
291 )
292 .expose(
293 ExposeBuilder::directory()
294 .name("foo_data")
295 .source(ExposeSource::Self_)
296 .target_name("bar_data")
297 .rights(fio::RW_STAR_DIR),
298 )
299 .build(),
300 ),
301 (
302 "c",
303 ComponentDeclBuilder::new()
304 .use_(UseBuilder::directory().name("baz_data").path("/data/hippo"))
305 .build(),
306 ),
307 ];
308 let model = T::new("a", components).build().await;
309 model
310 .check_use(
311 ["c"].try_into().unwrap(),
312 CheckUse::default_directory(ExpectedResult::Err(zx_status::Status::ACCESS_DENIED)),
313 )
314 .await;
315 }
316
317 pub async fn test_offer_from_component_manager_namespace_directory_incompatible_rights(&self) {
326 let components = vec![
327 (
328 "a",
329 ComponentDeclBuilder::new()
330 .offer(
331 OfferBuilder::directory()
332 .name("foo_data")
333 .target_name("bar_data")
334 .source(OfferSource::Parent)
335 .target_static_child("b"),
336 )
337 .child_default("b")
338 .build(),
339 ),
340 (
341 "b",
342 ComponentDeclBuilder::new()
343 .use_(UseBuilder::directory().name("bar_data").path("/data/hippo"))
344 .build(),
345 ),
346 ];
347 let namespace_capabilities = vec![CapabilityBuilder::directory()
348 .name("foo_data")
349 .path("/offer_from_cm_namespace/data/foo")
350 .rights(fio::W_STAR_DIR)
351 .build()];
352 let mut builder = T::new("a", components);
353 builder.set_namespace_capabilities(namespace_capabilities);
354 let model = builder.build().await;
355
356 model.install_namespace_directory("/offer_from_cm_namespace");
357 model
358 .check_use(
359 ["b"].try_into().unwrap(),
360 CheckUse::default_directory(ExpectedResult::Err(zx_status::Status::ACCESS_DENIED)),
361 )
362 .await;
363 }
364}