00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __OPC_UA_TESTS_COMMON_H__
00012 #define __OPC_UA_TESTS_COMMON_H__
00013
00014
00015 #include <gtest/gtest.h>
00016
00017 #include <opc/ua/protocol/extension_identifiers.h>
00018 #include <opc/ua/protocol/message_identifiers.h>
00019 #include <opc/ua/protocol/binary/stream.h>
00020 #include <opc/ua/protocol/secure_channel.h>
00021 #include <opc/ua/protocol/types.h>
00022 #include <opc/ua/protocol/protocol.h>
00023
00024 #include <algorithm>
00025 #include <stdexcept>
00026 #include <stdlib.h>
00027 #include <string>
00028
00029 inline std::string PrintData(const std::vector<char>& vec)
00030 {
00031 std::stringstream stream;
00032 for (std::size_t i = 0; i < vec.size(); ++i)
00033 {
00034 stream << "0x" << std::setfill('0') << std::setw(2) << std::hex << ((int)vec[i] & 0xff) << ' ';
00035 if ((i + 1) % 4 == 0)
00036 {
00037 stream << ' ';
00038 }
00039
00040 if ((i + 1) % 32 == 0)
00041 {
00042 stream << std::endl;
00043 }
00044 }
00045 return stream.str();
00046 }
00047
00048 inline std::string GetHost()
00049 {
00050 if (const char* host = getenv("OPCUA_HOST"))
00051 {
00052 return host;
00053 }
00054 return "localhost";
00055 }
00056
00057 inline int GetPort()
00058 {
00059 if (char* port = getenv("OPCUA_PORT"))
00060 {
00061 return atoi(port);
00062 }
00063 return 4841;
00064 }
00065
00066 inline std::string GetEndpoint()
00067 {
00068 if (char* endpoint = getenv("OPCUA_ENDPOINT"))
00069 {
00070 return endpoint;
00071 }
00072 return "opc.tcp://localhost:4841";
00073 }
00074
00075 class OutputChannel
00076 {
00077 public:
00078 virtual void Send(const char* data, std::size_t size)
00079 {
00080 SerializedData = std::vector<char>(data, data + size);
00081 }
00082
00083 virtual ~OutputChannel()
00084 {
00085 }
00086
00087 std::vector<char> SerializedData;
00088 };
00089
00090 typedef OpcUa::Binary::OStream<OutputChannel> BinaryOStream;
00091
00092 class OpcUaBinarySerialization : public ::testing::Test
00093 {
00094 public:
00095 OpcUaBinarySerialization()
00096 : Channel(new OutputChannel)
00097 , Stream(new BinaryOStream(Channel))
00098 {
00099 }
00100
00101 protected:
00102 virtual void SetUp()
00103 {
00104 }
00105
00106 virtual void TearDown()
00107 {
00108 }
00109
00110 OutputChannel& GetChannel()
00111 {
00112 return *Channel;
00113 }
00114
00115 BinaryOStream& GetStream()
00116 {
00117 return *Stream;
00118 }
00119
00120 private:
00121 std::shared_ptr<OutputChannel> Channel;
00122 std::unique_ptr<BinaryOStream> Stream;
00123 };
00124
00125 class InputChannel
00126 {
00127 public:
00128 InputChannel()
00129 {
00130 CurPos = SerializedData.begin();
00131 }
00132
00133 virtual ~InputChannel()
00134 {
00135 }
00136
00137 virtual std::size_t Receive(char* data, std::size_t size)
00138 {
00139 if (CurPos == SerializedData.end())
00140 {
00141 return 0;
00142 }
00143 const std::size_t dist = static_cast<std::size_t>(std::distance(CurPos, SerializedData.end()));
00144 const std::size_t minSize = std::min(size, dist);
00145 std::copy(CurPos, CurPos + minSize, data);
00146 CurPos+=minSize;
00147 return minSize;
00148 }
00149
00150 void SetData(const std::vector<char>& data)
00151 {
00152 SerializedData = data;
00153 CurPos = SerializedData.begin();
00154 }
00155
00156 bool IsEmpty() const
00157 {
00158 return CurPos == SerializedData.end();
00159 }
00160
00161 private:
00162 std::vector<char> SerializedData;
00163 std::vector<char>::iterator CurPos;
00164 };
00165
00166
00167 typedef OpcUa::Binary::IStream<InputChannel> BinaryIStream;
00168
00169 class OpcUaBinaryDeserialization : public ::testing::Test
00170 {
00171 public:
00172 OpcUaBinaryDeserialization()
00173 : Channel(new InputChannel)
00174 , Stream(new BinaryIStream(Channel))
00175 {
00176 }
00177
00178 protected:
00179 virtual void SetUp()
00180 {
00181 }
00182
00183 virtual void TearDown()
00184 {
00185 }
00186
00187 InputChannel& GetChannel()
00188 {
00189 return *Channel;
00190 }
00191
00192 BinaryIStream& GetStream()
00193 {
00194 return *Stream;
00195 }
00196
00197 protected:
00198 std::shared_ptr<InputChannel> Channel;
00199 std::unique_ptr<BinaryIStream> Stream;
00200 };
00201
00202
00203
00204
00205 #define TEST_RESPONSE_HEADER_BINARY_DATA \
00206 1,0,0,0,0,0,0,0, \
00207 2,0,0,0, \
00208 3,0,0,0, \
00209 static_cast<DiagnosticInfoMask>(DIM_LOCALIZED_TEXT | DIM_INNER_DIAGNOSTIC_INFO), 4,0,0,0, \
00210 DIM_ADDITIONAL_INFO, 3, 0, 0, 0, 'a', 'd', 'd', \
00211 2,0,0,0, 3,0,0,0, 's','t','r', 3,0,0,0, 's','t','r', \
00212 EV_TWO_BYTE, 7, \
00213 8
00214
00215 #define FILL_TEST_RESPONSE_HEADER(header) \
00216 header.Timestamp.Value = 1; \
00217 header.RequestHandle = 2; \
00218 header.ServiceResult = static_cast<StatusCode>(3); \
00219 header.InnerDiagnostics.EncodingMask = static_cast<DiagnosticInfoMask>(DIM_LOCALIZED_TEXT | DIM_INNER_DIAGNOSTIC_INFO); \
00220 header.InnerDiagnostics.LocalizedText = 4; \
00221 header.InnerDiagnostics.InnerDiagnostics.reset(new DiagnosticInfo()); \
00222 header.InnerDiagnostics.InnerDiagnostics->EncodingMask = DIM_ADDITIONAL_INFO; \
00223 header.InnerDiagnostics.InnerDiagnostics->AdditionalInfo = "add"; \
00224 header.StringTable = std::vector<std::string>(2, std::string("str")); \
00225 header.Additional.TypeId.Encoding = EV_TWO_BYTE; \
00226 header.Additional.TypeId.TwoByteData.Identifier = 7; \
00227 header.Additional.Encoding = 8;
00228
00229 #define ASSERT_RESPONSE_HEADER_EQ(header) \
00230 ASSERT_EQ(header.Timestamp.Value, 1); \
00231 ASSERT_EQ(header.RequestHandle, 2); \
00232 ASSERT_EQ(header.ServiceResult, static_cast<StatusCode>(3)); \
00233 ASSERT_EQ(header.InnerDiagnostics.EncodingMask, static_cast<DiagnosticInfoMask>(DIM_LOCALIZED_TEXT | DIM_INNER_DIAGNOSTIC_INFO)); \
00234 ASSERT_EQ(header.InnerDiagnostics.LocalizedText, 4); \
00235 ASSERT_TRUE(static_cast<bool>(header.InnerDiagnostics.InnerDiagnostics)); \
00236 ASSERT_EQ(header.InnerDiagnostics.InnerDiagnostics->EncodingMask, DIM_ADDITIONAL_INFO); \
00237 ASSERT_EQ(header.InnerDiagnostics.InnerDiagnostics->AdditionalInfo, "add"); \
00238 ASSERT_EQ(header.StringTable, std::vector<std::string>(2, std::string("str"))); \
00239 ASSERT_EQ(header.Additional.TypeId.Encoding, EV_TWO_BYTE); \
00240 ASSERT_EQ(header.Additional.TypeId.TwoByteData.Identifier, 7); \
00241 ASSERT_EQ(header.Additional.Encoding, 8);
00242
00243
00244 #define TEST_REQUEST_HEADER_BINARY_DATA \
00245 EV_TWO_BYTE, 1, \
00246 2, 0, 0, 0, 0, 0, 0, 0, \
00247 3, 0, 0, 0, \
00248 4, 0, 0, 0, \
00249 5, 0, 0, 0, \
00250 'a', 'u', 'd', 'i', 't', \
00251 5, 0, 0, 0, \
00252 0, \
00253 6, \
00254 8
00255
00256 #define FILL_TEST_REQUEST_HEADER(header) \
00257 header.SessionAuthenticationToken.Encoding = EV_TWO_BYTE; \
00258 header.SessionAuthenticationToken.TwoByteData.Identifier = 1; \
00259 header.UtcTime.Value = 2; \
00260 header.RequestHandle = 3; \
00261 header.ReturnDiagnostics = 4; \
00262 header.AuditEntryId = "audit"; \
00263 header.Timeout = 5; \
00264 header.Additional.TypeId.Encoding = EV_TWO_BYTE; \
00265 header.Additional.TypeId.TwoByteData.Identifier = 6; \
00266 header.Additional.Encoding = 8;
00267
00268 #define ASSERT_REQUEST_HEADER_EQ(header) \
00269 ASSERT_EQ(header.SessionAuthenticationToken.Encoding, EV_TWO_BYTE); \
00270 ASSERT_EQ(header.SessionAuthenticationToken.TwoByteData.Identifier, 1); \
00271 ASSERT_EQ(header.UtcTime.Value, 2); \
00272 ASSERT_EQ(header.RequestHandle, 3); \
00273 ASSERT_EQ(header.ReturnDiagnostics, 4); \
00274 ASSERT_EQ(header.AuditEntryId, "audit"); \
00275 ASSERT_EQ(header.Timeout, 5); \
00276 ASSERT_EQ(header.Additional.TypeId.Encoding, EV_TWO_BYTE); \
00277 ASSERT_EQ(header.Additional.TypeId.TwoByteData.Identifier, 6); \
00278 ASSERT_EQ(header.Additional.Encoding, 8);
00279
00280
00281 #define FILL_APPLICATION_DESCRIPTION(desc) \
00282 desc.ApplicationUri = "u"; \
00283 desc.ProductUri = "pu"; \
00284 desc.ApplicationName.Encoding = HAS_LOCALE | HAS_TEXT; \
00285 desc.ApplicationName.Locale = "RU"; \
00286 desc.ApplicationName.Text = "text"; \
00287 desc.ApplicationType = ApplicationType::Client; \
00288 desc.GatewayServerUri = "gw"; \
00289 desc.DiscoveryProfileUri = "dpu"; \
00290 desc.DiscoveryUrls.push_back("du");
00291
00292 #define TEST_APPLICATION_DESCRIPTION_BINARY_DATA \
00293 1,0,0,0, 'u', \
00294 2,0,0,0, 'p','u', \
00295 3, \
00296 2,0,0,0, 'R','U', \
00297 4,0,0,0, 't','e','x','t', \
00298 1,0,0,0, \
00299 2,0,0,0, 'g','w', \
00300 3,0,0,0, 'd','p','u', \
00301 1,0,0,0, 2,0,0,0, 'd','u'
00302
00303 #define ASSERT_APPLICATION_DESCRIPTION_EQ(desc) \
00304 ASSERT_EQ(desc.ApplicationUri, "u"); \
00305 ASSERT_EQ(desc.ProductUri, "pu"); \
00306 ASSERT_EQ(desc.ApplicationName.Encoding, HAS_LOCALE | HAS_TEXT); \
00307 ASSERT_EQ(desc.ApplicationName.Locale, "RU"); \
00308 ASSERT_EQ(desc.ApplicationName.Text, "text"); \
00309 ASSERT_EQ(desc.ApplicationType, ApplicationType::Client); \
00310 ASSERT_EQ(desc.GatewayServerUri, "gw"); \
00311 ASSERT_EQ(desc.DiscoveryProfileUri, "dpu"); \
00312 ASSERT_EQ(desc.DiscoveryUrls, std::vector<std::string>(1,"du"));
00313
00314 #define FILL_TEST_ENDPOINT(endpoint) \
00315 endpoint.EndpointUrl = "eu"; \
00316 FILL_APPLICATION_DESCRIPTION(endpoint.Server); \
00317 endpoint.ServerCertificate = ByteString(std::vector<uint8_t>{1,2,3,4}); \
00318 endpoint.SecurityMode = MessageSecurityMode::None; \
00319 endpoint.SecurityPolicyUri = "spu"; \
00320 UserTokenPolicy token; \
00321 token.PolicyId = "pi"; \
00322 token.TokenType = UserTokenType::UserName; \
00323 token.IssuedTokenType = "itt"; \
00324 token.IssuerEndpointUrl = "ieu"; \
00325 token.SecurityPolicyUri = "spu"; \
00326 endpoint.UserIdentityTokens.push_back(token); \
00327 endpoint.TransportProfileUri = "tpu"; \
00328 endpoint.SecurityLevel = 3;
00329
00330 #define TEST_ENDPOINT_BINARY_DATA \
00331 2,0,0,0, 'e','u', \
00332 TEST_APPLICATION_DESCRIPTION_BINARY_DATA, \
00333 4,0,0,0, 1,2,3,4, \
00334 1,0,0,0, \
00335 3,0,0,0, 's','p','u', \
00336 1,0,0,0, \
00337 2,0,0,0, 'p','i', \
00338 1,0,0,0, \
00339 3,0,0,0, 'i','t','t', \
00340 3,0,0,0, 'i','e','u', \
00341 3,0,0,0, 's','p','u', \
00342 3,0,0,0, 't','p','u', \
00343 3
00344
00345 #define ASSERT_ENDPOINT_EQ(e) \
00346 ASSERT_EQ(e.EndpointUrl, "eu"); \
00347 ASSERT_APPLICATION_DESCRIPTION_EQ(e.Server); \
00348 const ByteString certificate = ByteString(std::vector<uint8_t>{1,2,3,4}); \
00349 ASSERT_EQ(e.ServerCertificate, certificate); \
00350 ASSERT_EQ(e.SecurityMode, MessageSecurityMode::None); \
00351 ASSERT_EQ(e.SecurityPolicyUri, "spu"); \
00352 ASSERT_EQ(e.UserIdentityTokens.size(), 1); \
00353 ASSERT_EQ(e.UserIdentityTokens[0].PolicyId, "pi"); \
00354 ASSERT_EQ(e.UserIdentityTokens[0].TokenType, UserTokenType::UserName); \
00355 ASSERT_EQ(e.UserIdentityTokens[0].IssuedTokenType, "itt"); \
00356 ASSERT_EQ(e.UserIdentityTokens[0].IssuerEndpointUrl, "ieu"); \
00357 ASSERT_EQ(e.UserIdentityTokens[0].SecurityPolicyUri, "spu"); \
00358 ASSERT_EQ(e.TransportProfileUri, "tpu"); \
00359 ASSERT_EQ(e.SecurityLevel, 3);
00360
00361 #endif // __OPC_UA_TESTS_COMMON_H__
00362