Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
ApplicationCore
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ChimeraTK Mirror
ApplicationCore
Commits
3c193c1a
Commit
3c193c1a
authored
7 years ago
by
Martin Christoph Hierholzer
Browse files
Options
Downloads
Patches
Plain Diff
added tests for XML file generation
parent
30a5a52c
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
CMakeLists.txt
+1
-0
1 addition, 0 deletions
CMakeLists.txt
tests/executables_src/testApplication.cc
+214
-48
214 additions, 48 deletions
tests/executables_src/testApplication.cc
with
215 additions
and
48 deletions
CMakeLists.txt
+
1
−
0
View file @
3c193c1a
...
...
@@ -109,6 +109,7 @@ if(TESTING_IS_ENABLED)
FILE
(
COPY
${
CMAKE_SOURCE_DIR
}
/tests/test2.map DESTINATION
${
PROJECT_BINARY_DIR
}
)
FILE
(
COPY
${
CMAKE_SOURCE_DIR
}
/tests/test.dmap DESTINATION
${
PROJECT_BINARY_DIR
}
)
FILE
(
COPY
${
CMAKE_SOURCE_DIR
}
/tests/validConfig.xml DESTINATION
${
PROJECT_BINARY_DIR
}
)
FILE
(
COPY
${
CMAKE_SOURCE_DIR
}
/xmlschema/application.xsd DESTINATION
${
PROJECT_BINARY_DIR
}
)
endif
(
TESTING_IS_ENABLED
)
...
...
This diff is collapsed.
Click to expand it.
tests/executables_src/testApplication.cc
+
214
−
48
View file @
3c193c1a
...
...
@@ -14,9 +14,14 @@
#include
<boost/test/test_case_template.hpp>
#include
<boost/mpl/list.hpp>
#include
<boost/thread.hpp>
#include
<boost/filesystem.hpp>
#include
<libxml++/libxml++.h>
#include
"Application.h"
#include
"ControlSystemModule.h"
#include
"Multiplier.h"
#include
"Pipe.h"
using
namespace
boost
::
unit_test_framework
;
namespace
ctk
=
ChimeraTK
;
...
...
@@ -24,63 +29,224 @@ namespace ctk = ChimeraTK;
/*********************************************************************************************************************/
/* Application without name */
struct
Unnamed
App
:
public
ctk
::
Application
{
Unnamed
App
(
const
std
::
string
&
name
)
:
ctk
::
Application
(
name
)
{
ChimeraTK
::
ExperimentalFeatures
::
enable
();
}
~
Unnamed
App
()
{
shutdown
();
}
struct
Test
App
:
public
ctk
::
Application
{
Test
App
(
const
std
::
string
&
name
)
:
ctk
::
Application
(
name
)
{
ChimeraTK
::
ExperimentalFeatures
::
enable
();
}
~
Test
App
()
{
shutdown
();
}
using
Application
::
makeConnections
;
// we call makeConnections() manually in the tests to catch exceptions etc.
void
defineConnections
()
{}
// the setup is done in the tests
void
defineConnections
()
{
multiplierD
.
output
>>
csmod
(
"myVarD"
);
csmod
[
"mySubModule"
](
"myVarSIn"
)
>>
pipe
.
input
;
pipe
.
output
>>
csmod
[
"mySubModule"
](
"myVarSOut"
);
csmod
(
"myVarU16"
)
>>
multiplierU16
.
input
;
}
ctk
::
ConstMultiplier
<
double
>
multiplier
{
this
,
"multiplier"
,
"Some module"
,
42
};
ctk
::
ConstMultiplier
<
double
>
multiplierD
{
this
,
"multiplierD"
,
"Some module"
,
42
};
ctk
::
ScalarPipe
<
std
::
string
>
pipe
{
this
,
"pipe"
,
"unit"
,
"Some pipe module"
};
ctk
::
ConstMultiplier
<
uint16_t
,
uint16_t
,
120
>
multiplierU16
{
this
,
"multiplierU16"
,
"Some other module"
,
42
};
ctk
::
ControlSystemModule
csmod
;
};
/*********************************************************************************************************************/
/* test trigger by app variable when connecting a polled device register to an app variable */
BOOST_AUTO_TEST_CASE
(
testApplicationExceptions
)
{
std
::
cout
<<
"*********************************************************************************************************************"
<<
std
::
endl
;
std
::
cout
<<
"==> testApplicationExceptions"
<<
std
::
endl
;
// zero length name forbidden
try
{
Unnamed
App
app
(
""
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
ctk
::
ApplicationExceptionWithID
<
ctk
::
ApplicationExceptionID
::
illegalParameter
>
)
{
}
// names with spaces and special characters are forbidden
try
{
Unnamed
App
app
(
"With space"
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
ctk
::
ApplicationExceptionWithID
<
ctk
::
ApplicationExceptionID
::
illegalParameter
>
)
{
}
try
{
Unnamed
App
app
(
"WithExclamationMark!"
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
ctk
::
ApplicationExceptionWithID
<
ctk
::
ApplicationExceptionID
::
illegalParameter
>
)
{
}
// all allowed characters in the name
{
Unnamed
App
app
(
"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_1234567890"
);
}
// repeated characters are allowed
{
Unnamed
App
app
(
"AAAAAAA"
);
}
// Two apps at the same time are not allowed
Unnamed
App
app1
(
"FirstInstance"
);
try
{
Unnamed
App
app2
(
"SecondInstance"
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
std
::
runtime_error
)
{
}
std
::
cout
<<
"*********************************************************************************************************************"
<<
std
::
endl
;
std
::
cout
<<
"==> testApplicationExceptions"
<<
std
::
endl
;
// zero length name forbidden
try
{
Test
App
app
(
""
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
ctk
::
ApplicationExceptionWithID
<
ctk
::
ApplicationExceptionID
::
illegalParameter
>
)
{
}
// names with spaces and special characters are forbidden
try
{
Test
App
app
(
"With space"
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
ctk
::
ApplicationExceptionWithID
<
ctk
::
ApplicationExceptionID
::
illegalParameter
>
)
{
}
try
{
Test
App
app
(
"WithExclamationMark!"
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
ctk
::
ApplicationExceptionWithID
<
ctk
::
ApplicationExceptionID
::
illegalParameter
>
)
{
}
// all allowed characters in the name
{
Test
App
app
(
"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_1234567890"
);
}
// repeated characters are allowed
{
Test
App
app
(
"AAAAAAA"
);
}
// Two apps at the same time are not allowed
Test
App
app1
(
"FirstInstance"
);
try
{
Test
App
app2
(
"SecondInstance"
);
BOOST_FAIL
(
"Exception expected."
);
}
catch
(
std
::
runtime_error
)
{
}
}
/*********************************************************************************************************************/
// Helper function for testXmlGeneration:
// Obtain a value from an XML node
std
::
string
getValueFromNode
(
const
xmlpp
::
Node
*
node
,
const
std
::
string
&
subnodeName
)
{
xmlpp
::
Node
*
theChild
=
nullptr
;
for
(
const
auto
&
child
:
node
->
get_children
())
{
if
(
child
->
get_name
()
==
subnodeName
)
theChild
=
child
;
}
BOOST_REQUIRE
(
theChild
!=
nullptr
);
// requested child tag is there
auto
subChildList
=
theChild
->
get_children
();
if
(
subChildList
.
size
()
==
0
)
{
// special case: no text in the tag -> return empty string
return
""
;
}
BOOST_REQUIRE_EQUAL
(
subChildList
.
size
(),
1
);
// child tag contains only text (no further sub-tags)
const
xmlpp
::
TextNode
*
textNode
=
dynamic_cast
<
xmlpp
::
TextNode
*>
(
subChildList
.
front
());
BOOST_REQUIRE
(
textNode
!=
nullptr
);
return
textNode
->
get_content
();
}
/*********************************************************************************************************************/
/* test creation of XML file describing the variable tree */
BOOST_AUTO_TEST_CASE
(
testXmlGeneration
)
{
std
::
cout
<<
"*********************************************************************************************************************"
<<
std
::
endl
;
std
::
cout
<<
"==> testXmlGeneration"
<<
std
::
endl
;
// delete XML file if already existing
boost
::
filesystem
::
remove
(
"TestAppInstance.xml"
);
// create app which exports some properties and generate its XML file
TestApp
app
(
"TestAppInstance"
);
app
.
generateXML
();
// validate the XML file
xmlpp
::
XsdValidator
validator
(
"application.xsd"
);
validator
.
validate
(
"TestAppInstance.xml"
);
// parse XML file
xmlpp
::
DomParser
parser
;
try
{
parser
.
parse_file
(
"TestAppInstance.xml"
);
}
catch
(
xmlpp
::
exception
&
e
)
{
throw
std
::
runtime_error
(
std
::
string
(
"ConfigReader: Error opening the config file 'TestAppInstance.xml': "
)
+
e
.
what
());
}
// get root element
const
auto
root
=
parser
.
get_document
()
->
get_root_node
();
BOOST_CHECK_EQUAL
(
root
->
get_name
(),
"application"
);
// parsing loop
bool
found_myVarD
{
false
};
bool
found_myVarSIn
{
false
};
bool
found_myVarSOut
{
false
};
bool
found_myVarU8
{
false
};
for
(
const
auto
&
child
:
root
->
get_children
())
{
// cast into element, ignore if not an element (e.g. comment)
auto
*
element
=
dynamic_cast
<
const
xmlpp
::
Element
*>
(
child
);
if
(
!
element
)
continue
;
if
(
element
->
get_name
()
==
"variable"
)
{
// obtain attributes from the element
auto
xname
=
element
->
get_attribute
(
"name"
);
BOOST_REQUIRE
(
xname
!=
nullptr
);
std
::
string
name
(
xname
->
get_value
());
// obtain values from sub-elements
std
::
string
value_type
=
getValueFromNode
(
element
,
"value_type"
);
std
::
string
direction
=
getValueFromNode
(
element
,
"direction"
);
std
::
string
unit
=
getValueFromNode
(
element
,
"unit"
);
std
::
string
description
=
getValueFromNode
(
element
,
"description"
);
std
::
string
numberOfElements
=
getValueFromNode
(
element
,
"numberOfElements"
);
// check if variables are described correctly
if
(
name
==
"myVarD"
)
{
found_myVarD
=
true
;
BOOST_CHECK_EQUAL
(
value_type
,
"double"
);
BOOST_CHECK_EQUAL
(
direction
,
"application_to_control_system"
);
BOOST_CHECK_EQUAL
(
unit
,
""
);
BOOST_CHECK_EQUAL
(
description
,
"Output value after scaling"
);
BOOST_CHECK_EQUAL
(
numberOfElements
,
"1"
);
}
else
if
(
name
==
"myVarU16"
)
{
found_myVarU8
=
true
;
BOOST_CHECK_EQUAL
(
value_type
,
"uint16"
);
BOOST_CHECK_EQUAL
(
direction
,
"control_system_to_application"
);
BOOST_CHECK_EQUAL
(
unit
,
""
);
BOOST_CHECK_EQUAL
(
description
,
"Input value to be scaled"
);
BOOST_CHECK_EQUAL
(
numberOfElements
,
"120"
);
}
else
{
BOOST_ERROR
(
"Wrong variable name found."
);
}
}
else
if
(
element
->
get_name
()
==
"directory"
)
{
auto
xname
=
element
->
get_attribute
(
"name"
);
BOOST_REQUIRE
(
xname
!=
nullptr
);
std
::
string
name
(
xname
->
get_value
());
BOOST_CHECK_EQUAL
(
name
,
"mySubModule"
);
for
(
const
auto
&
subchild
:
child
->
get_children
())
{
auto
*
element
=
dynamic_cast
<
const
xmlpp
::
Element
*>
(
subchild
);
if
(
!
element
)
continue
;
BOOST_CHECK_EQUAL
(
element
->
get_name
(),
"variable"
);
// obtain attributes from the element
auto
xname
=
element
->
get_attribute
(
"name"
);
BOOST_REQUIRE
(
xname
!=
nullptr
);
std
::
string
name
(
xname
->
get_value
());
// obtain values from sub-elements
std
::
string
value_type
=
getValueFromNode
(
element
,
"value_type"
);
std
::
string
direction
=
getValueFromNode
(
element
,
"direction"
);
std
::
string
unit
=
getValueFromNode
(
element
,
"unit"
);
std
::
string
description
=
getValueFromNode
(
element
,
"description"
);
std
::
string
numberOfElements
=
getValueFromNode
(
element
,
"numberOfElements"
);
if
(
name
==
"myVarSIn"
)
{
found_myVarSIn
=
true
;
BOOST_CHECK_EQUAL
(
value_type
,
"string"
);
BOOST_CHECK_EQUAL
(
direction
,
"control_system_to_application"
);
BOOST_CHECK_EQUAL
(
unit
,
"unit"
);
BOOST_CHECK_EQUAL
(
description
,
"Some pipe module"
);
BOOST_CHECK_EQUAL
(
numberOfElements
,
"1"
);
}
else
if
(
name
==
"myVarSOut"
)
{
found_myVarSOut
=
true
;
BOOST_CHECK_EQUAL
(
value_type
,
"string"
);
BOOST_CHECK_EQUAL
(
direction
,
"application_to_control_system"
);
BOOST_CHECK_EQUAL
(
unit
,
"unit"
);
BOOST_CHECK_EQUAL
(
description
,
"Some pipe module"
);
BOOST_CHECK_EQUAL
(
numberOfElements
,
"1"
);
}
else
{
BOOST_ERROR
(
"Wrong variable name found."
);
}
}
}
else
{
BOOST_ERROR
(
"Wrong tag found."
);
}
}
BOOST_CHECK
(
found_myVarD
);
BOOST_CHECK
(
found_myVarSIn
);
BOOST_CHECK
(
found_myVarSOut
);
BOOST_CHECK
(
found_myVarU8
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment