Index: src/libchcore/TOverlappedDataBuffer.cpp =================================================================== diff -u -refe016ef1d0cb0cf1ba379dbe3693e35f6a2361e -radf2d680643ef85665b042e03fed274ab8f11180 --- src/libchcore/TOverlappedDataBuffer.cpp (.../TOverlappedDataBuffer.cpp) (revision efe016ef1d0cb0cf1ba379dbe3693e35f6a2361e) +++ src/libchcore/TOverlappedDataBuffer.cpp (.../TOverlappedDataBuffer.cpp) (revision adf2d680643ef85665b042e03fed274ab8f11180) @@ -94,7 +94,7 @@ void TOverlappedDataBuffer::ReinitializeBuffer(size_t stNewBufferSize) { - if (stNewBufferSize > m_stBufferSize) + if (stNewBufferSize != m_stBufferSize) { ReleaseBuffer(); Index: src/libchcore/TOverlappedDataBufferQueue.cpp =================================================================== diff -u -re4005a958c9412d890eeff1e8087c8298aa7bcf7 -radf2d680643ef85665b042e03fed274ab8f11180 --- src/libchcore/TOverlappedDataBufferQueue.cpp (.../TOverlappedDataBufferQueue.cpp) (revision e4005a958c9412d890eeff1e8087c8298aa7bcf7) +++ src/libchcore/TOverlappedDataBufferQueue.cpp (.../TOverlappedDataBufferQueue.cpp) (revision adf2d680643ef85665b042e03fed274ab8f11180) @@ -36,8 +36,6 @@ m_eventWritePossible(true, false), m_eventWriteFinished(true, false), m_eventAllBuffersAccountedFor(true, true), - m_stBufferSize(0), - m_ullNextExpectedWritePosition(0), m_bDataSourceFinished(false), m_bDataWritingFinished(false), m_ullNextReadBufferOrder(0), @@ -51,8 +49,6 @@ m_eventWritePossible(true, false), m_eventWriteFinished(true, false), m_eventAllBuffersAccountedFor(true, false), - m_stBufferSize(0), - m_ullNextExpectedWritePosition(0), m_bDataSourceFinished(false), m_bDataWritingFinished(false), m_ullNextReadBufferOrder(0), @@ -111,8 +107,11 @@ return nullptr; m_setFullBuffers.erase(m_setFullBuffers.begin()); - m_ullNextExpectedWritePosition += pBuffer->GetBytesTransferred(); + // if this is the last part - mark that writing is finished, so that no other buffer will be written + if (pBuffer->IsLastPart()) + m_bDataWritingFinished = true; + ++m_ullNextWriteBufferOrder; UpdateWritePossibleEvent(); @@ -129,14 +128,6 @@ if (!pBuffer) THROW_CORE_EXCEPTION(eErr_InvalidPointer); - // special case - if we already know that there was an end of file and the new packet arrived with the same information and no data - // then it can be treated as an empty buffer - if (pBuffer->IsLastPart() && m_bDataSourceFinished && pBuffer->GetBytesTransferred() == 0) - { - AddEmptyBuffer(pBuffer); - return; - } - std::pair pairInsertInfo = m_setFullBuffers.insert(pBuffer); if (!pairInsertInfo.second) THROW_CORE_EXCEPTION(eErr_InvalidOverlappedPosition); @@ -174,10 +165,6 @@ ++m_ullNextFinishedBufferOrder; - // if this is the last part - mark that writing is finished, so that no other buffer will be written - if (pBuffer->IsLastPart()) - m_bDataWritingFinished = true; - UpdateWriteFinishedEvent(); m_eventAllBuffersAccountedFor.ResetEvent(); @@ -228,25 +215,25 @@ // sanity check - if any of the buffers are still in use, we can't change the sizes if (m_listAllBuffers.size() != m_listEmptyBuffers.size()) THROW_CORE_EXCEPTION(eErr_InternalProblem); + if (stBufferSize == 0) + THROW_CORE_EXCEPTION(eErr_InvalidArgument); - if (stBufferSize > m_stBufferSize) + if (stBufferSize != GetSingleBufferSize()) { // buffer sizes increased - clear current buffers and proceed with creating new ones m_listAllBuffers.clear(); m_listEmptyBuffers.clear(); - m_setFullBuffers.clear(); } else if (stCount == m_listAllBuffers.size()) return; // nothing really changed - else if (stCount < m_listAllBuffers.size()) - stCount = m_listAllBuffers.size() - stCount; // allocate only the missing buffers else if (stCount > m_listAllBuffers.size()) + stCount -= m_listAllBuffers.size(); // allocate only the missing buffers + else if (stCount < m_listAllBuffers.size()) { // there are too many buffers - reduce m_listEmptyBuffers.clear(); - m_setFullBuffers.clear(); - size_t stCountToRemove = stCount - m_listAllBuffers.size(); + size_t stCountToRemove = m_listAllBuffers.size() - stCount; m_listAllBuffers.erase(m_listAllBuffers.begin(), m_listAllBuffers.begin() + stCountToRemove); for (const auto& upElement : m_listAllBuffers) @@ -267,11 +254,23 @@ m_listAllBuffers.push_back(std::move(upBuffer)); } - m_stBufferSize = stCount; UpdateReadPossibleEvent(); UpdateAllBuffersAccountedFor(); } +size_t TOverlappedDataBufferQueue::GetTotalBufferCount() const +{ + return m_listAllBuffers.size(); +} + +size_t TOverlappedDataBufferQueue::GetSingleBufferSize() const +{ + if (m_listAllBuffers.empty()) + return 0; + + return (*m_listAllBuffers.begin())->GetBufferSize(); +} + void TOverlappedDataBufferQueue::DataSourceChanged() { CleanupBuffers(); Index: src/libchcore/TOverlappedDataBufferQueue.h =================================================================== diff -u -re4005a958c9412d890eeff1e8087c8298aa7bcf7 -radf2d680643ef85665b042e03fed274ab8f11180 --- src/libchcore/TOverlappedDataBufferQueue.h (.../TOverlappedDataBufferQueue.h) (revision e4005a958c9412d890eeff1e8087c8298aa7bcf7) +++ src/libchcore/TOverlappedDataBufferQueue.h (.../TOverlappedDataBufferQueue.h) (revision adf2d680643ef85665b042e03fed274ab8f11180) @@ -41,6 +41,8 @@ ~TOverlappedDataBufferQueue(); void ReinitializeBuffers(size_t stCount, size_t stBufferSize); + size_t GetTotalBufferCount() const; + size_t GetSingleBufferSize() const; // buffer management virtual void AddEmptyBuffer(TOverlappedDataBuffer* pBuffer) override; @@ -55,6 +57,10 @@ // data source change void DataSourceChanged(); + // processing info + bool IsDataSourceFinished() const { return m_bDataSourceFinished; } + bool IsDataWritingFinished() const { return m_bDataWritingFinished; } + // event access HANDLE GetEventReadPossibleHandle() const { return m_eventReadPossible.Handle(); } HANDLE GetEventWritePossibleHandle() const { return m_eventWritePossible.Handle(); } @@ -72,7 +78,6 @@ private: std::deque> m_listAllBuffers; - size_t m_stBufferSize; std::list m_listEmptyBuffers; @@ -85,7 +90,6 @@ bool m_bDataSourceFinished; // input file was already read to the end bool m_bDataWritingFinished; // output file was already written to the end - unsigned long long m_ullNextExpectedWritePosition; // current write file pointer unsigned long long m_ullNextReadBufferOrder; // next order id for read buffers unsigned long long m_ullNextWriteBufferOrder; // next order id to be processed when writing unsigned long long m_ullNextFinishedBufferOrder; // next order id to be processed when finishing writing Index: src/libchcore/Tests/TOverlappedDataBufferQueueTests.cpp =================================================================== diff -u -re4005a958c9412d890eeff1e8087c8298aa7bcf7 -radf2d680643ef85665b042e03fed274ab8f11180 --- src/libchcore/Tests/TOverlappedDataBufferQueueTests.cpp (.../TOverlappedDataBufferQueueTests.cpp) (revision e4005a958c9412d890eeff1e8087c8298aa7bcf7) +++ src/libchcore/Tests/TOverlappedDataBufferQueueTests.cpp (.../TOverlappedDataBufferQueueTests.cpp) (revision adf2d680643ef85665b042e03fed274ab8f11180) @@ -3,6 +3,7 @@ #include "gmock/gmock.h" #include "../TOverlappedDataBufferQueue.h" #include "../TOverlappedDataBuffer.h" +#include "../TCoreException.h" using namespace chcore; @@ -31,14 +32,15 @@ EXPECT_NE(nullptr, queue.GetEventWritePossibleHandle()); EXPECT_NE(nullptr, queue.GetEventWriteFinishedHandle()); - DWORD dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); + EXPECT_TIMEOUT(queue.GetEventReadPossibleHandle()); + EXPECT_TIMEOUT(queue.GetEventWritePossibleHandle()); + EXPECT_TIMEOUT(queue.GetEventWriteFinishedHandle()); - dwResult = WaitForSingleObject(queue.GetEventWritePossibleHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); + EXPECT_FALSE(queue.IsDataSourceFinished()); + EXPECT_FALSE(queue.IsDataWritingFinished()); - dwResult = WaitForSingleObject(queue.GetEventWriteFinishedHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); + EXPECT_EQ(0, queue.GetTotalBufferCount()); + EXPECT_EQ(0, queue.GetSingleBufferSize()); } TEST(TOverlappedDataBufferQueueTests, AllocatingConstructor_SanityTest) @@ -53,35 +55,136 @@ EXPECT_NE(nullptr, queue.GetEventWritePossibleHandle()); EXPECT_NE(nullptr, queue.GetEventWriteFinishedHandle()); - DWORD dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); + EXPECT_SIGNALED(queue.GetEventReadPossibleHandle()); + EXPECT_TIMEOUT(queue.GetEventWritePossibleHandle()); + EXPECT_TIMEOUT(queue.GetEventWriteFinishedHandle()); - dwResult = WaitForSingleObject(queue.GetEventWritePossibleHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); + EXPECT_FALSE(queue.IsDataSourceFinished()); + EXPECT_FALSE(queue.IsDataWritingFinished()); +} - dwResult = WaitForSingleObject(queue.GetEventWriteFinishedHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); +TEST(TOverlappedDataBufferQueueTests, AllocatingConstructor_CheckBufferSizes) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + EXPECT_EQ(3, queue.GetTotalBufferCount()); + EXPECT_EQ(32768, queue.GetSingleBufferSize()); + + EXPECT_EQ(32768, pBuffers[0]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[1]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[2]->GetBufferSize()); } /////////////////////////////////////////////////////////////////////////////////////////////////// +TEST(TOverlappedDataBufferQueueTests, ReinitializeBuffer_FailsWithBuffersInUse) +{ + TOverlappedDataBufferQueue queue(3, 32768); + + queue.GetEmptyBuffer(); + + EXPECT_THROW(queue.ReinitializeBuffers(3, 65536), TCoreException); +} + +TEST(TOverlappedDataBufferQueueTests, ReinitializeBuffer_ZeroLengthBuffers) +{ + TOverlappedDataBufferQueue queue(3, 32768); + + EXPECT_THROW(queue.ReinitializeBuffers(3, 0), TCoreException); +} + +TEST(TOverlappedDataBufferQueueTests, ReinitializeBuffer_SameSizeSameCount) +{ + TOverlappedDataBufferQueue queue(3, 32768); + queue.ReinitializeBuffers(3, 32768); + + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + EXPECT_EQ(3, queue.GetTotalBufferCount()); + EXPECT_EQ(32768, queue.GetSingleBufferSize()); + + EXPECT_EQ(32768, pBuffers[0]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[1]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[2]->GetBufferSize()); +} + +TEST(TOverlappedDataBufferQueueTests, ReinitializeBuffer_IncreaseSize) +{ + TOverlappedDataBufferQueue queue(3, 32768); + queue.ReinitializeBuffers(3, 65536); + + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + EXPECT_EQ(3, queue.GetTotalBufferCount()); + EXPECT_EQ(65536, queue.GetSingleBufferSize()); + + EXPECT_EQ(65536, pBuffers[0]->GetBufferSize()); + EXPECT_EQ(65536, pBuffers[1]->GetBufferSize()); + EXPECT_EQ(65536, pBuffers[2]->GetBufferSize()); +} + +TEST(TOverlappedDataBufferQueueTests, ReinitializeBuffer_DecreaseSize) +{ + TOverlappedDataBufferQueue queue(3, 65536); + queue.ReinitializeBuffers(3, 32768); + + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + EXPECT_EQ(3, queue.GetTotalBufferCount()); + EXPECT_EQ(32768, queue.GetSingleBufferSize()); + + EXPECT_EQ(32768, pBuffers[0]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[1]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[2]->GetBufferSize()); +} + +TEST(TOverlappedDataBufferQueueTests, ReinitializeBuffer_IncreaseCount) +{ + TOverlappedDataBufferQueue queue(3, 32768); + queue.ReinitializeBuffers(5, 32768); + + EXPECT_EQ(5, queue.GetTotalBufferCount()); + EXPECT_EQ(32768, queue.GetSingleBufferSize()); + + TOverlappedDataBuffer* pBuffers[5] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + EXPECT_EQ(32768, pBuffers[0]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[1]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[2]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[3]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[4]->GetBufferSize()); +} + +TEST(TOverlappedDataBufferQueueTests, ReinitializeBuffer_DecreaseCount) +{ + TOverlappedDataBufferQueue queue(5, 32768); + queue.ReinitializeBuffers(3, 32768); + + EXPECT_EQ(3, queue.GetTotalBufferCount()); + EXPECT_EQ(32768, queue.GetSingleBufferSize()); + + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + EXPECT_EQ(32768, pBuffers[0]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[1]->GetBufferSize()); + EXPECT_EQ(32768, pBuffers[2]->GetBufferSize()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// TEST(TOverlappedDataBufferQueueTests, GetEmptyBuffer) { TOverlappedDataBufferQueue queue(3, 32768); - DWORD dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); + EXPECT_SIGNALED(queue.GetEventReadPossibleHandle()); EXPECT_NE(nullptr, queue.GetEmptyBuffer()); - dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); + EXPECT_SIGNALED(queue.GetEventReadPossibleHandle()); EXPECT_NE(nullptr, queue.GetEmptyBuffer()); - dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); + EXPECT_SIGNALED(queue.GetEventReadPossibleHandle()); EXPECT_NE(nullptr, queue.GetEmptyBuffer()); - dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); + EXPECT_TIMEOUT(queue.GetEventReadPossibleHandle()); EXPECT_EQ(nullptr, queue.GetEmptyBuffer()); } @@ -92,40 +195,106 @@ TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; - DWORD dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); + EXPECT_TIMEOUT(queue.GetEventReadPossibleHandle()); queue.AddEmptyBuffer(pBuffers[0]); - dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); + EXPECT_SIGNALED(queue.GetEventReadPossibleHandle()); queue.AddEmptyBuffer(pBuffers[1]); - dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); + EXPECT_SIGNALED(queue.GetEventReadPossibleHandle()); queue.AddEmptyBuffer(pBuffers[2]); - dwResult = WaitForSingleObject(queue.GetEventReadPossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); + EXPECT_SIGNALED(queue.GetEventReadPossibleHandle()); } +TEST(TOverlappedDataBufferQueueTests, AddEmptyBuffer_Null) +{ + TOverlappedDataBufferQueue queue(3, 32768); + + EXPECT_THROW(queue.AddEmptyBuffer(nullptr), TCoreException); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(TOverlappedDataBufferQueueTests, GetFullBuffer_AddFullBuffer) +TEST(TOverlappedDataBufferQueueTests, AddFullBuffer_GetFullBuffer) { TOverlappedDataBufferQueue queue(3, 32768); TOverlappedDataBuffer* pBuffer = queue.GetEmptyBuffer(); + queue.AddFullBuffer(pBuffer); + EXPECT_SIGNALED(queue.GetEventWritePossibleHandle()); + + pBuffer = queue.GetFullBuffer(); + EXPECT_TIMEOUT(queue.GetEventWritePossibleHandle()); +} + +TEST(TOverlappedDataBufferQueueTests, GetFullBuffer_WrongOrder) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + queue.AddFullBuffer(pBuffers[1]); + EXPECT_EQ(nullptr, queue.GetFullBuffer()); + + queue.AddFullBuffer(pBuffers[2]); + EXPECT_EQ(nullptr, queue.GetFullBuffer()); + + queue.AddFullBuffer(pBuffers[0]); + EXPECT_NE(nullptr, queue.GetFullBuffer()); +} + +TEST(TOverlappedDataBufferQueueTests, AddFullBuffer_HandlingSrcEof) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + pBuffers[1]->SetLastPart(true); + + queue.AddFullBuffer(pBuffers[0]); + EXPECT_FALSE(queue.IsDataSourceFinished()); + + queue.AddFullBuffer(pBuffers[1]); + EXPECT_TRUE(queue.IsDataSourceFinished()); +} + +TEST(TOverlappedDataBufferQueueTests, AddFullBuffer_HandlingDstEof) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + pBuffers[2]->SetLastPart(true); + + queue.AddFullBuffer(pBuffers[0]); + queue.AddFullBuffer(pBuffers[1]); + queue.AddFullBuffer(pBuffers[2]); + + TOverlappedDataBuffer* pBuffer = queue.GetFullBuffer(); + EXPECT_FALSE(queue.IsDataWritingFinished()); + pBuffer = queue.GetFullBuffer(); + EXPECT_FALSE(queue.IsDataWritingFinished()); + + // getting the last buffer (marked as eof) causes setting the data-writing-finished flag + pBuffer = queue.GetFullBuffer(); + EXPECT_TRUE(queue.IsDataWritingFinished()); +} + +TEST(TOverlappedDataBufferQueueTests, AddFullBuffer_Null) +{ + TOverlappedDataBufferQueue queue(3, 32768); + + EXPECT_THROW(queue.AddFullBuffer(nullptr), TCoreException); +} + +TEST(TOverlappedDataBufferQueueTests, AddFullBuffer_SameBufferTwice) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffer = queue.GetEmptyBuffer(); + pBuffer->InitForRead(0, 1280); pBuffer->SetBytesTransferred(1230); pBuffer->SetStatusCode(0); queue.AddFullBuffer(pBuffer); - DWORD dwResult = WaitForSingleObject(queue.GetEventWritePossibleHandle(), 0); - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); - - pBuffer = queue.GetFullBuffer(); - - dwResult = WaitForSingleObject(queue.GetEventWritePossibleHandle(), 0); - EXPECT_EQ(WAIT_TIMEOUT, dwResult); + EXPECT_THROW(queue.AddFullBuffer(pBuffer), TCoreException); } TEST(TOverlappedDataBufferQueueTests, GetFullBuffer_AddFullBuffer_OutOfOrder) @@ -159,7 +328,7 @@ } /////////////////////////////////////////////////////////////////////////////////////////////////// -TEST(TOverlappedDataBufferQueueTests, GetFinishedBuffer_AddFinishedBuffer_OutOfOrder) +TEST(TOverlappedDataBufferQueueTests, AddFinishedBuffer_OutOfOrder_Signals) { TOverlappedDataBufferQueue queue(3, 32768); TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; @@ -184,3 +353,104 @@ queue.AddFinishedBuffer(pBuffers[0]); EXPECT_SIGNALED(queue.GetEventWriteFinishedHandle()); } + +TEST(TOverlappedDataBufferQueueTests, GetFinishedBuffer_Signals) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + pBuffers[0]->InitForRead(0, 1000); + pBuffers[0]->SetBytesTransferred(1000); + pBuffers[0]->SetStatusCode(0); + + pBuffers[1]->InitForRead(0, 1200); + pBuffers[1]->SetBytesTransferred(1200); + pBuffers[1]->SetStatusCode(0); + + pBuffers[2]->InitForRead(0, 1400); + pBuffers[2]->SetBytesTransferred(800); + pBuffers[2]->SetStatusCode(0); + pBuffers[2]->SetLastPart(true); + + queue.AddFinishedBuffer(pBuffers[1]); + queue.AddFinishedBuffer(pBuffers[2]); + queue.AddFinishedBuffer(pBuffers[0]); + + queue.GetFinishedBuffer(); + EXPECT_SIGNALED(queue.GetEventWriteFinishedHandle()); + queue.GetFinishedBuffer(); + EXPECT_SIGNALED(queue.GetEventWriteFinishedHandle()); + queue.GetFinishedBuffer(); + EXPECT_TIMEOUT(queue.GetEventWriteFinishedHandle()); +} + +TEST(TOverlappedDataBufferQueueTests, GetFinishedBuffer_WrongOrder) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + pBuffers[0]->InitForRead(0, 1000); + pBuffers[0]->SetBytesTransferred(1000); + pBuffers[0]->SetStatusCode(0); + + pBuffers[1]->InitForRead(0, 1200); + pBuffers[1]->SetBytesTransferred(1200); + pBuffers[1]->SetStatusCode(0); + + pBuffers[2]->InitForRead(0, 1400); + pBuffers[2]->SetBytesTransferred(800); + pBuffers[2]->SetStatusCode(0); + pBuffers[2]->SetLastPart(true); + + queue.AddFinishedBuffer(pBuffers[1]); + EXPECT_EQ(nullptr, queue.GetFinishedBuffer()); + + queue.AddFinishedBuffer(pBuffers[2]); + EXPECT_EQ(nullptr, queue.GetFinishedBuffer()); + + queue.AddFinishedBuffer(pBuffers[0]); + EXPECT_NE(nullptr, queue.GetFinishedBuffer()); +} + +TEST(TOverlappedDataBufferQueueTests, AddFinishedBuffer_Null) +{ + TOverlappedDataBufferQueue queue(3, 32768); + + EXPECT_THROW(queue.AddFinishedBuffer(nullptr), TCoreException); +} + +TEST(TOverlappedDataBufferQueueTests, AddFinishedBuffer_SameBufferTwice) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffer = queue.GetEmptyBuffer(); + queue.AddFinishedBuffer(pBuffer); + EXPECT_THROW(queue.AddFinishedBuffer(pBuffer), TCoreException); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +TEST(TOverlappedDataBufferQueueTests, DataSourceChanged_CleanupBuffers) +{ + TOverlappedDataBufferQueue queue(3, 32768); + TOverlappedDataBuffer* pBuffers[3] = { queue.GetEmptyBuffer(), queue.GetEmptyBuffer(), queue.GetEmptyBuffer() }; + + pBuffers[0]->SetLastPart(true); + pBuffers[1]->SetLastPart(true); + pBuffers[2]->SetLastPart(true); + + queue.AddFullBuffer(pBuffers[1]); + queue.AddFullBuffer(pBuffers[2]); + queue.AddFullBuffer(pBuffers[0]); + + // this tests if the buffers are properly cleaned up - if they're not, DataSourceChanged() throws an exception + EXPECT_NO_THROW(queue.DataSourceChanged()); +} + +TEST(TOverlappedDataBufferQueueTests, DataSourceChanged_InvalidBufferCount) +{ + TOverlappedDataBufferQueue queue(3, 32768); + + queue.GetEmptyBuffer(); + + // this tests if the buffers are properly cleaned up - if they're not, DataSourceChanged() throws an exception + EXPECT_THROW(queue.DataSourceChanged(), TCoreException); +} Index: src/libchcore/Tests/TOverlappedDataBufferTests.cpp =================================================================== diff -u -refe016ef1d0cb0cf1ba379dbe3693e35f6a2361e -radf2d680643ef85665b042e03fed274ab8f11180 --- src/libchcore/Tests/TOverlappedDataBufferTests.cpp (.../TOverlappedDataBufferTests.cpp) (revision efe016ef1d0cb0cf1ba379dbe3693e35f6a2361e) +++ src/libchcore/Tests/TOverlappedDataBufferTests.cpp (.../TOverlappedDataBufferTests.cpp) (revision adf2d680643ef85665b042e03fed274ab8f11180) @@ -3,10 +3,130 @@ #include "gmock/gmock.h" #include "../TOverlappedDataBuffer.h" #include "../TCoreException.h" +#include "../TOverlappedDataBufferQueue.h" using namespace chcore; -TEST(TOverlappedDataBufferTests, DefaultConstructor_InvalidInput) +TEST(TOverlappedDataBufferTests, Constructor_InvalidInput) { EXPECT_THROW(TOverlappedDataBuffer(0, nullptr), TCoreException); } + +TEST(TOverlappedDataBufferTests, Constructor_SanityTest) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(32768, &queue); + + EXPECT_EQ(0, buffer.GetBufferOrder()); + EXPECT_NE(nullptr, buffer.GetBufferPtr()); + EXPECT_EQ(32768, buffer.GetBufferSize()); + EXPECT_EQ(0, buffer.GetBytesTransferred()); + EXPECT_EQ(0, buffer.GetErrorCode()); + EXPECT_EQ(0, buffer.GetFilePosition()); + EXPECT_EQ(0, buffer.GetRealDataSize()); + EXPECT_EQ(0, buffer.GetRequestedDataSize()); + EXPECT_EQ(0, buffer.GetStatusCode()); + EXPECT_FALSE(buffer.IsLastPart()); +} + +TEST(TOverlappedDataBufferTests, ReinitializeBuffer_ReduceSize) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(32768, &queue); + + buffer.ReinitializeBuffer(16384); + + EXPECT_NE(nullptr, buffer.GetBufferPtr()); + EXPECT_EQ(16384, buffer.GetBufferSize()); +} + +TEST(TOverlappedDataBufferTests, ReinitializeBuffer_IncreaseSize) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.ReinitializeBuffer(32768); + + EXPECT_NE(nullptr, buffer.GetBufferPtr()); + EXPECT_EQ(32768, buffer.GetBufferSize()); +} + +TEST(TOverlappedDataBufferTests, SetRequestedDataSize_GetRequestedDataSize) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetRequestedDataSize(123); + + EXPECT_EQ(123, buffer.GetRequestedDataSize()); +} + +TEST(TOverlappedDataBufferTests, SetRealDataSize_GetRealDataSize) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetRealDataSize(123); + + EXPECT_EQ(123, buffer.GetRealDataSize()); +} + +TEST(TOverlappedDataBufferTests, SetLastPart_IsLastPart) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetLastPart(true); + + EXPECT_TRUE(buffer.IsLastPart()); +} + +TEST(TOverlappedDataBufferTests, SetBufferOrder_GetBufferOrder) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetBufferOrder(123); + + EXPECT_EQ(123, buffer.GetBufferOrder()); +} + +TEST(TOverlappedDataBufferTests, SetErrorCode_GetErrorCode) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetErrorCode(123); + + EXPECT_EQ(123, buffer.GetErrorCode()); +} + +TEST(TOverlappedDataBufferTests, SetStatusCode_GetStatusCode) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetStatusCode(123); + + EXPECT_EQ(123, buffer.GetStatusCode()); +} + +TEST(TOverlappedDataBufferTests, SetBytesTransferred_GetBytesTransferred) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetBytesTransferred(123); + + EXPECT_EQ(123, buffer.GetBytesTransferred()); +} + +TEST(TOverlappedDataBufferTests, GetFilePosition_SetFilePosition) +{ + TOverlappedDataBufferQueue queue; + TOverlappedDataBuffer buffer(16384, &queue); + + buffer.SetFilePosition(123); + + EXPECT_EQ(123, buffer.GetFilePosition()); +}