diff --git a/compiler2/Value.cc b/compiler2/Value.cc index f8e864c8987bcdf3019acdbf84974cb91a22d6e4..e577b3673dd25f003e894173fad09b669a4995f7 100644 --- a/compiler2/Value.cc +++ b/compiler2/Value.cc @@ -171,6 +171,7 @@ namespace Common { case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: case OPTYPE_PROF_RUNNING: + case OPTYPE_NOW: break; case OPTYPE_GET_PORT_REF: u.expr.type = p.u.expr.type; // the type is not owned, don't copy it @@ -423,6 +424,9 @@ namespace Common { switch (u.expr.v_optype) { case OPTYPE_TESTCASENAME: // - break; + case OPTYPE_NOW: // - + error("Operation 'now' cannot be used in alt guards."); + break; case OPTYPE_RND: // - case OPTYPE_RNDWITHVAL: /** \todo -> SEED */ // v1 warning("Random number generation 'rnd()' change the actual snapshot."); @@ -764,6 +768,7 @@ namespace Common { case OPTYPE_TESTCASENAME: case OPTYPE_PROF_RUNNING: case OPTYPE_GET_PORT_REF: // type (not owned) + case OPTYPE_NOW: break; case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_ALIVE: @@ -1165,6 +1170,7 @@ namespace Common { case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: case OPTYPE_PROF_RUNNING: + case OPTYPE_NOW: break; case OPTYPE_GET_PORT_REF: u.expr.type = NULL; // will be set during semantic analysis @@ -1993,6 +1999,7 @@ namespace Common { case OPTYPE_TESTCASENAME: case OPTYPE_PROF_RUNNING: case OPTYPE_GET_PORT_REF: + case OPTYPE_NOW: break; case OPTYPE_UNARYPLUS: // v1 case OPTYPE_UNARYMINUS: @@ -2241,6 +2248,7 @@ namespace Common { case OPTYPE_TESTCASENAME: case OPTYPE_PROF_RUNNING: case OPTYPE_GET_PORT_REF: + case OPTYPE_NOW: break; case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_ALIVE: @@ -2617,6 +2625,7 @@ namespace Common { case OPTYPE_TESTCASENAME: case OPTYPE_PROF_RUNNING: case OPTYPE_GET_PORT_REF: + case OPTYPE_NOW: break; case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_ALIVE: @@ -3610,6 +3619,7 @@ namespace Common { case OPTYPE_STR2FLOAT: case OPTYPE_RND: case OPTYPE_RNDWITHVAL: + case OPTYPE_NOW: return Type::T_REAL; case OPTYPE_ACTIVATE: return Type::T_DEFAULT; @@ -4111,6 +4121,8 @@ namespace Common { return "getverdict()"; case OPTYPE_TESTCASENAME: return "testcasename()"; + case OPTYPE_NOW: + return "now"; case OPTYPE_CHECKSTATE_ANY: if (u.expr.r1) { return "port.checkstate()"; @@ -7127,6 +7139,13 @@ void Value::chk_expr_operand_execute_refd(Value *v1, case OPTYPE_TESTCASENAME: case OPTYPE_PROF_RUNNING: break; + case OPTYPE_NOW: { + Ttcn::StatementBlock* sb = my_scope->get_statementblock_scope(); + if (sb == NULL || sb->get_my_def() == NULL) { + error("Operation `%s' can only be used in testcases, functions or " + "altsteps", opname); + } + break; } case OPTYPE_GET_PORT_REF: if (u.expr.type == NULL) { Ttcn::PortScope* port_scope = my_scope->get_scope_port(); @@ -8256,6 +8275,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, case OPTYPE_JSON2CBOR: // v1 case OPTYPE_BSON2JSON: // v1 case OPTYPE_JSON2BSON: // v1 + case OPTYPE_NOW: break; case OPTYPE_TESTCASENAME: { // - if (!my_scope) FATAL_ERROR("Value::evaluate_value()"); @@ -9579,6 +9599,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, case OPTYPE_JSON2CBOR: case OPTYPE_BSON2JSON: case OPTYPE_JSON2BSON: + case OPTYPE_NOW: return true; case OPTYPE_COMP_NULL: // - return false; @@ -11225,6 +11246,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, case OPTYPE_GET_PORT_REF: // - case OPTYPE_CHECKSTATE_ANY: case OPTYPE_CHECKSTATE_ALL: + case OPTYPE_NOW: // - break; // nothing to do case OPTYPE_MATCH: // v1 t2 @@ -11637,6 +11659,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1, return string("rnd()"); case OPTYPE_TESTCASENAME: return string("testcasename()"); + case OPTYPE_NOW: + return string("now"); case OPTYPE_UNARYPLUS: return create_stringRepr_unary("+"); case OPTYPE_UNARYMINUS: @@ -13648,6 +13672,9 @@ void Value::chk_expr_operand_execute_refd(Value *v1, case OPTYPE_TESTCASENAME: // - expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()"); break; + case OPTYPE_NOW: + expr->expr = mputstr(expr->expr, "TTCN_Runtime::now()"); + break; case OPTYPE_ACTIVATE: // r1 generate_code_expr_activate(expr); break; @@ -15376,6 +15403,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, case OPTYPE_CHECKSTATE_ANY: case OPTYPE_CHECKSTATE_ALL: case OPTYPE_HOSTID: + case OPTYPE_NOW: return true; case OPTYPE_ENCODE: case OPTYPE_DECODE: diff --git a/compiler2/Value.hh b/compiler2/Value.hh index 847887227ea040369e8f1329d8376858826953d3..df7f642d24125e03652463b88d0f90035c9bd3a6 100644 --- a/compiler2/Value.hh +++ b/compiler2/Value.hh @@ -144,17 +144,18 @@ namespace Common { enum operationtype_t { OPTYPE_RND, // - OPTYPE_TESTCASENAME, // - + OPTYPE_NOW, // - OPTYPE_UNARYPLUS, // v1 OPTYPE_UNARYMINUS, // v1 OPTYPE_NOT, // v1 OPTYPE_NOT4B, // v1 - OPTYPE_BIT2HEX, // v1 6 + OPTYPE_BIT2HEX, // v1 7 OPTYPE_BIT2INT, // v1 OPTYPE_BIT2OCT, // v1 - OPTYPE_BIT2STR, // v1 - OPTYPE_CHAR2INT, // v1 10 + OPTYPE_BIT2STR, // v1 10 + OPTYPE_CHAR2INT, // v1 OPTYPE_CHAR2OCT, // v1 OPTYPE_FLOAT2INT, // v1 OPTYPE_FLOAT2STR, // v1 @@ -163,8 +164,8 @@ namespace Common { OPTYPE_HEX2OCT, // v1 OPTYPE_HEX2STR, // v1 OPTYPE_INT2CHAR, // v1 - OPTYPE_INT2FLOAT, // v1 - OPTYPE_INT2STR, // v1 20 + OPTYPE_INT2FLOAT, // v1 20 + OPTYPE_INT2STR, // v1 OPTYPE_INT2UNICHAR, // v1 OPTYPE_OCT2BIT, // v1 OPTYPE_OCT2CHAR, // v1 @@ -173,56 +174,56 @@ namespace Common { OPTYPE_OCT2STR, // v1 OPTYPE_OCT2UNICHAR, // v1 [v2] OPTYPE_STR2BIT, // v1 - OPTYPE_STR2FLOAT, // v1 + OPTYPE_STR2FLOAT, // v1 30 OPTYPE_STR2HEX, // v1 - OPTYPE_STR2INT, // v1 30 + OPTYPE_STR2INT, // v1 OPTYPE_STR2OCT, // v1 OPTYPE_UNICHAR2INT, // v1 OPTYPE_UNICHAR2CHAR, // v1 OPTYPE_UNICHAR2OCT, // v1 [v2] OPTYPE_ENUM2INT, // v1 - OPTYPE_ENCODE, // ti1 [v2] [v3] 35 + OPTYPE_ENCODE, // ti1 [v2] [v3] 38 OPTYPE_RNDWITHVAL, /** \todo -> SEED */ // v1 - OPTYPE_ADD, // v1 v2 + OPTYPE_ADD, // v1 v2 40 OPTYPE_SUBTRACT, // v1 v2 OPTYPE_MULTIPLY, // v1 v2 - OPTYPE_DIVIDE, // v1 v2 40 + OPTYPE_DIVIDE, // v1 v2 OPTYPE_MOD, // v1 v2 OPTYPE_REM, // v1 v2 OPTYPE_CONCAT, // v1 v2 OPTYPE_EQ, // v1 v2 OPTYPE_LT, // v1 v2 OPTYPE_GT, // v1 v2 - OPTYPE_NE, // v1 v2 + OPTYPE_NE, // v1 v2 50 OPTYPE_GE, // v1 v2 OPTYPE_LE, // v1 v2 - OPTYPE_AND, // v1 v2 50 + OPTYPE_AND, // v1 v2 OPTYPE_OR, // v1 v2 OPTYPE_XOR, // v1 v2 OPTYPE_AND4B, // v1 v2 OPTYPE_OR4B, // v1 v2 OPTYPE_XOR4B, // v1 v2 OPTYPE_SHL, // v1 v2 - OPTYPE_SHR, // v1 v2 + OPTYPE_SHR, // v1 v2 60 OPTYPE_ROTL, // v1 v2 OPTYPE_ROTR, // v1 v2 - OPTYPE_INT2BIT, // v1 v2 60 + OPTYPE_INT2BIT, // v1 v2 OPTYPE_INT2HEX, // v1 v2 OPTYPE_INT2OCT, // v1 v2 - OPTYPE_DECODE, // r1 r2 [v3] [v4] + OPTYPE_DECODE, // r1 r2 [v3] [v4] 66 OPTYPE_SUBSTR, // ti1 v2 v3 OPTYPE_REGEXP, // ti1 t2 v3 b4 - OPTYPE_DECOMP, // v1 v2 v3 66 + OPTYPE_DECOMP, // v1 v2 v3 - OPTYPE_REPLACE, // ti1 v2 v3 ti4 + OPTYPE_REPLACE, // ti1 v2 v3 ti4 70 - OPTYPE_ISVALUE, // ti1 68 + OPTYPE_ISVALUE, // ti1 OPTYPE_ISBOUND, // ti1 OPTYPE_ISPRESENT, // ti1 OPTYPE_ISCHOSEN, // r1 i2 @@ -232,7 +233,7 @@ namespace Common { OPTYPE_LENGTHOF, // ti1 OPTYPE_SIZEOF, // ti1 OPTYPE_VALUEOF, // ti1 - OPTYPE_MATCH, // v1 t2 + OPTYPE_MATCH, // v1 t2 80 OPTYPE_TTCN2STRING, // ti1 OPTYPE_REMOVE_BOM, //v1 @@ -241,11 +242,11 @@ namespace Common { OPTYPE_DECODE_BASE64, //v1 /** cannot distinguish during parsing; can be COMP or TMR */ - OPTYPE_UNDEF_RUNNING, // r1 [r2] b4 78 + OPTYPE_UNDEF_RUNNING, // r1 [r2] b4 86 OPTYPE_COMP_NULL, // - (from V_TTCN3_NULL) OPTYPE_COMP_MTC, // - OPTYPE_COMP_SYSTEM, // - - OPTYPE_COMP_SELF, // - + OPTYPE_COMP_SELF, // - 90 OPTYPE_COMP_CREATE, // r1 [v2] [v3] b4 OPTYPE_COMP_RUNNING, // v1 [r2] b4 OPTYPE_COMP_RUNNING_ANY, // - @@ -253,9 +254,9 @@ namespace Common { OPTYPE_COMP_ALIVE, // v1 OPTYPE_COMP_ALIVE_ANY, // - OPTYPE_COMP_ALIVE_ALL, // - - OPTYPE_TMR_READ, // r1 90 + OPTYPE_TMR_READ, // r1 OPTYPE_TMR_RUNNING, // r1 [r2] b4 - OPTYPE_TMR_RUNNING_ANY, // - + OPTYPE_TMR_RUNNING_ANY, // - 100 OPTYPE_GETVERDICT, // - OPTYPE_ACTIVATE, // r1 OPTYPE_ACTIVATE_REFD, //v1 t_list2 @@ -263,12 +264,12 @@ namespace Common { OPTYPE_EXECUTE_REFD, // v1 t_list2 [v3] OPTYPE_LOG2STR, // logargs - OPTYPE_PROF_RUNNING, // - 99 + OPTYPE_PROF_RUNNING, // - 107 OPTYPE_ENCVALUE_UNICHAR, // ti1 [v2] [v3] [v4] OPTYPE_DECVALUE_UNICHAR, // r1 r2 [v3] [v4] [v5] - OPTYPE_ANY2UNISTR, // logarg, length = 1 + OPTYPE_ANY2UNISTR, // logarg, length = 1 110 OPTYPE_CHECKSTATE_ANY, // [r1] v2, port or any OPTYPE_CHECKSTATE_ALL, // [r1] v2, port or all OPTYPE_HOSTID, // [v1] @@ -281,7 +282,7 @@ namespace Common { OPTYPE_GET_PORT_REF, // - - NUMBER_OF_OPTYPES // must be last + NUMBER_OF_OPTYPES // must be last 120 }; enum macrotype_t { diff --git a/compiler2/ttcn3/compiler.l b/compiler2/ttcn3/compiler.l index 9c40574c4db9a038e620e517ced19fa1bcfd3ac9..563588c694105ac64b99924d33aa8c7944166fca 100644 --- a/compiler2/ttcn3/compiler.l +++ b/compiler2/ttcn3/compiler.l @@ -451,6 +451,7 @@ none RETURN(NoneKeyword); not RETURN(NotKeyword); not_a_number RETURN(NaNKeyword); not4b RETURN(Not4bKeyword); +now RETURN(NowKeyword); nowait RETURN(NowaitKeyword); null RETURN(NullKeyword); objid RETURN(ObjectIdentifierKeyword); diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y index cc5fdbb26aaf2190cacf4eb0adcb22c7d8703464..42e566f2ea01494c31e8a5a52438245370191b81 100644 --- a/compiler2/ttcn3/compiler.y +++ b/compiler2/ttcn3/compiler.y @@ -719,6 +719,7 @@ static const string anyname("anytype"); %token NoneKeyword %token NotKeyword %token Not4bKeyword +%token NowKeyword %token NowaitKeyword %token NullKeyword %token ObjectIdentifierKeyword @@ -9444,6 +9445,11 @@ OpCall: // 611 $$ = new Value(Value::OPTYPE_GET_PORT_REF); $$->set_location(infile, @$); } +| NowKeyword + { + $$ = new Value(Value::OPTYPE_NOW); + $$->set_location(infile, @$); + } ; PredefinedOps: diff --git a/core/Communication.cc b/core/Communication.cc index 84d4b620f6a4b1a20dcec0b9fa4281306156d3bd..bf4c2ccbefe7e06e435531d35c956af483e1cf4f 100644 --- a/core/Communication.cc +++ b/core/Communication.cc @@ -29,6 +29,7 @@ #include <errno.h> #include <fcntl.h> #include <netdb.h> +#include <time.h> #include <sys/types.h> #include <sys/socket.h> @@ -850,7 +851,7 @@ void TTCN_Communication::send_hc_ready() void TTCN_Communication::send_create_req(const char *component_type_module, const char *component_type_name, const char *component_name, - const char *component_location, boolean is_alive) + const char *component_location, boolean is_alive, timeval testcase_start_time) { Text_Buf text_buf; text_buf.push_int(MSG_CREATE_REQ); @@ -859,6 +860,8 @@ void TTCN_Communication::send_create_req(const char *component_type_module, text_buf.push_string(component_name); text_buf.push_string(component_location); text_buf.push_int(is_alive ? 1 : 0); + text_buf.push_int(testcase_start_time.tv_sec); + text_buf.push_int(testcase_start_time.tv_usec); send_message(text_buf); } @@ -1377,6 +1380,9 @@ void TTCN_Communication::process_create_ptc() boolean is_alive = incoming_buf.pull_int().get_val(); qualified_name current_testcase; incoming_buf.pull_qualified_name(current_testcase); + timeval testcase_start_time; + testcase_start_time.tv_sec = incoming_buf.pull_int().get_val(); + testcase_start_time.tv_usec = incoming_buf.pull_int().get_val(); incoming_buf.cut_message(); try { @@ -1384,7 +1390,7 @@ void TTCN_Communication::process_create_ptc() component_type.module_name, component_type.definition_name, system_type.module_name, system_type.definition_name, component_name, is_alive, current_testcase.module_name, - current_testcase.definition_name); + current_testcase.definition_name, testcase_start_time); } catch (...) { // to prevent from memory leaks delete [] component_type.module_name; diff --git a/core/Communication.hh b/core/Communication.hh index a73b50cbe35f6895862d8bc7e57b11a91616efea..9334e4e6aa2ac0d976a6d107cbedad36e6768dd0 100644 --- a/core/Communication.hh +++ b/core/Communication.hh @@ -85,7 +85,8 @@ public: static void send_create_req(const char *component_type_module, const char *component_type_name, const char *component_name, - const char *component_location, boolean is_alive); + const char *component_location, boolean is_alive, + timeval testcase_start_time); static void prepare_start_req(Text_Buf& text_buf, component component_reference, const char *module_name, const char *function_name); diff --git a/core/Runtime.cc b/core/Runtime.cc index 3f046eb9d80d233ea66635b1e7d40c0a23de2557..27bdba48f001a4abaa23581571bd7b9a38f9280a 100644 --- a/core/Runtime.cc +++ b/core/Runtime.cc @@ -60,6 +60,7 @@ #include <TitanLoggerApi.hh> #include "Profiler.hh" #include "Integer.hh" +#include "Float.hh" #include "Port.hh" namespace API = TitanLoggerApi; @@ -80,6 +81,7 @@ boolean TTCN_Runtime::is_alive = FALSE; const char *TTCN_Runtime::control_module_name = NULL; qualified_name TTCN_Runtime::testcase_name = { NULL, NULL }; +timeval TTCN_Runtime::start_time = { 0, 0 }; char *TTCN_Runtime::host_name = NULL; @@ -397,6 +399,20 @@ CHARSTRING TTCN_Runtime::get_testcasename() return CHARSTRING(testcase_name.definition_name); } +FLOAT TTCN_Runtime::now() +{ + if (start_time.tv_sec == 0 && start_time.tv_usec == 0) { + TTCN_error("Accessing the test system time while no test case is running."); + } + + struct timeval current_time; + if (gettimeofday(¤t_time, NULL) == -1) { + TTCN_error("gettimeofday() system call failed."); + } + return FLOAT((double)(current_time.tv_sec - start_time.tv_sec) + + 1e-6 * (double)(current_time.tv_usec - start_time.tv_usec)); +} + void TTCN_Runtime::load_logger_plugins() { TTCN_Logger::load_plugins((component)self, component_name); @@ -694,7 +710,7 @@ component TTCN_Runtime::create_component( } TTCN_Communication::send_create_req(created_component_type_module, created_component_type_name, created_component_name, - created_component_location, created_component_alive); + created_component_location, created_component_alive, start_time); if (is_mtc()) { // updating the component status flags // 'any component.done' and 'any component.killed' might be successful @@ -2077,6 +2093,9 @@ void TTCN_Runtime::begin_testcase( all_component_done_status = ALT_YES; any_component_killed_status = ALT_NO; all_component_killed_status = ALT_YES; + if (gettimeofday(&start_time, NULL) == -1) { + TTCN_error("gettimeofday() system call failed."); + } } verdicttype TTCN_Runtime::end_testcase() @@ -2134,6 +2153,8 @@ verdicttype TTCN_Runtime::end_testcase() // restore the control part timers and defaults TTCN_Default::restore_control_defaults(); TIMER::restore_control_timers(); + start_time.tv_sec = 0; + start_time.tv_usec = 0; if (executor_state == MTC_PAUSED) { TTCN_Logger::log_executor_runtime( API::ExecutorRuntime_reason::user__paused__waiting__to__resume); @@ -2446,7 +2467,8 @@ void TTCN_Runtime::process_create_ptc(component component_reference, const char *component_type_module, const char *component_type_name, const char *system_type_module, const char *system_type_name, const char *par_component_name, boolean par_is_alive, - const char *current_testcase_module, const char *current_testcase_name) + const char *current_testcase_module, const char *current_testcase_name, + timeval testcase_start_time) { switch (executor_state) { case HC_ACTIVE: @@ -2495,6 +2517,7 @@ void TTCN_Runtime::process_create_ptc(component component_reference, set_component_name(par_component_name); is_alive = par_is_alive; set_testcase_name(current_testcase_module, current_testcase_name); + start_time = testcase_start_time; executor_state = PTC_INITIAL; } } diff --git a/core/Runtime.hh b/core/Runtime.hh index e3ec3f13c3c68be9e5ca82e0b69265b41d397886..de12671aab6c11e9d0f9d4613878c1ad011e6529 100644 --- a/core/Runtime.hh +++ b/core/Runtime.hh @@ -23,6 +23,7 @@ #define RUNTIME_HH #include <sys/types.h> +#include <time.h> #include "Types.h" class Text_Buf; @@ -30,6 +31,7 @@ class COMPONENT; class VERDICTTYPE; class CHARSTRING; class INTEGER; +class FLOAT; class PORT; extern "C" { @@ -68,6 +70,8 @@ private: static const char *control_module_name; static qualified_name testcase_name; + + static timeval start_time; static char *host_name; @@ -176,6 +180,8 @@ public: static CHARSTRING get_testcase_id_macro(); static CHARSTRING get_testcasename(); + + static FLOAT now(); static void load_logger_plugins(); static void set_logger_parameters(); @@ -313,7 +319,8 @@ public: const char *component_type_module, const char *component_type_name, const char *system_type_module, const char *system_type_name, const char *par_component_name, boolean par_is_alive, - const char *current_testcase_module, const char *current_testcase_name); + const char *current_testcase_module, const char *current_testcase_name, + timeval testcase_start_time); static void process_create_ack(component new_component); static void process_running(boolean result_value); diff --git a/function_test/Semantic_Analyser/Makefile.semantic b/function_test/Semantic_Analyser/Makefile.semantic index b2489c0657973aca06a01ee2dd9de7cb6166e912..2fca67933dee51dfe3443b9222789c5b0172c4fe 100644 --- a/function_test/Semantic_Analyser/Makefile.semantic +++ b/function_test/Semantic_Analyser/Makefile.semantic @@ -16,7 +16,7 @@ include ../../Makefile.personal SADIRS := ver param template any_from pattern_ref float recof_index \ port_translation mtc_and_system_clause port_map_connect deterministic invoking_function_from_specific_places \ -json +json realtime ifdef RT2 SADIRS += deprecated erroneous_attributes template_concat endif diff --git a/function_test/Semantic_Analyser/realtime/.gitignore b/function_test/Semantic_Analyser/realtime/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2d293255e6d2f314e34950e486a48630d873491 --- /dev/null +++ b/function_test/Semantic_Analyser/realtime/.gitignore @@ -0,0 +1,2 @@ +!Makefile +!*.ttcn diff --git a/function_test/Semantic_Analyser/realtime/Makefile b/function_test/Semantic_Analyser/realtime/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8c650452065be483f7b5a23c9c4721c06812f962 --- /dev/null +++ b/function_test/Semantic_Analyser/realtime/Makefile @@ -0,0 +1,12 @@ +############################################################################## +# Copyright (c) 2000-2018 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################## +include ../common.mk diff --git a/function_test/Semantic_Analyser/realtime/realtimeNow_SE.ttcn b/function_test/Semantic_Analyser/realtime/realtimeNow_SE.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..c5dc66f1007c42a8f547351499e644a98c901535 --- /dev/null +++ b/function_test/Semantic_Analyser/realtime/realtimeNow_SE.ttcn @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright (c) 2000-2018 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ + +/* This module tests the keyword 'now', which querries the current test system time. */ +module realtimeNow_SE { //^In TTCN-3 module// + +const float c := now; //^In constant definition// //error\: Operation `now' can only be used in testcases, functions or altsteps// + +template float t := now; //^In template definition// //error\: Operation `now' can only be used in testcases, functions or altsteps// + +type component CT { //^In type definition// //^In component element definitions// + var float cv := now; //^In variable definition// //error\: Operation `now' can only be used in testcases, functions or altsteps// +} + +function f(in float p := now) { //^In function definition// //^In formal parameter list// //^In parameter// //^In default value// //error\: Operation `now' can only be used in testcases, functions or altsteps// + timer tmr; + tmr.start(1.0); + alt { //^In alt construct// + [now > 0.0] tmr.timeout {} //^In guard expression// //error\: Operation 'now' cannot be used in alt guards// + } +} + +control { //^In control part// + log(now); //^In log statement// //error\: Operation `now' can only be used in testcases, functions or altsteps// +} + +} diff --git a/function_test/Semantic_Analyser/realtime/t b/function_test/Semantic_Analyser/realtime/t new file mode 100755 index 0000000000000000000000000000000000000000..3a4b58ec16cf2f1390a36c7a92f8823e3b94b425 --- /dev/null +++ b/function_test/Semantic_Analyser/realtime/t @@ -0,0 +1,9 @@ +#!/usr/bin/perl +# note this is called through "perl -w" +use strict; + +my $self = $0; +$self =~ s!/t!!; + +exec('make check --no-print-directory -s -C ' . $self); + diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc index 25adf9b098bac0590e03f0a5474e164c77e1bed6..2d63097752a611b597767d9e95043ae609df0527 100644 --- a/mctr2/mctr/MainController.cc +++ b/mctr2/mctr/MainController.cc @@ -874,6 +874,7 @@ boolean MainController::any_component_done_requested, MainController::all_component_done_requested, MainController::any_component_killed_requested, MainController::all_component_killed_requested; +timeval MainController::testcase_start_time; void MainController::add_component(component_struct *comp) { @@ -3243,6 +3244,8 @@ void MainController::send_create_ptc(host_struct *hc, text_buf.push_string(component_name); text_buf.push_int(is_alive ? 1 : 0); text_buf.push_qualified_name(current_testcase); + text_buf.push_int(testcase_start_time.tv_sec); + text_buf.push_int(testcase_start_time.tv_usec); send_message(hc->hc_fd, text_buf); } @@ -4119,6 +4122,8 @@ void MainController::process_create_req(component_struct *tc) component_location = NULL; } boolean is_alive = text_buf.pull_int().get_val(); + testcase_start_time.tv_sec = text_buf.pull_int().get_val(); + testcase_start_time.tv_usec = text_buf.pull_int().get_val(); host_struct *host = choose_ptc_location(component_type.definition_name, component_name, component_location); diff --git a/mctr2/mctr/MainController.h b/mctr2/mctr/MainController.h index 1a15e5fba342e3278fe3714a0be45c84ddaa261e..0ff512d6fff9546471388b521f72db5a6c0a5145 100644 --- a/mctr2/mctr/MainController.h +++ b/mctr2/mctr/MainController.h @@ -35,6 +35,7 @@ #include <pthread.h> #include <sys/types.h> #include <netinet/in.h> +#include <time.h> #include "../../core/Types.h" #include "../../common/NetworkHandler.hh" @@ -364,6 +365,7 @@ class MainController { static boolean any_component_done_requested, any_component_done_sent, all_component_done_requested, any_component_killed_requested, all_component_killed_requested; + static timeval testcase_start_time; static void add_component(component_struct *comp); static component_struct *lookup_component(component comp_ref); static void destroy_all_components(); diff --git a/regression_test/Makefile b/regression_test/Makefile index eb47a9d1daf75df0e7c947ed2686917eb529ebeb..c3db18b1274f9d1ded4b01d7ede8a0cd00fbeceb 100644 --- a/regression_test/Makefile +++ b/regression_test/Makefile @@ -49,7 +49,7 @@ all_from lazyEval tryCatch text2ttcn json ttcn2json profiler templateOmit \ customEncoding makefilegen uidChars checkstate hostid templateIstemplatekind \ selectUnion templateExclusiveRange any_from templatePatternRef indexWithRecofArray \ connectMapOperTest fuzzy portTranslation ischosen OER functionSubref done \ -nondeterministicDefaultParam predefFunction2 +nondeterministicDefaultParam predefFunction2 realtime ifdef DYN DIRS += loggerplugin junitlogger diff --git a/regression_test/realtime/.gitignore b/regression_test/realtime/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dde473e4b790d23d5209fabd0806b0f0d61c6c50 --- /dev/null +++ b/regression_test/realtime/.gitignore @@ -0,0 +1,5 @@ +realtime +realtime.exe +realtimeNow*.cc +realtimeNow*.hh +realtime*.log diff --git a/regression_test/realtime/Makefile b/regression_test/realtime/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a73eac7511b824bb81c532e75f6310e24faaab1c --- /dev/null +++ b/regression_test/realtime/Makefile @@ -0,0 +1,54 @@ +############################################################################## +# Copyright (c) 2000-2018 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Botond, Baranyi – initial implementation +# +############################################################################## +TOPDIR := .. +include $(TOPDIR)/Makefile.regression + +.SUFFIXES: .ttcn .hh +.PHONY: all clean dep run + +TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX) + +TTCN3_MODULES = realtimeNow.ttcn + +GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) +GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) +ifdef CODE_SPLIT +GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc)) +else ifdef SPLIT_TO_SLICES +POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_)) +POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc)) +GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES))) +GENERATED_SOURCES += $(GENERATED_SOURCES2) +endif + +OBJECTS = $(GENERATED_SOURCES:.cc=.o) + +TARGET = realtime$(EXESUFFIX) + +all: $(TARGET) + +$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS) + +.ttcn.cc .ttcn.hh: + $(TTCN3_COMPILER) $< + +clean distclean: + -rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) *.log Makefile.bak + +dep: $(GENERATED_SOURCES) + makedepend $(CPPFLAGS) $(GENERATED_SOURCES) + +run: $(TARGET) config.cfg + $(TTCN3_DIR)/bin/ttcn3_start $^ + diff --git a/regression_test/realtime/config.cfg b/regression_test/realtime/config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..6f3814cafd76d0ebb6bddfa5c013b52b0fa8211f --- /dev/null +++ b/regression_test/realtime/config.cfg @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2000-2018 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################### +[LOGGING] +LogFile := "realtime_%r.log" +FileMask := LOG_ALL +ConsoleMask := TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS + +[EXECUTE] +realtimeNow diff --git a/regression_test/realtime/realtimeNow.ttcn b/regression_test/realtime/realtimeNow.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..10f828c47a547d98898ca974c564a91ffe08eac9 --- /dev/null +++ b/regression_test/realtime/realtimeNow.ttcn @@ -0,0 +1,53 @@ +/****************************************************************************** + * Copyright (c) 2000-2018 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ + +// This module tests the keyword 'now', which querries the current test system time. +module realtimeNow { + +type component CT {} + +type record of float FloatList; + +function f_test_now(in float p_caller_time) runs on CT { + var float time_now := now; + if (p_caller_time > time_now) { + setverdict(fail, "Comparison with caller time failed. Caller: ", p_caller_time, ", now: ", time_now); + } + var FloatList times := {}; + for (var integer i := 0; i < 100; i := i + 1) { + timer t := 0.01; + t.start; + t.timeout; + times[i] := now; + if (i > 0 and times[i] < times[i - 1]) { + setverdict(fail, "Measured times are not ascending: ", times); + } + } + setverdict(pass); +} + +testcase tc_now_mtc() runs on CT { + f_test_now(now); +} + +testcase tc_now_ptc() runs on CT { + var CT ct := CT.create; + ct.start(f_test_now(now)); + ct.done; +} + +control { + execute(tc_now_mtc()); + execute(tc_now_ptc()); +} + +}