[Tarantool-patches] [PATCH 5/9] error: use error_payload in MessagePack codecs
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Sat Nov 6 02:56:36 MSK 2021
Before this patch mp_error API could only encode and decode
hardcoded fields from the C++ classes inheriting struct error.
The fields are gone from the classes in a previous patch - moved
into error_payload. Now to be able to support arbitrary fields in
the payload the MessagePack encoding/decoding must use its content
instead of hardcoded fields depending on error type.
Part of #5568
---
src/box/error.cc | 7 --
src/box/error.h | 28 +++++-
src/box/mp_error.cc | 194 +++++++++++---------------------------
src/lib/core/diag.c | 17 ++--
src/lib/core/diag.h | 9 ++
src/lib/core/exception.h | 66 +++++++++++++
test/unit/mp_error.cc | 76 ++++++++++++++-
test/unit/mp_error.result | 27 +++++-
8 files changed, 262 insertions(+), 162 deletions(-)
diff --git a/src/box/error.cc b/src/box/error.cc
index 629ec703f..be3b3b6f5 100644
--- a/src/box/error.cc
+++ b/src/box/error.cc
@@ -256,13 +256,6 @@ XlogGapError::XlogGapError(const char *file, unsigned line,
(long long) vclock_sum(to), s_to ? s_to : "");
}
-XlogGapError::XlogGapError(const char *file, unsigned line,
- const char *msg)
- : XlogError(&type_XlogGapError, file, line)
-{
- error_format_msg(this, "%s", msg);
-}
-
struct error *
BuildXlogGapError(const char *file, unsigned line,
const struct vclock *from, const struct vclock *to)
diff --git a/src/box/error.h b/src/box/error.h
index 43faaea70..c2ccf48bb 100644
--- a/src/box/error.h
+++ b/src/box/error.h
@@ -213,6 +213,11 @@ public:
ClientError(const char *file, unsigned line, uint32_t errcode, ...);
+ ClientError()
+ :Exception(&type_ClientError, NULL, 0)
+ {
+ }
+
static uint32_t get_errcode(const struct error *e);
protected:
ClientError(const type_info *type, const char *file, unsigned line,
@@ -243,6 +248,11 @@ public:
const char *object_name, const char *user_name,
bool run_trigers = true);
+ AccessDeniedError()
+ :ClientError(&type_AccessDeniedError, NULL, 0, 0)
+ {
+ }
+
const char *
object_type() const
{
@@ -276,6 +286,12 @@ struct XlogError: public Exception
{
error_vformat_msg(this, format, ap);
}
+
+ XlogError()
+ :Exception(&type_XlogError, NULL, 0)
+ {
+ }
+
XlogError(const struct type_info *type, const char *file,
unsigned line)
:Exception(type, file, line)
@@ -289,8 +305,11 @@ struct XlogGapError: public XlogError
{
XlogGapError(const char *file, unsigned line,
const struct vclock *from, const struct vclock *to);
- XlogGapError(const char *file, unsigned line,
- const char *msg);
+
+ XlogGapError()
+ :XlogError(&type_XlogGapError, NULL, 0)
+ {
+ }
virtual void raise() { throw this; }
};
@@ -301,6 +320,11 @@ public:
CustomError(const char *file, unsigned int line,
const char *custom_type, uint32_t errcode);
+ CustomError()
+ :ClientError(&type_CustomError, NULL, 0, 0)
+ {
+ }
+
virtual void log() const;
const char*
diff --git a/src/box/mp_error.cc b/src/box/mp_error.cc
index 35c770400..fba562a84 100644
--- a/src/box/mp_error.cc
+++ b/src/box/mp_error.cc
@@ -118,35 +118,31 @@ struct mp_error {
const char *type;
const char *file;
const char *message;
- const char *custom_type;
- const char *ad_object_type;
- const char *ad_object_name;
- const char *ad_access_type;
+ struct error_payload payload;
};
static void
mp_error_create(struct mp_error *mp_error)
{
memset(mp_error, 0, sizeof(*mp_error));
+ error_payload_create(&mp_error->payload);
+}
+
+static void
+mp_error_destroy(struct mp_error *mp_error)
+{
+ error_payload_destroy(&mp_error->payload);
}
static uint32_t
mp_sizeof_error_one(const struct error *error)
{
uint32_t errcode = box_error_code(error);
-
- bool is_custom = false;
- bool is_access_denied = false;
-
- if (strcmp(error->type->name, "CustomError") == 0) {
- is_custom = true;
- } else if (strcmp(error->type->name, "AccessDeniedError") == 0) {
- is_access_denied = true;
- }
-
- uint32_t details_num = 6;
+ int field_count = error->payload.count;
+ uint32_t map_size = 6 + (field_count > 0);
uint32_t data_size = 0;
+ data_size += mp_sizeof_map(map_size);
data_size += mp_sizeof_uint(MP_ERROR_TYPE);
data_size += mp_sizeof_str(strlen(error->type->name));
data_size += mp_sizeof_uint(MP_ERROR_LINE);
@@ -160,28 +156,15 @@ mp_sizeof_error_one(const struct error *error)
data_size += mp_sizeof_uint(MP_ERROR_CODE);
data_size += mp_sizeof_uint(errcode);
- if (is_access_denied) {
- ++details_num;
- data_size += mp_sizeof_uint(MP_ERROR_FIELDS);
- data_size += mp_sizeof_map(3);
- AccessDeniedError *ad_err = type_cast(AccessDeniedError, error);
- data_size += mp_sizeof_str(strlen("object_type"));
- data_size += mp_sizeof_str(strlen(ad_err->object_type()));
- data_size += mp_sizeof_str(strlen("object_name"));
- data_size += mp_sizeof_str(strlen(ad_err->object_name()));
- data_size += mp_sizeof_str(strlen("access_type"));
- data_size += mp_sizeof_str(strlen(ad_err->access_type()));
- } else if (is_custom) {
- ++details_num;
+ if (field_count > 0) {
data_size += mp_sizeof_uint(MP_ERROR_FIELDS);
- data_size += mp_sizeof_map(1);
- data_size += mp_sizeof_str(strlen("custom_type"));
- data_size +=
- mp_sizeof_str(strlen(box_error_custom_type(error)));
+ data_size += mp_sizeof_map(field_count);
+ for (int i = 0; i < field_count; ++i) {
+ const struct error_field *f = error->payload.fields[i];
+ data_size += mp_sizeof_str(strlen(f->name));
+ data_size += f->size;
+ }
}
-
- data_size += mp_sizeof_map(details_num);
-
return data_size;
}
@@ -195,21 +178,10 @@ static char *
mp_encode_error_one(char *data, const struct error *error)
{
uint32_t errcode = box_error_code(error);
+ int field_count = error->payload.count;
+ uint32_t map_size = 6 + (field_count > 0);
- bool is_custom = false;
- bool is_access_denied = false;
-
- if (strcmp(error->type->name, "CustomError") == 0) {
- is_custom = true;
- } else if (strcmp(error->type->name, "AccessDeniedError") == 0) {
- is_access_denied = true;
- }
-
- uint32_t details_num = 6;
- if (is_access_denied || is_custom)
- ++details_num;
-
- data = mp_encode_map(data, details_num);
+ data = mp_encode_map(data, map_size);
data = mp_encode_uint(data, MP_ERROR_TYPE);
data = mp_encode_str0(data, error->type->name);
data = mp_encode_uint(data, MP_ERROR_LINE);
@@ -223,21 +195,15 @@ mp_encode_error_one(char *data, const struct error *error)
data = mp_encode_uint(data, MP_ERROR_CODE);
data = mp_encode_uint(data, errcode);
- if (is_access_denied) {
- data = mp_encode_uint(data, MP_ERROR_FIELDS);
- data = mp_encode_map(data, 3);
- AccessDeniedError *ad_err = type_cast(AccessDeniedError, error);
- data = mp_encode_str0(data, "object_type");
- data = mp_encode_str0(data, ad_err->object_type());
- data = mp_encode_str0(data, "object_name");
- data = mp_encode_str0(data, ad_err->object_name());
- data = mp_encode_str0(data, "access_type");
- data = mp_encode_str0(data, ad_err->access_type());
- } else if (is_custom) {
+ if (field_count > 0) {
data = mp_encode_uint(data, MP_ERROR_FIELDS);
- data = mp_encode_map(data, 1);
- data = mp_encode_str0(data, "custom_type");
- data = mp_encode_str0(data, box_error_custom_type(error));
+ data = mp_encode_map(data, field_count);
+ for (int i = 0; i < field_count; ++i) {
+ const struct error_field *f = error->payload.fields[i];
+ data = mp_encode_str0(data, f->name);
+ memcpy(data, f->data, f->size);
+ data += f->size;
+ }
}
return data;
}
@@ -254,72 +220,50 @@ error_build_xc(struct mp_error *mp_error)
struct error *err = NULL;
if (mp_error->type == NULL || mp_error->message == NULL ||
mp_error->file == NULL) {
-missing_fields:
diag_set(ClientError, ER_INVALID_MSGPACK,
"Missing mandatory error fields");
return NULL;
}
if (strcmp(mp_error->type, "ClientError") == 0) {
- err = new ClientError(mp_error->file, mp_error->line,
- ER_UNKNOWN);
+ err = new ClientError();
} else if (strcmp(mp_error->type, "CustomError") == 0) {
- if (mp_error->custom_type == NULL)
- goto missing_fields;
- err = new CustomError(mp_error->file, mp_error->line,
- mp_error->custom_type, mp_error->code);
+ err = new CustomError();
} else if (strcmp(mp_error->type, "AccessDeniedError") == 0) {
- if (mp_error->ad_access_type == NULL ||
- mp_error->ad_object_type == NULL ||
- mp_error->ad_object_name == NULL)
- goto missing_fields;
- err = new AccessDeniedError(mp_error->file, mp_error->line,
- mp_error->ad_access_type,
- mp_error->ad_object_type,
- mp_error->ad_object_name, "",
- false);
+ err = new AccessDeniedError();
} else if (strcmp(mp_error->type, "XlogError") == 0) {
- err = new XlogError(&type_XlogError, mp_error->file,
- mp_error->line);
+ err = new XlogError();
} else if (strcmp(mp_error->type, "XlogGapError") == 0) {
- err = new XlogGapError(mp_error->file, mp_error->line,
- mp_error->message);
+ err = new XlogGapError();
} else if (strcmp(mp_error->type, "SystemError") == 0) {
- err = new SystemError(mp_error->file, mp_error->line,
- "%s", mp_error->message);
+ err = new SystemError();
} else if (strcmp(mp_error->type, "SocketError") == 0) {
- err = new SocketError(mp_error->file, mp_error->line, "", "");
- error_format_msg(err, "%s", mp_error->message);
+ err = new SocketError();
} else if (strcmp(mp_error->type, "OutOfMemory") == 0) {
- err = new OutOfMemory(mp_error->file, mp_error->line,
- 0, "", "");
+ err = new OutOfMemory();
} else if (strcmp(mp_error->type, "TimedOut") == 0) {
- err = new TimedOut(mp_error->file, mp_error->line);
+ err = new TimedOut();
} else if (strcmp(mp_error->type, "ChannelIsClosed") == 0) {
- err = new ChannelIsClosed(mp_error->file, mp_error->line);
+ err = new ChannelIsClosed();
} else if (strcmp(mp_error->type, "FiberIsCancelled") == 0) {
- err = new FiberIsCancelled(mp_error->file, mp_error->line);
+ err = new FiberIsCancelled();
} else if (strcmp(mp_error->type, "LuajitError") == 0) {
- err = new LuajitError(mp_error->file, mp_error->line,
- mp_error->message);
+ err = new LuajitError();
} else if (strcmp(mp_error->type, "IllegalParams") == 0) {
- err = new IllegalParams(mp_error->file, mp_error->line,
- "%s", mp_error->message);
+ err = new IllegalParams();
} else if (strcmp(mp_error->type, "CollationError") == 0) {
- err = new CollationError(mp_error->file, mp_error->line,
- "%s", mp_error->message);
+ err = new CollationError();
} else if (strcmp(mp_error->type, "SwimError") == 0) {
- err = new SwimError(mp_error->file, mp_error->line,
- "%s", mp_error->message);
+ err = new SwimError();
} else if (strcmp(mp_error->type, "CryptoError") == 0) {
- err = new CryptoError(mp_error->file, mp_error->line,
- "%s", mp_error->message);
+ err = new CryptoError();
} else {
- err = new ClientError(mp_error->file, mp_error->line,
- ER_UNKNOWN);
+ err = new ClientError();
}
err->code = mp_error->code;
err->saved_errno = mp_error->saved_errno;
+ error_set_location(err, mp_error->file, mp_error->line);
+ error_move_payload(err, &mp_error->payload);
error_format_msg(err, "%s", mp_error->message);
return err;
}
@@ -350,12 +294,6 @@ mp_decode_and_copy_str(const char **data, struct region *region)
return region_strdup(region, str, str_len);;
}
-static inline bool
-str_nonterm_is_eq(const char *l, const char *r, uint32_t r_len)
-{
- return r_len == strlen(l) && memcmp(l, r, r_len) == 0;
-}
-
static int
mp_decode_error_fields(const char **data, struct mp_error *mp_err,
struct region *region)
@@ -363,35 +301,16 @@ mp_decode_error_fields(const char **data, struct mp_error *mp_err,
if (mp_typeof(**data) != MP_MAP)
return -1;
uint32_t map_sz = mp_decode_map(data);
- const char *key;
- uint32_t key_len;
for (uint32_t i = 0; i < map_sz; ++i) {
- if (mp_typeof(**data) != MP_STR)
+ uint32_t svp = region_used(region);
+ const char *key = mp_decode_and_copy_str(data, region);
+ if (key == NULL)
return -1;
- key = mp_decode_str(data, &key_len);
- if (str_nonterm_is_eq("object_type", key, key_len)) {
- mp_err->ad_object_type =
- mp_decode_and_copy_str(data, region);
- if (mp_err->ad_object_type == NULL)
- return -1;
- } else if (str_nonterm_is_eq("object_name", key, key_len)) {
- mp_err->ad_object_name =
- mp_decode_and_copy_str(data, region);
- if (mp_err->ad_object_name == NULL)
- return -1;
- } else if (str_nonterm_is_eq("access_type", key, key_len)) {
- mp_err->ad_access_type =
- mp_decode_and_copy_str(data, region);
- if (mp_err->ad_access_type == NULL)
- return -1;
- } else if (str_nonterm_is_eq("custom_type", key, key_len)) {
- mp_err->custom_type =
- mp_decode_and_copy_str(data, region);
- if (mp_err->custom_type == NULL)
- return -1;
- } else {
- mp_next(data);
- }
+ const char *value = *data;
+ mp_next(data);
+ uint32_t value_len = *data - value;
+ error_payload_set_mp(&mp_err->payload, key, value, value_len);
+ region_truncate(region, svp);
}
return 0;
}
@@ -462,6 +381,7 @@ mp_decode_error_one(const char **data)
}
finish:
region_truncate(region, region_svp);
+ mp_error_destroy(&mp_err);
return err;
error:
diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c
index 217c3ae7e..b6fa1f5bb 100644
--- a/src/lib/core/diag.c
+++ b/src/lib/core/diag.c
@@ -119,18 +119,21 @@ error_create(struct error *e,
e->saved_errno = 0;
e->code = 0;
error_payload_create(&e->payload);
- if (file != NULL) {
- snprintf(e->file, sizeof(e->file), "%s", file);
- e->line = line;
- } else {
- e->file[0] = '\0';
- e->line = 0;
- }
+ if (file == NULL)
+ file = "";
+ error_set_location(e, file, line);
e->errmsg[0] = '\0';
e->cause = NULL;
e->effect = NULL;
}
+void
+error_set_location(struct error *e, const char *file, int line)
+{
+ snprintf(e->file, sizeof(e->file), "%s", file);
+ e->line = line;
+}
+
struct diag *
diag_get(void)
{
diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h
index 03bd223e1..40d934c19 100644
--- a/src/lib/core/diag.h
+++ b/src/lib/core/diag.h
@@ -190,6 +190,12 @@ error_field_unset(struct error *e, const char *name)
error_payload_unset(&e->payload, name);
}
+static inline void
+error_move_payload(struct error *e, struct error_payload *src)
+{
+ error_payload_move(&e->payload, src);
+}
+
/**
* Unlink error from its effect. For instance:
* e1 -> e2 -> e3 -> e4 (e1:set_prev(e2); e2:set_prev(e3) ...)
@@ -243,6 +249,9 @@ error_create(struct error *e,
const struct type_info *type, const char *file,
unsigned line);
+void
+error_set_location(struct error *e, const char *file, int line);
+
void
error_format_msg(struct error *e, const char *format, ...);
diff --git a/src/lib/core/exception.h b/src/lib/core/exception.h
index 7277b2784..28bc7ef05 100644
--- a/src/lib/core/exception.h
+++ b/src/lib/core/exception.h
@@ -91,6 +91,12 @@ public:
SystemError(const char *file, unsigned line,
const char *format, ...);
+
+ SystemError()
+ :Exception(&type_SystemError, NULL, 0)
+ {
+ }
+
protected:
SystemError(const struct type_info *type, const char *file, unsigned line);
};
@@ -100,6 +106,12 @@ class SocketError: public SystemError {
public:
SocketError(const char *file, unsigned line, const char *socketname,
const char *format, ...);
+
+ SocketError()
+ :SystemError(&type_SocketError, file, line)
+ {
+ }
+
virtual void raise()
{
throw this;
@@ -111,18 +123,36 @@ public:
OutOfMemory(const char *file, unsigned line,
size_t amount, const char *allocator,
const char *object);
+
+ OutOfMemory()
+ :SystemError(&type_OutOfMemory, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
class TimedOut: public SystemError {
public:
TimedOut(const char *file, unsigned line);
+
+ TimedOut()
+ :SystemError(&type_TimedOut, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
class ChannelIsClosed: public Exception {
public:
ChannelIsClosed(const char *file, unsigned line);
+
+ ChannelIsClosed()
+ :Exception(&type_ChannelIsClosed, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
@@ -133,6 +163,12 @@ public:
class FiberIsCancelled: public Exception {
public:
FiberIsCancelled(const char *file, unsigned line);
+
+ FiberIsCancelled()
+ :Exception(&type_FiberIsCancelled, NULL, 0)
+ {
+ }
+
virtual void log() const;
virtual void raise() { throw this; }
};
@@ -141,12 +177,24 @@ class LuajitError: public Exception {
public:
LuajitError(const char *file, unsigned line,
const char *msg);
+
+ LuajitError()
+ :Exception(&type_LuajitError, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
class IllegalParams: public Exception {
public:
IllegalParams(const char *file, unsigned line, const char *format, ...);
+
+ IllegalParams()
+ :Exception(&type_IllegalParams, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
@@ -154,18 +202,36 @@ class CollationError: public Exception {
public:
CollationError(const char *file, unsigned line, const char *format,
...);
+
+ CollationError()
+ :Exception(&type_CollationError, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
class SwimError: public Exception {
public:
SwimError(const char *file, unsigned line, const char *format, ...);
+
+ SwimError()
+ :Exception(&type_SwimError, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
class CryptoError: public Exception {
public:
CryptoError(const char *file, unsigned line, const char *format, ...);
+
+ CryptoError()
+ :Exception(&type_CryptoError, NULL, 0)
+ {
+ }
+
virtual void raise() { throw this; }
};
diff --git a/test/unit/mp_error.cc b/test/unit/mp_error.cc
index fe0cd49b9..e6560883e 100644
--- a/test/unit/mp_error.cc
+++ b/test/unit/mp_error.cc
@@ -34,9 +34,11 @@
#include "memory.h"
#include "msgpuck.h"
#include "mp_extension_types.h"
+#include "random.h"
#include "tt_static.h"
#include "small/ibuf.h"
#include "mpstream/mpstream.h"
+#include "uuid/tt_uuid.h"
#include "box/error.h"
#include "box/mp_error.h"
@@ -362,7 +364,7 @@ void
test_fail_not_enough_fields()
{
header();
- plan(2);
+ plan(4);
char buffer[2048];
memset(buffer, 0, sizeof(buffer));
@@ -383,8 +385,12 @@ test_fail_not_enough_fields()
const char *pos = buffer;
struct error *unpacked = error_unpack(&pos, len);
- is(unpacked, NULL, "check not enough additional fields");
- ok(!diag_is_empty(diag_get()), "error about parsing problem is set");
+ isnt(unpacked, NULL, "check lack of fields");
+ is(strcmp(error_field_get_str(unpacked, "object_type"),
+ err.ad_object_type), 0, "object type");
+ is(strcmp(error_field_get_str(unpacked, "access_type"),
+ err.ad_access_type), 0, "access type");
+ is(error_field_get_str(unpacked, "object_name"), NULL, "object name");
check_plan();
footer();
}
@@ -455,6 +461,65 @@ test_unknown_additional_fields()
footer();
}
+static void
+test_payload(void)
+{
+ header();
+ plan(11);
+ char buffer[2048];
+ memset(buffer, 0, sizeof(buffer));
+
+ struct error *e = new ClientError();
+ error_ref(e);
+ e->code = 42;
+ e->saved_errno = 1;
+ error_format_msg(e, "msg");
+ error_set_location(e, "file", 2);
+ error_field_set_str(e, "key1", "1");
+ error_field_set_uint(e, "key2", 1);
+ error_field_set_int(e, "key3", -1);
+ error_field_set_double(e, "key4", 1.5);
+ error_field_set_bool(e, "key5", true);
+ struct tt_uuid uuid;
+ tt_uuid_create(&uuid);
+ error_field_set_uuid(e, "key6", &uuid);
+
+ mp_encode_error(buffer, e);
+ error_unref(e);
+
+ int8_t type;
+ const char *data = buffer;
+ mp_decode_extl(&data, &type);
+ e = error_unpack_unsafe(&data);
+ error_ref(e);
+
+ is(e->code, 42, "code");
+ is(e->saved_errno, 1, "errno");
+ is(strcmp(e->errmsg, "msg"), 0, "msg");
+ is(e->line, 2, "line");
+ is(strcmp(e->file, "file"), 0, "file");
+ is(strcmp(error_field_get_str(e, "key1"), "1"), 0, "key str");
+ uint64_t val_uint;
+ ok(error_field_get_uint(e, "key2", &val_uint) && val_uint == 1,
+ "key uint");
+ int64_t val_int;
+ ok(error_field_get_int(e, "key3", &val_int) && val_int == -1,
+ "key int");
+ double val_dbl;
+ ok(error_field_get_double(e, "key4", &val_dbl) && val_dbl == 1.5,
+ "key double");
+ bool val_bool;
+ ok(error_field_get_bool(e, "key5", &val_bool) && val_bool, "key bool");
+ struct tt_uuid val_uuid;
+ ok(error_field_get_uuid(e, "key6", &val_uuid) &&
+ tt_uuid_is_equal(&uuid, &val_uuid), "key uuid");
+
+ error_unref(e);
+
+ check_plan();
+ footer();
+}
+
static int
mp_fprint_ext_test(FILE *file, const char **data, int depth)
{
@@ -723,7 +788,8 @@ int
main(void)
{
header();
- plan(6);
+ plan(7);
+ random_init();
memory_init();
fiber_init(fiber_c_invoke);
@@ -732,10 +798,12 @@ main(void)
test_fail_not_enough_fields();
test_unknown_fields();
test_unknown_additional_fields();
+ test_payload();
test_mp_print();
fiber_free();
memory_free();
+ random_free();
footer();
return check_plan();
}
diff --git a/test/unit/mp_error.result b/test/unit/mp_error.result
index 0582458d3..356d2dc97 100644
--- a/test/unit/mp_error.result
+++ b/test/unit/mp_error.result
@@ -1,5 +1,5 @@
*** main ***
-1..6
+1..7
*** test_stack_error_decode ***
1..17
ok 1 - check CustomError
@@ -27,9 +27,11 @@ ok 1 - subtests
ok 2 - subtests
*** test_decode_unknown_type: done ***
*** test_fail_not_enough_fields ***
- 1..2
- ok 1 - check not enough additional fields
- ok 2 - error about parsing problem is set
+ 1..4
+ ok 1 - check lack of fields
+ ok 2 - object type
+ ok 3 - access type
+ ok 4 - object name
ok 3 - subtests
*** test_fail_not_enough_fields: done ***
*** test_unknown_fields ***
@@ -41,6 +43,21 @@ ok 4 - subtests
ok 1 - check unknown additional field
ok 5 - subtests
*** test_unknown_additional_fields: done ***
+ *** test_payload ***
+ 1..11
+ ok 1 - code
+ ok 2 - errno
+ ok 3 - msg
+ ok 4 - line
+ ok 5 - file
+ ok 6 - key str
+ ok 7 - key uint
+ ok 8 - key int
+ ok 9 - key double
+ ok 10 - key bool
+ ok 11 - key uuid
+ok 6 - subtests
+ *** test_payload: done ***
*** test_mp_print ***
1..60
# zero depth, normal error
@@ -109,6 +126,6 @@ ok 5 - subtests
ok 58 - mp_fprint depth 0 correct length
ok 59 - mp_fprint depth 0 correct prefix and suffix
ok 60 - mp_fprint depth 0 correct object in the middle
-ok 6 - subtests
+ok 7 - subtests
*** test_mp_print: done ***
*** main: done ***
--
2.24.3 (Apple Git-128)
More information about the Tarantool-patches
mailing list