Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#349] Add service name generator to be able to run tests concurrently #472

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions doc/how-to-create-an-iceoryx2-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ number is `Xold.Yold.Zold`.
10. Adjust the `<version>` to `X.Y.Z` in `$GIT_ROOT$/package.xml`.
11. Call `rg "Xold\.Yold\.Zold"` and adjust all findings.
* C and C++ examples, `BUILD.bazel` & `CMakeLists.txt`
12. **Merge all changes to `main`.**
13. Set tag on GitHub and add the release document as notes to the tag
12. Adjust the major, minor and patch version number in `iceoryx2_bb_elementary::PackageVersion`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a script taking care of setting the version number in all known locations would be helpful. I'll add it to my todo list :)

13. **Merge all changes to `main`.**
14. Set tag on GitHub and add the release document as notes to the tag
description. Add also a link to the file.
14. Check the order of all dependencies in
15. Check the order of all dependencies in
`$GIT_ROOT$/./internal/scripts/crates_io_publish_script.sh`.
When calling `cargo publish -p $PACKAGE$` all dependencies, also dev-dependencies,
must be already published to `crates.io` via `cargo publish -p`. Verify the
Expand All @@ -92,7 +93,7 @@ number is `Xold.Yold.Zold`.
* If the publish script was started and a crate requires a dependency which
is not available on `crates.io` the release has to be redone and the patch
version has to increase by one for the whole workspace.
15. Call `$GIT_ROOT$/./internal/scripts/crates_io_publish_script.sh` and publish
16. Call `$GIT_ROOT$/./internal/scripts/crates_io_publish_script.sh` and publish
all crates on `crates.io` and `docs.rs`.
16. Verify that the release looks fine on `docs.rs` (click through the
17. Verify that the release looks fine on `docs.rs` (click through the
documentation to check if everything was generated correctly)
26 changes: 5 additions & 21 deletions iceoryx2-bb/elementary/src/package_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

use iceoryx2_pal_concurrency_sync::iox_atomic::IoxAtomicU64;
use std::{fmt::Display, sync::atomic::Ordering};
use std::fmt::Display;

/// Represents the crates version acquired through the internal environment variables set by cargo,
/// ("CARGO_PKG_VERSION_{MAJOR|MINOR|PATCH}").
Expand Down Expand Up @@ -63,26 +62,11 @@ impl PackageVersion {

/// Returns the current [`PackageVersion`]
pub fn get() -> PackageVersion {
static PACKAGE_VERSION: IoxAtomicU64 = IoxAtomicU64::new(0);
const MAJOR: u16 = 0;
const MINOR: u16 = 4;
const PATCH: u16 = 1;

if PACKAGE_VERSION.load(Ordering::Relaxed) == 0 {
let major = option_env!("CARGO_PKG_VERSION_MAJOR")
.and_then(|s| s.parse::<u16>().ok())
.unwrap_or(u16::MAX);
let minor = option_env!("CARGO_PKG_VERSION_MINOR")
.and_then(|s| s.parse::<u16>().ok())
.unwrap_or(u16::MAX);
let patch = option_env!("CARGO_PKG_VERSION_PATCH")
.and_then(|s| s.parse::<u16>().ok())
.unwrap_or(u16::MAX);

PACKAGE_VERSION.store(
PackageVersion::from_version(major, minor, patch).0,
Ordering::Relaxed,
);
}

PackageVersion::from_u64(PACKAGE_VERSION.load(Ordering::Relaxed))
PackageVersion::from_version(MAJOR, MINOR, PATCH)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious, do we have a specific version convention? not sure why we didn't use the semver, which is popular in rust. so in the future we may have beta, alpha or rc versions.

https://crates.io/crates/semver

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general we try to be very cautious to introduce external crates. For any other project I would agree with you but iceoryx2 shall be certified as ASIL D according to ISO26262 which is the highest safety standard in the automotive world.

This requires 100% MC/DC coverage for every line of code. Every test must be covered by a requirement, we need detailed architecture documents and documentation, a safety manual and so on.

So, every dependency we introduce must satisfy all of this! No exception. But actually, nearly none of them does it, and it is a challenge to do it. We have a strategy in place how to solve this but one of the key factors is - try to avoid external crates as much as possible.

Another answer we need to find is, how to handle or prevent supply chain attacks.

So in light of all of this, we try to be very cautious with external dependencies since the more we have the more work we have to do in the near future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASIL D according to ISO26262 ... how to handle or prevent supply chain attacks.

understood, quite a bit different from the normal project. thanks for your explaination:)

}
}

Expand Down
35 changes: 35 additions & 0 deletions iceoryx2-bb/elementary/tests/package_version_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2024 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available under the
// terms of the Apache Software License 2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
// which is available at https://opensource.org/licenses/MIT.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

use iceoryx2_bb_elementary::package_version::PackageVersion;
use iceoryx2_bb_testing::assert_that;

#[test]
fn package_version_works() {
let major = option_env!("CARGO_PKG_VERSION_MAJOR")
.and_then(|s| s.parse::<u16>().ok())
.expect("Contains a valid major version number.");
let minor = option_env!("CARGO_PKG_VERSION_MINOR")
.and_then(|s| s.parse::<u16>().ok())
.expect("Contains a valid minor version number.");
let patch = option_env!("CARGO_PKG_VERSION_PATCH")
.and_then(|s| s.parse::<u16>().ok())
.expect("Contains a valid patch version number.");

let sut = PackageVersion::get();

assert_that!(sut.major(), eq major);
assert_that!(sut.minor(), eq minor);
assert_that!(sut.patch(), eq patch);

assert_that!(major == 0 && minor == 0 && patch == 0, eq false);
}
22 changes: 11 additions & 11 deletions iceoryx2-cal/src/dynamic_storage/posix_shared_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,18 +215,18 @@ impl<'builder, T: Send + Sync + Debug> Builder<'builder, T> {

let init_state = shm.base_address().as_ptr() as *const Data<T>;

// The mem-sync is actually not required since an uninitialized dynamic storage has
// only write permissions and can be therefore not consumed.
// This is only for the case that this strategy fails on an obscure POSIX platform.
//
//////////////////////////////////////////
// SYNC POINT: read Data<T>::data
//////////////////////////////////////////
let package_version = unsafe { &(*init_state) }
.version
.load(std::sync::atomic::Ordering::SeqCst);

loop {
// The mem-sync is actually not required since an uninitialized dynamic storage has
// only write permissions and can be therefore not consumed.
// This is only for the case that this strategy fails on an obscure POSIX platform.
//
//////////////////////////////////////////
// SYNC POINT: read Data<T>::data
//////////////////////////////////////////
let package_version = unsafe { &(*init_state) }
.version
.load(std::sync::atomic::Ordering::SeqCst);

let package_version = PackageVersion::from_u64(package_version);
if package_version.to_u64() == 0 {
if elapsed_time >= self.timeout {
Expand Down
33 changes: 12 additions & 21 deletions iceoryx2-ffi/cxx/tests/src/service_event_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

#include <cstdlib>

#include "iox2/node.hpp"
#include "iox2/node_name.hpp"
#include "iox2/service.hpp"
Expand All @@ -24,8 +26,7 @@ constexpr iox::units::Duration TIMEOUT = iox::units::Duration::fromMilliseconds(
template <typename T>
struct ServiceEventTest : public ::testing::Test {
ServiceEventTest()
: service_name_value { "We all love the hypnotoad!" }
, service_name { ServiceName::create(service_name_value).expect("") }
: service_name { iox2_testing::generate_service_name() }
, node { NodeBuilder().create<T::TYPE>().expect("") }
, service { node.service_builder(service_name).event().create().expect("") }
, notifier { service.notifier_builder().create().expect("") }
Expand All @@ -37,7 +38,6 @@ struct ServiceEventTest : public ::testing::Test {
static std::atomic<size_t> event_id_counter;
static constexpr ServiceType TYPE = T::TYPE;
//NOLINTBEGIN(misc-non-private-member-variables-in-classes), required for tests
const char* service_name_value { nullptr };
ServiceName service_name;
Node<T::TYPE> node;
PortFactoryEvent<T::TYPE> service;
Expand All @@ -56,8 +56,7 @@ TYPED_TEST_SUITE(ServiceEventTest, iox2_testing::ServiceTypes);
TYPED_TEST(ServiceEventTest, created_service_does_exist) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

ASSERT_FALSE(
Service<SERVICE_TYPE>::does_exist(service_name, Config::global_config(), MessagingPattern::Event).expect(""));
Expand All @@ -78,8 +77,7 @@ TYPED_TEST(ServiceEventTest, created_service_does_exist) {
TYPED_TEST(ServiceEventTest, creating_existing_service_fails) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto sut = node.service_builder(service_name).event().create().expect("");
Expand All @@ -94,8 +92,7 @@ TYPED_TEST(ServiceEventTest, service_settings_are_applied) {
constexpr uint64_t NUMBER_OF_NOTIFIERS = 5;
constexpr uint64_t NUMBER_OF_LISTENERS = 7;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto sut = node.service_builder(service_name)
Expand All @@ -115,8 +112,7 @@ TYPED_TEST(ServiceEventTest, open_fails_with_incompatible_max_notifiers_requirem
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
constexpr uint64_t NUMBER_OF_NOTIFIERS = 5;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto sut = node.service_builder(service_name).event().max_notifiers(NUMBER_OF_NOTIFIERS).create().expect("");
Expand All @@ -130,8 +126,7 @@ TYPED_TEST(ServiceEventTest, open_fails_with_incompatible_max_listeners_requirem
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;
constexpr uint64_t NUMBER_OF_LISTENERS = 7;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto sut = node.service_builder(service_name).event().max_listeners(NUMBER_OF_LISTENERS).create().expect("");
Expand All @@ -144,8 +139,7 @@ TYPED_TEST(ServiceEventTest, open_fails_with_incompatible_max_listeners_requirem
TYPED_TEST(ServiceEventTest, open_or_create_service_does_exist) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

ASSERT_FALSE(
Service<SERVICE_TYPE>::does_exist(service_name, Config::global_config(), MessagingPattern::Event).expect(""));
Expand Down Expand Up @@ -180,8 +174,7 @@ TYPED_TEST(ServiceEventTest, open_or_create_service_does_exist) {
TYPED_TEST(ServiceEventTest, opening_non_existing_service_fails) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto sut = node.service_builder(service_name).event().open();
Expand All @@ -192,8 +185,7 @@ TYPED_TEST(ServiceEventTest, opening_non_existing_service_fails) {
TYPED_TEST(ServiceEventTest, opening_existing_service_works) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;

const auto* name_value = "First time we met, I saw the ocean, it was wet!";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto sut_create = node.service_builder(service_name).event().create();
Expand All @@ -204,8 +196,7 @@ TYPED_TEST(ServiceEventTest, opening_existing_service_works) {
TYPED_TEST(ServiceEventTest, service_name_is_set) {
constexpr ServiceType SERVICE_TYPE = TestFixture::TYPE;

const auto* name_value = "Another one bites the toad.";
const auto service_name = ServiceName::create(name_value).expect("");
const auto service_name = iox2_testing::generate_service_name();

auto node = NodeBuilder().create<SERVICE_TYPE>().expect("");
auto sut = node.service_builder(service_name).event().create().expect("");
Expand Down
Loading
Loading