blob: 41b3b95be05ad03c0944c1656421e822daf7650c [file] [log] [blame]
/*
* Copyright (C) 2020 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 <gtest/gtest.h>
#include <string>
#include "chre/platform/atomic.h"
#include "chre/platform/condition_variable.h"
#include "chre/platform/mutex.h"
#include "chre/platform/shared/log_buffer.h"
namespace chre {
// TODO(b/146164384): Test that the onLogsReady callback is called
// asynchronously
class TestLogBufferCallback : public LogBufferCallbackInterface {
public:
void onLogsReady(LogBuffer *logBuffer) {
// Do nothing
}
};
static constexpr size_t kDefaultBufferSize = 1024;
static constexpr size_t kBytesBeforeLogData = 6;
TEST(LogBuffer, HandleOneLogAndCopy) {
char buffer[kDefaultBufferSize];
constexpr size_t kOutBufferSize = 20;
char outBuffer[kOutBufferSize];
const char *testLogStr = "test";
char testedBuffer[kOutBufferSize];
TestLogBufferCallback callback;
LogBuffer logBuffer(&callback, buffer, kDefaultBufferSize);
logBuffer.handleLog(LogBufferLogLevel::INFO, 0, testLogStr);
size_t bytesCopied = logBuffer.copyLogs(outBuffer, kOutBufferSize);
EXPECT_EQ(bytesCopied,
strlen(testLogStr) +
kBytesBeforeLogData /*loglevel, timestamp, and loglen*/);
memcpy(testedBuffer, outBuffer + kBytesBeforeLogData, strlen(testLogStr));
testedBuffer[strlen(testLogStr)] = '\0';
EXPECT_TRUE(strcmp(testedBuffer, testLogStr) == 0);
}
TEST(LogBuffer, FailOnMoreCopyThanHandle) {
char buffer[kDefaultBufferSize];
constexpr size_t kOutBufferSize = 20;
char outBuffer[kOutBufferSize];
constexpr size_t kEmptyBufferSize = 10;
char emptyBuffer[kEmptyBufferSize];
emptyBuffer[0] = '\0';
const char *testLogStr = "test";
TestLogBufferCallback callback;
char testedBuffer[kOutBufferSize];
LogBuffer logBuffer(&callback, buffer, kDefaultBufferSize);
logBuffer.handleLog(LogBufferLogLevel::INFO, 0, testLogStr);
logBuffer.copyLogs(outBuffer, kOutBufferSize);
memcpy(testedBuffer, outBuffer + kBytesBeforeLogData, strlen(testLogStr));
testedBuffer[strlen(testLogStr)] = '\0';
size_t bytesCopied = logBuffer.copyLogs(outBuffer, kOutBufferSize);
EXPECT_EQ(bytesCopied, 0);
EXPECT_EQ(strlen(emptyBuffer), 0);
}
TEST(LogBuffer, FailOnHandleLargerLogThanBufferSize) {
char buffer[kDefaultBufferSize];
constexpr size_t kOutBufferSize = 20;
char outBuffer[kOutBufferSize];
// Note the size of this log is too big to fit in the buffer that we are
// using for the LogBuffer object
std::string testLogStrStr(1025, 'a');
TestLogBufferCallback callback;
LogBuffer logBuffer(&callback, buffer, kDefaultBufferSize);
logBuffer.handleLog(LogBufferLogLevel::INFO, 0, testLogStrStr.c_str());
size_t bytesCopied = logBuffer.copyLogs(outBuffer, kOutBufferSize);
// Should not be able to read this log out because there should be no log in
// the first place
EXPECT_EQ(bytesCopied, 0);
}
TEST(LogBuffer, LogOverwritten) {
char buffer[kDefaultBufferSize];
constexpr size_t kOutBufferSize = 200;
char outBuffer[kOutBufferSize];
char testedBuffer[kOutBufferSize];
TestLogBufferCallback callback;
LogBuffer logBuffer(&callback, buffer, kDefaultBufferSize);
// This for loop adds 1060 bytes of data through the buffer which is > than
// 1024
for (size_t i = 0; i < 10; i++) {
std::string testLogStrStr(100, 'a' + i);
const char *testLogStr = testLogStrStr.c_str();
logBuffer.handleLog(LogBufferLogLevel::INFO, 0, testLogStr);
}
size_t bytesCopied = logBuffer.copyLogs(outBuffer, kBytesBeforeLogData + 100);
memcpy(testedBuffer, outBuffer + kBytesBeforeLogData, 100);
testedBuffer[100] = '\0';
// Should have read out the second from front test log string which is 'a' + 1
// = 'b'
EXPECT_TRUE(strcmp(testedBuffer, std::string(100, 'b').c_str()) == 0);
EXPECT_EQ(bytesCopied, kBytesBeforeLogData + 100);
}
TEST(LogBuffer, CopyIntoEmptyBuffer) {
char buffer[kDefaultBufferSize];
constexpr size_t kOutBufferSize = 0;
char outBuffer[kOutBufferSize];
TestLogBufferCallback callback;
LogBuffer logBuffer(&callback, buffer, kDefaultBufferSize);
logBuffer.handleLog(LogBufferLogLevel::INFO, 0, "test");
size_t bytesCopied = logBuffer.copyLogs(outBuffer, kOutBufferSize);
EXPECT_EQ(bytesCopied, 0);
}
// TODO(srok): Add multithreaded tests
} // namespace chre