Skip to content

Commit 6366e72

Browse files
authored
Merge pull request #439 from xieyuschen/iox2-213-add-more-test-cases
[#213] test: add test cases
2 parents 2649b09 + c472781 commit 6366e72

File tree

3 files changed

+213
-6
lines changed

3 files changed

+213
-6
lines changed

iceoryx2/src/service/builder/publish_subscribe.rs

+2
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ impl<Payload: Debug + ?Sized, UserHeader: Debug, ServiceType: service::Service>
271271
}
272272
}
273273

274+
// triggers the underlying is_service_available method to check whether the service described in base is available.
274275
fn is_service_available(
275276
&mut self,
276277
error_msg: &str,
@@ -370,6 +371,7 @@ impl<Payload: Debug + ?Sized, UserHeader: Debug, ServiceType: service::Service>
370371
self
371372
}
372373

374+
/// Validates configuration and overrides the invalid setting with meaningful values.
373375
fn adjust_attributes_to_meaningful_values(&mut self) {
374376
let origin = format!("{:?}", self);
375377
let settings = self.base.service_config.publish_subscribe_mut();

iceoryx2/src/service/static_config/message_type_details.rs

+153-6
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,24 @@ use serde::{Deserialize, Serialize};
2020
#[derive(Default, Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
2121
pub enum TypeVariant {
2222
#[default]
23-
/// A fixed size type like [`u64`]
23+
/// A type notated by [`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#reprc).
24+
/// with a constant size known at compile time is recognized as FixedSize.
25+
/// The FixedSize type should satisfy the [`Sized`].
26+
/// For example, all primitive types are FixedSize. The self-contained structs(without pointer members
27+
/// or heap-usages) are FixedSize.
2428
FixedSize,
25-
/// A dynamic sized type like a slice
29+
30+
/// A dynamic sized type strictly refers to the slice of an iceoryx2 compatible types.
31+
/// The struct with pointer members or with heap usage MUSTN't be recognized as Dynamic type.
32+
/// Indeed, they're the in-compatible iceoryx2 types.
33+
///
34+
/// The underlying reason is the shared memory which we use to store the payload data.
35+
/// If the payload type would use the heap then the type would use
36+
/// process local memory that is not available to another process.
37+
///
38+
/// The pointer requirement comes again from shared memory.
39+
/// It has a different pointer address offset in every process rendering any absolute pointer
40+
/// useless and dereferencing it would end up in a segfault.
2641
Dynamic,
2742
}
2843

@@ -33,9 +48,10 @@ pub struct TypeDetail {
3348
pub variant: TypeVariant,
3449
/// Contains the output of [`core::any::type_name()`].
3550
pub type_name: String,
36-
/// The size of the underlying type.
51+
/// The size of the underlying type calculated by [`core::mem::size_of`].
3752
pub size: usize,
38-
/// The alignment of the underlying type.
53+
/// The ABI-required minimum alignment of the underlying type calculated by [`core::mem::align_of`].
54+
/// It may be set by users with a larger alignment, e.g. the memory provided by allocator used by SIMD.
3955
pub alignment: usize,
4056
}
4157

@@ -64,11 +80,11 @@ pub struct MessageTypeDetails {
6480
}
6581

6682
impl MessageTypeDetails {
67-
pub(crate) fn from<Header, UserHeader, Payload>(variant: TypeVariant) -> Self {
83+
pub(crate) fn from<Header, UserHeader, Payload>(payload_variant: TypeVariant) -> Self {
6884
Self {
6985
header: TypeDetail::__internal_new::<Header>(TypeVariant::FixedSize),
7086
user_header: TypeDetail::__internal_new::<UserHeader>(TypeVariant::FixedSize),
71-
payload: TypeDetail::__internal_new::<Payload>(variant),
87+
payload: TypeDetail::__internal_new::<Payload>(payload_variant),
7288
}
7389
}
7490

@@ -78,6 +94,7 @@ impl MessageTypeDetails {
7894
payload_start as *const u8
7995
}
8096

97+
/// returns the pointer to the user header
8198
pub(crate) fn user_header_ptr_from_header(&self, header: *const u8) -> *const u8 {
8299
let header = header as usize;
83100
let user_header_start = align(header + self.header.size, self.user_header.alignment);
@@ -120,3 +137,133 @@ impl MessageTypeDetails {
120137
&& self.payload.alignment <= rhs.payload.alignment
121138
}
122139
}
140+
141+
#[cfg(test)]
142+
mod tests {
143+
use super::*;
144+
use iceoryx2_bb_testing::assert_that;
145+
146+
#[cfg(target_pointer_width = "32")]
147+
const ALIGNMENT: usize = 4;
148+
#[cfg(target_pointer_width = "64")]
149+
const ALIGNMENT: usize = 8;
150+
151+
#[test]
152+
fn test_from() {
153+
#[repr(C)]
154+
struct MyPayload {
155+
_a: i32,
156+
_b: bool,
157+
_c: i64,
158+
}
159+
160+
let sut = MessageTypeDetails::from::<i32, i64, MyPayload>(TypeVariant::FixedSize);
161+
let expected = MessageTypeDetails{
162+
header: TypeDetail{
163+
variant: TypeVariant::FixedSize,
164+
type_name: "i32".to_string(),
165+
size: 4,
166+
alignment: 4, // i32 uses 4 bytes, so its aliment is always 4 no matter x32 or x64.
167+
},
168+
user_header: TypeDetail{
169+
variant: TypeVariant::FixedSize,
170+
type_name: "i64".to_string(),
171+
size: 8,
172+
alignment: ALIGNMENT,
173+
},
174+
payload: TypeDetail{
175+
variant: TypeVariant::FixedSize,
176+
type_name: "iceoryx2::service::static_config::message_type_details::tests::test_from::MyPayload".to_string(),
177+
size: 16,
178+
alignment: ALIGNMENT,
179+
},
180+
};
181+
assert_that!(sut, eq expected);
182+
183+
let sut = MessageTypeDetails::from::<i32, bool, i64>(TypeVariant::Dynamic);
184+
let expected = MessageTypeDetails {
185+
header: TypeDetail {
186+
variant: TypeVariant::FixedSize,
187+
type_name: "i32".to_string(),
188+
size: 4,
189+
alignment: 4,
190+
},
191+
user_header: TypeDetail {
192+
variant: TypeVariant::FixedSize,
193+
type_name: "bool".to_string(),
194+
size: 1,
195+
alignment: 1,
196+
},
197+
payload: TypeDetail {
198+
variant: TypeVariant::Dynamic,
199+
type_name: "i64".to_string(),
200+
size: 8,
201+
alignment: ALIGNMENT,
202+
},
203+
};
204+
assert_that!(sut, eq expected);
205+
}
206+
207+
#[test]
208+
fn test_user_header_ptr_from_header() {
209+
let details = MessageTypeDetails::from::<i32, bool, i64>(TypeVariant::Dynamic);
210+
#[repr(C)]
211+
struct Demo {
212+
header: i32,
213+
user_header: bool,
214+
_payload: i64,
215+
}
216+
217+
let demo = Demo {
218+
header: 123,
219+
user_header: true,
220+
_payload: 123,
221+
};
222+
223+
let ptr: *const u8 = &demo.header as *const _ as *const u8;
224+
let user_header_ptr = details.user_header_ptr_from_header(ptr);
225+
let sut: *const bool = user_header_ptr as *const bool;
226+
assert_that!(unsafe { *sut } , eq demo.user_header);
227+
228+
let details = MessageTypeDetails::from::<i64, i32, i64>(TypeVariant::Dynamic);
229+
#[repr(C)]
230+
struct Demo2 {
231+
header: i64,
232+
user_header: i32,
233+
_payload: i64,
234+
}
235+
236+
let demo = Demo2 {
237+
header: 123,
238+
user_header: 999,
239+
_payload: 123,
240+
};
241+
242+
let ptr: *const u8 = &demo.header as *const _ as *const u8;
243+
let user_header_ptr = details.user_header_ptr_from_header(ptr);
244+
let sut: *const i32 = user_header_ptr as *const i32;
245+
assert_that!(unsafe { *sut } , eq demo.user_header);
246+
}
247+
248+
#[test]
249+
fn test_payload_ptr_from_header() {
250+
let details = MessageTypeDetails::from::<i32, i32, i32>(TypeVariant::Dynamic);
251+
#[repr(C)]
252+
struct Demo {
253+
header: i32,
254+
_user_header: i32,
255+
payload: i32,
256+
}
257+
258+
let demo = Demo {
259+
header: 123,
260+
_user_header: 123,
261+
payload: 9999,
262+
};
263+
264+
let ptr: *const u8 = &demo.header as *const _ as *const u8;
265+
let payload_ptr = details.payload_ptr_from_header(ptr) as *const i32;
266+
let sut = unsafe { *payload_ptr };
267+
assert_that!(sut, eq demo.payload);
268+
}
269+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) 2024 Contributors to the Eclipse Foundation
2+
//
3+
// See the NOTICE file(s) distributed with this work for additional
4+
// information regarding copyright ownership.
5+
//
6+
// This program and the accompanying materials are made available under the
7+
// terms of the Apache Software License 2.0 which is available at
8+
// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9+
// which is available at https://opensource.org/licenses/MIT.
10+
//
11+
// SPDX-License-Identifier: Apache-2.0 OR MIT
12+
13+
#[cfg(test)]
14+
mod service_static_config_message_type_details {
15+
use iceoryx2::service::static_config::message_type_details::{TypeDetail, TypeVariant};
16+
use iceoryx2_bb_testing::assert_that;
17+
use std::mem::size_of;
18+
19+
#[cfg(target_pointer_width = "32")]
20+
const ALIGNMENT: usize = 4;
21+
#[cfg(target_pointer_width = "64")]
22+
const ALIGNMENT: usize = 8;
23+
24+
#[test]
25+
fn test_internal_new() {
26+
#[repr(C)]
27+
struct Tmp;
28+
let sut = TypeDetail::__internal_new::<Tmp>(TypeVariant::FixedSize);
29+
let expected = TypeDetail{
30+
variant: TypeVariant::FixedSize,
31+
type_name: "service_static_config_tests::service_static_config_message_type_details::test_internal_new::Tmp".to_string(),
32+
size: 0 ,
33+
alignment: 1,
34+
};
35+
assert_that!(sut, eq expected);
36+
37+
let sut = TypeDetail::__internal_new::<i64>(TypeVariant::FixedSize);
38+
let expected = TypeDetail {
39+
variant: TypeVariant::FixedSize,
40+
type_name: "i64".to_string(),
41+
size: 8,
42+
alignment: ALIGNMENT,
43+
};
44+
45+
assert_that!(sut, eq expected);
46+
47+
let sut = TypeDetail::__internal_new::<TypeDetail>(TypeVariant::FixedSize);
48+
let expected = TypeDetail {
49+
variant: TypeVariant::FixedSize,
50+
type_name: "iceoryx2::service::static_config::message_type_details::TypeDetail"
51+
.to_string(),
52+
size: size_of::<TypeDetail>(),
53+
alignment: ALIGNMENT,
54+
};
55+
56+
assert_that!(sut, eq expected);
57+
}
58+
}

0 commit comments

Comments
 (0)