Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/test state machine lib #1744

Merged
merged 66 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
8dfa645
Added state_machine_lib tests
Nov 9, 2018
41bd224
Added msg_name to StateContext call
Nov 9, 2018
0a293e8
Check current working directory for test_state_machine_lib
Nov 12, 2018
77cafbd
ls ./..
Nov 12, 2018
9df4890
Copy file to .ros
Nov 12, 2018
08a60fd
Copy files to .ros
Nov 12, 2018
db0e85d
Build state_machine_lib only
Nov 12, 2018
0cb27bc
Bug
Nov 12, 2018
983ad21
Test
Nov 12, 2018
d20c32e
Test
Nov 12, 2018
1319864
Test
Nov 13, 2018
15af272
Test
Nov 13, 2018
d4afdee
Test
Nov 13, 2018
95879a8
Fixed bug
Nov 26, 2018
d4f96ae
Added state_machine_lib tests
Nov 9, 2018
8b2fe69
Added msg_name to StateContext call
Nov 9, 2018
1259378
Check current working directory for test_state_machine_lib
Nov 12, 2018
a86c7cf
ls ./..
Nov 12, 2018
f2f504c
Copy file to .ros
Nov 12, 2018
07be004
Copy files to .ros
Nov 12, 2018
25688c1
Build state_machine_lib only
Nov 12, 2018
224a095
Test
Nov 12, 2018
ac88dc0
Test
Nov 12, 2018
7a6a39c
Test
Nov 13, 2018
56afdb0
Test
Nov 13, 2018
ef10050
Test
Nov 13, 2018
74c12d8
Fixed bug
Nov 26, 2018
be7bc9a
Resolve conflict
Nov 26, 2018
d3d7305
Removed unrelated files
Nov 26, 2018
ea761c1
Removed unrelated files
Nov 26, 2018
f54a204
Cleaned test cpp
Nov 27, 2018
6ca186a
Added license reference
Nov 27, 2018
6617820
Removed commented main
Nov 27, 2018
97bb690
Added state_machine_lib tests
Nov 9, 2018
5ad7a6b
Added msg_name to StateContext call
Nov 9, 2018
7cb98d6
Check current working directory for test_state_machine_lib
Nov 12, 2018
6cd266a
ls ./..
Nov 12, 2018
f1990b5
Copy file to .ros
Nov 12, 2018
22e05d0
Copy files to .ros
Nov 12, 2018
1565dc6
Test
Nov 12, 2018
6f55651
Test
Nov 12, 2018
67e3311
Fixed bug
Nov 26, 2018
f021e6f
Added state_machine_lib tests
Nov 9, 2018
960c25d
Added msg_name to StateContext call
Nov 9, 2018
d4c95f1
Check current working directory for test_state_machine_lib
Nov 12, 2018
77214f6
ls ./..
Nov 12, 2018
e39c7f5
Build state_machine_lib only
Nov 12, 2018
09d0a94
Test
Nov 13, 2018
0a40b1f
Test
Nov 13, 2018
dd7683d
Test
Nov 13, 2018
de6f887
Added license reference
Nov 27, 2018
27017d3
Removed commented main
Nov 27, 2018
bb42f2e
Conflict resolved
Nov 28, 2018
e63d84b
Bug
Nov 28, 2018
cb2afee
Left callback to unexisting state commented
Nov 30, 2018
00b8854
Callback to unexisting state uncommented
Nov 30, 2018
a6f63ce
Updated to ROS Cpp Style guidelines
Dec 4, 2018
28526bb
Updated Copyright date
Dec 4, 2018
4bab103
Replace cout check
Dec 12, 2018
169fbeb
Removed unrelated files
Dec 12, 2018
33a0972
WIP
Dec 12, 2018
47600d3
WIP
Dec 12, 2018
3e4f210
Replaced std::cout checks
Dec 12, 2018
2acf6a4
Removed showStateName from state_context.cpp
Dec 13, 2018
0927c08
Merge remote-tracking branch 'upstream/feature/test_PR_1609' into fea…
Jan 25, 2019
0c3f8a4
Updated requested changes
Jan 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ variables:
- test -f "${ROSINSTALL_FILE}" && wstool merge "${ROSINSTALL_FILE}"
- wstool up
- cd ..
- rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO}

- rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO}

build_kinetic:
stage: build
Expand Down
8 changes: 8 additions & 0 deletions ros/src/common/libs/state_machine_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,11 @@ install(TARGETS state_machine_lib
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

if(CATKIN_ENABLE_TESTING)
find_package(rostest REQUIRED)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/testStates.yaml $ENV{HOME}/.ros/testStates.yaml COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/reference.dot $ENV{HOME}/.ros/reference.dot COPYONLY)
add_rostest_gtest(test-state_machine_lib test/test_state_machine_lib.test test/src/test_main.cpp test/src/test_state_hpp.cpp test/src/test_state_context.cpp)
target_link_libraries(test-state_machine_lib ${catkin_LIBRARIES} state_machine_lib)
endif()
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ class State
CallbackExitFunc = _f;
}

void showStateName(void)
const std::string & getStateName(void) const
{
std::cout << state_name_ << "-";
return state_name_;
}
void setParent(std::shared_ptr<State> _parent)
{
Expand All @@ -115,10 +115,6 @@ class State
{
return child_state_;
}
std::string getStateName(void)
{
return std::string(state_name_);
}

void addTransition(const std::string key, const uint64_t val)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void StateContext::nextState(const std::string& transition_key)

if (isCurrentState(_target_state_name))
{
showStateName();
std::cout << state->getStateName() << "-";
}
}

Expand Down
23 changes: 23 additions & 0 deletions ros/src/common/libs/state_machine_lib/test/reference.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
digraph state_machine_graph {
dpi = "192";
node [style=filled];
0[label="Start",color = "crimson", group = 1];
1[label="Init", group = 1];
2[label="Intermediate"];
3[label="Final", group = 1];
subgraph cluster_0{
label = "Start";
group = 1;
}
0->1 [label="started"];
subgraph cluster_1{
label = "Init";
group = 1;
2->3 [label="go_to_final"];
1->2 [label="init_start"];
}
subgraph cluster_3{
label = "Final";
group = 1;
}
}
30 changes: 30 additions & 0 deletions ros/src/common/libs/state_machine_lib/test/src/test_main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2018 Autoware Foundation. All rights reserved.
*
* Licensed 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 <ros/ros.h>
#include <gtest/gtest.h>

class TestSuite: public ::testing::Test {
public:
TestSuite(){}
~TestSuite(){}
};

int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
//ros::init(argc, argv, "TestNode");
return RUN_ALL_TESTS();
}
106 changes: 106 additions & 0 deletions ros/src/common/libs/state_machine_lib/test/src/test_state_context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2018 Autoware Foundation. All rights reserved.
*
* Licensed 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 <ros/ros.h>
#include <gtest/gtest.h>

#include <fstream>
#include <unistd.h>
#include <dirent.h>

#include "state_machine_lib/state_context.hpp"

class TestClass
{
public:
TestClass() : counter_(0) {}

int counter_;
void increaseCounter(const std::string&)
{
counter_++;
}
};

class TestSuite: public ::testing::Test {
public:
TestSuite(){}
~TestSuite(){}

TestClass test_obj_;

};

TEST_F(TestSuite, StateContextConstructor){

std::string file_name = "testStates.yaml";
std::string msg_name = "test_states";
state_machine::StateContext state_context(file_name, msg_name);

// Check generated dot file
std::ifstream generated_dot_file("/tmp/"+msg_name+".dot");
std::stringstream dot_file_string;
dot_file_string << generated_dot_file.rdbuf();

std::ifstream reference_dot_file("reference.dot");
std::stringstream reference_dot_file_string;
reference_dot_file_string << reference_dot_file.rdbuf();

ASSERT_STREQ(dot_file_string.str().c_str(), reference_dot_file_string.str().c_str()) << "The generated dot file should be " << reference_dot_file_string.str();

// Check start state
std::shared_ptr<state_machine::State> start_state;
start_state = state_context.getStartState();
std::string test_string;
test_string = "Start\n";
ASSERT_STREQ(start_state->getStateName().c_str(), "Start") << "First state should be Start";
ASSERT_STREQ(state_context.getStateText().c_str(), test_string.c_str()) << "Text should be " << test_string;
ASSERT_STREQ(state_context.getAvailableTransition().c_str(), "started:Init,") << "Available transition should be: started:Init,";
}

TEST_F(TestSuite, ChangeStates){

std::string file_name = "testStates.yaml";
std::string msg_name = "test_states";
state_machine::StateContext state_context(file_name, msg_name);

state_context.nextState("started");
ASSERT_STREQ(state_context.getStateText().c_str(), "Init\n") << "Text should be: Init\n";
ASSERT_STREQ(state_context.getAvailableTransition().c_str(), "init_start:Intermediate,") << "Available transition should be: init_start:Intermediate,";
}

TEST_F(TestSuite, SetCallbacksStateContext){

std::string file_name = "testStates.yaml";
std::string msg_name = "test_states";
state_machine::StateContext state_context(file_name, msg_name);

// Set callbacks
int counter = test_obj_.counter_;

std::function<void(const std::string&)> _f = [this] (const std::string&) { test_obj_.increaseCounter(std::string("string")); };
ASSERT_TRUE(state_context.setCallback(state_machine::CallbackType::UPDATE, "Start", _f));
ASSERT_TRUE(state_context.setCallback(state_machine::CallbackType::EXIT, "Start", _f));

state_context.onUpdate();
counter++;
ASSERT_EQ(test_obj_.counter_, counter) << "counter should be : " << counter;

// Set Callback for unexisting state
ASSERT_TRUE(!state_context.setCallback(state_machine::CallbackType::UPDATE, "NoState", _f)) << "Should be false";
}


176 changes: 176 additions & 0 deletions ros/src/common/libs/state_machine_lib/test/src/test_state_hpp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Copyright 2018 Autoware Foundation. All rights reserved.
*
* Licensed 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 <ros/ros.h>
#include <gtest/gtest.h>

#include "state_machine_lib/state.hpp"

class TestClass
{
public:
TestClass(){
counter_ = 0;
}

int counter_;
void increaseCounter(const std::string&)
{
counter_++;
}
};

class TestSuite: public ::testing::Test {
public:
TestSuite(){}
~TestSuite(){}

TestClass test_obj_;

};

TEST_F(TestSuite, CheckStateConstructor){

std::string state_name = "TestState";
uint64_t state_id = 0;
state_machine::State state(state_name, state_id);

ASSERT_EQ(state.getStateID(),state_id) << "_state_id should be " << state_id;
ASSERT_STREQ(state.getStateName().c_str(), state_name.c_str()) << "state_name should be " << state_name;
ASSERT_TRUE(state.getChild() == NULL) << "child_state_ pointer should be NULL";
ASSERT_TRUE(state.getParent() == NULL) << "parent_state_ pointer should be NULL";
ASSERT_STREQ(state.getEnteredKey().c_str(), "") << "entered_key should be " << "";

}

TEST_F(TestSuite, TestParentChild){

std::string state_name;
uint64_t state_id;

state_name = "Start";
state_id = 0;
state_machine::State *first_state = new state_machine::State(state_name, state_id);
std::shared_ptr<state_machine::State> first_state_ptr(first_state);

state_name = "Init";
state_id = 1;
state_machine::State *second_state = new state_machine::State(state_name, state_id);
std::shared_ptr<state_machine::State> second_state_ptr(second_state);

state_name = "Final";
state_id = 2;
state_machine::State *third_state = new state_machine::State(state_name, state_id);
std::shared_ptr<state_machine::State> third_state_ptr(third_state);

// Set parent
second_state_ptr->setParent(first_state_ptr);
third_state_ptr->setParent(second_state_ptr);

ASSERT_TRUE(first_state_ptr->getParent() == NULL) << "Parent should be " << NULL;
ASSERT_TRUE(second_state_ptr->getParent() == first_state_ptr) << "Parent should be " << first_state_ptr;
ASSERT_TRUE(third_state_ptr->getParent() == second_state_ptr) << "Parent should be " << second_state_ptr;

// Set child
first_state_ptr->setChild(second_state_ptr);
second_state_ptr->setChild(third_state_ptr);

ASSERT_TRUE(first_state_ptr->getChild() == second_state_ptr) << "Child should be " << second_state_ptr;
ASSERT_TRUE(second_state_ptr->getChild() == third_state_ptr) << "Child should be " << third_state_ptr;
ASSERT_TRUE(third_state_ptr->getChild() == NULL) << "Child should be " << NULL;
}

TEST_F(TestSuite, SetCallbacks){

std::string state_name;
uint64_t state_id;

state_name = "Start";
state_id = 0;
state_machine::State *first_state = new state_machine::State(state_name, state_id);
std::shared_ptr<state_machine::State> first_state_ptr(first_state);

state_name = "Init";
state_id = 1;
state_machine::State *second_state = new state_machine::State(state_name, state_id);
std::shared_ptr<state_machine::State> second_state_ptr(second_state);

// Set child
first_state_ptr->setChild(second_state_ptr);

// Set callbacks
int counter = test_obj_.counter_;

std::function<void(const std::string&)> _f = [this] (const std::string&) { test_obj_.increaseCounter(std::string("string")); };
first_state_ptr->setCallbackEntry(_f);
first_state_ptr->setCallbackExit(_f);
first_state_ptr->setCallbackUpdate(_f);

first_state_ptr->onEntry();
counter++;
ASSERT_EQ(test_obj_.counter_, counter) << "counter should be : " << counter;

first_state_ptr->onUpdate();
counter++;
ASSERT_EQ(test_obj_.counter_, counter) << "counter should be : " << counter;

first_state_ptr->onExit();
counter++;
ASSERT_EQ(test_obj_.counter_, counter) << "counter should be : " << counter;
}

TEST_F(TestSuite, SetKey){

std::string state_name;
uint64_t state_id;

state_name = "Start";
state_id = 0;
state_machine::State *first_state = new state_machine::State(state_name, state_id);
std::shared_ptr<state_machine::State> first_state_ptr(first_state);

ASSERT_STREQ(first_state_ptr->getEnteredKey().c_str(), "") << "entered_key should be " << "";
std::string key = "newKey";
first_state_ptr->setEnteredKey(key);
ASSERT_STREQ(first_state_ptr->getEnteredKey().c_str(), key.c_str()) << "entered_key should be " << key;
}

TEST_F(TestSuite, TestTransitionMap){

std::string state_name;
uint64_t state_id;
std::string key;
uint64_t value;
std::map<std::string, uint64_t> transition_map;

state_name = "Start";
state_id = 0;
state_machine::State *first_state = new state_machine::State(state_name, state_id);
std::shared_ptr<state_machine::State> first_state_ptr(first_state);

transition_map = first_state_ptr->getTransitionMap();
ASSERT_EQ(transition_map[""], 0) << "Transition value should be" << 0;

key = "newTransition";
value = 0;

first_state_ptr->addTransition(key, value);
ASSERT_EQ(first_state_ptr->getTansitionVal(key), value) << "Transition value for key : " << key << " should be " << value;

transition_map = first_state_ptr->getTransitionMap();
ASSERT_EQ(transition_map[key], value) << "Transition value should be" << value;
}

Loading