Skip to content
Snippets Groups Projects
Commit c1387013 authored by Florian Fischer's avatar Florian Fischer
Browse files

[lib/LinuxVersion] multiple fixes

* remove fancy but broken static LinuxVersion object.
  This means each usage of a EMPER_LINUX_* macro results in a syscall.
  But I think this is worth it when the result is a sound program.
  Users of those macros should store the result of the comparison anyway.
* fix that we skipped parsing the last part of a version string
* add a test for LinuxVersion
* IO_MUST_INVALIDATE_BROKEN_CHAIN can still be const
parent 83d9fb46
No related branches found
No related tags found
1 merge request!252[lib/LinuxVersion] multiple fixes
...@@ -45,7 +45,7 @@ void async(const Fiber::fiber_fun0_t& function, workeraffinity_t* affinity) { ...@@ -45,7 +45,7 @@ void async(const Fiber::fiber_fun0_t& function, workeraffinity_t* affinity) {
namespace emper { namespace emper {
bool IO_MUST_INVALIDATE_BROKEN_CHAIN = EMPER_LINUX_LT("5.15.0"); const bool IO_MUST_INVALIDATE_BROKEN_CHAIN = EMPER_LINUX_LT("5.15.0");
auto getFullVersion() -> std::string { return EMPER_FULL_VERSION; } auto getFullVersion() -> std::string { return EMPER_FULL_VERSION; }
......
...@@ -138,7 +138,7 @@ static const bool IO_URING_SQPOLL = ...@@ -138,7 +138,7 @@ static const bool IO_URING_SQPOLL =
// Emper.cpp object. // Emper.cpp object.
// This also has the advantage that the probability we crash because printing // This also has the advantage that the probability we crash because printing
// warnings during the comparison use not yet initialized components is reduced. // warnings during the comparison use not yet initialized components is reduced.
extern bool IO_MUST_INVALIDATE_BROKEN_CHAIN; extern const bool IO_MUST_INVALIDATE_BROKEN_CHAIN;
static const bool IO_URING_SHARED_WQ = static const bool IO_URING_SHARED_WQ =
#ifdef EMPER_IO_URING_SHARED_WQ #ifdef EMPER_IO_URING_SHARED_WQ
......
...@@ -33,19 +33,22 @@ static auto checked_strtol(const std::string& s) -> long { ...@@ -33,19 +33,22 @@ static auto checked_strtol(const std::string& s) -> long {
namespace emper::lib { namespace emper::lib {
LinuxVersion LinuxVersion::linuxVersion;
// Returns 1 if s is smaller, -1 if this is smaller, 0 if equal // Returns 1 if s is smaller, -1 if this is smaller, 0 if equal
auto LinuxVersion::compare(const std::string& s) -> int { auto LinuxVersion::compare(const std::string& s) -> int {
size_t dot_pos, dot_pos2;
size_t last_dot_pos = 0, last_dot_pos2 = 0; size_t last_dot_pos = 0, last_dot_pos2 = 0;
bool was_last = false;
for (;;) { for (;;) {
size_t dot_pos = this->version.find('.', last_dot_pos); dot_pos = this->version.find('.', last_dot_pos);
// We run out of parts to compare the versions must be equal if (dot_pos == std::string::npos) {
if (dot_pos == std::string::npos) return 0; was_last = true;
dot_pos = this->version.size();
size_t dot_pos2 = s.find('.', last_dot_pos2); dot_pos2 = s.size();
assert(dot_pos2 != std::string::npos); } else {
dot_pos2 = s.find('.', last_dot_pos2);
assert(dot_pos2 != std::string::npos);
}
long n1 = checked_strtol(this->version.substr(last_dot_pos, dot_pos - last_dot_pos)); long n1 = checked_strtol(this->version.substr(last_dot_pos, dot_pos - last_dot_pos));
long n2 = checked_strtol(s.substr(last_dot_pos2, dot_pos2 - last_dot_pos2)); long n2 = checked_strtol(s.substr(last_dot_pos2, dot_pos2 - last_dot_pos2));
...@@ -54,6 +57,9 @@ auto LinuxVersion::compare(const std::string& s) -> int { ...@@ -54,6 +57,9 @@ auto LinuxVersion::compare(const std::string& s) -> int {
if (n1 < n2) return -1; if (n1 < n2) return -1;
// We ran out of parts to compare the versions must be equal
if (was_last) return 0;
last_dot_pos = dot_pos + 1; last_dot_pos = dot_pos + 1;
last_dot_pos2 = dot_pos2 + 1; last_dot_pos2 = dot_pos2 + 1;
} }
......
...@@ -6,15 +6,18 @@ ...@@ -6,15 +6,18 @@
#include <string> #include <string>
class TestLinuxVersion;
namespace emper::lib { namespace emper::lib {
class LinuxVersion { class LinuxVersion {
friend class ::TestLinuxVersion;
std::string version; std::string version;
auto compare(const std::string& s) -> int; auto compare(const std::string& s) -> int;
public: LinuxVersion(std::string version) : version(version) {}
static LinuxVersion linuxVersion;
public:
LinuxVersion() { LinuxVersion() {
struct utsname buf; struct utsname buf;
uname(&buf); uname(&buf);
...@@ -33,13 +36,8 @@ class LinuxVersion { ...@@ -33,13 +36,8 @@ class LinuxVersion {
}; };
} // namespace emper::lib } // namespace emper::lib
#define EMPER_LINUX_EQ(version) \ #define EMPER_LINUX_EQ(version) (emper::lib::LinuxVersion() == version)
([]() -> bool { return empere::lib::LinuxVersion::linuxVersion == version; }()) #define EMPER_LINUX_GT(version) (emper::lib::LinuxVersion() > version))
#define EMPER_LINUX_GT(version) \ #define EMPER_LINUX_GE(version) (emper::lib::LinuxVersion() >= version)
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion > version; }()) #define EMPER_LINUX_LT(version) (emper::lib::LinuxVersion() < version)
#define EMPER_LINUX_GE(version) \ #define EMPER_LINUX_LE(version) (emper::lib::LinuxVersion() <= version)
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion >= version; }())
#define EMPER_LINUX_LT(version) \
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion < version; }())
#define EMPER_LINUX_LE(version) \
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion <= version; }())
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Fischer
#include <gtest/gtest.h>
#include <string>
#include <utility>
#include "lib/LinuxVersion.hpp"
using emper::lib::LinuxVersion;
class TestLinuxVersion {
public:
static auto eq(std::string v1, const std::string& v2) -> bool {
return LinuxVersion(std::move(v1)) == v2;
}
static auto neq(std::string v1, const std::string& v2) -> bool {
return LinuxVersion(std::move(v1)) != v2;
}
static auto lt(std::string v1, const std::string& v2) -> bool {
return LinuxVersion(std::move(v1)) < v2;
}
static auto le(std::string v1, const std::string& v2) -> bool {
return LinuxVersion(std::move(v1)) <= v2;
}
static auto gt(std::string v1, const std::string& v2) -> bool {
return LinuxVersion(std::move(v1)) > v2;
}
static auto ge(std::string v1, const std::string& v2) -> bool {
return LinuxVersion(std::move(v1)) >= v2;
}
};
// NOLINTNEXTLINE(modernize-use-trailing-return-type)
TEST(LinuxVersion, eq) {
ASSERT_TRUE(TestLinuxVersion::eq("5.13.0", "5.13.0"));
ASSERT_TRUE(TestLinuxVersion::eq("5.13-foo.0", "5.13.0"));
}
// NOLINTNEXTLINE(modernize-use-trailing-return-type)
TEST(LinuxVersion, neq) {
ASSERT_TRUE(TestLinuxVersion::neq("4.1.0", "5.13.0"));
ASSERT_TRUE(TestLinuxVersion::neq("4.1", "5.13.0"));
ASSERT_TRUE(TestLinuxVersion::neq("5.14.0", "5.13.0"));
ASSERT_TRUE(TestLinuxVersion::neq("5.13.1", "5.13.2"));
ASSERT_TRUE(TestLinuxVersion::neq("5.13-foo.1", "5.13.2"));
}
// NOLINTNEXTLINE(modernize-use-trailing-return-type)
TEST(LinuxVersion, lt) {
ASSERT_TRUE(TestLinuxVersion::lt("4.13", "5.14.0"));
ASSERT_TRUE(TestLinuxVersion::lt("5.13.0", "5.14.0"));
ASSERT_TRUE(TestLinuxVersion::lt("5.13-foo.1", "5.13.2"));
ASSERT_TRUE(TestLinuxVersion::lt("5.13.1-foo", "5.13.2"));
}
// NOLINTNEXTLINE(modernize-use-trailing-return-type)
TEST(LinuxVersion, le) {
ASSERT_TRUE(TestLinuxVersion::le("4.13.0", "5.14.0"));
ASSERT_TRUE(TestLinuxVersion::le("4.14.0", "5.14.0"));
}
// NOLINTNEXTLINE(modernize-use-trailing-return-type)
TEST(LinuxVersion, gt) {
ASSERT_TRUE(TestLinuxVersion::gt("5.14.0", "4.13"));
ASSERT_TRUE(TestLinuxVersion::gt("5.14.0", "5.13.0"));
ASSERT_TRUE(TestLinuxVersion::gt("5.13.2", "5.13-foo.1"));
ASSERT_TRUE(TestLinuxVersion::gt("5.13.2", "5.13.1-foo"));
}
// NOLINTNEXTLINE(modernize-use-trailing-return-type)
TEST(LinuxVersion, ge) {
ASSERT_TRUE(TestLinuxVersion::ge("5.14.0", "4.13"));
ASSERT_TRUE(TestLinuxVersion::ge("5.14.0", "5.14.0"));
}
...@@ -13,4 +13,12 @@ tests += [ ...@@ -13,4 +13,12 @@ tests += [
'gtest': true, 'gtest': true,
'is_parallel': true, 'is_parallel': true,
}, },
{
'source': files('LinuxVersionTest.cpp'),
'name': 'LinuxVersionTest',
'description': 'Tests LinuxVerison',
'gtest': true,
'is_parallel': true,
},
] ]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment