diff --git a/src/rgw/driver/sfs/CMakeLists.txt b/src/rgw/driver/sfs/CMakeLists.txt index 8e611904f0253..fe01936692a97 100644 --- a/src/rgw/driver/sfs/CMakeLists.txt +++ b/src/rgw/driver/sfs/CMakeLists.txt @@ -24,7 +24,6 @@ set(sfs_srcs sqlite/sqlite_lifecycle.cc sqlite/users/users_conversions.cc sqlite/buckets/bucket_conversions.cc - sqlite/objects/object_conversions.cc sqlite/versioned_object/versioned_object_conversions.cc sqlite/dbconn.cc bucket.cc diff --git a/src/rgw/driver/sfs/bucket.cc b/src/rgw/driver/sfs/bucket.cc index c773f1c586645..28e1e43ef2a63 100644 --- a/src/rgw/driver/sfs/bucket.cc +++ b/src/rgw/driver/sfs/bucket.cc @@ -85,7 +85,7 @@ int SFSBucket::list( auto last_version = db_versioned_objects.get_last_versioned_object(objref->path.get_uuid()); - if (last_version->object_state == rgw::sal::ObjectState::COMMITTED) { + if (last_version->object_state == rgw::sal::sfs::ObjectState::COMMITTED) { // check for delimiter if (check_add_common_prefix(dpp, objref->name, params, 0, results, y)) { continue; @@ -128,13 +128,13 @@ int SFSBucket::list_versions( rgw_bucket_dir_entry dirent; dirent.key = cls_rgw_obj_key(objref->name, object_version.version_id); dirent.meta.accounted_size = object_version.size; - dirent.meta.mtime = object_version.creation_time; + dirent.meta.mtime = object_version.create_time; dirent.meta.etag = object_version.etag; dirent.flags = rgw_bucket_dir_entry::FLAG_VER; if (last_version.has_value() && last_version->id == object_version.id) { dirent.flags |= rgw_bucket_dir_entry::FLAG_CURRENT; } - if (object_version.object_state == rgw::sal::ObjectState::DELETED) { + if (object_version.object_state == rgw::sal::sfs::ObjectState::DELETED) { dirent.flags |= rgw_bucket_dir_entry::FLAG_DELETE_MARKER; } dirent.meta.owner_display_name = bucket->get_owner().display_name; @@ -243,7 +243,7 @@ int SFSBucket::check_empty(const DoutPrefixProvider* dpp, optional_yield y) { sfs::sqlite::SQLiteVersionedObjects db_versions(store->db_conn); for (const auto& obj : objects) { auto last_version = db_versions.get_last_versioned_object(obj); - if (last_version->object_state != rgw::sal::ObjectState::DELETED) { + if (last_version->object_state != rgw::sal::sfs::ObjectState::DELETED) { ldpp_dout(dpp, -1) << __func__ << ": Bucket Not Empty.." << dendl; return -ENOTEMPTY; } diff --git a/src/rgw/driver/sfs/object.cc b/src/rgw/driver/sfs/object.cc index 174feba147100..84012601fd9db 100644 --- a/src/rgw/driver/sfs/object.cc +++ b/src/rgw/driver/sfs/object.cc @@ -459,7 +459,7 @@ void SFSObject::_refresh_meta_from_object() { auto db_version = db_versioned_objects.get_versioned_object(get_instance()); if (db_version.has_value()) { auto uuid = objref->path.get_uuid(); - auto deleted = db_version->object_state == ObjectState::DELETED; + auto deleted = db_version->object_state == sfs::ObjectState::DELETED; objref.reset(sfs::Object::create_for_query( get_name(), uuid, deleted, db_version->id )); diff --git a/src/rgw/driver/sfs/object_state.h b/src/rgw/driver/sfs/object_state.h index 747558458679e..91e4de53887db 100644 --- a/src/rgw/driver/sfs/object_state.h +++ b/src/rgw/driver/sfs/object_state.h @@ -14,7 +14,7 @@ #ifndef RGW_SFS_OBJECT_STATE_H #define RGW_SFS_OBJECT_STATE_H -namespace rgw::sal { +namespace rgw::sal::sfs { enum class ObjectState { OPEN = 0, @@ -24,6 +24,6 @@ enum class ObjectState { LAST_VALUE = DELETED }; -} // namespace rgw::sal +} // namespace rgw::sal::sfs #endif // RGW_SFS_OBJECT_STATE_H diff --git a/src/rgw/driver/sfs/sqlite/bindings/enum.h b/src/rgw/driver/sfs/sqlite/bindings/enum.h new file mode 100644 index 0000000000000..a2ff42be0e9c1 --- /dev/null +++ b/src/rgw/driver/sfs/sqlite/bindings/enum.h @@ -0,0 +1,68 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t +// vim: ts=8 sw=2 smarttab ft=cpp +/* + * Ceph - scalable distributed file system + * SFS SAL implementation + * + * Copyright (C) 2023 SUSE LLC + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ +#pragma once + +#include + +#include "rgw/driver/sfs/sqlite/sqlite_orm.h" + +/// sqliteorm binding for enum types. +/// This binding can be used for any enum that has the LAST_VALUE value set to +/// the last possible value and the initial value set to 0. +/// This is used for the conversion from uint to enum to ensure that the uint +/// value is not out of range. +namespace sqlite_orm { +template +struct type_printer>::type> + : public integer_printer {}; + +template +struct statement_binder>::type> { + int bind(sqlite3_stmt* stmt, int index, const T& value) const { + return statement_binder().bind(stmt, index, static_cast(value)); + } +}; + +template +struct field_printer>::type> { + std::string operator()(const T& value) const { + return std::to_string(static_cast(value)); + } +}; + +template +struct row_extractor>::type> { + T extract(uint row_value) const { + if (row_value > static_cast(T::LAST_VALUE)) { + throw(std::system_error( + ERANGE, std::system_category(), + "Invalid enum value found: (" + std::to_string(row_value) + ")" + )); + } + return static_cast(row_value); + } + + T extract(sqlite3_stmt* stmt, int columnIndex) const { + auto int_value = sqlite3_column_int(stmt, columnIndex); + if (int_value < 0) { + throw(std::system_error( + ERANGE, std::system_category(), + "Invalid enum value found: (" + std::to_string(int_value) + ")" + )); + } + return this->extract(static_cast(int_value)); + } +}; + +} // namespace sqlite_orm diff --git a/src/rgw/driver/sfs/sqlite/bindings/real_time.h b/src/rgw/driver/sfs/sqlite/bindings/real_time.h new file mode 100644 index 0000000000000..470d51f1d8e22 --- /dev/null +++ b/src/rgw/driver/sfs/sqlite/bindings/real_time.h @@ -0,0 +1,93 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t +// vim: ts=8 sw=2 smarttab ft=cpp +/* + * Ceph - scalable distributed file system + * SFS SAL implementation + * + * Copyright (C) 2023 SUSE LLC + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ +#pragma once + +#include "common/ceph_time.h" +#include "rgw/driver/sfs/sqlite/sqlite_orm.h" + +/// ceph::real_time is represented as a uint64 (unsigned). +/// SQLite works with int64 (signed) values, which means we lose 1 bit of +/// resolution. +/// This means max possible time to be stored is 2262-04-11 23:47:16.854775807 +/// timestamps are stored with the same resolution as +/// ceph::real_cock::time_point (nanoseconds) +namespace rgw::sal::sfs::sqlite { + +static int64_t time_point_to_int64(const ceph::real_time& t) { + uint64_t nanos = + std::chrono::duration_cast(t.time_since_epoch()) + .count(); + // we check that the value is not greater than int64 max + if (nanos > std::numeric_limits::max()) { + std::stringstream oss; + oss << "Error converting ceph::real_time to int64. " + "Nanoseconds value: " + << nanos << " is out of range"; + throw std::system_error(ERANGE, std::system_category(), oss.str()); + } + // we can safely static_cast to int64_t now + return static_cast(nanos); +} + +static ceph::real_time time_point_from_int64(int64_t value) { + std::optional ret; + if (value < 0) { + // to ensure that we stick to the int64 positive range. + std::stringstream oss; + oss << "Error converting int64 nanoseconds value to " + "ceph::real_cock::time_point. Value: " + << value << " is out of range"; + throw std::system_error(ERANGE, std::system_category(), oss.str()); + } + uint64_t uint64_nanos = static_cast(value); + return ceph::real_time(std::chrono::nanoseconds(uint64_nanos)); +} + +} // namespace rgw::sal::sfs::sqlite + +namespace sqlite_orm { + +template <> +struct type_printer : public integer_printer {}; + +template <> +struct statement_binder { + int bind(sqlite3_stmt* stmt, int index, const ceph::real_time& value) const { + return statement_binder().bind( + stmt, index, rgw::sal::sfs::sqlite::time_point_to_int64(value) + ); + } +}; + +template <> +struct field_printer { + std::string operator()(const ceph::real_time& t) const { + auto int_value = rgw::sal::sfs::sqlite::time_point_to_int64(t); + return std::to_string(int_value); + } +}; + +template <> +struct row_extractor { + ceph::real_time extract(int64_t row_value) const { + return rgw::sal::sfs::sqlite::time_point_from_int64(row_value); + } + + ceph::real_time extract(sqlite3_stmt* stmt, int columnIndex) const { + auto int_value = sqlite3_column_int64(stmt, columnIndex); + return this->extract(int_value); + } +}; + +} // namespace sqlite_orm diff --git a/src/rgw/driver/sfs/sqlite/bindings/uuid_d.h b/src/rgw/driver/sfs/sqlite/bindings/uuid_d.h new file mode 100644 index 0000000000000..70a295a76b229 --- /dev/null +++ b/src/rgw/driver/sfs/sqlite/bindings/uuid_d.h @@ -0,0 +1,71 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t +// vim: ts=8 sw=2 smarttab ft=cpp +/* + * Ceph - scalable distributed file system + * SFS SAL implementation + * + * Copyright (C) 2023 SUSE LLC + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ +#pragma once + +#include + +#include "rgw/driver/sfs/sqlite/sqlite_orm.h" +#include "rgw_common.h" + +namespace sqlite_orm { +template <> +struct type_printer : public text_printer {}; + +template <> +struct statement_binder { + int bind(sqlite3_stmt* stmt, int index, const uuid_d& value) const { + return statement_binder().bind(stmt, index, value.to_string()); + } +}; + +template <> +struct field_printer { + std::string operator()(const uuid_d& value) const { + return value.to_string(); + } +}; + +template <> +struct row_extractor { + uuid_d extract(const char* row_value) const { + if (row_value) { + uuid_d ret_value; + if (!ret_value.parse(row_value)) { + throw std::system_error( + ERANGE, std::system_category(), + "incorrect uuid string (" + std::string(row_value) + ")" + ); + } + return ret_value; + } else { + // ! row_value + throw std::system_error( + ERANGE, std::system_category(), "incorrect uuid string (nullptr)" + ); + } + } + + uuid_d extract(sqlite3_stmt* stmt, int columnIndex) const { + auto str = sqlite3_column_text(stmt, columnIndex); + // sqlite3_colume_text returns const unsigned char* + return this->extract(reinterpret_cast(str)); + } + uuid_d extract(sqlite3_value* row_value) const { + // sqlite3_colume_text returns const unsigned char* + auto characters = + reinterpret_cast(sqlite3_value_text(row_value)); + return extract(characters); + } +}; +} // namespace sqlite_orm diff --git a/src/rgw/driver/sfs/sqlite/conversion_utils.h b/src/rgw/driver/sfs/sqlite/conversion_utils.h index 264ec765e9288..8c55bdd70424e 100644 --- a/src/rgw/driver/sfs/sqlite/conversion_utils.h +++ b/src/rgw/driver/sfs/sqlite/conversion_utils.h @@ -13,6 +13,7 @@ */ #pragma once +#include "rgw_common.h" namespace rgw::sal::sfs::sqlite { template diff --git a/src/rgw/driver/sfs/sqlite/dbconn.h b/src/rgw/driver/sfs/sqlite/dbconn.h index edead7f585ba5..3af9ade23d345 100644 --- a/src/rgw/driver/sfs/sqlite/dbconn.h +++ b/src/rgw/driver/sfs/sqlite/dbconn.h @@ -57,8 +57,9 @@ inline auto _make_storage(const std::string& path) { ), sqlite_orm::make_index("bucket_ownerid_idx", &DBBucket::owner_id), sqlite_orm::make_index("bucket_name_idx", &DBBucket::bucket_name), - sqlite_orm::make_index("objects_bucketid_idx", &DBObject::bucket_id), - sqlite_orm::make_index("objects_bucketid_idx", &DBObject::bucket_id), + sqlite_orm::make_index( + "objects_bucketid_idx", &DBOPObjectInfo::bucket_id + ), sqlite_orm::make_index( "vobjs_versionid_idx", &DBVersionedObject::version_id ), @@ -126,16 +127,11 @@ inline auto _make_storage(const std::string& path) { sqlite_orm::make_table( std::string(OBJECTS_TABLE), sqlite_orm::make_column( - "object_id", &DBObject::object_id, sqlite_orm::primary_key() + "uuid", &DBOPObjectInfo::uuid, sqlite_orm::primary_key() ), - sqlite_orm::make_column("bucket_id", &DBObject::bucket_id), - sqlite_orm::make_column("name", &DBObject::name), - sqlite_orm::make_column("size", &DBObject::size), - sqlite_orm::make_column("etag", &DBObject::etag), - sqlite_orm::make_column("mtime", &DBObject::mtime), - sqlite_orm::make_column("set_mtime", &DBObject::set_mtime), - sqlite_orm::make_column("delete_at_time", &DBObject::delete_at_time), - sqlite_orm::foreign_key(&DBObject::bucket_id) + sqlite_orm::make_column("bucket_id", &DBOPObjectInfo::bucket_id), + sqlite_orm::make_column("name", &DBOPObjectInfo::name), + sqlite_orm::foreign_key(&DBOPObjectInfo::bucket_id) .references(&DBBucket::bucket_id) ), sqlite_orm::make_table( @@ -146,21 +142,28 @@ inline auto _make_storage(const std::string& path) { ), sqlite_orm::make_column("object_id", &DBVersionedObject::object_id), sqlite_orm::make_column("checksum", &DBVersionedObject::checksum), + sqlite_orm::make_column("size", &DBVersionedObject::size), sqlite_orm::make_column( - "deletion_time", &DBVersionedObject::deletion_time + "create_time", &DBVersionedObject::create_time ), - sqlite_orm::make_column("size", &DBVersionedObject::size), sqlite_orm::make_column( - "creation_time", &DBVersionedObject::creation_time + "delete_time", &DBVersionedObject::delete_time ), + sqlite_orm::make_column( + "commit_time", &DBVersionedObject::commit_time + ), + sqlite_orm::make_column("mtime", &DBVersionedObject::mtime), sqlite_orm::make_column( "object_state", &DBVersionedObject::object_state ), sqlite_orm::make_column("version_id", &DBVersionedObject::version_id), sqlite_orm::make_column("etag", &DBVersionedObject::etag), sqlite_orm::make_column("attrs", &DBVersionedObject::attrs), + sqlite_orm::make_column( + "version_type", &DBVersionedObject::version_type + ), sqlite_orm::foreign_key(&DBVersionedObject::object_id) - .references(&DBObject::object_id) + .references(&DBOPObjectInfo::uuid) ), sqlite_orm::make_table( std::string(ACCESS_KEYS), diff --git a/src/rgw/driver/sfs/sqlite/objects/object_conversions.cc b/src/rgw/driver/sfs/sqlite/objects/object_conversions.cc deleted file mode 100644 index 128757073c761..0000000000000 --- a/src/rgw/driver/sfs/sqlite/objects/object_conversions.cc +++ /dev/null @@ -1,45 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -// vim: ts=8 sw=2 smarttab ft=cpp -/* - * Ceph - scalable distributed file system - * SFS SAL implementation - * - * Copyright (C) 2022 SUSE LLC - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - */ -#include "object_conversions.h" - -#include "../conversion_utils.h" - -namespace rgw::sal::sfs::sqlite { - -DBOPObjectInfo get_rgw_object(const DBObject& object) { - DBOPObjectInfo rgw_object; - rgw_object.uuid.parse(object.object_id.c_str()); - rgw_object.bucket_id = object.bucket_id; - rgw_object.name = object.name; - assign_optional_value(object.size, rgw_object.size); - assign_optional_value(object.etag, rgw_object.etag); - assign_optional_value(object.mtime, rgw_object.mtime); - assign_optional_value(object.set_mtime, rgw_object.set_mtime); - assign_optional_value(object.delete_at_time, rgw_object.delete_at); - return rgw_object; -} - -DBObject get_db_object(const DBOPObjectInfo& object) { - DBObject db_object; - db_object.object_id = object.uuid.to_string(); - db_object.bucket_id = object.bucket_id; - db_object.name = object.name; - assign_db_value(object.size, db_object.size); - assign_db_value(object.etag, db_object.etag); - assign_db_value(object.mtime, db_object.mtime); - assign_db_value(object.set_mtime, db_object.set_mtime); - assign_db_value(object.delete_at, db_object.delete_at_time); - return db_object; -} -} // namespace rgw::sal::sfs::sqlite diff --git a/src/rgw/driver/sfs/sqlite/objects/object_definitions.h b/src/rgw/driver/sfs/sqlite/objects/object_definitions.h index 06b18a9f74131..fbe022f1e1aa1 100644 --- a/src/rgw/driver/sfs/sqlite/objects/object_definitions.h +++ b/src/rgw/driver/sfs/sqlite/objects/object_definitions.h @@ -15,32 +15,15 @@ #include +#include "rgw/driver/sfs/sqlite/bindings/uuid_d.h" #include "rgw_common.h" namespace rgw::sal::sfs::sqlite { -using BLOB = std::vector; - -struct DBObject { - std::string object_id; - std::string bucket_id; - std::string name; - std::optional size; - std::optional etag; - std::optional mtime; - std::optional set_mtime; - std::optional delete_at_time; -}; - struct DBOPObjectInfo { uuid_d uuid; std::string bucket_id; std::string name; - size_t size; - std::string etag; - ceph::real_time mtime; - ceph::real_time set_mtime; - ceph::real_time delete_at; }; } // namespace rgw::sal::sfs::sqlite diff --git a/src/rgw/driver/sfs/sqlite/sqlite_objects.cc b/src/rgw/driver/sfs/sqlite/sqlite_objects.cc index cd79778c4299b..8df3e32e5fef1 100644 --- a/src/rgw/driver/sfs/sqlite/sqlite_objects.cc +++ b/src/rgw/driver/sfs/sqlite/sqlite_objects.cc @@ -17,46 +17,24 @@ using namespace sqlite_orm; namespace rgw::sal::sfs::sqlite { -std::vector get_rgw_uuids(const std::vector& uuids) { - std::vector ret_ids; - for (auto const& uuid : uuids) { - uuid_d rgw_uuid; - rgw_uuid.parse(uuid.c_str()); - ret_ids.push_back(rgw_uuid); - } - return ret_ids; -} - -std::vector get_rgw_objects( - const std::vector& db_objects -) { - std::vector ret_objs; - for (const auto& db_obj : db_objects) { - auto rgw_obj = get_rgw_object(db_obj); - ret_objs.push_back(rgw_obj); - } - return ret_objs; -} - SQLiteObjects::SQLiteObjects(DBConnRef _conn) : conn(_conn) {} std::vector SQLiteObjects::get_objects( const std::string& bucket_id ) const { auto storage = conn->get_storage(); - auto objects = - storage.get_all(where(is_equal(&DBObject::bucket_id, bucket_id)) - ); - return get_rgw_objects(objects); + return storage.get_all( + where(is_equal(&DBOPObjectInfo::bucket_id, bucket_id)) + ); } std::optional SQLiteObjects::get_object(const uuid_d& uuid ) const { auto storage = conn->get_storage(); - auto object = storage.get_pointer(uuid.to_string()); + auto object = storage.get_pointer(uuid.to_string()); std::optional ret_value; if (object) { - ret_value = get_rgw_object(*object); + ret_value = *object; } return ret_value; } @@ -65,40 +43,39 @@ std::optional SQLiteObjects::get_object( const std::string& bucket_id, const std::string& object_name ) const { auto storage = conn->get_storage(); - auto objects = storage.get_all(where( - is_equal(&DBObject::bucket_id, bucket_id) and - is_equal(&DBObject::name, object_name) + auto objects = storage.get_all(where( + is_equal(&DBOPObjectInfo::bucket_id, bucket_id) and + is_equal(&DBOPObjectInfo::name, object_name) )); std::optional ret_value; // value must be unique if (objects.size() == 1) { - ret_value = get_rgw_object(objects[0]); + ret_value = objects[0]; } return ret_value; } void SQLiteObjects::store_object(const DBOPObjectInfo& object) const { auto storage = conn->get_storage(); - auto db_object = get_db_object(object); - storage.replace(db_object); + storage.replace(object); } void SQLiteObjects::remove_object(const uuid_d& uuid) const { auto storage = conn->get_storage(); - storage.remove(uuid.to_string()); + storage.remove(uuid); } std::vector SQLiteObjects::get_object_ids() const { auto storage = conn->get_storage(); - return get_rgw_uuids(storage.select(&DBObject::object_id)); + return storage.select(&DBOPObjectInfo::uuid); } std::vector SQLiteObjects::get_object_ids(const std::string& bucket_id ) const { auto storage = conn->get_storage(); - return get_rgw_uuids(storage.select( - &DBObject::object_id, where(c(&DBObject::bucket_id) = bucket_id) - )); + return storage.select( + &DBOPObjectInfo::uuid, where(c(&DBOPObjectInfo::bucket_id) = bucket_id) + ); } } // namespace rgw::sal::sfs::sqlite diff --git a/src/rgw/driver/sfs/sqlite/sqlite_objects.h b/src/rgw/driver/sfs/sqlite/sqlite_objects.h index 175aefde204d4..5ce7bfe331064 100644 --- a/src/rgw/driver/sfs/sqlite/sqlite_objects.h +++ b/src/rgw/driver/sfs/sqlite/sqlite_objects.h @@ -14,7 +14,6 @@ #pragma once #include "dbconn.h" -#include "objects/object_conversions.h" namespace rgw::sal::sfs::sqlite { diff --git a/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_conversions.cc b/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_conversions.cc index 79540f57853a2..9bcc4346c0492 100644 --- a/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_conversions.cc +++ b/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_conversions.cc @@ -34,15 +34,18 @@ DBOPVersionedObjectInfo get_rgw_versioned_object(const DBVersionedObject& object ) { DBOPVersionedObjectInfo rgw_object; rgw_object.id = object.id; - rgw_object.object_id.parse(object.object_id.c_str()); + rgw_object.object_id = object.object_id; rgw_object.checksum = object.checksum; - decode_blob(object.deletion_time, rgw_object.deletion_time); rgw_object.size = object.size; - decode_blob(object.creation_time, rgw_object.creation_time); - rgw_object.object_state = get_object_state(object.object_state); + rgw_object.create_time = object.create_time; + rgw_object.delete_time = object.delete_time; + rgw_object.commit_time = object.commit_time; + rgw_object.mtime = object.mtime; + rgw_object.object_state = object.object_state; rgw_object.version_id = object.version_id; rgw_object.etag = object.etag; assign_optional_value(object.attrs, rgw_object.attrs); + rgw_object.version_type = object.version_type; return rgw_object; } @@ -50,15 +53,18 @@ DBVersionedObject get_db_versioned_object(const DBOPVersionedObjectInfo& object ) { DBVersionedObject db_object; db_object.id = object.id; - db_object.object_id = object.object_id.to_string(); + db_object.object_id = object.object_id; db_object.checksum = object.checksum; - encode_blob(object.deletion_time, db_object.deletion_time); db_object.size = object.size; - encode_blob(object.creation_time, db_object.creation_time); - db_object.object_state = get_uint_object_state(object.object_state); + db_object.create_time = object.create_time; + db_object.delete_time = object.delete_time; + db_object.commit_time = object.commit_time; + db_object.mtime = object.mtime; + db_object.object_state = object.object_state; db_object.version_id = object.version_id; db_object.etag = object.etag; assign_db_value(object.attrs, db_object.attrs); + db_object.version_type = object.version_type; return db_object; } } // namespace rgw::sal::sfs::sqlite diff --git a/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_definitions.h b/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_definitions.h index c9abaab78a6f6..b41a60a9659f8 100644 --- a/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_definitions.h +++ b/src/rgw/driver/sfs/sqlite/versioned_object/versioned_object_definitions.h @@ -16,6 +16,9 @@ #include #include "rgw/driver/sfs/object_state.h" +#include "rgw/driver/sfs/sqlite/bindings/enum.h" +#include "rgw/driver/sfs/sqlite/bindings/real_time.h" +#include "rgw/driver/sfs/version_type.h" #include "rgw/rgw_common.h" #include "rgw_common.h" @@ -25,28 +28,34 @@ using BLOB = std::vector; struct DBVersionedObject { uint id; - std::string object_id; + uuid_d object_id; std::string checksum; - BLOB deletion_time; size_t size; - BLOB creation_time; - uint object_state; + ceph::real_time create_time; + ceph::real_time delete_time; + ceph::real_time commit_time; + ceph::real_time mtime; + ObjectState object_state; std::string version_id; std::string etag; std::optional attrs; + VersionType version_type = rgw::sal::sfs::VersionType::REGULAR; }; struct DBOPVersionedObjectInfo { uint id; uuid_d object_id; std::string checksum; - ceph::real_time deletion_time; size_t size; - ceph::real_time creation_time; + ceph::real_time create_time; + ceph::real_time delete_time; + ceph::real_time commit_time; + ceph::real_time mtime; ObjectState object_state; std::string version_id; std::string etag; rgw::sal::Attrs attrs; + VersionType version_type = rgw::sal::sfs::VersionType::REGULAR; }; } // namespace rgw::sal::sfs::sqlite diff --git a/src/rgw/driver/sfs/types.cc b/src/rgw/driver/sfs/types.cc index 35ab4af7382c2..525a6030032b1 100644 --- a/src/rgw/driver/sfs/types.cc +++ b/src/rgw/driver/sfs/types.cc @@ -126,11 +126,10 @@ Object* Object::try_create_with_last_version_fetch_from_database( result->deleted = (last_version->object_state == ObjectState::DELETED); result->version_id = last_version->id; result->meta = { - .size = obj->size, - .etag = obj->etag, - .mtime = obj->mtime, - .set_mtime = obj->set_mtime, - .delete_at = obj->delete_at}; + .size = last_version->size, + .etag = last_version->etag, + .mtime = last_version->mtime, + .delete_at = last_version->delete_time}; result->attrs = last_version->attrs; result->instance = last_version->version_id; @@ -157,11 +156,10 @@ Object* Object::try_create_fetch_from_database( result->deleted = (version->object_state == ObjectState::DELETED); result->version_id = version->id; result->meta = { - .size = obj->size, - .etag = obj->etag, - .mtime = obj->mtime, - .set_mtime = obj->set_mtime, - .delete_at = obj->delete_at}; + .size = version->size, + .etag = version->etag, + .mtime = version->mtime, + .delete_at = version->delete_time}; result->attrs = version->attrs; result->instance = version->version_id; return result; @@ -227,7 +225,7 @@ void Object::metadata_change_version_state(SFStore* store, ObjectState state) { versioned_object->object_state = state; if (state == ObjectState::DELETED) { deleted = true; - versioned_object->deletion_time = ceph::real_clock::now(); + versioned_object->delete_time = ceph::real_clock::now(); } db_versioned_objs.store_versioned_object(*versioned_object); } @@ -245,11 +243,6 @@ void Object::metadata_finish(SFStore* store) { auto db_object = dbobjs.get_object(path.get_uuid()); ceph_assert(db_object.has_value()); db_object->name = name; - db_object->size = meta.size; - db_object->etag = meta.etag; - db_object->mtime = meta.mtime; - db_object->set_mtime = meta.set_mtime; - db_object->delete_at = meta.delete_at; dbobjs.store_object(*db_object); sqlite::SQLiteVersionedObjects db_versioned_objs(store->db_conn); @@ -257,7 +250,9 @@ void Object::metadata_finish(SFStore* store) { ceph_assert(db_versioned_object.has_value()); // TODO calculate checksum. Is it already calculated while writing? db_versioned_object->size = meta.size; - db_versioned_object->creation_time = meta.mtime; + db_versioned_object->create_time = meta.mtime; + db_versioned_object->delete_time = meta.delete_at; + db_versioned_object->mtime = meta.mtime; db_versioned_object->object_state = ObjectState::COMMITTED; db_versioned_object->etag = meta.etag; db_versioned_object->attrs = get_attrs(); @@ -406,7 +401,7 @@ void Bucket::delete_object(ObjectRef objref, const rgw_obj_key& key) { _undelete_object(objref, key, db_versioned_objs, *last_version); } else { last_version->object_state = ObjectState::DELETED; - last_version->deletion_time = ceph::real_clock::now(); + last_version->delete_time = ceph::real_clock::now(); if (last_version->version_id != "") { // generate a new version id @@ -444,7 +439,7 @@ std::string Bucket::create_non_existing_object_delete_marker( version_info.object_id = obj->path.get_uuid(); version_info.object_state = ObjectState::DELETED; version_info.version_id = new_version_id; - version_info.deletion_time = ceph::real_clock::now(); + version_info.delete_time = ceph::real_clock::now(); sqlite::SQLiteVersionedObjects db_versioned_objs(store->db_conn); obj->version_id = db_versioned_objs.insert_versioned_object(version_info); @@ -478,7 +473,7 @@ void Bucket::_undelete_object( // non-versioned object // just remove the delete marker in the version and store last_version.object_state = ObjectState::COMMITTED; - last_version.deletion_time = ceph::real_clock::now(); + last_version.delete_time = ceph::real_clock::now(); sqlite_versioned_objects.store_versioned_object(last_version); objref->deleted = false; } diff --git a/src/rgw/driver/sfs/sqlite/objects/object_conversions.h b/src/rgw/driver/sfs/version_type.h similarity index 55% rename from src/rgw/driver/sfs/sqlite/objects/object_conversions.h rename to src/rgw/driver/sfs/version_type.h index 862325f47082d..aa2b598e19379 100644 --- a/src/rgw/driver/sfs/sqlite/objects/object_conversions.h +++ b/src/rgw/driver/sfs/version_type.h @@ -4,21 +4,24 @@ * Ceph - scalable distributed file system * SFS SAL implementation * - * Copyright (C) 2022 SUSE LLC + * Copyright (C) 2023 SUSE LLC * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. */ -#pragma once +#ifndef RGW_SFS_VERSION_TYPE_H +#define RGW_SFS_VERSION_TYPE_H -#include "object_definitions.h" +namespace rgw::sal::sfs { -namespace rgw::sal::sfs::sqlite { +enum class VersionType { + REGULAR = 0, + DELETE_MARKER, + LAST_VALUE = DELETE_MARKER +}; -// Functions that convert DB type to RGW type (and vice-versa) -DBOPObjectInfo get_rgw_object(const DBObject& object); -DBObject get_db_object(const DBOPObjectInfo& object); +} // namespace rgw::sal::sfs -} // namespace rgw::sal::sfs::sqlite +#endif // RGW_SFS_VERSION_TYPE_H diff --git a/src/test/rgw/sfs/compatibility_test_cases/columns_added.h b/src/test/rgw/sfs/compatibility_test_cases/columns_added.h index 60086aefcb300..cef66877f9bb4 100644 --- a/src/test/rgw/sfs/compatibility_test_cases/columns_added.h +++ b/src/test/rgw/sfs/compatibility_test_cases/columns_added.h @@ -1,5 +1,8 @@ -#include "rgw/driver/sfs/sqlite/dbconn.h" +#include "rgw/driver/sfs/sqlite/bindings/enum.h" +#include "rgw/driver/sfs/sqlite/bindings/real_time.h" +#include "rgw/driver/sfs/sqlite/bindings/uuid_d.h" #include "rgw/driver/sfs/sqlite/conversion_utils.h" +#include "rgw/driver/sfs/sqlite/dbconn.h" using namespace rgw::sal::sfs::sqlite; @@ -73,34 +76,49 @@ struct DBTestBucket { // bool deleted; }; -struct DBTestObject { - std::string object_id; +struct DBOPTestObjectInfo { + uuid_d uuid; std::string bucket_id; std::string name; - std::optional size; - std::optional etag; - std::optional mtime; - std::optional set_mtime; - std::optional delete_at_time; }; struct DBTestVersionedObject { uint id; std::string object_id; std::string checksum; - BLOB deletion_time; size_t size; - BLOB creation_time; - uint object_state; + ceph::real_time create_time; + ceph::real_time delete_time; + ceph::real_time commit_time; + ceph::real_time mtime; + rgw::sal::sfs::ObjectState object_state; std::string version_id; std::string etag; std::optional attrs; + rgw::sal::sfs::VersionType version_type = rgw::sal::sfs::VersionType::REGULAR; }; -inline auto _make_test_storage(const std::string &path) { - return sqlite_orm::make_storage(path, - sqlite_orm::make_table(std::string(USERS_TABLE), - sqlite_orm::make_column("user_id", &DBTestUser::user_id, sqlite_orm::primary_key()), +struct DBOPTestLCHead { + std::string lc_index; // primary key + std::string marker; + long start_date; +}; + +struct DBOPTestLCEntry { + std::string lc_index; // composite primary key + std::string bucket_name; // composite primary key + uint64_t start_time; + uint32_t status; +}; + +inline auto _make_test_storage(const std::string& path) { + return sqlite_orm::make_storage( + path, + sqlite_orm::make_table( + std::string(USERS_TABLE), + sqlite_orm::make_column( + "user_id", &DBTestUser::user_id, sqlite_orm::primary_key() + ), sqlite_orm::make_column("tenant", &DBTestUser::tenant), sqlite_orm::make_column("ns", &DBTestUser::ns), sqlite_orm::make_column("display_name", &DBTestUser::display_name), @@ -114,20 +132,34 @@ inline auto _make_test_storage(const std::string &path) { sqlite_orm::make_column("user_caps", &DBTestUser::user_caps), sqlite_orm::make_column("admin", &DBTestUser::admin), sqlite_orm::make_column("system", &DBTestUser::system), - sqlite_orm::make_column("placement_name", &DBTestUser::placement_name), - sqlite_orm::make_column("placement_storage_class", &DBTestUser::placement_storage_class), - sqlite_orm::make_column("placement_tags", &DBTestUser::placement_tags), + sqlite_orm::make_column( + "placement_name", &DBTestUser::placement_name + ), + sqlite_orm::make_column( + "placement_storage_class", &DBTestUser::placement_storage_class + ), + sqlite_orm::make_column( + "placement_tags", &DBTestUser::placement_tags + ), sqlite_orm::make_column("bucket_quota", &DBTestUser::bucket_quota), sqlite_orm::make_column("temp_url_keys", &DBTestUser::temp_url_keys), sqlite_orm::make_column("user_quota", &DBTestUser::user_quota), sqlite_orm::make_column("type", &DBTestUser::type), sqlite_orm::make_column("mfa_ids", &DBTestUser::mfa_ids), - sqlite_orm::make_column("assumed_role_arn", &DBTestUser::assumed_role_arn), + sqlite_orm::make_column( + "assumed_role_arn", &DBTestUser::assumed_role_arn + ), sqlite_orm::make_column("user_attrs", &DBTestUser::user_attrs), sqlite_orm::make_column("user_version", &DBTestUser::user_version), - sqlite_orm::make_column("user_version_tag", &DBTestUser::user_version_tag)), - sqlite_orm::make_table(std::string(BUCKETS_TABLE), - sqlite_orm::make_column("bucket_id", &DBTestBucket::bucket_id, sqlite_orm::primary_key()), + sqlite_orm::make_column( + "user_version_tag", &DBTestUser::user_version_tag + ) + ), + sqlite_orm::make_table( + std::string(BUCKETS_TABLE), + sqlite_orm::make_column( + "bucket_id", &DBTestBucket::bucket_id, sqlite_orm::primary_key() + ), sqlite_orm::make_column("bucket_name", &DBTestBucket::bucket_name), sqlite_orm::make_column("tenant", &DBTestBucket::tenant), sqlite_orm::make_column("marker", &DBTestBucket::marker), @@ -135,40 +167,96 @@ inline auto _make_test_storage(const std::string &path) { sqlite_orm::make_column("flags", &DBTestBucket::flags), sqlite_orm::make_column("zone_group", &DBTestBucket::zone_group), sqlite_orm::make_column("quota", &DBTestBucket::quota), - sqlite_orm::make_column("creation_time", &DBTestBucket::creation_time), - sqlite_orm::make_column("placement_name", &DBTestBucket::placement_name), - sqlite_orm::make_column("placement_storage_class", &DBTestBucket::placement_storage_class), + sqlite_orm::make_column( + "creation_time", &DBTestBucket::creation_time + ), + sqlite_orm::make_column( + "placement_name", &DBTestBucket::placement_name + ), + sqlite_orm::make_column( + "placement_storage_class", &DBTestBucket::placement_storage_class + ), // this column will be added // sqlite_orm::make_column("deleted", &DBTestBucket::deleted), sqlite_orm::make_column("bucket_attrs", &DBTestBucket::bucket_attrs), - sqlite_orm::foreign_key(&DBTestBucket::owner_id).references(&DBTestUser::user_id)), - sqlite_orm::make_table(std::string(OBJECTS_TABLE), - sqlite_orm::make_column("object_id", &DBTestObject::object_id, sqlite_orm::primary_key()), - sqlite_orm::make_column("bucket_id", &DBTestObject::bucket_id), - sqlite_orm::make_column("name", &DBTestObject::name), - sqlite_orm::make_column("size", &DBTestObject::size), - sqlite_orm::make_column("etag", &DBTestObject::etag), - sqlite_orm::make_column("mtime", &DBTestObject::mtime), - sqlite_orm::make_column("set_mtime", &DBTestObject::set_mtime), - sqlite_orm::make_column("delete_at_time", &DBTestObject::delete_at_time), - sqlite_orm::foreign_key(&DBTestObject::bucket_id).references(&DBTestBucket::bucket_id)), - sqlite_orm::make_table(std::string(VERSIONED_OBJECTS_TABLE), - sqlite_orm::make_column("id", &DBTestVersionedObject::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key()), - sqlite_orm::make_column("object_id", &DBTestVersionedObject::object_id), + sqlite_orm::make_column("object_lock", &DBTestBucket::object_lock), + sqlite_orm::foreign_key(&DBTestBucket::owner_id) + .references(&DBTestUser::user_id) + ), + sqlite_orm::make_table( + std::string(OBJECTS_TABLE), + sqlite_orm::make_column( + "uuid", &DBOPTestObjectInfo::uuid, sqlite_orm::primary_key() + ), + sqlite_orm::make_column("bucket_id", &DBOPTestObjectInfo::bucket_id), + sqlite_orm::make_column("name", &DBOPTestObjectInfo::name), + sqlite_orm::foreign_key(&DBOPTestObjectInfo::bucket_id) + .references(&DBTestBucket::bucket_id) + ), + sqlite_orm::make_table( + std::string(VERSIONED_OBJECTS_TABLE), + sqlite_orm::make_column( + "id", &DBTestVersionedObject::id, sqlite_orm::autoincrement(), + sqlite_orm::primary_key() + ), + sqlite_orm::make_column( + "object_id", &DBTestVersionedObject::object_id + ), sqlite_orm::make_column("checksum", &DBTestVersionedObject::checksum), - sqlite_orm::make_column("deletion_time", &DBTestVersionedObject::deletion_time), sqlite_orm::make_column("size", &DBTestVersionedObject::size), - sqlite_orm::make_column("creation_time", &DBTestVersionedObject::creation_time), - sqlite_orm::make_column("object_state", &DBTestVersionedObject::object_state), - sqlite_orm::make_column("version_id", &DBTestVersionedObject::version_id), + sqlite_orm::make_column( + "create_time", &DBTestVersionedObject::create_time + ), + sqlite_orm::make_column( + "delete_time", &DBTestVersionedObject::delete_time + ), + sqlite_orm::make_column( + "commit_time", &DBTestVersionedObject::commit_time + ), + sqlite_orm::make_column("mtime", &DBTestVersionedObject::mtime), + sqlite_orm::make_column( + "object_state", &DBTestVersionedObject::object_state + ), + sqlite_orm::make_column( + "version_id", &DBTestVersionedObject::version_id + ), sqlite_orm::make_column("etag", &DBTestVersionedObject::etag), sqlite_orm::make_column("attrs", &DBTestVersionedObject::attrs), - sqlite_orm::foreign_key(&DBTestVersionedObject::object_id).references(&DBTestObject::object_id)), - sqlite_orm::make_table(std::string(ACCESS_KEYS), - sqlite_orm::make_column("id", &DBAccessKey::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key()), - sqlite_orm::make_column("access_key", &DBAccessKey::access_key), - sqlite_orm::make_column("user_id", &DBAccessKey::user_id), - sqlite_orm::foreign_key(&DBAccessKey::user_id).references(&DBTestUser::user_id)) + sqlite_orm::make_column( + "version_type", &DBTestVersionedObject::version_type + ), + sqlite_orm::foreign_key(&DBTestVersionedObject::object_id) + .references(&DBOPTestObjectInfo::uuid) + ), + sqlite_orm::make_table( + std::string(ACCESS_KEYS), + sqlite_orm::make_column( + "id", &DBTestAccessKey::id, sqlite_orm::autoincrement(), + sqlite_orm::primary_key() + ), + sqlite_orm::make_column("access_key", &DBTestAccessKey::access_key), + sqlite_orm::make_column("user_id", &DBTestAccessKey::user_id), + sqlite_orm::foreign_key(&DBTestAccessKey::user_id) + .references(&DBTestUser::user_id) + ), + sqlite_orm::make_table( + std::string(LC_HEAD_TABLE), + sqlite_orm::make_column( + "lc_index", &DBOPTestLCHead::lc_index, sqlite_orm::primary_key() + ), + sqlite_orm::make_column("marker", &DBOPTestLCHead::marker), + sqlite_orm::make_column("start_date", &DBOPTestLCHead::start_date) + ), + sqlite_orm::make_table( + std::string(LC_ENTRIES_TABLE), + sqlite_orm::make_column("lc_index", &DBOPTestLCEntry::lc_index), + sqlite_orm::make_column("bucket_name", &DBOPTestLCEntry::bucket_name), + sqlite_orm::make_column("start_time", &DBOPTestLCEntry::start_time), + sqlite_orm::make_column("status", &DBOPTestLCEntry::status), + sqlite_orm::primary_key( + &DBOPTestLCEntry::lc_index, &DBOPTestLCEntry::bucket_name + ) + ) ); } @@ -178,19 +266,20 @@ struct TestDB { TestStorage storage; DBTestUser test_user; DBTestBucket test_bucket; - DBTestObject test_object; + DBOPTestObjectInfo test_object; DBTestVersionedObject test_version; - explicit TestDB(const std::string & db_full_path) - : storage(_make_test_storage(db_full_path)) - { + explicit TestDB(const std::string& db_full_path) + : storage(_make_test_storage(db_full_path)) { storage.on_open = [](sqlite3* db) { sqlite3_extended_result_codes(db, 1); sqlite3_busy_timeout(db, 10000); - sqlite3_exec(db, - "PRAGMA journal_mode=WAL;PRAGMA synchronous=normal;" - "PRAGMA temp_store = memory;PRAGMA mmap_size = 30000000000;", - 0, 0, 0); + sqlite3_exec( + db, + "PRAGMA journal_mode=WAL;PRAGMA synchronous=normal;" + "PRAGMA temp_store = memory;PRAGMA mmap_size = 30000000000;", + 0, 0, 0 + ); }; storage.open_forever(); storage.busy_timeout(5000); @@ -211,9 +300,11 @@ struct TestDB { return bucket; } - DBTestObject get_test_object() { - DBTestObject object; - object.object_id = "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; + DBOPTestObjectInfo get_test_object() { + DBOPTestObjectInfo object; + uuid_d uuid_val; + uuid_val.parse("9f06d9d3-307f-4c98-865b-cd3b087acc4f"); + object.uuid = uuid_val; object.bucket_id = "bucket1_id"; object.name = "object_name"; return object; @@ -224,41 +315,44 @@ struct TestDB { version.id = 1; version.object_id = "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; version.checksum = "checksum1"; - encode_blob(ceph::real_clock::now(), version.deletion_time); + version.delete_time = ceph::real_clock::now(); version.size = rand(); - encode_blob(ceph::real_clock::now(), version.creation_time); - version.object_state = 2; + version.create_time = ceph::real_clock::now(); + version.object_state = rgw::sal::sfs::ObjectState::COMMITTED; version.version_id = "version_id_1"; return version; } - bool compareUser(const DBTestUser & user1, const DBTestUser & user2) { + bool compareUser(const DBTestUser& user1, const DBTestUser& user2) { if (user1.user_id != user2.user_id) return false; return true; } - bool compareBucket(const DBTestBucket & bucket1, const DBTestBucket & bucket2) { + bool compareBucket(const DBTestBucket& bucket1, const DBTestBucket& bucket2) { if (bucket1.bucket_id != bucket2.bucket_id) return false; if (bucket1.bucket_name != bucket2.bucket_name) return false; if (bucket1.owner_id != bucket2.owner_id) return false; return true; } - bool compareObject(const DBTestObject & obj1, const DBTestObject & obj2) { - if (obj1.object_id != obj2.object_id) return false; + bool compareObject( + const DBOPTestObjectInfo& obj1, const DBOPTestObjectInfo& obj2 + ) { + if (obj1.uuid != obj2.uuid) return false; if (obj1.bucket_id != obj2.bucket_id) return false; if (obj1.name != obj2.name) return false; return true; } - bool compareVersion(const DBTestVersionedObject & v1, - const DBTestVersionedObject & v2) { + bool compareVersion( + const DBTestVersionedObject& v1, const DBTestVersionedObject& v2 + ) { if (v1.version_id != v2.version_id) return false; if (v1.object_id != v2.object_id) return false; if (v1.checksum != v2.checksum) return false; - if (v1.deletion_time != v2.deletion_time) return false; + if (v1.delete_time != v2.delete_time) return false; if (v1.size != v2.size) return false; - if (v1.creation_time != v2.creation_time) return false; + if (v1.create_time != v2.create_time) return false; if (v1.object_state != v2.object_state) return false; if (v1.version_id != v2.version_id) return false; return true; @@ -285,7 +379,7 @@ struct TestDB { auto users = storage.get_all(); if (users.size() != 1) return false; - auto objs = storage.get_all(); + auto objs = storage.get_all(); if (objs.size() != 1) return false; auto versions = storage.get_all(); @@ -299,7 +393,7 @@ struct TestDB { if (!user) return false; if (!compareUser(*user, test_user)) return false; - auto object = storage.get_pointer(test_object.object_id); + auto object = storage.get_pointer(test_object.uuid); if (!object) return false; if (!compareObject(*object, test_object)) return false; @@ -309,7 +403,6 @@ struct TestDB { return true; } - }; -} // namespace rgw::test::metadata::new_columns_added +} // namespace rgw::test::metadata::columns_added diff --git a/src/test/rgw/sfs/compatibility_test_cases/columns_deleted.h b/src/test/rgw/sfs/compatibility_test_cases/columns_deleted.h index 3fda5d555f619..579bd85f9b2c0 100644 --- a/src/test/rgw/sfs/compatibility_test_cases/columns_deleted.h +++ b/src/test/rgw/sfs/compatibility_test_cases/columns_deleted.h @@ -1,5 +1,5 @@ -#include "rgw/driver/sfs/sqlite/dbconn.h" #include "rgw/driver/sfs/sqlite/conversion_utils.h" +#include "rgw/driver/sfs/sqlite/dbconn.h" using namespace rgw::sal::sfs::sqlite; @@ -72,15 +72,10 @@ struct DBTestBucket { bool deleted; }; -struct DBTestObject { - std::string object_id; +struct DBOPTestObjectInfo { + uuid_d uuid; std::string bucket_id; std::string name; - std::optional size; - std::optional etag; - std::optional mtime; - std::optional set_mtime; - std::optional delete_at_time; std::string extra; // extra column that is considered as deleted }; @@ -88,20 +83,40 @@ struct DBTestVersionedObject { uint id; std::string object_id; std::string checksum; - BLOB deletion_time; size_t size; - BLOB creation_time; - uint object_state; + ceph::real_time create_time; + ceph::real_time delete_time; + ceph::real_time commit_time; + ceph::real_time mtime; + rgw::sal::sfs::ObjectState object_state; std::string version_id; std::string etag; std::optional attrs; + rgw::sal::sfs::VersionType version_type = rgw::sal::sfs::VersionType::REGULAR; std::string extra; // extra column that is considered as deleted }; -inline auto _make_test_storage(const std::string &path) { - return sqlite_orm::make_storage(path, - sqlite_orm::make_table(std::string(USERS_TABLE), - sqlite_orm::make_column("user_id", &DBTestUser::user_id, sqlite_orm::primary_key()), +struct DBOPTestLCHead { + std::string lc_index; // primary key + std::string marker; + long start_date; +}; + +struct DBOPTestLCEntry { + std::string lc_index; // composite primary key + std::string bucket_name; // composite primary key + uint64_t start_time; + uint32_t status; +}; + +inline auto _make_test_storage(const std::string& path) { + return sqlite_orm::make_storage( + path, + sqlite_orm::make_table( + std::string(USERS_TABLE), + sqlite_orm::make_column( + "user_id", &DBTestUser::user_id, sqlite_orm::primary_key() + ), sqlite_orm::make_column("tenant", &DBTestUser::tenant), sqlite_orm::make_column("ns", &DBTestUser::ns), sqlite_orm::make_column("display_name", &DBTestUser::display_name), @@ -115,20 +130,34 @@ inline auto _make_test_storage(const std::string &path) { sqlite_orm::make_column("user_caps", &DBTestUser::user_caps), sqlite_orm::make_column("admin", &DBTestUser::admin), sqlite_orm::make_column("system", &DBTestUser::system), - sqlite_orm::make_column("placement_name", &DBTestUser::placement_name), - sqlite_orm::make_column("placement_storage_class", &DBTestUser::placement_storage_class), - sqlite_orm::make_column("placement_tags", &DBTestUser::placement_tags), + sqlite_orm::make_column( + "placement_name", &DBTestUser::placement_name + ), + sqlite_orm::make_column( + "placement_storage_class", &DBTestUser::placement_storage_class + ), + sqlite_orm::make_column( + "placement_tags", &DBTestUser::placement_tags + ), sqlite_orm::make_column("bucket_quota", &DBTestUser::bucket_quota), sqlite_orm::make_column("temp_url_keys", &DBTestUser::temp_url_keys), sqlite_orm::make_column("user_quota", &DBTestUser::user_quota), sqlite_orm::make_column("type", &DBTestUser::type), sqlite_orm::make_column("mfa_ids", &DBTestUser::mfa_ids), - sqlite_orm::make_column("assumed_role_arn", &DBTestUser::assumed_role_arn), + sqlite_orm::make_column( + "assumed_role_arn", &DBTestUser::assumed_role_arn + ), sqlite_orm::make_column("user_attrs", &DBTestUser::user_attrs), sqlite_orm::make_column("user_version", &DBTestUser::user_version), - sqlite_orm::make_column("user_version_tag", &DBTestUser::user_version_tag)), - sqlite_orm::make_table(std::string(BUCKETS_TABLE), - sqlite_orm::make_column("bucket_id", &DBTestBucket::bucket_id, sqlite_orm::primary_key()), + sqlite_orm::make_column( + "user_version_tag", &DBTestUser::user_version_tag + ) + ), + sqlite_orm::make_table( + std::string(BUCKETS_TABLE), + sqlite_orm::make_column( + "bucket_id", &DBTestBucket::bucket_id, sqlite_orm::primary_key() + ), sqlite_orm::make_column("bucket_name", &DBTestBucket::bucket_name), sqlite_orm::make_column("tenant", &DBTestBucket::tenant), sqlite_orm::make_column("marker", &DBTestBucket::marker), @@ -136,41 +165,97 @@ inline auto _make_test_storage(const std::string &path) { sqlite_orm::make_column("flags", &DBTestBucket::flags), sqlite_orm::make_column("zone_group", &DBTestBucket::zone_group), sqlite_orm::make_column("quota", &DBTestBucket::quota), - sqlite_orm::make_column("creation_time", &DBTestBucket::creation_time), - sqlite_orm::make_column("placement_name", &DBTestBucket::placement_name), - sqlite_orm::make_column("placement_storage_class", &DBTestBucket::placement_storage_class), + sqlite_orm::make_column( + "creation_time", &DBTestBucket::creation_time + ), + sqlite_orm::make_column( + "placement_name", &DBTestBucket::placement_name + ), + sqlite_orm::make_column( + "placement_storage_class", &DBTestBucket::placement_storage_class + ), sqlite_orm::make_column("deleted", &DBTestBucket::deleted), sqlite_orm::make_column("bucket_attrs", &DBTestBucket::bucket_attrs), - sqlite_orm::foreign_key(&DBTestBucket::owner_id).references(&DBTestUser::user_id)), - sqlite_orm::make_table(std::string(OBJECTS_TABLE), - sqlite_orm::make_column("object_id", &DBTestObject::object_id, sqlite_orm::primary_key()), - sqlite_orm::make_column("bucket_id", &DBTestObject::bucket_id), - sqlite_orm::make_column("name", &DBTestObject::name), - sqlite_orm::make_column("size", &DBTestObject::size), - sqlite_orm::make_column("etag", &DBTestObject::etag), - sqlite_orm::make_column("mtime", &DBTestObject::mtime), - sqlite_orm::make_column("set_mtime", &DBTestObject::set_mtime), - sqlite_orm::make_column("delete_at_time", &DBTestObject::delete_at_time), - sqlite_orm::make_column("extra", &DBTestObject::extra), - sqlite_orm::foreign_key(&DBTestObject::bucket_id).references(&DBTestBucket::bucket_id)), - sqlite_orm::make_table(std::string(VERSIONED_OBJECTS_TABLE), - sqlite_orm::make_column("id", &DBTestVersionedObject::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key()), - sqlite_orm::make_column("object_id", &DBTestVersionedObject::object_id), + sqlite_orm::make_column("object_lock", &DBTestBucket::object_lock), + sqlite_orm::foreign_key(&DBTestBucket::owner_id) + .references(&DBTestUser::user_id) + ), + sqlite_orm::make_table( + std::string(OBJECTS_TABLE), + sqlite_orm::make_column( + "uuid", &DBOPTestObjectInfo::uuid, sqlite_orm::primary_key() + ), + sqlite_orm::make_column("bucket_id", &DBOPTestObjectInfo::bucket_id), + sqlite_orm::make_column("name", &DBOPTestObjectInfo::name), + sqlite_orm::make_column("extra", &DBOPTestObjectInfo::extra), + sqlite_orm::foreign_key(&DBOPTestObjectInfo::bucket_id) + .references(&DBTestBucket::bucket_id) + ), + sqlite_orm::make_table( + std::string(VERSIONED_OBJECTS_TABLE), + sqlite_orm::make_column( + "id", &DBTestVersionedObject::id, sqlite_orm::autoincrement(), + sqlite_orm::primary_key() + ), + sqlite_orm::make_column( + "object_id", &DBTestVersionedObject::object_id + ), sqlite_orm::make_column("checksum", &DBTestVersionedObject::checksum), - sqlite_orm::make_column("deletion_time", &DBTestVersionedObject::deletion_time), sqlite_orm::make_column("size", &DBTestVersionedObject::size), - sqlite_orm::make_column("creation_time", &DBTestVersionedObject::creation_time), - sqlite_orm::make_column("object_state", &DBTestVersionedObject::object_state), - sqlite_orm::make_column("version_id", &DBTestVersionedObject::version_id), + sqlite_orm::make_column( + "create_time", &DBTestVersionedObject::create_time + ), + sqlite_orm::make_column( + "delete_time", &DBTestVersionedObject::delete_time + ), + sqlite_orm::make_column( + "commit_time", &DBTestVersionedObject::commit_time + ), + sqlite_orm::make_column("mtime", &DBTestVersionedObject::mtime), + sqlite_orm::make_column( + "object_state", &DBTestVersionedObject::object_state + ), + sqlite_orm::make_column( + "version_id", &DBTestVersionedObject::version_id + ), sqlite_orm::make_column("etag", &DBTestVersionedObject::etag), sqlite_orm::make_column("attrs", &DBTestVersionedObject::attrs), + sqlite_orm::make_column( + "version_type", &DBTestVersionedObject::version_type + ), sqlite_orm::make_column("extra", &DBTestVersionedObject::extra), - sqlite_orm::foreign_key(&DBTestVersionedObject::object_id).references(&DBTestObject::object_id)), - sqlite_orm::make_table(std::string(ACCESS_KEYS), - sqlite_orm::make_column("id", &DBTestAccessKey::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key()), + sqlite_orm::foreign_key(&DBTestVersionedObject::object_id) + .references(&DBOPTestObjectInfo::uuid) + ), + sqlite_orm::make_table( + std::string(ACCESS_KEYS), + sqlite_orm::make_column( + "id", &DBTestAccessKey::id, sqlite_orm::autoincrement(), + sqlite_orm::primary_key() + ), sqlite_orm::make_column("access_key", &DBTestAccessKey::access_key), sqlite_orm::make_column("user_id", &DBTestAccessKey::user_id), - sqlite_orm::foreign_key(&DBTestAccessKey::user_id).references(&DBTestUser::user_id)) + sqlite_orm::foreign_key(&DBTestAccessKey::user_id) + .references(&DBTestUser::user_id) + ), + sqlite_orm::make_table( + std::string(LC_HEAD_TABLE), + sqlite_orm::make_column( + "lc_index", &DBOPTestLCHead::lc_index, sqlite_orm::primary_key() + ), + sqlite_orm::make_column("marker", &DBOPTestLCHead::marker), + sqlite_orm::make_column("start_date", &DBOPTestLCHead::start_date) + ), + sqlite_orm::make_table( + std::string(LC_ENTRIES_TABLE), + sqlite_orm::make_column("lc_index", &DBOPTestLCEntry::lc_index), + sqlite_orm::make_column("bucket_name", &DBOPTestLCEntry::bucket_name), + sqlite_orm::make_column("start_time", &DBOPTestLCEntry::start_time), + sqlite_orm::make_column("status", &DBOPTestLCEntry::status), + sqlite_orm::primary_key( + &DBOPTestLCEntry::lc_index, &DBOPTestLCEntry::bucket_name + ) + ) ); } @@ -180,19 +265,20 @@ struct TestDB { TestStorage storage; DBTestUser test_user; DBTestBucket test_bucket; - DBTestObject test_object; + DBOPTestObjectInfo test_object; DBTestVersionedObject test_version; - explicit TestDB(const std::string & db_full_path) - : storage(_make_test_storage(db_full_path)) - { + explicit TestDB(const std::string& db_full_path) + : storage(_make_test_storage(db_full_path)) { storage.on_open = [](sqlite3* db) { sqlite3_extended_result_codes(db, 1); sqlite3_busy_timeout(db, 10000); - sqlite3_exec(db, - "PRAGMA journal_mode=WAL;PRAGMA synchronous=normal;" - "PRAGMA temp_store = memory;PRAGMA mmap_size = 30000000000;", - 0, 0, 0); + sqlite3_exec( + db, + "PRAGMA journal_mode=WAL;PRAGMA synchronous=normal;" + "PRAGMA temp_store = memory;PRAGMA mmap_size = 30000000000;", + 0, 0, 0 + ); }; storage.open_forever(); storage.busy_timeout(5000); @@ -214,9 +300,11 @@ struct TestDB { return bucket; } - DBTestObject get_test_object() { - DBTestObject object; - object.object_id = "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; + DBOPTestObjectInfo get_test_object() { + DBOPTestObjectInfo object; + uuid_d uuid_val; + uuid_val.parse("9f06d9d3-307f-4c98-865b-cd3b087acc4f"); + object.uuid = uuid_val; object.bucket_id = "bucket1_id"; object.name = "object_name"; return object; @@ -227,43 +315,46 @@ struct TestDB { version.id = 1; version.object_id = "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; version.checksum = "checksum1"; - encode_blob(ceph::real_clock::now(), version.deletion_time); + version.delete_time = ceph::real_clock::now(); version.size = rand(); - encode_blob(ceph::real_clock::now(), version.creation_time); - version.object_state = 2; + version.create_time = ceph::real_clock::now(); + version.object_state = rgw::sal::sfs::ObjectState::COMMITTED; version.version_id = "version_id_1"; version.etag = "etag_1"; version.extra = "extra_1"; return version; } - bool compareUser(const DBTestUser & user1, const DBTestUser & user2) { + bool compareUser(const DBTestUser& user1, const DBTestUser& user2) { if (user1.user_id != user2.user_id) return false; return true; } - bool compareBucket(const DBTestBucket & bucket1, const DBTestBucket & bucket2) { + bool compareBucket(const DBTestBucket& bucket1, const DBTestBucket& bucket2) { if (bucket1.bucket_id != bucket2.bucket_id) return false; if (bucket1.bucket_name != bucket2.bucket_name) return false; if (bucket1.owner_id != bucket2.owner_id) return false; return true; } - bool compareObject(const DBTestObject & obj1, const DBTestObject & obj2) { - if (obj1.object_id != obj2.object_id) return false; + bool compareObject( + const DBOPTestObjectInfo& obj1, const DBOPTestObjectInfo& obj2 + ) { + if (obj1.uuid != obj2.uuid) return false; if (obj1.bucket_id != obj2.bucket_id) return false; if (obj1.name != obj2.name) return false; return true; } - bool compareVersion(const DBTestVersionedObject & v1, - const DBTestVersionedObject & v2) { + bool compareVersion( + const DBTestVersionedObject& v1, const DBTestVersionedObject& v2 + ) { if (v1.version_id != v2.version_id) return false; if (v1.object_id != v2.object_id) return false; if (v1.checksum != v2.checksum) return false; - if (v1.deletion_time != v2.deletion_time) return false; + if (v1.delete_time != v2.delete_time) return false; if (v1.size != v2.size) return false; - if (v1.creation_time != v2.creation_time) return false; + if (v1.create_time != v2.create_time) return false; if (v1.object_state != v2.object_state) return false; if (v1.version_id != v2.version_id) return false; if (v1.etag != v2.etag) return false; @@ -292,7 +383,7 @@ struct TestDB { auto users = storage.get_all(); if (users.size() != 1) return false; - auto objs = storage.get_all(); + auto objs = storage.get_all(); if (objs.size() != 1) return false; auto versions = storage.get_all(); @@ -306,7 +397,7 @@ struct TestDB { if (!user) return false; if (!compareUser(*user, test_user)) return false; - auto object = storage.get_pointer(test_object.object_id); + auto object = storage.get_pointer(test_object.uuid); if (!object) return false; if (!compareObject(*object, test_object)) return false; @@ -316,7 +407,6 @@ struct TestDB { return true; } - }; -} // namespace rgw::test::metadata::new_columns_added +} // namespace rgw::test::metadata::columns_deleted diff --git a/src/test/rgw/sfs/compatibility_test_cases/optional_columns_added.h b/src/test/rgw/sfs/compatibility_test_cases/optional_columns_added.h index 8a5f181bff129..1842a4638cb04 100644 --- a/src/test/rgw/sfs/compatibility_test_cases/optional_columns_added.h +++ b/src/test/rgw/sfs/compatibility_test_cases/optional_columns_added.h @@ -1,5 +1,5 @@ -#include "rgw/driver/sfs/sqlite/dbconn.h" #include "rgw/driver/sfs/sqlite/conversion_utils.h" +#include "rgw/driver/sfs/sqlite/dbconn.h" using namespace rgw::sal::sfs::sqlite; @@ -43,7 +43,7 @@ struct DBTestAccessKey { struct DBTestBucket { std::string bucket_name; std::string bucket_id; - // these 2 columns will be added + // These 2 columns will be added // std::optional tenant; // std::optional marker; std::optional size; @@ -73,34 +73,49 @@ struct DBTestBucket { bool deleted; }; -struct DBTestObject { - std::string object_id; +struct DBOPTestObjectInfo { + uuid_d uuid; std::string bucket_id; std::string name; - std::optional size; - std::optional etag; - std::optional mtime; - std::optional set_mtime; - std::optional delete_at_time; }; struct DBTestVersionedObject { uint id; std::string object_id; std::string checksum; - BLOB deletion_time; size_t size; - BLOB creation_time; - uint object_state; + ceph::real_time create_time; + ceph::real_time delete_time; + ceph::real_time commit_time; + ceph::real_time mtime; + rgw::sal::sfs::ObjectState object_state; std::string version_id; std::string etag; std::optional attrs; + rgw::sal::sfs::VersionType version_type = rgw::sal::sfs::VersionType::REGULAR; }; -inline auto _make_test_storage(const std::string &path) { - return sqlite_orm::make_storage(path, - sqlite_orm::make_table(std::string(USERS_TABLE), - sqlite_orm::make_column("user_id", &DBTestUser::user_id, sqlite_orm::primary_key()), +struct DBOPTestLCHead { + std::string lc_index; // primary key + std::string marker; + long start_date; +}; + +struct DBOPTestLCEntry { + std::string lc_index; // composite primary key + std::string bucket_name; // composite primary key + uint64_t start_time; + uint32_t status; +}; + +inline auto _make_test_storage(const std::string& path) { + return sqlite_orm::make_storage( + path, + sqlite_orm::make_table( + std::string(USERS_TABLE), + sqlite_orm::make_column( + "user_id", &DBTestUser::user_id, sqlite_orm::primary_key() + ), sqlite_orm::make_column("tenant", &DBTestUser::tenant), sqlite_orm::make_column("ns", &DBTestUser::ns), sqlite_orm::make_column("display_name", &DBTestUser::display_name), @@ -114,20 +129,34 @@ inline auto _make_test_storage(const std::string &path) { sqlite_orm::make_column("user_caps", &DBTestUser::user_caps), sqlite_orm::make_column("admin", &DBTestUser::admin), sqlite_orm::make_column("system", &DBTestUser::system), - sqlite_orm::make_column("placement_name", &DBTestUser::placement_name), - sqlite_orm::make_column("placement_storage_class", &DBTestUser::placement_storage_class), - sqlite_orm::make_column("placement_tags", &DBTestUser::placement_tags), + sqlite_orm::make_column( + "placement_name", &DBTestUser::placement_name + ), + sqlite_orm::make_column( + "placement_storage_class", &DBTestUser::placement_storage_class + ), + sqlite_orm::make_column( + "placement_tags", &DBTestUser::placement_tags + ), sqlite_orm::make_column("bucket_quota", &DBTestUser::bucket_quota), sqlite_orm::make_column("temp_url_keys", &DBTestUser::temp_url_keys), sqlite_orm::make_column("user_quota", &DBTestUser::user_quota), sqlite_orm::make_column("type", &DBTestUser::type), sqlite_orm::make_column("mfa_ids", &DBTestUser::mfa_ids), - sqlite_orm::make_column("assumed_role_arn", &DBTestUser::assumed_role_arn), + sqlite_orm::make_column( + "assumed_role_arn", &DBTestUser::assumed_role_arn + ), sqlite_orm::make_column("user_attrs", &DBTestUser::user_attrs), sqlite_orm::make_column("user_version", &DBTestUser::user_version), - sqlite_orm::make_column("user_version_tag", &DBTestUser::user_version_tag)), - sqlite_orm::make_table(std::string(BUCKETS_TABLE), - sqlite_orm::make_column("bucket_id", &DBTestBucket::bucket_id, sqlite_orm::primary_key()), + sqlite_orm::make_column( + "user_version_tag", &DBTestUser::user_version_tag + ) + ), + sqlite_orm::make_table( + std::string(BUCKETS_TABLE), + sqlite_orm::make_column( + "bucket_id", &DBTestBucket::bucket_id, sqlite_orm::primary_key() + ), sqlite_orm::make_column("bucket_name", &DBTestBucket::bucket_name), // these 2 columns will be added // sqlite_orm::make_column("tenant", &DBTestBucket::tenant), @@ -136,39 +165,95 @@ inline auto _make_test_storage(const std::string &path) { sqlite_orm::make_column("flags", &DBTestBucket::flags), sqlite_orm::make_column("zone_group", &DBTestBucket::zone_group), sqlite_orm::make_column("quota", &DBTestBucket::quota), - sqlite_orm::make_column("creation_time", &DBTestBucket::creation_time), - sqlite_orm::make_column("placement_name", &DBTestBucket::placement_name), - sqlite_orm::make_column("placement_storage_class", &DBTestBucket::placement_storage_class), + sqlite_orm::make_column( + "creation_time", &DBTestBucket::creation_time + ), + sqlite_orm::make_column( + "placement_name", &DBTestBucket::placement_name + ), + sqlite_orm::make_column( + "placement_storage_class", &DBTestBucket::placement_storage_class + ), sqlite_orm::make_column("deleted", &DBTestBucket::deleted), sqlite_orm::make_column("bucket_attrs", &DBTestBucket::bucket_attrs), - sqlite_orm::foreign_key(&DBTestBucket::owner_id).references(&DBTestUser::user_id)), - sqlite_orm::make_table(std::string(OBJECTS_TABLE), - sqlite_orm::make_column("object_id", &DBTestObject::object_id, sqlite_orm::primary_key()), - sqlite_orm::make_column("bucket_id", &DBTestObject::bucket_id), - sqlite_orm::make_column("name", &DBTestObject::name), - sqlite_orm::make_column("size", &DBTestObject::size), - sqlite_orm::make_column("etag", &DBTestObject::etag), - sqlite_orm::make_column("mtime", &DBTestObject::mtime), - sqlite_orm::make_column("set_mtime", &DBTestObject::set_mtime), - sqlite_orm::make_column("delete_at_time", &DBTestObject::delete_at_time), - sqlite_orm::foreign_key(&DBTestObject::bucket_id).references(&DBTestBucket::bucket_id)), - sqlite_orm::make_table(std::string(VERSIONED_OBJECTS_TABLE), - sqlite_orm::make_column("id", &DBTestVersionedObject::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key()), - sqlite_orm::make_column("object_id", &DBTestVersionedObject::object_id), + sqlite_orm::make_column("object_lock", &DBTestBucket::object_lock), + sqlite_orm::foreign_key(&DBTestBucket::owner_id) + .references(&DBTestUser::user_id) + ), + sqlite_orm::make_table( + std::string(OBJECTS_TABLE), + sqlite_orm::make_column( + "uuid", &DBOPTestObjectInfo::uuid, sqlite_orm::primary_key() + ), + sqlite_orm::make_column("bucket_id", &DBOPTestObjectInfo::bucket_id), + sqlite_orm::make_column("name", &DBOPTestObjectInfo::name), + sqlite_orm::foreign_key(&DBOPTestObjectInfo::bucket_id) + .references(&DBTestBucket::bucket_id) + ), + sqlite_orm::make_table( + std::string(VERSIONED_OBJECTS_TABLE), + sqlite_orm::make_column( + "id", &DBTestVersionedObject::id, sqlite_orm::autoincrement(), + sqlite_orm::primary_key() + ), + sqlite_orm::make_column( + "object_id", &DBTestVersionedObject::object_id + ), sqlite_orm::make_column("checksum", &DBTestVersionedObject::checksum), - sqlite_orm::make_column("deletion_time", &DBTestVersionedObject::deletion_time), sqlite_orm::make_column("size", &DBTestVersionedObject::size), - sqlite_orm::make_column("creation_time", &DBTestVersionedObject::creation_time), - sqlite_orm::make_column("object_state", &DBTestVersionedObject::object_state), - sqlite_orm::make_column("version_id", &DBTestVersionedObject::version_id), + sqlite_orm::make_column( + "create_time", &DBTestVersionedObject::create_time + ), + sqlite_orm::make_column( + "delete_time", &DBTestVersionedObject::delete_time + ), + sqlite_orm::make_column( + "commit_time", &DBTestVersionedObject::commit_time + ), + sqlite_orm::make_column("mtime", &DBTestVersionedObject::mtime), + sqlite_orm::make_column( + "object_state", &DBTestVersionedObject::object_state + ), + sqlite_orm::make_column( + "version_id", &DBTestVersionedObject::version_id + ), sqlite_orm::make_column("etag", &DBTestVersionedObject::etag), sqlite_orm::make_column("attrs", &DBTestVersionedObject::attrs), - sqlite_orm::foreign_key(&DBTestVersionedObject::object_id).references(&DBTestObject::object_id)), - sqlite_orm::make_table(std::string(ACCESS_KEYS), - sqlite_orm::make_column("id", &DBAccessKey::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key()), - sqlite_orm::make_column("access_key", &DBAccessKey::access_key), - sqlite_orm::make_column("user_id", &DBAccessKey::user_id), - sqlite_orm::foreign_key(&DBAccessKey::user_id).references(&DBTestUser::user_id)) + sqlite_orm::make_column( + "version_type", &DBTestVersionedObject::version_type + ), + sqlite_orm::foreign_key(&DBTestVersionedObject::object_id) + .references(&DBOPTestObjectInfo::uuid) + ), + sqlite_orm::make_table( + std::string(ACCESS_KEYS), + sqlite_orm::make_column( + "id", &DBTestAccessKey::id, sqlite_orm::autoincrement(), + sqlite_orm::primary_key() + ), + sqlite_orm::make_column("access_key", &DBTestAccessKey::access_key), + sqlite_orm::make_column("user_id", &DBTestAccessKey::user_id), + sqlite_orm::foreign_key(&DBTestAccessKey::user_id) + .references(&DBTestUser::user_id) + ), + sqlite_orm::make_table( + std::string(LC_HEAD_TABLE), + sqlite_orm::make_column( + "lc_index", &DBOPTestLCHead::lc_index, sqlite_orm::primary_key() + ), + sqlite_orm::make_column("marker", &DBOPTestLCHead::marker), + sqlite_orm::make_column("start_date", &DBOPTestLCHead::start_date) + ), + sqlite_orm::make_table( + std::string(LC_ENTRIES_TABLE), + sqlite_orm::make_column("lc_index", &DBOPTestLCEntry::lc_index), + sqlite_orm::make_column("bucket_name", &DBOPTestLCEntry::bucket_name), + sqlite_orm::make_column("start_time", &DBOPTestLCEntry::start_time), + sqlite_orm::make_column("status", &DBOPTestLCEntry::status), + sqlite_orm::primary_key( + &DBOPTestLCEntry::lc_index, &DBOPTestLCEntry::bucket_name + ) + ) ); } @@ -178,19 +263,20 @@ struct TestDB { TestStorage storage; DBTestUser test_user; DBTestBucket test_bucket; - DBTestObject test_object; + DBOPTestObjectInfo test_object; DBTestVersionedObject test_version; - explicit TestDB(const std::string & db_full_path) - : storage(_make_test_storage(db_full_path)) - { + explicit TestDB(const std::string& db_full_path) + : storage(_make_test_storage(db_full_path)) { storage.on_open = [](sqlite3* db) { sqlite3_extended_result_codes(db, 1); sqlite3_busy_timeout(db, 10000); - sqlite3_exec(db, - "PRAGMA journal_mode=WAL;PRAGMA synchronous=normal;" - "PRAGMA temp_store = memory;PRAGMA mmap_size = 30000000000;", - 0, 0, 0); + sqlite3_exec( + db, + "PRAGMA journal_mode=WAL;PRAGMA synchronous=normal;" + "PRAGMA temp_store = memory;PRAGMA mmap_size = 30000000000;", + 0, 0, 0 + ); }; storage.open_forever(); storage.busy_timeout(5000); @@ -211,9 +297,11 @@ struct TestDB { return bucket; } - DBTestObject get_test_object() { - DBTestObject object; - object.object_id = "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; + DBOPTestObjectInfo get_test_object() { + DBOPTestObjectInfo object; + uuid_d uuid_val; + uuid_val.parse("9f06d9d3-307f-4c98-865b-cd3b087acc4f"); + object.uuid = uuid_val; object.bucket_id = "bucket1_id"; object.name = "object_name"; return object; @@ -224,41 +312,44 @@ struct TestDB { version.id = 1; version.object_id = "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; version.checksum = "checksum1"; - encode_blob(ceph::real_clock::now(), version.deletion_time); + version.delete_time = ceph::real_clock::now(); version.size = rand(); - encode_blob(ceph::real_clock::now(), version.creation_time); - version.object_state = 2; + version.create_time = ceph::real_clock::now(); + version.object_state = rgw::sal::sfs::ObjectState::COMMITTED; version.version_id = "version_id_1"; return version; } - bool compareUser(const DBTestUser & user1, const DBTestUser & user2) { + bool compareUser(const DBTestUser& user1, const DBTestUser& user2) { if (user1.user_id != user2.user_id) return false; return true; } - bool compareBucket(const DBTestBucket & bucket1, const DBTestBucket & bucket2) { + bool compareBucket(const DBTestBucket& bucket1, const DBTestBucket& bucket2) { if (bucket1.bucket_id != bucket2.bucket_id) return false; if (bucket1.bucket_name != bucket2.bucket_name) return false; if (bucket1.owner_id != bucket2.owner_id) return false; return true; } - bool compareObject(const DBTestObject & obj1, const DBTestObject & obj2) { - if (obj1.object_id != obj2.object_id) return false; + bool compareObject( + const DBOPTestObjectInfo& obj1, const DBOPTestObjectInfo& obj2 + ) { + if (obj1.uuid != obj2.uuid) return false; if (obj1.bucket_id != obj2.bucket_id) return false; if (obj1.name != obj2.name) return false; return true; } - bool compareVersion(const DBTestVersionedObject & v1, - const DBTestVersionedObject & v2) { + bool compareVersion( + const DBTestVersionedObject& v1, const DBTestVersionedObject& v2 + ) { if (v1.version_id != v2.version_id) return false; if (v1.object_id != v2.object_id) return false; if (v1.checksum != v2.checksum) return false; - if (v1.deletion_time != v2.deletion_time) return false; + if (v1.delete_time != v2.delete_time) return false; if (v1.size != v2.size) return false; - if (v1.creation_time != v2.creation_time) return false; + if (v1.create_time != v2.create_time) return false; if (v1.object_state != v2.object_state) return false; if (v1.version_id != v2.version_id) return false; return true; @@ -285,7 +376,7 @@ struct TestDB { auto users = storage.get_all(); if (users.size() != 1) return false; - auto objs = storage.get_all(); + auto objs = storage.get_all(); if (objs.size() != 1) return false; auto versions = storage.get_all(); @@ -299,7 +390,7 @@ struct TestDB { if (!user) return false; if (!compareUser(*user, test_user)) return false; - auto object = storage.get_pointer(test_object.object_id); + auto object = storage.get_pointer(test_object.uuid); if (!object) return false; if (!compareObject(*object, test_object)) return false; @@ -309,7 +400,6 @@ struct TestDB { return true; } - }; -} // namespace rgw::test::metadata::new_columns_added +} // namespace rgw::test::metadata::optional_columns_added diff --git a/src/test/rgw/sfs/test_rgw_sfs_gc.cc b/src/test/rgw/sfs/test_rgw_sfs_gc.cc index 73617b8b163b4..2f06e6ac27255 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_gc.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_gc.cc @@ -140,7 +140,7 @@ class TestSFSGC : public ::testing::Test { DBOPVersionedObjectInfo db_version; db_version.id = version; db_version.object_id = object->path.get_uuid(); - db_version.object_state = rgw::sal::ObjectState::COMMITTED; + db_version.object_state = rgw::sal::sfs::ObjectState::COMMITTED; db_version.version_id = std::to_string(version); db_versioned_objects.insert_versioned_object(db_version); } @@ -152,7 +152,7 @@ class TestSFSGC : public ::testing::Test { auto last_version = db_versioned_objects.get_last_versioned_object( object->path.get_uuid()); ASSERT_TRUE(last_version.has_value()); - last_version->object_state = rgw::sal::ObjectState::DELETED; + last_version->object_state = rgw::sal::sfs::ObjectState::DELETED; last_version->version_id.append("_next_"); last_version->version_id.append(std::to_string(last_version->id)); db_versioned_objects.insert_versioned_object(*last_version); diff --git a/src/test/rgw/sfs/test_rgw_sfs_metadata_compatibility.cc b/src/test/rgw/sfs/test_rgw_sfs_metadata_compatibility.cc index 994db78ff4d6f..58c6174d0c173 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_metadata_compatibility.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_metadata_compatibility.cc @@ -3,21 +3,20 @@ #include "common/ceph_context.h" #include "common/ceph_time.h" - -#include "rgw/rgw_sal_sfs.h" - -#include "rgw/driver/sfs/sqlite/dbconn.h" #include "rgw/driver/sfs/sqlite/conversion_utils.h" +#include "rgw/driver/sfs/sqlite/dbconn.h" +#include "rgw/rgw_sal_sfs.h" // test cases -#include "compatibility_test_cases/columns_deleted.h" -#include "compatibility_test_cases/columns_added.h" -#include "compatibility_test_cases/optional_columns_added.h" +#include #include -#include #include +#include "compatibility_test_cases/columns_added.h" +#include "compatibility_test_cases/columns_deleted.h" +#include "compatibility_test_cases/optional_columns_added.h" + /* HINT s3gw.db will create here: /tmp/rgw_sfs_tests @@ -30,9 +29,8 @@ namespace metadata_tests = rgw::test::metadata; const static std::string TEST_DIR = "rgw_sfs_tests"; - class TestSFSMetadataCompatibility : public ::testing::Test { -protected: + protected: void SetUp() override { fs::current_path(fs::temp_directory_path()); fs::create_directory(TEST_DIR); @@ -43,22 +41,19 @@ class TestSFSMetadataCompatibility : public ::testing::Test { fs::remove_all(TEST_DIR); } -public: + public: static std::string getTestDir() { auto test_dir = fs::temp_directory_path() / TEST_DIR; return test_dir.string(); } - static fs::path getDBFullPath(const std::string & base_dir) { + static fs::path getDBFullPath(const std::string& base_dir) { auto db_full_name = "s3gw.db"; - auto db_full_path = fs::path(base_dir) / db_full_name; + auto db_full_path = fs::path(base_dir) / db_full_name; return db_full_path; } - static fs::path getDBFullPath() { - return getDBFullPath(getTestDir()); - } - + static fs::path getDBFullPath() { return getDBFullPath(getTestDir()); } }; TEST_F(TestSFSMetadataCompatibility, ColumnsAdded) { @@ -66,23 +61,28 @@ TEST_F(TestSFSMetadataCompatibility, ColumnsAdded) { // as the columns added have no default value and they cannot be empty it // will throw an exception. auto test_db = - std::make_shared(getDBFullPath()); + std::make_shared(getDBFullPath()); test_db->addData(); auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); - ASSERT_THROW(new rgw::sal::SFStore(ceph_context.get(), getTestDir()), - sqlite_sync_exception); + ASSERT_THROW( + new rgw::sal::SFStore(ceph_context.get(), getTestDir()), + sqlite_sync_exception + ); try { new rgw::sal::SFStore(ceph_context.get(), getTestDir()); - } catch (const std::exception & e) { + } catch (const std::exception& e) { // check the exception message // this time it doesn't point the tables because it tries to drop the // buckets table and as the objects table has a foreign key to buckets it // throws a foreign key error. - EXPECT_STREQ("ERROR ACCESSING SFS METADATA. Metadata database might be corrupted or is no longer compatible", - e.what()); + EXPECT_STREQ( + "ERROR ACCESSING SFS METADATA. Metadata database might be corrupted or " + "is no longer compatible", + e.what() + ); } // check that original data was not altered EXPECT_TRUE(test_db->checkDataExists()); @@ -92,7 +92,9 @@ TEST_F(TestSFSMetadataCompatibility, OptionalColumnsAdded) { // checks adding extra columns. // as the columns added are optional no error should be thrown auto test_db = - std::make_shared(getDBFullPath()); + std::make_shared( + getDBFullPath() + ); test_db->addData(); auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); @@ -108,21 +110,27 @@ TEST_F(TestSFSMetadataCompatibility, ColumnsDeleted) { // when the SFS database tries to sync it will detect columns removed // in its schema auto test_db = - std::make_shared(getDBFullPath()); + std::make_shared(getDBFullPath() + ); test_db->addData(); auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); // check that it throws a sqlite_sync_exception - ASSERT_THROW(new rgw::sal::SFStore(ceph_context.get(), getTestDir()), - sqlite_sync_exception); + ASSERT_THROW( + new rgw::sal::SFStore(ceph_context.get(), getTestDir()), + sqlite_sync_exception + ); try { new rgw::sal::SFStore(ceph_context.get(), getTestDir()); - } catch (const std::exception & e) { + } catch (const std::exception& e) { // check the exception message - EXPECT_STREQ("ERROR ACCESSING SFS METADATA. Tables: [ objects versioned_objects ] are no longer compatible.", - e.what()); + EXPECT_STREQ( + "ERROR ACCESSING SFS METADATA. Tables: [ objects versioned_objects ] " + "are no longer compatible.", + e.what() + ); } // check that original data was not altered EXPECT_TRUE(test_db->checkDataExists()); diff --git a/src/test/rgw/sfs/test_rgw_sfs_sfs_bucket.cc b/src/test/rgw/sfs/test_rgw_sfs_sfs_bucket.cc index 7f96517e6aa8f..f8e6fdbda2c99 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_sfs_bucket.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_sfs_bucket.cc @@ -1,18 +1,18 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +#include + +#include +#include + #include "common/ceph_context.h" +#include "rgw/driver/sfs/sqlite/buckets/bucket_conversions.h" #include "rgw/driver/sfs/sqlite/dbconn.h" #include "rgw/driver/sfs/sqlite/sqlite_buckets.h" -#include "rgw/driver/sfs/sqlite/buckets/bucket_conversions.h" #include "rgw/driver/sfs/sqlite/sqlite_users.h" - #include "rgw/rgw_sal_sfs.h" -#include -#include -#include - /* HINT s3gw.db will create here: /tmp/rgw_sfs_tests @@ -24,7 +24,7 @@ namespace fs = std::filesystem; const static std::string TEST_DIR = "rgw_sfs_tests"; class TestSFSBucket : public ::testing::Test { -protected: + protected: void SetUp() override { fs::current_path(fs::temp_directory_path()); fs::create_directory(TEST_DIR); @@ -40,17 +40,15 @@ class TestSFSBucket : public ::testing::Test { return test_dir.string(); } - fs::path getDBFullPath(const std::string & base_dir) const { + fs::path getDBFullPath(const std::string& base_dir) const { auto db_full_name = "s3gw.db"; - auto db_full_path = fs::path(base_dir) / db_full_name; + auto db_full_path = fs::path(base_dir) / db_full_name; return db_full_path; } - fs::path getDBFullPath() const { - return getDBFullPath(getTestDir()); - } + fs::path getDBFullPath() const { return getDBFullPath(getTestDir()); } - void createUser(const std::string & username, DBConnRef conn) { + void createUser(const std::string& username, DBConnRef conn) { SQLiteUsers users(conn); DBOPUserInfo user; user.uinfo.user_id.id = username; @@ -59,11 +57,11 @@ class TestSFSBucket : public ::testing::Test { } std::shared_ptr createTestObject( - const std::string & bucket_id, - const std::string & name, - DBConnRef conn) { + const std::string& bucket_id, const std::string& name, DBConnRef conn + ) { auto object = std::shared_ptr( - rgw::sal::sfs::Object::create_for_testing(name)); + rgw::sal::sfs::Object::create_for_testing(name) + ); SQLiteObjects db_objects(conn); DBOPObjectInfo db_object; db_object.uuid = object->path.get_uuid(); @@ -73,9 +71,9 @@ class TestSFSBucket : public ::testing::Test { return object; } - void createTestBucket(const std::string & bucket_id, - const std::string & user_id, - DBConnRef conn) { + void createTestBucket( + const std::string& bucket_id, const std::string& user_id, DBConnRef conn + ) { SQLiteBuckets db_buckets(conn); DBOPBucketInfo bucket; bucket.binfo.bucket.name = bucket_id + "_name"; @@ -85,21 +83,22 @@ class TestSFSBucket : public ::testing::Test { db_buckets.store_bucket(bucket); } - void createTestObjectVersion(std::shared_ptr & object, - uint version, - DBConnRef conn) { + void createTestObjectVersion( + std::shared_ptr& object, uint version, + DBConnRef conn + ) { object->version_id = version; SQLiteVersionedObjects db_versioned_objects(conn); DBOPVersionedObjectInfo db_version; db_version.id = version; db_version.object_id = object->path.get_uuid(); - db_version.object_state = rgw::sal::ObjectState::COMMITTED; + db_version.object_state = rgw::sal::sfs::ObjectState::COMMITTED; db_version.version_id = std::to_string(version); db_versioned_objects.insert_versioned_object(db_version); } }; -RGWAccessControlPolicy get_aclp_default(){ +RGWAccessControlPolicy get_aclp_default() { RGWAccessControlPolicy aclp; rgw_user aclu("usr_id"); aclp.get_acl().create_default(aclu, "usr_id"); @@ -110,10 +109,10 @@ RGWAccessControlPolicy get_aclp_default(){ return aclp; } -RGWAccessControlPolicy get_aclp_1(){ +RGWAccessControlPolicy get_aclp_1() { RGWAccessControlPolicy aclp; rgw_user aclu("usr_id"); - RGWAccessControlList &acl = aclp.get_acl(); + RGWAccessControlList& acl = aclp.get_acl(); ACLGrant aclg; rgw_user gusr("usr_id_2"); aclg.set_canon(gusr, "usr_id_2", (RGW_PERM_READ_OBJS | RGW_PERM_WRITE_OBJS)); @@ -125,14 +124,15 @@ RGWAccessControlPolicy get_aclp_1(){ return aclp; } -RGWBucketInfo get_binfo(){ +RGWBucketInfo get_binfo() { RGWBucketInfo arg_info; return arg_info; } -void compareListEntry(const rgw_bucket_dir_entry & entry, - std::shared_ptr object, - const std::string & username) { +void compareListEntry( + const rgw_bucket_dir_entry& entry, + std::shared_ptr object, const std::string& username +) { EXPECT_EQ(entry.key.name, object->name); EXPECT_EQ(entry.meta.etag, object->get_meta().etag); EXPECT_EQ(entry.meta.mtime, object->get_meta().mtime); @@ -172,31 +172,37 @@ TEST_F(TestSFSBucket, UserCreateBucketCheckGotFromCreate) { std::unique_ptr bucket_from_create; - EXPECT_EQ(user->create_bucket(&ndp, //dpp - arg_bucket, //b - "zg1", //zonegroup_id - arg_pl_rule, //placement_rule - arg_swift_ver_location, //swift_ver_location - &arg_quota_info, //pquota_info - arg_aclp, //policy - arg_attrs, //attrs - arg_info, //info - arg_objv, //ep_objv - false, //exclusive - false, //obj_lock_enabled - &existed, //existed - arg_req_info, //req_info - &bucket_from_create, //bucket - null_yield //optional_yield - ), - 0); + EXPECT_EQ( + user->create_bucket( + &ndp, //dpp + arg_bucket, //b + "zg1", //zonegroup_id + arg_pl_rule, //placement_rule + arg_swift_ver_location, //swift_ver_location + &arg_quota_info, //pquota_info + arg_aclp, //policy + arg_attrs, //attrs + arg_info, //info + arg_objv, //ep_objv + false, //exclusive + false, //obj_lock_enabled + &existed, //existed + arg_req_info, //req_info + &bucket_from_create, //bucket + null_yield //optional_yield + ), + 0 + ); EXPECT_EQ(existed, false); EXPECT_EQ(bucket_from_create->get_tenant(), "t_id"); EXPECT_EQ(bucket_from_create->get_name(), "b_name"); EXPECT_EQ(bucket_from_create->get_placement_rule().name, "default"); EXPECT_EQ(bucket_from_create->get_placement_rule().storage_class, "STANDARD"); - EXPECT_NE(bucket_from_create->get_attrs().find(RGW_ATTR_ACL), bucket_from_create->get_attrs().end()); + EXPECT_NE( + bucket_from_create->get_attrs().find(RGW_ATTR_ACL), + bucket_from_create->get_attrs().end() + ); EXPECT_FALSE(arg_info.flags & BUCKET_VERSIONED); EXPECT_FALSE(arg_info.flags & BUCKET_OBJ_LOCK_ENABLED); @@ -213,7 +219,6 @@ TEST_F(TestSFSBucket, UserCreateBucketCheckGotFromCreate) { //@warning this triggers segfault //EXPECT_EQ(bucket_from_create->get_owner()->get_id().id, "usr_id"); - } TEST_F(TestSFSBucket, UserCreateBucketCheckGotFromStore) { @@ -248,36 +253,42 @@ TEST_F(TestSFSBucket, UserCreateBucketCheckGotFromStore) { std::unique_ptr bucket_from_create; - EXPECT_EQ(user->create_bucket(&ndp, //dpp - arg_bucket, //b - "zg1", //zonegroup_id - arg_pl_rule, //placement_rule - arg_swift_ver_location, //swift_ver_location - &arg_quota_info, //pquota_info - arg_aclp, //policy - arg_attrs, //attrs - arg_info, //info - arg_objv, //ep_objv - false, //exclusive - false, //obj_lock_enabled - &existed, //existed - arg_req_info, //req_info - &bucket_from_create, //bucket - null_yield //optional_yield - ), - 0); + EXPECT_EQ( + user->create_bucket( + &ndp, //dpp + arg_bucket, //b + "zg1", //zonegroup_id + arg_pl_rule, //placement_rule + arg_swift_ver_location, //swift_ver_location + &arg_quota_info, //pquota_info + arg_aclp, //policy + arg_attrs, //attrs + arg_info, //info + arg_objv, //ep_objv + false, //exclusive + false, //obj_lock_enabled + &existed, //existed + arg_req_info, //req_info + &bucket_from_create, //bucket + null_yield //optional_yield + ), + 0 + ); std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); EXPECT_EQ(*bucket_from_store, *bucket_from_create); - EXPECT_NE(bucket_from_store->get_attrs().find(RGW_ATTR_ACL), bucket_from_store->get_attrs().end()); + EXPECT_NE( + bucket_from_store->get_attrs().find(RGW_ATTR_ACL), + bucket_from_store->get_attrs().end() + ); auto acl_bl_it = bucket_from_store->get_attrs().find(RGW_ATTR_ACL); { @@ -322,52 +333,52 @@ TEST_F(TestSFSBucket, BucketSetAcl) { std::unique_ptr bucket_from_create; - EXPECT_EQ(user->create_bucket(&ndp, //dpp - arg_bucket, //b - "zg1", //zonegroup_id - arg_pl_rule, //placement_rule - arg_swift_ver_location, //swift_ver_location - &arg_quota_info, //pquota_info - arg_aclp, //policy - arg_attrs, //attrs - arg_info, //info - arg_objv, //ep_objv - false, //exclusive - false, //obj_lock_enabled - &existed, //existed - arg_req_info, //req_info - &bucket_from_create, //bucket - null_yield //optional_yield - ), - 0); + EXPECT_EQ( + user->create_bucket( + &ndp, //dpp + arg_bucket, //b + "zg1", //zonegroup_id + arg_pl_rule, //placement_rule + arg_swift_ver_location, //swift_ver_location + &arg_quota_info, //pquota_info + arg_aclp, //policy + arg_attrs, //attrs + arg_info, //info + arg_objv, //ep_objv + false, //exclusive + false, //obj_lock_enabled + &existed, //existed + arg_req_info, //req_info + &bucket_from_create, //bucket + null_yield //optional_yield + ), + 0 + ); std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); RGWAccessControlPolicy arg_aclp_1 = get_aclp_1(); - EXPECT_EQ(bucket_from_store->set_acl(&ndp, - arg_aclp_1, - null_yield), - 0); + EXPECT_EQ(bucket_from_store->set_acl(&ndp, arg_aclp_1, null_yield), 0); EXPECT_NE(bucket_from_store->get_acl(), bucket_from_create->get_acl()); EXPECT_EQ(bucket_from_store->get_acl(), get_aclp_1()); std::unique_ptr bucket_from_store_1; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store_1, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store_1, null_yield + ), + 0 + ); EXPECT_EQ(bucket_from_store->get_acl(), bucket_from_store_1->get_acl()); } @@ -404,33 +415,36 @@ TEST_F(TestSFSBucket, BucketMergeAndStoreAttrs) { std::unique_ptr bucket_from_create; - EXPECT_EQ(user->create_bucket(&ndp, //dpp - arg_bucket, //b - "zg1", //zonegroup_id - arg_pl_rule, //placement_rule - arg_swift_ver_location, //swift_ver_location - &arg_quota_info, //pquota_info - arg_aclp, //policy - arg_attrs, //attrs - arg_info, //info - arg_objv, //ep_objv - false, //exclusive - false, //obj_lock_enabled - &existed, //existed - arg_req_info, //req_info - &bucket_from_create, //bucket - null_yield //optional_yield - ), - 0); + EXPECT_EQ( + user->create_bucket( + &ndp, //dpp + arg_bucket, //b + "zg1", //zonegroup_id + arg_pl_rule, //placement_rule + arg_swift_ver_location, //swift_ver_location + &arg_quota_info, //pquota_info + arg_aclp, //policy + arg_attrs, //attrs + arg_info, //info + arg_objv, //ep_objv + false, //exclusive + false, //obj_lock_enabled + &existed, //existed + arg_req_info, //req_info + &bucket_from_create, //bucket + null_yield //optional_yield + ), + 0 + ); std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); rgw::sal::Attrs new_attrs; RGWAccessControlPolicy arg_aclp_1 = get_aclp_1(); @@ -440,10 +454,9 @@ TEST_F(TestSFSBucket, BucketMergeAndStoreAttrs) { new_attrs[RGW_ATTR_ACL] = acl_bl; } - EXPECT_EQ(bucket_from_store->merge_and_store_attrs(&ndp, - new_attrs, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->merge_and_store_attrs(&ndp, new_attrs, null_yield), 0 + ); EXPECT_EQ(bucket_from_store->get_attrs(), new_attrs); EXPECT_NE(bucket_from_store->get_acl(), bucket_from_create->get_acl()); @@ -451,12 +464,12 @@ TEST_F(TestSFSBucket, BucketMergeAndStoreAttrs) { std::unique_ptr bucket_from_store_1; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store_1, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store_1, null_yield + ), + 0 + ); EXPECT_EQ(bucket_from_store_1->get_attrs(), new_attrs); EXPECT_EQ(bucket_from_store->get_acl(), bucket_from_store_1->get_acl()); @@ -494,33 +507,36 @@ TEST_F(TestSFSBucket, DeleteBucket) { std::unique_ptr bucket_from_create; - EXPECT_EQ(user->create_bucket(&ndp, //dpp - arg_bucket, //b - "zg1", //zonegroup_id - arg_pl_rule, //placement_rule - arg_swift_ver_location, //swift_ver_location - &arg_quota_info, //pquota_info - arg_aclp, //policy - arg_attrs, //attrs - arg_info, //info - arg_objv, //ep_objv - false, //exclusive - false, //obj_lock_enabled - &existed, //existed - arg_req_info, //req_info - &bucket_from_create, //bucket - null_yield //optional_yield - ), - 0); + EXPECT_EQ( + user->create_bucket( + &ndp, //dpp + arg_bucket, //b + "zg1", //zonegroup_id + arg_pl_rule, //placement_rule + arg_swift_ver_location, //swift_ver_location + &arg_quota_info, //pquota_info + arg_aclp, //policy + arg_attrs, //attrs + arg_info, //info + arg_objv, //ep_objv + false, //exclusive + false, //obj_lock_enabled + &existed, //existed + arg_req_info, //req_info + &bucket_from_create, //bucket + null_yield //optional_yield + ), + 0 + ); std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); EXPECT_EQ(*bucket_from_store, *bucket_from_create); @@ -532,20 +548,18 @@ TEST_F(TestSFSBucket, DeleteBucket) { ASSERT_TRUE(b_metadata.has_value()); EXPECT_FALSE(b_metadata->deleted); - EXPECT_EQ(bucket_from_store->remove_bucket(&ndp, - true, - false, - nullptr, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->remove_bucket(&ndp, true, false, nullptr, null_yield), + 0 + ); // after removing bucket should not be available anymore - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - -ENOENT); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + -ENOENT + ); // Also verify in metadata that the bucket has the deleted marker b_metadata = db_buckets->get_bucket(bucket_from_create->get_bucket_id()); @@ -554,31 +568,34 @@ TEST_F(TestSFSBucket, DeleteBucket) { // now create the bucket again (should be ok, but bucket_id should differ) auto prev_bucket_id = bucket_from_create->get_bucket_id(); - EXPECT_EQ(user->create_bucket(&ndp, //dpp - arg_bucket, //b - "zg1", //zonegroup_id - arg_pl_rule, //placement_rule - arg_swift_ver_location, //swift_ver_location - &arg_quota_info, //pquota_info - arg_aclp, //policy - arg_attrs, //attrs - arg_info, //info - arg_objv, //ep_objv - false, //exclusive - false, //obj_lock_enabled - &existed, //existed - arg_req_info, //req_info - &bucket_from_create, //bucket - null_yield //optional_yield - ), - 0); - - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + user->create_bucket( + &ndp, //dpp + arg_bucket, //b + "zg1", //zonegroup_id + arg_pl_rule, //placement_rule + arg_swift_ver_location, //swift_ver_location + &arg_quota_info, //pquota_info + arg_aclp, //policy + arg_attrs, //attrs + arg_info, //info + arg_objv, //ep_objv + false, //exclusive + false, //obj_lock_enabled + &existed, //existed + arg_req_info, //req_info + &bucket_from_create, //bucket + null_yield //optional_yield + ), + 0 + ); + + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); EXPECT_EQ(*bucket_from_store, *bucket_from_create); EXPECT_NE(prev_bucket_id, bucket_from_create->get_bucket_id()); @@ -593,7 +610,6 @@ TEST_F(TestSFSBucket, DeleteBucket) { ASSERT_EQ(metadata_same_name.size(), 2); ASSERT_TRUE(metadata_same_name[0].deleted); ASSERT_FALSE(metadata_same_name[1].deleted); - } TEST_F(TestSFSBucket, TestListObjectsAndVersions) { @@ -640,12 +656,12 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { arg_info.bucket.name = "test_bucket_name"; arg_info.bucket.bucket_id = "test_bucket"; std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); ASSERT_NE(bucket_from_store, nullptr); @@ -655,21 +671,17 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { params.prefix = ""; rgw::sal::Bucket::ListResults results; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results, - null_yield), - 0); + EXPECT_EQ(bucket_from_store->list(&ndp, params, 0, results, null_yield), 0); - std::map> expected_objects; + std::map> + expected_objects; expected_objects[object1->name] = object1; expected_objects[object2->name] = object2; expected_objects[object3->name] = object3; expected_objects[object4->name] = object4; auto nb_found_objects = 0; EXPECT_EQ(expected_objects.size(), results.objs.size()); - for (auto & ret_obj : results.objs) { + for (auto& ret_obj : results.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -682,12 +694,12 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { // list with 'folder/' prefix params.prefix = "folder/"; rgw::sal::Bucket::ListResults results_folder_prefix; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_folder_prefix, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_folder_prefix, null_yield + ), + 0 + ); expected_objects.clear(); expected_objects[object1->name] = object1; @@ -695,7 +707,7 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { expected_objects[object3->name] = object3; nb_found_objects = 0; EXPECT_EQ(expected_objects.size(), results_folder_prefix.objs.size()); - for (auto & ret_obj : results_folder_prefix.objs) { + for (auto& ret_obj : results_folder_prefix.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -708,18 +720,15 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { // list with 'ob' prefix params.prefix = "ob"; rgw::sal::Bucket::ListResults results_ob_prefix; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_ob_prefix, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list(&ndp, params, 0, results_ob_prefix, null_yield), 0 + ); expected_objects.clear(); expected_objects[object4->name] = object4; nb_found_objects = 0; EXPECT_EQ(expected_objects.size(), results_ob_prefix.objs.size()); - for (auto & ret_obj : results_ob_prefix.objs) { + for (auto& ret_obj : results_ob_prefix.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -729,19 +738,15 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { // ensure all objects expected were found EXPECT_EQ(expected_objects.size(), nb_found_objects); - // list all versions // list with empty prefix params.prefix = ""; params.list_versions = true; rgw::sal::Bucket::ListResults results_versions; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_versions, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list(&ndp, params, 0, results_versions, null_yield), 0 + ); // we'll find 4 objects with 2 versions each (8 entries) EXPECT_EQ(8, results_versions.objs.size()); expected_objects.clear(); @@ -751,7 +756,7 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { expected_objects[object4->name] = object4; nb_found_objects = 0; EXPECT_EQ(expected_objects.size(), results.objs.size()); - for (auto & ret_obj : results_versions.objs) { + for (auto& ret_obj : results_versions.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -765,12 +770,12 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { params.prefix = "folder/"; params.list_versions = true; rgw::sal::Bucket::ListResults results_versions_folder_prefix; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_versions_folder_prefix, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_versions_folder_prefix, null_yield + ), + 0 + ); expected_objects.clear(); expected_objects[object1->name] = object1; @@ -779,7 +784,7 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { nb_found_objects = 0; // 3 objects match the prefix with 2 versions each EXPECT_EQ(6, results_versions_folder_prefix.objs.size()); - for (auto & ret_obj : results_versions_folder_prefix.objs) { + for (auto& ret_obj : results_versions_folder_prefix.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -789,23 +794,24 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { // ensure all objects expected were found EXPECT_EQ(expected_objects.size() * 2, nb_found_objects); - // list versions with 'ob' prefix params.prefix = "ob"; params.list_versions = true; rgw::sal::Bucket::ListResults results_versions_ob_prefix; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_versions_ob_prefix, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_versions_ob_prefix, null_yield + ), + 0 + ); expected_objects.clear(); expected_objects[object4->name] = object4; nb_found_objects = 0; - EXPECT_EQ(expected_objects.size() * 2, results_versions_ob_prefix.objs.size()); - for (auto & ret_obj : results_versions_ob_prefix.objs) { + EXPECT_EQ( + expected_objects.size() * 2, results_versions_ob_prefix.objs.size() + ); + for (auto& ret_obj : results_versions_ob_prefix.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -817,7 +823,6 @@ TEST_F(TestSFSBucket, TestListObjectsAndVersions) { } TEST_F(TestSFSBucket, TestListObjectsDelimiter) { - auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); auto store = new rgw::sal::SFStore(ceph_context.get(), getTestDir()); @@ -843,15 +848,19 @@ TEST_F(TestSFSBucket, TestListObjectsDelimiter) { createTestObjectVersion(object1, version_id++, store->db_conn); createTestObjectVersion(object1, version_id++, store->db_conn); - auto object2 = createTestObject("test_bucket", "directory/directory/", store->db_conn); + auto object2 = + createTestObject("test_bucket", "directory/directory/", store->db_conn); createTestObjectVersion(object2, version_id++, store->db_conn); createTestObjectVersion(object2, version_id++, store->db_conn); - auto object3 = createTestObject("test_bucket", "directory/directory/file", store->db_conn); + auto object3 = createTestObject( + "test_bucket", "directory/directory/file", store->db_conn + ); createTestObjectVersion(object3, version_id++, store->db_conn); createTestObjectVersion(object3, version_id++, store->db_conn); - auto object4 = createTestObject("test_bucket", "directory/file", store->db_conn); + auto object4 = + createTestObject("test_bucket", "directory/file", store->db_conn); createTestObjectVersion(object4, version_id++, store->db_conn); createTestObjectVersion(object4, version_id++, store->db_conn); @@ -870,12 +879,12 @@ TEST_F(TestSFSBucket, TestListObjectsDelimiter) { arg_info.bucket.name = "test_bucket_name"; arg_info.bucket.bucket_id = "test_bucket"; std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); ASSERT_NE(bucket_from_store, nullptr); @@ -886,15 +895,11 @@ TEST_F(TestSFSBucket, TestListObjectsDelimiter) { params.delim = ""; rgw::sal::Bucket::ListResults results; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results, - null_yield), - 0); + EXPECT_EQ(bucket_from_store->list(&ndp, params, 0, results, null_yield), 0); // we expect to get all the objects - std::map> expected_objects; + std::map> + expected_objects; expected_objects[object1->name] = object1; expected_objects[object2->name] = object2; expected_objects[object3->name] = object3; @@ -902,7 +907,7 @@ TEST_F(TestSFSBucket, TestListObjectsDelimiter) { expected_objects[object5->name] = object5; auto nb_found_objects = 0; EXPECT_EQ(expected_objects.size(), results.objs.size()); - for (auto & ret_obj : results.objs) { + for (auto& ret_obj : results.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -919,41 +924,43 @@ TEST_F(TestSFSBucket, TestListObjectsDelimiter) { params.delim = "i"; rgw::sal::Bucket::ListResults results_delimiter_i; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_i, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list(&ndp, params, 0, results_delimiter_i, null_yield), + 0 + ); // we expect zero objects EXPECT_EQ(results_delimiter_i.objs.size(), 0); // check common_prefixes (should be fi and di) EXPECT_EQ(results_delimiter_i.common_prefixes.size(), 2); - EXPECT_NE(results_delimiter_i.common_prefixes.find("fi"), - results_delimiter_i.common_prefixes.end()); - EXPECT_NE(results_delimiter_i.common_prefixes.find("di"), - results_delimiter_i.common_prefixes.end()); + EXPECT_NE( + results_delimiter_i.common_prefixes.find("fi"), + results_delimiter_i.common_prefixes.end() + ); + EXPECT_NE( + results_delimiter_i.common_prefixes.find("di"), + results_delimiter_i.common_prefixes.end() + ); // use delimiter '/' params.prefix = ""; params.delim = "/"; rgw::sal::Bucket::ListResults results_delimiter_slash; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_slash, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_delimiter_slash, null_yield + ), + 0 + ); // we expect only the "file" oject (the rest are aggregated in common prefix) expected_objects.clear(); expected_objects[object5->name] = object5; nb_found_objects = 0; EXPECT_EQ(expected_objects.size(), results_delimiter_slash.objs.size()); - for (auto & ret_obj : results_delimiter_slash.objs) { + for (auto& ret_obj : results_delimiter_slash.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -965,32 +972,34 @@ TEST_F(TestSFSBucket, TestListObjectsDelimiter) { // check common_prefixes EXPECT_EQ(results_delimiter_slash.common_prefixes.size(), 1); - EXPECT_NE(results_delimiter_slash.common_prefixes.find("directory/"), - results_delimiter_slash.common_prefixes.end()); + EXPECT_NE( + results_delimiter_slash.common_prefixes.find("directory/"), + results_delimiter_slash.common_prefixes.end() + ); // use delimiter '/directory' params.prefix = ""; params.delim = "/directory"; rgw::sal::Bucket::ListResults results_delimiter_directory; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_directory, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_delimiter_directory, null_yield + ), + 0 + ); // we expect // directory/ // directory/file // file expected_objects.clear(); - expected_objects[object1->name] = object1; // directory/ - expected_objects[object4->name] = object4; // directory/file - expected_objects[object5->name] = object5; // file + expected_objects[object1->name] = object1; // directory/ + expected_objects[object4->name] = object4; // directory/file + expected_objects[object5->name] = object5; // file nb_found_objects = 0; EXPECT_EQ(expected_objects.size(), results_delimiter_directory.objs.size()); - for (auto & ret_obj : results_delimiter_directory.objs) { + for (auto& ret_obj : results_delimiter_directory.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -1002,29 +1011,32 @@ TEST_F(TestSFSBucket, TestListObjectsDelimiter) { // check common_prefixes EXPECT_EQ(results_delimiter_directory.common_prefixes.size(), 1); - EXPECT_NE(results_delimiter_directory.common_prefixes.find("directory/directory"), - results_delimiter_directory.common_prefixes.end()); - + EXPECT_NE( + results_delimiter_directory.common_prefixes.find("directory/directory"), + results_delimiter_directory.common_prefixes.end() + ); // use delimiter 'i' and prefix 'd' params.prefix = "d"; params.delim = "i"; rgw::sal::Bucket::ListResults results_delimiter_i_prefix_d; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_i_prefix_d, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_delimiter_i_prefix_d, null_yield + ), + 0 + ); // we expect zero objects EXPECT_EQ(results_delimiter_i_prefix_d.objs.size(), 0); // check common_prefixes (should be fi and di) EXPECT_EQ(results_delimiter_i_prefix_d.common_prefixes.size(), 1); - EXPECT_NE(results_delimiter_i_prefix_d.common_prefixes.find("di"), - results_delimiter_i_prefix_d.common_prefixes.end()); + EXPECT_NE( + results_delimiter_i_prefix_d.common_prefixes.find("di"), + results_delimiter_i_prefix_d.common_prefixes.end() + ); } TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { @@ -1053,15 +1065,19 @@ TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { createTestObjectVersion(object1, version_id++, store->db_conn); createTestObjectVersion(object1, version_id++, store->db_conn); - auto object2 = createTestObject("test_bucket", "directory/directory/", store->db_conn); + auto object2 = + createTestObject("test_bucket", "directory/directory/", store->db_conn); createTestObjectVersion(object2, version_id++, store->db_conn); createTestObjectVersion(object2, version_id++, store->db_conn); - auto object3 = createTestObject("test_bucket", "directory/directory/file", store->db_conn); + auto object3 = createTestObject( + "test_bucket", "directory/directory/file", store->db_conn + ); createTestObjectVersion(object3, version_id++, store->db_conn); createTestObjectVersion(object3, version_id++, store->db_conn); - auto object4 = createTestObject("test_bucket", "directory/file", store->db_conn); + auto object4 = + createTestObject("test_bucket", "directory/file", store->db_conn); createTestObjectVersion(object4, version_id++, store->db_conn); createTestObjectVersion(object4, version_id++, store->db_conn); @@ -1080,12 +1096,12 @@ TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { arg_info.bucket.name = "test_bucket_name"; arg_info.bucket.bucket_id = "test_bucket"; std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); ASSERT_NE(bucket_from_store, nullptr); @@ -1097,15 +1113,11 @@ TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { params.list_versions = true; rgw::sal::Bucket::ListResults results; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results, - null_yield), - 0); + EXPECT_EQ(bucket_from_store->list(&ndp, params, 0, results, null_yield), 0); // we expect to get all the objects - std::map> expected_objects; + std::map> + expected_objects; expected_objects[object1->name] = object1; expected_objects[object2->name] = object2; expected_objects[object3->name] = object3; @@ -1114,7 +1126,7 @@ TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { auto nb_found_objects = 0; // we have 2 versions per object EXPECT_EQ(expected_objects.size() * 2, results.objs.size()); - for (auto & ret_obj : results.objs) { + for (auto& ret_obj : results.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -1131,41 +1143,43 @@ TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { params.delim = "i"; rgw::sal::Bucket::ListResults results_delimiter_i; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_i, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list(&ndp, params, 0, results_delimiter_i, null_yield), + 0 + ); // we expect zero objects EXPECT_EQ(results_delimiter_i.objs.size(), 0); // check common_prefixes (should be fi and di) EXPECT_EQ(results_delimiter_i.common_prefixes.size(), 2); - EXPECT_NE(results_delimiter_i.common_prefixes.find("fi"), - results_delimiter_i.common_prefixes.end()); - EXPECT_NE(results_delimiter_i.common_prefixes.find("di"), - results_delimiter_i.common_prefixes.end()); + EXPECT_NE( + results_delimiter_i.common_prefixes.find("fi"), + results_delimiter_i.common_prefixes.end() + ); + EXPECT_NE( + results_delimiter_i.common_prefixes.find("di"), + results_delimiter_i.common_prefixes.end() + ); // use delimiter '/' params.prefix = ""; params.delim = "/"; rgw::sal::Bucket::ListResults results_delimiter_slash; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_slash, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_delimiter_slash, null_yield + ), + 0 + ); // we expect only the "file" oject (the rest are aggregated in common prefix) expected_objects.clear(); expected_objects[object5->name] = object5; nb_found_objects = 0; EXPECT_EQ(expected_objects.size() * 2, results_delimiter_slash.objs.size()); - for (auto & ret_obj : results_delimiter_slash.objs) { + for (auto& ret_obj : results_delimiter_slash.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -1177,32 +1191,36 @@ TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { // check common_prefixes EXPECT_EQ(results_delimiter_slash.common_prefixes.size(), 1); - EXPECT_NE(results_delimiter_slash.common_prefixes.find("directory/"), - results_delimiter_slash.common_prefixes.end()); + EXPECT_NE( + results_delimiter_slash.common_prefixes.find("directory/"), + results_delimiter_slash.common_prefixes.end() + ); // use delimiter '/directory' params.prefix = ""; params.delim = "/directory"; rgw::sal::Bucket::ListResults results_delimiter_directory; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_directory, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_delimiter_directory, null_yield + ), + 0 + ); // we expect // directory/ // directory/file // file expected_objects.clear(); - expected_objects[object1->name] = object1; // directory/ - expected_objects[object4->name] = object4; // directory/file - expected_objects[object5->name] = object5; // file + expected_objects[object1->name] = object1; // directory/ + expected_objects[object4->name] = object4; // directory/file + expected_objects[object5->name] = object5; // file nb_found_objects = 0; - EXPECT_EQ(expected_objects.size() * 2, results_delimiter_directory.objs.size()); - for (auto & ret_obj : results_delimiter_directory.objs) { + EXPECT_EQ( + expected_objects.size() * 2, results_delimiter_directory.objs.size() + ); + for (auto& ret_obj : results_delimiter_directory.objs) { auto it = expected_objects.find(ret_obj.key.name); if (it != expected_objects.end()) { compareListEntry(ret_obj, it->second, "test_user"); @@ -1214,29 +1232,32 @@ TEST_F(TestSFSBucket, TestListObjectVersionsDelimiter) { // check common_prefixes EXPECT_EQ(results_delimiter_directory.common_prefixes.size(), 1); - EXPECT_NE(results_delimiter_directory.common_prefixes.find("directory/directory"), - results_delimiter_directory.common_prefixes.end()); - + EXPECT_NE( + results_delimiter_directory.common_prefixes.find("directory/directory"), + results_delimiter_directory.common_prefixes.end() + ); // use delimiter 'i' and prefix 'd' params.prefix = "d"; params.delim = "i"; rgw::sal::Bucket::ListResults results_delimiter_i_prefix_d; - EXPECT_EQ(bucket_from_store->list(&ndp, - params, - 0, - results_delimiter_i_prefix_d, - null_yield), - 0); + EXPECT_EQ( + bucket_from_store->list( + &ndp, params, 0, results_delimiter_i_prefix_d, null_yield + ), + 0 + ); // we expect zero objects EXPECT_EQ(results_delimiter_i_prefix_d.objs.size(), 0); // check common_prefixes (should be fi and di) EXPECT_EQ(results_delimiter_i_prefix_d.common_prefixes.size(), 1); - EXPECT_NE(results_delimiter_i_prefix_d.common_prefixes.find("di"), - results_delimiter_i_prefix_d.common_prefixes.end()); + EXPECT_NE( + results_delimiter_i_prefix_d.common_prefixes.find("di"), + results_delimiter_i_prefix_d.common_prefixes.end() + ); } TEST_F(TestSFSBucket, UserCreateBucketObjectLockEnabled) { @@ -1272,37 +1293,42 @@ TEST_F(TestSFSBucket, UserCreateBucketObjectLockEnabled) { std::unique_ptr bucket_from_create; - EXPECT_EQ(user->create_bucket(&ndp, //dpp - arg_bucket, //b - "zg1", //zonegroup_id - arg_pl_rule, //placement_rule - arg_swift_ver_location, //swift_ver_location - &arg_quota_info, //pquota_info - arg_aclp, //policy - arg_attrs, //attrs - arg_info, //info - arg_objv, //ep_objv - false, //exclusive - true, //obj_lock_enabled - &existed, //existed - arg_req_info, //req_info - &bucket_from_create, //bucket - null_yield //optional_yield - ), - 0); + EXPECT_EQ( + user->create_bucket( + &ndp, //dpp + arg_bucket, //b + "zg1", //zonegroup_id + arg_pl_rule, //placement_rule + arg_swift_ver_location, //swift_ver_location + &arg_quota_info, //pquota_info + arg_aclp, //policy + arg_attrs, //attrs + arg_info, //info + arg_objv, //ep_objv + false, //exclusive + true, //obj_lock_enabled + &existed, //existed + arg_req_info, //req_info + &bucket_from_create, //bucket + null_yield //optional_yield + ), + 0 + ); EXPECT_TRUE(arg_info.flags & BUCKET_VERSIONED); EXPECT_TRUE(arg_info.flags & BUCKET_OBJ_LOCK_ENABLED); std::unique_ptr bucket_from_store; - EXPECT_EQ(store->get_bucket(&ndp, - user.get(), - arg_info.bucket, - &bucket_from_store, - null_yield), - 0); + EXPECT_EQ( + store->get_bucket( + &ndp, user.get(), arg_info.bucket, &bucket_from_store, null_yield + ), + 0 + ); EXPECT_EQ(bucket_from_create->get_info().flags, arg_info.flags); - EXPECT_EQ(bucket_from_create->get_info().flags, bucket_from_store->get_info().flags); + EXPECT_EQ( + bucket_from_create->get_info().flags, bucket_from_store->get_info().flags + ); } diff --git a/src/test/rgw/sfs/test_rgw_sfs_sqlite_objects.cc b/src/test/rgw/sfs/test_rgw_sfs_sqlite_objects.cc index c5046fa735be0..05f5476ce7731 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_sqlite_objects.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_sqlite_objects.cc @@ -1,26 +1,25 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +#include + +#include +#include + #include "common/ceph_context.h" #include "rgw/driver/sfs/sqlite/dbconn.h" -#include "rgw/driver/sfs/sqlite/sqlite_objects.h" #include "rgw/driver/sfs/sqlite/sqlite_buckets.h" +#include "rgw/driver/sfs/sqlite/sqlite_objects.h" #include "rgw/driver/sfs/sqlite/sqlite_users.h" -#include "rgw/driver/sfs/sqlite/objects/object_conversions.h" - #include "rgw/rgw_sal_sfs.h" -#include -#include -#include - using namespace rgw::sal::sfs::sqlite; namespace fs = std::filesystem; const static std::string TEST_DIR = "rgw_sfs_tests"; class TestSFSSQLiteObjects : public ::testing::Test { -protected: + protected: void SetUp() override { fs::current_path(fs::temp_directory_path()); fs::create_directory(TEST_DIR); @@ -36,24 +35,24 @@ class TestSFSSQLiteObjects : public ::testing::Test { return test_dir.string(); } - fs::path getDBFullPath(const std::string & base_dir) const { + fs::path getDBFullPath(const std::string& base_dir) const { auto db_full_name = "s3gw.db"; - auto db_full_path = fs::path(base_dir) / db_full_name; + auto db_full_path = fs::path(base_dir) / db_full_name; return db_full_path; } - fs::path getDBFullPath() const { - return getDBFullPath(getTestDir()); - } + fs::path getDBFullPath() const { return getDBFullPath(getTestDir()); } - void createUser(const std::string & username, DBConnRef conn) { + void createUser(const std::string& username, DBConnRef conn) { SQLiteUsers users(conn); DBOPUserInfo user; user.uinfo.user_id.id = username; users.store_user(user); } - void createBucket(const std::string & username, const std::string & bucketname, DBConnRef conn) { + void createBucket( + const std::string& username, const std::string& bucketname, DBConnRef conn + ) { createUser(username, conn); SQLiteBuckets buckets(conn); DBOPBucketInfo bucket; @@ -64,33 +63,25 @@ class TestSFSSQLiteObjects : public ::testing::Test { } }; -void compareObjects(const DBOPObjectInfo & origin, const DBOPObjectInfo & dest) { +void compareObjects(const DBOPObjectInfo& origin, const DBOPObjectInfo& dest) { ASSERT_EQ(origin.uuid, dest.uuid); ASSERT_EQ(origin.bucket_id, dest.bucket_id); ASSERT_EQ(origin.name, dest.name); - ASSERT_EQ(origin.size, dest.size); - ASSERT_EQ(origin.etag, dest.etag); - ASSERT_EQ(origin.mtime, dest.mtime); - ASSERT_EQ(origin.set_mtime, dest.set_mtime); - ASSERT_EQ(origin.delete_at, dest.delete_at); } -DBOPObjectInfo createTestObject(const std::string & suffix, CephContext *context, const std::string & username="usertest") { +DBOPObjectInfo createTestObject( + const std::string& suffix, CephContext* context, + const std::string& username = "usertest" +) { DBOPObjectInfo object; object.uuid.generate_random(); object.bucket_id = "test_bucket"; object.name = "test" + suffix; - object.size = rand(); - object.etag = "test_etag_" + suffix; - object.mtime = ceph::real_clock::now(); - object.set_mtime = ceph::real_clock::now(); - object.delete_at = ceph::real_clock::now(); return object; } -bool uuidInVector(const uuid_d & uuid, const std::vector & uuids) -{ - for (auto const & list_uuid : uuids) { +bool uuidInVector(const uuid_d& uuid, const std::vector& uuids) { + for (auto const& list_uuid : uuids) { if (list_uuid == uuid) return true; } return false; @@ -117,7 +108,6 @@ TEST_F(TestSFSSQLiteObjects, CreateAndGet) { compareObjects(object, *ret_object); } - TEST_F(TestSFSSQLiteObjects, ListObjectsIDs) { auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); @@ -185,7 +175,6 @@ TEST_F(TestSFSSQLiteObjects, ListBucketsIDsPerBucket) { EXPECT_EQ(objects_ids[0], test_object_3.uuid); } - TEST_F(TestSFSSQLiteObjects, remove_object) { auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); @@ -311,19 +300,27 @@ TEST_F(TestSFSSQLiteObjects, CreateObjectForNonExistingBucket) { SQLiteObjects db_objects(conn); auto storage = conn->get_storage(); - DBObject db_object; + DBOPObjectInfo db_object; - db_object.object_id = "254ddc1a-06a6-11ed-b939-0242ac120002"; + uuid_d uuid_obj; + uuid_obj.parse("254ddc1a-06a6-11ed-b939-0242ac120002"); + db_object.uuid = uuid_obj; db_object.name = "test"; - EXPECT_THROW({ - try { - storage.replace(db_object);; - } catch( const std::system_error & e ) { - EXPECT_STREQ( "FOREIGN KEY constraint failed: constraint failed", e.what() ); - throw; - } - }, std::system_error ); + EXPECT_THROW( + { + try { + storage.replace(db_object); + ; + } catch (const std::system_error& e) { + EXPECT_STREQ( + "FOREIGN KEY constraint failed: constraint failed", e.what() + ); + throw; + } + }, + std::system_error + ); } TEST_F(TestSFSSQLiteObjects, GetObjectByBucketAndObjectName) { @@ -341,20 +338,29 @@ TEST_F(TestSFSSQLiteObjects, GetObjectByBucketAndObjectName) { auto db_objects = std::make_shared(conn); // create objects with names "test1", "test2" and "test3"... in bucket "test_bucket" - auto object_1 = createTestObject("1", ceph_context.get()); // name is "test1", bucket is "test_bucket" + auto object_1 = createTestObject( + "1", ceph_context.get() + ); // name is "test1", bucket is "test_bucket" db_objects->store_object(object_1); - auto object_2 = createTestObject("2", ceph_context.get()); // name is "test2", bucket is "test_bucket" + auto object_2 = createTestObject( + "2", ceph_context.get() + ); // name is "test2", bucket is "test_bucket" db_objects->store_object(object_2); - auto object_3 = createTestObject("3", ceph_context.get()); // name is "test3", bucket is "test_bucket" + auto object_3 = createTestObject( + "3", ceph_context.get() + ); // name is "test3", bucket is "test_bucket" db_objects->store_object(object_3); // create object "test1" in bucket "test_bucket_2" - auto object_1_2 = createTestObject("1", ceph_context.get()); // name is "test3", bucket is "test_bucket" + auto object_1_2 = createTestObject( + "1", ceph_context.get() + ); // name is "test3", bucket is "test_bucket" object_1_2.bucket_id = "test_bucket_2"; db_objects->store_object(object_1_2); // run a few queries - auto ret_object = db_objects->get_object("test_bucket", "this_object_does_not_exist"); + auto ret_object = + db_objects->get_object("test_bucket", "this_object_does_not_exist"); ASSERT_FALSE(ret_object.has_value()); ret_object = db_objects->get_object("test_bucket", "test1"); diff --git a/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc b/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc index b888388c17f24..b376d4fa78ab3 100644 --- a/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc +++ b/src/test/rgw/sfs/test_rgw_sfs_sqlite_versioned_objects.cc @@ -1,20 +1,20 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab +#include + +#include +#include + #include "common/ceph_context.h" #include "rgw/driver/sfs/sqlite/dbconn.h" -#include "rgw/driver/sfs/sqlite/sqlite_versioned_objects.h" -#include "rgw/driver/sfs/sqlite/sqlite_objects.h" #include "rgw/driver/sfs/sqlite/sqlite_buckets.h" +#include "rgw/driver/sfs/sqlite/sqlite_objects.h" #include "rgw/driver/sfs/sqlite/sqlite_users.h" +#include "rgw/driver/sfs/sqlite/sqlite_versioned_objects.h" #include "rgw/driver/sfs/sqlite/versioned_object/versioned_object_conversions.h" - #include "rgw/rgw_sal_sfs.h" -#include -#include -#include - using namespace rgw::sal::sfs::sqlite; namespace fs = std::filesystem; @@ -22,13 +22,17 @@ const static std::string TEST_DIR = "rgw_sfs_tests"; const static std::string TEST_USERNAME = "test_username"; const static std::string TEST_BUCKET = "test_bucket"; -const static std::string TEST_OBJECT_ID = "80943a6d-9f72-4001-bac0-a9a036be8c49"; -const static std::string TEST_OBJECT_ID_1 = "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; -const static std::string TEST_OBJECT_ID_2 = "af06d9d3-307f-4c98-865b-cd3b087acc4f"; -const static std::string TEST_OBJECT_ID_3 = "bf06d9d3-307f-4c98-865b-cd3b087acc4f"; +const static std::string TEST_OBJECT_ID = + "80943a6d-9f72-4001-bac0-a9a036be8c49"; +const static std::string TEST_OBJECT_ID_1 = + "9f06d9d3-307f-4c98-865b-cd3b087acc4f"; +const static std::string TEST_OBJECT_ID_2 = + "af06d9d3-307f-4c98-865b-cd3b087acc4f"; +const static std::string TEST_OBJECT_ID_3 = + "bf06d9d3-307f-4c98-865b-cd3b087acc4f"; class TestSFSSQLiteVersionedObjects : public ::testing::Test { -protected: + protected: void SetUp() override { fs::current_path(fs::temp_directory_path()); fs::create_directory(TEST_DIR); @@ -44,24 +48,24 @@ class TestSFSSQLiteVersionedObjects : public ::testing::Test { return test_dir.string(); } - fs::path getDBFullPath(const std::string & base_dir) const { + fs::path getDBFullPath(const std::string& base_dir) const { auto db_full_name = "s3gw.db"; - auto db_full_path = fs::path(base_dir) / db_full_name; + auto db_full_path = fs::path(base_dir) / db_full_name; return db_full_path; } - fs::path getDBFullPath() const { - return getDBFullPath(getTestDir()); - } + fs::path getDBFullPath() const { return getDBFullPath(getTestDir()); } - void createUser(const std::string & username, DBConnRef conn) { + void createUser(const std::string& username, DBConnRef conn) { SQLiteUsers users(conn); DBOPUserInfo user; user.uinfo.user_id.id = username; users.store_user(user); } - void createBucket(const std::string & username, const std::string & bucketname, DBConnRef conn) { + void createBucket( + const std::string& username, const std::string& bucketname, DBConnRef conn + ) { createUser(username, conn); SQLiteBuckets buckets(conn); DBOPBucketInfo bucket; @@ -72,11 +76,8 @@ class TestSFSSQLiteVersionedObjects : public ::testing::Test { } void createObject( - const std::string & username, - const std::string & bucketname, - const std::string object_id, - CephContext *context, - DBConnRef conn + const std::string& username, const std::string& bucketname, + const std::string object_id, CephContext* context, DBConnRef conn ) { createBucket(username, bucketname, conn); SQLiteObjects objects(conn); @@ -85,28 +86,29 @@ class TestSFSSQLiteVersionedObjects : public ::testing::Test { object.uuid.parse(object_id.c_str()); object.bucket_id = bucketname; object.name = "test_name"; - object.size = rand(); - object.etag = "test_etag"; - object.mtime = ceph::real_clock::now(); - object.set_mtime = ceph::real_clock::now(); - object.delete_at = ceph::real_clock::now(); objects.store_object(object); } }; -DBOPVersionedObjectInfo createTestVersionedObject(uint id, const std::string & object_id, const std::string & suffix) { +DBOPVersionedObjectInfo createTestVersionedObject( + uint id, const std::string& object_id, const std::string& suffix +) { DBOPVersionedObjectInfo test_versioned_object; test_versioned_object.id = id; uuid_d uuid; uuid.parse(object_id.c_str()); test_versioned_object.object_id = uuid; test_versioned_object.checksum = "test_checksum_" + suffix; - test_versioned_object.deletion_time = ceph::real_clock::now(); test_versioned_object.size = rand(); - test_versioned_object.creation_time = ceph::real_clock::now(); - test_versioned_object.object_state = rgw::sal::ObjectState::OPEN; + test_versioned_object.create_time = ceph::real_clock::now(); + test_versioned_object.delete_time = ceph::real_clock::now(); + test_versioned_object.commit_time = ceph::real_clock::now(); + test_versioned_object.mtime = ceph::real_clock::now(); + test_versioned_object.object_state = rgw::sal::sfs::ObjectState::OPEN; test_versioned_object.version_id = "test_version_id_" + suffix; test_versioned_object.etag = "test_etag_" + suffix; + test_versioned_object.version_type = + rgw::sal::sfs::VersionType::DELETE_MARKER; //set attrs with default ACL { @@ -125,7 +127,10 @@ DBOPVersionedObjectInfo createTestVersionedObject(uint id, const std::string & o return test_versioned_object; } -void compareVersionedObjectsAttrs(const std::optional & origin, const std::optional & dest) { +void compareVersionedObjectsAttrs( + const std::optional& origin, + const std::optional& dest +) { ASSERT_EQ(origin.has_value(), true); ASSERT_EQ(origin.has_value(), dest.has_value()); auto orig_acl_bl_it = origin->find(RGW_ATTR_ACL); @@ -142,17 +147,21 @@ void compareVersionedObjectsAttrs(const std::optional & origin, ASSERT_EQ(orig_aclp, dest_aclp); } -void compareVersionedObjects(const DBOPVersionedObjectInfo & origin, const DBOPVersionedObjectInfo & dest) { +void compareVersionedObjects( + const DBOPVersionedObjectInfo& origin, const DBOPVersionedObjectInfo& dest +) { ASSERT_EQ(origin.id, dest.id); ASSERT_EQ(origin.object_id, dest.object_id); ASSERT_EQ(origin.checksum, dest.checksum); - ASSERT_EQ(origin.deletion_time, dest.deletion_time); ASSERT_EQ(origin.size, dest.size); - ASSERT_EQ(origin.creation_time, dest.creation_time); + ASSERT_EQ(origin.create_time, dest.create_time); + ASSERT_EQ(origin.delete_time, dest.delete_time); + ASSERT_EQ(origin.commit_time, dest.commit_time); ASSERT_EQ(origin.object_state, dest.object_state); ASSERT_EQ(origin.version_id, dest.version_id); ASSERT_EQ(origin.etag, dest.etag); compareVersionedObjectsAttrs(origin.attrs, dest.attrs); + ASSERT_EQ(origin.version_type, dest.version_type); } TEST_F(TestSFSSQLiteVersionedObjects, CreateAndGet) { @@ -165,7 +174,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, CreateAndGet) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto versioned_object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); @@ -173,12 +182,14 @@ TEST_F(TestSFSSQLiteVersionedObjects, CreateAndGet) { db_versioned_objects->insert_versioned_object(versioned_object); EXPECT_TRUE(fs::exists(getDBFullPath())); - auto ret_ver_object = db_versioned_objects->get_versioned_object(versioned_object.id); + auto ret_ver_object = + db_versioned_objects->get_versioned_object(versioned_object.id); ASSERT_TRUE(ret_ver_object.has_value()); compareVersionedObjects(versioned_object, *ret_ver_object); // get by version id - ret_ver_object = db_versioned_objects->get_versioned_object("test_version_id_1"); + ret_ver_object = + db_versioned_objects->get_versioned_object("test_version_id_1"); ASSERT_TRUE(ret_ver_object.has_value()); compareVersionedObjects(versioned_object, *ret_ver_object); } @@ -192,7 +203,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, ListObjectsIDs) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto db_versioned_objects = std::make_shared(conn); @@ -230,13 +241,13 @@ TEST_F(TestSFSSQLiteVersionedObjects, ListBucketsIDsPerObject) { DBConnRef conn = std::make_shared(ceph_context.get()); createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID_1, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID_1, ceph_context.get(), conn ); createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID_2, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID_2, ceph_context.get(), conn ); createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID_3, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID_3, ceph_context.get(), conn ); auto db_versioned_objects = std::make_shared(conn); @@ -278,7 +289,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, RemoveObject) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto db_versioned_objects = std::make_shared(conn); @@ -310,7 +321,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, RemoveObjectThatDoesNotExist) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto db_versioned_objects = std::make_shared(conn); @@ -345,7 +356,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, CreateAndUpdate) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto versioned_object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); @@ -353,7 +364,8 @@ TEST_F(TestSFSSQLiteVersionedObjects, CreateAndUpdate) { db_versioned_objects->insert_versioned_object(versioned_object); EXPECT_TRUE(fs::exists(getDBFullPath())); - auto ret_ver_object = db_versioned_objects->get_versioned_object(versioned_object.id); + auto ret_ver_object = + db_versioned_objects->get_versioned_object(versioned_object.id); ASSERT_TRUE(ret_ver_object.has_value()); compareVersionedObjects(versioned_object, *ret_ver_object); @@ -366,7 +378,8 @@ TEST_F(TestSFSSQLiteVersionedObjects, CreateAndUpdate) { db_versioned_objects->insert_versioned_object(new_versioned); // get the first version - ret_ver_object = db_versioned_objects->get_versioned_object(versioned_object.id); + ret_ver_object = + db_versioned_objects->get_versioned_object(versioned_object.id); ASSERT_TRUE(ret_ver_object.has_value()); ASSERT_EQ(original_size, ret_ver_object->size); versioned_object.size = original_size; @@ -398,7 +411,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, GetExisting) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); @@ -424,7 +437,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, CreateObjectForNonExistingBucket) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); SQLiteVersionedObjects db_objects(conn); @@ -433,18 +446,26 @@ TEST_F(TestSFSSQLiteVersionedObjects, CreateObjectForNonExistingBucket) { DBVersionedObject db_object; db_object.id = 1; - db_object.object_id = "254ddc1a-06a6-11ed-b939-0242ac120002"; + uuid_d uuid_val; + uuid_val.parse("254ddc1a-06a6-11ed-b939-0242ac120002"); + db_object.object_id = uuid_val; db_object.checksum = "test"; db_object.size = rand(); - EXPECT_THROW({ - try { - storage.replace(db_object);; - } catch( const std::system_error & e ) { - EXPECT_STREQ( "FOREIGN KEY constraint failed: constraint failed", e.what() ); - throw; - } - }, std::system_error ); + EXPECT_THROW( + { + try { + storage.replace(db_object); + ; + } catch (const std::system_error& e) { + EXPECT_STREQ( + "FOREIGN KEY constraint failed: constraint failed", e.what() + ); + throw; + } + }, + std::system_error + ); } TEST_F(TestSFSSQLiteVersionedObjects, Testobject_stateConversion) { @@ -455,7 +476,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, Testobject_stateConversion) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); SQLiteVersionedObjects db_objects(conn); @@ -463,59 +484,28 @@ TEST_F(TestSFSSQLiteVersionedObjects, Testobject_stateConversion) { auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); auto db_object = get_db_versioned_object(object); - ASSERT_EQ(0, db_object.object_state); + ASSERT_EQ(rgw::sal::sfs::ObjectState::OPEN, db_object.object_state); - db_object.object_state = 1; + db_object.object_state = rgw::sal::sfs::ObjectState::COMMITTED; storage.replace(db_object); auto ret_object = db_objects.get_versioned_object(db_object.id); ASSERT_TRUE(ret_object.has_value()); - ASSERT_EQ(rgw::sal::ObjectState::COMMITTED, ret_object->object_state); + ASSERT_EQ(rgw::sal::sfs::ObjectState::COMMITTED, ret_object->object_state); - db_object.object_state = 2; + db_object.object_state = rgw::sal::sfs::ObjectState::LOCKED; storage.replace(db_object); ret_object = db_objects.get_versioned_object(db_object.id); ASSERT_TRUE(ret_object.has_value()); - ASSERT_EQ(rgw::sal::ObjectState::LOCKED, ret_object->object_state); + ASSERT_EQ(rgw::sal::sfs::ObjectState::LOCKED, ret_object->object_state); - db_object.object_state = 3; + db_object.object_state = rgw::sal::sfs::ObjectState::DELETED; storage.replace(db_object); ret_object = db_objects.get_versioned_object(db_object.id); ASSERT_TRUE(ret_object.has_value()); - ASSERT_EQ(rgw::sal::ObjectState::DELETED, ret_object->object_state); -} - -TEST_F(TestSFSSQLiteVersionedObjects, Testobject_stateBadValue) { - auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); - ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); - - DBConnRef conn = std::make_shared(ceph_context.get()); - - // Create the object, we need it because of foreign key constrains - createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn - ); - - SQLiteVersionedObjects db_objects(conn); - auto storage = conn->get_storage(); - - auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); - auto db_object = get_db_versioned_object(object); - ASSERT_EQ(0, db_object.object_state); - - db_object.object_state = 10; - storage.replace(db_object); - - EXPECT_THROW({ - try { - auto ret_object = db_objects.get_versioned_object(db_object.id); - } catch( const std::system_error & e ) { - EXPECT_STREQ( "incorrect state found (10)", e.what() ); - throw; - } - }, std::runtime_error ); + ASSERT_EQ(rgw::sal::sfs::ObjectState::DELETED, ret_object->object_state); } TEST_F(TestSFSSQLiteVersionedObjects, StoreCreatesNewVersions) { @@ -529,7 +519,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, StoreCreatesNewVersions) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); @@ -588,7 +578,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, GetLastVersion) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); @@ -615,7 +605,8 @@ TEST_F(TestSFSSQLiteVersionedObjects, GetLastVersion) { uuid_d uuid_that_does_not_exist; uuid_that_does_not_exist.parse(TEST_OBJECT_ID_2.c_str()); - ret_object = db_versioned_objects->get_last_versioned_object(uuid_that_does_not_exist); + ret_object = + db_versioned_objects->get_last_versioned_object(uuid_that_does_not_exist); ASSERT_FALSE(ret_object.has_value()); } @@ -630,7 +621,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, TestInsertIncreaseID) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); @@ -680,7 +671,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, TestUpdate) { // Create the object, we need it because of foreign key constrains createObject( - TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn ); auto object = createTestVersionedObject(1, TEST_OBJECT_ID, "1"); @@ -690,7 +681,7 @@ TEST_F(TestSFSSQLiteVersionedObjects, TestUpdate) { ASSERT_TRUE(ret_ver_object.has_value()); compareVersionedObjects(object, *ret_ver_object); - object.object_state = rgw::sal::ObjectState::OPEN; + object.object_state = rgw::sal::sfs::ObjectState::OPEN; db_versioned_objects->store_versioned_object(object); ret_ver_object = db_versioned_objects->get_versioned_object(1); @@ -700,3 +691,51 @@ TEST_F(TestSFSSQLiteVersionedObjects, TestUpdate) { ret_ver_object = db_versioned_objects->get_versioned_object(2); ASSERT_FALSE(ret_ver_object.has_value()); } + +TEST_F(TestSFSSQLiteVersionedObjects, StoreUnsupportedTimestamp) { + auto ceph_context = std::make_shared(CEPH_ENTITY_TYPE_CLIENT); + ceph_context->_conf.set_val("rgw_sfs_data_path", getTestDir()); + + DBConnRef conn = std::make_shared(ceph_context.get()); + + // Create the object, we need it because of foreign key constrains + createObject( + TEST_USERNAME, TEST_BUCKET, TEST_OBJECT_ID, ceph_context.get(), conn + ); + + SQLiteVersionedObjects db_versions(conn); + auto storage = conn->get_storage(); + + DBVersionedObject db_version; + + db_version.id = 1; + uuid_d uuid_val; + uuid_val.parse(TEST_OBJECT_ID.c_str()); + db_version.object_id = uuid_val; + db_version.checksum = "test"; + db_version.size = rand(); + + // our max supported value is int64::max + uint64_t nanos_int64_plus_one = + static_cast(std::numeric_limits::max()) + 1; + db_version.create_time = + ceph::real_time(std::chrono::nanoseconds(nanos_int64_plus_one)); + + EXPECT_THROW( + { + try { + storage.replace(db_version); + ; + } catch (const std::system_error& e) { + EXPECT_STREQ( + "Error converting ceph::real_time to int64. Nanoseconds value: " + "9223372036854775808 is out of range: Numerical result out of " + "range", + e.what() + ); + throw; + } + }, + std::system_error + ); +}