1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <thrift/conformance/cpp2/Any.h>
18 
19 #include <folly/portability/GTest.h>
20 #include <thrift/conformance/cpp2/Protocol.h>
21 #include <thrift/conformance/cpp2/Testing.h>
22 
23 namespace apache::thrift::conformance {
24 namespace {
25 
TEST(AnyTest,SetProtocol)26 TEST(AnyTest, SetProtocol) {
27   Any any;
28   Protocol customProtocol("Hi");
29   setProtocol(customProtocol, any);
30   EXPECT_TRUE(hasProtocol(any, customProtocol));
31   EXPECT_EQ(getProtocol(any), customProtocol);
32   EXPECT_TRUE(any.customProtocol_ref().has_value());
33   EXPECT_TRUE(any.protocol_ref().has_value());
34 
35   setProtocol(getStandardProtocol<StandardProtocol::Compact>(), any);
36   EXPECT_TRUE(
37       hasProtocol(any, getStandardProtocol<StandardProtocol::Compact>()));
38   EXPECT_EQ(getProtocol(any), getStandardProtocol<StandardProtocol::Compact>());
39   EXPECT_FALSE(any.customProtocol_ref().has_value());
40   EXPECT_FALSE(any.protocol_ref().has_value());
41 
42   setProtocol(customProtocol, any);
43   EXPECT_TRUE(any.customProtocol_ref().has_value());
44   EXPECT_TRUE(any.protocol_ref().has_value());
45 
46   setProtocol(getStandardProtocol<StandardProtocol::Binary>(), any);
47   EXPECT_TRUE(
48       hasProtocol(any, getStandardProtocol<StandardProtocol::Binary>()));
49   EXPECT_EQ(getProtocol(any), getStandardProtocol<StandardProtocol::Binary>());
50   EXPECT_FALSE(any.customProtocol_ref().has_value());
51   EXPECT_TRUE(any.protocol_ref().has_value());
52 }
53 
TEST(AnyTest,None)54 TEST(AnyTest, None) {
55   Any any;
56   validateAny(any);
57   EXPECT_EQ(getProtocol(any), getStandardProtocol<StandardProtocol::Compact>());
58   any.set_protocol(StandardProtocol::Custom);
59   validateAny(any);
60   EXPECT_EQ(getProtocol(any), getStandardProtocol<StandardProtocol::Custom>());
61   any.set_customProtocol("");
62   validateAny(any);
63   EXPECT_EQ(getProtocol(any), getStandardProtocol<StandardProtocol::Custom>());
64 
65   any.set_customProtocol("Custom");
66   EXPECT_NE(getProtocol(any), getStandardProtocol<StandardProtocol::Custom>());
67   EXPECT_THROW(validateAny(any), std::invalid_argument);
68 }
69 
TEST(AnyTest,Standard)70 TEST(AnyTest, Standard) {
71   Any any;
72   any.set_protocol(StandardProtocol::Binary);
73   EXPECT_EQ(getProtocol(any), getStandardProtocol<StandardProtocol::Binary>());
74   EXPECT_TRUE(
75       hasProtocol(any, getStandardProtocol<StandardProtocol::Binary>()));
76 
77   // Junk in the customProtocol.
78   any.set_customProtocol("Ignored");
79   EXPECT_EQ(getProtocol(any), getStandardProtocol<StandardProtocol::Binary>());
80   EXPECT_TRUE(
81       hasProtocol(any, getStandardProtocol<StandardProtocol::Binary>()));
82 
83   // Unnormalize name.
84   any.set_protocol(StandardProtocol::Custom);
85   any.set_customProtocol("Binary");
86   EXPECT_NE(getProtocol(any), getStandardProtocol<StandardProtocol::Binary>());
87   EXPECT_THROW(validateAny(any), std::invalid_argument);
88 }
89 
TEST(AnyTest,Custom)90 TEST(AnyTest, Custom) {
91   Any any;
92   any.set_protocol(StandardProtocol::Custom);
93   any.set_customProtocol("Hi");
94   EXPECT_EQ(getProtocol(any), Protocol("Hi"));
95   EXPECT_TRUE(hasProtocol(any, Protocol("Hi")));
96   EXPECT_NE(getProtocol(any), Protocol("Bye"));
97   EXPECT_FALSE(hasProtocol(any, Protocol("Bye")));
98   EXPECT_NE(getProtocol(any), Protocol(StandardProtocol::Custom));
99   EXPECT_FALSE(hasProtocol(any, Protocol(StandardProtocol::Custom)));
100   EXPECT_NE(getProtocol(any), Protocol(StandardProtocol::Binary));
101   EXPECT_FALSE(hasProtocol(any, Protocol(StandardProtocol::Binary)));
102 }
103 
TEST(AnyTest,Unknown)104 TEST(AnyTest, Unknown) {
105   Any any;
106   any.set_protocol(kUnknownStdProtocol);
107   EXPECT_EQ(getProtocol(any), UnknownProtocol());
108   EXPECT_TRUE(hasProtocol(any, UnknownProtocol()));
109   EXPECT_EQ(getProtocol(any).name(), "");
110 }
111 
TEST(AnyTest,Custom_EmptyString)112 TEST(AnyTest, Custom_EmptyString) {
113   Any any;
114   // Empty string protocol is the same as None
115   any.set_protocol(StandardProtocol::Custom);
116   any.set_customProtocol("");
117   EXPECT_TRUE(any.customProtocol_ref().has_value());
118   EXPECT_EQ(getProtocol(any), kNoProtocol);
119   EXPECT_TRUE(hasProtocol(any, kNoProtocol));
120 }
121 
TEST(AnyTest,ValidateAny)122 TEST(AnyTest, ValidateAny) {
123   const auto bad = "foo.com:42/my/type";
124   const auto good = "foo.com/my/type";
125   Any any;
126   validateAny(any);
127   any.set_type("");
128   any.set_customProtocol("");
129   validateAny(any);
130   any.type_ref().ensure() = bad;
131   EXPECT_THROW(validateAny(any), std::invalid_argument);
132   any.type_ref() = good;
133   any.customProtocol_ref().ensure() = bad;
134   EXPECT_THROW(validateAny(any), std::invalid_argument);
135   any.customProtocol_ref() = good;
136   validateAny(any);
137 }
138 
139 } // namespace
140 } // namespace apache::thrift::conformance
141