static void test_cache_timestamp(session &sess) { argument_data data("this is a timestamp test"); key k("this is a timestamp test key"); sess.transform(k); dnet_io_control ctl; memset(&ctl, 0, sizeof(ctl)); ctl.data = data.data(); dnet_current_time(&ctl.io.timestamp); ctl.io.flags = DNET_IO_FLAGS_CACHE; ctl.io.start = 5; ctl.io.size = data.size(); memcpy(&ctl.id, &k.id(), sizeof(dnet_id)); ctl.fd = -1; ELLIPTICS_REQUIRE(write_result, sess.write_data(ctl)); sleep(ctl.io.start + 2); ELLIPTICS_REQUIRE(read_result, sess.read_data(k, 0, 0)); auto io = read_result.get_one().io_attribute(); BOOST_REQUIRE_EQUAL(io->timestamp.tsec, ctl.io.timestamp.tsec); BOOST_REQUIRE_EQUAL(io->timestamp.tnsec, ctl.io.timestamp.tnsec); }
async_result<T>::async_result(const session &sess) : m_data(std::make_shared<data>()) { m_data->filter = sess.get_filter(); m_data->checker = sess.get_checker(); m_data->policy = sess.get_exceptions_policy(); m_data->error_handler = sess.get_error_handler(); }
static void test_direct_backend(session &sess) { const key id = std::string("direct-backend-test"); sess.set_groups({ 0 }); const std::string first_str = "first-data"; const std::string second_str = "second-data"; server_node &node = global_data->nodes.front(); session first = sess.clone(); first.set_direct_id(node.remote(), 0); session second = sess.clone(); second.set_direct_id(node.remote(), 3); ELLIPTICS_REQUIRE(async_first_write, first.write_data(id, first_str, 0)); ELLIPTICS_REQUIRE(async_second_write, second.write_data(id, second_str, 0)); ELLIPTICS_REQUIRE(async_first_read, first.read_data(id, 0, 0)); read_result_entry first_read = async_first_read.get_one(); BOOST_REQUIRE_EQUAL(first_read.file().to_string(), first_str); BOOST_REQUIRE_EQUAL(first_read.command()->backend_id, 0); ELLIPTICS_REQUIRE(async_second_read, second.read_data(id, 0, 0)); read_result_entry second_read = async_second_read.get_one(); BOOST_REQUIRE_EQUAL(second_read.file().to_string(), second_str); BOOST_REQUIRE_EQUAL(second_read.command()->backend_id, 3); }
static void test_set_backend_ids_for_disabled(session &sess) { server_node &node = global_data->nodes.back(); auto ids = generate_ids(16); ELLIPTICS_REQUIRE(async_set_result, sess.set_backend_ids(node.remote(), 4, ids)); backend_status_result_entry result = async_set_result.get_one(); BOOST_REQUIRE(result.is_valid()); BOOST_REQUIRE_EQUAL(result.count(), 1); dnet_backend_status *status = result.backend(0); BOOST_REQUIRE_EQUAL(status->backend_id, 4); BOOST_REQUIRE_EQUAL(status->state, DNET_BACKEND_DISABLED); ELLIPTICS_REQUIRE(async_enable_result, sess.enable_backend(node.remote(), 4)); // Wait 0.1 secs to ensure that route list was changed usleep(100 * 1000); auto route_ids = backend_ids(sess, node.remote(), 4); BOOST_REQUIRE_EQUAL(ids.size(), route_ids.size()); BOOST_REQUIRE(compare_ids(ids, route_ids)); }
static void test_cache_overflow(session &sess) { ioremap::cache::cache_manager *cache = (ioremap::cache::cache_manager*) global_data->nodes[0].get_native()->cache; const size_t cache_size = cache->cache_size(); const size_t cache_pages_number = cache->cache_pages_number(); argument_data data("0"); cache->clear(); size_t record_size = 0; { ELLIPTICS_REQUIRE(write_result, sess.write_cache(key(std::string("0")), data, 3000)); const auto& stats = cache->get_total_cache_stats(); record_size = stats.size_of_objects; } size_t records_number = (cache_size / cache_pages_number / record_size) * 10; for (size_t id = 1; id < records_number; ++id) { ELLIPTICS_REQUIRE(write_result, sess.write_cache(key(boost::lexical_cast<std::string>(id)), data, 3000)); const auto& stats = cache->get_total_cache_stats(); size_t total_pages_sizes = 0; for (size_t i = 0; i < stats.pages_sizes.size(); ++i) { total_pages_sizes += stats.pages_sizes[i]; // BOOST_REQUIRE_LE(stats.pages_sizes[i], stats.pages_max_sizes[i]); } // BOOST_REQUIRE_LE(stats.size_of_objects, cache_size); // BOOST_REQUIRE_EQUAL(stats.size_of_objects, total_pages_sizes); } }
static void test_cache_records_sizes(session &sess, const nodes_data *setup) { dnet_node *node = setup->nodes[0].get_native(); dnet_backend_io *backend_io = dnet_get_backend_io(node->io, 0); ioremap::cache::cache_manager *cache = reinterpret_cast<ioremap::cache::cache_manager *>(backend_io->cache); const size_t cache_size = cache->cache_size(); const size_t cache_pages_number = cache->cache_pages_number(); argument_data data("0"); cache->clear(); size_t record_size = 0; { ELLIPTICS_REQUIRE(write_result, sess.write_cache(key(boost::lexical_cast<std::string>(0)), data, 3000)); auto stats = cache->get_total_cache_stats(); record_size = stats.size_of_objects; BOOST_REQUIRE_EQUAL(stats.number_of_objects, 1); } size_t records_number = cache_size / cache_pages_number / record_size - 5; for (size_t id = 1; id < records_number; ++id) { ELLIPTICS_REQUIRE(write_result, sess.write_cache(key(boost::lexical_cast<std::string>(id)), data, 3000)); auto stats = cache->get_total_cache_stats(); size_t total_pages_sizes = 0; for (size_t i = 0; i < stats.pages_sizes.size(); ++i) { total_pages_sizes += stats.pages_sizes[i]; } BOOST_REQUIRE_EQUAL(stats.number_of_objects * record_size, stats.size_of_objects); BOOST_REQUIRE_EQUAL(stats.number_of_objects, id + 1); BOOST_REQUIRE_EQUAL(stats.size_of_objects, total_pages_sizes); } }
table_creator_2(session & sql) : tests::table_creator_base(sql) { sql << "create table soci_test(\"num_float\" float, \"num_int\" integer, " "\"name\" varchar(20), \"sometime\" timestamp, \"chr\" char)"; sql.commit(); sql.begin(); }
table_creator_1(session & sql) : tests::table_creator_base(sql) { sql << "create table soci_test(id integer, val integer, c char, " "str varchar(20), sh smallint, ul decimal(9,0), d double precision, " "tm timestamp, i1 integer, i2 integer, i3 integer, name varchar(20))"; sql.commit(); sql.begin(); }
table_creator_3(session & sql) : tests::table_creator_base(sql) { // CommonTest uses lower-case column names, // so we need to enforce such names here. // That's why column names are enclosed in "" sql << "create table soci_test(\"name\" varchar(100) not null, " "\"phone\" varchar(15))"; sql.commit(); sql.begin(); }
static void init_application_impl(session &sess, const std::string &app_name, nodes_data &data) { node_info info = node_info::create(data, sess.get_groups()); ELLIPTICS_REQUIRE(exec_result, sess.exec(NULL, app_name + "@init", info.pack())); sync_exec_result result = exec_result; BOOST_REQUIRE_EQUAL(result.size(), data.nodes.size()); for (auto it = result.begin(); it != result.end(); ++it) BOOST_REQUIRE_EQUAL(it->context().data().to_string(), "inited"); }
static void test_error_message(session &s, const std::string &id, int err) { s.set_filter(filters::all); ELLIPTICS_REQUIRE_ERROR(read_result, s.read_data(id, 0, 0), err); sync_read_result sync_result = read_result.get(); BOOST_REQUIRE(sync_result.size() > 0); read_result_entry entry = sync_result[0]; BOOST_REQUIRE_EXCEPTION(entry.io_attribute(), not_found_error, test_error_check_exception); }
void init_application_impl(session &sess, const std::string &app_name, const nodes_data *setup) { sess.set_timeout(600); auto log = sess.get_logger(); DNET_LOG_INFO(log, "Sending @init"); node_info info = node_info_create(setup, sess.get_groups()); ELLIPTICS_REQUIRE(exec_result, sess.exec(NULL, app_name + "@init", info.pack())); sync_exec_result result = exec_result; BOOST_REQUIRE_EQUAL(result.size(), setup->nodes.size()); for (auto it = result.begin(); it != result.end(); ++it) BOOST_REQUIRE_EQUAL(it->context().data().to_string(), "inited"); }
statement_impl::statement_impl(session & s) : session_(s), refCount_(1), row_(0), fetchSize_(1), initialFetchSize_(1), alreadyDescribed_(false) { backEnd_ = s.make_statement_backend(); }
torrent_handle add_magnet_uri(session& ses, std::string const& uri , add_torrent_params p) { std::string name; std::string tracker; boost::optional<std::string> display_name = url_has_argument(uri, "dn"); if (display_name) name = unescape_string(display_name->c_str()); boost::optional<std::string> tracker_string = url_has_argument(uri, "tr"); if (tracker_string) tracker = unescape_string(tracker_string->c_str()); boost::optional<std::string> btih = url_has_argument(uri, "xt"); if (!btih) return torrent_handle(); if (btih->compare(0, 9, "urn:btih:") != 0) return torrent_handle(); sha1_hash info_hash; if (btih->size() == 40 + 9) info_hash = boost::lexical_cast<sha1_hash>(btih->substr(9)); else info_hash.assign(base32decode(btih->substr(9))); if (!tracker.empty()) p.tracker_url = tracker.c_str(); p.info_hash = info_hash; if (!name.empty()) p.name = name.c_str(); return ses.add_torrent(p); }
torrent_handle add_magnet_uri(session& ses, std::string const& uri , std::string const& save_path , storage_mode_t storage_mode , bool paused , storage_constructor_type sc , void* userdata) { std::string name; std::string tracker; error_code ec; std::string display_name = url_has_argument(uri, "dn"); if (!display_name.empty()) name = unescape_string(display_name.c_str(), ec); std::string tracker_string = url_has_argument(uri, "tr"); if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), ec); std::string btih = url_has_argument(uri, "xt"); if (btih.empty()) return torrent_handle(); if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle(); sha1_hash info_hash; if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]); else info_hash.assign(base32decode(btih.substr(9))); return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash , name.empty() ? 0 : name.c_str(), save_path, entry() , storage_mode, paused, sc, userdata); }
torrent_handle add_magnet_uri_deprecated(session& ses, std::string const& uri , add_torrent_params p, error_code& ec) { parse_magnet_uri(uri, p, ec); if (ec) return torrent_handle(); return ses.add_torrent(p, ec); }
torrent_handle add_magnet_uri(session& ses, std::string const& uri , fs::path const& save_path , storage_mode_t storage_mode , bool paused , storage_constructor_type sc , void* userdata) { std::string name; std::string tracker; boost::optional<std::string> display_name = url_has_argument(uri, "dn"); if (display_name) name = unescape_string(display_name->c_str()); boost::optional<std::string> tracker_string = url_has_argument(uri, "tr"); if (tracker_string) tracker = unescape_string(tracker_string->c_str()); boost::optional<std::string> btih = url_has_argument(uri, "xt"); if (!btih) return torrent_handle(); if (btih->compare(0, 9, "urn:btih:") != 0) return torrent_handle(); sha1_hash info_hash; if (btih->size() == 40 + 9) info_hash = boost::lexical_cast<sha1_hash>(btih->substr(9)); else info_hash.assign(base32decode(btih->substr(9))); return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash , name.empty() ? 0 : name.c_str(), save_path, entry() , storage_mode, paused, sc, userdata); }
torrent_handle add_magnet_uri(session& ses, std::string const& uri , add_torrent_params p, error_code& ec) { std::string name; std::string tracker; error_code e; boost::optional<std::string> display_name = url_has_argument(uri, "dn"); if (display_name) name = unescape_string(display_name->c_str(), e); boost::optional<std::string> tracker_string = url_has_argument(uri, "tr"); if (tracker_string) tracker = unescape_string(tracker_string->c_str(), e); boost::optional<std::string> btih = url_has_argument(uri, "xt"); if (!btih) { ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category); return torrent_handle(); } if (btih->compare(0, 9, "urn:btih:") != 0) { ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category); return torrent_handle(); } sha1_hash info_hash; if (btih->size() == 40 + 9) from_hex(&(*btih)[9], 40, (char*)&info_hash[0]); else info_hash.assign(base32decode(btih->substr(9))); if (!tracker.empty()) p.tracker_url = tracker.c_str(); p.info_hash = info_hash; if (!name.empty()) p.name = name.c_str(); return ses.add_torrent(p, ec); }
torrent_handle add_magnet_uri(session& ses, std::string const& uri , std::string const& save_path , storage_mode_t storage_mode , bool paused , storage_constructor_type sc , void* userdata) { add_torrent_params params(sc); params.storage_mode = storage_mode; params.userdata = userdata; params.save_path = save_path; if (paused) params.flags |= add_torrent_params::flag_paused; else params.flags &= ~add_torrent_params::flag_paused; error_code ec; std::string display_name = url_has_argument(uri, "dn"); if (!display_name.empty()) params.name = unescape_string(display_name.c_str(), ec); std::string tracker_string = url_has_argument(uri, "tr"); if (!tracker_string.empty()) params.trackers.push_back(unescape_string(tracker_string.c_str(), ec)); std::string btih = url_has_argument(uri, "xt"); if (btih.empty()) return torrent_handle(); if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle(); if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)¶ms.info_hash[0]); else params.info_hash.assign(base32decode(btih.substr(9))); return ses.add_torrent(params); }
/* * Multiple writes with same key must be processed in the same order as * they were initiated by client. * * Following test checks this mechanics by calling write_cas() with data containing * counter that is incremented after every write_cas() and checking that previosly stored * counter is one unit less than current counter. Also this test writes multiple different * keys (with repetitions) in different order, thereby modelling real workload case. */ static void test_write_order_execution(session &sess) { const int num_write_repetitions = 5; const int num_different_keys = 10; std::vector<std::pair<key, int>> keys; for (int i = 0; i < num_different_keys; ++i) { key id(std::to_string(static_cast<unsigned long long>(i))); for (int j = 0; j < num_write_repetitions; ++j) { keys.push_back(std::make_pair(id, i)); } } std::unique_ptr<async_write_result[]> results(new async_write_result[keys.size()]); dnet_id old_csum; const int num_iterations = 30; for (int i = 0; i < num_iterations; ++i) { // every key is associated with counter, which is initialized by zero std::vector<int> write_counter(num_different_keys, 0); std::random_shuffle(keys.begin(), keys.end()); for (size_t j = 0; j < keys.size(); ++j) { // increment counter associated with key identified by key_id const int key_id = keys[j].second; const int new_value = write_counter[key_id]++; if (new_value > 0) { const int prev_value = new_value - 1; memset(&old_csum, 0, sizeof(old_csum)); sess.transform(std::to_string(static_cast<unsigned long long>(prev_value)), old_csum); results[j] = std::move(sess.write_cas(keys[j].first, std::to_string(static_cast<unsigned long long>(new_value)), old_csum, 0)); } else { // first write results[j] = std::move(sess.write_data(keys[j].first, std::to_string(static_cast<unsigned long long>(new_value)), 0)); } } for (size_t j = 0; j < keys.size(); ++j) { results[j].wait(); const int err = results[j].error().code(); BOOST_REQUIRE_MESSAGE(err == 0, "write_cas() failed (err=" + std::to_string(static_cast<unsigned long long>(err)) + "): " "multiple consecutive writes are executed out-of-order " "or overlapped. Oplock mechanism of backend's request queue is broken."); } } }
static void start_application(session &sess, const std::string &app_name) { key key_id = app_name; key_id.transform(sess); dnet_id id = key_id.id(); ELLIPTICS_REQUIRE(result, sess.exec(&id, app_name + "@start-task", data_pointer())); }
std::function<void ()> make(const char *test_name, Method method, session sess, Args... args) { uint64_t trace_id = 0; auto buffer = reinterpret_cast<unsigned char *>(&trace_id); for (size_t i = 0; i < sizeof(trace_id); ++i) { buffer[i] = rand(); } sess.set_trace_id(trace_id); test_wrapper wrapper = { std::make_shared<ioremap::elliptics::logger>(sess.get_logger(), blackhole::log::attributes_t()), test_name, std::bind(method, sess, std::forward<Args>(args)...) }; return wrapper; }
vector<string> database::retrieve_column_titles(const binomen &table) const { const session s = get_session(); const unique_ptr<dialect_sql> cmd = make_dialect_sql(); cmd->write_retrieve_metadata(table); const result_stream stream = s->exec_with_stream_output(*cmd, 1); vector<string> result; while (unique_ptr<row> r = s->next_output(stream)) { string name; r->get("name", name); string type; r->get("type", type); result.push_back("\"" + name + "\" " + type); } return result; }
void key::transform(session &sess) { if (m_by_id) return; memset(&m_id, 0, sizeof(m_id)); sess.transform(m_remote, m_id); m_id.type = m_type; }
static void set_backends_delay_for_group(session &sess, int group, int delay) { for (size_t i = 0; i < nodes_count; ++i) { for (size_t j = 0; j < backends_count; ++j) { const size_t node_id = (group - 1) * nodes_count + i; const server_node &node = global_data->nodes[node_id]; sess.set_delay(node.remote(), j, delay); } } }
/** * Executes the read operation. * * @param session Internal CurveCP session reference * @param ec Output error code * @param bytes_transferred Output number of bytes transferred * @return Whether the operation should be retried */ session::want operator()(session &session, boost::system::error_code &ec, std::size_t &bytes_transferred) const { boost::asio::mutable_buffer buffer = boost::asio::detail::buffer_sequence_adapter<boost::asio::mutable_buffer, MutableBufferSequence>::first(buffers_); return session.read(buffer, ec, bytes_transferred) ? session::want::nothing : session::want::read; }
void cache_read_check_lru(session &sess, int id, lru_list_emulator_t &lru_list_emulator, ioremap::cache::cache_manager *cache) { key idKey = key(boost::lexical_cast<std::string>(id)); std::unique_ptr<async_read_result> read_result; int objects_number_before = cache->get_total_cache_stats().number_of_objects; if (!lru_list_emulator.contains(id)) { ELLIPTICS_WARN_ERROR(read_result, sess.read_data(idKey, 0, 0), -ENOENT); } else { ELLIPTICS_REQUIRE(read_result, sess.read_data(idKey, 0, 0)); lru_list_emulator.update(id); } int objects_number_after = cache->get_total_cache_stats().number_of_objects; int objects_removed = objects_number_before - objects_number_after; for (int i = 0; i < objects_removed; ++i) { lru_list_emulator.remove_last(); } }
static std::vector<dnet_raw_id> backend_ids(session &sess, const address &addr, uint32_t backend_id) { std::vector<dnet_route_entry> routes = sess.get_routes(); std::vector<dnet_raw_id> result; for (auto it = routes.begin(); it != routes.end(); ++it) { if (it->addr == addr && it->backend_id == backend_id) result.push_back(it->id); } return result; }
static void send_echo(session &sess, const std::string &app_name, const std::string &data) { key key_id = app_name; key_id.transform(sess); dnet_id id = key_id.id(); ELLIPTICS_REQUIRE(exec_result, sess.exec(&id, app_name + "@echo", data)); sync_exec_result result = exec_result; BOOST_REQUIRE_EQUAL(result.size(), 1); BOOST_REQUIRE_EQUAL(result[0].context().data().to_string(), data); }
torrent_handle add_feed_item(session& s, feed_item const& fi , add_torrent_params const& tp, error_code& ec) { add_torrent_params p = tp; p.url = fi.url; p.uuid = fi.uuid; // #error figure out how to get the feed url in here // p.source_feed_url = ???; p.ti.reset(); p.info_hash.clear(); p.name = fi.title.c_str(); return s.add_torrent(p, ec); }