More session id work
This commit is contained in:
parent
1ceccd0720
commit
578065be47
@ -27,20 +27,42 @@ namespace parselink {
|
||||
namespace proto {
|
||||
|
||||
struct session_id {
|
||||
std::array<std::byte, 32> bytes;
|
||||
public:
|
||||
session_id() noexcept;
|
||||
|
||||
// Not the intended way to build a session id. Ideally, they'll be randomly
|
||||
// generated.
|
||||
explicit constexpr session_id(std::array<std::byte, 32> const& v) noexcept {
|
||||
std::copy(v.begin(), v.end(), bytes_.begin());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator<=>(
|
||||
session_id const& other) const noexcept {
|
||||
return bytes <=> other.bytes;
|
||||
return bytes_ <=> other.bytes_;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator==(
|
||||
session_id const& other) const noexcept {
|
||||
return bytes_ == other.bytes_;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator<=>(
|
||||
std::span<std::byte const> other) const noexcept {
|
||||
return std::lexicographical_compare_three_way(bytes.begin(),
|
||||
bytes.end(), other.begin(), other.end(),
|
||||
return std::lexicographical_compare_three_way(bytes_.begin(),
|
||||
bytes_.end(), other.begin(), other.end(),
|
||||
std::compare_three_way());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator==(
|
||||
std::span<std::byte const> other) const noexcept {
|
||||
return std::equal(bytes_.begin(), bytes_.end(), other.begin(), other.end());
|
||||
}
|
||||
|
||||
constexpr std::span<std::byte const> raw() const noexcept {
|
||||
return bytes_;
|
||||
}
|
||||
private:
|
||||
std::array<std::byte, 32> bytes_;
|
||||
};
|
||||
|
||||
} // namespace proto
|
||||
|
||||
@ -4,6 +4,7 @@ cc_library(
|
||||
name = "proto",
|
||||
srcs = [
|
||||
"session.cpp",
|
||||
"session_id.cpp",
|
||||
],
|
||||
deps = [
|
||||
"//include/parselink:proto",
|
||||
|
||||
38
source/proto/session_id.cpp
Normal file
38
source/proto/session_id.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// ___ __ _ _
|
||||
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
|
||||
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
|
||||
// / ___/ (_| | | \__ \ __/ /__| | | | | <
|
||||
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// Author: Kurt Sassenrath
|
||||
// Module: proto
|
||||
//
|
||||
// Session ID implementation
|
||||
//
|
||||
// Copyright (c) 2023 Kurt Sassenrath.
|
||||
//
|
||||
// License TBD.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "parselink/proto/session_id.h"
|
||||
|
||||
#include "hydrogen.h"
|
||||
|
||||
namespace {
|
||||
void ensure_initialized() {
|
||||
static auto init_crng [[maybe_unused]] = [] { return hydro_init(); }();
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
auto get_random_bytes() {
|
||||
ensure_initialized();
|
||||
std::array<std::byte, N> out;
|
||||
hydro_random_buf(out.data(), N);
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace parselink::proto;
|
||||
session_id::session_id() noexcept : bytes_(get_random_bytes<32>()) {}
|
||||
22
tests/proto/BUILD
Normal file
22
tests/proto/BUILD
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
cc_library(
|
||||
name = "test_deps",
|
||||
srcs = [
|
||||
"test_main.cpp",
|
||||
],
|
||||
deps = [
|
||||
"//source/proto",
|
||||
"@expected",
|
||||
"@fmt",
|
||||
"@magic_enum",
|
||||
"@ut",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "session_id",
|
||||
srcs = [
|
||||
"test_session_id.cpp",
|
||||
],
|
||||
deps = ["test_deps"],
|
||||
)
|
||||
2
tests/proto/test_main.cpp
Normal file
2
tests/proto/test_main.cpp
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
int main(int, char**) {}
|
||||
52
tests/proto/test_session_id.cpp
Normal file
52
tests/proto/test_session_id.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <boost/ut.hpp>
|
||||
#include <parselink/proto/session_id.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace boost::ut;
|
||||
using namespace parselink::proto;
|
||||
|
||||
template <typename... Bytes>
|
||||
constexpr std::array<std::byte, sizeof...(Bytes)> make_bytes(Bytes&&... bytes) {
|
||||
return {std::byte(std::forward<Bytes>(bytes))...};
|
||||
}
|
||||
|
||||
constexpr std::array<std::byte, 32> null_id_bytes = {};
|
||||
|
||||
}
|
||||
|
||||
suite session_id_tests = [] {
|
||||
"test explicitly generated session ids"_test = [] {
|
||||
constexpr session_id sid1(null_id_bytes);
|
||||
constexpr session_id sid2(null_id_bytes);
|
||||
expect(sid1 == sid2);
|
||||
expect(sid1 == null_id_bytes);
|
||||
constexpr auto basic_id = make_bytes(
|
||||
0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f);
|
||||
constexpr session_id sid3(basic_id);
|
||||
constexpr session_id sid4(basic_id);
|
||||
expect(sid3 == sid4);
|
||||
expect(sid3 == basic_id);
|
||||
};
|
||||
|
||||
"test random generated"_test = [] {
|
||||
session_id sid1;
|
||||
session_id sid2;
|
||||
expect(sid1 != null_id_bytes);
|
||||
expect(sid2 != null_id_bytes);
|
||||
expect(sid1 != sid2);
|
||||
};
|
||||
|
||||
"test random generated entropy"_test = [] {
|
||||
constexpr static std::size_t iter_count = 100000;
|
||||
std::set<session_id> sessions;
|
||||
while (sessions.size() < iter_count) {
|
||||
session_id s;
|
||||
expect(!sessions.contains(s));
|
||||
sessions.insert(std::move(s));
|
||||
}
|
||||
};
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user