blob: e73b67b4c88cae305502141b98cdc74ee3f5ef27 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "post_buffer.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <string.h>
#include <vector>
namespace gapir {
namespace test {
namespace {
const std::vector<uint8_t> input = { 0, 1, 2, 3, 4, 5 };
class PostBufferTest : public ::testing::Test {
protected:
virtual void SetUp() {
mPostBuffer.reset();
mOutput.clear();
mPostsCounter = 0;
}
void setupPostBuffer(uint32_t bufferSize, bool callbackShouldSucceed) {
mPostBuffer.reset(new PostBuffer(bufferSize,
[&, callbackShouldSucceed](const void* ptr, uint32_t size) {
mPostsCounter++;
mOutput.resize(mOutput.size()+size);
memcpy(&mOutput[mOutput.size()-size], ptr, size);
return callbackShouldSucceed;
}));
}
std::unique_ptr<PostBuffer> mPostBuffer;
std::vector<uint8_t> mOutput;
uint32_t mPostsCounter;
};
} // anonymous namespace
TEST_F(PostBufferTest, ZeroSizedBuffer) {
// No buffering, callback always succeeds.
setupPostBuffer(0, true);
// Push should immediately call the post callback as there's no buffering.
EXPECT_TRUE(mPostBuffer->push(&input.front(), input.size()));
EXPECT_EQ(input, mOutput);
const uint32_t postsCounterBeforeFlush = mPostsCounter;
// Flush should be a no-op if there's no buffering.
EXPECT_TRUE(mPostBuffer->flush());
EXPECT_EQ(postsCounterBeforeFlush, mPostsCounter);
}
TEST_F(PostBufferTest, PushSmallPacketsThenFlush) {
// Buffer much larger than the whole input, callback always succeeds.
setupPostBuffer(input.size()*4, true);
for (size_t i = 0; i < input.size(); ++i) {
EXPECT_TRUE(mPostBuffer->push(&input[i], 1));
}
EXPECT_TRUE(mPostBuffer->flush());
EXPECT_EQ(input, mOutput);
}
TEST_F(PostBufferTest, PushLargePacketsThenFlush) {
// Buffer size smaller than each packet pushed.
setupPostBuffer(1, true);
ASSERT_EQ(0, input.size() % 2); // Make sure we're not being silly.
for (size_t i = 0; i < input.size(); i += 2) {
EXPECT_TRUE(mPostBuffer->push(&input[i], 2));
}
// Each packet larger than the buffer should trigger a separate post.
EXPECT_EQ(input.size()/2, mPostsCounter);
EXPECT_EQ(input, mOutput);
const uint32_t postsCounterBeforeFlush = mPostsCounter;
// Flush should be a no-op as none of the packets did fit in the buffer.
EXPECT_TRUE(mPostBuffer->flush());
EXPECT_EQ(postsCounterBeforeFlush, mPostsCounter);
}
TEST_F(PostBufferTest, PushMixSizedPacketsThenFlush) {
// Buffer size respectively smaller, equal and larger than pushed packets.
setupPostBuffer(2, true);
ASSERT_EQ(1+2+3, input.size()); // Make sure we're not being silly.
EXPECT_TRUE(mPostBuffer->push(&input[0], 1));
EXPECT_TRUE(mPostBuffer->push(&input[1], 2));
EXPECT_TRUE(mPostBuffer->push(&input[3], 3));
EXPECT_TRUE(mPostBuffer->flush());
EXPECT_EQ(input, mOutput);
}
TEST_F(PostBufferTest, FlushOnDestruction) {
// Buffer much larger than the whole input, callback always succeeds.
setupPostBuffer(input.size()*4, true);
EXPECT_TRUE(mPostBuffer->push(&input.front(), input.size()));
// Note: While the semantics are not explicit about it, we don't expect
// the PostBuffer to be flushed after only 1/4 of its capacity has been
// pushed to. If this happens to be wrong, remove the following check.
EXPECT_EQ(0, mPostsCounter);
// Check that the packets gets posted on PostBuffer destruction.
mPostBuffer.reset();
EXPECT_EQ(input, mOutput);
}
TEST_F(PostBufferTest, ReportCallbackErrors) {
// No buffering, callback always failing.
setupPostBuffer(0, false);
// At least one of these commands should call and report a callback error.
bool pushSuccess = mPostBuffer->push(&input.front(), input.size());
bool flushSuccess = mPostBuffer->flush();
EXPECT_LT(0, mPostsCounter);
EXPECT_FALSE(pushSuccess && flushSuccess);
}
} // namespace test
} // namespace gapir