// 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 #include #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 class SecretProtoTest : public testing::Test {}; using MyTypes = ::testing::Types; TYPED_TEST_SUITE(SecretProtoTest, MyTypes); template T CreateProto(); template <> TestProto CreateProto() { TestProto proto; proto.set_num(123); proto.set_str("Single proto"); return proto; } template <> NestedTestProto CreateProto() { 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 s; EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam())); } TYPED_TEST(SecretProtoTest, Constructor) { TypeParam proto = CreateProto(); SecretProto s(proto); EXPECT_TRUE(MessageDifferencer::Equals(*s, proto)); } TYPED_TEST(SecretProtoTest, CopyConstructor) { TypeParam proto = CreateProto(); SecretProto s(proto); SecretProto t(s); EXPECT_TRUE(MessageDifferencer::Equals(*s, proto)); EXPECT_TRUE(MessageDifferencer::Equals(*t, proto)); } TYPED_TEST(SecretProtoTest, SourceDestroyedAfterCopyConstructor) { TypeParam proto = CreateProto(); auto s = absl::make_unique>(proto); SecretProto 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(); SecretProto t; { SecretProto 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(); SecretProto s(proto); SecretProto 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(); SecretProto t; { SecretProto 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(); SecretData data; data.resize(proto.ByteSizeLong()); ASSERT_TRUE(proto.SerializeToArray(data.data(), data.size())); StatusOr> secret_proto = SecretProto::ParseFromSecretData(data); ASSERT_TRUE(secret_proto.ok()) << secret_proto.status(); EXPECT_TRUE(MessageDifferencer::Equals(**secret_proto, proto)); } TYPED_TEST(SecretProtoTest, AsSecretData) { TypeParam proto = CreateProto(); std::string serialized = proto.SerializeAsString(); SecretProto secret_proto(proto); StatusOr 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