summaryrefslogtreecommitdiff
path: root/libs/tdlib/td/test
diff options
context:
space:
mode:
Diffstat (limited to 'libs/tdlib/td/test')
-rw-r--r--libs/tdlib/td/test/CMakeLists.txt50
-rw-r--r--libs/tdlib/td/test/TestsRunner.cpp63
-rw-r--r--libs/tdlib/td/test/TestsRunner.h19
-rw-r--r--libs/tdlib/td/test/data.cpp69
-rw-r--r--libs/tdlib/td/test/data.h15
-rw-r--r--libs/tdlib/td/test/db.cpp575
-rw-r--r--libs/tdlib/td/test/fuzz_url.cpp33
-rw-r--r--libs/tdlib/td/test/http.cpp373
-rw-r--r--libs/tdlib/td/test/main.cpp40
-rw-r--r--libs/tdlib/td/test/message_entities.cpp529
-rw-r--r--libs/tdlib/td/test/mtproto.cpp347
-rw-r--r--libs/tdlib/td/test/secret.cpp1056
-rw-r--r--libs/tdlib/td/test/string_cleaning.cpp107
-rw-r--r--libs/tdlib/td/test/tdclient.cpp837
-rw-r--r--libs/tdlib/td/test/tests_runner.cpp18
-rw-r--r--libs/tdlib/td/test/tests_runner.h18
16 files changed, 0 insertions, 4149 deletions
diff --git a/libs/tdlib/td/test/CMakeLists.txt b/libs/tdlib/td/test/CMakeLists.txt
deleted file mode 100644
index d120d8d3fb..0000000000
--- a/libs/tdlib/td/test/CMakeLists.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
-
-#SOURCE SETS
-set(TD_TEST_SOURCE
- ${CMAKE_CURRENT_SOURCE_DIR}/db.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/http.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/mtproto.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/message_entities.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/secret.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/string_cleaning.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/TestsRunner.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/tests_runner.cpp
-
- ${CMAKE_CURRENT_SOURCE_DIR}/TestsRunner.h
- ${CMAKE_CURRENT_SOURCE_DIR}/tests_runner.h
-
- ${CMAKE_CURRENT_SOURCE_DIR}/data.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/data.h
-
- ${TDUTILS_TEST_SOURCE}
- ${TDACTOR_TEST_SOURCE}
-)
-set(TD_TEST_SOURCE ${TD_TEST_SOURCE} PARENT_SCOPE)
-
-set(TESTS_MAIN
- main.cpp
-)
-
-add_library(all_tests STATIC ${TD_TEST_SOURCE})
-target_include_directories(all_tests PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
-target_link_libraries(all_tests PRIVATE tdactor tddb tdcore tdnet tdutils)
-
-if (NOT CMAKE_CROSSCOMPILING OR EMSCRIPTEN)
- #Tests
- add_executable(run_all_tests ${TESTS_MAIN} ${TD_TEST_SOURCE})
- if (CLANG AND NOT CYGWIN AND NOT EMSCRIPTEN)
- target_compile_options(run_all_tests PUBLIC -fsanitize=undefined -fno-sanitize=vptr)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fno-sanitize=vptr")
- endif()
- target_include_directories(run_all_tests PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
- target_link_libraries(run_all_tests PRIVATE tdactor tddb tdcore tdnet tdutils)
-
- if (CLANG)
-# add_executable(fuzz_url fuzz_url.cpp)
-# target_link_libraries(fuzz_url PRIVATE tdclient)
-# target_compile_options(fuzz_url PRIVATE "-fsanitize-coverage=trace-pc-guard")
- endif()
-
- add_test(run_all_tests run_all_tests)
-endif()
diff --git a/libs/tdlib/td/test/TestsRunner.cpp b/libs/tdlib/td/test/TestsRunner.cpp
deleted file mode 100644
index fbe155738e..0000000000
--- a/libs/tdlib/td/test/TestsRunner.cpp
+++ /dev/null
@@ -1,63 +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 "test/TestsRunner.h"
-
-#include "td/utils/common.h"
-#include "td/utils/FileLog.h"
-#include "td/utils/format.h"
-#include "td/utils/logging.h"
-#include "td/utils/port/path.h"
-#include "td/utils/tests.h"
-
-#include <limits>
-
-DESC_TESTS(string_cleaning);
-DESC_TESTS(message_entities);
-DESC_TESTS(variant);
-DESC_TESTS(secret);
-DESC_TESTS(actors_main);
-DESC_TESTS(actors_simple);
-DESC_TESTS(actors_workers);
-DESC_TESTS(db);
-DESC_TESTS(json);
-DESC_TESTS(http);
-DESC_TESTS(heap);
-DESC_TESTS(pq);
-DESC_TESTS(mtproto);
-
-namespace td {
-
-void TestsRunner::run_all_tests() {
- LOAD_TESTS(string_cleaning);
- LOAD_TESTS(message_entities);
- LOAD_TESTS(variant);
- LOAD_TESTS(secret);
- LOAD_TESTS(actors_main);
- LOAD_TESTS(actors_simple);
- LOAD_TESTS(actors_workers);
- LOAD_TESTS(db);
- LOAD_TESTS(json);
- LOAD_TESTS(http);
- LOAD_TESTS(heap);
- LOAD_TESTS(pq);
- LOAD_TESTS(mtproto);
- Test::run_all();
-}
-
-static FileLog file_log;
-static TsLog ts_log(&file_log);
-
-void TestsRunner::init(string dir) {
- SET_VERBOSITY_LEVEL(VERBOSITY_NAME(WARNING));
- chdir(dir).ensure();
- LOG(WARNING) << "Redirect log into " << tag("file", dir + TD_DIR_SLASH + "log.txt");
- if (file_log.init("log.txt", std::numeric_limits<int64>::max())) {
- log_interface = &ts_log;
- }
-}
-
-} // namespace td
diff --git a/libs/tdlib/td/test/TestsRunner.h b/libs/tdlib/td/test/TestsRunner.h
deleted file mode 100644
index a5bc66d855..0000000000
--- a/libs/tdlib/td/test/TestsRunner.h
+++ /dev/null
@@ -1,19 +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)
-//
-#pragma once
-
-#include "td/utils/common.h"
-
-namespace td {
-
-class TestsRunner {
- public:
- static void init(string dir);
- static void run_all_tests();
-};
-
-} // namespace td
diff --git a/libs/tdlib/td/test/data.cpp b/libs/tdlib/td/test/data.cpp
deleted file mode 100644
index a57a9147c5..0000000000
--- a/libs/tdlib/td/test/data.cpp
+++ /dev/null
@@ -1,69 +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 "test/data.h"
-namespace td {
-static const char thumbnail_arr[] =
- "_9j_4AAQSkZJRgABAQEASABIAAD_2wBDAAICAgICAQICAgIDAgIDAwYEAwMDAwcFBQQGCAcJCAgHCAgJCg0LCQoMCggICw8LDA0ODg8OCQsQERAOEQ"
- "0ODg7_2wBDAQIDAwMDAwcEBAcOCQgJDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg7_wAARCAAyADIDASIA"
- "AhEBAxEB_8QAHAAAAQUBAQEAAAAAAAAAAAAAAAUGBwgJAgQD_8QAMRAAAgEDAwMDAgUDBQAAAAAAAQIDBAURAAYSByExCBNBFCIVMlFhcZGhsQkjUm"
- "KB_8QAGgEAAgMBAQAAAAAAAAAAAAAABgcAAggEBf_EACgRAAECBgIBBAMBAQAAAAAAAAECEQADBAUhMRJBBhMyUWEUIlJCkf_aAAwDAQACEQMRAD8A"
- "381CvUXrbtzYtTLa6ZPx3cKj76SGQLHTn491-_E_9QC38a464dSH2H08gpLZMI9x3dmhom7EwKB98uP2yAP3Ofg6z2M8jVXvM5qqkyFpeTsCCR3Lk9"
- "y2eWe_yD3znTG8esEqtR-TVAlJ9qRgqbZJ6T1956ELjyG_T6RRpqQhJHvWrIS-gkf6UfjrGHMTVePUH1HuVYxp7rTWOFj9sVDRocfoOUgYk_00nUXX"
- "XqdQTrIdzmsQgHhWUcLowOcdwoPwfB1W3fG8KjaNlpnoqNK-veCWVYXk9qL26eMSOXkPZclUUdxkk-QMaiPZPqFp9wdT7btC92iltlRcZvpqea33Na"
- "mNZSuVjcY7BsYDA-SMjByD5c2w01V-DMp5aS4HtffypjnXffULxNPeqmjNwlVU1YZRcFtfCSRjfXRIfUa1bG9SFuuddDbt6UUdkqHIVbhTkmmJPjmp"
- "-6P-ckfrjVno5ElgSWJ1kjdQyspyGB8EH51kUWDShpFIbAAkQEjsDktk5wAMAD9hq2Pp16lTrdl2BeJzJSyKzWWWRs8Co5NCD8qR3A-CCv6aE7_45T"
- "y5SqijSUKTlSNhvlJ-tkPrI0YMLD5DUmYiTVrE2WssmYMEK_lYxvQLbYHYi4-jRo0p4bUZ6-oC7y3P1IXajJ5QW-lio4jyIKgqsreDg_cwPceQMY86"
- "hQAKoUeAMdzk6lzrhb5aT1R7kUqSKpoaiLt-YNEo_wAqw_8ANMuqsVbTWy3x1tEbeXV2E0isWkOcn7QPABAyTnPxp9zfJPH_ABO1US6xYSJwSMZIHE"
- "krIyriFYJA2obyIzbMst_8oulZLpwVeiVkA4BPIAIBwORTkAnQOsExZNddoWn1T9Kju6G1yU9bLW01ILraKetiqKgLDJHSH3gVi94hoxIBkOYwCM6r"
- "x6yLDYdt9fOi9T03l3DfN2_h8VRPBdYF-uWp-pWSCmZY40CyZYqYuPJOSqQp-0TtuK1dPt0b6oLNvfZg3R9HDM8UU8X3orcQxTDqAGwnEk4J8kAEa8"
- "th2NtTZnVjprfZ62fd9vgsMU9jmu1OZJ7YaZ-ApqFsKEVXYq0vEBnZeJIw5UdRfrd5Fd6mptyipCVMFMwUyQXDsWwWcAk6Goc1ts9dZLNT01enishy"
- "PcQ6jgs40csSAHc4MPynrYKyxwXHgaenngWfhMvExBl5cWB8Fc4IPgg6WbJdqi07ntd5pJ-Ro6mGpgfOSntsGwD-hGRj9zpSHTjfm-t6XWt2zXWqhg"
- "J-rqqGpo-VNLKMMY4nVwW5sCzKue5YjAPHTbobXf6eWjs9-t0duv1RHFIaSGpWYAT_AJMEAEEkkFWAYEeMYJd9vvtHeJyKWanPByT_AEBkD6ZzCUuX"
- "j1fYKeZVypmCviAM_ofaTjB5MPrbuRGucUizU0c0bZR1DL2-CMjRriliFNbKanzn2olTP8DGjWczvGo0onQfcV666bXhFwsXUGKnhq6m0LItRSTSGN"
- "KpUR5olZgDxAdCCcHCuT8Y1nd0O3dW9X-gta1nv0fTvct_u9xZZ4LuK-sjZgrSSokhb2hyBVEAwBGDjuQdft02GPcuxLjZ3dYnniIhlePmI5B-Vivy"
- "AfIyMjI-dUZpukO99qbiEtv6YxVFQjk-9QVkP08mD5BGJMHzhhkds_roG8lNVUKlOhSwkJCSHPEJUVMwBcEqJDgx7NqlU9P6hQySslSgeyQA-W6SIb"
- "O6tqQbUk2jcEu0k93WrRPrGjVZPd4_mRhjv7gRyvEqCMnHjTT6f1VmrfUttCyb2RL7FT0sFos9NV0iJTQUsCPUksVHeV5QWLcTyZBnHwp9RoKy47tp"
- "pr5a7haK6mOGiniaBBjHZc_GRnlnP9iI1u1huF9r7dV2GrnpNx0NSs9BUUqM5Dg5AKr3Iz_Tv8Egnvg_h12Rbq2pXI9JC-BlBRZSikK5nJ_UEEAOzk"
- "dCF_5N5hbJVzpKZM4rKeYmcQ6U8m4aDqKSC_F2B7OIsX1grfTIfVHsSh6gRXPZW5LeJLlYLxaqeWgt0pMyoyTVKf7QkZ4lAVuLEHAbDYMc7F3jsHdX"
- "-tXPtXb9FX38PRrW1N5p0MlKwp6f3qcyOo4BFaQxA5yWVVxjSjvDp31r6rdNVgvHS2WgqaWZaumd6yn9mr44WSLizLKnuAI6lk7PChPbOrhem3phH0"
- "k9Ie1NpyWZbHdVgM9ypRULMY5nYkoZFGG4jio8-PJ8nsE2bSLJQeK8j_oIPz0SNwRLpqKsokKUrk5H6l2YEKSrQ7AwexE76NGjXmx0QaMDRo1IkfKS"
- "KKZCk0ayp_xdQR_fXEVLS0yn6emip8-fbjC_40aNWc66ijDbZj0YGjRo1WLwaNGjUiR__9k";
-
-const char *thumbnail = thumbnail_arr;
-const size_t thumbnail_size = sizeof(thumbnail_arr) - 1;
-
-static const char gzip_bomb_arr[] =
- "eJzt3VlQU2cYxvGTSFSkqHWJuIHTUqotAetIBmWzVUeUqlRrFcIqZlxCUKRshZBULVS0oqLiwqJWUVwAQQNBgSgt1EHFlS1AQCsZ1qAsASKTRonnnJ"
- "ledHrViz5cfvMOOd_v_d-eJCK5vf6MaUmDLK7Jk_tZ9sSDEyYmdo7fOMeqdKSs-jXRxA_m8_fZPGTMW-Rhlf-AP7XxrGTW-qCOyWPtB90qdo-"
- "NHtXfEi3Wlul0bWrxYNa1QaVY12ure9OdRgz_SVzyX-"
- "nS59eYP1uYV68zHBLi7xcf2qyd7ddSbhX2geFsfPs3aeO04xhKLWffzBGGQyOHIeckkUmXZ1qZoH2a4XBWddSKRKGJ-"
- "9UQxe8HGIbDXaZLU4U8SfDf_-UhiXroGG0wJSatvIgVcbXihV2YKTnpdP6ulHWxUtaxsez9U96O_ahCypHn9_AnOow0nI3uu1gRN-"
- "Qq18SU0wZXFVfwlcxblapX025Sk6mPNymY37bVhV0LeK_hp7-3gu3nNZizl7pj1FNVSYxlY1QxnzZ4QanK2c7waeuO-"
- "MWbmly9NUfIuBQadLP6C8PZouwzf-QKTebaiGp-o-7o1Nrt7zKhq1CZQxt8og6pySOyeiNvlWaSk4UX5tdICf12vNvNSF_"
- "3P2ukLLOkokDaHc17B7ItjPsbtnvQBls0snaepGrQ0SegipxsWHsykCfZlqKwoTYROPt1oIK5382XS7tjwmB0dYJRtDrPmrayHq1XH0cuEJlnXROQk"
- "-o5K6WcRTceCKdQm-BOipQKGaXnbU_R7rhM5Ny-"
- "jFmk4bGpwbBBkY2W3XjDOaGq2o6c1ByxUrBPe6qktNqmxzsqpMSLx0kraXf81dmi72NkOTyILJElskSWBLJElgSyRJbDg8gSWSJLZEkgS2RJIEtkOT"
- "yILJElskSWBLJElgSyRJbDi0CWyBJZIktkiSyH74gskSWyRJYEskSWBLJElu_uiCyRJbJElgSyRJbDvsgSWSJLZIkskeXwJLJElsgSWSJLZPluEFn-"
- "11nq_NUHhOP3MGfHl7pe3eBeYz_S1Jhbye4pZRxnTCxxbZeP9Jw3gnXUOLb4jm1MyAOjcEmSo-ESnr5HI-2Nj9_kupErWfL5sYyx-"
- "phmrlrZSlZXqylU6gsrH5TVryVZHqWWLdY_hU9x2cDJhe8f7efK9XzzVczmzPtrqMF4_qUS_"
- "ebj1iYWkHN9InW4gt2YExOkeUru6brq1UH951Spg4vSyY2e7V13Ii5RIhPk0gY3nmjNZplVNT09R-7zrEiprZey8q-kKZxCSdSOSMdN-s_"
- "pjUrOyiD5t4jWNTdZ-nXWWlODVzekLwxklIba22WQ-FuUmpg8IcOmTRW2mhKKMh-"
- "nbyRiyFwlaCV7ACUoQQlKUIISlKAEJShBCUpQghKUoAQlKEEJSlCCEpSgBCUoQQlKUIISlKAEJShBCUpQghKUoAQlKEEJSlCCEpSgBCUoQQlKUIISl"
- "KAEJShBCcp_ouzPDS_"
- "jjv6KMWnp4tNs6yuBM3bHLpkuGBP1nLgnMfa3DN8xwjrl9p14o26PpinFCzbvcpC7meuhEyLZUuJCaJGU9nmanev3cOQBLQeSaHfIyLjcYdno0LOUW"
- "khtk2bB9revxtcp15Cvxj9qCEj9iSPfmpIlpE0W1k32N-naUPDiE-oOwm2t2xyM-8eKDlELCesXPVC8_XoFTd5T8usVrmuOb_"
- "Y32eGpEpyiTdqGL61mOh7rjFhO5XDqZEHtKmbRYt9z1EJmxqR1S99-F8IQJ5T8LoQOp2aPamZy5UAtbXX15d4fSomE8w4-"
- "tBzS0zOliRL1wyk0oDil6pa-"
- "pbYQsZs31SwoQQlKUIISlKAEJShBCUpQghKUoAQlKEEJSlCCEpSgBCUoQQlKUIISlKAEJShBCUpQghKUoAQlKEEJSlCCEpSgBCUoQQlKUIISlKAEJS"
- "hBCUpQ_jtKiTgqPPDO3MOL_Pv3TxL68UbFJ5tlxpXs_XLFDAd3Gy-JIPvL_"
- "KOXG414uxZmy1zt7B9axXrM53w9d0a0L0vMGGduuE7ODydO5bOO39kQKiPf5d-Udqb6Ck8SEOGbKSMXsSmvXuqVR1T4ireEkA9010f1xDnVKNpCMy_"
- "8PeXBKz7NVkGM9LnfeXeS7_LXbJ7NbWM3mjUkCTrJRdQI8zhVHHl3lUVtHbnbnKqB6wmfMpRlhfdISsvLSbK9PMmc_euSyN-sd-2bGn-_"
- "gGUfq3l5kvyhddcwhbA81KTrTW8cl3qg9lDnjhfL5ZpgW9qTt_KDnrP9xgQ8e0m-y39YFLsxN4hxoEkkayYXcbg-"
- "TLGznukoHjpzn3qgqJTV2ogJXaK6ctqTgxKUoPyfUeqmx4szeRJuj3josnbUu0O57kcXXX-bi25IozxSONDzF5jalI4";
-const char *gzip_bomb = gzip_bomb_arr;
-const size_t gzip_bomb_size = sizeof(gzip_bomb_arr) - 1;
-} // namespace td
diff --git a/libs/tdlib/td/test/data.h b/libs/tdlib/td/test/data.h
deleted file mode 100644
index c447d5cba6..0000000000
--- a/libs/tdlib/td/test/data.h
+++ /dev/null
@@ -1,15 +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)
-//
-#pragma once
-#include "td/utils/common.h"
-namespace td {
-extern const char *thumbnail;
-extern const size_t thumbnail_size;
-
-extern const char *gzip_bomb;
-extern const size_t gzip_bomb_size;
-} // namespace td
diff --git a/libs/tdlib/td/test/db.cpp b/libs/tdlib/td/test/db.cpp
deleted file mode 100644
index 8917dd65b8..0000000000
--- a/libs/tdlib/td/test/db.cpp
+++ /dev/null
@@ -1,575 +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 "td/db/binlog/BinlogHelper.h"
-#include "td/db/BinlogKeyValue.h"
-#include "td/db/SeqKeyValue.h"
-#include "td/db/SqliteKeyValue.h"
-#include "td/db/SqliteKeyValueSafe.h"
-#include "td/db/TsSeqKeyValue.h"
-
-#include "td/utils/common.h"
-#include "td/utils/logging.h"
-#include "td/utils/port/FileFd.h"
-#include "td/utils/port/thread.h"
-#include "td/utils/Random.h"
-#include "td/utils/Slice.h"
-#include "td/utils/Status.h"
-#include "td/utils/tests.h"
-
-#include <limits>
-#include <map>
-#include <memory>
-
-REGISTER_TESTS(db);
-
-using namespace td;
-
-template <class ContainerT>
-static typename ContainerT::value_type &rand_elem(ContainerT &cont) {
- CHECK(0 < cont.size() && cont.size() <= static_cast<size_t>(std::numeric_limits<int>::max()));
- return cont[Random::fast(0, static_cast<int>(cont.size()) - 1)];
-}
-
-TEST(DB, binlog_encryption) {
- CSlice binlog_name = "test_binlog";
- Binlog::destroy(binlog_name).ignore();
-
- auto hello = DbKey::raw_key(std::string(32, 'A'));
- auto cucumber = DbKey::password("cucumber");
- auto empty = DbKey::empty();
- auto long_data = string(10000, 'Z');
- {
- Binlog binlog;
- binlog.init(binlog_name.str(), [](const BinlogEvent &x) {}).ensure();
- binlog.add_raw_event(BinlogEvent::create_raw(binlog.next_id(), 1, 0, create_storer("AAAA")));
- binlog.add_raw_event(BinlogEvent::create_raw(binlog.next_id(), 1, 0, create_storer("BBBB")));
- binlog.add_raw_event(BinlogEvent::create_raw(binlog.next_id(), 1, 0, create_storer(long_data)));
- LOG(INFO) << "SET PASSWORD";
- binlog.change_key(cucumber);
- binlog.change_key(hello);
- LOG(INFO) << "OK";
- binlog.add_raw_event(BinlogEvent::create_raw(binlog.next_id(), 1, 0, create_storer("CCCC")));
- binlog.close().ensure();
- }
-
- auto add_suffix = [&] {
- auto fd = FileFd::open(binlog_name, FileFd::Flags::Write | FileFd::Flags::Append).move_as_ok();
- fd.write("abacabadaba").ensure();
- };
-
- add_suffix();
-
- {
- std::vector<string> v;
- LOG(INFO) << "RESTART";
- Binlog binlog;
- binlog.init(binlog_name.str(), [&](const BinlogEvent &x) { v.push_back(x.data_.str()); }, hello).ensure();
- CHECK(v == std::vector<string>({"AAAA", "BBBB", long_data, "CCCC"}));
- }
-
- add_suffix();
-
- {
- std::vector<string> v;
- LOG(INFO) << "RESTART";
- Binlog binlog;
- auto status = binlog.init(binlog_name.str(), [&](const BinlogEvent &x) { v.push_back(x.data_.str()); }, cucumber);
- CHECK(status.is_error());
- }
-
- add_suffix();
-
- {
- std::vector<string> v;
- LOG(INFO) << "RESTART";
- Binlog binlog;
- auto status =
- binlog.init(binlog_name.str(), [&](const BinlogEvent &x) { v.push_back(x.data_.str()); }, cucumber, hello);
- CHECK(v == std::vector<string>({"AAAA", "BBBB", long_data, "CCCC"}));
- }
-};
-
-TEST(DB, sqlite_lfs) {
- string path = "test_sqlite_db";
- SqliteDb::destroy(path).ignore();
- SqliteDb db;
- db.init(path).ensure();
- db.exec("PRAGMA journal_mode=WAL").ensure();
- db.exec("PRAGMA user_version").ensure();
-}
-
-TEST(DB, sqlite_encryption) {
- string path = "test_sqlite_db";
- SqliteDb::destroy(path).ignore();
-
- auto empty = DbKey::empty();
- auto cucumber = DbKey::password("cucumber");
- auto tomato = DbKey::raw_key(string(32, 'a'));
-
- {
- auto db = SqliteDb::open_with_key(path, empty).move_as_ok();
- db.set_user_version(123);
- auto kv = SqliteKeyValue();
- kv.init_with_connection(db.clone(), "kv");
- kv.set("a", "b");
- }
- SqliteDb::open_with_key(path, cucumber).ensure_error(); // key was set...
-
- SqliteDb::change_key(path, cucumber, empty).ensure();
-
- SqliteDb::open_with_key(path, tomato).ensure_error();
- {
- auto db = SqliteDb::open_with_key(path, cucumber).move_as_ok();
- auto kv = SqliteKeyValue();
- kv.init_with_connection(db.clone(), "kv");
- CHECK(kv.get("a") == "b");
- CHECK(db.user_version().ok() == 123);
- }
-
- SqliteDb::change_key(path, tomato, cucumber).ensure();
- SqliteDb::change_key(path, tomato, cucumber).ensure();
-
- SqliteDb::open_with_key(path, cucumber).ensure_error();
- {
- auto db = SqliteDb::open_with_key(path, tomato).move_as_ok();
- auto kv = SqliteKeyValue();
- kv.init_with_connection(db.clone(), "kv");
- CHECK(kv.get("a") == "b");
- CHECK(db.user_version().ok() == 123);
- }
-
- SqliteDb::change_key(path, empty, tomato).ensure();
- SqliteDb::change_key(path, empty, tomato).ensure();
-
- {
- auto db = SqliteDb::open_with_key(path, empty).move_as_ok();
- auto kv = SqliteKeyValue();
- kv.init_with_connection(db.clone(), "kv");
- CHECK(kv.get("a") == "b");
- CHECK(db.user_version().ok() == 123);
- }
- SqliteDb::open_with_key(path, cucumber).ensure_error();
-}
-
-using SeqNo = uint64;
-struct DbQuery {
- enum Type { Get, Set, Erase } type;
- SeqNo tid = 0;
- int32 id = 0;
- string key;
- string value;
-};
-
-template <class ImplT>
-class QueryHandler {
- public:
- ImplT &impl() {
- return impl_;
- }
- void do_query(DbQuery &query) {
- switch (query.type) {
- case DbQuery::Get:
- query.value = impl_.get(query.key);
- return;
- case DbQuery::Set:
- query.tid = impl_.set(query.key, query.value);
- return;
- case DbQuery::Erase:
- query.tid = impl_.erase(query.key);
- return;
- }
- }
-
- private:
- ImplT impl_;
-};
-
-class SqliteKV {
- public:
- string get(string key) {
- return kv_->get().get(key);
- }
- SeqNo set(string key, string value) {
- kv_->get().set(key, value);
- return 0;
- }
- SeqNo erase(string key) {
- kv_->get().erase(key);
- return 0;
- }
- Status init(string name) {
- auto sql_connection = std::make_shared<SqliteConnectionSafe>(name);
- kv_ = std::make_shared<SqliteKeyValueSafe>("kv", sql_connection);
- return Status::OK();
- }
- void close() {
- kv_.reset();
- }
-
- private:
- std::shared_ptr<SqliteKeyValueSafe> kv_;
-};
-
-class BaselineKV {
- public:
- string get(string key) {
- return map_[key];
- }
- SeqNo set(string key, string value) {
- map_[key] = value;
- return ++current_tid_;
- }
- SeqNo erase(string key) {
- map_.erase(key);
- return ++current_tid_;
- }
-
- private:
- std::map<string, string> map_;
- SeqNo current_tid_ = 0;
-};
-
-TEST(DB, key_value) {
- SET_VERBOSITY_LEVEL(VERBOSITY_NAME(INFO));
- std::vector<std::string> keys;
- std::vector<std::string> values;
-
- for (int i = 0; i < 100; i++) {
- keys.push_back(rand_string('a', 'b', Random::fast(1, 10)));
- }
- for (int i = 0; i < 1000; i++) {
- values.push_back(rand_string('a', 'b', Random::fast(1, 10)));
- }
-
- int queries_n = 300000;
- std::vector<DbQuery> queries(queries_n);
- for (auto &q : queries) {
- int op = Random::fast(0, 2);
- const auto &key = rand_elem(keys);
- const auto &value = rand_elem(values);
- if (op == 0) {
- q.type = DbQuery::Get;
- q.key = key;
- } else if (op == 1) {
- q.type = DbQuery::Erase;
- q.key = key;
- } else if (op == 2) {
- q.type = DbQuery::Set;
- q.key = key;
- q.value = value;
- }
- }
-
- QueryHandler<BaselineKV> baseline;
- QueryHandler<SeqKeyValue> kv;
- QueryHandler<TsSeqKeyValue> ts_kv;
- QueryHandler<BinlogKeyValue<Binlog>> new_kv;
-
- CSlice new_kv_name = "test_new_kv";
- Binlog::destroy(new_kv_name).ignore();
- new_kv.impl().init(new_kv_name.str()).ensure();
-
- QueryHandler<SqliteKeyValue> sqlite_kv;
- CSlice name = "test_sqlite_kv";
- SqliteDb::destroy(name).ignore();
- sqlite_kv.impl().init(name.str()).ensure();
-
- int cnt = 0;
- for (auto &q : queries) {
- DbQuery a = q;
- DbQuery b = q;
- DbQuery c = q;
- DbQuery d = q;
- DbQuery e = q;
- baseline.do_query(a);
- kv.do_query(b);
- ts_kv.do_query(c);
- sqlite_kv.do_query(d);
- new_kv.do_query(e);
- ASSERT_EQ(a.value, b.value);
- ASSERT_EQ(a.value, c.value);
- ASSERT_EQ(a.value, d.value);
- ASSERT_EQ(a.value, e.value);
- if (cnt++ % 10000 == 0) {
- new_kv.impl().init(new_kv_name.str()).ensure();
- }
- }
-}
-
-TEST(DB, thread_key_value) {
-#if !TD_THREAD_UNSUPPORTED
- std::vector<std::string> keys;
- std::vector<std::string> values;
-
- for (int i = 0; i < 100; i++) {
- keys.push_back(rand_string('a', 'b', Random::fast(1, 10)));
- }
- for (int i = 0; i < 1000; i++) {
- values.push_back(rand_string('a', 'b', Random::fast(1, 10)));
- }
-
- int threads_n = 4;
- int queries_n = 100000;
-
- std::vector<std::vector<DbQuery>> queries(threads_n, std::vector<DbQuery>(queries_n));
- for (auto &qs : queries) {
- for (auto &q : qs) {
- int op = Random::fast(0, 10);
- const auto &key = rand_elem(keys);
- const auto &value = rand_elem(values);
- if (op > 1) {
- q.type = DbQuery::Get;
- q.key = key;
- } else if (op == 0) {
- q.type = DbQuery::Erase;
- q.key = key;
- } else if (op == 1) {
- q.type = DbQuery::Set;
- q.key = key;
- q.value = value;
- }
- }
- }
-
- QueryHandler<BaselineKV> baseline;
- QueryHandler<TsSeqKeyValue> ts_kv;
-
- std::vector<thread> threads(threads_n);
- std::vector<std::vector<DbQuery>> res(threads_n);
- for (int i = 0; i < threads_n; i++) {
- threads[i] = thread([&ts_kv, &queries, &res, i]() {
- for (auto q : queries[i]) {
- ts_kv.do_query(q);
- res[i].push_back(q);
- }
- });
- }
- for (auto &thread : threads) {
- thread.join();
- }
-
- std::vector<std::size_t> pos(threads_n);
- while (true) {
- bool was = false;
- for (int i = 0; i < threads_n; i++) {
- auto p = pos[i];
- if (p == res[i].size()) {
- continue;
- }
- auto &q = res[i][p];
- if (q.tid == 0) {
- if (q.type == DbQuery::Get) {
- auto nq = q;
- baseline.do_query(nq);
- if (nq.value == q.value) {
- was = true;
- pos[i]++;
- }
- } else {
- was = true;
- pos[i]++;
- }
- }
- }
- if (was) {
- continue;
- }
-
- int best = -1;
- SeqNo best_tid = 0;
- for (int i = 0; i < threads_n; i++) {
- auto p = pos[i];
- if (p == res[i].size()) {
- continue;
- }
- was = true;
- auto &q = res[i][p];
- if (q.tid != 0) {
- if (best == -1 || q.tid < best_tid) {
- best = i;
- best_tid = q.tid;
- }
- }
- }
- if (!was) {
- break;
- }
- ASSERT_TRUE(best != -1);
- baseline.do_query(res[best][pos[best]]);
- pos[best]++;
- }
-#endif
-}
-
-TEST(DB, persistent_key_value) {
- using KeyValue = BinlogKeyValue<ConcurrentBinlog>;
- // using KeyValue = PersistentKeyValue;
- // using KeyValue = SqliteKV;
- SET_VERBOSITY_LEVEL(VERBOSITY_NAME(WARNING));
- std::vector<std::string> keys;
- std::vector<std::string> values;
- CSlice name = "test_pmc";
- Binlog::destroy(name).ignore();
- SqliteDb::destroy(name).ignore();
-
- for (int i = 0; i < 100; i++) {
- keys.push_back(rand_string('a', 'b', Random::fast(1, 10)));
- }
- for (int i = 0; i < 1000; i++) {
- values.push_back(rand_string('a', 'b', Random::fast(1, 10)));
- }
-
- QueryHandler<BaselineKV> baseline;
-
- for (int iter = 0; iter < 25; iter++) {
- int threads_n = 4;
- int queries_n = 3000 / threads_n;
-
- std::vector<std::vector<DbQuery>> queries(threads_n, std::vector<DbQuery>(queries_n));
- for (auto &qs : queries) {
- for (auto &q : qs) {
- int op = Random::fast(0, 10);
- const auto &key = rand_elem(keys);
- const auto &value = rand_elem(values);
- if (op > 1) {
- q.type = DbQuery::Get;
- q.key = key;
- } else if (op == 0) {
- q.type = DbQuery::Erase;
- q.key = key;
- } else if (op == 1) {
- q.type = DbQuery::Set;
- q.key = key;
- q.value = value;
- }
- }
- }
-
- std::vector<std::vector<DbQuery>> res(threads_n);
- class Worker : public Actor {
- public:
- Worker(ActorShared<> parent, std::shared_ptr<QueryHandler<KeyValue>> kv, const std::vector<DbQuery> *queries,
- std::vector<DbQuery> *res)
- : parent_(std::move(parent)), kv_(std::move(kv)), queries_(queries), res_(res) {
- }
- void loop() override {
- for (auto q : *queries_) {
- kv_->do_query(q);
- res_->push_back(q);
- }
- stop();
- }
-
- private:
- ActorShared<> parent_;
- std::shared_ptr<QueryHandler<KeyValue>> kv_;
- const std::vector<DbQuery> *queries_;
- std::vector<DbQuery> *res_;
- };
- class Main : public Actor {
- public:
- Main(int threads_n, const std::vector<std::vector<DbQuery>> *queries, std::vector<std::vector<DbQuery>> *res)
- : threads_n_(threads_n), queries_(queries), res_(res) {
- }
-
- void start_up() override {
- LOG(INFO) << "start_up";
- kv_->impl().init("test_pmc").ensure();
- ref_cnt_ = threads_n_;
- for (int i = 0; i < threads_n_; i++) {
- create_actor_on_scheduler<Worker>("Worker", i + 1, actor_shared(this, 2), kv_, &queries_->at(i), &res_->at(i))
- .release();
- }
- }
-
- void tear_down() override {
- LOG(INFO) << "tear_down";
- // kv_->impl().close();
- }
- void hangup_shared() override {
- LOG(INFO) << "hangup";
- ref_cnt_--;
- if (ref_cnt_ == 0) {
- kv_->impl().close();
- Scheduler::instance()->finish();
- stop();
- }
- }
- void hangup() override {
- LOG(ERROR) << "BAD HANGUP";
- }
-
- private:
- int threads_n_;
- const std::vector<std::vector<DbQuery>> *queries_;
- std::vector<std::vector<DbQuery>> *res_;
-
- std::shared_ptr<QueryHandler<KeyValue>> kv_{new QueryHandler<KeyValue>()};
- int ref_cnt_;
- };
-
- ConcurrentScheduler sched;
- sched.init(threads_n);
- sched.create_actor_unsafe<Main>(0, "Main", threads_n, &queries, &res).release();
- sched.start();
- while (sched.run_main(10)) {
- // empty
- }
- sched.finish();
-
- std::vector<std::size_t> pos(threads_n);
- while (true) {
- bool was = false;
- for (int i = 0; i < threads_n; i++) {
- auto p = pos[i];
- if (p == res[i].size()) {
- continue;
- }
- auto &q = res[i][p];
- if (q.tid == 0) {
- if (q.type == DbQuery::Get) {
- auto nq = q;
- baseline.do_query(nq);
- if (nq.value == q.value) {
- was = true;
- pos[i]++;
- }
- } else {
- was = true;
- pos[i]++;
- }
- }
- }
- if (was) {
- continue;
- }
-
- int best = -1;
- SeqNo best_tid = 0;
- for (int i = 0; i < threads_n; i++) {
- auto p = pos[i];
- if (p == res[i].size()) {
- continue;
- }
- was = true;
- auto &q = res[i][p];
- if (q.tid != 0) {
- if (best == -1 || q.tid < best_tid) {
- best = i;
- best_tid = q.tid;
- }
- }
- }
- if (!was) {
- break;
- }
- ASSERT_TRUE(best != -1);
- baseline.do_query(res[best][pos[best]]);
- pos[best]++;
- }
- }
-}
diff --git a/libs/tdlib/td/test/fuzz_url.cpp b/libs/tdlib/td/test/fuzz_url.cpp
deleted file mode 100644
index 74047135c0..0000000000
--- a/libs/tdlib/td/test/fuzz_url.cpp
+++ /dev/null
@@ -1,33 +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 "td/telegram/MessageEntity.h"
-
-#include "td/utils/common.h"
-#include "td/utils/logging.h"
-#include "td/utils/Slice.h"
-
-#include <cstddef>
-#include <cstdint>
-
-static td::string get_utf_string(td::Slice from) {
- td::string res;
- td::string alph = " ab@./01#";
- for (auto c : from) {
- res += alph[td::uint8(c) % alph.size()];
- }
- LOG(ERROR) << res;
- return res;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(std::uint8_t *data, std::size_t data_size) {
- td::find_urls(get_utf_string(td::Slice(data, data_size)));
- //td::find_hashtags(get_utf_string(td::Slice(data, data_size)));
- //td::find_bot_commands(get_utf_string(td::Slice(data, data_size)));
- //td::is_email_address(get_utf_string(td::Slice(data, data_size)));
- //td::find_mentions(get_utf_string(td::Slice(data, data_size)));
- return 0;
-}
diff --git a/libs/tdlib/td/test/http.cpp b/libs/tdlib/td/test/http.cpp
deleted file mode 100644
index 98c94b2e8a..0000000000
--- a/libs/tdlib/td/test/http.cpp
+++ /dev/null
@@ -1,373 +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 "td/utils/tests.h"
-
-#include "td/net/HttpChunkedByteFlow.h"
-#include "td/net/HttpHeaderCreator.h"
-#include "td/net/HttpQuery.h"
-#include "td/net/HttpReader.h"
-
-#include "td/utils/AesCtrByteFlow.h"
-#include "td/utils/base64.h"
-#include "td/utils/buffer.h"
-#include "td/utils/BufferedFd.h"
-#include "td/utils/ByteFlow.h"
-#include "td/utils/crypto.h"
-#include "td/utils/format.h"
-#include "td/utils/Gzip.h"
-#include "td/utils/GzipByteFlow.h"
-#include "td/utils/logging.h"
-#include "td/utils/misc.h"
-#include "td/utils/port/Fd.h"
-#include "td/utils/port/FileFd.h"
-#include "td/utils/port/path.h"
-#include "td/utils/port/thread_local.h"
-#include "td/utils/Random.h"
-#include "td/utils/Slice.h"
-#include "td/utils/Status.h"
-
-#include "test/data.h"
-
-#include <algorithm>
-#include <cstdlib>
-#include <limits>
-
-REGISTER_TESTS(http)
-
-using namespace td;
-
-static string make_chunked(string str) {
- auto v = rand_split(str);
- string res;
- for (auto &s : v) {
- res += PSTRING() << format::as_hex_dump(int(s.size()));
- res += "\r\n";
- res += s;
- res += "\r\n";
- }
- res += "0\r\n\r\n";
- return res;
-}
-
-static string gen_http_content() {
- int t = Random::fast(0, 2);
- int len;
- if (t == 0) {
- len = Random::fast(1, 10);
- } else if (t == 1) {
- len = Random::fast(100, 200);
- } else {
- len = Random::fast(1000, 20000);
- }
- return rand_string(std::numeric_limits<char>::min(), std::numeric_limits<char>::max(), len);
-}
-
-static string make_http_query(string content, bool is_chunked, bool is_gzip, double gzip_k = 5,
- string zip_override = "") {
- HttpHeaderCreator hc;
- hc.init_post("/");
- hc.add_header("jfkdlsahhjk", rand_string('a', 'z', Random::fast(1, 2000)));
- if (is_gzip) {
- BufferSlice zip;
- if (zip_override.empty()) {
- zip = gzencode(content, gzip_k);
- } else {
- zip = BufferSlice(zip_override);
- }
- if (!zip.empty()) {
- hc.add_header("content-encoding", "gzip");
- content = zip.as_slice().str();
- }
- }
- if (is_chunked) {
- hc.add_header("transfer-encoding", "chunked");
- content = make_chunked(content);
- } else {
- hc.set_content_size(content.size());
- }
- string res;
- auto r_header = hc.finish();
- CHECK(r_header.is_ok());
- res += r_header.ok().str();
- res += content;
- return res;
-}
-
-static string rand_http_query(string content) {
- bool is_chunked = Random::fast(0, 1) == 0;
- bool is_gzip = Random::fast(0, 1) == 0;
- return make_http_query(std::move(content), is_chunked, is_gzip);
-}
-
-static string join(const std::vector<string> &v) {
- string res;
- for (auto &s : v) {
- res += s;
- }
- return res;
-}
-
-TEST(Http, stack_overflow) {
- ChainBufferWriter writer;
- BufferSlice slice(string(256, 'A'));
- for (int i = 0; i < 1000000; i++) {
- ChainBufferWriter tmp_writer;
- writer.append(slice.clone());
- }
- {
- auto reader = writer.extract_reader();
- reader.sync_with_writer();
- }
-}
-
-TEST(Http, reader) {
-#if TD_ANDROID || TD_TIZEN
- return;
-#endif
- clear_thread_locals();
- SET_VERBOSITY_LEVEL(VERBOSITY_NAME(INFO));
- auto start_mem = BufferAllocator::get_buffer_mem();
- {
- auto input_writer = ChainBufferWriter::create_empty();
- auto input = input_writer.extract_reader();
- HttpReader reader;
- int max_post_size = 10000;
- reader.init(&input, max_post_size, 0);
-
- std::srand(4);
- std::vector<string> contents(1000);
- std::generate(contents.begin(), contents.end(), gen_http_content);
- auto v = td::transform(contents, rand_http_query);
- auto vec_str = rand_split(join(v));
-
- HttpQuery q;
- std::vector<string> res;
- for (auto &str : vec_str) {
- input_writer.append(str);
- input.sync_with_writer();
- while (true) {
- auto r_state = reader.read_next(&q);
- LOG_IF(ERROR, r_state.is_error()) << r_state.error() << tag("ok", res.size());
- ASSERT_TRUE(r_state.is_ok());
- auto state = r_state.ok();
- if (state == 0) {
- if (q.files_.empty()) {
- ASSERT_TRUE(td::narrow_cast<int>(q.content_.size()) <= max_post_size);
- auto expected = contents[res.size()];
- ASSERT_EQ(expected, q.content_.str());
- res.push_back(q.content_.str());
- } else {
- auto r_fd = FileFd::open(q.files_[0].temp_file_name, FileFd::Read);
- ASSERT_TRUE(r_fd.is_ok());
- auto fd = r_fd.move_as_ok();
- string content(td::narrow_cast<size_t>(q.files_[0].size), '\0');
- auto r_size = fd.read(MutableSlice(content));
- ASSERT_TRUE(r_size.is_ok());
- ASSERT_TRUE(r_size.ok() == content.size());
- ASSERT_TRUE(td::narrow_cast<int>(content.size()) > max_post_size);
- ASSERT_EQ(contents[res.size()], content);
- res.push_back(content);
- fd.close();
- }
- } else {
- break;
- }
- }
- }
- ASSERT_EQ(contents.size(), res.size());
- ASSERT_EQ(contents, res);
- }
- clear_thread_locals();
- ASSERT_EQ(start_mem, BufferAllocator::get_buffer_mem());
-}
-
-TEST(Http, gzip_bomb) {
-#if TD_ANDROID || TD_TIZEN || TD_EMSCRIPTEN // the test should be disabled on low-memory systems
- return;
-#endif
- auto gzip_bomb_str =
- gzdecode(gzdecode(base64url_decode(Slice(gzip_bomb, gzip_bomb_size)).ok()).as_slice()).as_slice().str();
-
- auto query = make_http_query("", false, true, 0.01, gzip_bomb_str);
- auto parts = rand_split(query);
- auto input_writer = ChainBufferWriter::create_empty();
- auto input = input_writer.extract_reader();
- HttpReader reader;
- HttpQuery q;
- reader.init(&input, 100000000, 0);
- for (auto &part : parts) {
- input_writer.append(part);
- input.sync_with_writer();
- auto r_state = reader.read_next(&q);
- if (r_state.is_error()) {
- LOG(INFO) << r_state.error();
- return;
- }
- ASSERT_TRUE(r_state.ok() != 0);
- }
-}
-
-TEST(Http, aes_ctr_encode_decode_flow) {
- auto str = rand_string('a', 'z', 1000000);
- auto parts = rand_split(str);
- auto input_writer = ChainBufferWriter::create_empty();
- auto input = input_writer.extract_reader();
- ByteFlowSource source(&input);
- UInt256 key;
- UInt128 iv;
- Random::secure_bytes(key.raw, sizeof(key));
- Random::secure_bytes(iv.raw, sizeof(iv));
- AesCtrByteFlow aes_encode;
- aes_encode.init(key, iv);
- AesCtrByteFlow aes_decode;
- aes_decode.init(key, iv);
- ByteFlowSink sink;
- source >> aes_encode >> aes_decode >> sink;
-
- ASSERT_TRUE(!sink.is_ready());
- for (auto &part : parts) {
- input_writer.append(part);
- source.wakeup();
- }
- ASSERT_TRUE(!sink.is_ready());
- source.close_input(Status::OK());
- ASSERT_TRUE(sink.is_ready());
- LOG_IF(ERROR, sink.status().is_error()) << sink.status();
- ASSERT_TRUE(sink.status().is_ok());
- ASSERT_EQ(str, sink.result()->move_as_buffer_slice().as_slice().str());
-}
-
-TEST(Http, aes_file_encryption) {
- auto str = rand_string('a', 'z', 1000000);
- CSlice name = "test_encryption";
- unlink(name).ignore();
- UInt256 key;
- UInt128 iv;
- Random::secure_bytes(key.raw, sizeof(key));
- Random::secure_bytes(iv.raw, sizeof(iv));
-
- {
- BufferedFdBase<FileFd> fd(FileFd::open(name, FileFd::Write | FileFd::Create).move_as_ok());
-
- auto parts = rand_split(str);
-
- ChainBufferWriter output_writer;
- auto output_reader = output_writer.extract_reader();
- ByteFlowSource source(&output_reader);
- AesCtrByteFlow aes_encode;
- aes_encode.init(key, iv);
- ByteFlowSink sink;
-
- source >> aes_encode >> sink;
- fd.set_output_reader(sink.get_output());
-
- for (auto &part : parts) {
- output_writer.append(part);
- source.wakeup();
- fd.flush_write().ensure();
- }
- fd.close();
- }
-
- {
- BufferedFdBase<FileFd> fd(FileFd::open(name, FileFd::Read).move_as_ok());
-
- ChainBufferWriter input_writer;
- auto input_reader = input_writer.extract_reader();
- ByteFlowSource source(&input_reader);
- AesCtrByteFlow aes_encode;
- aes_encode.init(key, iv);
- ByteFlowSink sink;
- source >> aes_encode >> sink;
- fd.set_input_writer(&input_writer);
-
- fd.update_flags(Fd::Flag::Read);
- while (can_read(fd)) {
- fd.flush_read(4096).ensure();
- source.wakeup();
- }
-
- fd.close();
-
- source.close_input(Status::OK());
- ASSERT_TRUE(sink.is_ready());
- LOG_IF(ERROR, sink.status().is_error()) << sink.status();
- ASSERT_TRUE(sink.status().is_ok());
- auto result = sink.result()->move_as_buffer_slice().as_slice().str();
- ASSERT_EQ(str, result);
- }
-}
-
-TEST(Http, chunked_flow) {
- auto str = rand_string('a', 'z', 100);
- auto parts = rand_split(make_chunked(str));
- auto input_writer = ChainBufferWriter::create_empty();
- auto input = input_writer.extract_reader();
- ByteFlowSource source(&input);
- HttpChunkedByteFlow chunked_flow;
- ByteFlowSink sink;
- source >> chunked_flow >> sink;
-
- for (auto &part : parts) {
- input_writer.append(part);
- source.wakeup();
- }
- source.close_input(Status::OK());
- ASSERT_TRUE(sink.is_ready());
- LOG_IF(ERROR, sink.status().is_error()) << sink.status();
- ASSERT_TRUE(sink.status().is_ok());
- auto res = sink.result()->move_as_buffer_slice().as_slice().str();
- ASSERT_EQ(str.size(), res.size());
- ASSERT_EQ(str, res);
-}
-
-TEST(Http, chunked_flow_error) {
- auto str = rand_string('a', 'z', 100000);
- for (int d = 1; d < 100; d += 10) {
- auto new_str = make_chunked(str);
- new_str.resize(str.size() - d);
- auto parts = rand_split(new_str);
- auto input_writer = ChainBufferWriter::create_empty();
- auto input = input_writer.extract_reader();
- ByteFlowSource source(&input);
- HttpChunkedByteFlow chunked_flow;
- ByteFlowSink sink;
- source >> chunked_flow >> sink;
-
- for (auto &part : parts) {
- input_writer.append(part);
- source.wakeup();
- }
- ASSERT_TRUE(!sink.is_ready());
- source.close_input(Status::OK());
- ASSERT_TRUE(sink.is_ready());
- ASSERT_TRUE(!sink.status().is_ok());
- }
-}
-
-TEST(Http, gzip_chunked_flow) {
- auto str = rand_string('a', 'z', 1000000);
- auto parts = rand_split(make_chunked(gzencode(str).as_slice().str()));
-
- auto input_writer = ChainBufferWriter::create_empty();
- auto input = input_writer.extract_reader();
- ByteFlowSource source(&input);
- HttpChunkedByteFlow chunked_flow;
- GzipByteFlow gzip_flow(Gzip::Decode);
- ByteFlowSink sink;
- source >> chunked_flow >> gzip_flow >> sink;
-
- for (auto &part : parts) {
- input_writer.append(part);
- source.wakeup();
- }
- source.close_input(Status::OK());
- ASSERT_TRUE(sink.is_ready());
- LOG_IF(ERROR, sink.status().is_error()) << sink.status();
- ASSERT_TRUE(sink.status().is_ok());
- ASSERT_EQ(str, sink.result()->move_as_buffer_slice().as_slice().str());
-}
diff --git a/libs/tdlib/td/test/main.cpp b/libs/tdlib/td/test/main.cpp
deleted file mode 100644
index 0ef46c75b2..0000000000
--- a/libs/tdlib/td/test/main.cpp
+++ /dev/null
@@ -1,40 +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 "td/utils/tests.h"
-
-#include "td/utils/logging.h"
-
-#include <cstring>
-
-#if TD_EMSCRIPTEN
-#include <emscripten.h>
-#endif
-
-int main(int argc, char **argv) {
- // TODO port OptionsParser to Windows
- for (int i = 1; i < argc; i++) {
- if (!std::strcmp(argv[i], "--filter")) {
- CHECK(i + 1 < argc);
- td::Test::add_substr_filter(argv[++i]);
- }
- if (!std::strcmp(argv[i], "--stress")) {
- td::Test::set_stress_flag(true);
- }
- }
-#if TD_EMSCRIPTEN
- emscripten_set_main_loop(
- [] {
- if (!td::Test::run_all_step()) {
- emscripten_cancel_main_loop();
- }
- },
- 10, 0);
-#else
- td::Test::run_all();
-#endif
- return 0;
-}
diff --git a/libs/tdlib/td/test/message_entities.cpp b/libs/tdlib/td/test/message_entities.cpp
deleted file mode 100644
index 473a87140a..0000000000
--- a/libs/tdlib/td/test/message_entities.cpp
+++ /dev/null
@@ -1,529 +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 "td/telegram/MessageEntity.h"
-
-#include "td/utils/format.h"
-#include "td/utils/logging.h"
-#include "td/utils/tests.h"
-
-REGISTER_TESTS(message_entities);
-
-using namespace td;
-
-static void check_mention(string str, std::vector<string> expected) {
- auto result_slice = find_mentions(str);
- std::vector<string> result;
- for (auto &it : result_slice) {
- result.push_back(it.str());
- }
- if (result != expected) {
- LOG(FATAL) << tag("text", str) << tag("got", format::as_array(result))
- << tag("expected", format::as_array(expected));
- }
-}
-
-TEST(MessageEntities, mention) {
- check_mention("@mention", {"@mention"});
- check_mention("@mention ", {"@mention"});
- check_mention(" @mention", {"@mention"});
- check_mention(" @mention ", {"@mention"});
- check_mention("@abc @xyz @abc @xyz @xxx@yyy @ttt", {});
- check_mention("@abcde @xyzxy @abcde @xyzxy @xxxxx@yyyyy @ttttt",
- {"@abcde", "@xyzxy", "@abcde", "@xyzxy", "@xxxxx", "@ttttt"});
- check_mention("no@mention", {});
- check_mention("@n", {});
- check_mention("@abcdefghijklmnopqrstuvwxyz123456", {"@abcdefghijklmnopqrstuvwxyz123456"});
- check_mention("@abcdefghijklmnopqrstuvwxyz1234567", {});
- check_mention("нет@mention", {});
- check_mention("@ya @gif @wiki @vid @bing @pic @bold @imdb @coub @like @vote @giff @cap ya cap @y @yar @bingg @bin",
- {"@ya", "@gif", "@wiki", "@vid", "@bing", "@pic", "@bold", "@imdb", "@coub", "@like", "@vote", "@giff",
- "@cap", "@bingg"});
-};
-
-static void check_bot_command(string str, std::vector<string> expected) {
- auto result_slice = find_bot_commands(str);
- std::vector<string> result;
- for (auto &it : result_slice) {
- result.push_back(it.str());
- }
- if (result != expected) {
- LOG(FATAL) << tag("text", str) << tag("got", format::as_array(result))
- << tag("expected", format::as_array(expected));
- }
-}
-
-TEST(MessageEntities, bot_command) {
- // 1..64@3..32
- check_bot_command("/abc", {"/abc"});
- check_bot_command(" /abc", {"/abc"});
- check_bot_command("/abc ", {"/abc"});
- check_bot_command(" /abc ", {"/abc"});
- check_bot_command("/a@abc", {"/a@abc"});
- check_bot_command("/a@b", {});
- check_bot_command("/@bfdsa", {});
- check_bot_command("/test/", {});
-}
-
-static void check_hashtag(string str, std::vector<string> expected) {
- auto result_slice = find_hashtags(str);
- std::vector<string> result;
- for (auto &it : result_slice) {
- result.push_back(it.str());
- }
- if (result != expected) {
- LOG(FATAL) << tag("text", str) << tag("got", format::as_array(result))
- << tag("expected", format::as_array(expected));
- }
-}
-
-TEST(MessageEntities, hashtag) {
- check_hashtag("", {});
- check_hashtag("#", {});
- check_hashtag("##", {});
- check_hashtag("###", {});
- check_hashtag("#a", {"#a"});
- check_hashtag(" #a", {"#a"});
- check_hashtag("#a ", {"#a"});
- check_hashtag(" #я ", {"#я"});
- check_hashtag(" я#a ", {});
- check_hashtag(" #a# ", {});
- check_hashtag(" #123 ", {});
- check_hashtag(" #123a ", {"#123a"});
- check_hashtag(" #a123 ", {"#a123"});
- check_hashtag(" #123a# ", {});
- check_hashtag(" #" + string(300, '1'), {});
- check_hashtag(" #" + string(256, '1'), {});
- check_hashtag(" #" + string(256, '1') + "a ", {});
- check_hashtag(" #" + string(255, '1') + "a", {"#" + string(255, '1') + "a"});
- check_hashtag(" #" + string(255, '1') + "Я", {"#" + string(255, '1') + "Я"});
- check_hashtag(" #" + string(255, '1') + "a" + string(255, 'b') + "# ", {});
- check_hashtag("#a#b #c #d", {"#c", "#d"});
- check_hashtag("#test", {"#test"});
- check_hashtag(u8"\U0001F604\U0001F604\U0001F604\U0001F604 \U0001F604\U0001F604\U0001F604#" + string(200, '1') +
- "ООО" + string(200, '2'),
- {"#" + string(200, '1') + "ООО" + string(53, '2')});
- check_hashtag(u8"#a\u2122", {"#a"});
-}
-
-static void check_cashtag(string str, std::vector<string> expected) {
- auto result_slice = find_cashtags(str);
- std::vector<string> result;
- for (auto &it : result_slice) {
- result.push_back(it.str());
- }
- if (result != expected) {
- LOG(FATAL) << tag("text", str) << tag("got", format::as_array(result))
- << tag("expected", format::as_array(expected));
- }
-}
-
-TEST(MessageEntities, cashtag) {
- check_cashtag("", {});
- check_cashtag("$", {});
- check_cashtag("$$", {});
- check_cashtag("$$$", {});
- check_cashtag("$a", {});
- check_cashtag(" $a", {});
- check_cashtag("$a ", {});
- check_cashtag(" $я ", {});
- check_cashtag("$ab", {});
- check_cashtag("$abc", {});
- check_cashtag("$", {});
- check_cashtag("$A", {});
- check_cashtag("$AB", {});
- check_cashtag("$АBC", {});
- check_cashtag("$АВС", {});
- check_cashtag("$ABC", {"$ABC"});
- check_cashtag("$ABCD", {"$ABCD"});
- check_cashtag("$ABCDE", {"$ABCDE"});
- check_cashtag("$ABCDEF", {"$ABCDEF"});
- check_cashtag("$ABCDEFG", {"$ABCDEFG"});
- check_cashtag("$ABCDEFGH", {"$ABCDEFGH"});
- check_cashtag("$ABCDEFGHJ", {});
- check_cashtag("$ABCDEFGH1", {});
- check_cashtag(" $XYZ", {"$XYZ"});
- check_cashtag("$XYZ ", {"$XYZ"});
- check_cashtag(" $XYZ ", {"$XYZ"});
- check_cashtag(" $$XYZ ", {});
- check_cashtag(" $XYZ$ ", {});
- check_cashtag(" $ABC1 ", {});
- check_cashtag(" $1ABC ", {});
- check_cashtag(" 1$ABC ", {});
- check_cashtag(" А$ABC ", {});
- check_cashtag("$ABC$DEF $GHI $KLM", {"$GHI", "$KLM"});
- check_cashtag("$TEST", {"$TEST"});
- check_cashtag(u8"$ABC\u2122", {"$ABC"});
- check_cashtag(u8"\u2122$ABC", {"$ABC"});
- check_cashtag(u8"\u2122$ABC\u2122", {"$ABC"});
-}
-
-static void check_is_email_address(string str, bool expected) {
- bool result = is_email_address(str);
- LOG_IF(FATAL, result != expected) << "Expected " << expected << " as result of is_email_address(" << str << ")";
-}
-
-TEST(MessageEntities, is_email_address) {
- check_is_email_address("telegram.org", false);
- check_is_email_address("security@telegram.org", true);
- check_is_email_address("security.telegram.org", false);
- check_is_email_address("", false);
- check_is_email_address("@", false);
- check_is_email_address("A@a.a.a.ab", true);
- check_is_email_address("A@a.ab", true);
- check_is_email_address("Test@aa.aa.aa.aa", true);
- check_is_email_address("Test@test.abd", true);
- check_is_email_address("a@a.a.a.ab", true);
- check_is_email_address("test@test.abd", true);
- check_is_email_address("test@test.com", true);
- check_is_email_address("test.abd", false);
- check_is_email_address("a.ab", false);
- check_is_email_address("a.bc@d.ef", true);
-
- vector<string> bad_userdatas = {"",
- "a.a.a.a.a.a.a.a.a.a.a.a",
- "+.+.+.+.+.+",
- "*.a.a",
- "a.*.a",
- "a.a.*",
- "a.a.",
- "a.a.abcdefghijklmnopqrstuvwxyz0123456789",
- "a.abcdefghijklmnopqrstuvwxyz0.a",
- "abcdefghijklmnopqrstuvwxyz0.a.a"};
- vector<string> good_userdatas = {"a.a.a.a.a.a.a.a.a.a.a",
- "a+a+a+a+a+a+a+a+a+a+a",
- "+.+.+.+.+._",
- "aozAQZ0-5-9_+-aozAQZ0-5-9_.aozAQZ0-5-9_.-._.+-",
- "a.a.a",
- "a.a.abcdefghijklmnopqrstuvwxyz012345678",
- "a.abcdefghijklmnopqrstuvwxyz.a",
- "a..a",
- "abcdefghijklmnopqrstuvwxyz.a.a",
- ".a.a"};
-
- vector<string> bad_domains = {"",
- ".",
- "abc",
- "localhost",
- "a.a.a.a.a.a.a.ab",
- ".......",
- "a.a.a.a.a.a+ab",
- "a+a.a.a.a.a.ab",
- "a.a.a.a.a.a.a",
- "a.a.a.a.a.a.abcdefg",
- "a.a.a.a.a.a.ab0yz",
- "a.a.a.a.a.a.ab9yz",
- "a.a.a.a.a.a.ab-yz",
- "a.a.a.a.a.a.ab_yz",
- "a.a.a.a.a.a.ab*yz",
- ".ab",
- ".a.ab",
- "a..ab",
- "a.a.a..a.ab",
- ".a.a.a.a.ab",
- "abcdefghijklmnopqrstuvwxyz01234.ab",
- "ab0cd.abd.aA*sd.0.9.0-9.ABOYZ",
- "ab*cd.abd.aAasd.0.9.0-9.ABOYZ",
- "ab0cd.abd.aAasd.0.9.0*9.ABOYZ",
- "*b0cd.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0c*.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9.0-*.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9.*-9.ABOYZ",
- "-b0cd.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0c-.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0cd.ab_d.aA-sd.-.9.0-9.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9.--9.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9.0--.ABOYZ",
- "_b0cd.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0c_.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0cd.ab_d.aA-sd._.9.0-9.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9._-9.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9.0-_.ABOYZ",
- "-.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0cd.ab_d.-.0.9.0-9.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9.-.ABOYZ",
- "_.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "ab0cd.ab_d._.0.9.0-9.ABOYZ",
- "ab0cd.ab_d.aA-sd.0.9._.ABOYZ"};
- vector<string> good_domains = {"a.a.a.a.a.a.ab",
- "a.a.a.a.a.a.abcdef",
- "a.a.a.a.a.a.aboyz",
- "a.a.a.a.a.a.ABOYZ",
- "a.a.a.a.a.a.AbOyZ",
- "abcdefghijklmnopqrstuvwxyz0123.ab",
- "ab0cd.ab_d.aA-sd.0.9.0-9.ABOYZ",
- "A.Z.aA-sd.a.z.0-9.ABOYZ"};
-
- for (auto &userdata : bad_userdatas) {
- for (auto &domain : bad_domains) {
- check_is_email_address(userdata + '@' + domain, false);
- check_is_email_address(userdata + domain, false);
- }
- for (auto &domain : good_domains) {
- check_is_email_address(userdata + '@' + domain, false);
- check_is_email_address(userdata + domain, false);
- }
- }
- for (auto &userdata : good_userdatas) {
- for (auto &domain : bad_domains) {
- check_is_email_address(userdata + '@' + domain, false);
- check_is_email_address(userdata + domain, false);
- }
- for (auto &domain : good_domains) {
- check_is_email_address(userdata + '@' + domain, true);
- check_is_email_address(userdata + domain, false);
- }
- }
-}
-
-static void check_url(string str, std::vector<string> expected_urls,
- std::vector<string> expected_email_addresses = {}) {
- auto result_slice = find_urls(str);
- std::vector<string> result_urls;
- std::vector<string> result_email_addresses;
- for (auto &it : result_slice) {
- if (!it.second) {
- result_urls.push_back(it.first.str());
- } else {
- result_email_addresses.push_back(it.first.str());
- }
- }
- if (result_urls != expected_urls) {
- LOG(FATAL) << tag("text", str) << tag("got", format::as_array(result_urls))
- << tag("expected", format::as_array(expected_urls));
- }
- if (result_email_addresses != expected_email_addresses) {
- LOG(FATAL) << tag("text", str) << tag("got", format::as_array(result_email_addresses))
- << tag("expected", format::as_array(expected_email_addresses));
- }
-}
-
-TEST(MessageEntities, url) {
- check_url("telegram.org", {"telegram.org"});
- check_url("(telegram.org)", {"telegram.org"});
- check_url("\ntelegram.org)", {"telegram.org"});
- check_url(" telegram.org)", {"telegram.org"});
- check_url(".telegram.org)", {});
- check_url("()telegram.org/?q=()", {"telegram.org/?q=()"});
- check_url("\"telegram.org\"", {"telegram.org"});
- check_url(" telegram. org. www. com... telegram.org... ...google.com...", {"telegram.org"});
- check_url(" telegram.org ", {"telegram.org"});
- check_url("Такой сайт: http://www.google.com или такой telegram.org ", {"http://www.google.com", "telegram.org"});
- check_url(" telegram.org. ", {"telegram.org"});
- check_url("http://google,.com", {});
- check_url("http://telegram.org/?asd=123#123.", {"http://telegram.org/?asd=123#123"});
- check_url("[http://google.com](test)", {"http://google.com"});
- check_url("", {});
- check_url(".", {});
- check_url("http://@google.com", {});
- check_url("http://@goog.com", {}); // TODO: server fix
- check_url("http://@@google.com", {"http://@@google.com"});
- check_url("http://a@google.com", {"http://a@google.com"});
- check_url("http://test@google.com", {"http://test@google.com"});
- check_url("google.com:᪉᪉᪉᪉᪉", {"google.com"});
- check_url("https://telegram.org", {"https://telegram.org"});
- check_url("http://telegram.org", {"http://telegram.org"});
- check_url("ftp://telegram.org", {"ftp://telegram.org"});
- check_url("ftps://telegram.org", {});
- check_url("sftp://telegram.org", {"sftp://telegram.org"});
- check_url("hTtPs://telegram.org", {"hTtPs://telegram.org"});
- check_url("HTTP://telegram.org", {"HTTP://telegram.org"});
- check_url("аHTTP://telegram.org", {"HTTP://telegram.org"});
- check_url("sHTTP://telegram.org", {});
- check_url("://telegram.org", {});
- check_url("google.com:᪀᪀", {"google.com"});
- check_url(
- "http://"
- "abcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkab"
- "cdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcd"
- "efghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdef"
- "ghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefgh"
- "ijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghij"
- "kabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijka"
- "bcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabc"
- "defghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijk.com",
- {});
- check_url("http://  .com", {});
- check_url("URL:     .com", {});
- check_url("URL: .com", {});
- check_url(".com", {});
- check_url("http://  .", {});
- check_url("http://.", {});
- check_url("http://.com", {});
- check_url("http:// .", {});
- check_url(",ahttp://google.com", {"http://google.com"});
- check_url(".ahttp://google.com", {});
- check_url("http://1.0", {});
- check_url("http://a.0", {});
- check_url("http://a.a", {});
- check_url("google.com:1#ab c", {"google.com:1#ab"});
- check_url("google.com:1#", {"google.com:1#"});
- check_url("google.com:1#1", {"google.com:1#1"});
- check_url("google.com:00000001/abs", {"google.com:00000001/abs"});
- check_url("google.com:000000065535/abs", {"google.com:000000065535/abs"});
- check_url("google.com:000000065536/abs", {"google.com"});
- check_url("google.com:000000080/abs", {"google.com:000000080/abs"});
- check_url("google.com:0000000/abs", {"google.com"});
- check_url("google.com:0/abs", {"google.com"});
- check_url("google.com:/abs", {"google.com"});
- check_url("google.com:65535", {"google.com:65535"});
- check_url("google.com:65536", {"google.com"});
- check_url("google.com:99999", {"google.com"});
- check_url("google.com:100000", {"google.com"});
- check_url("127.001", {});
- check_url("127.0.0.1", {"127.0.0.1"});
- check_url("127.0.0.01", {});
- check_url("127.0.0.256", {});
- check_url("127.0.0.300", {});
- check_url("127.0.0.1000", {});
- check_url("127.0.0.260", {});
- check_url("1.0", {});
- check_url("www.🤙.tk", {"www.🤙.tk"});
- check_url("a.ab", {});
- check_url("test.abd", {});
- check_url("ТеСт.Москва", {});
- check_url("ТеСт.МоСкВΑ", {});
- check_url("ТеСт.МоСкВа", {"ТеСт.МоСкВа"});
- check_url("ТеСт.МоСкВач", {});
- check_url("http://ÀТеСт.МоСкВач", {"http://ÀТеСт.МоСкВач"});
- check_url("ÀÁ.com. ÀÁ.com.", {"ÀÁ.com", "ÀÁ.com"});
- check_url("ÀÁ.com,ÀÁ.com.", {"ÀÁ.com", "ÀÁ.com"});
- check_url("teiegram.org", {});
- check_url("http://test.google.com/?q=abc()}[]def", {"http://test.google.com/?q=abc()"});
- check_url("http://test.google.com/?q=abc([{)]}def", {"http://test.google.com/?q=abc([{)]}def"});
- check_url("http://test.google.com/?q=abc(){}]def", {"http://test.google.com/?q=abc(){}"});
- check_url("http://test.google.com/?q=abc){}[]def", {"http://test.google.com/?q=abc"});
- check_url("http://test.google.com/?q=abc(){}[]def", {"http://test.google.com/?q=abc(){}[]def"});
- check_url("http://test-.google.com", {});
- check_url("http://test_.google.com", {"http://test_.google.com"});
- check_url("http://google_.com", {});
- check_url("http://google._com_", {});
- check_url("http://[2001:4860:0:2001::68]/", {}); // TODO
- check_url("test.abd", {});
- check_url("/.b/..a @.....@/. a.ba", {"a.ba"});
- check_url("bbbbbbbbbbbbbb.@.@", {});
- check_url("http://google.com/", {"http://google.com/"});
- check_url("http://google.com?", {"http://google.com"});
- check_url("http://google.com#", {"http://google.com#"});
- check_url("http://google.com/?", {"http://google.com/"});
- check_url("https://www.google.com/ab,", {"https://www.google.com/ab"});
- check_url("@.", {});
- check_url(
- "a.b.google.com dfsknnfs gsdfgsg http://códuia.de/ dffdg,\" 12)(cpia.de/())(\" http://гришка.рф/ sdufhdf "
- "http://xn--80afpi2a3c.xn--p1ai/ I have a good time.Thanks, guys!\n\n(hdfughidufhgdis)go#ogle.com гришка.рф "
- "hsighsdf gi почта.рф\n\n✪df.ws/123 "
- "xn--80afpi2a3c.xn--p1ai\n\nhttp://foo.com/blah_blah\nhttp://foo.com/blah_blah/\n(Something like "
- "http://foo.com/blah_blah)\nhttp://foo.com/blah_blah_(wikipedi8989a_Вася)\n(Something like "
- "http://foo.com/blah_blah_(Стакан_007))\nhttp://foo.com/blah_blah.\nhttp://foo.com/blah_blah/.\n<http://foo.com/"
- "blah_blah>\n<http://fo@@@@@@@@@^%#*@^&@$#*@#%^*&!^#o.com/blah_blah/>\nhttp://foo.com/blah_blah,\nhttp://"
- "www.example.com/wpstyle/?p=364.\nhttp://✪df.ws/123\nrdar://1234\nrdar:/1234\nhttp://"
- "userid:password@example.com:8080\nhttp://userid@example.com\nhttp://userid@example.com:8080\nhttp://"
- "userid:password@example.com\nhttp://example.com:8080 "
- "x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E\nmessage://"
- "%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e\nhttp://➡️.ws/䨹\nwww.➡️.ws/"
- "䨹\n<tag>http://example.com</tag>\nJust a www.example.com "
- "link.\n\n➡️.ws/"
- "䨹\n\nabcdefghijklmnopqrstuvwxyz0123456789qwe_sdfsdf.aweawe-sdfs.com\nwww.🤙.tk:1\ngoogle.com:"
- "᪉᪉᪉᪉\ngoogle."
- "com:᪀᪀\nhttp://  .com\nURL:     .com\nURL: "
- ".com\n\ngoogle.com?qwe\ngoogle.com#qwe\ngoogle.com/?\ngoogle.com/#\ngoogle.com?\ngoogle.com#\n",
- {"a.b.google.com",
- "http://códuia.de/",
- "cpia.de/()",
- "http://гришка.рф/",
- "http://xn--80afpi2a3c.xn--p1ai/",
- "гришка.рф",
- "почта.рф",
- "✪df.ws/123",
- "xn--80afpi2a3c.xn--p1ai",
- "http://foo.com/blah_blah",
- "http://foo.com/blah_blah/",
- "http://foo.com/blah_blah",
- "http://foo.com/blah_blah_(wikipedi8989a_Вася)",
- "http://foo.com/blah_blah_(Стакан_007)",
- "http://foo.com/blah_blah",
- "http://foo.com/blah_blah/",
- "http://foo.com/blah_blah",
- "http://foo.com/blah_blah",
- "http://www.example.com/wpstyle/?p=364",
- "http://✪df.ws/123",
- "http://userid:password@example.com:8080",
- "http://userid@example.com",
- "http://userid@example.com:8080",
- "http://userid:password@example.com",
- "http://example.com:8080",
- "http://➡️.ws/䨹",
- "www.➡️.ws/䨹",
- "http://example.com",
- "www.example.com",
- "➡️.ws/䨹",
- "abcdefghijklmnopqrstuvwxyz0123456789qwe_sdfsdf.aweawe-sdfs.com",
- "www.🤙.tk:1",
- "google.com",
- "google.com",
- "google.com?qwe",
- "google.com#qwe",
- "google.com/",
- "google.com/#",
- "google.com",
- "google.com#"});
- check_url("https://t.…", {});
- check_url("('http://telegram.org/a-b/?br=ie&lang=en',)", {"http://telegram.org/a-b/?br=ie&lang=en"});
- check_url("https://ai.telegram.org/bot%20bot/test-...", {"https://ai.telegram.org/bot%20bot/test-"});
- check_url("a.bc@c.com", {}, {"a.bc@c.com"});
- check_url("https://a.bc@c.com", {"https://a.bc@c.com"});
- check_url("https://a.de[bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.de/bc@c.com", {"https://a.de/bc@c.com"});
- check_url("https://a.de]bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.de{bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.de}bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.de(bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.de)bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.de\\bc@c.com", {"https://a.de\\bc@c.com"});
- check_url("https://a.de'bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.de`bc@c.com", {"https://a.de"}, {"bc@c.com"});
- check_url("https://a.bc:de.fg@c.com", {"https://a.bc:de.fg@c.com"});
- check_url("https://a:h.bc:de.fg@c.com", {"https://a:h.bc:de.fg@c.com"});
- check_url("https://abc@c.com", {"https://abc@c.com"});
- check_url("https://de[bc@c.com", {}, {"bc@c.com"});
- check_url("https://de/bc@c.com", {});
- check_url("https://de]bc@c.com", {}, {"bc@c.com"});
- check_url("https://de{bc@c.com", {}, {"bc@c.com"});
- check_url("https://de}bc@c.com", {}, {"bc@c.com"});
- check_url("https://de(bc@c.com", {}, {"bc@c.com"});
- check_url("https://de)bc@c.com", {}, {"bc@c.com"});
- check_url("https://de\\bc@c.com", {"https://de\\bc@c.com"});
- check_url("https://de'bc@c.com", {}, {"bc@c.com"});
- check_url("https://de`bc@c.com", {}, {"bc@c.com"});
- check_url("https://bc:defg@c.com", {"https://bc:defg@c.com"});
- check_url("https://a:hbc:defg@c.com", {"https://a:hbc:defg@c.com"});
- check_url("https://a.bc@test.com:cd.com", {"https://a.bc@test.com", "cd.com"});
- check_url("telegram.Org", {});
- check_url("telegram.ORG", {"telegram.ORG"});
- check_url("a.b.c.com.a.b.c", {});
- check_url("File '/usr/views.py'", {}); // TODO server fix
- check_url("@views.py'", {}); // TODO server fix
- check_url("#views.py'", {}); // TODO server fix
- check_url("/views.py'", {}); // TODO server fix
- check_url(".views.py", {});
- check_url("'views.py'", {"views.py"});
- check_url("bug.http://test.com/test/+#", {}); // TODO {"http://test.com/test/+#"}
- check_url("//AB.C.D.E.F.GH//", {});
- check_url("<http://www.ics.uci.edu/pub/ietf/uri/historical.html#WARNING>",
- {"http://www.ics.uci.edu/pub/ietf/uri/historical.html#WARNING"});
- check_url("Look :test@example.com", {":test@example.com"}, {}); // TODO {}, {"test@example.com"}
- check_url("http://test.com#a", {"http://test.com#a"});
- check_url("http://test.com#", {"http://test.com#"});
- check_url("http://test.com?#", {"http://test.com?#"});
- check_url("http://test.com/?#", {"http://test.com/?#"});
- check_url("https://t.me/abcdef…", {"https://t.me/abcdef"});
- check_url("https://t.me…", {"https://t.me"});
- check_url("https://t.m…", {});
- check_url("https://t.…", {});
- check_url("https://t…", {});
- check_url("👉http://ab.com/cdefgh-1IJ", {"http://ab.com/cdefgh-1IJ"});
- check_url("...👉http://ab.com/cdefgh-1IJ", {}); // TODO
-}
diff --git a/libs/tdlib/td/test/mtproto.cpp b/libs/tdlib/td/test/mtproto.cpp
deleted file mode 100644
index 7702a1e37b..0000000000
--- a/libs/tdlib/td/test/mtproto.cpp
+++ /dev/null
@@ -1,347 +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 "td/utils/tests.h"
-
-#include "td/actor/actor.h"
-#include "td/actor/PromiseFuture.h"
-
-#include "td/mtproto/crypto.h"
-#include "td/mtproto/Handshake.h"
-#include "td/mtproto/HandshakeActor.h"
-#include "td/mtproto/HandshakeConnection.h"
-#include "td/mtproto/PingConnection.h"
-#include "td/mtproto/RawConnection.h"
-
-#include "td/net/Socks5.h"
-
-#include "td/telegram/ConfigManager.h"
-#include "td/telegram/net/PublicRsaKeyShared.h"
-
-#include "td/utils/logging.h"
-#include "td/utils/port/IPAddress.h"
-#include "td/utils/port/SocketFd.h"
-#include "td/utils/Status.h"
-
-REGISTER_TESTS(mtproto);
-
-using namespace td;
-using namespace mtproto;
-
-#if !TD_WINDOWS && !TD_EMSCRIPTEN // TODO
-TEST(Mtproto, config) {
- ConcurrentScheduler sched;
- int threads_n = 0;
- sched.init(threads_n);
-
- int cnt = 3;
- {
- auto guard = sched.get_current_guard();
- get_simple_config_azure(PromiseCreator::lambda([&](Result<SimpleConfig> r_simple_config) {
- LOG(ERROR) << to_string(r_simple_config.ok());
- if (--cnt == 0) {
- Scheduler::instance()->finish();
- }
- }))
- .release();
-
- get_simple_config_google_app(PromiseCreator::lambda([&](Result<SimpleConfig> r_simple_config) {
- LOG(ERROR) << to_string(r_simple_config.ok());
- if (--cnt == 0) {
- Scheduler::instance()->finish();
- }
- }))
- .release();
-
- get_simple_config_google_dns(PromiseCreator::lambda([&](Result<SimpleConfig> r_simple_config) {
- LOG(ERROR) << to_string(r_simple_config.ok());
- if (--cnt == 0) {
- Scheduler::instance()->finish();
- }
- }))
- .release();
- }
- sched.start();
- while (sched.run_main(10)) {
- // empty;
- }
- sched.finish();
-}
-#endif
-
-TEST(Mtproto, encrypted_config) {
- string data =
- " LQ2 \b\n\tru6xVXpHHckW4eQWK0X3uThupVOor5sXT8t298IjDksYeUseQTOIrnUqiQj7o"
- "+ZgPfhnfe+lfcQA+naax9akgllimjlJtL5riTf3O7iqZSnJ614qmCucxqqVTbXk/"
- "hY2KaJTtsMqk7cShJjM3aQ4DD40h2InTaG7uyVO2q7K0GMUTeY3AM0Rt1lUjKHLD"
- "g4RwjTzZaG8TwfgL/mZ7jsvgTTTATPWKUo7SmxQ9Hsj+07NMGqr6JKZS6aiU1Knz"
- "VGCZ3OJEyRYocktN4HjaLpkguilaHWlVM2UNFUd5a+ajfLIiiKlH0FRC3XZ12CND"
- "Y+NBjv0I57N2O4fBfswTlA== ";
- auto config = decode_config(data).move_as_ok();
-}
-
-class TestPingActor : public Actor {
- public:
- TestPingActor(IPAddress ip_address, Status *result) : ip_address_(ip_address), result_(result) {
- }
-
- private:
- IPAddress ip_address_;
- std::unique_ptr<mtproto::PingConnection> ping_connection_;
- Status *result_;
-
- void start_up() override {
- ping_connection_ = std::make_unique<mtproto::PingConnection>(std::make_unique<mtproto::RawConnection>(
- SocketFd::open(ip_address_).move_as_ok(), mtproto::TransportType::Tcp, nullptr));
-
- ping_connection_->get_pollable().set_observer(this);
- subscribe(ping_connection_->get_pollable());
- set_timeout_in(10);
- yield();
- }
- void tear_down() override {
- unsubscribe_before_close(ping_connection_->get_pollable());
- ping_connection_->close();
- Scheduler::instance()->finish();
- }
-
- void loop() override {
- auto status = ping_connection_->flush();
- if (status.is_error()) {
- *result_ = std::move(status);
- return stop();
- }
- if (ping_connection_->was_pong()) {
- LOG(ERROR) << "GOT PONG";
- return stop();
- }
- }
-
- void timeout_expired() override {
- *result_ = Status::Error("Timeout expired");
- stop();
- }
-};
-
-static IPAddress get_default_ip_address() {
- IPAddress ip_address;
- ip_address.init_ipv4_port("149.154.167.40", 80).ensure();
- return ip_address;
-}
-
-class Mtproto_ping : public td::Test {
- public:
- using Test::Test;
- bool step() final {
- if (!is_inited_) {
- sched_.init(0);
- sched_.create_actor_unsafe<TestPingActor>(0, "Pinger", get_default_ip_address(), &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_;
-};
-Mtproto_ping mtproto_ping("Mtproto_ping");
-
-class Context : public AuthKeyHandshakeContext {
- public:
- DhCallback *get_dh_callback() override {
- return nullptr;
- }
- PublicRsaKeyInterface *get_public_rsa_key_interface() override {
- return &public_rsa_key;
- }
-
- private:
- PublicRsaKeyShared public_rsa_key{DcId::empty()};
-};
-
-class HandshakeTestActor : public Actor {
- public:
- explicit HandshakeTestActor(Status *result) : result_(result) {
- }
-
- private:
- Status *result_;
- bool wait_for_raw_connection_ = false;
- std::unique_ptr<RawConnection> raw_connection_;
- bool wait_for_handshake_ = false;
- std::unique_ptr<AuthKeyHandshake> handshake_;
- Status status_;
- bool wait_for_result_ = false;
-
- void tear_down() override {
- if (raw_connection_) {
- raw_connection_->close();
- }
- finish(Status::Error("Interrupted"));
- }
- void loop() override {
- if (!wait_for_raw_connection_ && !raw_connection_) {
- raw_connection_ = std::make_unique<mtproto::RawConnection>(SocketFd::open(get_default_ip_address()).move_as_ok(),
- mtproto::TransportType::Tcp, nullptr);
- }
- if (!wait_for_handshake_ && !handshake_) {
- handshake_ = std::make_unique<AuthKeyHandshake>(0);
- }
- if (raw_connection_ && handshake_) {
- if (wait_for_result_) {
- wait_for_result_ = false;
- if (status_.is_error()) {
- finish(std::move(status_));
- return stop();
- }
- if (!handshake_->is_ready_for_finish()) {
- finish(Status::Error("Key is not ready.."));
- return stop();
- }
- finish(Status::OK());
- return stop();
- }
-
- wait_for_result_ = true;
- create_actor<HandshakeActor>(
- "HandshakeActor", std::move(handshake_), std::move(raw_connection_), std::make_unique<Context>(), 10.0,
- PromiseCreator::lambda([self = actor_id(this)](Result<std::unique_ptr<RawConnection>> raw_connection) {
- send_closure(self, &HandshakeTestActor::got_connection, std::move(raw_connection), 1);
- }),
- PromiseCreator::lambda([self = actor_id(this)](Result<std::unique_ptr<AuthKeyHandshake>> handshake) {
- send_closure(self, &HandshakeTestActor::got_handshake, std::move(handshake), 1);
- }))
- .release();
- wait_for_raw_connection_ = true;
- wait_for_handshake_ = true;
- }
- }
-
- void got_connection(Result<std::unique_ptr<RawConnection>> r_raw_connection, int32 dummy) {
- CHECK(wait_for_raw_connection_);
- wait_for_raw_connection_ = false;
- if (r_raw_connection.is_ok()) {
- raw_connection_ = r_raw_connection.move_as_ok();
- status_ = Status::OK();
- } else {
- status_ = r_raw_connection.move_as_error();
- }
- // TODO: save error
- loop();
- }
-
- void got_handshake(Result<std::unique_ptr<AuthKeyHandshake>> r_handshake, int32 dummy) {
- CHECK(wait_for_handshake_);
- wait_for_handshake_ = false;
- CHECK(r_handshake.is_ok());
- handshake_ = r_handshake.move_as_ok();
- loop();
- }
-
- void finish(Status status) {
- if (!result_) {
- return;
- }
- *result_ = std::move(status);
- result_ = nullptr;
- Scheduler::instance()->finish();
- }
-};
-
-class Mtproto_handshake : public td::Test {
- public:
- using Test::Test;
- bool step() final {
- if (!is_inited_) {
- sched_.init(0);
- sched_.create_actor_unsafe<HandshakeTestActor>(0, "HandshakeTestActor", &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_;
-};
-Mtproto_handshake mtproto_handshake("Mtproto_handshake");
-
-class Socks5TestActor : public Actor {
- public:
- void start_up() override {
- auto promise = PromiseCreator::lambda([actor_id = actor_id(this)](Result<SocketFd> res) {
- send_closure(actor_id, &Socks5TestActor::on_result, std::move(res), false);
- });
-
- class Callback : public Socks5::Callback {
- public:
- explicit Callback(Promise<SocketFd> promise) : promise_(std::move(promise)) {
- }
- void set_result(Result<SocketFd> result) override {
- promise_.set_result(std::move(result));
- }
- void on_connected() override {
- }
-
- private:
- Promise<SocketFd> promise_;
- };
-
- IPAddress socks5_ip;
- socks5_ip.init_ipv4_port("131.191.89.104", 43077).ensure();
- IPAddress mtproto_ip = get_default_ip_address();
-
- auto r_socket = SocketFd::open(socks5_ip);
- create_actor<Socks5>("socks5", r_socket.move_as_ok(), mtproto_ip, "", "",
- std::make_unique<Callback>(std::move(promise)), actor_shared())
- .release();
- }
-
- private:
- void on_result(Result<SocketFd> res, bool dummy) {
- res.ensure();
- Scheduler::instance()->finish();
- }
-};
-
-TEST(Mtproto, socks5) {
- return;
- ConcurrentScheduler sched;
- int threads_n = 0;
- sched.init(threads_n);
-
- sched.create_actor_unsafe<Socks5TestActor>(0, "Socks5TestActor").release();
- sched.start();
- while (sched.run_main(10)) {
- // empty;
- }
- sched.finish();
-}
diff --git a/libs/tdlib/td/test/secret.cpp b/libs/tdlib/td/test/secret.cpp
deleted file mode 100644
index 2abed9787b..0000000000
--- a/libs/tdlib/td/test/secret.cpp
+++ /dev/null
@@ -1,1056 +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 "td/actor/PromiseFuture.h"
-
-#include "td/db/binlog/detail/BinlogEventsProcessor.h"
-
-#include "td/mtproto/crypto.h"
-#include "td/mtproto/utils.h"
-
-#include "td/telegram/Global.h"
-#include "td/telegram/MessageId.h"
-#include "td/telegram/SecretChatActor.h"
-#include "td/telegram/SecretChatId.h"
-
-#include "td/telegram/secret_api.h"
-#include "td/telegram/telegram_api.h"
-
-#include "td/tl/tl_object_parse.h"
-#include "td/tl/tl_object_store.h"
-
-#include "td/utils/base64.h"
-#include "td/utils/buffer.h"
-#include "td/utils/crypto.h"
-#include "td/utils/format.h"
-#include "td/utils/Gzip.h"
-#include "td/utils/logging.h"
-#include "td/utils/misc.h"
-#include "td/utils/Random.h"
-#include "td/utils/Slice.h"
-#include "td/utils/Status.h"
-#include "td/utils/tests.h"
-#include "td/utils/tl_helpers.h"
-#include "td/utils/tl_parsers.h"
-#include "td/utils/tl_storers.h"
-
-#include <cstdio>
-#include <ctime>
-#include <limits>
-#include <map>
-#include <memory>
-
-REGISTER_TESTS(secret);
-
-namespace my_api {
-
-using namespace td;
-
-//messages_getDhConfig
-class messages_getDhConfig {
- public:
- int32 version_;
- int32 random_length_;
-
- messages_getDhConfig() = default;
-
- messages_getDhConfig(int32 version_, int32 random_length_);
-
- static const int32 ID = 651135312;
-
- explicit messages_getDhConfig(TlBufferParser &p)
-#define FAIL(error) p.set_error(error)
- : version_(TlFetchInt::parse(p))
- , random_length_(TlFetchInt::parse(p))
-#undef FAIL
- {
- }
-};
-
-//InputUser
-class InputUser {
- public:
- static tl_object_ptr<InputUser> fetch(TlBufferParser &p);
-};
-
-class inputUser final : public InputUser {
- public:
- int32 user_id_;
- int64 access_hash_;
-
- static const int32 ID = -668391402;
- inputUser() = default;
-
- explicit inputUser(TlBufferParser &p)
-#define FAIL(error) p.set_error(error)
- : user_id_(TlFetchInt::parse(p))
- , access_hash_(TlFetchLong::parse(p))
-#undef FAIL
- {
- }
-};
-tl_object_ptr<InputUser> InputUser::fetch(TlBufferParser &p) {
-#define FAIL(error) \
- p.set_error(error); \
- return nullptr;
- int constructor = p.fetch_int();
- switch (constructor) {
- case inputUser::ID:
- return make_tl_object<inputUser>(p);
- default:
- FAIL(PSTRING() << "Unknown constructor found " << format::as_hex(constructor));
- }
-#undef FAIL
-}
-
-class messages_requestEncryption final {
- public:
- tl_object_ptr<InputUser> user_id_;
- int32 random_id_;
- BufferSlice g_a_;
-
- static const int32 ID = -162681021;
- messages_requestEncryption();
-
- explicit messages_requestEncryption(TlBufferParser &p)
-#define FAIL(error) p.set_error(error)
- : user_id_(TlFetchObject<InputUser>::parse(p))
- , random_id_(TlFetchInt::parse(p))
- , g_a_(TlFetchBytes<BufferSlice>::parse(p))
-#undef FAIL
- {
- }
-};
-
-class inputEncryptedChat final {
- public:
- int32 chat_id_;
- int64 access_hash_;
-
- inputEncryptedChat() = default;
-
- static const int32 ID = -247351839;
- explicit inputEncryptedChat(TlBufferParser &p)
-#define FAIL(error) p.set_error(error)
- : chat_id_(TlFetchInt::parse(p))
- , access_hash_(TlFetchLong::parse(p))
-#undef FAIL
- {
- }
- static tl_object_ptr<inputEncryptedChat> fetch(TlBufferParser &p) {
- return make_tl_object<inputEncryptedChat>(p);
- }
-};
-
-class messages_acceptEncryption final {
- public:
- tl_object_ptr<inputEncryptedChat> peer_;
- BufferSlice g_b_;
- int64 key_fingerprint_;
-
- messages_acceptEncryption() = default;
-
- static const int32 ID = 1035731989;
-
- explicit messages_acceptEncryption(TlBufferParser &p)
-#define FAIL(error) p.set_error(error)
- : peer_(TlFetchBoxed<TlFetchObject<inputEncryptedChat>, -247351839>::parse(p))
- , g_b_(TlFetchBytes<BufferSlice>::parse(p))
- , key_fingerprint_(TlFetchLong::parse(p))
-#undef FAIL
- {
- }
-};
-
-class messages_sendEncryptedService final {
- public:
- tl_object_ptr<inputEncryptedChat> peer_;
- int64 random_id_;
- BufferSlice data_;
-
- messages_sendEncryptedService() = default;
- static const int32 ID = 852769188;
- explicit messages_sendEncryptedService(TlBufferParser &p)
-#define FAIL(error) p.set_error(error)
- : peer_(TlFetchBoxed<TlFetchObject<inputEncryptedChat>, -247351839>::parse(p))
- , random_id_(TlFetchLong::parse(p))
- , data_(TlFetchBytes<BufferSlice>::parse(p))
-#undef FAIL
- {
- }
-};
-
-class messages_sendEncrypted final {
- public:
- tl_object_ptr<inputEncryptedChat> peer_;
- int64 random_id_;
- BufferSlice data_;
-
- messages_sendEncrypted() = default;
- static const int32 ID = -1451792525;
-
- explicit messages_sendEncrypted(TlBufferParser &p)
-#define FAIL(error) p.set_error(error)
- : peer_(TlFetchBoxed<TlFetchObject<inputEncryptedChat>, -247351839>::parse(p))
- , random_id_(TlFetchLong::parse(p))
- , data_(TlFetchBytes<BufferSlice>::parse(p))
-#undef FAIL
- {
- }
-};
-
-template <class F>
-static void downcast_call(TlBufferParser &p, F &&f) {
- auto id = p.fetch_int();
- switch (id) {
- case messages_getDhConfig::ID:
- return f(*make_tl_object<messages_getDhConfig>(p));
- case messages_requestEncryption::ID:
- return f(*make_tl_object<messages_requestEncryption>(p));
- case messages_acceptEncryption::ID:
- return f(*make_tl_object<messages_acceptEncryption>(p));
- case messages_sendEncrypted::ID:
- return f(*make_tl_object<messages_sendEncrypted>(p));
- case messages_sendEncryptedService::ID:
- return f(*make_tl_object<messages_sendEncryptedService>(p));
- default:
- CHECK(0) << id;
- UNREACHABLE();
- }
-}
-
-class messages_dhConfig final {
- public:
- int32 g_;
- BufferSlice p_;
- int32 version_;
- BufferSlice random_;
-
- messages_dhConfig() = default;
-
- messages_dhConfig(int32 g_, BufferSlice &&p_, int32 version_, BufferSlice &&random_)
- : g_(g_), p_(std::move(p_)), version_(version_), random_(std::move(random_)) {
- }
-
- static const int32 ID = 740433629;
- int32 get_id() const {
- return ID;
- }
-
- void store(TlStorerCalcLength &s) const {
- (void)sizeof(s);
- TlStoreBinary::store(g_, s);
- TlStoreString::store(p_, s);
- TlStoreBinary::store(version_, s);
- TlStoreString::store(random_, s);
- }
- void store(TlStorerUnsafe &s) const {
- (void)sizeof(s);
- TlStoreBinary::store(g_, s);
- TlStoreString::store(p_, s);
- TlStoreBinary::store(version_, s);
- TlStoreString::store(random_, s);
- }
-};
-
-class encryptedChat final {
- public:
- int32 id_;
- int64 access_hash_;
- int32 date_;
- int32 admin_id_;
- int32 participant_id_;
- BufferSlice g_a_or_b_;
- int64 key_fingerprint_;
-
- encryptedChat() = default;
-
- encryptedChat(int32 id_, int64 access_hash_, int32 date_, int32 admin_id_, int32 participant_id_,
- BufferSlice &&g_a_or_b_, int64 key_fingerprint_)
- : id_(id_)
- , access_hash_(access_hash_)
- , date_(date_)
- , admin_id_(admin_id_)
- , participant_id_(participant_id_)
- , g_a_or_b_(std::move(g_a_or_b_))
- , key_fingerprint_(key_fingerprint_) {
- }
-
- static const int32 ID = -94974410;
- int32 get_id() const {
- return ID;
- }
-
- void store(TlStorerCalcLength &s) const {
- (void)sizeof(s);
- TlStoreBinary::store(id_, s);
- TlStoreBinary::store(access_hash_, s);
- TlStoreBinary::store(date_, s);
- TlStoreBinary::store(admin_id_, s);
- TlStoreBinary::store(participant_id_, s);
- TlStoreString::store(g_a_or_b_, s);
- TlStoreBinary::store(key_fingerprint_, s);
- }
-
- void store(TlStorerUnsafe &s) const {
- (void)sizeof(s);
- TlStoreBinary::store(id_, s);
- TlStoreBinary::store(access_hash_, s);
- TlStoreBinary::store(date_, s);
- TlStoreBinary::store(admin_id_, s);
- TlStoreBinary::store(participant_id_, s);
- TlStoreString::store(g_a_or_b_, s);
- TlStoreBinary::store(key_fingerprint_, s);
- }
-};
-
-class messages_sentEncryptedMessage final {
- public:
- int32 date_;
-
- messages_sentEncryptedMessage() = default;
-
- explicit messages_sentEncryptedMessage(int32 date_) : date_(date_) {
- }
-
- static const int32 ID = 1443858741;
- int32 get_id() const {
- return ID;
- }
-
- void store(TlStorerCalcLength &s) const {
- (void)sizeof(s);
- TlStoreBinary::store(date_, s);
- }
-
- void store(TlStorerUnsafe &s) const {
- (void)sizeof(s);
- TlStoreBinary::store(date_, s);
- }
-};
-
-} // namespace my_api
-
-namespace td {
-static int32 g = 3;
-static string prime_base64 =
- "xxyuucaxyQSObFIvcPE_c5gNQCOOPiHBSTTQN1Y9kw9IGYoKp8FAWCKUk9IlMPTb-jNvbgrJJROVQ67UTM58NyD9UfaUWHBaxozU_mtrE6vcl0ZRKW"
- "kyhFTxj6-MWV9kJHf-lrsqlB1bzR1KyMxJiAcI-ps3jjxPOpBgvuZ8-aSkppWBEFGQfhYnU7VrD2tBDbp02KhLKhSzFE4O8ShHVP0X7ZUNWWW0ud1G"
- "WC2xF40WnGvEZbDW_5yjko_vW5rk5Bj8Feg-vqD4f6n_Xu1wBQ3tKEn0e_lZ2VaFDOkphR8NgRX2NbEF7i5OFdBLJFS_b0-t8DSxBAMRnNjjuS_MW"
- "w";
-
-class FakeDhCallback : public DhCallback {
- public:
- int is_good_prime(Slice prime_str) const override {
- auto it = cache.find(prime_str.str());
- if (it == cache.end()) {
- return -1;
- }
- return it->second;
- }
- void add_good_prime(Slice prime_str) const override {
- cache[prime_str.str()] = 1;
- }
- void add_bad_prime(Slice prime_str) const override {
- cache[prime_str.str()] = 0;
- }
- mutable std::map<string, int> cache;
-};
-
-class FakeBinlog
- : public BinlogInterface
- , public Actor {
- public:
- FakeBinlog() {
- register_actor("FakeBinlog", this).release();
- }
- void force_sync(Promise<> promise) override {
- if (pending_events_.empty()) {
- pending_events_.emplace_back();
- }
- pending_events_.back().promises_.push_back(std::move(promise));
- pending_events_.back().sync_flag = true;
- request_sync();
- }
- void request_sync() {
- if (!has_request_sync) {
- has_request_sync = true;
- if (Random::fast(0, 4) == 0) {
- set_timeout_in(Random::fast(0, 99) / 100.0 * 0.005 + 0.001);
- } else {
- yield();
- }
- }
- }
- void force_flush() override {
- }
-
- uint64 next_id() override {
- auto res = last_id_;
- last_id_++;
- return res;
- }
- uint64 next_id(int32 shift) override {
- auto res = last_id_;
- last_id_ += shift;
- return res;
- }
- template <class F>
- void for_each(const F &f) {
- events_processor_.for_each([&](auto &x) {
- LOG(INFO) << "REPLAY: " << x.id_;
- f(x);
- });
- }
-
- void restart() {
- has_request_sync = false;
- cancel_timeout();
- for (auto &pending : pending_events_) {
- auto &event = pending.event;
- if (!event.empty()) {
- // LOG(ERROR) << "FORGET EVENT: " << event.id_ << " " << event;
- }
- }
- pending_events_.clear();
- }
-
- void change_key(DbKey key, Promise<> promise) override {
- }
-
- protected:
- void close_impl(Promise<> promise) override {
- }
- void close_and_destroy_impl(Promise<> promise) override {
- }
- void add_raw_event_impl(uint64 id, BufferSlice &&raw_event, Promise<> promise) override {
- auto event = BinlogEvent(std::move(raw_event));
- LOG(INFO) << "ADD EVENT: " << event.id_ << " " << event;
- pending_events_.emplace_back();
- pending_events_.back().event = std::move(event);
- pending_events_.back().promises_.push_back(std::move(promise));
- }
- void do_force_sync() {
- if (pending_events_.empty()) {
- return;
- }
- cancel_timeout();
- has_request_sync = false;
- auto pos = static_cast<size_t>(Random::fast_uint64() % pending_events_.size());
- // pos = pending_events_.size() - 1;
- std::vector<Promise<>> promises;
- for (size_t i = 0; i <= pos; i++) {
- auto &pending = pending_events_[i];
- auto event = std::move(pending.event);
- if (!event.empty()) {
- LOG(INFO) << "SAVE EVENT: " << event.id_ << " " << event;
- events_processor_.add_event(std::move(event));
- }
- append(promises, std::move(pending.promises_));
- }
- pending_events_.erase(pending_events_.begin(), pending_events_.begin() + pos + 1);
- for (auto &promise : promises) {
- promise.set_value(Unit());
- }
-
- for (auto &event : pending_events_) {
- if (event.sync_flag) {
- request_sync();
- break;
- }
- }
- }
- void timeout_expired() override {
- do_force_sync();
- }
- void wakeup() override {
- if (has_request_sync) {
- do_force_sync();
- }
- }
- bool has_request_sync = false;
- uint64 last_id_ = 1;
- detail::BinlogEventsProcessor events_processor_;
-
- struct PendingEvent {
- BinlogEvent event;
- bool sync_flag = false;
- std::vector<Promise<>> promises_;
- };
-
- std::vector<PendingEvent> pending_events_;
-};
-
-using FakeKeyValue = BinlogKeyValue<BinlogInterface>;
-class OldFakeKeyValue : public KeyValueSyncInterface {
- SeqNo set(string key, string value) override {
- kv_[key] = value;
- return 0;
- }
-
- SeqNo erase(const string &key) override {
- kv_.erase(key);
- return 0;
- }
-
- bool isset(const string &key) override {
- return kv_.count(key) > 0;
- }
-
- string get(const string &key) override {
- auto it = kv_.find(key);
- if (it != kv_.end()) {
- return it->second;
- }
- return string();
- }
-
- private:
- std::map<string, string> kv_;
-};
-
-class Master;
-class FakeSecretChatContext : public SecretChatActor::Context {
- public:
- FakeSecretChatContext(std::shared_ptr<BinlogInterface> binlog, std::shared_ptr<KeyValueSyncInterface> key_value,
- std::shared_ptr<bool> close_flag, ActorShared<Master> master)
- : binlog_(std::move(binlog))
- , key_value_(std::move(key_value))
- , close_flag_(std::move(close_flag))
- , master_(std::move(master)) {
- secret_chat_db_ = std::make_unique<SecretChatDb>(key_value_, 1);
- net_query_creator_.stop_check(); // :(
- }
- DhCallback *dh_callback() override {
- return &fake_dh_callback_;
- }
- NetQueryCreator &net_query_creator() override {
- return net_query_creator_;
- }
- int32 unix_time() override {
- return static_cast<int32>(std::time(nullptr));
- }
- bool close_flag() override {
- return *close_flag_;
- }
- BinlogInterface *binlog() override {
- return binlog_.get();
- }
- SecretChatDb *secret_chat_db() override {
- return secret_chat_db_.get();
- }
- std::shared_ptr<DhConfig> dh_config() override {
- static auto config = [] {
- DhConfig dh_config;
- dh_config.version = 12;
- dh_config.g = g;
- dh_config.prime = base64url_decode(prime_base64).move_as_ok();
- return std::make_shared<DhConfig>(dh_config);
- }();
-
- return config;
- }
- void set_dh_config(std::shared_ptr<DhConfig> dh_config) override {
- // empty
- }
-
- bool get_config_option_boolean(const string &name) const override {
- return false;
- }
-
- // We don't want to expose the whole NetQueryDispatcher, MessagesManager and ContactsManager.
- // So it is more clear which parts of MessagesManager is really used. And it is much easier to create tests.
- void send_net_query(NetQueryPtr query, ActorShared<NetQueryCallback> callback, bool ordered) override;
-
- void on_update_secret_chat(int64 access_hash, UserId user_id, SecretChatState state, bool is_outbound, int32 ttl,
- int32 date, string key_hash, int32 layer) override {
- }
-
- void on_inbound_message(UserId user_id, MessageId message_id, int32 date,
- tl_object_ptr<telegram_api::encryptedFile> file,
- tl_object_ptr<secret_api::decryptedMessage> message, Promise<>) override;
-
- void on_send_message_error(int64 random_id, Status error, Promise<>) override;
- void on_send_message_ack(int64 random_id) override;
- void on_send_message_ok(int64 random_id, MessageId message_id, int32 date,
- tl_object_ptr<telegram_api::EncryptedFile> file, Promise<>) override;
- void on_delete_messages(std::vector<int64> random_id, Promise<>) override;
- void on_flush_history(MessageId, Promise<>) override;
- void on_read_message(int64, Promise<>) override;
-
- void on_screenshot_taken(UserId user_id, MessageId message_id, int32 date, int64 random_id,
- Promise<> promise) override {
- }
- void on_set_ttl(UserId user_id, MessageId message_id, int32 date, int32 ttl, int64 random_id,
- Promise<> promise) override {
- }
-
- private:
- FakeDhCallback fake_dh_callback_;
- static NetQueryCreator net_query_creator_;
- std::shared_ptr<BinlogInterface> binlog_;
- std::shared_ptr<KeyValueSyncInterface> key_value_;
- std::shared_ptr<bool> close_flag_;
- ActorShared<Master> master_;
-
- std::shared_ptr<SecretChatDb> secret_chat_db_;
-};
-NetQueryCreator FakeSecretChatContext::net_query_creator_;
-
-class Master : public Actor {
- public:
- explicit Master(Status *status) : status_(status) {
- }
- class SecretChatProxy : public Actor {
- public:
- SecretChatProxy(string name, ActorShared<Master> parent) : name_(std::move(name)) {
- binlog_ = std::make_shared<FakeBinlog>();
- key_value_ = std::make_shared<FakeKeyValue>();
- key_value_->external_init_begin(LogEvent::HandlerType::BinlogPmcMagic);
- key_value_->external_init_finish(binlog_);
- close_flag_ = std::make_shared<bool>(false);
- parent_ = parent.get();
- parent_token_ = parent.token();
- actor_ = create_actor<SecretChatActor>(
- "SecretChat " + name_, 123,
- std::make_unique<FakeSecretChatContext>(binlog_, key_value_, close_flag_, std::move(parent)), true);
- on_binlog_replay_finish();
- }
-
- ActorOwn<SecretChatActor> actor_;
-
- void add_inbound_message(int32 chat_id, BufferSlice data, uint64 crc) {
- CHECK(crc64(data.as_slice()) == crc);
- auto event = std::make_unique<logevent::InboundSecretMessage>();
- event->qts = 0;
- event->chat_id = chat_id;
- event->date = 0;
- event->encrypted_message = std::move(data);
- event->qts_ack = PromiseCreator::lambda(
- [actor_id = actor_id(this), chat_id, data = event->encrypted_message.copy(), crc](Result<> result) mutable {
- if (result.is_ok()) {
- LOG(INFO) << "FINISH add_inbound_message " << tag("crc", crc);
- return;
- }
- LOG(INFO) << "RESEND add_inbound_message " << tag("crc", crc) << result.error();
- send_closure(actor_id, &SecretChatProxy::add_inbound_message, chat_id, std::move(data), crc);
- });
-
- add_event(Event::delayed_closure(&SecretChatActor::add_inbound_message, std::move(event)));
- }
-
- void send_message(tl_object_ptr<secret_api::decryptedMessage> message) {
- BufferSlice serialized_message(serialize(*message));
- auto resend_promise = PromiseCreator::lambda(
- [actor_id = actor_id(this), serialized_message = std::move(serialized_message)](Result<> result) mutable {
- TlBufferParser parser(&serialized_message);
- auto message = secret_api::decryptedMessage::fetch(parser);
- if (result.is_ok()) {
- LOG(INFO) << "FINISH send_message " << tag("message", to_string(message));
- return;
- }
- LOG(INFO) << "RESEND send_message " << tag("message", to_string(message)) << result.error();
- CHECK(serialize(*message) == serialized_message.as_slice());
- send_closure(actor_id, &SecretChatProxy::send_message, std::move(message));
- });
- auto sync_promise = PromiseCreator::lambda([actor_id = actor_id(this), generation = this->binlog_generation_,
- resend_promise = std::move(resend_promise)](Result<> result) mutable {
- if (result.is_error()) {
- resend_promise.set_error(result.move_as_error());
- return;
- }
- send_closure(actor_id, &SecretChatProxy::sync_binlog, generation, std::move(resend_promise));
- });
-
- add_event(
- Event::delayed_closure(&SecretChatActor::send_message, std::move(message), nullptr, std::move(sync_promise)));
- }
- int32 binlog_generation_ = 0;
- void sync_binlog(int32 binlog_generation, Promise<> promise) {
- if (binlog_generation != binlog_generation_) {
- return promise.set_error(Status::Error("binlog generation mismatch"));
- }
- binlog_->force_sync(std::move(promise));
- }
- void on_closed() {
- LOG(INFO) << "CLOSED";
- ready_ = false;
- *close_flag_ = false;
-
- key_value_ = std::make_shared<FakeKeyValue>();
- key_value_->external_init_begin(LogEvent::HandlerType::BinlogPmcMagic);
-
- std::vector<BinlogEvent> events;
- binlog_generation_++;
- binlog_->restart();
- binlog_->for_each([&](const BinlogEvent &event) {
- if (event.type_ == LogEvent::HandlerType::BinlogPmcMagic) {
- key_value_->external_init_handle(event);
- } else {
- events.push_back(event.clone());
- }
- });
-
- key_value_->external_init_finish(binlog_);
-
- actor_ = create_actor<SecretChatActor>(
- "SecretChat " + name_, 123,
- std::make_unique<FakeSecretChatContext>(binlog_, key_value_, close_flag_,
- ActorShared<Master>(parent_, parent_token_)),
- true);
-
- for (auto &event : events) {
- CHECK(event.type_ == LogEvent::HandlerType::SecretChats);
- auto r_message = logevent::SecretChatEvent::from_buffer_slice(event.data_as_buffer_slice());
- LOG_IF(FATAL, r_message.is_error()) << "Failed to deserialize event: " << r_message.error();
- auto message = r_message.move_as_ok();
- message->set_logevent_id(event.id_);
- LOG(INFO) << "Process binlog event " << *message;
- switch (message->get_type()) {
- case logevent::SecretChatEvent::Type::InboundSecretMessage:
- send_closure_later(actor_, &SecretChatActor::replay_inbound_message,
- std::unique_ptr<logevent::InboundSecretMessage>(
- static_cast<logevent::InboundSecretMessage *>(message.release())));
- break;
- case logevent::SecretChatEvent::Type::OutboundSecretMessage:
- send_closure_later(actor_, &SecretChatActor::replay_outbound_message,
- std::unique_ptr<logevent::OutboundSecretMessage>(
- static_cast<logevent::OutboundSecretMessage *>(message.release())));
- break;
- default:
- UNREACHABLE();
- }
- };
- start_test();
- on_binlog_replay_finish();
- }
- void on_binlog_replay_finish() {
- ready_ = true;
- LOG(INFO) << "on_binlog_replay_finish!";
- send_closure(actor_, &SecretChatActor::binlog_replay_finish);
- for (auto &event : pending_events_) {
- send_event(actor_, std::move(event));
- }
- pending_events_.clear();
- }
- void start_test() {
- set_timeout_in(Random::fast(50, 99) * 0.3 / 50);
- events_cnt_ = 0;
- }
-
- private:
- string name_;
-
- ActorId<Master> parent_;
- uint64 parent_token_;
- std::shared_ptr<FakeBinlog> binlog_;
- std::shared_ptr<FakeKeyValue> key_value_;
- std::shared_ptr<bool> close_flag_;
- int events_cnt_ = 0;
-
- std::vector<Event> pending_events_;
- bool ready_ = false;
-
- bool is_active() {
- return !actor_.empty() && ready_;
- }
- void add_event(Event event) {
- events_cnt_++;
- if (is_active()) {
- LOG(INFO) << "EMIT";
- send_event(actor_, std::move(event));
- } else {
- LOG(INFO) << "DELAY";
- pending_events_.push_back(std::move(event));
- }
- }
-
- int32 bad_cnt_ = 0;
- void timeout_expired() override {
- LOG(INFO) << "TIMEOUT EXPIRED";
- if (events_cnt_ < 4) {
- bad_cnt_++;
- CHECK(bad_cnt_ < 10);
- } else {
- bad_cnt_ = 0;
- }
- *close_flag_ = true;
- actor_.reset();
- }
- };
-
- auto &get_by_id(uint64 id) {
- if (id == 1) {
- return alice_;
- } else {
- return bob_;
- }
- }
- auto &from() {
- return get_by_id(get_link_token());
- }
- auto &to() {
- return get_by_id(3 - get_link_token());
- }
- void start_up() override {
- set_context(std::make_shared<Global>());
- alice_ = create_actor<SecretChatProxy>("SecretChatProxy alice", "alice", actor_shared(this, 1));
- bob_ = create_actor<SecretChatProxy>("SecretChatProxy bob", "bob", actor_shared(this, 2));
- send_closure(alice_->get_actor_unsafe()->actor_, &SecretChatActor::create_chat, 2, 0, 123,
- PromiseCreator::lambda([actor_id = actor_id(this)](Result<SecretChatId> res) {
- send_closure(actor_id, &Master::got_secret_chat_id, std::move(res), 0);
- }));
- }
- void got_secret_chat_id(Result<SecretChatId> res, int) { // second parameter is needed to workaround clang bug
- CHECK(res.is_ok());
- auto id = res.move_as_ok();
- LOG(INFO) << "SecretChatId = " << id;
- }
- bool can_fail(NetQueryPtr &query) {
- static int cnt = 20;
- if (cnt > 0) {
- cnt--;
- return false;
- }
- if (query->tl_constructor() == telegram_api::messages_sendEncrypted::ID ||
- query->tl_constructor() == telegram_api::messages_sendEncryptedFile::ID) {
- return true;
- }
- return false;
- }
- void send_net_query(NetQueryPtr query, ActorShared<NetQueryCallback> callback, bool ordered) {
- if (can_fail(query) && Random::fast(0, 1) == 0) {
- LOG(INFO) << "Fail query " << query;
- auto resend_promise =
- PromiseCreator::lambda([id = actor_shared(this, get_link_token()), callback_actor = callback.get(),
- callback_token = callback.token()](Result<NetQueryPtr> r_net_query) mutable {
- if (r_net_query.is_error()) {
- id.release();
- return;
- }
- send_closure(std::move(id), &Master::send_net_query, r_net_query.move_as_ok(),
- ActorShared<NetQueryCallback>(callback_actor, callback_token), true);
- });
- query->set_error(Status::Error(429, "Test error"));
- send_closure(std::move(callback), &NetQueryCallback::on_result_resendable, std::move(query),
- std::move(resend_promise));
- return;
- } else {
- LOG(INFO) << "Do not fail " << query;
- }
- auto query_slice = query->query().clone();
- if (query->gzip_flag() == NetQuery::GzipFlag::On) {
- query_slice = gzdecode(query_slice.as_slice());
- }
- TlBufferParser parser(&query_slice);
- //auto object = telegram_api::Function::fetch(parser);
- //LOG(INFO) << query_slice.size();
- //parser.get_status().ensure();
- my_api::downcast_call(parser, [&](auto &object) {
- this->process_net_query(std::move(object), std::move(query), std::move(callback));
- });
- }
- template <class T>
- void process_net_query(T &&object, NetQueryPtr query, ActorShared<NetQueryCallback> callback) {
- LOG(FATAL) << "Unsupported query: " << to_string(object);
- }
- void process_net_query(my_api::messages_getDhConfig &&get_dh_config, NetQueryPtr net_query,
- ActorShared<NetQueryCallback> callback) {
- //LOG(INFO) << "Got query " << to_string(get_dh_config);
- my_api::messages_dhConfig config;
- config.p_ = BufferSlice(base64url_decode(prime_base64).move_as_ok());
- config.g_ = g;
- config.version_ = 12;
- auto storer = TLObjectStorer<my_api::messages_dhConfig>(config);
- BufferSlice answer(storer.size());
- storer.store(answer.as_slice().ubegin());
- net_query->set_ok(std::move(answer));
- send_closure(std::move(callback), &NetQueryCallback::on_result, std::move(net_query));
- }
- void process_net_query(my_api::messages_requestEncryption &&request_encryption, NetQueryPtr net_query,
- ActorShared<NetQueryCallback> callback) {
- CHECK(get_link_token() == 1);
- send_closure(alice_->get_actor_unsafe()->actor_, &SecretChatActor::update_chat,
- make_tl_object<telegram_api::encryptedChatWaiting>(123, 321, 0, 1, 2));
- send_closure(
- bob_->get_actor_unsafe()->actor_, &SecretChatActor::update_chat,
- make_tl_object<telegram_api::encryptedChatRequested>(123, 321, 0, 1, 2, request_encryption.g_a_.clone()));
- net_query->clear();
- }
- void process_net_query(my_api::messages_acceptEncryption &&request_encryption, NetQueryPtr net_query,
- ActorShared<NetQueryCallback> callback) {
- CHECK(get_link_token() == 2);
- send_closure(alice_->get_actor_unsafe()->actor_, &SecretChatActor::update_chat,
- make_tl_object<telegram_api::encryptedChat>(123, 321, 0, 1, 2, request_encryption.g_b_.clone(),
- request_encryption.key_fingerprint_));
-
- my_api::encryptedChat encrypted_chat(123, 321, 0, 1, 2, BufferSlice(), request_encryption.key_fingerprint_);
- auto storer = TLObjectStorer<my_api::encryptedChat>(encrypted_chat);
- BufferSlice answer(storer.size());
- storer.store(answer.as_slice().ubegin());
- net_query->set_ok(std::move(answer));
- send_closure(std::move(callback), &NetQueryCallback::on_result, std::move(net_query));
- send_closure(alice_, &SecretChatProxy::start_test);
- send_closure(bob_, &SecretChatProxy::start_test);
- send_ping(1, 5000);
- set_timeout_in(1);
- }
- void timeout_expired() override {
- send_message(1, "oppa");
- send_message(2, "appo");
- set_timeout_in(1);
- }
- void send_ping(int id, int cnt) {
- if (cnt % 200 == 0) {
- LOG(ERROR) << "send ping " << tag("id", id) << tag("cnt", cnt);
- } else {
- LOG(INFO) << "send ping " << tag("id", id) << tag("cnt", cnt);
- }
- string text = PSTRING() << "PING: " << cnt;
- send_message(id, std::move(text));
- }
- void send_message(int id, string text) {
- auto random_id = Random::secure_int64();
- LOG(INFO) << "send message: " << tag("id", id) << tag("text", text) << tag("random_id", random_id);
- sent_messages_[random_id] = Message{id, text};
- send_closure(get_by_id(id), &SecretChatProxy::send_message,
- secret_api::make_object<secret_api::decryptedMessage>(0, random_id, 0, text, Auto(), Auto(), Auto(),
- Auto(), 0));
- }
- void process_net_query(my_api::messages_sendEncryptedService &&message, NetQueryPtr net_query,
- ActorShared<NetQueryCallback> callback) {
- process_net_query_send_enrypted(std::move(message.data_), std::move(net_query), std::move(callback));
- }
- void process_net_query(my_api::messages_sendEncrypted &&message, NetQueryPtr net_query,
- ActorShared<NetQueryCallback> callback) {
- process_net_query_send_enrypted(std::move(message.data_), std::move(net_query), std::move(callback));
- }
- void process_net_query_send_enrypted(BufferSlice data, NetQueryPtr net_query,
- ActorShared<NetQueryCallback> callback) {
- my_api::messages_sentEncryptedMessage sent_message;
- sent_message.date_ = 0;
- auto storer = TLObjectStorer<my_api::messages_sentEncryptedMessage>(sent_message);
- BufferSlice answer(storer.size());
- storer.store(answer.as_slice().ubegin());
- net_query->set_ok(std::move(answer));
- send_closure(std::move(callback), &NetQueryCallback::on_result, std::move(net_query));
-
- // We can't loose updates yet :(
- auto crc = crc64(data.as_slice());
- LOG(INFO) << "send SecretChatProxy::add_inbound_message" << tag("crc", crc);
- send_closure(to(), &SecretChatProxy::add_inbound_message, narrow_cast<int32>(3 - get_link_token()), std::move(data),
- crc);
- }
-
- int32 last_ping_ = std::numeric_limits<int32>::max();
- void on_inbound_message(string message, Promise<> promise) {
- promise.set_value(Unit());
- LOG(INFO) << "GOT INBOUND MESSAGE: " << message << " " << get_link_token();
- int32 cnt;
- int x = std::sscanf(message.c_str(), "PING: %d", &cnt);
- if (x != 1) {
- return;
- }
- if (cnt == 0) {
- Scheduler::instance()->finish();
- *status_ = Status::OK();
- return;
- }
- if (cnt >= last_ping_) {
- return;
- }
- last_ping_ = cnt;
- send_ping(narrow_cast<int32>(get_link_token()), cnt - 1);
- }
- void on_send_message_error(int64 random_id, Status error, Promise<> promise) {
- promise.set_value(Unit());
- LOG(INFO) << "on_send_message_error: " << tag("random_id", random_id) << error;
- auto it = sent_messages_.find(random_id);
- if (it == sent_messages_.end()) {
- LOG(INFO) << "TODO: try fix errors about message after it is sent";
- return;
- }
- CHECK(it != sent_messages_.end());
- auto message = it->second;
- // sent_messages_.erase(it);
- send_message(message.id, message.text);
- }
- void on_send_message_ok(int64 random_id, Promise<> promise) {
- promise.set_value(Unit());
- LOG(INFO) << "on_send_message_ok: " << tag("random_id", random_id);
- auto it = sent_messages_.find(random_id);
- if (it == sent_messages_.end()) {
- LOG(INFO) << "TODO: try fix errors about message after it is sent";
- return;
- }
- CHECK(it != sent_messages_.end());
- // sent_messages_.erase(it);
- }
-
- private:
- Status *status_;
- ActorOwn<SecretChatProxy> alice_;
- ActorOwn<SecretChatProxy> bob_;
- struct Message {
- int32 id;
- string text;
- };
- std::map<int64, Message> sent_messages_;
-
- void hangup_shared() override {
- LOG(INFO) << "GOT HANGUP: " << get_link_token();
- send_closure(from(), &SecretChatProxy::on_closed);
- }
-};
-
-void FakeSecretChatContext::send_net_query(NetQueryPtr query, ActorShared<NetQueryCallback> callback, bool ordered) {
- send_closure(master_, &Master::send_net_query, std::move(query), std::move(callback), ordered);
-}
-void FakeSecretChatContext::on_inbound_message(UserId user_id, MessageId message_id, int32 date,
- tl_object_ptr<telegram_api::encryptedFile> file,
- tl_object_ptr<secret_api::decryptedMessage> message, Promise<> promise) {
- send_closure(master_, &Master::on_inbound_message, message->message_, std::move(promise));
-}
-void FakeSecretChatContext::on_send_message_error(int64 random_id, Status error, Promise<> promise) {
- send_closure(master_, &Master::on_send_message_error, random_id, std::move(error), std::move(promise));
-}
-void FakeSecretChatContext::on_send_message_ack(int64 random_id) {
-}
-void FakeSecretChatContext::on_send_message_ok(int64 random_id, MessageId message_id, int32 date,
- tl_object_ptr<telegram_api::EncryptedFile> file, Promise<> promise) {
- send_closure(master_, &Master::on_send_message_ok, random_id, std::move(promise));
-}
-void FakeSecretChatContext::on_delete_messages(std::vector<int64> random_id, Promise<> promise) {
- promise.set_value(Unit());
-}
-void FakeSecretChatContext::on_flush_history(MessageId, Promise<> promise) {
- promise.set_error(Status::Error("unsupported"));
-}
-void FakeSecretChatContext::on_read_message(int64, Promise<> promise) {
- promise.set_error(Status::Error("unsupported"));
-}
-
-TEST(Secret, go) {
- SET_VERBOSITY_LEVEL(VERBOSITY_NAME(ERROR));
- ConcurrentScheduler sched;
- int threads_n = 0;
- sched.init(threads_n);
-
- Status result;
- sched.create_actor_unsafe<Master>(0, "HandshakeTestActor", &result).release();
- sched.start();
- while (sched.run_main(10)) {
- // empty;
- }
- sched.finish();
-
- if (result.is_error()) {
- LOG(ERROR) << result;
- }
- ASSERT_TRUE(result.is_ok());
-}
-
-} // namespace td
diff --git a/libs/tdlib/td/test/string_cleaning.cpp b/libs/tdlib/td/test/string_cleaning.cpp
deleted file mode 100644
index 6fbd8150a4..0000000000
--- a/libs/tdlib/td/test/string_cleaning.cpp
+++ /dev/null
@@ -1,107 +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 "td/telegram/misc.h"
-
-#include "td/utils/Slice.h"
-#include "td/utils/tests.h"
-
-REGISTER_TESTS(string_cleaning);
-
-using namespace td;
-
-TEST(StringCleaning, clean_name) {
- ASSERT_EQ("@mention", clean_name("@mention", 1000000));
- ASSERT_EQ("@mention", clean_name(" @mention ", 1000000));
- ASSERT_EQ("@MENTION", clean_name("@MENTION", 1000000));
- ASSERT_EQ("ЛШТШФУМ", clean_name("ЛШТШФУМ", 1000000));
- ASSERT_EQ("....", clean_name("....", 1000000));
- ASSERT_EQ(". ASD ..", clean_name(". ASD ..", 1000000));
- ASSERT_EQ(". ASD", clean_name(". ASD ..", 10));
- ASSERT_EQ(". ASD", clean_name(".\n\n\nASD\n\n\n..", 10));
- ASSERT_EQ("", clean_name("\n\n\n\n\n\n", 1000000));
- ASSERT_EQ("", clean_name("\xC2\xA0\xC2\xA0\xC2\xA0\xC2\xA0\xC2\xA0\n\n\n\n\n\n \n\xC2\xA0 \xC2\xA0 \n", 100000));
- ASSERT_EQ("abc", clean_name("\xC2\xA0\xC2\xA0"
- "abc\xC2\xA0\xC2\xA0\xC2\xA0\xC2\xA0",
- 1000000));
-};
-
-TEST(StringCleaning, clean_username) {
- ASSERT_EQ("@mention", clean_username("@mention"));
- ASSERT_EQ("@mention", clean_username(" @mention "));
- ASSERT_EQ("@mention", clean_username("@MENTION"));
- ASSERT_EQ("ЛШТШФУМ", clean_username("ЛШТШФУМ"));
- ASSERT_EQ("", clean_username("...."));
- ASSERT_EQ("asd", clean_username(". ASD .."));
-};
-
-static void check_clean_input_string(string str, string expected, bool expected_result) {
- auto result = clean_input_string(str);
- ASSERT_EQ(expected_result, result);
- if (result) {
- ASSERT_EQ(expected, str);
- }
-}
-
-TEST(StringCleaning, clean_input_string) {
- check_clean_input_string("/abc", "/abc", true);
- check_clean_input_string(string(50000, 'a'), string(34996, 'a'), true);
- check_clean_input_string("\xff", "", false);
- check_clean_input_string("\xc0\x80", "", false);
- check_clean_input_string("\xd0", "", false);
- check_clean_input_string("\xe0\xaf", "", false);
- check_clean_input_string("\xf0\xa6", "", false);
- check_clean_input_string("\xf0\xa6\x88", "", false);
- check_clean_input_string("\xf4\x8f\xbf\xbf", "\xf4\x8f\xbf\xbf", true);
- check_clean_input_string("\xf4\x8f\xbf\xc0", "", false);
- check_clean_input_string("\r\r\r\r\r\r\r", "", true);
- check_clean_input_string("\r\n\r\n\r\n\r\n\r\n\r\n\r", "\n\n\n\n\n\n", true);
- check_clean_input_string(Slice("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21")
- .str(),
- " \x0a \x21", true);
- check_clean_input_string(
- "\xe2\x80\xa7\xe2\x80\xa8\xe2\x80\xa9\xe2\x80\xaa\xe2\x80\xab\xe2\x80\xac\xe2\x80\xad\xe2\x80\xae\xe2\x80\xaf",
- "\xe2\x80\xa7\xe2\x80\xaf", true);
- check_clean_input_string("\xcc\xb3\xcc\xbf\xcc\x8a", "", true);
-}
-
-static void check_strip_empty_characters(string str, size_t max_length, string expected) {
- ASSERT_EQ(expected, strip_empty_characters(str, max_length));
-}
-
-TEST(StringCleaning, strip_empty_characters) {
- check_strip_empty_characters("/abc", 4, "/abc");
- check_strip_empty_characters("/abc", 3, "/ab");
- check_strip_empty_characters("/abc", 0, "");
- check_strip_empty_characters("/abc", 10000000, "/abc");
- string spaces =
- u8"\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u200B\u202F\u205F\u3000\uFEFF"
- u8"\uFFFC\uFFFC";
- string spaces_replace = " ";
- string empty = "\xE2\x80\x8C\xE2\x80\x8D\xE2\x80\xAE\xC2\xA0\xC2\xA0";
-
- check_strip_empty_characters(spaces, 1000000, "");
- check_strip_empty_characters(empty, 1000000, "");
- check_strip_empty_characters(empty + "a", 1000000, empty + "a");
- check_strip_empty_characters(spaces + empty + spaces + "abc" + spaces, 1000000, empty + spaces_replace + "abc");
- check_strip_empty_characters(spaces + spaces + empty + spaces + spaces + empty + empty, 1000000,
- empty + spaces_replace + spaces_replace + empty + empty);
- check_strip_empty_characters("\r\r\r\r\r\r\r", 1000000, "");
- check_strip_empty_characters("\r\n\r\n\r\n\r\n\r\n\r\n\r", 1000000, "");
- check_strip_empty_characters(Slice(" \t\r\n\0\va\v\0\n\r\t ").str(), 1000000, "a");
- check_strip_empty_characters(
- Slice("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21")
- .str(),
- 1000000,
- "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
- "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21");
- check_strip_empty_characters("\xcc\xb3\xcc\xbf\xcc\x8a", 2, "\xcc\xb3\xcc\xbf");
- check_strip_empty_characters(
- "\xe2\x80\xa7\xe2\x80\xa8\xe2\x80\xa9\xe2\x80\xaa\xe2\x80\xab\xe2\x80\xac\xe2\x80\xad\xe2\x80\xae", 3,
- "\xe2\x80\xa7\xe2\x80\xa8\xe2\x80\xa9");
-}
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
diff --git a/libs/tdlib/td/test/tests_runner.cpp b/libs/tdlib/td/test/tests_runner.cpp
deleted file mode 100644
index 0edb186f0a..0000000000
--- a/libs/tdlib/td/test/tests_runner.cpp
+++ /dev/null
@@ -1,18 +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 "test/tests_runner.h"
-
-#include "test/TestsRunner.h"
-
-extern "C" {
-void tests_runner_init(const char *dir) {
- td::TestsRunner::init(dir);
-}
-void run_all_tests() {
- td::TestsRunner::run_all_tests();
-}
-}
diff --git a/libs/tdlib/td/test/tests_runner.h b/libs/tdlib/td/test/tests_runner.h
deleted file mode 100644
index 3de566858b..0000000000
--- a/libs/tdlib/td/test/tests_runner.h
+++ /dev/null
@@ -1,18 +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)
-//
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void tests_runner_init(const char *dir);
-void run_all_tests();
-
-#ifdef __cplusplus
-}
-#endif