Add support for log-handler
This handler is based off of version handler with major differences in
handler_builder
Tested:
created the blackbox blob successfully using this lib.
Read the data from the blob using a host side tool
Signed-off-by: Gaurav Gandhi <gauravgandhi@google.com>
Change-Id: I9ef775af752156a1647453ff3831ef4c0449d546
diff --git a/bmc/log-handler/test/log_json_unittest.cpp b/bmc/log-handler/test/log_json_unittest.cpp
new file mode 100644
index 0000000..5759c25
--- /dev/null
+++ b/bmc/log-handler/test/log_json_unittest.cpp
@@ -0,0 +1,314 @@
+// Copyright 2021 Google Inc.
+//
+// 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 "general_systemd.hpp"
+#include "log_handlers_builder.hpp"
+#include "skip_action.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace ipmi_flash
+{
+namespace
+{
+using ::testing::IsEmpty;
+
+using json = nlohmann::json;
+
+TEST(LogJsonTest, ValidConfigurationNoLogHandler)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/sink_seq",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "systemd",
+ "unit" : "absolute"
+ }
+ }
+ }
+ }]
+ )"_json;
+ auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
+ ASSERT_THAT(h, ::testing::SizeIs(1));
+ EXPECT_THAT(h[0].blobId, "/log/sink_seq");
+ EXPECT_FALSE(h[0].actions == nullptr);
+ EXPECT_FALSE(h[0].handler == nullptr);
+}
+
+TEST(LogJsonTest, ValidConfigurationLogBlobName)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/log/sink_seq",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions": {
+ "open" : {
+ "type" : "systemd",
+ "unit" : "phosphor-ipmi-flash-log-sink-sequencer.target"
+ }
+ }
+ }
+ }]
+ )"_json;
+ auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
+ ASSERT_THAT(h, ::testing::SizeIs(1));
+ EXPECT_THAT(h[0].blobId, "/log/sink_seq");
+ EXPECT_FALSE(h[0].actions == nullptr);
+ EXPECT_FALSE(h[0].handler == nullptr);
+}
+
+TEST(LogJsonTest, MissingHandlerType)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/image",
+ "log":{
+ "handler": {
+ "path" : "/tmp/log_info"
+ },
+ "actions": {
+ "open" : {
+ "type" : "systemd",
+ "unit" : "absolute"}
+ }
+ }
+ }]
+ )"_json;
+ EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
+}
+
+TEST(LogJsonTest, BadBlobName)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/bad/image",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions": {
+ "open" : {
+ "type" : "systemd",
+ "unit" : "absolute"}
+ }
+ }
+ }]
+ )"_json;
+ EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
+}
+
+TEST(LogJsonTest, MissingActions)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/image",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ }
+ }
+ }]
+ )"_json;
+ EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
+}
+
+TEST(LogJsonTest, MissingOpenAction)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/image",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions": {}
+ }
+ }]
+ )"_json;
+ EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
+}
+
+TEST(LogJsonTest, OneInvalidTwoValidSucceeds)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/sink_seq0",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "systemd",
+ "unit" : "absolute"
+ }
+ }
+ }
+ },
+ {
+ "blob" : "/log/sink_seq1",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "systemd",
+ "unit" : "absolute"
+ }
+ }
+ }
+ },
+ {
+ "blob" : "/bad/sink_seq",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "systemd",
+ "unit" : "absolute"
+ }
+ }
+ }
+ }
+ ]
+ )"_json;
+ auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
+ ASSERT_THAT(h, ::testing::SizeIs(2));
+ EXPECT_THAT(h[0].blobId, "/log/sink_seq0");
+ EXPECT_THAT(h[1].blobId, "/log/sink_seq1");
+}
+
+TEST(LogJsonTest, BlobNameIsTooShort)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "systemd",
+ "unit" : "absolute"
+ }
+ }
+ }
+ }]
+ )"_json;
+ EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
+}
+
+TEST(LogJsonTest, OpenSkipAction)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/sink_seqs",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "skip"
+ }
+ }
+ }
+ }]
+ )"_json;
+ auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
+ EXPECT_THAT(h, ::testing::SizeIs(1));
+ EXPECT_TRUE(h[0].blobId == "/log/sink_seqs");
+ ASSERT_FALSE(h[0].actions == nullptr);
+ EXPECT_FALSE(h[0].actions->onOpen == nullptr);
+}
+
+TEST(LogJsonTest, OpenActionsWithDifferentModes)
+{
+ auto j2 = R"(
+ [{
+ "blob" : "/flash/blob1",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "systemd",
+ "unit" : "absolute",
+ "mode" : "replace-nope"
+ }
+ }
+ }
+ },
+ {
+ "blob" : "/flash/blob2",
+ "log":{
+ "handler": {
+ "type" : "file",
+ "path" : "/tmp/log_info"
+ },
+ "actions":{
+ "open" :{
+ "type" : "systemd",
+ "unit" : "absolute",
+ "mode" : "replace-fake"
+ }
+ }
+ }
+ }
+ ]
+ )"_json;
+ auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
+ ASSERT_THAT(h, ::testing::SizeIs(2));
+
+ EXPECT_FALSE(h[0].handler == nullptr);
+ EXPECT_FALSE(h[0].actions == nullptr);
+ EXPECT_THAT(h[0].blobId, "/log/blob1");
+ auto onOpen0 = reinterpret_cast<SystemdNoFile*>(h[0].actions->onOpen.get());
+ EXPECT_THAT(onOpen0->getMode(), "replace-nope");
+
+ EXPECT_FALSE(h[1].handler == nullptr);
+ EXPECT_FALSE(h[1].actions == nullptr);
+ EXPECT_THAT(h[1].blobId, "/log/blob2");
+ auto onOpen1 = reinterpret_cast<SystemdNoFile*>(h[1].actions->onOpen.get());
+ EXPECT_THAT(onOpen1->getMode(), "replace-fake");
+}
+} // namespace
+} // namespace ipmi_flash