blob: 69d3297b5fc0f31bcd1ced62ac85ca506bd38b46 [file] [log] [blame]
// Copyright 2021 Google LLC
//
// 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 "tink/util/secret_proto.h"
#include <string>
#include <utility>
#include "google/protobuf/util/message_differencer.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/memory/memory.h"
#include "proto/test_proto.pb.h"
namespace crypto {
namespace tink {
namespace util {
namespace {
using ::google::crypto::tink::NestedTestProto;
using ::google::crypto::tink::TestProto;
using ::google::protobuf::util::MessageDifferencer;
template <typename T>
class SecretProtoTest : public testing::Test {};
using MyTypes = ::testing::Types<NestedTestProto, TestProto>;
TYPED_TEST_SUITE(SecretProtoTest, MyTypes);
template <typename T>
T CreateProto();
template <>
TestProto CreateProto<TestProto>() {
TestProto proto;
proto.set_num(123);
proto.set_str("Single proto");
return proto;
}
template <>
NestedTestProto CreateProto<NestedTestProto>() {
NestedTestProto proto;
proto.mutable_a()->set_num(12);
proto.mutable_a()->set_str("A proto");
proto.mutable_b()->set_num(14);
proto.mutable_b()->set_str("B proto");
proto.set_num(42);
proto.set_str("Main proto");
return proto;
}
TYPED_TEST(SecretProtoTest, DefaultConstructor) {
SecretProto<TypeParam> s;
EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()));
}
TYPED_TEST(SecretProtoTest, Constructor) {
TypeParam proto = CreateProto<TypeParam>();
SecretProto<TypeParam> s(proto);
EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
}
TYPED_TEST(SecretProtoTest, CopyConstructor) {
TypeParam proto = CreateProto<TypeParam>();
SecretProto<TypeParam> s(proto);
SecretProto<TypeParam> t(s);
EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}
TYPED_TEST(SecretProtoTest, SourceDestroyedAfterCopyConstructor) {
TypeParam proto = CreateProto<TypeParam>();
auto s = absl::make_unique<SecretProto<TypeParam>>(proto);
SecretProto<TypeParam> t(*s);
EXPECT_TRUE(MessageDifferencer::Equals(**s, proto));
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
// Test with source destroyed after the copy
s.reset();
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}
TYPED_TEST(SecretProtoTest, AssignmentOperator) {
TypeParam proto = CreateProto<TypeParam>();
SecretProto<TypeParam> t;
{
SecretProto<TypeParam> s(proto);
t = s;
EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}
// Test with source destroyed after the copy
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}
TYPED_TEST(SecretProtoTest, MoveConstructor) {
TypeParam proto = CreateProto<TypeParam>();
SecretProto<TypeParam> s(proto);
SecretProto<TypeParam> t(std::move(s));
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
// NOLINTNEXTLINE: bugprone-use-after-move
EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()) ||
MessageDifferencer::Equals(*s, proto));
}
TYPED_TEST(SecretProtoTest, MoveAssignment) {
TypeParam proto = CreateProto<TypeParam>();
SecretProto<TypeParam> t;
{
SecretProto<TypeParam> s(proto);
t = std::move(s);
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
// NOLINTNEXTLINE: bugprone-use-after-move
EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()) ||
MessageDifferencer::Equals(*s, proto));
}
// Test with source destroyed after the move
EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}
TYPED_TEST(SecretProtoTest, FromSecretData) {
TypeParam proto = CreateProto<TypeParam>();
SecretData data;
data.resize(proto.ByteSizeLong());
ASSERT_TRUE(proto.SerializeToArray(data.data(), data.size()));
StatusOr<SecretProto<TypeParam>> secret_proto =
SecretProto<TypeParam>::ParseFromSecretData(data);
ASSERT_TRUE(secret_proto.ok()) << secret_proto.status();
EXPECT_TRUE(MessageDifferencer::Equals(**secret_proto, proto));
}
TYPED_TEST(SecretProtoTest, AsSecretData) {
TypeParam proto = CreateProto<TypeParam>();
std::string serialized = proto.SerializeAsString();
SecretProto<TypeParam> secret_proto(proto);
StatusOr<SecretData> secret_serialized = secret_proto.SerializeAsSecretData();
ASSERT_TRUE(secret_serialized.ok()) << secret_serialized.status();
EXPECT_EQ(serialized, SecretDataAsStringView(*secret_serialized));
}
} // namespace
} // namespace util
} // namespace tink
} // namespace crypto