jp-embedded / scxmlcc

The SCXML state machine to C++ compiler
GNU General Public License v3.0
140 stars 34 forks source link

Thread safe unittest #52

Closed ringlej closed 6 years ago

jp-embedded commented 6 years ago

looks good :-)

I think it would be good to unit test both with and without '-t'. Maybe like something below. Ideally it would be nice if both versions could be tested from the same test program so we don't have to build two test programs, but that gives name conflicts as it is now. One option could be to add a parameter to scxmlcc to force the generated class name. Or probably better - an option to put the generated class in a namespace.

diff --git a/src/test/makefile b/src/test/makefile
index df52100..aab3cd6 100644
--- a/src/test/makefile
+++ b/src/test/makefile
@@ -19,22 +19,31 @@ CPPFLAGS := -Wall -Wpedantic -O2 -MD -MP
 CPPFLAGS += -isystem gtest-1.7.0/include -pthread

 test.objs := test.o
+test_t.objs := test_t.o

-all: test
+all: test test_t

 clean: gtest.clean
-       rm -f test
+       rm -f test test_t
        rm -f $(patsubst %.txml,%.h,$(wildcard *.txml))
        rm -f $(patsubst %.scxml,%.h,$(wildcard *.scxml))
+       rm -f $(patsubst %.txml,%_t.h,$(wildcard *.txml))
+       rm -f $(patsubst %.scxml,%_t.h,$(wildcard *.scxml))
        rm -f $(patsubst %.txml,%.scxml,$(wildcard *.txml))
        rm -f $(test.objs) $(test.objs:.o=.d)
+       rm -f $(test_t.objs) $(test_t.objs:.o=.d)

 $(test.objs): libgtest.a
+$(test_t.objs): libgtest.a

 test: $(test.objs)
        $(CXX) -o $@ $^ libgtest.a -lpthread

+test_t: $(test_t.objs)
+       $(CXX) -o $@ $^ libgtest.a -lpthread
+
 -include $(test.objs:.o=.d)
+-include $(test_t.objs:.o=.d)

 include scxml.mk
 include gtest.mk
diff --git a/src/test/scxml.mk b/src/test/scxml.mk
index a389af6..fa3e219 100644
--- a/src/test/scxml.mk
+++ b/src/test/scxml.mk
@@ -20,3 +20,6 @@ SCXMLCC:=../scxmlcc
 %.h: %.scxml
        $(SCXMLCC) -o $@ $<

+%_t.h: %.scxml
+       $(SCXMLCC) -t -o $@ $<
+
ubuntu@ip-10-82-178-90:~/work/scxmlcc/src/test$ git add test_t.cpp
ubuntu@ip-10-82-178-90:~/work/scxmlcc/src/test$ git diff
diff --git a/src/test/makefile b/src/test/makefile
index df52100..aab3cd6 100644
--- a/src/test/makefile
+++ b/src/test/makefile
@@ -19,22 +19,31 @@ CPPFLAGS := -Wall -Wpedantic -O2 -MD -MP
 CPPFLAGS += -isystem gtest-1.7.0/include -pthread

 test.objs := test.o
+test_t.objs := test_t.o

-all: test
+all: test test_t

 clean: gtest.clean
-       rm -f test
+       rm -f test test_t
        rm -f $(patsubst %.txml,%.h,$(wildcard *.txml))
        rm -f $(patsubst %.scxml,%.h,$(wildcard *.scxml))
+       rm -f $(patsubst %.txml,%_t.h,$(wildcard *.txml))
+       rm -f $(patsubst %.scxml,%_t.h,$(wildcard *.scxml))
        rm -f $(patsubst %.txml,%.scxml,$(wildcard *.txml))
        rm -f $(test.objs) $(test.objs:.o=.d)
+       rm -f $(test_t.objs) $(test_t.objs:.o=.d)

 $(test.objs): libgtest.a
+$(test_t.objs): libgtest.a

 test: $(test.objs)
        $(CXX) -o $@ $^ libgtest.a -lpthread

+test_t: $(test_t.objs)
+       $(CXX) -o $@ $^ libgtest.a -lpthread
+
 -include $(test.objs:.o=.d)
+-include $(test_t.objs:.o=.d)

 include scxml.mk
 include gtest.mk
diff --git a/src/test/scxml.mk b/src/test/scxml.mk
index a389af6..fa3e219 100644
--- a/src/test/scxml.mk
+++ b/src/test/scxml.mk
@@ -20,3 +20,6 @@ SCXMLCC:=../scxmlcc
 %.h: %.scxml
        $(SCXMLCC) -o $@ $<

+%_t.h: %.scxml
+       $(SCXMLCC) -t -o $@ $<
+
diff --git a/src/test/test_t.cpp b/src/test/test_t.cpp
new file mode 100644
index 0000000..2724191
--- /dev/null
+++ b/src/test/test_t.cpp
@@ -0,0 +1,67 @@
+#include "test144_t.h"
+#include "../examples/timer_switch_t.h"
+// ..and probably all the rest could be tested with thread safe also
+
+#include <gtest/gtest.h>
+
+
+// test that events are inserted into the queue in the order in which they are raised. If
+// foo occurs before bar, success, otherwise failure -->
+TEST(w3c_t, 144)
+{
+       sc_test144 sc;
+       sc.init();
+       EXPECT_EQ(typeid(sc_test144::state_pass), typeid(*sc.cur_state));
+}
+
+struct sc_timer_switch::user_model
+{
+       int timer;
+};
+
+template<> void sc_timer_switch::state_actions<sc_timer_switch::state_off>::enter(sc_timer_switch::data_model &m)
+{
+       m.user->timer = 0;
+}
+
+template<> bool sc_timer_switch::transition_actions<&sc_timer_switch::state::unconditional, sc_timer_switch::state_on, sc_timer_swit
+{
+       return m.user->timer >= 5;
+}
+
+template<> void sc_timer_switch::transition_actions<&sc_timer_switch::state::event_timer, sc_timer_switch::state_on>::enter(sc_timer
+{
+       ++m.user->timer;
+}
+
+TEST(timer_switch_t, 0)
+{
+       sc_timer_switch::user_model m;
+       sc_timer_switch sc(&m);
+       sc.init();
+       EXPECT_EQ(typeid(sc_timer_switch::state_off), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_button);
+       EXPECT_EQ(typeid(sc_timer_switch::state_on), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_button);
+       EXPECT_EQ(typeid(sc_timer_switch::state_off), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_button);
+       EXPECT_EQ(typeid(sc_timer_switch::state_on), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_timer);
+       EXPECT_EQ(typeid(sc_timer_switch::state_on), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_timer);
+       EXPECT_EQ(typeid(sc_timer_switch::state_on), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_timer);
+       EXPECT_EQ(typeid(sc_timer_switch::state_on), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_timer);
+       EXPECT_EQ(typeid(sc_timer_switch::state_on), typeid(*sc.cur_state));
+       sc.dispatch(&sc_timer_switch::state::event_timer);
+       EXPECT_EQ(typeid(sc_timer_switch::state_off), typeid(*sc.cur_state));
+}
+
+int main(int argc, char *argv[])
+{
+       ::testing::InitGoogleTest(&argc, argv);
+       return RUN_ALL_TESTS();
+}
+
+
ringlej commented 6 years ago

Sorry I haven't responded earlier. I added a commit to allow specifying a namespace to enclose the sc in a given namespace name.

Also, please see the commit comment for bfba655 as it describes a race condition I faced and how this fixes my use case