#include <balancer/kernel/custom_io/queue.h>
#include <library/cpp/testing/unittest/registar.h>

Y_UNIT_TEST_SUITE(TBalancerQueueTest) {
    using namespace NSrvKernel;
    static const char DATA[] = "test0test1test2test3test4";

    Y_UNIT_TEST(TestChunkQueue) {
        TContExecutor e(32000);
        TChunkQueue queue(&e);

        auto popCont = [&queue](TCont* /*cont*/) {
            TChunkList chuck;
            Y_UNUSED(queue.Pop(chuck, TInstant::Zero()));
            UNIT_ASSERT_EQUAL(chuck, DATA);
            UNIT_ASSERT_EQUAL(queue.InQueue(), 0);
            UNIT_ASSERT_EQUAL(queue.Pop(chuck, TInstant::Zero()), ETIMEDOUT);
        };

        auto pushCont = [&queue, &popCont](TCont* cont) {
            for (int i = 0; i < 5; ++i) {
                queue.Push(TChunkList("test" + ToString(i)));
            }
            UNIT_ASSERT_EQUAL(queue.InQueue(), 25);
            cont->Executor()->Create(popCont, "pop_cont");
        };

        e.Execute(pushCont);
    }

    Y_UNIT_TEST(TestLimitedChunkQueue) {
        TContExecutor e(32000);
        TLimitedChunkQueue queue(&e, 25);

        auto popCont = [&queue](TCont* /*cont*/) {
            TChunkList chuck;
            queue.Pop(chuck, TInstant::Zero());
            UNIT_ASSERT_EQUAL(chuck, DATA);
            UNIT_ASSERT_EQUAL(queue.InQueue(), 0);
            UNIT_ASSERT_EQUAL(queue.Pop(chuck, TInstant::Zero()), ETIMEDOUT);
        };

        auto pushCont = [&queue, &popCont](TCont* cont) {
            for (int i = 0; i < 10; ++i) {
                queue.Push(TChunkList("test" + ToString(i)));
            }
            UNIT_ASSERT_EQUAL(queue.InQueue(), 25);
            UNIT_ASSERT_EQUAL(queue.Dropped(), 25);
            cont->Executor()->Create(popCont, "pop_cont");
        };

        e.Execute(pushCont);
    }
};
