Index: src/libchcore/GTestMacros.h =================================================================== diff -u --- src/libchcore/GTestMacros.h (revision 0) +++ src/libchcore/GTestMacros.h (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -0,0 +1,16 @@ +#ifndef __GTESTMACROS_H__ +#define __GTESTMACROS_H__ + +#define EXPECT_TIMEOUT(handle)\ + {\ + DWORD dwResult = WaitForSingleObject(handle, 0); \ + EXPECT_EQ(WAIT_TIMEOUT, dwResult); \ + } + +#define EXPECT_SIGNALED(handle)\ + {\ + DWORD dwResult = WaitForSingleObject(handle, 0); \ + EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); \ + } + +#endif Index: src/libchcore/OverlappedCallbacks.cpp =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/OverlappedCallbacks.cpp (.../OverlappedCallbacks.cpp) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/OverlappedCallbacks.cpp (.../OverlappedCallbacks.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -47,7 +47,10 @@ // in case of error (e.g end-of-file error triggers the difference and dwNumberOfBytesTransfered contains more up-to-date information) pBuffer->SetBytesTransferred(dwNumberOfBytesTransfered); - pQueue->AddFinishedReadBuffer(pBuffer); + if (pBuffer->HasError()) + pQueue->AddFailedReadBuffer(pBuffer); + else + pQueue->AddFinishedReadBuffer(pBuffer); } VOID CALLBACK OverlappedWriteCompleted(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) @@ -58,6 +61,9 @@ pBuffer->SetErrorCode(dwErrorCode); pBuffer->SetBytesTransferred(dwNumberOfBytesTransfered); - pQueue->AddFinishedWriteBuffer(pBuffer); + if (pBuffer->HasError()) + pQueue->AddFailedWriteBuffer(pBuffer); + else + pQueue->AddFinishedWriteBuffer(pBuffer); } } Index: src/libchcore/TBufferList.h =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/TBufferList.h (.../TBufferList.h) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/TBufferList.h (.../TBufferList.h) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -16,8 +16,8 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // ============================================================================ -#ifndef __TUNORDEREDBUFFERQUEUE_H__ -#define __TUNORDEREDBUFFERQUEUE_H__ +#ifndef __TBUFFERLIST_H__ +#define __TBUFFERLIST_H__ namespace chcore { Index: src/libchcore/TFailedBufferQueue.cpp =================================================================== diff -u -r6e4ac7776b68464371cd8522a2a8d79fbcab3b28 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/TFailedBufferQueue.cpp (.../TFailedBufferQueue.cpp) (revision 6e4ac7776b68464371cd8522a2a8d79fbcab3b28) +++ src/libchcore/TFailedBufferQueue.cpp (.../TFailedBufferQueue.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -54,13 +54,6 @@ return pBuffer; } - const TOverlappedDataBuffer* const TFailedBufferQueue::Peek() const - { - if(!m_setBuffers.empty()) - return *m_setBuffers.begin(); - return nullptr; - } - bool TFailedBufferQueue::IsBufferReady() const { return !m_setBuffers.empty(); Index: src/libchcore/TFailedBufferQueue.h =================================================================== diff -u -r6e4ac7776b68464371cd8522a2a8d79fbcab3b28 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/TFailedBufferQueue.h (.../TFailedBufferQueue.h) (revision 6e4ac7776b68464371cd8522a2a8d79fbcab3b28) +++ src/libchcore/TFailedBufferQueue.h (.../TFailedBufferQueue.h) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -38,45 +38,39 @@ template void PushWithFallback(TOverlappedDataBuffer* pBuffer, T& rRetryQueue) { - if(pBuffer->HasError()) + if (!pBuffer->HasError()) + throw TCoreException(eErr_InvalidArgument, L"Cannot push successful buffer to failed queue", LOCATION); + if(pBuffer->GetFilePosition() < m_ullErrorPosition) { - if(pBuffer->GetFilePosition() < m_ullErrorPosition) - { - // case: new buffer failed at even earlier position in file than the one that failed previously (should also work for numeric_limits::max()) - // - move existing buffers with errors to failed read buffers, add current one to full queue - m_ullErrorPosition = pBuffer->GetFilePosition(); + // case: new buffer failed at even earlier position in file than the one that failed previously (should also work for numeric_limits::max()) + // - move existing buffers with errors to failed read buffers, add current one to full queue + m_ullErrorPosition = pBuffer->GetFilePosition(); - BufferCollection newQueue; + BufferCollection newQueue; - for(TOverlappedDataBuffer* pBuf : m_setBuffers) + for(TOverlappedDataBuffer* pBuf : m_setBuffers) + { + if(pBuf->HasError()) + rRetryQueue.Push(pBuf, true); + else { - if(pBuf->HasError()) - rRetryQueue.Push(pBuf, true); - else - { - auto pairInsert = newQueue.insert(pBuf); - if (!pairInsert.second) - throw TCoreException(eErr_InvalidArgument, L"Tried to insert duplicate buffer into the collection", LOCATION); - } + auto pairInsert = newQueue.insert(pBuf); + if (!pairInsert.second) + throw TCoreException(eErr_InvalidArgument, L"Tried to insert duplicate buffer into the collection", LOCATION); } - - if(newQueue.size() != m_setBuffers.size()) - std::swap(m_setBuffers, newQueue); } - else if(pBuffer->GetFilePosition() > m_ullErrorPosition) - { - // case: new buffer failed at position later than the one that failed before - add to failed buffers - // for retry - rRetryQueue.Push(pBuffer, true); - return; - } - //else -> case: we've received the same buffer that failed before; add to normal full queue for user to handle that + + if(newQueue.size() != m_setBuffers.size()) + std::swap(m_setBuffers, newQueue); } - else if(m_ullErrorPosition == pBuffer->GetFilePosition()) + else if(pBuffer->GetFilePosition() > m_ullErrorPosition) { - // case: adding correctly read buffer that previously failed to read; clear the error flag and add full buffer - m_ullErrorPosition = NoPosition; + // case: new buffer failed at position later than the one that failed before - add to failed buffers + // for retry + rRetryQueue.Push(pBuffer, true); + return; } + //else throw TCoreException (will be thrown by insert() below) auto pairInsert = m_setBuffers.insert(pBuffer); if (!pairInsert.second) @@ -86,7 +80,6 @@ } TOverlappedDataBuffer* Pop(); - const TOverlappedDataBuffer* const Peek() const; void Clear(); Index: src/libchcore/TOverlappedDataBuffer.cpp =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/TOverlappedDataBuffer.cpp (.../TOverlappedDataBuffer.cpp) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/TOverlappedDataBuffer.cpp (.../TOverlappedDataBuffer.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -58,6 +58,9 @@ void TOverlappedDataBuffer::ReinitializeBuffer(size_t stNewBufferSize) { + if (stNewBufferSize == 0) + throw TCoreException(eErr_InvalidArgument, L"Cannot create 0-sized buffer", LOCATION); + if (stNewBufferSize != m_stBufferSize) { ReleaseBuffer(); @@ -111,5 +114,6 @@ SetErrorCode(ERROR_SUCCESS); SetStatusCode(0); SetBytesTransferred(0); + SetParam(nullptr); } } Index: src/libchcore/TReadBufferQueueWrapper.h =================================================================== diff -u -r6e4ac7776b68464371cd8522a2a8d79fbcab3b28 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/TReadBufferQueueWrapper.h (.../TReadBufferQueueWrapper.h) (revision 6e4ac7776b68464371cd8522a2a8d79fbcab3b28) +++ src/libchcore/TReadBufferQueueWrapper.h (.../TReadBufferQueueWrapper.h) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -38,8 +38,6 @@ void Push(TOverlappedDataBuffer* pBuffer, bool bKeepPosition); TOverlappedDataBuffer* Pop(); - bool IsBufferReady() const; - void Clear(); size_t GetCount() const; @@ -52,6 +50,7 @@ void ReleaseBuffers(const TBufferListPtr& spBuffers); private: + bool IsBufferReady() const; void UpdateHasBuffers(); private: Index: src/libchcore/TWriteBufferQueueWrapper.h =================================================================== diff -u -r6e4ac7776b68464371cd8522a2a8d79fbcab3b28 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/TWriteBufferQueueWrapper.h (.../TWriteBufferQueueWrapper.h) (revision 6e4ac7776b68464371cd8522a2a8d79fbcab3b28) +++ src/libchcore/TWriteBufferQueueWrapper.h (.../TWriteBufferQueueWrapper.h) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -38,8 +38,6 @@ void Push(TOverlappedDataBuffer* pBuffer); TOverlappedDataBuffer* Pop(); - bool IsBufferReady() const; - void Clear(); size_t GetCount() const; @@ -49,6 +47,7 @@ void ReleaseBuffers(const TBufferListPtr& spBuffers); private: + bool IsBufferReady() const; void UpdateHasBuffers(); private: Index: src/libchcore/Tests/OverlappedCallbacksTests.cpp =================================================================== diff -u -r6e4ac7776b68464371cd8522a2a8d79fbcab3b28 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/Tests/OverlappedCallbacksTests.cpp (.../OverlappedCallbacksTests.cpp) (revision 6e4ac7776b68464371cd8522a2a8d79fbcab3b28) +++ src/libchcore/Tests/OverlappedCallbacksTests.cpp (.../OverlappedCallbacksTests.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -47,7 +47,7 @@ EXPECT_EQ(ERROR_ACCESS_DENIED, buffer.GetErrorCode()); EXPECT_EQ(0, buffer.GetRealDataSize()); - EXPECT_EQ(queue.GetWriteBuffer(), &buffer); + EXPECT_EQ(queue.GetFailedReadBuffer(), &buffer); } TEST(OverlappedCallbackTests, OverlappedWriteCompleted_Success) Index: src/libchcore/Tests/TBufferListTests.cpp =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/Tests/TBufferListTests.cpp (.../TBufferListTests.cpp) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/Tests/TBufferListTests.cpp (.../TBufferListTests.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -2,10 +2,50 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" #include "../TBufferList.h" +#include "../TCoreException.h" +#include "../TOverlappedDataBuffer.h" using namespace chcore; -TEST(TBufferListTests, DefaultTest) +TEST(TBufferListTests, DefaultConstructionSanityTest) { TBufferList bufferList; + + EXPECT_EQ(0, bufferList.GetCount()); + EXPECT_EQ(true, bufferList.IsEmpty()); + EXPECT_EQ(nullptr, bufferList.Pop()); } + +TEST(TBufferListTests, PushNull) +{ + TBufferList bufferList; + + EXPECT_THROW(bufferList.Push(nullptr), TCoreException); +} + +TEST(TBufferListTests, PushBuffer) +{ + TBufferList bufferList; + + TOverlappedDataBuffer rBuffer(4096, nullptr); + + bufferList.Push(&rBuffer); + + EXPECT_EQ(1, bufferList.GetCount()); + EXPECT_EQ(false, bufferList.IsEmpty()); + EXPECT_EQ(&rBuffer, bufferList.Pop()); +} + +TEST(TBufferListTests, Clear) +{ + TBufferList bufferList; + + TOverlappedDataBuffer rBuffer(4096, nullptr); + + bufferList.Push(&rBuffer); + bufferList.Clear(); + + EXPECT_EQ(0, bufferList.GetCount()); + EXPECT_EQ(true, bufferList.IsEmpty()); + EXPECT_EQ(nullptr, bufferList.Pop()); +} Index: src/libchcore/Tests/TFailedBufferQueueTests.cpp =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/Tests/TFailedBufferQueueTests.cpp (.../TFailedBufferQueueTests.cpp) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/Tests/TFailedBufferQueueTests.cpp (.../TFailedBufferQueueTests.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -2,10 +2,193 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" #include "../TFailedBufferQueue.h" +#include "../GTestMacros.h" +#include "../TOverlappedDataBuffer.h" +#include using namespace chcore; -TEST(TFailedBufferQueueTests, DefaultTest) +class FallbackCollection : public std::vector { +public: + void Push(TOverlappedDataBuffer* pBuffer, bool /*bKeepPos*/) + { + push_back(pBuffer); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// Construction tests + +TEST(TFailedBufferQueueTests, ConstructionSanityTest) +{ TFailedBufferQueue queue; + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(true, queue.IsEmpty()); } + +/////////////////////////////////////////////////////////////////////////////// +// PushBuffer tests + +TEST(TFailedBufferQueueTests, PushBuffer_FirstFailure) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer(4096, nullptr); + buffer.SetErrorCode(123); + + FallbackCollection collection; + + queue.PushWithFallback(&buffer, collection); + EXPECT_EQ(false, queue.IsEmpty()); + EXPECT_EQ(1, queue.GetCount()); + EXPECT_SIGNALED(queue.GetHasBuffersEvent()); + EXPECT_EQ(true, collection.empty()); +} + +TEST(TFailedBufferQueueTests, PushBuffer_TwoSubsequentFailures) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer1(4096, nullptr); + TOverlappedDataBuffer buffer2(4096, nullptr); + buffer1.SetFilePosition(0); + buffer1.SetErrorCode(123); + buffer2.SetFilePosition(1000); + buffer2.SetErrorCode(234); + + FallbackCollection collection; + + queue.PushWithFallback(&buffer1, collection); + queue.PushWithFallback(&buffer2, collection); + + EXPECT_EQ(false, queue.IsEmpty()); + EXPECT_EQ(1, queue.GetCount()); + EXPECT_SIGNALED(queue.GetHasBuffersEvent()); + EXPECT_EQ(1, collection.size()); + EXPECT_EQ(&buffer2, collection.front()); + EXPECT_EQ(1000, collection.front()->GetFilePosition()); + EXPECT_EQ(234, collection.front()->GetErrorCode()); +} + +TEST(TFailedBufferQueueTests, PushBuffer_TwoFailuresOutOfOrder) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer1(4096, nullptr); + TOverlappedDataBuffer buffer2(4096, nullptr); + buffer1.SetFilePosition(0); + buffer1.SetErrorCode(123); + buffer2.SetFilePosition(1000); + buffer2.SetErrorCode(234); + + FallbackCollection collection; + + queue.PushWithFallback(&buffer2, collection); + queue.PushWithFallback(&buffer1, collection); + + EXPECT_EQ(false, queue.IsEmpty()); + EXPECT_EQ(1, queue.GetCount()); + EXPECT_SIGNALED(queue.GetHasBuffersEvent()); + EXPECT_EQ(1, collection.size()); + EXPECT_EQ(&buffer2, collection.front()); + EXPECT_EQ(1000, collection.front()->GetFilePosition()); + EXPECT_EQ(234, collection.front()->GetErrorCode()); +} + +TEST(TFailedBufferQueueTests, PushBuffer_ThrowOnNonErrorBuffer) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer1(4096, nullptr); + buffer1.SetFilePosition(0); + buffer1.SetErrorCode(ERROR_SUCCESS); + + FallbackCollection collection; + + EXPECT_THROW(queue.PushWithFallback(&buffer1, collection), TCoreException); +} + +TEST(TFailedBufferQueueTests, PushBuffer_WithSamePosition) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer1(4096, nullptr); + TOverlappedDataBuffer buffer2(4096, nullptr); + buffer1.SetFilePosition(1000); + buffer1.SetErrorCode(123); + buffer2.SetFilePosition(1000); + buffer2.SetErrorCode(234); + + FallbackCollection collection; + + queue.PushWithFallback(&buffer1, collection); + EXPECT_THROW(queue.PushWithFallback(&buffer2, collection), TCoreException); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Pop tests + +TEST(TFailedBufferQueueTests, PopBuffer_EmptyContainer) +{ + TFailedBufferQueue queue; + EXPECT_EQ(nullptr, queue.Pop()); +} + +TEST(TFailedBufferQueueTests, PopBuffer_WithSamePosition) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer1(4096, nullptr); + TOverlappedDataBuffer buffer2(4096, nullptr); + TOverlappedDataBuffer buffer3(4096, nullptr); + buffer1.SetFilePosition(0); + buffer1.SetErrorCode(123); + buffer2.SetFilePosition(1000); + buffer2.SetErrorCode(234); + + FallbackCollection collection; + + queue.PushWithFallback(&buffer1, collection); + queue.Pop(); + + EXPECT_EQ(0, collection.size()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + + queue.PushWithFallback(&buffer2, collection); + EXPECT_EQ(1, queue.GetCount()); +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// Clear tests + +TEST(TFailedBufferQueueTests, Clear) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer1(4096, nullptr); + buffer1.SetFilePosition(0); + buffer1.SetErrorCode(123); + + FallbackCollection collection; + + queue.PushWithFallback(&buffer1, collection); + queue.Clear(); + + EXPECT_EQ(0, queue.GetCount()); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// ReleaseBuffers + +TEST(TFailedBufferQueueTests, ReleaseBuffers) +{ + TFailedBufferQueue queue; + TOverlappedDataBuffer buffer1(4096, nullptr); + buffer1.SetFilePosition(0); + buffer1.SetErrorCode(123); + + FallbackCollection collection; + + queue.PushWithFallback(&buffer1, collection); + + TBufferListPtr spReturnedBuffers(std::make_shared()); + queue.ReleaseBuffers(spReturnedBuffers); + + EXPECT_EQ(1, spReturnedBuffers->GetCount()); +} Index: src/libchcore/Tests/TOrderedBufferQueueTests.cpp =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/Tests/TOrderedBufferQueueTests.cpp (.../TOrderedBufferQueueTests.cpp) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/Tests/TOrderedBufferQueueTests.cpp (.../TOrderedBufferQueueTests.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -2,10 +2,201 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" #include "../TOrderedBufferQueue.h" +#include "../GTestMacros.h" using namespace chcore; -TEST(TOrderedBufferQueueTests, DefaultTest) +// no expected position mode +TEST(TOrderedBufferQueueTests, NoExpectedPos_ConstructionSanityTest) { - TOrderedBufferQueue bufferList; + TOrderedBufferQueue queue; + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_EQ(true, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(nullptr, queue.Peek()); } + +TEST(TOrderedBufferQueueTests, NoExpectedPos_Push) +{ + TOrderedBufferQueue queue; + TOverlappedDataBuffer buffer(1024, nullptr); + + queue.Push(&buffer); + + EXPECT_EQ(1, queue.GetCount()); + EXPECT_EQ(false, queue.IsEmpty()); + EXPECT_SIGNALED(queue.GetHasBuffersEvent()); + EXPECT_EQ(&buffer, queue.Peek()); +} + +TEST(TOrderedBufferQueueTests, NoExpectedPos_Pop) +{ + TOrderedBufferQueue queue; + TOverlappedDataBuffer buffer(1024, nullptr); + + queue.Push(&buffer); + EXPECT_EQ(&buffer, queue.Pop()); + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_EQ(true, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(nullptr, queue.Peek()); +} + +TEST(TOrderedBufferQueueTests, NoExpectedPos_Clear) +{ + TOrderedBufferQueue queue; + TOverlappedDataBuffer buffer(1024, nullptr); + + queue.Push(&buffer); + queue.Clear(); + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_EQ(true, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(nullptr, queue.Peek()); +} + +TEST(TOrderedBufferQueueTests, NoExpectedPos_ReleaseBuffers) +{ + TOrderedBufferQueue queue; + TBufferListPtr spReleaseList(std::make_shared()); + TOverlappedDataBuffer buffer(1024, nullptr); + + queue.Push(&buffer); + queue.ReleaseBuffers(spReleaseList); + + EXPECT_EQ(1, spReleaseList->GetCount()); +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// expected position mode +TEST(TOrderedBufferQueueTests, ExpectedPos_ConstructionSanityTest) +{ + TOrderedBufferQueue queue(0); + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_EQ(true, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(nullptr, queue.Peek()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_PushAtExpectedPosition) +{ + TOrderedBufferQueue queue(0); + TOverlappedDataBuffer buffer(1024, nullptr); + buffer.SetFilePosition(0); + + queue.Push(&buffer); + + EXPECT_EQ(1, queue.GetCount()); + EXPECT_EQ(false, queue.IsEmpty()); + EXPECT_SIGNALED(queue.GetHasBuffersEvent()); + EXPECT_EQ(&buffer, queue.Peek()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_PushAtOtherPosition) +{ + TOrderedBufferQueue queue(0); + TOverlappedDataBuffer buffer(1024, nullptr); + buffer.SetFilePosition(1000); + + queue.Push(&buffer); + + EXPECT_EQ(1, queue.GetCount()); + EXPECT_EQ(false, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(&buffer, queue.Peek()); + EXPECT_EQ(nullptr, queue.Pop()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_PushOutOfOrder) +{ + TOrderedBufferQueue queue(0); + TOverlappedDataBuffer buffer1(1024, nullptr); + buffer1.SetFilePosition(1000); + buffer1.SetRequestedDataSize(1000); + TOverlappedDataBuffer buffer2(1024, nullptr); + buffer2.SetFilePosition(0); + buffer2.SetRequestedDataSize(1000); + + queue.Push(&buffer1); + queue.Push(&buffer2); + + EXPECT_EQ(2, queue.GetCount()); + EXPECT_EQ(false, queue.IsEmpty()); + EXPECT_SIGNALED(queue.GetHasBuffersEvent()); + EXPECT_EQ(&buffer2, queue.Peek()); + EXPECT_EQ(&buffer2, queue.Pop()); + EXPECT_EQ(&buffer1, queue.Pop()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_Pop) +{ + TOrderedBufferQueue queue(0); + TOverlappedDataBuffer buffer(1024, nullptr); + + queue.Push(&buffer); + EXPECT_EQ(&buffer, queue.Pop()); + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_EQ(true, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(nullptr, queue.Peek()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_Clear) +{ + TOrderedBufferQueue queue(0); + TOverlappedDataBuffer buffer(1024, nullptr); + + queue.Push(&buffer); + queue.Clear(); + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_EQ(true, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); + EXPECT_EQ(nullptr, queue.Peek()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_ClearUnordered) +{ + TOrderedBufferQueue queue(0); + TOverlappedDataBuffer buffer1(1024, nullptr); + buffer1.SetFilePosition(1000); + buffer1.SetRequestedDataSize(1000); + + queue.Push(&buffer1); + + queue.Clear(); + + EXPECT_EQ(0, queue.GetCount()); + EXPECT_EQ(true, queue.IsEmpty()); + EXPECT_TIMEOUT(queue.GetHasBuffersEvent()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_ReleaseBuffers) +{ + TOrderedBufferQueue queue(0); + TBufferListPtr spReleaseList(std::make_shared()); + TOverlappedDataBuffer buffer(1024, nullptr); + + queue.Push(&buffer); + queue.ReleaseBuffers(spReleaseList); + + EXPECT_EQ(1, spReleaseList->GetCount()); +} + +TEST(TOrderedBufferQueueTests, ExpectedPos_ReleaseBuffersUnordered) +{ + TOrderedBufferQueue queue(0); + TBufferListPtr spReleaseList(std::make_shared()); + TOverlappedDataBuffer buffer(1024, nullptr); + buffer.SetFilePosition(1000); + + queue.Push(&buffer); + queue.ReleaseBuffers(spReleaseList); + + EXPECT_EQ(1, spReleaseList->GetCount()); +} Index: src/libchcore/Tests/TOverlappedDataBufferTests.cpp =================================================================== diff -u -r6e4ac7776b68464371cd8522a2a8d79fbcab3b28 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/Tests/TOverlappedDataBufferTests.cpp (.../TOverlappedDataBufferTests.cpp) (revision 6e4ac7776b68464371cd8522a2a8d79fbcab3b28) +++ src/libchcore/Tests/TOverlappedDataBufferTests.cpp (.../TOverlappedDataBufferTests.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -8,30 +8,33 @@ using namespace chcore; +/////////////////////////////////////////////////////////////////////////////// +// construction + +TEST(TOverlappedDataBufferTests, Constructor_ZeroSizedBuffer) +{ + EXPECT_THROW(TOverlappedDataBuffer(0, nullptr), TCoreException); +} + TEST(TOverlappedDataBufferTests, Constructor_NullParam) { - TOverlappedDataBuffer buffer(0, nullptr); + TOverlappedDataBuffer buffer(4096, nullptr); EXPECT_EQ(nullptr, buffer.GetParam()); } -TEST(TOverlappedDataBufferTests, SetParam_GetParam) +TEST(TOverlappedDataBufferTests, Constructor_NonNullParam) { - int iTest = 5; + TOverlappedDataBuffer buffer(4096, (void*)5); - TOverlappedDataBuffer buffer(0, &iTest); - - EXPECT_EQ(&iTest, buffer.GetParam()); + EXPECT_EQ((void*)5, buffer.GetParam()); } TEST(TOverlappedDataBufferTests, Constructor_SanityTest) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + int iParam = 5; + TOverlappedDataBuffer buffer(32768, &iParam); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(32768, &queue); - EXPECT_NE(nullptr, buffer.GetBufferPtr()); EXPECT_EQ(32768, buffer.GetBufferSize()); EXPECT_EQ(0, buffer.GetBytesTransferred()); @@ -43,14 +46,42 @@ EXPECT_FALSE(buffer.IsLastPart()); } -TEST(TOverlappedDataBufferTests, ReinitializeBuffer_ReduceSize) +/////////////////////////////////////////////////////////////////////////////// +// parameter handling + +TEST(TOverlappedDataBufferTests, GetParam) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + int iTest = 5; - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(32768, &queue); + TOverlappedDataBuffer buffer(4096, &iTest); + EXPECT_EQ(&iTest, buffer.GetParam()); +} + +TEST(TOverlappedDataBufferTests, SetParam_GetParam) +{ + int iTest = 5; + + TOverlappedDataBuffer buffer(4096, &iTest); + buffer.SetParam(nullptr); + + EXPECT_EQ(nullptr, buffer.GetParam()); +} + +/////////////////////////////////////////////////////////////////////////////// +// buffer re-initialization + +TEST(TOverlappedDataBufferTests, ReinitializeBuffer_ZeroSize) +{ + TOverlappedDataBuffer buffer(32768, nullptr); + + EXPECT_THROW(buffer.ReinitializeBuffer(0), TCoreException); +} + +TEST(TOverlappedDataBufferTests, ReinitializeBuffer_ReduceSize) +{ + TOverlappedDataBuffer buffer(32768, nullptr); + buffer.ReinitializeBuffer(16384); EXPECT_NE(nullptr, buffer.GetBufferPtr()); @@ -59,118 +90,97 @@ TEST(TOverlappedDataBufferTests, ReinitializeBuffer_IncreaseSize) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.ReinitializeBuffer(32768); EXPECT_NE(nullptr, buffer.GetBufferPtr()); EXPECT_EQ(32768, buffer.GetBufferSize()); } -TEST(TOverlappedDataBufferTests, SetRequestedDataSize_GetRequestedDataSize) +TEST(TOverlappedDataBufferTests, ReinitializeBuffer_SameSize) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); + void* pBuffer = buffer.GetBufferPtr(); + buffer.ReinitializeBuffer(16384); + + EXPECT_EQ(pBuffer, buffer.GetBufferPtr()); +} + +/////////////////////////////////////////////////////////////////////////////// +// other attributes + +TEST(TOverlappedDataBufferTests, SetRequestedDataSize_GetRequestedDataSize) +{ + TOverlappedDataBuffer buffer(16384, nullptr); + buffer.SetRequestedDataSize(123); EXPECT_EQ(123, buffer.GetRequestedDataSize()); } TEST(TOverlappedDataBufferTests, SetRealDataSize_GetRealDataSize) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetRealDataSize(123); EXPECT_EQ(123, buffer.GetRealDataSize()); } TEST(TOverlappedDataBufferTests, SetLastPart_IsLastPart) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetLastPart(true); EXPECT_TRUE(buffer.IsLastPart()); } TEST(TOverlappedDataBufferTests, SetErrorCode_GetErrorCode) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetErrorCode(123); EXPECT_EQ(123, buffer.GetErrorCode()); } TEST(TOverlappedDataBufferTests, SetStatusCode_GetStatusCode) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetStatusCode(123); EXPECT_EQ(123, buffer.GetStatusCode()); } TEST(TOverlappedDataBufferTests, SetBytesTransferred_GetBytesTransferred) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetBytesTransferred(123); EXPECT_EQ(123, buffer.GetBytesTransferred()); } TEST(TOverlappedDataBufferTests, GetFilePosition_SetFilePosition) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetFilePosition(123); EXPECT_EQ(123, buffer.GetFilePosition()); } /////////////////////////////////////////////////////////////////////////////////////////////////// +// TEST(TOverlappedDataBufferTests, InitForRead) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetRequestedDataSize(123); buffer.SetFilePosition(1); buffer.SetRealDataSize(120); @@ -192,12 +202,8 @@ TEST(TOverlappedDataBufferTests, InitForWrite) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetRequestedDataSize(123); buffer.SetFilePosition(1); buffer.SetRealDataSize(120); @@ -215,19 +221,16 @@ TEST(TOverlappedDataBufferTests, Reset) { - logger::TLogFileDataPtr spLogData(std::make_shared()); + TOverlappedDataBuffer buffer(16384, nullptr); - TOverlappedMemoryPoolPtr spBuffers(std::make_shared()); - TOverlappedReaderWriter queue(spLogData, spBuffers, 0, 4096); - TOverlappedDataBuffer buffer(16384, &queue); - buffer.SetRequestedDataSize(123); buffer.SetFilePosition(1); buffer.SetRealDataSize(120); buffer.SetLastPart(true); buffer.SetErrorCode(54); buffer.SetStatusCode(3); buffer.SetBytesTransferred(12); + buffer.SetParam((void*)1); buffer.Reset(); @@ -238,6 +241,7 @@ EXPECT_EQ(0, buffer.GetErrorCode()); EXPECT_EQ(0, buffer.GetStatusCode()); EXPECT_EQ(0, buffer.GetBytesTransferred()); + EXPECT_EQ(nullptr, buffer.GetParam()); } /////////////////////////////////////////////////////////////////////////////////////////////////// Index: src/libchcore/Tests/TOverlappedReaderWriterTests.cpp =================================================================== diff -u -r6e4ac7776b68464371cd8522a2a8d79fbcab3b28 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/Tests/TOverlappedReaderWriterTests.cpp (.../TOverlappedReaderWriterTests.cpp) (revision 6e4ac7776b68464371cd8522a2a8d79fbcab3b28) +++ src/libchcore/Tests/TOverlappedReaderWriterTests.cpp (.../TOverlappedReaderWriterTests.cpp) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -5,22 +5,11 @@ #include "../TOverlappedDataBuffer.h" #include "../TCoreException.h" #include "../../liblogger/TLogFileData.h" +#include "../GTestMacros.h" using namespace chcore; -#define EXPECT_TIMEOUT(handle)\ - {\ - DWORD dwResult = WaitForSingleObject(handle, 0); \ - EXPECT_EQ(WAIT_TIMEOUT, dwResult); \ - } -#define EXPECT_SIGNALED(handle)\ - {\ - DWORD dwResult = WaitForSingleObject(handle, 0); \ - EXPECT_EQ(WAIT_OBJECT_0 + 0, dwResult); \ - } - - TEST(TOverlappedReaderWriterTests, DefaultConstructor_SanityTest) { logger::TLogFileDataPtr spLogData(std::make_shared()); Index: src/libchcore/libchcore.vc140.vcxproj =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -463,6 +463,7 @@ + Index: src/libchcore/libchcore.vc140.vcxproj.filters =================================================================== diff -u -r3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9 -rbef894e38e5c1486824787cf8c47a87a0828b228 --- src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision 3ccbdb8d3eac3427e6d3354854476e57fdc7ceb9) +++ src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -494,6 +494,9 @@ Source Files\Tools\Data Buffer\Queues + + Tests + Index: va_stdafx.h =================================================================== diff -u -r078d08f91614ef157c27460989324ddd968c78cd -rbef894e38e5c1486824787cf8c47a87a0828b228 --- va_stdafx.h (.../va_stdafx.h) (revision 078d08f91614ef157c27460989324ddd968c78cd) +++ va_stdafx.h (.../va_stdafx.h) (revision bef894e38e5c1486824787cf8c47a87a0828b228) @@ -17,3 +17,14 @@ void Test_##test_case_name##_##test_name##::Exec() #define EXPECT_EQ(a, b) (a) == (b) +#define EXPECT_THROW(operation, exc)\ +do\ +{\ + try\ + {\ + operation;\ + }\ + catch(const exc&)\ + {\ + }\ +} while(false)