summaryrefslogtreecommitdiff
path: root/libs/tdlib/td/test/tdclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/tdlib/td/test/tdclient.cpp')
-rw-r--r--libs/tdlib/td/test/tdclient.cpp837
1 files changed, 0 insertions, 837 deletions
diff --git a/libs/tdlib/td/test/tdclient.cpp b/libs/tdlib/td/test/tdclient.cpp
deleted file mode 100644
index 7cef0fcbc0..0000000000
--- a/libs/tdlib/td/test/tdclient.cpp
+++ /dev/null
@@ -1,837 +0,0 @@
-//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-#include "data.h"
-
-#include "td/actor/PromiseFuture.h"
-
-#include "td/telegram/ClientActor.h"
-
-#include "td/telegram/td_api.h"
-
-#include "td/utils/base64.h"
-#include "td/utils/BufferedFd.h"
-#include "td/utils/filesystem.h"
-#include "td/utils/format.h"
-#include "td/utils/logging.h"
-#include "td/utils/misc.h"
-#include "td/utils/port/FileFd.h"
-#include "td/utils/port/path.h"
-#include "td/utils/Random.h"
-#include "td/utils/Slice.h"
-#include "td/utils/Status.h"
-#include "td/utils/tests.h"
-
-#include <cstdio>
-#include <functional>
-#include <map>
-#include <memory>
-#include <utility>
-
-REGISTER_TESTS(tdclient);
-
-namespace td {
-
-template <class T>
-static void check_td_error(T &result) {
- CHECK(result->get_id() != td_api::error::ID) << to_string(result);
-}
-
-static void rmrf(CSlice path) {
- td::walk_path(path, [](CSlice path, bool is_dir) {
- if (is_dir) {
- td::rmdir(path).ignore();
- } else {
- td::unlink(path).ignore();
- }
- });
-}
-
-class TestClient : public Actor {
- public:
- explicit TestClient(string name) : name_(std::move(name)) {
- }
- struct Update {
- uint64 id;
- tl_object_ptr<td_api::Object> object;
- Update(uint64 id, tl_object_ptr<td_api::Object> object) : id(id), object(std::move(object)) {
- }
- };
- class Listener {
- public:
- Listener() = default;
- Listener(const Listener &) = delete;
- Listener &operator=(const Listener &) = delete;
- Listener(Listener &&) = delete;
- Listener &operator=(Listener &&) = delete;
- virtual ~Listener() = default;
- virtual void start_listen(TestClient *client) {
- }
- virtual void stop_listen() {
- }
- virtual void on_update(std::shared_ptr<Update> update) = 0;
- };
- void close(Promise<> close_promise) {
- close_promise_ = std::move(close_promise);
- td_.reset();
- }
-
- unique_ptr<TdCallback> make_td_callback() {
- class TdCallbackImpl : public TdCallback {
- public:
- explicit TdCallbackImpl(ActorId<TestClient> client) : client_(client) {
- }
- void on_result(uint64 id, tl_object_ptr<td_api::Object> result) override {
- send_closure(client_, &TestClient::on_result, id, std::move(result));
- }
- void on_error(uint64 id, tl_object_ptr<td_api::error> error) override {
- send_closure(client_, &TestClient::on_error, id, std::move(error));
- }
- void on_closed() override {
- send_closure(client_, &TestClient::on_closed);
- }
-
- private:
- ActorId<TestClient> client_;
- };
- return make_unique<TdCallbackImpl>(actor_id(this));
- }
-
- void add_listener(std::unique_ptr<Listener> listener) {
- auto *ptr = listener.get();
- listeners_.push_back(std::move(listener));
- ptr->start_listen(this);
- }
- void remove_listener(Listener *listener) {
- pending_remove_.push_back(listener);
- }
- void do_pending_remove_listeners() {
- for (auto listener : pending_remove_) {
- do_remove_listener(listener);
- }
- pending_remove_.clear();
- }
- void do_remove_listener(Listener *listener) {
- for (size_t i = 0; i < listeners_.size(); i++) {
- if (listeners_[i].get() == listener) {
- listener->stop_listen();
- listeners_.erase(listeners_.begin() + i);
- break;
- }
- }
- }
-
- void on_result(uint64 id, tl_object_ptr<td_api::Object> result) {
- on_update(std::make_shared<Update>(id, std::move(result)));
- }
- void on_error(uint64 id, tl_object_ptr<td_api::error> error) {
- on_update(std::make_shared<Update>(id, std::move(error)));
- }
- void on_update(std::shared_ptr<Update> update) {
- for (auto &listener : listeners_) {
- listener->on_update(update);
- }
- do_pending_remove_listeners();
- }
-
- void on_closed() {
- stop();
- }
-
- void start_up() override {
- rmrf(name_);
- set_context(std::make_shared<td::ActorContext>());
- set_tag(name_);
- LOG(INFO) << "START UP!";
-
- td_ = create_actor<ClientActor>("Td-proxy", make_td_callback());
- }
-
- ActorOwn<ClientActor> td_;
-
- string name_;
-
- private:
- std::vector<std::unique_ptr<Listener>> listeners_;
- std::vector<Listener *> pending_remove_;
-
- Promise<> close_promise_;
-};
-
-class Task : public TestClient::Listener {
- public:
- void on_update(std::shared_ptr<TestClient::Update> update) override {
- auto it = sent_queries_.find(update->id);
- if (it != sent_queries_.end()) {
- it->second(std::move(update->object));
- sent_queries_.erase(it);
- }
- process_update(update);
- }
- void start_listen(TestClient *client) override {
- client_ = client;
- start_up();
- }
- virtual void process_update(std::shared_ptr<TestClient::Update> update) {
- }
-
- template <class F>
- void send_query(tl_object_ptr<td_api::Function> function, F callback) {
- auto id = current_query_id_++;
- sent_queries_[id] = std::forward<F>(callback);
- send_closure(client_->td_, &ClientActor::request, id, std::move(function));
- }
-
- protected:
- std::map<uint64, std::function<void(tl_object_ptr<td_api::Object>)>> sent_queries_;
- TestClient *client_;
- uint64 current_query_id_ = 1;
-
- virtual void start_up() {
- }
- void stop() {
- client_->remove_listener(this);
- }
-};
-
-class DoAuthentication : public Task {
- public:
- DoAuthentication(string name, string phone, string code, Promise<> promise)
- : name_(std::move(name)), phone_(std::move(phone)), code_(std::move(code)), promise_(std::move(promise)) {
- }
- void start_up() override {
- send_query(make_tl_object<td_api::getAuthorizationState>(),
- [this](auto res) { this->process_authorization_state(std::move(res)); });
- }
- void process_authorization_state(tl_object_ptr<td_api::Object> authorization_state) {
- start_flag_ = true;
- tl_object_ptr<td_api::Function> function;
- switch (authorization_state->get_id()) {
- case td_api::authorizationStateWaitEncryptionKey::ID:
- function = make_tl_object<td_api::checkDatabaseEncryptionKey>();
- break;
- case td_api::authorizationStateWaitPhoneNumber::ID:
- function = make_tl_object<td_api::setAuthenticationPhoneNumber>(phone_, false, true);
- break;
- case td_api::authorizationStateWaitCode::ID:
- function = make_tl_object<td_api::checkAuthenticationCode>(code_, name_, "");
- break;
- case td_api::authorizationStateWaitTdlibParameters::ID: {
- auto parameters = td_api::make_object<td_api::tdlibParameters>();
- parameters->use_test_dc_ = true;
- parameters->database_directory_ = name_ + TD_DIR_SLASH;
- parameters->use_message_database_ = true;
- parameters->use_secret_chats_ = true;
- parameters->api_id_ = 94575;
- parameters->api_hash_ = "a3406de8d171bb422bb6ddf3bbd800e2";
- parameters->system_language_code_ = "en";
- parameters->device_model_ = "Desktop";
- parameters->system_version_ = "Unknown";
- parameters->application_version_ = "tdclient-test";
- parameters->ignore_file_names_ = false;
- parameters->enable_storage_optimizer_ = true;
- function = td_api::make_object<td_api::setTdlibParameters>(std::move(parameters));
- break;
- }
- case td_api::authorizationStateReady::ID:
- on_authorization_ready();
- return;
- default:
- CHECK(false) << "Unexpected authorization state " << to_string(authorization_state);
- }
- send_query(std::move(function), [this](auto res) { CHECK(res->get_id() == td_api::ok::ID) << to_string(res); });
- }
- void on_authorization_ready() {
- LOG(INFO) << "GOT AUTHORIZED";
- stop();
- }
-
- private:
- string name_;
- string phone_;
- string code_;
- Promise<> promise_;
- bool start_flag_{false};
- void process_update(std::shared_ptr<TestClient::Update> update) override {
- if (!start_flag_) {
- return;
- }
- if (!update->object) {
- return;
- }
- if (update->object->get_id() == td_api::updateAuthorizationState::ID) {
- auto o = std::move(update->object);
- process_authorization_state(std::move(static_cast<td_api::updateAuthorizationState &>(*o).authorization_state_));
- }
- }
-};
-
-class SetUsername : public Task {
- public:
- SetUsername(string username, Promise<> promise) : username_(std::move(username)), promise_(std::move(promise)) {
- }
-
- private:
- string username_;
- Promise<> promise_;
- int32 self_id_;
- string tag_;
-
- void start_up() override {
- send_query(make_tl_object<td_api::getMe>(), [this](auto res) { this->process_me_user(std::move(res)); });
- }
-
- void process_me_user(tl_object_ptr<td_api::Object> res) {
- CHECK(res->get_id() == td_api::user::ID);
- auto user = move_tl_object_as<td_api::user>(res);
- self_id_ = user->id_;
- if (user->username_ != username_) {
- LOG(INFO) << "SET USERNAME: " << username_;
- send_query(make_tl_object<td_api::setUsername>(username_), [this](auto res) {
- CHECK(res->get_id() == td_api::ok::ID);
- this->send_self_message();
- });
- } else {
- send_self_message();
- }
- }
- void send_self_message() {
- tag_ = PSTRING() << format::as_hex(Random::secure_int64());
-
- send_query(make_tl_object<td_api::createPrivateChat>(self_id_, false), [this](auto res) {
- CHECK(res->get_id() == td_api::chat::ID);
- auto chat = move_tl_object_as<td_api::chat>(res);
- this->send_query(
- make_tl_object<td_api::sendMessage>(
- chat->id_, 0, false, false, nullptr,
- make_tl_object<td_api::inputMessageText>(
- make_tl_object<td_api::formattedText>(PSTRING() << tag_ << " INIT", Auto()), false, false)),
- [](auto res) {});
- });
- }
-
- void process_update(std::shared_ptr<TestClient::Update> update) override {
- if (!update->object) {
- return;
- }
- if (update->object->get_id() == td_api::updateMessageSendSucceeded::ID) {
- auto updateNewMessage = move_tl_object_as<td_api::updateMessageSendSucceeded>(update->object);
- auto &message = updateNewMessage->message_;
- if (message->content_->get_id() == td_api::messageText::ID) {
- auto messageText = move_tl_object_as<td_api::messageText>(message->content_);
- auto text = messageText->text_->text_;
- if (text.substr(0, tag_.size()) == tag_) {
- LOG(INFO) << "GOT SELF MESSAGE";
- return stop();
- }
- }
- }
- }
-};
-
-class CheckTestA : public Task {
- public:
- CheckTestA(string tag, Promise<> promise) : tag_(std::move(tag)), promise_(std::move(promise)) {
- }
-
- private:
- string tag_;
- Promise<> promise_;
- string previous_text_;
- int cnt_ = 20;
- void process_update(std::shared_ptr<TestClient::Update> update) override {
- if (update->object->get_id() == td_api::updateNewMessage::ID) {
- auto updateNewMessage = move_tl_object_as<td_api::updateNewMessage>(update->object);
- auto &message = updateNewMessage->message_;
- if (message->content_->get_id() == td_api::messageText::ID) {
- auto messageText = move_tl_object_as<td_api::messageText>(message->content_);
- auto text = messageText->text_->text_;
- if (text.substr(0, tag_.size()) == tag_) {
- CHECK(text > previous_text_) << tag("now", text) << tag("previous", previous_text_);
- previous_text_ = text;
- cnt_--;
- LOG(INFO) << "GOT " << tag("text", text) << tag("left", cnt_);
- if (cnt_ == 0) {
- return stop();
- }
- }
- }
- }
- }
-};
-
-class TestA : public Task {
- public:
- TestA(string tag, string username) : tag_(std::move(tag)), username_(std::move(username)) {
- }
- void start_up() override {
- send_query(make_tl_object<td_api::searchPublicChat>(username_), [this](auto res) {
- CHECK(res->get_id() == td_api::chat::ID);
- auto chat = move_tl_object_as<td_api::chat>(res);
- for (int i = 0; i < 20; i++) {
- this->send_query(make_tl_object<td_api::sendMessage>(
- chat->id_, 0, false, false, nullptr,
- make_tl_object<td_api::inputMessageText>(
- make_tl_object<td_api::formattedText>(PSTRING() << tag_ << " " << (1000 + i), Auto()),
- false, false)),
- [&](auto res) { this->stop(); });
- }
- });
- }
-
- private:
- string tag_;
- string username_;
-};
-
-class TestSecretChat : public Task {
- public:
- TestSecretChat(string tag, string username) : tag_(std::move(tag)), username_(std::move(username)) {
- }
-
- void start_up() override {
- auto f = [this](auto res) {
- CHECK(res->get_id() == td_api::chat::ID);
- auto chat = move_tl_object_as<td_api::chat>(res);
- this->chat_id_ = chat->id_;
- this->secret_chat_id_ = move_tl_object_as<td_api::chatTypeSecret>(chat->type_)->secret_chat_id_;
- };
- send_query(make_tl_object<td_api::searchPublicChat>(username_), [this, f = std::move(f)](auto res) mutable {
- CHECK(res->get_id() == td_api::chat::ID);
- auto chat = move_tl_object_as<td_api::chat>(res);
- CHECK(chat->type_->get_id() == td_api::chatTypePrivate::ID);
- auto info = move_tl_object_as<td_api::chatTypePrivate>(chat->type_);
- this->send_query(make_tl_object<td_api::createNewSecretChat>(info->user_id_), std::move(f));
- });
- }
-
- void process_update(std::shared_ptr<TestClient::Update> update) override {
- if (!update->object) {
- return;
- }
- if (update->object->get_id() == td_api::updateSecretChat::ID) {
- auto update_secret_chat = move_tl_object_as<td_api::updateSecretChat>(update->object);
- if (update_secret_chat->secret_chat_->id_ != secret_chat_id_ ||
- update_secret_chat->secret_chat_->state_->get_id() != td_api::secretChatStateReady::ID) {
- return;
- }
- LOG(INFO) << "SEND ENCRYPTED MESSAGES";
- for (int i = 0; i < 20; i++) {
- send_query(make_tl_object<td_api::sendMessage>(
- chat_id_, 0, false, false, nullptr,
- make_tl_object<td_api::inputMessageText>(
- make_tl_object<td_api::formattedText>(PSTRING() << tag_ << " " << (1000 + i), Auto()), false,
- false)),
- [](auto res) {});
- }
- }
- }
-
- private:
- string tag_;
- string username_;
- int64 secret_chat_id_ = 0;
- int64 chat_id_ = 0;
-};
-
-class TestFileGenerated : public Task {
- public:
- TestFileGenerated(string tag, string username) : tag_(std::move(tag)), username_(std::move(username)) {
- }
-
- void start_up() override {
- }
-
- void process_update(std::shared_ptr<TestClient::Update> update) override {
- if (!update->object) {
- return;
- }
- if (update->object->get_id() == td_api::updateNewMessage::ID) {
- auto updateNewMessage = move_tl_object_as<td_api::updateNewMessage>(update->object);
- auto &message = updateNewMessage->message_;
- chat_id_ = message->chat_id_;
- if (message->content_->get_id() == td_api::messageText::ID) {
- auto messageText = move_tl_object_as<td_api::messageText>(message->content_);
- auto text = messageText->text_->text_;
- if (text.substr(0, tag_.size()) == tag_) {
- if (text.substr(tag_.size() + 1) == "ONE_FILE") {
- return one_file();
- }
- }
- }
- } else if (update->object->get_id() == td_api::updateFileGenerationStart::ID) {
- auto info = move_tl_object_as<td_api::updateFileGenerationStart>(update->object);
- generate_file(info->generation_id_, info->original_path_, info->destination_path_, info->conversion_);
- } else if (update->object->get_id() == td_api::updateFile::ID) {
- auto file = move_tl_object_as<td_api::updateFile>(update->object);
- LOG(INFO) << to_string(file);
- }
- }
- void one_file() {
- LOG(ERROR) << "Start ONE_FILE test";
- string file_path = string("test_documents") + TD_DIR_SLASH + "a.txt";
- mkpath(file_path).ensure();
- auto raw_file =
- FileFd::open(file_path, FileFd::Flags::Create | FileFd::Flags::Truncate | FileFd::Flags::Write).move_as_ok();
- auto file = BufferedFd<FileFd>(std::move(raw_file));
- for (int i = 1; i < 100000; i++) {
- file.write(PSLICE() << i << "\n").ensure();
- }
- file.flush_write().ensure(); // important
- file.close();
- this->send_query(make_tl_object<td_api::sendMessage>(
- chat_id_, 0, false, false, nullptr,
- make_tl_object<td_api::inputMessageDocument>(
- make_tl_object<td_api::inputFileGenerated>(file_path, "square", 0),
- make_tl_object<td_api::inputThumbnail>(
- make_tl_object<td_api::inputFileGenerated>(file_path, "thumbnail", 0), 0, 0),
- make_tl_object<td_api::formattedText>(tag_, Auto()))),
- [](auto res) { check_td_error(res); });
-
- this->send_query(
- make_tl_object<td_api::sendMessage>(chat_id_, 0, false, false, nullptr,
- make_tl_object<td_api::inputMessageDocument>(
- make_tl_object<td_api::inputFileGenerated>(file_path, "square", 0),
- nullptr, make_tl_object<td_api::formattedText>(tag_, Auto()))),
- [](auto res) { check_td_error(res); });
- }
-
- friend class GenerateFile;
- class GenerateFile : public Actor {
- public:
- GenerateFile(Task *parent, int64 id, string original_path, string destination_path, string conversion)
- : parent_(parent)
- , id_(id)
- , original_path_(std::move(original_path))
- , destination_path_(std::move(destination_path))
- , conversion_(std::move(conversion)) {
- }
-
- private:
- Task *parent_;
- int64 id_;
- string original_path_;
- string destination_path_;
- string conversion_;
-
- FILE *from = nullptr;
- FILE *to = nullptr;
-
- void start_up() override {
- from = std::fopen(original_path_.c_str(), "rb");
- CHECK(from);
- to = std::fopen(destination_path_.c_str(), "wb");
- CHECK(to);
- yield();
- }
- void loop() override {
- int cnt = 0;
- while (true) {
- uint32 x;
- auto r = std::fscanf(from, "%u", &x);
- if (r != 1) {
- return stop();
- }
- std::fprintf(to, "%u\n", x * x);
- if (++cnt >= 10000) {
- break;
- }
- }
- auto ready = std::ftell(to);
- LOG(ERROR) << "READY: " << ready;
- parent_->send_query(make_tl_object<td_api::setFileGenerationProgress>(
- id_, 1039823 /*yeah, exact size of this file*/, narrow_cast<int32>(ready)),
- [](auto result) { check_td_error(result); });
- set_timeout_in(0.02);
- }
- void tear_down() override {
- std::fclose(from);
- std::fclose(to);
- parent_->send_query(make_tl_object<td_api::finishFileGeneration>(id_, nullptr),
- [](auto result) { check_td_error(result); });
- }
- };
- void generate_file(int64 id, string original_path, string destination_path, string conversion) {
- LOG(ERROR) << "Generate file " << tag("id", id) << tag("original_path", original_path)
- << tag("destination_path", destination_path) << tag("conversion", conversion);
- if (conversion == "square") {
- create_actor<GenerateFile>("GenerateFile", this, id, original_path, destination_path, conversion).release();
- } else if (conversion == "thumbnail") {
- write_file(destination_path, base64url_decode(Slice(thumbnail, thumbnail_size)).ok()).ensure();
- this->send_query(make_tl_object<td_api::finishFileGeneration>(id, nullptr),
- [](auto result) { check_td_error(result); });
- } else {
- LOG(FATAL) << "unknown " << tag("conversion", conversion);
- }
- }
-
- private:
- string tag_;
- string username_;
- int64 chat_id_ = 0;
-};
-
-class CheckTestC : public Task {
- public:
- CheckTestC(string username, string tag, Promise<> promise)
- : username_(std::move(username)), tag_(std::move(tag)), promise_(std::move(promise)) {
- }
-
- void start_up() override {
- send_query(make_tl_object<td_api::searchPublicChat>(username_), [this](auto res) {
- CHECK(res->get_id() == td_api::chat::ID);
- auto chat = move_tl_object_as<td_api::chat>(res);
- chat_id_ = chat->id_;
- this->one_file();
- });
- }
-
- private:
- string username_;
- string tag_;
- Promise<> promise_;
- int64 chat_id_;
-
- void one_file() {
- this->send_query(
- make_tl_object<td_api::sendMessage>(
- chat_id_, 0, false, false, nullptr,
- make_tl_object<td_api::inputMessageText>(
- make_tl_object<td_api::formattedText>(PSTRING() << tag_ << " ONE_FILE", Auto()), false, false)),
- [](auto res) { check_td_error(res); });
- }
-
- void process_update(std::shared_ptr<TestClient::Update> update) override {
- if (!update->object) {
- return;
- }
- if (update->object->get_id() == td_api::updateNewMessage::ID) {
- auto updateNewMessage = move_tl_object_as<td_api::updateNewMessage>(update->object);
- auto &message = updateNewMessage->message_;
- if (message->content_->get_id() == td_api::messageDocument::ID) {
- auto messageDocument = move_tl_object_as<td_api::messageDocument>(message->content_);
- auto text = messageDocument->caption_->text_;
- if (text.substr(0, tag_.size()) == tag_) {
- file_id_to_check_ = messageDocument->document_->document_->id_;
- LOG(ERROR) << "GOT FILE " << to_string(messageDocument->document_->document_);
- this->send_query(make_tl_object<td_api::downloadFile>(file_id_to_check_, 1),
- [](auto res) { check_td_error(res); });
- }
- }
- } else if (update->object->get_id() == td_api::updateFile::ID) {
- auto updateFile = move_tl_object_as<td_api::updateFile>(update->object);
- if (updateFile->file_->id_ == file_id_to_check_ && (updateFile->file_->local_->is_downloading_completed_)) {
- check_file(updateFile->file_->local_->path_);
- }
- }
- }
-
- void check_file(CSlice path) {
- FILE *from = std::fopen(path.c_str(), "rb");
- CHECK(from);
- uint32 x;
- uint32 y = 1;
- while (std::fscanf(from, "%u", &x) == 1) {
- CHECK(x == y * y);
- y++;
- }
- std::fclose(from);
- stop();
- }
- int32 file_id_to_check_ = 0;
-};
-
-class LoginTestActor : public Actor {
- public:
- explicit LoginTestActor(Status *status) : status_(status) {
- *status_ = Status::OK();
- }
-
- private:
- Status *status_;
- ActorOwn<TestClient> alice_;
- ActorOwn<TestClient> bob_;
-
- string alice_phone_ = "9996636437";
- string bob_phone_ = "9996636438";
- string alice_username_ = "alice_" + alice_phone_;
- string bob_username_ = "bob_" + bob_phone_;
-
- string stage_name_;
-
- void begin_stage(string stage_name, double timeout) {
- LOG(WARNING) << "Begin stage '" << stage_name << "'";
- stage_name_ = std::move(stage_name);
- set_timeout_in(timeout);
- }
-
- void start_up() override {
- begin_stage("Logging in", 160);
- alice_ = create_actor<TestClient>("AliceClient", "alice");
- bob_ = create_actor<TestClient>("BobClient", "bob");
-
- send_closure(alice_, &TestClient::add_listener,
- std::make_unique<DoAuthentication>(
- "alice", alice_phone_, "33333",
- PromiseCreator::event(self_closure(this, &LoginTestActor::start_up_fence_dec))));
-
- send_closure(bob_, &TestClient::add_listener,
- std::make_unique<DoAuthentication>(
- "bob", bob_phone_, "33333",
- PromiseCreator::event(self_closure(this, &LoginTestActor::start_up_fence_dec))));
- }
-
- int start_up_fence_ = 3;
- void start_up_fence_dec() {
- --start_up_fence_;
- if (start_up_fence_ == 0) {
- init();
- } else if (start_up_fence_ == 1) {
- return init();
- class WaitActor : public Actor {
- public:
- WaitActor(double timeout, Promise<> promise) : timeout_(timeout), promise_(std::move(promise)) {
- }
- void start_up() override {
- set_timeout_in(timeout_);
- }
- void timeout_expired() override {
- stop();
- }
-
- private:
- double timeout_;
- Promise<> promise_;
- };
- create_actor<WaitActor>("WaitActor", 2,
- PromiseCreator::event(self_closure(this, &LoginTestActor::start_up_fence_dec)))
- .release();
- }
- }
-
- void init() {
- send_closure(alice_, &TestClient::add_listener,
- std::make_unique<SetUsername>(
- alice_username_, PromiseCreator::event(self_closure(this, &LoginTestActor::init_fence_dec))));
- send_closure(bob_, &TestClient::add_listener,
- std::make_unique<SetUsername>(
- bob_username_, PromiseCreator::event(self_closure(this, &LoginTestActor::init_fence_dec))));
- }
-
- int init_fence_ = 2;
- void init_fence_dec() {
- if (--init_fence_ == 0) {
- test_a();
- }
- }
-
- int32 test_a_fence_ = 2;
- void test_a_fence() {
- if (--test_a_fence_ == 0) {
- test_b();
- }
- }
-
- void test_a() {
- begin_stage("Ready to create chats", 80);
- string alice_tag = PSTRING() << format::as_hex(Random::secure_int64());
- string bob_tag = PSTRING() << format::as_hex(Random::secure_int64());
-
- send_closure(bob_, &TestClient::add_listener,
- std::make_unique<CheckTestA>(
- alice_tag, PromiseCreator::event(self_closure(this, &LoginTestActor::test_a_fence))));
- send_closure(alice_, &TestClient::add_listener,
- std::make_unique<CheckTestA>(
- bob_tag, PromiseCreator::event(self_closure(this, &LoginTestActor::test_a_fence))));
-
- send_closure(alice_, &TestClient::add_listener, std::make_unique<TestA>(alice_tag, bob_username_));
- send_closure(bob_, &TestClient::add_listener, std::make_unique<TestA>(bob_tag, alice_username_));
- // send_closure(alice_, &TestClient::add_listener, std::make_unique<TestChat>(bob_username_));
- }
-
- void timeout_expired() override {
- LOG(FATAL) << "Timeout expired in stage '" << stage_name_ << "'";
- }
-
- int32 test_b_fence_ = 1;
- void test_b_fence() {
- if (--test_b_fence_ == 0) {
- test_c();
- }
- }
-
- int32 test_c_fence_ = 1;
- void test_c_fence() {
- if (--test_c_fence_ == 0) {
- finish();
- }
- }
-
- void test_b() {
- begin_stage("Create secret chat", 40);
- string tag = PSTRING() << format::as_hex(Random::secure_int64());
-
- send_closure(
- bob_, &TestClient::add_listener,
- std::make_unique<CheckTestA>(tag, PromiseCreator::event(self_closure(this, &LoginTestActor::test_b_fence))));
- send_closure(alice_, &TestClient::add_listener, std::make_unique<TestSecretChat>(tag, bob_username_));
- }
-
- void test_c() {
- begin_stage("Send generated file", 240);
- string tag = PSTRING() << format::as_hex(Random::secure_int64());
-
- send_closure(bob_, &TestClient::add_listener,
- std::make_unique<CheckTestC>(
- alice_username_, tag, PromiseCreator::event(self_closure(this, &LoginTestActor::test_c_fence))));
- send_closure(alice_, &TestClient::add_listener, std::make_unique<TestFileGenerated>(tag, bob_username_));
- }
-
- int32 finish_fence_ = 2;
- void finish_fence() {
- finish_fence_--;
- if (finish_fence_ == 0) {
- Scheduler::instance()->finish();
- stop();
- }
- }
- void finish() {
- send_closure(alice_, &TestClient::close, PromiseCreator::event(self_closure(this, &LoginTestActor::finish_fence)));
- send_closure(bob_, &TestClient::close, PromiseCreator::event(self_closure(this, &LoginTestActor::finish_fence)));
- }
-};
-
-class Tdclient_login : public td::Test {
- public:
- using Test::Test;
- bool step() final {
- if (!is_inited_) {
- SET_VERBOSITY_LEVEL(VERBOSITY_NAME(DEBUG) + 2);
- sched_.init(4);
- sched_.create_actor_unsafe<LoginTestActor>(0, "LoginTestActor", &result_).release();
- sched_.start();
- is_inited_ = true;
- }
-
- bool ret = sched_.run_main(10);
- if (ret) {
- return true;
- }
- sched_.finish();
- if (result_.is_error()) {
- LOG(ERROR) << result_;
- }
- ASSERT_TRUE(result_.is_ok());
- return false;
- }
-
- private:
- bool is_inited_ = false;
- ConcurrentScheduler sched_;
- Status result_;
-};
-Tdclient_login Tdclient_login("Tdclient_login");
-}; // namespace td