-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add port unittest and fix off by one problem
- Loading branch information
Showing
3 changed files
with
116 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#include <boost/ut.hpp> | ||
|
||
#include <fmt/format.h> | ||
#include <fmt/ranges.h> | ||
|
||
#include <gnuradio-4.0/Port.hpp> | ||
|
||
template<> | ||
struct fmt::formatter<gr::Tag> { | ||
template<typename ParseContext> | ||
constexpr auto | ||
parse(ParseContext &ctx) { | ||
return ctx.begin(); | ||
} | ||
|
||
template<typename FormatContext> | ||
constexpr auto | ||
format(const gr::Tag &tag, FormatContext &ctx) const { | ||
return fmt::format_to(ctx.out(), " {}->{{ {} }}\n", tag.index, tag.map); | ||
} | ||
}; | ||
|
||
const boost::ut::suite PortTests = [] { | ||
using namespace boost::ut; | ||
using namespace gr; | ||
|
||
"CustomSizePort"_test = [] { | ||
PortOut<int, RequiredSamples<1, 16>, StreamBufferType<CircularBuffer<int, 32>>> out; | ||
expect(out.resizeBuffer(32) == gr::ConnectionResult::SUCCESS); | ||
expect(eq(out.buffer().streamBuffer.size(), static_cast<std::size_t>(getpagesize()))); // 4096 (page-size) is the minimum buffer size | ||
}; | ||
|
||
"InputPort"_test = [] { | ||
PortIn<int> in; | ||
expect(eq(in.buffer().streamBuffer.size(), 65536UZ)); | ||
|
||
auto writer = in.buffer().streamBuffer.new_writer(); | ||
auto tagWriter = in.buffer().tagBuffer.new_writer(); | ||
{ // put testdata into buffer | ||
auto writeSpan = writer.reserve<SpanReleasePolicy::ProcessAll>(5); | ||
auto tagSpan = tagWriter.reserve(3); | ||
tagSpan[0] = {-1, {{"id", "tag@-1"}}}; | ||
tagSpan[1] = {1, {{"id", "tag@101"}}}; | ||
tagSpan[2] = {4, {{"id", "tag@104"}}}; | ||
std::ranges::iota(writeSpan, 100); | ||
tagSpan.publish(3); // this should not be necessary as the ProcessAll policy should publish automatically | ||
writeSpan.publish(5); // this should not be necessary as the ProcessAll policy should publish automatically | ||
} | ||
{ // partial consume | ||
auto data = in.get<SpanReleasePolicy::ProcessAll>(5); | ||
expect(std::ranges::equal(data.tags, std::vector<gr::Tag>{ {-1, {{"id", "tag@-1"}}}, {1, {{"id", "tag@101"}}}, {4, {{"id", "tag@104"}}} })); | ||
expect(std::ranges::equal(data, std::views::iota(100) | std::views::take(5))); | ||
expect(data.consume(2)); | ||
} | ||
{ // full consume | ||
auto data = in.get<SpanReleasePolicy::ProcessAll>(2); | ||
expect(std::ranges::equal(data.tags, std::vector<gr::Tag>{ {1, {{"id", "tag@101"}}}} )); | ||
expect(std::ranges::equal(data, std::views::iota(100) | std::views::drop(2) | std::views::take(2))); | ||
} | ||
{ // get empty range | ||
auto data = in.get<SpanReleasePolicy::ProcessAll>(0); | ||
expect(std::ranges::equal(data.tags, std::vector<gr::Tag>{} )); | ||
expect(std::ranges::equal(data, std::vector<int>())); | ||
} | ||
}; | ||
|
||
"OutputPort"_test = [] { | ||
PortOut<int> out; | ||
auto reader = out.buffer().streamBuffer.new_reader(); | ||
auto tagReader = out.buffer().tagBuffer.new_reader(); | ||
{ | ||
auto data = out.reserve<SpanReleasePolicy::ProcessAll>(5); | ||
out.publishTag({{"id", "tag@-1"}}, -1); | ||
out.publishPendingTags(); | ||
out.publishTag({{"id", "tag@101"}}, 1); | ||
out.publishPendingTags(); | ||
out.publishTag({{"id", "tag@104"}}, 4); | ||
out.publishPendingTags(); | ||
std::ranges::iota(data, 100); | ||
out.publishPendingTags(); | ||
data.publish(5); // should be automatic | ||
} | ||
{ | ||
auto data = reader.get<SpanReleasePolicy::ProcessAll>(); | ||
auto tags = tagReader.get<SpanReleasePolicy::ProcessAll>(); | ||
expect(std::ranges::equal(data, std::views::iota(100) | std::views::take(5))); | ||
// fmt::print("data: {}, tags: {}\n", std::span{data}, std::span{tags}); | ||
expect(std::ranges::equal(tags, std::vector<gr::Tag>{ { -1, {{"id", "tag@-1"}}}, {1, {{"id", "tag@101"}}}, {4, {{"id", "tag@104"}}} })); | ||
} | ||
{ | ||
auto data = out.reserve<SpanReleasePolicy::ProcessAll>(5); | ||
out.publishTag({{"id", "tag@-1"}}, -1); | ||
out.publishPendingTags(); | ||
out.publishTag({{"id", "tag@106"}}, 1); | ||
out.publishPendingTags(); | ||
out.publishTag({{"id", "tag@109"}}, 4); | ||
out.publishPendingTags(); | ||
std::ranges::iota(data, 105); | ||
out.publishPendingTags(); | ||
data.publish(5); // should be automatic | ||
} | ||
{ | ||
auto data = reader.get(); | ||
auto tags = tagReader.get(); | ||
expect(std::ranges::equal(data, std::views::iota(105) | std::views::take(5))); | ||
//fmt::print("data: {}, tags: {}\n", std::span{data}, std::span{tags}); | ||
expect(std::ranges::equal(tags, std::vector<gr::Tag>{ { -1, {{"id", "tag@-1"}}}, {6, {{"id", "tag@106"}}}, {9, {{"id", "tag@109"}}} })); | ||
} | ||
}; | ||
}; | ||
|
||
int | ||
main() { /* tests are statically executed */ | ||
} |