понедельник, 17 декабря 2018 г.

[prog.c++] Поддержка unit-тестирования для агентов в SObjectizer-е начинает дышать!

То, о чем так долго говорили больше, начинает приобретать не просто реальные очертания, а уже оставляет вполне осязаемые плоды своей жизнедеятельности. Под катом работающий код для тестирования поведения пусть и тривиального, но реального агента.

Важная штука: средства для тестирования агентов будут входить прямо в состав SObjectizer-5.5. Это значит, что в их реализации нам придется ориентироваться на какое-то подмножество C++11, что нас не радует. Но, думаю, возможность писать тестовые сценарии для агентов без необходимости ставить себе какой-нибудь so_5_extra, сделает SObjectizer привлекательнее для тех, кто еще кипятит не решился сделать выбор в пользу SObjectizer-а (и кого, может быть, смущает двойное лицензирование so_5_extra).

Еще очень и очень многое предстоит сделать, как в коде, так и в документации. Даже то, что реализовано сейчас, представляет из себя грязный черновой код, который еще предстоит доводить напильником, причесывать и документировать. Шансы успеть до Нового Года есть, но это если никаких принципиальных барьеров не возникнет.

Тем не менее, отрадно.

#include <so_5/experimental/testing/v1/all.hpp>

#include <various_helpers_1/time_limited_execution.hpp>
#include <various_helpers_1/ensure.hpp>

namespace tests = so_5::experimental::testing::v1;

struct hello final : public so_5::signal_t {};

class test_agent_t final : public so_5::agent_t
{
public :
   test_agent_t( context_t ctx )
      :  so_5::agent_t( std::move(ctx) )
   {
      so_subscribe_self().event( &test_agent_t::on_hello );
   }

private :
   void
   on_hello( mhood_t<hello> )
   {
      std::cout << "Hello!" << std::endl;
   }
};

int
main()
{
   run_with_time_limit(
      []()
      {
         tests::testing_env_t env;

         so_5::agent_t * test_agent;
         env.environment().introduce_coop( [&](so_5::coop_t & coop) {
               test_agent = coop.make_agent< test_agent_t >();
            } );

         env.scenario().define_step( "hello_received" )
            .impact( [test_agent] { so_5::send<hello>(*test_agent); } )
            .triggers_when( *test_agent & tests::reacts_to< hello >() );

         env.scenario().run_for( std::chrono::seconds(1) );

         ensure_or_die( env.scenario().completed(),
               "scenario should complete its work" );
      },
      5 );

   return 0;
}

Комментариев нет: