mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-20 16:50:14 +00:00
Merge "bucket: Add clone/staleness operations for ast_bucket/ast_bucket_file"
This commit is contained in:
@@ -217,6 +217,23 @@ struct ast_bucket *ast_bucket_alloc(const char *uri);
|
|||||||
*/
|
*/
|
||||||
int ast_bucket_create(struct ast_bucket *bucket);
|
int ast_bucket_create(struct ast_bucket *bucket);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clone a bucket
|
||||||
|
*
|
||||||
|
* This will create a copy of the passed in \c ast_bucket structure. While
|
||||||
|
* all properties of the \c ast_bucket structure are copied, any metadata
|
||||||
|
* in the original structure simply has its reference count increased.
|
||||||
|
*
|
||||||
|
* \param file The bucket to clone
|
||||||
|
*
|
||||||
|
* \retval non-NULL success
|
||||||
|
* \retval NULL failure
|
||||||
|
*
|
||||||
|
* \note This operation should be called prior to updating a bucket
|
||||||
|
* object, as \c ast_bucket instances are immutable
|
||||||
|
*/
|
||||||
|
struct ast_bucket *ast_bucket_clone(struct ast_bucket *bucket);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Delete a bucket from backend storage
|
* \brief Delete a bucket from backend storage
|
||||||
*
|
*
|
||||||
@@ -239,6 +256,23 @@ int ast_bucket_delete(struct ast_bucket *bucket);
|
|||||||
*/
|
*/
|
||||||
struct ast_bucket *ast_bucket_retrieve(const char *uri);
|
struct ast_bucket *ast_bucket_retrieve(const char *uri);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Retrieve whether or not the backing datastore views the bucket as stale
|
||||||
|
* \since 14.0.0
|
||||||
|
*
|
||||||
|
* This function will ask whatever data storage backs the bucket's schema
|
||||||
|
* type if the current instance of the object is stale. It will not
|
||||||
|
* update the bucket object itself, as said objects are immutable. If the
|
||||||
|
* caller of this function would like to update the object, it should perform
|
||||||
|
* a retrieve operation.
|
||||||
|
*
|
||||||
|
* \param bucket The bucket object to check
|
||||||
|
*
|
||||||
|
* \retval 0 if \c bucket is not stale
|
||||||
|
* \retval 1 if \c bucket is stale
|
||||||
|
*/
|
||||||
|
int ast_bucket_is_stale(struct ast_bucket *bucket);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Add an observer for bucket creation and deletion operations
|
* \brief Add an observer for bucket creation and deletion operations
|
||||||
*
|
*
|
||||||
@@ -308,6 +342,24 @@ int ast_bucket_file_create(struct ast_bucket_file *file);
|
|||||||
*/
|
*/
|
||||||
struct ast_bucket_file *ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri);
|
struct ast_bucket_file *ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clone a bucket file
|
||||||
|
*
|
||||||
|
* This will create a copy of the passed in \c ast_bucket_file structure. While
|
||||||
|
* all properties of the \c ast_bucket_file structure are copied, any metadata
|
||||||
|
* in the original structure simply has its reference count increased. Note that
|
||||||
|
* this copies the structure, not the underlying file.
|
||||||
|
*
|
||||||
|
* \param file The bucket file to clone
|
||||||
|
*
|
||||||
|
* \retval non-NULL success
|
||||||
|
* \retval NULL failure
|
||||||
|
*
|
||||||
|
* \note This operation should be called prior to updating a bucket file
|
||||||
|
* object, as \c ast_bucket_file instances are immutable
|
||||||
|
*/
|
||||||
|
struct ast_bucket_file *ast_bucket_file_clone(struct ast_bucket_file *file);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Update an existing bucket file in backend storage
|
* \brief Update an existing bucket file in backend storage
|
||||||
*
|
*
|
||||||
@@ -342,6 +394,23 @@ int ast_bucket_file_delete(struct ast_bucket_file *file);
|
|||||||
*/
|
*/
|
||||||
struct ast_bucket_file *ast_bucket_file_retrieve(const char *uri);
|
struct ast_bucket_file *ast_bucket_file_retrieve(const char *uri);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Retrieve whether or not the backing datastore views the bucket file as stale
|
||||||
|
* \since 14.0.0
|
||||||
|
*
|
||||||
|
* This function will ask whatever data storage backs the bucket file's schema
|
||||||
|
* type if the current instance of the object is stale. It will not
|
||||||
|
* update the bucket file object itself, as said objects are immutable. If the
|
||||||
|
* caller of this function would like to update the object, it should perform
|
||||||
|
* a retrieve operation.
|
||||||
|
*
|
||||||
|
* \param bucket_file The bucket file object to check
|
||||||
|
*
|
||||||
|
* \retval 0 if \c bucket_file is not stale
|
||||||
|
* \retval 1 if \c bucket_file is stale
|
||||||
|
*/
|
||||||
|
int ast_bucket_file_is_stale(struct ast_bucket_file *file);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Add an observer for bucket file creation and deletion operations
|
* \brief Add an observer for bucket file creation and deletion operations
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -163,12 +163,25 @@ static int bucket_wizard_delete(const struct ast_sorcery *sorcery, void *data, v
|
|||||||
return bucket->scheme_impl->bucket->delete(sorcery, data, object);
|
return bucket->scheme_impl->bucket->delete(sorcery, data, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! \brief Callback function for determining if a bucket is stale */
|
||||||
|
static int bucket_wizard_is_stale(const struct ast_sorcery *sorcery, void *data, void *object)
|
||||||
|
{
|
||||||
|
struct ast_bucket *bucket = object;
|
||||||
|
|
||||||
|
if (!bucket->scheme_impl->bucket->is_stale) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bucket->scheme_impl->bucket->is_stale(sorcery, data, object);
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Intermediary bucket wizard */
|
/*! \brief Intermediary bucket wizard */
|
||||||
static struct ast_sorcery_wizard bucket_wizard = {
|
static struct ast_sorcery_wizard bucket_wizard = {
|
||||||
.name = "bucket",
|
.name = "bucket",
|
||||||
.create = bucket_wizard_create,
|
.create = bucket_wizard_create,
|
||||||
.retrieve_id = bucket_wizard_retrieve,
|
.retrieve_id = bucket_wizard_retrieve,
|
||||||
.delete = bucket_wizard_delete,
|
.delete = bucket_wizard_delete,
|
||||||
|
.is_stale = bucket_wizard_is_stale,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Callback function for creating a bucket file */
|
/*! \brief Callback function for creating a bucket file */
|
||||||
@@ -240,6 +253,18 @@ static int bucket_file_wizard_delete(const struct ast_sorcery *sorcery, void *da
|
|||||||
return file->scheme_impl->file->delete(sorcery, data, object);
|
return file->scheme_impl->file->delete(sorcery, data, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! \brief Callback function for determining if a bucket is stale */
|
||||||
|
static int bucket_file_wizard_is_stale(const struct ast_sorcery *sorcery, void *data, void *object)
|
||||||
|
{
|
||||||
|
struct ast_bucket_file *file = object;
|
||||||
|
|
||||||
|
if (!file->scheme_impl->file->is_stale) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file->scheme_impl->file->is_stale(sorcery, data, object);
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Intermediary file wizard */
|
/*! \brief Intermediary file wizard */
|
||||||
static struct ast_sorcery_wizard bucket_file_wizard = {
|
static struct ast_sorcery_wizard bucket_file_wizard = {
|
||||||
.name = "bucket_file",
|
.name = "bucket_file",
|
||||||
@@ -247,6 +272,7 @@ static struct ast_sorcery_wizard bucket_file_wizard = {
|
|||||||
.retrieve_id = bucket_file_wizard_retrieve,
|
.retrieve_id = bucket_file_wizard_retrieve,
|
||||||
.update = bucket_file_wizard_update,
|
.update = bucket_file_wizard_update,
|
||||||
.delete = bucket_file_wizard_delete,
|
.delete = bucket_file_wizard_delete,
|
||||||
|
.is_stale = bucket_file_wizard_is_stale,
|
||||||
};
|
};
|
||||||
|
|
||||||
int __ast_bucket_scheme_register(const char *name, struct ast_sorcery_wizard *bucket,
|
int __ast_bucket_scheme_register(const char *name, struct ast_sorcery_wizard *bucket,
|
||||||
@@ -459,6 +485,28 @@ int ast_bucket_create(struct ast_bucket *bucket)
|
|||||||
return ast_sorcery_create(bucket_sorcery, bucket);
|
return ast_sorcery_create(bucket_sorcery, bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
* \brief Sorcery object type copy handler for \c ast_bucket
|
||||||
|
*/
|
||||||
|
static int bucket_copy_handler(const void *src, void *dst)
|
||||||
|
{
|
||||||
|
const struct ast_bucket *src_bucket = src;
|
||||||
|
struct ast_bucket *dst_bucket = dst;
|
||||||
|
|
||||||
|
dst_bucket->scheme_impl = ao2_bump(src_bucket->scheme_impl);
|
||||||
|
ast_string_field_set(dst_bucket, scheme, src_bucket->scheme);
|
||||||
|
dst_bucket->created = src_bucket->created;
|
||||||
|
dst_bucket->modified = src_bucket->modified;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ast_bucket *ast_bucket_clone(struct ast_bucket *bucket)
|
||||||
|
{
|
||||||
|
return ast_sorcery_copy(bucket_sorcery, bucket);
|
||||||
|
}
|
||||||
|
|
||||||
struct ast_bucket *ast_bucket_retrieve(const char *uri)
|
struct ast_bucket *ast_bucket_retrieve(const char *uri)
|
||||||
{
|
{
|
||||||
if (ast_strlen_zero(uri)) {
|
if (ast_strlen_zero(uri)) {
|
||||||
@@ -468,6 +516,11 @@ struct ast_bucket *ast_bucket_retrieve(const char *uri)
|
|||||||
return ast_sorcery_retrieve_by_id(bucket_sorcery, "bucket", uri);
|
return ast_sorcery_retrieve_by_id(bucket_sorcery, "bucket", uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ast_bucket_is_stale(struct ast_bucket *bucket)
|
||||||
|
{
|
||||||
|
return ast_sorcery_is_stale(bucket_sorcery, bucket);
|
||||||
|
}
|
||||||
|
|
||||||
int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks)
|
int ast_bucket_observer_add(const struct ast_sorcery_observer *callbacks)
|
||||||
{
|
{
|
||||||
return ast_sorcery_observer_add(bucket_sorcery, "bucket", callbacks);
|
return ast_sorcery_observer_add(bucket_sorcery, "bucket", callbacks);
|
||||||
@@ -730,6 +783,29 @@ static int bucket_copy(const char *infile, const char *outfile)
|
|||||||
return 0; /* success */
|
return 0; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
* \brief Sorcery object type copy handler for \c ast_bucket_file
|
||||||
|
*/
|
||||||
|
static int bucket_file_copy_handler(const void *src, void *dst)
|
||||||
|
{
|
||||||
|
const struct ast_bucket_file *src_file = src;
|
||||||
|
struct ast_bucket_file *dst_file = dst;
|
||||||
|
|
||||||
|
dst_file->scheme_impl = ao2_bump(src_file->scheme_impl);
|
||||||
|
ast_string_field_set(dst_file, scheme, src_file->scheme);
|
||||||
|
dst_file->created = src_file->created;
|
||||||
|
dst_file->modified = src_file->modified;
|
||||||
|
strcpy(dst_file->path, src_file->path); /* safe */
|
||||||
|
|
||||||
|
dst_file->metadata = ao2_container_clone(src_file->metadata, 0);
|
||||||
|
if (!dst_file->metadata) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct ast_bucket_file *ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri)
|
struct ast_bucket_file *ast_bucket_file_copy(struct ast_bucket_file *file, const char *uri)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct ast_bucket_file *, copy, ast_bucket_file_alloc(uri), ao2_cleanup);
|
RAII_VAR(struct ast_bucket_file *, copy, ast_bucket_file_alloc(uri), ao2_cleanup);
|
||||||
@@ -749,6 +825,11 @@ struct ast_bucket_file *ast_bucket_file_copy(struct ast_bucket_file *file, const
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ast_bucket_file *ast_bucket_file_clone(struct ast_bucket_file *file)
|
||||||
|
{
|
||||||
|
return ast_sorcery_copy(bucket_sorcery, file);
|
||||||
|
}
|
||||||
|
|
||||||
struct ast_bucket_file *ast_bucket_file_retrieve(const char *uri)
|
struct ast_bucket_file *ast_bucket_file_retrieve(const char *uri)
|
||||||
{
|
{
|
||||||
if (ast_strlen_zero(uri)) {
|
if (ast_strlen_zero(uri)) {
|
||||||
@@ -758,6 +839,11 @@ struct ast_bucket_file *ast_bucket_file_retrieve(const char *uri)
|
|||||||
return ast_sorcery_retrieve_by_id(bucket_sorcery, "file", uri);
|
return ast_sorcery_retrieve_by_id(bucket_sorcery, "file", uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ast_bucket_file_is_stale(struct ast_bucket_file *file)
|
||||||
|
{
|
||||||
|
return ast_sorcery_is_stale(bucket_sorcery, file);
|
||||||
|
}
|
||||||
|
|
||||||
int ast_bucket_file_observer_add(const struct ast_sorcery_observer *callbacks)
|
int ast_bucket_file_observer_add(const struct ast_sorcery_observer *callbacks)
|
||||||
{
|
{
|
||||||
return ast_sorcery_observer_add(bucket_sorcery, "file", callbacks);
|
return ast_sorcery_observer_add(bucket_sorcery, "file", callbacks);
|
||||||
@@ -945,6 +1031,7 @@ int ast_bucket_init(void)
|
|||||||
ast_sorcery_object_field_register(bucket_sorcery, "bucket", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket, scheme));
|
ast_sorcery_object_field_register(bucket_sorcery, "bucket", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket, scheme));
|
||||||
ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, created));
|
ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, created));
|
||||||
ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, modified));
|
ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, modified));
|
||||||
|
ast_sorcery_object_set_copy_handler(bucket_sorcery, "bucket", bucket_copy_handler);
|
||||||
|
|
||||||
if (ast_sorcery_apply_default(bucket_sorcery, "file", "bucket_file", NULL) == AST_SORCERY_APPLY_FAIL) {
|
if (ast_sorcery_apply_default(bucket_sorcery, "file", "bucket_file", NULL) == AST_SORCERY_APPLY_FAIL) {
|
||||||
ast_log(LOG_ERROR, "Failed to apply intermediary for 'file' object type in Bucket sorcery\n");
|
ast_log(LOG_ERROR, "Failed to apply intermediary for 'file' object type in Bucket sorcery\n");
|
||||||
@@ -959,6 +1046,7 @@ int ast_bucket_init(void)
|
|||||||
ast_sorcery_object_field_register(bucket_sorcery, "file", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket_file, scheme));
|
ast_sorcery_object_field_register(bucket_sorcery, "file", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket_file, scheme));
|
||||||
ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, created));
|
ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, created));
|
||||||
ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, modified));
|
ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, modified));
|
||||||
|
ast_sorcery_object_set_copy_handler(bucket_sorcery, "file", bucket_file_copy_handler);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ struct bucket_test_state {
|
|||||||
unsigned int updated:1;
|
unsigned int updated:1;
|
||||||
/*! \brief Whether the object has been deleted or not */
|
/*! \brief Whether the object has been deleted or not */
|
||||||
unsigned int deleted:1;
|
unsigned int deleted:1;
|
||||||
|
/*! \brief Whether the object is stale or not */
|
||||||
|
unsigned int is_stale:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Global scope structure for testing bucket wizards */
|
/*! \brief Global scope structure for testing bucket wizards */
|
||||||
@@ -60,6 +62,7 @@ static void bucket_test_wizard_clear(void)
|
|||||||
bucket_test_wizard_state.created = 0;
|
bucket_test_wizard_state.created = 0;
|
||||||
bucket_test_wizard_state.updated = 0;
|
bucket_test_wizard_state.updated = 0;
|
||||||
bucket_test_wizard_state.deleted = 0;
|
bucket_test_wizard_state.deleted = 0;
|
||||||
|
bucket_test_wizard_state.is_stale = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bucket_test_wizard_create(const struct ast_sorcery *sorcery, void *data, void *object)
|
static int bucket_test_wizard_create(const struct ast_sorcery *sorcery, void *data, void *object)
|
||||||
@@ -107,11 +110,17 @@ static int bucket_test_wizard_delete(const struct ast_sorcery *sorcery, void *da
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bucket_test_wizard_is_stale(const struct ast_sorcery *sorcery, void *data, void *object)
|
||||||
|
{
|
||||||
|
return bucket_test_wizard_state.is_stale;
|
||||||
|
}
|
||||||
|
|
||||||
static struct ast_sorcery_wizard bucket_test_wizard = {
|
static struct ast_sorcery_wizard bucket_test_wizard = {
|
||||||
.name = "test",
|
.name = "test",
|
||||||
.create = bucket_test_wizard_create,
|
.create = bucket_test_wizard_create,
|
||||||
.retrieve_id = bucket_test_wizard_retrieve_id,
|
.retrieve_id = bucket_test_wizard_retrieve_id,
|
||||||
.delete = bucket_test_wizard_delete,
|
.delete = bucket_test_wizard_delete,
|
||||||
|
.is_stale = bucket_test_wizard_is_stale,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ast_sorcery_wizard bucket_file_test_wizard = {
|
static struct ast_sorcery_wizard bucket_file_test_wizard = {
|
||||||
@@ -120,6 +129,7 @@ static struct ast_sorcery_wizard bucket_file_test_wizard = {
|
|||||||
.update = bucket_test_wizard_update,
|
.update = bucket_test_wizard_update,
|
||||||
.retrieve_id = bucket_test_wizard_retrieve_id,
|
.retrieve_id = bucket_test_wizard_retrieve_id,
|
||||||
.delete = bucket_test_wizard_delete,
|
.delete = bucket_test_wizard_delete,
|
||||||
|
.is_stale = bucket_test_wizard_is_stale,
|
||||||
};
|
};
|
||||||
|
|
||||||
AST_TEST_DEFINE(bucket_scheme_register)
|
AST_TEST_DEFINE(bucket_scheme_register)
|
||||||
@@ -233,6 +243,50 @@ AST_TEST_DEFINE(bucket_create)
|
|||||||
return AST_TEST_PASS;
|
return AST_TEST_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AST_TEST_DEFINE(bucket_clone)
|
||||||
|
{
|
||||||
|
RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
|
||||||
|
RAII_VAR(struct ast_bucket *, clone, NULL, ao2_cleanup);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case TEST_INIT:
|
||||||
|
info->name = "bucket_clone";
|
||||||
|
info->category = "/main/bucket/";
|
||||||
|
info->summary = "bucket clone unit test";
|
||||||
|
info->description =
|
||||||
|
"Test cloning a bucket";
|
||||||
|
return AST_TEST_NOT_RUN;
|
||||||
|
case TEST_EXECUTE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(bucket = ast_bucket_alloc("test:///tmp/bob"))) {
|
||||||
|
ast_test_status_update(test, "Failed to allocate bucket\n");
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket_test_wizard_clear();
|
||||||
|
|
||||||
|
if (ast_bucket_create(bucket)) {
|
||||||
|
ast_test_status_update(test, "Failed to create bucket with URI '%s'\n",
|
||||||
|
ast_sorcery_object_get_id(bucket));
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
clone = ast_bucket_clone(bucket);
|
||||||
|
if (!clone) {
|
||||||
|
ast_test_status_update(test, "Failed to clone bucket with URI '%s'\n",
|
||||||
|
ast_sorcery_object_get_id(bucket));
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_test_validate(test, strcmp(ast_sorcery_object_get_id(bucket), ast_sorcery_object_get_id(clone)) == 0);
|
||||||
|
ast_test_validate(test, bucket->scheme_impl == clone->scheme_impl);
|
||||||
|
ast_test_validate(test, strcmp(bucket->scheme, clone->scheme) == 0);
|
||||||
|
|
||||||
|
return AST_TEST_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
AST_TEST_DEFINE(bucket_delete)
|
AST_TEST_DEFINE(bucket_delete)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
|
||||||
@@ -276,6 +330,38 @@ AST_TEST_DEFINE(bucket_delete)
|
|||||||
return AST_TEST_PASS;
|
return AST_TEST_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AST_TEST_DEFINE(bucket_is_stale)
|
||||||
|
{
|
||||||
|
RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case TEST_INIT:
|
||||||
|
info->name = "bucket_is_stale";
|
||||||
|
info->category = "/main/bucket/";
|
||||||
|
info->summary = "bucket staleness unit test";
|
||||||
|
info->description =
|
||||||
|
"Test if staleness of a bucket is reported correctly";
|
||||||
|
return AST_TEST_NOT_RUN;
|
||||||
|
case TEST_EXECUTE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(bucket = ast_bucket_alloc("test:///tmp/bob"))) {
|
||||||
|
ast_test_status_update(test, "Failed to allocate bucket\n");
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket_test_wizard_clear();
|
||||||
|
|
||||||
|
ast_test_validate(test, ast_bucket_is_stale(bucket) == 0);
|
||||||
|
|
||||||
|
bucket_test_wizard_state.is_stale = 1;
|
||||||
|
|
||||||
|
ast_test_validate(test, ast_bucket_is_stale(bucket) == 1);
|
||||||
|
|
||||||
|
return AST_TEST_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
AST_TEST_DEFINE(bucket_json)
|
AST_TEST_DEFINE(bucket_json)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_bucket *, bucket, NULL, ao2_cleanup);
|
||||||
@@ -440,6 +526,52 @@ AST_TEST_DEFINE(bucket_file_create)
|
|||||||
return AST_TEST_PASS;
|
return AST_TEST_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AST_TEST_DEFINE(bucket_file_clone)
|
||||||
|
{
|
||||||
|
RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
|
||||||
|
RAII_VAR(struct ast_bucket_file *, clone, NULL, ao2_cleanup);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case TEST_INIT:
|
||||||
|
info->name = "bucket_file_clone";
|
||||||
|
info->category = "/main/bucket/";
|
||||||
|
info->summary = "file clone unit test";
|
||||||
|
info->description =
|
||||||
|
"Test cloning a file";
|
||||||
|
return AST_TEST_NOT_RUN;
|
||||||
|
case TEST_EXECUTE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
|
||||||
|
ast_test_status_update(test, "Failed to allocate file\n");
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket_test_wizard_clear();
|
||||||
|
|
||||||
|
if (ast_bucket_file_create(file)) {
|
||||||
|
ast_test_status_update(test, "Failed to create file with URI '%s'\n",
|
||||||
|
ast_sorcery_object_get_id(file));
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
ast_bucket_file_metadata_set(file, "bob", "joe");
|
||||||
|
|
||||||
|
clone = ast_bucket_file_clone(file);
|
||||||
|
if (!clone) {
|
||||||
|
ast_test_status_update(test, "Failed to clone file with URI '%s'\n",
|
||||||
|
ast_sorcery_object_get_id(file));
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_test_validate(test, strcmp(ast_sorcery_object_get_id(file), ast_sorcery_object_get_id(clone)) == 0);
|
||||||
|
ast_test_validate(test, file->scheme_impl == clone->scheme_impl);
|
||||||
|
ast_test_validate(test, strcmp(file->scheme, clone->scheme) == 0);
|
||||||
|
ast_test_validate(test, ao2_container_count(file->metadata) == ao2_container_count(clone->metadata));
|
||||||
|
|
||||||
|
return AST_TEST_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
AST_TEST_DEFINE(bucket_file_copy)
|
AST_TEST_DEFINE(bucket_file_copy)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
|
||||||
@@ -625,6 +757,38 @@ AST_TEST_DEFINE(bucket_file_delete)
|
|||||||
return AST_TEST_PASS;
|
return AST_TEST_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AST_TEST_DEFINE(bucket_file_is_stale)
|
||||||
|
{
|
||||||
|
RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case TEST_INIT:
|
||||||
|
info->name = "bucket_file_is_stale";
|
||||||
|
info->category = "/main/bucket/";
|
||||||
|
info->summary = "file staleness unit test";
|
||||||
|
info->description =
|
||||||
|
"Test if staleness of a bucket file is reported correctly";
|
||||||
|
return AST_TEST_NOT_RUN;
|
||||||
|
case TEST_EXECUTE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(file = ast_bucket_file_alloc("test:///tmp/bob"))) {
|
||||||
|
ast_test_status_update(test, "Failed to allocate file\n");
|
||||||
|
return AST_TEST_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket_test_wizard_clear();
|
||||||
|
|
||||||
|
ast_test_validate(test, ast_bucket_file_is_stale(file) == 0);
|
||||||
|
|
||||||
|
bucket_test_wizard_state.is_stale = 1;
|
||||||
|
|
||||||
|
ast_test_validate(test, ast_bucket_file_is_stale(file) == 1);
|
||||||
|
|
||||||
|
return AST_TEST_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
AST_TEST_DEFINE(bucket_file_metadata_set)
|
AST_TEST_DEFINE(bucket_file_metadata_set)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_bucket_file *, file, NULL, ao2_cleanup);
|
||||||
@@ -827,11 +991,13 @@ static int unload_module(void)
|
|||||||
AST_TEST_UNREGISTER(bucket_scheme_register);
|
AST_TEST_UNREGISTER(bucket_scheme_register);
|
||||||
AST_TEST_UNREGISTER(bucket_alloc);
|
AST_TEST_UNREGISTER(bucket_alloc);
|
||||||
AST_TEST_UNREGISTER(bucket_create);
|
AST_TEST_UNREGISTER(bucket_create);
|
||||||
|
AST_TEST_UNREGISTER(bucket_clone);
|
||||||
AST_TEST_UNREGISTER(bucket_delete);
|
AST_TEST_UNREGISTER(bucket_delete);
|
||||||
AST_TEST_UNREGISTER(bucket_retrieve);
|
AST_TEST_UNREGISTER(bucket_retrieve);
|
||||||
AST_TEST_UNREGISTER(bucket_json);
|
AST_TEST_UNREGISTER(bucket_json);
|
||||||
AST_TEST_UNREGISTER(bucket_file_alloc);
|
AST_TEST_UNREGISTER(bucket_file_alloc);
|
||||||
AST_TEST_UNREGISTER(bucket_file_create);
|
AST_TEST_UNREGISTER(bucket_file_create);
|
||||||
|
AST_TEST_UNREGISTER(bucket_file_clone);
|
||||||
AST_TEST_UNREGISTER(bucket_file_copy);
|
AST_TEST_UNREGISTER(bucket_file_copy);
|
||||||
AST_TEST_UNREGISTER(bucket_file_retrieve);
|
AST_TEST_UNREGISTER(bucket_file_retrieve);
|
||||||
AST_TEST_UNREGISTER(bucket_file_update);
|
AST_TEST_UNREGISTER(bucket_file_update);
|
||||||
@@ -854,15 +1020,19 @@ static int load_module(void)
|
|||||||
AST_TEST_REGISTER(bucket_scheme_register);
|
AST_TEST_REGISTER(bucket_scheme_register);
|
||||||
AST_TEST_REGISTER(bucket_alloc);
|
AST_TEST_REGISTER(bucket_alloc);
|
||||||
AST_TEST_REGISTER(bucket_create);
|
AST_TEST_REGISTER(bucket_create);
|
||||||
|
AST_TEST_REGISTER(bucket_clone);
|
||||||
AST_TEST_REGISTER(bucket_delete);
|
AST_TEST_REGISTER(bucket_delete);
|
||||||
AST_TEST_REGISTER(bucket_retrieve);
|
AST_TEST_REGISTER(bucket_retrieve);
|
||||||
|
AST_TEST_REGISTER(bucket_is_stale);
|
||||||
AST_TEST_REGISTER(bucket_json);
|
AST_TEST_REGISTER(bucket_json);
|
||||||
AST_TEST_REGISTER(bucket_file_alloc);
|
AST_TEST_REGISTER(bucket_file_alloc);
|
||||||
AST_TEST_REGISTER(bucket_file_create);
|
AST_TEST_REGISTER(bucket_file_create);
|
||||||
|
AST_TEST_REGISTER(bucket_file_clone);
|
||||||
AST_TEST_REGISTER(bucket_file_copy);
|
AST_TEST_REGISTER(bucket_file_copy);
|
||||||
AST_TEST_REGISTER(bucket_file_retrieve);
|
AST_TEST_REGISTER(bucket_file_retrieve);
|
||||||
AST_TEST_REGISTER(bucket_file_update);
|
AST_TEST_REGISTER(bucket_file_update);
|
||||||
AST_TEST_REGISTER(bucket_file_delete);
|
AST_TEST_REGISTER(bucket_file_delete);
|
||||||
|
AST_TEST_REGISTER(bucket_file_is_stale);
|
||||||
AST_TEST_REGISTER(bucket_file_metadata_set);
|
AST_TEST_REGISTER(bucket_file_metadata_set);
|
||||||
AST_TEST_REGISTER(bucket_file_metadata_unset);
|
AST_TEST_REGISTER(bucket_file_metadata_unset);
|
||||||
AST_TEST_REGISTER(bucket_file_metadata_get);
|
AST_TEST_REGISTER(bucket_file_metadata_get);
|
||||||
|
|||||||
Reference in New Issue
Block a user