00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <src/server/xml_address_space_loader.h>
00012
00013 #include <opc/ua/protocol/attribute_ids.h>
00014 #include <opc/ua/protocol/object_ids.h>
00015 #include <opc/ua/protocol/status_codes.h>
00016 #include <opc/ua/server/addons/address_space.h>
00017 #include <opc/ua/server/address_space.h>
00018
00019 #include <functional>
00020
00021 #include <gtest/gtest.h>
00022 #include <gmock/gmock.h>
00023
00024
00025
00026
00027 using namespace testing;
00028 using namespace OpcUa;
00029 using namespace OpcUa::Internal;
00030
00031 class XmlAddressSpace : public testing::Test
00032 {
00033 protected:
00034 virtual void SetUp()
00035 {
00036 const bool debug = false;
00037 NameSpace = OpcUa::Server::CreateAddressSpace(debug);
00038 }
00039
00040 virtual void TearDown()
00041 {
00042 NameSpace.reset();
00043 }
00044
00045 protected:
00046 std::vector<ReferenceDescription> Browse(const NodeId& id) const
00047 {
00048 OpcUa::BrowseDescription description;
00049 description.NodeToBrowse = id;
00050 OpcUa::NodesQuery query;
00051 query.NodesToBrowse.push_back(description);
00052 return NameSpace->Browse(query);
00053 }
00054
00055 bool HasReference(std::vector<ReferenceDescription> refs, ReferenceId referenceId, NodeId targetNode) const
00056 {
00057 for (const ReferenceDescription ref : refs)
00058 {
00059 if (ref.TargetNodeId == targetNode && ref.ReferenceTypeId == referenceId)
00060 {
00061 return true;
00062 }
00063 }
00064 return false;
00065 }
00066
00067 template <typename T>
00068 bool HasAttribute(const NodeId& object, OpcUa::AttributeId attribute, T value)
00069 {
00070 ReadParameters params;
00071 ReadValueId id;
00072 id.Node = object;
00073 id.Attribute = attribute;
00074 params.AttributesToRead.push_back(id);
00075 std::vector<DataValue> values = NameSpace->Read(params);
00076 EXPECT_EQ(values.size(), 1);
00077 if (values.size() != 1)
00078 {
00079 return false;
00080 }
00081
00082 const DataValue var = values.front();
00083 EXPECT_EQ(var.Status, StatusCode::Good);
00084 return var == value;
00085 }
00086
00087 std::string ConfigPath(const char* name)
00088 {
00089 return std::string("tests/server/") + name;
00090 }
00091
00092 protected:
00093 Server::AddressSpace::UniquePtr NameSpace;
00094 };
00095
00096 TEST_F(XmlAddressSpace, ExceptionIfCannotLoadDocument)
00097 {
00098 XmlAddressSpaceLoader loader(*NameSpace);
00099 ASSERT_THROW(loader.Load(ConfigPath("not_found.xml")), std::exception);
00100 }
00101
00102 TEST_F(XmlAddressSpace, ExceptionIfRootNodeInvalid)
00103 {
00104 XmlAddressSpaceLoader loader(*NameSpace);
00105 ASSERT_THROW(loader.Load(ConfigPath("invalid_root.xml")), std::exception);
00106 }
00107
00108 TEST_F(XmlAddressSpace, ExceptionIfNodeVersionOfAddressSpace)
00109 {
00110 XmlAddressSpaceLoader loader(*NameSpace);
00111 ASSERT_THROW(loader.Load(ConfigPath("no_version.xml")), std::exception);
00112 }
00113
00114 TEST_F(XmlAddressSpace, ExceptionIfUnknownVersion)
00115 {
00116 XmlAddressSpaceLoader loader(*NameSpace);
00117 ASSERT_THROW(loader.Load(ConfigPath("invalid_version.xml")), std::exception);
00118 }
00119
00120 TEST_F(XmlAddressSpace, NoExceptionIfDocumentValid)
00121 {
00122 XmlAddressSpaceLoader loader(*NameSpace);
00123 ASSERT_NO_THROW(loader.Load(ConfigPath("empty.xml")));
00124 }
00125
00126 TEST_F(XmlAddressSpace, BaseNodeHasId)
00127 {
00128 XmlAddressSpaceLoader loader(*NameSpace);
00129 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00130
00131 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::NodeId, NumericNodeId((uint32_t)ObjectId::RootFolder, 10)));
00132 }
00133
00134 TEST_F(XmlAddressSpace, BaseNodeHasClass)
00135 {
00136 XmlAddressSpaceLoader loader(*NameSpace);
00137 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00138
00139 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::NodeClass, (int32_t)NodeClass::Object));
00140 }
00141
00142 TEST_F(XmlAddressSpace, BaseNodeHasBrowseName)
00143 {
00144 XmlAddressSpaceLoader loader(*NameSpace);
00145 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00146
00147 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::BrowseName, QualifiedName("Root")));
00148 }
00149
00150 TEST_F(XmlAddressSpace, BaseNodeHasDiaplayName)
00151 {
00152 XmlAddressSpaceLoader loader(*NameSpace);
00153 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00154
00155 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::DisplayName, LocalizedText("Root")));
00156 }
00157
00158 TEST_F(XmlAddressSpace, BaseNodeHasDescription)
00159 {
00160 XmlAddressSpaceLoader loader(*NameSpace);
00161 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00162
00163 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::Description, std::string("Root")));
00164 }
00165
00166 TEST_F(XmlAddressSpace, BaseNodeHasWriteMask)
00167 {
00168 XmlAddressSpaceLoader loader(*NameSpace);
00169 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00170
00171 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::WriteMask, (uint32_t)10));
00172 }
00173
00174 TEST_F(XmlAddressSpace, BaseNodeHasUserWriteMask)
00175 {
00176 XmlAddressSpaceLoader loader(*NameSpace);
00177 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00178
00179 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::UserWriteMask, (uint32_t)0));
00180 }
00181
00182 TEST_F(XmlAddressSpace, BaseNodeHasIsAbstract)
00183 {
00184 XmlAddressSpaceLoader loader(*NameSpace);
00185 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00186
00187 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::IsAbstract, false));
00188 }
00189
00190 TEST_F(XmlAddressSpace, BaseNodeHasSymmetric)
00191 {
00192 XmlAddressSpaceLoader loader(*NameSpace);
00193 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00194
00195 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::Symmetric, false));
00196 }
00197
00198 TEST_F(XmlAddressSpace, BaseNodeHasInverseName)
00199 {
00200 XmlAddressSpaceLoader loader(*NameSpace);
00201 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00202
00203 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::InverseName, std::string("inverse_name")));
00204 }
00205
00206 TEST_F(XmlAddressSpace, BaseNodeHasContainsNoLoops)
00207 {
00208 XmlAddressSpaceLoader loader(*NameSpace);
00209 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00210
00211 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::ContainsNoLoops, false));
00212 }
00213
00214 TEST_F(XmlAddressSpace, BaseNodeHasEventNotifier)
00215 {
00216 XmlAddressSpaceLoader loader(*NameSpace);
00217 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00218
00219 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::EventNotifier, std::vector<uint8_t>{0}));
00220 }
00221
00222 TEST_F(XmlAddressSpace, BaseNodeHasValue)
00223 {
00224 XmlAddressSpaceLoader loader(*NameSpace);
00225 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00226
00227 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::Value, (uint32_t)55));
00228 }
00229
00230 TEST_F(XmlAddressSpace, BaseNodeHasDataType)
00231 {
00232 XmlAddressSpaceLoader loader(*NameSpace);
00233 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00234
00235 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::DataType, NodeId(ObjectId::UInt32)));
00236 }
00237
00238 TEST_F(XmlAddressSpace, BaseNodeHasValueRank)
00239 {
00240 XmlAddressSpaceLoader loader(*NameSpace);
00241 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00242
00243 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::ValueRank, (int32_t)0));
00244 }
00245
00246 TEST_F(XmlAddressSpace, BaseNodeHasArrayDimensions)
00247 {
00248 XmlAddressSpaceLoader loader(*NameSpace);
00249 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00250
00251 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::ArrayDimensions, (uint32_t)0));
00252 }
00253
00254 TEST_F(XmlAddressSpace, BaseNodeHasAccessLevel)
00255 {
00256 XmlAddressSpaceLoader loader(*NameSpace);
00257 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00258
00259 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::AccessLevel, (uint32_t)0));
00260 }
00261
00262 TEST_F(XmlAddressSpace, BaseNodeHasUserAccessLevel)
00263 {
00264 XmlAddressSpaceLoader loader(*NameSpace);
00265 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00266
00267 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::UserAccessLevel, (uint32_t)0));
00268 }
00269
00270 TEST_F(XmlAddressSpace, BaseNodeHasMinimumSamplingInterval)
00271 {
00272 XmlAddressSpaceLoader loader(*NameSpace);
00273 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00274
00275 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::MinimumSamplingInterval, (uint32_t)100));
00276 }
00277
00278 TEST_F(XmlAddressSpace, BaseNodeHasHistorizing)
00279 {
00280 XmlAddressSpaceLoader loader(*NameSpace);
00281 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00282
00283 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::Historizing, true));
00284 }
00285
00286 TEST_F(XmlAddressSpace, BaseNodeHasExecutable)
00287 {
00288 XmlAddressSpaceLoader loader(*NameSpace);
00289 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00290
00291 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::Executable, false));
00292 }
00293
00294 TEST_F(XmlAddressSpace, BaseNodeHasUserExecutable)
00295 {
00296 XmlAddressSpaceLoader loader(*NameSpace);
00297 ASSERT_NO_THROW(loader.Load(ConfigPath("base_node.xml")));
00298
00299 ASSERT_TRUE(HasAttribute(NumericNodeId(84, 10), AttributeId::UserExecutable, false));
00300 }
00301
00302 TEST_F(XmlAddressSpace, InternalReference)
00303 {
00304 XmlAddressSpaceLoader loader(*NameSpace);
00305 ASSERT_NO_THROW(loader.Load(ConfigPath("predefined_references.xml")));
00306
00307 const NodeId targetNode = NumericNodeId(100, 10);
00308 std::vector<ReferenceDescription> references = Browse(NumericNodeId(99, 10));
00309 ASSERT_TRUE(HasReference(references, ReferenceId::References, targetNode));
00310 ASSERT_TRUE(HasReference(references, ReferenceId::NonHierarchicalReferences, targetNode));
00311 ASSERT_TRUE(HasReference(references, ReferenceId::HierarchicalReferences, targetNode));
00312
00313 ASSERT_TRUE(HasReference(references, ReferenceId::References, targetNode));
00314 ASSERT_TRUE(HasReference(references, ReferenceId::NonHierarchicalReferences, targetNode));
00315 ASSERT_TRUE(HasReference(references, ReferenceId::HierarchicalReferences, targetNode));
00316 ASSERT_TRUE(HasReference(references, ReferenceId::HasChild, targetNode));
00317 ASSERT_TRUE(HasReference(references, ReferenceId::Organizes, targetNode));
00318 ASSERT_TRUE(HasReference(references, ReferenceId::HasEventSource, targetNode));
00319 ASSERT_TRUE(HasReference(references, ReferenceId::HasModellingRule, targetNode));
00320 ASSERT_TRUE(HasReference(references, ReferenceId::HasEncoding, targetNode));
00321 ASSERT_TRUE(HasReference(references, ReferenceId::HasDescription, targetNode));
00322 ASSERT_TRUE(HasReference(references, ReferenceId::HasTypeDefinition, targetNode));
00323 ASSERT_TRUE(HasReference(references, ReferenceId::GeneratesEvent, targetNode));
00324 ASSERT_TRUE(HasReference(references, ReferenceId::Aggregates, targetNode));
00325 ASSERT_TRUE(HasReference(references, ReferenceId::HasSubtype, targetNode));
00326 ASSERT_TRUE(HasReference(references, ReferenceId::HasProperty, targetNode));
00327 ASSERT_TRUE(HasReference(references, ReferenceId::HasComponent, targetNode));
00328 ASSERT_TRUE(HasReference(references, ReferenceId::HasNotifier, targetNode));
00329 ASSERT_TRUE(HasReference(references, ReferenceId::HasOrderedComponent, targetNode));
00330 ASSERT_TRUE(HasReference(references, ReferenceId::HasModelParent, targetNode));
00331 ASSERT_TRUE(HasReference(references, ReferenceId::FromState, targetNode));
00332 ASSERT_TRUE(HasReference(references, ReferenceId::ToState, targetNode));
00333 ASSERT_TRUE(HasReference(references, ReferenceId::HasCause, targetNode));
00334 ASSERT_TRUE(HasReference(references, ReferenceId::HasEffect, targetNode));
00335 ASSERT_TRUE(HasReference(references, ReferenceId::HasHistoricalConfiguration, targetNode));
00336 ASSERT_TRUE(HasReference(references, ReferenceId::HasHistoricalEventConfiguration, targetNode));
00337 ASSERT_TRUE(HasReference(references, ReferenceId::HasSubStateMachine, targetNode));
00338 ASSERT_TRUE(HasReference(references, ReferenceId::HasEventHistory, targetNode));
00339 ASSERT_TRUE(HasReference(references, ReferenceId::AlwaysGeneratesEvent, targetNode));
00340 ASSERT_TRUE(HasReference(references, ReferenceId::HasTrueSubState, targetNode));
00341 ASSERT_TRUE(HasReference(references, ReferenceId::HasFalseSubState, targetNode));
00342 ASSERT_TRUE(HasReference(references, ReferenceId::HasCondition, targetNode));
00343 ASSERT_FALSE(HasReference(references, ReferenceId::Unknown, targetNode));
00344 }
00345
00346 TEST_F(XmlAddressSpace, DISABLED_ExternalReference)
00347 {
00348 XmlAddressSpaceLoader loader(*NameSpace);
00349 ASSERT_NO_THROW(loader.Load(ConfigPath("predefined_references.xml")));
00350
00351 const NodeId targetNode = NumericNodeId(99, 10);
00352 std::vector<ReferenceDescription> references = Browse(NumericNodeId(84));
00353 ASSERT_TRUE(HasReference(references, ReferenceId::Organizes, targetNode));
00354 }