This is an automated email from the ASF dual-hosted git repository.

asekretenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 9bb35fe23fed7756af9ceebccea74bf175fa6e47
Author: Andrei Sekretenko <asekrete...@mesosphere.com>
AuthorDate: Mon Aug 31 18:34:00 2020 +0200

    Extracted FrameworkInfo comparison logic from tests.
    
    This patch extracts the code that performs `FrameworkInfo` comparison
    via protobuf `MessageDifferencer` from the framework update tests
    into a set of general-purpose methods.
    
    Review: https://reviews.apache.org/r/72822
---
 include/mesos/type_utils.hpp                | 15 ++++++++
 include/mesos/v1/mesos.hpp                  | 15 ++++++++
 src/Makefile.am                             |  1 +
 src/common/type_utils.cpp                   | 29 ++++++++++++++++
 src/common/type_utils_differencers.hpp      | 53 ++++++++++++++++++++++++++++
 src/tests/master/update_framework_tests.cpp | 54 ++++++++++-------------------
 src/v1/mesos.cpp                            | 30 ++++++++++++++++
 7 files changed, 161 insertions(+), 36 deletions(-)

diff --git a/include/mesos/type_utils.hpp b/include/mesos/type_utils.hpp
index da9fd96..2745ff0 100644
--- a/include/mesos/type_utils.hpp
+++ b/include/mesos/type_utils.hpp
@@ -30,6 +30,7 @@
 
 #include <mesos/mesos.hpp>
 
+#include <stout/option.hpp>
 #include <stout/stringify.hpp>
 #include <stout/strings.hpp>
 #include <stout/uuid.hpp>
@@ -121,6 +122,20 @@ inline bool operator==(const FrameworkInfo& left, const 
FrameworkInfo& right)
 }
 
 
+namespace typeutils {
+
+// Returns whether two `FrameworkInfo`s are equivalent for framework
+// subscription purposes or not (i.e. whether subscribing a framework with the
+// `left` should have the same effects as with the `right`).
+bool equivalent(const FrameworkInfo& left, const FrameworkInfo& right);
+
+// Performs the same comparison as `equivalent()` and returns a human-readable
+// diff if the `FrameworkInfo`s are not equivalnt.
+Option<std::string> diff(const FrameworkInfo& left, const FrameworkInfo& 
right);
+
+} // namespace typeutils {
+
+
 inline bool operator==(const OfferID& left, const OfferID& right)
 {
   return left.value() == right.value();
diff --git a/include/mesos/v1/mesos.hpp b/include/mesos/v1/mesos.hpp
index d8304f1..853330a 100644
--- a/include/mesos/v1/mesos.hpp
+++ b/include/mesos/v1/mesos.hpp
@@ -25,6 +25,7 @@
 
 #include <mesos/v1/mesos.pb.h> // ONLY USEFUL AFTER RUNNING PROTOC.
 
+#include <stout/option.hpp>
 #include <stout/strings.hpp>
 
 // This file includes definitions for operators on public protobuf
@@ -105,6 +106,20 @@ inline bool operator==(const FrameworkInfo& left, const 
FrameworkInfo& right)
 }
 
 
+namespace typeutils {
+
+// Returns whether two `FrameworkInfo`s are equivalent for framework
+// subscription purposes or not (i.e. whether subscribing a framework with the
+// `left` should have the same effects as with the `right`).
+bool equivalent(const FrameworkInfo& left, const FrameworkInfo& right);
+
+// Performs the same comparison as `equivalent()` and returns a human-readable
+// diff if the `FrameworkInfo`s are not equivalnt.
+Option<std::string> diff(const FrameworkInfo& left, const FrameworkInfo& 
right);
+
+} // namespace typeutils {
+
+
 inline bool operator==(const OfferID& left, const OfferID& right)
 {
   return left.value() == right.value();
diff --git a/src/Makefile.am b/src/Makefile.am
index 1043c7b..673ea6c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1091,6 +1091,7 @@ libmesos_no_3rdparty_la_SOURCES +=                        
                \
   common/resources_utils.hpp                                           \
   common/roles.cpp                                                     \
   common/status_utils.hpp                                              \
+  common/type_utils_differencers.hpp                                   \
   common/type_utils.cpp                                                        
\
   common/validation.cpp                                                        
\
   common/validation.hpp                                                        
\
diff --git a/src/common/type_utils.cpp b/src/common/type_utils.cpp
index bb43784..899fd6d 100644
--- a/src/common/type_utils.cpp
+++ b/src/common/type_utils.cpp
@@ -26,10 +26,14 @@
 #include <stout/protobuf.hpp>
 
 #include "messages/messages.hpp"
+#include "common/type_utils_differencers.hpp"
 
 using std::ostream;
 using std::string;
 using std::vector;
+using std::unique_ptr;
+
+using ::mesos::typeutils::internal::createFrameworkInfoDifferencer;
 
 namespace mesos {
 
@@ -678,6 +682,31 @@ bool operator!=(const CheckStatusInfo& left, const 
CheckStatusInfo& right)
 }
 
 
+namespace typeutils {
+
+bool equivalent(const FrameworkInfo& left, const FrameworkInfo& right)
+{
+  return createFrameworkInfoDifferencer<FrameworkInfo>()->Compare(left, right);
+}
+
+
+Option<string> diff(const FrameworkInfo& left, const FrameworkInfo& right)
+{
+  unique_ptr<::google::protobuf::util::MessageDifferencer> differencer{
+    createFrameworkInfoDifferencer<FrameworkInfo>()};
+
+  string result;
+  differencer->ReportDifferencesToString(&result);
+  if (differencer->Compare(left, right)) {
+    return None();
+  }
+
+  return result;
+}
+
+} // namespace typeutils {
+
+
 ostream& operator<<(ostream& stream, const CapabilityInfo& capabilityInfo)
 {
   return stream << JSON::protobuf(capabilityInfo);
diff --git a/src/common/type_utils_differencers.hpp 
b/src/common/type_utils_differencers.hpp
new file mode 100644
index 0000000..b106014
--- /dev/null
+++ b/src/common/type_utils_differencers.hpp
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 <memory>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/util/message_differencer.h>
+
+namespace mesos {
+namespace typeutils {
+namespace internal {
+
+// Creates a protobuf `MessageDifferencer` specifically configured for
+// comparing `FrameworkInfo`s (either V0 or V1 ones).
+//
+// TODO(asekretenko): Remove the `unique_ptr` wrapper if `MessageDifferencer`
+// becomes move-constructible in future versions of protobuf.
+template <class TFrameworkInfo>
+std::unique_ptr<::google::protobuf::util::MessageDifferencer>
+createFrameworkInfoDifferencer()
+{
+  static const ::google::protobuf::Descriptor* descriptor =
+    TFrameworkInfo::descriptor();
+
+  CHECK_EQ(13, descriptor->field_count())
+    << "After adding a field to FrameworkInfo, please make sure "
+    << "that FrameworkInfoDifferencer handles this field properly;"
+    << "after that, adjust the expected fields count in this check.";
+
+  std::unique_ptr<::google::protobuf::util::MessageDifferencer> differencer{
+    new ::google::protobuf::util::MessageDifferencer()};
+
+  differencer->TreatAsSet(descriptor->FindFieldByName("capabilities"));
+  differencer->TreatAsSet(descriptor->FindFieldByName("roles"));
+  return differencer;
+}
+
+} // namespace internal {
+} // namespace typeutils {
+} // namespace mesos {
diff --git a/src/tests/master/update_framework_tests.cpp 
b/src/tests/master/update_framework_tests.cpp
index d2a63b6..34e5a70 100644
--- a/src/tests/master/update_framework_tests.cpp
+++ b/src/tests/master/update_framework_tests.cpp
@@ -19,8 +19,6 @@
 
 #include <gmock/gmock.h>
 
-#include <google/protobuf/util/message_differencer.h>
-
 #include <mesos/executor.hpp>
 
 #include <mesos/v1/mesos.hpp>
@@ -119,28 +117,6 @@ static TFrameworkInfo changeAllMutableFields(const 
TFrameworkInfo& oldInfo)
   return newInfo;
 }
 
-
-template <class TFrameworkInfo>
-static Option<std::string> diff(
-    const TFrameworkInfo& lhs, const TFrameworkInfo& rhs)
-{
-  const google::protobuf::Descriptor* descriptor = 
TFrameworkInfo::descriptor();
-  google::protobuf::util::MessageDifferencer differencer;
-
-  differencer.TreatAsSet(descriptor->FindFieldByName("capabilities"));
-  differencer.TreatAsSet(descriptor->FindFieldByName("roles"));
-
-  string result;
-  differencer.ReportDifferencesToString(&result);
-
-  if (differencer.Compare(lhs, rhs)) {
-    return None();
-  }
-
-  return result;
-}
-
-
 namespace v1 {
 
 
@@ -257,10 +233,11 @@ TEST_F(UpdateFrameworkTest, UserChangeFails)
 
   FrameworkInfo expected = DEFAULT_FRAMEWORK_INFO;
   *expected.mutable_id() = subscribed->framework_id();
-  EXPECT_NONE(diff(frameworks->frameworks(0).framework_info(), expected));
+  EXPECT_NONE(::mesos::v1::typeutils::diff(
+      frameworks->frameworks(0).framework_info(), expected));
 
   // Sanity check for diff()
-  EXPECT_SOME(diff(update, expected));
+  EXPECT_SOME(::mesos::v1::typeutils::diff(update, expected));
 }
 
 
@@ -307,10 +284,11 @@ TEST_F(UpdateFrameworkTest, PrincipalChangeFails)
 
   FrameworkInfo expected = DEFAULT_FRAMEWORK_INFO;
   *expected.mutable_id() = subscribed->framework_id();
-  EXPECT_NONE(diff(frameworks->frameworks(0).framework_info(), expected));
+  EXPECT_NONE(::mesos::v1::typeutils::diff(
+      frameworks->frameworks(0).framework_info(), expected));
 
   // Sanity check for diff()
-  EXPECT_SOME(diff(update, expected));
+  EXPECT_SOME(::mesos::v1::typeutils::diff(update, expected));
 }
 
 
@@ -358,10 +336,11 @@ TEST_F(UpdateFrameworkTest, CheckpointingChangeFails)
 
   FrameworkInfo expected = DEFAULT_FRAMEWORK_INFO;
   *expected.mutable_id() = subscribed->framework_id();
-  EXPECT_NONE(diff(frameworks->frameworks(0).framework_info(), expected));
+  EXPECT_NONE(::mesos::v1::typeutils::diff(
+      frameworks->frameworks(0).framework_info(), expected));
 
   // Sanity check for diff()
-  EXPECT_SOME(diff(update, expected));
+  EXPECT_SOME(::mesos::v1::typeutils::diff(update, expected));
 }
 
 
@@ -446,13 +425,15 @@ TEST_F(UpdateFrameworkTest, 
MutableFieldsUpdateSuccessfully)
   const FrameworkInfo& frameworkInfo =
     frameworks->frameworks(0).framework_info();
 
-  EXPECT_NONE(diff(frameworkInfo, update));
+  EXPECT_NONE(::mesos::v1::typeutils::diff(frameworkInfo, update));
 
   AWAIT_READY(updateFrameworkMessage);
-  EXPECT_NONE(diff(evolve(updateFrameworkMessage->framework_info()), update));
+  EXPECT_NONE(::mesos::v1::typeutils::diff(
+      evolve(updateFrameworkMessage->framework_info()), update));
 
   AWAIT_READY(frameworkUpdated);
-  EXPECT_NONE(diff(frameworkUpdated->framework().framework_info(), update));
+  EXPECT_NONE(::mesos::v1::typeutils::diff(
+      frameworkUpdated->framework().framework_info(), update));
 };
 
 
@@ -995,10 +976,11 @@ TEST_F(UpdateFrameworkV0Test, 
MutableFieldsUpdateSuccessfully)
 
   AWAIT_READY(updateFrameworkMessage);
 
-  EXPECT_NONE(diff(updateFrameworkMessage->framework_info(), update));
+  EXPECT_NONE(::mesos::typeutils::diff(
+      updateFrameworkMessage->framework_info(), update));
 
   AWAIT_READY(frameworkUpdated);
-  EXPECT_NONE(diff(
+  EXPECT_NONE(::mesos::typeutils::diff(
       devolve(frameworkUpdated->framework().framework_info()), update));
 
   Future<v1::master::Response::GetFrameworks> frameworks =
@@ -1008,7 +990,7 @@ TEST_F(UpdateFrameworkV0Test, 
MutableFieldsUpdateSuccessfully)
   const FrameworkInfo& reportedFrameworkInfo =
     devolve(frameworks->frameworks(0).framework_info());
 
-  EXPECT_NONE(diff(reportedFrameworkInfo, update));
+  EXPECT_NONE(::mesos::typeutils::diff(reportedFrameworkInfo, update));
 
   driver.stop();
   driver.join();
diff --git a/src/v1/mesos.cpp b/src/v1/mesos.cpp
index c2fb528..6e412e0 100644
--- a/src/v1/mesos.cpp
+++ b/src/v1/mesos.cpp
@@ -25,9 +25,14 @@
 #include <mesos/v1/mesos.hpp>
 #include <mesos/v1/resources.hpp>
 
+#include "common/type_utils_differencers.hpp"
+
 using std::ostream;
 using std::string;
 using std::vector;
+using std::unique_ptr;
+
+using ::mesos::typeutils::internal::createFrameworkInfoDifferencer;
 
 namespace mesos {
 namespace v1 {
@@ -506,6 +511,31 @@ bool operator!=(const TaskStatus& left, const TaskStatus& 
right)
 }
 
 
+namespace typeutils {
+
+bool equivalent(const FrameworkInfo& left, const FrameworkInfo& right)
+{
+  return createFrameworkInfoDifferencer<FrameworkInfo>()->Compare(left, right);
+}
+
+
+Option<string> diff(const FrameworkInfo& left, const FrameworkInfo& right)
+{
+  unique_ptr<::google::protobuf::util::MessageDifferencer> differencer{
+    createFrameworkInfoDifferencer<FrameworkInfo>()};
+
+  string result;
+  differencer->ReportDifferencesToString(&result);
+  if (differencer->Compare(left, right)) {
+    return None();
+  }
+
+  return result;
+}
+
+} // namespace typeutils {
+
+
 ostream& operator<<(ostream& stream, const CapabilityInfo& capabilityInfo)
 {
   return stream << JSON::protobuf(capabilityInfo);

Reply via email to