blob: 256a83334044afc3b339b215de29521d209b94c1 [file] [log] [blame]
// Copyright 2022 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "vtpm/commands/virtualizer.h"
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <base/bind.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <trunks/mock_command_parser.h>
#include <trunks/mock_response_serializer.h>
#include <trunks/tpm_generated.h>
#include "vtpm/commands/mock_command.h"
namespace vtpm {
namespace {
using ::testing::_;
using ::testing::DoAll;
using ::testing::Pointee;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StrictMock;
using ::testing::WithArgs;
constexpr char kFakeRequest[] = "fake request";
constexpr char kTestResponse[] = "test response";
constexpr trunks::TPM_CC kTestCommandCode = trunks::TPM_CC_Sign;
constexpr trunks::TPM_CC kTestUnsupportedCommandCode =
trunks::TPM_CC_PCR_Allocate;
} // namespace
class VirtualizerTest : public testing::Test {
void SetUp() override {
std::unordered_map<trunks::TPM_CC, Command*> table;
table[kTestCommandCode] = &mock_command_;
virtualizer_ =
std::make_unique<Virtualizer>(&mock_cmd_parser_, &mock_resp_serializer_,
table, &mock_fallback_command_);
}
protected:
StrictMock<trunks::MockCommandParser> mock_cmd_parser_;
StrictMock<trunks::MockResponseSerializer> mock_resp_serializer_;
StrictMock<MockCommand> mock_command_;
StrictMock<MockCommand> mock_fallback_command_;
std::unique_ptr<Virtualizer> virtualizer_;
};
namespace {
TEST_F(VirtualizerTest, Delegate) {
std::string response;
CommandResponseCallback callback =
base::BindOnce([](std::string* resp_out,
const std::string& resp_in) { *resp_out = resp_in; },
&response);
EXPECT_CALL(mock_cmd_parser_,
ParseHeader(Pointee(std::string(kFakeRequest)), _, _, _))
.WillOnce(DoAll(SetArgPointee<3>(kTestCommandCode),
Return(trunks::TPM_RC_SUCCESS)));
EXPECT_CALL(mock_command_, Run(kFakeRequest, _))
.WillOnce(WithArgs<1>([](CommandResponseCallback callback) {
std::move(callback).Run(kTestResponse);
}));
virtualizer_->Run(kFakeRequest, std::move(callback));
EXPECT_EQ(response, kTestResponse);
}
TEST_F(VirtualizerTest, ParserError) {
std::string response;
CommandResponseCallback callback =
base::BindOnce([](std::string* resp_out,
const std::string& resp_in) { *resp_out = resp_in; },
&response);
const trunks::TPM_RC parser_rc = trunks::TPM_RC_INSUFFICIENT;
EXPECT_CALL(mock_cmd_parser_,
ParseHeader(Pointee(std::string(kFakeRequest)), _, _, _))
.WillOnce(Return(parser_rc));
EXPECT_CALL(mock_resp_serializer_, SerializeHeaderOnlyResponse(parser_rc, _))
.WillOnce(SetArgPointee<1>(kTestResponse));
virtualizer_->Run(kFakeRequest, std::move(callback));
EXPECT_EQ(response, kTestResponse);
}
TEST_F(VirtualizerTest, Fallback) {
std::string response;
CommandResponseCallback callback =
base::BindOnce([](std::string* resp_out,
const std::string& resp_in) { *resp_out = resp_in; },
&response);
EXPECT_CALL(mock_cmd_parser_,
ParseHeader(Pointee(std::string(kFakeRequest)), _, _, _))
.WillOnce(DoAll(SetArgPointee<3>(kTestUnsupportedCommandCode),
Return(trunks::TPM_RC_SUCCESS)));
EXPECT_CALL(mock_fallback_command_, Run(kFakeRequest, _))
.WillOnce(WithArgs<1>([](CommandResponseCallback callback) {
std::move(callback).Run(kTestResponse);
}));
virtualizer_->Run(kFakeRequest, std::move(callback));
EXPECT_EQ(response, kTestResponse);
}
} // namespace
} // namespace vtpm