More session id work
This commit is contained in:
parent
1ceccd0720
commit
578065be47
@ -27,20 +27,42 @@ namespace parselink {
|
|||||||
namespace proto {
|
namespace proto {
|
||||||
|
|
||||||
struct session_id {
|
struct session_id {
|
||||||
std::array<std::byte, 32> bytes;
|
public:
|
||||||
session_id() noexcept;
|
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<=>(
|
[[nodiscard]] constexpr auto operator<=>(
|
||||||
session_id const& other) const noexcept {
|
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<=>(
|
[[nodiscard]] constexpr auto operator<=>(
|
||||||
std::span<std::byte const> other) const noexcept {
|
std::span<std::byte const> other) const noexcept {
|
||||||
return std::lexicographical_compare_three_way(bytes.begin(),
|
return std::lexicographical_compare_three_way(bytes_.begin(),
|
||||||
bytes.end(), other.begin(), other.end(),
|
bytes_.end(), other.begin(), other.end(),
|
||||||
std::compare_three_way());
|
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
|
} // namespace proto
|
||||||
|
|||||||
@ -4,6 +4,7 @@ cc_library(
|
|||||||
name = "proto",
|
name = "proto",
|
||||||
srcs = [
|
srcs = [
|
||||||
"session.cpp",
|
"session.cpp",
|
||||||
|
"session_id.cpp",
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
"//include/parselink:proto",
|
"//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