Skip to content

Commit f0b9125

Browse files
committed
Add test for buffered pump
1 parent e579c3b commit f0b9125

File tree

8 files changed

+177
-48
lines changed

8 files changed

+177
-48
lines changed

libio/include/io/core/stateful.hpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#endif // HAS_PRAGMA_ONCE
1919

2020
#include "channels.hpp"
21+
#include "threading.hpp"
2122

2223
namespace io {
2324

@@ -31,7 +32,6 @@ class IO_PUBLIC_SYMBOL pump: public object {
3132
pump() noexcept;
3233
public:
3334
virtual std::size_t pull(std::error_code& ec, uint8_t* const to, std::size_t bytes) noexcept = 0;
34-
virtual bool sync(std::error_code& ec) noexcept;
3535
};
3636

3737
class IO_PUBLIC_SYMBOL channel_pump: public pump {
@@ -51,9 +51,14 @@ class IO_PUBLIC_SYMBOL buffered_channel_pump: public channel_pump {
5151
static s_pump create(std::error_code& ec,const s_read_channel& src, byte_buffer&& buff) noexcept;
5252
static s_pump create(std::error_code& ec,const s_read_channel& src, std::size_t buffer_size) noexcept;
5353
virtual std::size_t pull(std::error_code& ec, uint8_t* const to, std::size_t bytes) noexcept override;
54-
virtual bool sync(std::error_code& ec) noexcept override;
54+
protected:
55+
bool sync(std::error_code& ec) noexcept;
56+
private:
57+
std::size_t get_chunk_size(std::size_t bytes) noexcept;
58+
std::size_t take(uint8_t* const to, std::size_t bytes) noexcept;
5559
protected:
5660
byte_buffer read_buff_;
61+
critical_section mtx_;
5762
};
5863

5964
class funnel;
@@ -84,9 +89,12 @@ class IO_PUBLIC_SYMBOL buffered_channel_funnel: public channel_funnel {
8489
public:
8590
static s_funnel create(std::error_code& ec,const s_write_channel& dst, std::size_t buffer_size) noexcept;
8691
virtual std::size_t push(std::error_code& ec, const uint8_t* src, std::size_t bytes) noexcept override;
87-
virtual void flush(std::error_code& ec) noexcept override;
92+
protected:
93+
void flush(std::error_code& ec) noexcept override;
8894
protected:
8995
byte_buffer write_buff_;
96+
private:
97+
critical_section mtx_;
9098
};
9199

92100
} // namespace io

libio/src/core/memory_channel.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ std::size_t memory_read_channel::read(std::error_code& ec,uint8_t* const buff, s
3838
}
3939
else if (io_likely(!data_.empty())) {
4040
lock_guard lock(mtx_);
41-
std::size_t available = data_.size();
41+
std::size_t available = data_.length();
4242
ret = (available >= bytes) ? bytes : available;
4343
io_memmove(buff, data_.position().get(), ret);
4444
data_.shift(ret);

libio/src/core/stateful.cpp

+27-18
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ pump::pump() noexcept:
1818
object()
1919
{}
2020

21-
bool pump::sync(std::error_code& ec) noexcept
22-
{
23-
return true;
24-
}
25-
2621
// channel_pump
2722
channel_pump::channel_pump(const s_read_channel& src) noexcept:
2823
pump(),
@@ -69,7 +64,8 @@ s_pump buffered_channel_pump::create(std::error_code& ec,const s_read_channel& s
6964

7065
buffered_channel_pump::buffered_channel_pump(const s_read_channel& src,byte_buffer&& buff) noexcept:
7166
channel_pump( src ),
72-
read_buff_( std::forward<byte_buffer>(buff) )
67+
read_buff_( std::forward<byte_buffer>(buff) ),
68+
mtx_()
7369
{}
7470

7571
bool buffered_channel_pump::sync(std::error_code& ec) noexcept
@@ -88,25 +84,36 @@ bool buffered_channel_pump::sync(std::error_code& ec) noexcept
8884
return ret;
8985
}
9086

87+
std::size_t buffered_channel_pump::get_chunk_size(std::size_t bytes) noexcept
88+
{
89+
std::size_t buffered = read_buff_.length();
90+
return bytes > buffered ? buffered : bytes;
91+
}
92+
93+
std::size_t buffered_channel_pump::take(uint8_t* const to, std::size_t bytes) noexcept
94+
{
95+
std::size_t length = read_buff_.length();
96+
std::size_t ret = bytes > length ? length : bytes;
97+
io_memmove(to, read_buff_.position().get(), ret );
98+
read_buff_.shift(ret);
99+
return ret;
100+
}
101+
91102
std::size_t buffered_channel_pump::pull(std::error_code& ec, uint8_t* const to,std::size_t bytes) noexcept
92103
{
104+
lock_guard lock(mtx_);
93105
std::size_t ret = 0;
106+
uint8_t* i = to;
94107
while( (bytes > 0) && !ec) {
95-
std::size_t buffered = read_buff_.length();
96-
if( buffered >= bytes) {
97-
buffered = bytes;
98-
}
99-
else if( 0 == buffered) {
108+
if (0 == read_buff_.length()) {
100109
read_buff_.clear();
101110
if( !sync(ec) )
102111
break;
103-
else
104-
buffered = read_buff_.length();
105112
}
106-
io_memmove(to, read_buff_.position().get(), buffered );
107-
read_buff_.shift(buffered);
108-
ret += bytes;
109-
bytes -= buffered;
113+
std::size_t taken = take(i, get_chunk_size(bytes));
114+
i += taken;
115+
ret += taken;
116+
bytes -= taken;
110117
}
111118
return ret;
112119
}
@@ -159,7 +166,8 @@ s_funnel buffered_channel_funnel::create(std::error_code& ec,const s_write_chann
159166

160167
buffered_channel_funnel::buffered_channel_funnel(const s_write_channel& dst, byte_buffer&& buff) noexcept:
161168
channel_funnel(dst),
162-
write_buff_(std::forward<byte_buffer>(buff))
169+
write_buff_(std::forward<byte_buffer>(buff)),
170+
mtx_()
163171
{}
164172

165173

@@ -176,6 +184,7 @@ void buffered_channel_funnel::flush(std::error_code& ec) noexcept
176184

177185
std::size_t buffered_channel_funnel::push(std::error_code& ec, const uint8_t* src, std::size_t bytes) noexcept
178186
{
187+
lock_guard lock(mtx_);
179188
std::size_t ret = 0;
180189
const uint8_t* px = src;
181190
while( !ec && (bytes > 0) ) {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#include "stdafx.hpp"
2-
#include "memory_reead_channel_fixture.hpp"
2+
#include "memory_channel_test.hpp"
33

4-
const char* memory_read_channel_fixture::TEST_DATA = "Test message";
4+
const char* memory_read_channel_fixture::TEST_DATA = "0123456789ABCDEF";
55

6+
// memory_read_channel_fixture
67
memory_read_channel_fixture::memory_read_channel_fixture():
78
::testing::Test(),
89
rch_(),
@@ -11,26 +12,11 @@ memory_read_channel_fixture::memory_read_channel_fixture():
1112

1213
void memory_read_channel_fixture::SetUp()
1314
{
14-
io::byte_buffer buff = io::byte_buffer::wrap(ec_, TEST_DATA);
15+
io::byte_buffer buff = io::byte_buffer::wrap(ec_, TEST_DATA, 16);
1516
EXPECT_FALSE(ec_);
1617
rch_ = io::memory_read_channel::open(ec_, std::move(buff));
1718
}
1819

19-
20-
// Test case for memory_read_channel::open
21-
TEST_F(memory_read_channel_fixture, should_open_from_memory_block) {
22-
EXPECT_FALSE(ec_);
23-
EXPECT_TRUE(rch_);
24-
}
25-
26-
// Test case for memory_read_channel::read
27-
TEST_F(memory_read_channel_fixture, should_read_from_memory_block) {
28-
uint8_t buffer[20];
29-
std::size_t bytes_read = rch_->read(ec_, buffer, sizeof(buffer));
30-
EXPECT_FALSE(ec_);
31-
EXPECT_GT(bytes_read, 0);
32-
}
33-
3420
// memory_write_channel_fixture
3521
memory_write_channel_fixture::memory_write_channel_fixture():
3622
::testing::Test(),
@@ -43,20 +29,50 @@ void memory_write_channel_fixture::SetUp()
4329
wch_ = io::memory_write_channel::open(ec_);
4430
}
4531

46-
// Test case for memory_write_channel::open
47-
TEST_F(memory_write_channel_fixture, should_open_to_memory_block) {
32+
// Tests
33+
34+
TEST_F(memory_read_channel_fixture, should_open_from_memory_block)
35+
{
36+
EXPECT_FALSE(ec_);
37+
EXPECT_TRUE(rch_);
38+
}
39+
40+
TEST_F(memory_read_channel_fixture, should_read_from_memory_block)
41+
{
42+
uint8_t buffer[9] = {0};
43+
std::size_t actual = rch_->read(ec_, buffer, 8);
44+
EXPECT_FALSE(ec_);
45+
ASSERT_EQ(actual,8);
46+
ASSERT_STREQ("01234567",reinterpret_cast<char*>(&buffer[0]));
47+
}
48+
49+
TEST_F(memory_read_channel_fixture, should_return_0_when_eof)
50+
{
51+
uint8_t buffer[9] = {0};
52+
std::size_t actual = rch_->read(ec_, buffer, 8);
53+
EXPECT_FALSE(ec_);
54+
ASSERT_EQ(actual,8);
55+
ASSERT_STREQ("01234567",reinterpret_cast<char*>(&buffer[0]));
56+
actual = rch_->read(ec_, buffer, 8);
57+
ASSERT_EQ(actual,8);
58+
ASSERT_STREQ("89ABCDEF",reinterpret_cast<char*>(&buffer[0]));
59+
actual = rch_->read(ec_, buffer, 8);
60+
ASSERT_EQ(actual,0);
61+
}
62+
63+
TEST_F(memory_write_channel_fixture, should_open_to_memory_block)
64+
{
4865
EXPECT_TRUE(wch_);
4966
EXPECT_FALSE(ec_);
5067
}
5168

52-
// Test case for memory_write_channel::should_wirite_into_memory
53-
TEST_F(memory_write_channel_fixture, should_write_into_memory_block) {
69+
TEST_F(memory_write_channel_fixture, should_write_into_memory_block)
70+
{
5471
const char* message = "Test message";
5572
wch_->write(ec_, reinterpret_cast<const uint8_t*>(message), io_strlen(message));
5673
EXPECT_FALSE(ec_);
57-
5874
io::byte_buffer written = wch_->data(ec_);
5975
EXPECT_FALSE(ec_);
6076
EXPECT_EQ(written.length(), io_strlen(message));
61-
EXPECT_EQ(io_memcmp(written.position().cdata(), message, io_strlen(message)), 0);
77+
ASSERT_STREQ(message, written.position().cdata());
6278
}

test/memory_reead_channel_fixture.hpp renamed to test/memory_channel_test.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
#ifndef __MEMORY_REEAD_CHANNEL_FIXTURE_HPP_INCLUDED__
2-
#define __MEMORY_REEAD_CHANNEL_FIXTURE_HPP_INCLUDED__
1+
#ifndef __MEMORY_REEAD_CHANNEL_TEST_HPP_INCLUDED__
2+
#define __MEMORY_REEAD_CHANNEL_TEST_HPP_INCLUDED__
33

4+
#include <io/config/libio_config.hpp>
45

56
#ifdef HAS_PRAGMA_ONCE
67
#pragma once

test/statefull_test.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "stdafx.hpp"
2+
#include "statefull_test.hpp"
3+
4+
const char* stateful_test_fixture::TEST_DATA = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
5+
6+
const std::size_t stateful_test_fixture::BUFF_SIZE = 1024;
7+
8+
stateful_test_fixture::stateful_test_fixture():
9+
::testing::Test(),
10+
rch_(),
11+
wch_(),
12+
ec_()
13+
{
14+
}
15+
16+
void stateful_test_fixture::SetUp() {
17+
io::byte_buffer read_buff = io::byte_buffer::wrap(ec_, TEST_DATA, io_strlen(TEST_DATA));
18+
rch_ = io::memory_read_channel::open(ec_, std::move(read_buff) );
19+
EXPECT_FALSE(ec_);
20+
wch_ = io::memory_write_channel::open(ec_, BUFF_SIZE);
21+
EXPECT_FALSE(ec_);
22+
}
23+
24+
25+
TEST_F(stateful_test_fixture, should_synch_when_buffer_underflow) {
26+
auto tmp_buff = io::byte_buffer::allocate(ec_,16);
27+
EXPECT_FALSE(ec_);
28+
auto instance = io::buffered_channel_pump::create(ec_, rch_, std::move(tmp_buff) );
29+
EXPECT_FALSE(ec_);
30+
uint8_t data[33] = {0};
31+
std::size_t read = instance->pull(ec_, data, 32);
32+
ASSERT_STRCASEEQ("Lorem ipsum dolor sit amet, cons",reinterpret_cast<char*>(&data[0]));
33+
ASSERT_EQ(32, read);
34+
EXPECT_FALSE(ec_);
35+
}
36+
37+
TEST_F(stateful_test_fixture, should_return_zerro_when_input_data_over) {
38+
auto tmp_buff = io::byte_buffer::allocate(ec_,64);
39+
EXPECT_FALSE(ec_);
40+
auto instance = io::buffered_channel_pump::create(ec_, rch_, std::move(tmp_buff) );
41+
EXPECT_FALSE(ec_);
42+
uint8_t data[124] = {0};
43+
std::size_t read = instance->pull(ec_, data, 123);
44+
ASSERT_STRCASEEQ(TEST_DATA,reinterpret_cast<char*>(&data[0]));
45+
ASSERT_EQ(123, read);
46+
EXPECT_FALSE(ec_);
47+
read = instance->pull(ec_, data, 124);
48+
ASSERT_EQ(0, read);
49+
}
50+
51+
TEST_F(stateful_test_fixture, should_sync_buffered_channel_pump) {
52+
//auto test_pump = buffered_channel_pump::create(ec, read_channel, byte_buffer(20));
53+
//EXPECT_TRUE(test_pump->sync(ec_));
54+
}
55+

test/statefull_test.hpp

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef __IO_STATEFULL_TEST_HPP_INCLUDED__
2+
#define __IO_STATEFULL_TEST_HPP_INCLUDED__
3+
4+
#include <io/config/libio_config.hpp>
5+
6+
#ifdef HAS_PRAGMA_ONCE
7+
#pragma once
8+
#endif // HAS_PRAGMA_ONCE
9+
10+
#include <gtest/gtest.h>
11+
#include <gtest/gtest-matchers.h>
12+
13+
#include <system_error>
14+
15+
#include <io/core/stateful.hpp>
16+
#include <io/core/memory_channel.hpp>
17+
18+
class stateful_test_fixture : public ::testing::Test {
19+
public:
20+
static const char* TEST_DATA;
21+
static const std::size_t BUFF_SIZE;
22+
public:
23+
stateful_test_fixture();
24+
void SetUp() override;
25+
protected:
26+
io::s_read_channel rch_;
27+
io::s_memory_write_channel wch_;
28+
std::error_code ec_;
29+
};
30+
31+
#endif // __IO_STATEFULL_TEST_HPP_INCLUDED__

test/test.cbp

+9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<Add option="-D_UNICODE" />
2323
<Add option="-DUNICODE" />
2424
<Add directory="include/win" />
25+
<Add directory="./" />
2526
</Compiler>
2627
<Linker>
2728
<Add library="io" />
@@ -46,6 +47,7 @@
4647
<Add option="-D_WIN32_WINNT=0x0A00" />
4748
<Add option="-D_UNICODE" />
4849
<Add option="-DUNICODE" />
50+
<Add directory="./" />
4951
</Compiler>
5052
<Linker>
5153
<Add option="-O3" />
@@ -70,6 +72,7 @@
7072
<Add option="-D_WIN32_WINNT=0x0A00" />
7173
<Add option="-D_UNICODE" />
7274
<Add option="-DUNICODE" />
75+
<Add directory="./" />
7376
</Compiler>
7477
<Linker>
7578
<Add library="io" />
@@ -93,6 +96,7 @@
9396
<Add option="-D_WIN32_WINNT=0x0A00" />
9497
<Add option="-D_UNICODE" />
9598
<Add option="-DUNICODE" />
99+
<Add directory="./" />
96100
</Compiler>
97101
<Linker>
98102
<Add option="-s" />
@@ -115,6 +119,7 @@
115119
<Add option="-std=gnu++23" />
116120
<Add option="-fexceptions" />
117121
<Add option="`pkg-config --cflags gtest gnutls`" />
122+
<Add directory="./" />
118123
</Compiler>
119124
<Linker>
120125
<Add option="`pkg-config --libs gtest gnutls`" />
@@ -137,6 +142,10 @@
137142
<Unit filename="fixtures.hpp" />
138143
<Unit filename="hash_test.cpp" />
139144
<Unit filename="main.cpp" />
145+
<Unit filename="memory_channel_test.cpp" />
146+
<Unit filename="memory_channel_test.hpp" />
147+
<Unit filename="statefull_test.cpp" />
148+
<Unit filename="statefull_test.hpp" />
140149
<Unit filename="stdafx.cpp" />
141150
<Unit filename="stdafx.hpp">
142151
<Option compile="1" />

0 commit comments

Comments
 (0)