123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- #include <library/cpp/testing/unittest/registar.h>
- #include "actor.h"
- #include "queue_in_actor.h"
- #include <library/cpp/messagebus/misc/test_sync.h>
- #include <util/generic/object_counter.h>
- #include <util/system/event.h>
- using namespace NActor;
- template <typename TThis>
- struct TTestActorBase: public TAtomicRefCount<TThis>, public TActor<TThis> {
- TTestSync Started;
- TTestSync Acted;
- TTestActorBase(TExecutor* executor)
- : TActor<TThis>(executor)
- {
- }
- void Act(TDefaultTag) {
- Started.Inc();
- static_cast<TThis*>(this)->Act2();
- Acted.Inc();
- }
- };
- struct TNopActor: public TTestActorBase<TNopActor> {
- TObjectCounter<TNopActor> AllocCounter;
- TNopActor(TExecutor* executor)
- : TTestActorBase<TNopActor>(executor)
- {
- }
- void Act2() {
- }
- };
- struct TWaitForSignalActor: public TTestActorBase<TWaitForSignalActor> {
- TWaitForSignalActor(TExecutor* executor)
- : TTestActorBase<TWaitForSignalActor>(executor)
- {
- }
- TSystemEvent WaitFor;
- void Act2() {
- WaitFor.Wait();
- }
- };
- struct TDecrementAndSendActor: public TTestActorBase<TDecrementAndSendActor>, public TQueueInActor<TDecrementAndSendActor, int> {
- TSystemEvent Done;
- TDecrementAndSendActor* Next;
- TDecrementAndSendActor(TExecutor* executor)
- : TTestActorBase<TDecrementAndSendActor>(executor)
- , Next(nullptr)
- {
- }
- void ProcessItem(TDefaultTag, TDefaultTag, int n) {
- if (n == 0) {
- Done.Signal();
- } else {
- Next->EnqueueAndSchedule(n - 1);
- }
- }
- void Act(TDefaultTag) {
- DequeueAll();
- }
- };
- struct TObjectCountChecker {
- TObjectCountChecker() {
- CheckCounts();
- }
- ~TObjectCountChecker() {
- CheckCounts();
- }
- void CheckCounts() {
- UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TNopActor>::ObjectCount());
- UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TWaitForSignalActor>::ObjectCount());
- UNIT_ASSERT_VALUES_EQUAL(TAtomicBase(0), TObjectCounter<TDecrementAndSendActor>::ObjectCount());
- }
- };
- Y_UNIT_TEST_SUITE(TActor) {
- Y_UNIT_TEST(Simple) {
- TObjectCountChecker objectCountChecker;
- TExecutor executor(4);
- TIntrusivePtr<TNopActor> actor(new TNopActor(&executor));
- actor->Schedule();
- actor->Acted.WaitFor(1u);
- }
- Y_UNIT_TEST(ScheduleAfterStart) {
- TObjectCountChecker objectCountChecker;
- TExecutor executor(4);
- TIntrusivePtr<TWaitForSignalActor> actor(new TWaitForSignalActor(&executor));
- actor->Schedule();
- actor->Started.WaitFor(1);
- actor->Schedule();
- actor->WaitFor.Signal();
- // make sure Act is called second time
- actor->Acted.WaitFor(2u);
- }
- void ComplexImpl(int queueSize, int actorCount) {
- TObjectCountChecker objectCountChecker;
- TExecutor executor(queueSize);
- TVector<TIntrusivePtr<TDecrementAndSendActor>> actors;
- for (int i = 0; i < actorCount; ++i) {
- actors.push_back(new TDecrementAndSendActor(&executor));
- }
- for (int i = 0; i < actorCount; ++i) {
- actors.at(i)->Next = &*actors.at((i + 1) % actorCount);
- }
- for (int i = 0; i < actorCount; ++i) {
- actors.at(i)->EnqueueAndSchedule(10000);
- }
- for (int i = 0; i < actorCount; ++i) {
- actors.at(i)->Done.WaitI();
- }
- }
- Y_UNIT_TEST(ComplexContention) {
- ComplexImpl(4, 6);
- }
- Y_UNIT_TEST(ComplexNoContention) {
- ComplexImpl(6, 4);
- }
- }
|