lttng/session.h \
lttng/snapshot.h \
lttng/tracker.h \
+ lttng/trace-format-descriptor.h \
lttng/userspace-probe.h
lttngactioninclude_HEADERS= \
lttng/session-internal.hpp \
lttng/snapshot-internal.hpp \
lttng/trigger/trigger-internal.hpp \
+ lttng/trace-format-descriptor-internal.hpp \
lttng/userspace-probe-internal.hpp \
version.hpp \
version.i
#include <lttng/event-expr.h>
#include <lttng/event-field-value.h>
#include <lttng/event-rule/event-rule.h>
-#include <lttng/event-rule/log4j-logging.h>
#include <lttng/event-rule/jul-logging.h>
#include <lttng/event-rule/kernel-kprobe.h>
#include <lttng/event-rule/kernel-syscall.h>
-#include <lttng/event-rule/python-logging.h>
#include <lttng/event-rule/kernel-tracepoint.h>
#include <lttng/event-rule/kernel-uprobe.h>
+#include <lttng/event-rule/log4j-logging.h>
+#include <lttng/event-rule/python-logging.h>
#include <lttng/event-rule/user-tracepoint.h>
#include <lttng/event.h>
#include <lttng/handle.h>
#include <lttng/session-descriptor.h>
#include <lttng/session.h>
#include <lttng/snapshot.h>
+#include <lttng/trace-format-descriptor.h>
#include <lttng/tracker.h>
#include <lttng/trigger/trigger.h>
#include <lttng/userspace-probe.h>
--- /dev/null
+/*
+ * Copyright (C) 2022 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_TRACE_FORMAT_DESCRIPTOR_INTERNAL_HPP
+#define LTTNG_TRACE_FORMAT_DESCRIPTOR_INTERNAL_HPP
+
+#include <bits/stdint-uintn.h>
+#include <common/config/session-config.hpp>
+#include <common/dynamic-array.hpp>
+#include <common/macros.hpp>
+#include <common/optional.hpp>
+#include <cstdint>
+#include <functional>
+#include <lttng/lttng.h>
+#include <lttng/trace-format-descriptor.h>
+#include <memory>
+#include <pthread.h>
+#include <sys/types.h>
+#include <unordered_map>
+#include <urcu/ref.h>
+
+struct lttng_payload;
+struct lttng_payload_view;
+struct mi_writer;
+
+struct lttng_trace_format_descriptor_comm {
+ uint8_t type;
+};
+
+namespace lttng {
+class trace_format_descriptor {
+public:
+ using uptr = std::unique_ptr<trace_format_descriptor>;
+ using sptr = std::shared_ptr<trace_format_descriptor>;
+ explicit trace_format_descriptor(enum lttng_trace_format_descriptor_type type) : _type(type)
+ {
+ }
+
+ virtual ~trace_format_descriptor();
+ virtual uptr clone() const = 0; // Virtual constructor (copying)
+
+ enum lttng_trace_format_descriptor_type type() const
+ {
+ return _type;
+ }
+
+ virtual lttng_error_code mi_serialize(mi_writer *writer) const final;
+ virtual lttng_error_code config_serialize(config_writer *writer) const final;
+ virtual int serialize(lttng_payload *payload) const;
+ static ssize_t create_from_payload(lttng_payload_view *view, uptr& descriptor);
+
+ friend bool operator==(
+ trace_format_descriptor const& lhs, trace_format_descriptor const& rhs)
+ {
+ if (lhs.type() != rhs.type()) {
+ return false;
+ }
+ return lhs.equal_to(rhs);
+ }
+
+ friend bool operator!=(
+ trace_format_descriptor const& lhs, trace_format_descriptor const& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+protected:
+ using DeserializerFunction =
+ std::function<ssize_t(lttng_payload_view *view, uptr& descriptor)>;
+ using deserializer_map =
+ std::unordered_map<lttng_trace_format_descriptor_type, DeserializerFunction>;
+
+ static deserializer_map _deserializer_map;
+ virtual bool equal_to(trace_format_descriptor const& rhs) const = 0;
+
+private:
+ enum lttng_trace_format_descriptor_type _type = LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_UNKNOWN;
+
+ virtual lttng_error_code subtype_mi_serialize(mi_writer *writer) const = 0;
+ virtual lttng_error_code subtype_config_serialize(config_writer *writer) const = 0;
+};
+
+class trace_format_descriptor_ctf1 : public trace_format_descriptor {
+public:
+ trace_format_descriptor_ctf1() :
+ trace_format_descriptor(LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1)
+ {
+ } // Default constructor.
+
+ trace_format_descriptor_ctf1(trace_format_descriptor_ctf1 const&) :
+ trace_format_descriptor_ctf1()
+ {
+ } // Copy constructor
+
+ uptr clone() const
+ {
+ return uptr(new trace_format_descriptor_ctf1(*this));
+ }
+
+ uint64_t getMajor() const
+ {
+ return _major;
+ }
+ uint64_t getMinor() const
+ {
+ return _minor;
+ }
+
+protected:
+ static ssize_t deserialize(lttng_payload_view *view, uptr& descriptor);
+ bool equal_to(trace_format_descriptor const& rhs) const override;
+
+private:
+ lttng_error_code subtype_mi_serialize(mi_writer *writer) const override;
+ lttng_error_code subtype_config_serialize(config_writer *writer) const override;
+
+ const uint64_t _major = 1;
+ const uint64_t _minor = 8;
+};
+
+class trace_format_descriptor_ctf2 : public trace_format_descriptor {
+public:
+ trace_format_descriptor_ctf2() :
+ trace_format_descriptor(LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2)
+ {
+ }
+
+ trace_format_descriptor_ctf2(trace_format_descriptor_ctf2 const&) :
+ trace_format_descriptor_ctf2()
+ {
+ } // Copy constructor
+
+ uptr clone() const
+ {
+ return uptr(new trace_format_descriptor_ctf2(*this));
+ }
+
+ uint64_t getMajor() const
+ {
+ return _major;
+ }
+ uint64_t getMinor() const
+ {
+ return _minor;
+ }
+
+protected:
+ static ssize_t deserialize(lttng_payload_view *view, uptr& descriptor);
+ bool equal_to(trace_format_descriptor const& rhs) const override;
+
+private:
+ lttng_error_code subtype_mi_serialize(mi_writer *writer) const override;
+ lttng_error_code subtype_config_serialize(config_writer *writer) const override;
+ const uint64_t _major = 2;
+ const uint64_t _minor = 0;
+};
+} // namespace lttng
+
+#endif /* LTTNG_TRACE_FORMAT_DESCRIPTOR_INTERNAL_HPP */
--- /dev/null
+/*
+ * Copyright (C) 2022 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_TRACE_FORMAT_DESCRIPTOR_H
+#define LTTNG_TRACE_FORMAT_DESCRIPTOR_H
+
+#include <inttypes.h>
+#include <lttng/lttng-export.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct lttng_trace_format_descriptor;
+
+enum lttng_trace_format_descriptor_status {
+ LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID = -1,
+ LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK = 0,
+};
+
+enum lttng_trace_format_descriptor_type {
+ LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_UNKNOWN = -1,
+ LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1 = 0,
+ LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2 = 1,
+};
+
+LTTNG_EXPORT extern enum lttng_trace_format_descriptor_type lttng_trace_format_get_type(
+ const struct lttng_trace_format_descriptor *descriptor);
+
+LTTNG_EXPORT extern struct lttng_trace_format_descriptor *
+lttng_trace_format_ctf_1_descriptor_create(void);
+
+LTTNG_EXPORT extern enum lttng_trace_format_descriptor_status lttng_trace_format_ctf_1_get_version(
+ const struct lttng_trace_format_descriptor *descriptor,
+ uint64_t *major,
+ uint64_t *minor);
+
+LTTNG_EXPORT extern struct lttng_trace_format_descriptor *
+lttng_trace_format_ctf_2_descriptor_create(void);
+
+LTTNG_EXPORT extern enum lttng_trace_format_descriptor_status lttng_trace_format_ctf_2_get_version(
+ const struct lttng_trace_format_descriptor *descriptor,
+ uint64_t *major,
+ uint64_t *minor);
+
+LTTNG_EXPORT void lttng_trace_format_descriptor_destroy(
+ struct lttng_trace_format_descriptor *descriptor);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LTTNG_TRACE_FORMAT_DESCRIPTOR_H */
spawn-viewer.cpp spawn-viewer.hpp \
thread.cpp thread.hpp \
time.cpp \
+ trace-format-descriptor.cpp \
tracker.cpp tracker.hpp \
trigger.cpp \
unix.cpp unix.hpp \
extern const char * const config_event_context_vegid;
extern const char * const config_event_context_vsgid;
+extern const char * const config_element_session_trace_format;
+extern const char * const config_element_session_trace_format_ctf1;
+extern const char * const config_element_session_trace_format_ctf2;
+
#endif /* CONFIG_SESSION_INTERNAL_H */
const char * const config_event_context_vegid = "VEGID";
const char * const config_event_context_vsgid = "VSGID";
+const char * const config_element_session_trace_format = "trace_format";
+const char * const config_element_session_trace_format_ctf1 = "ctf1";
+const char * const config_element_session_trace_format_ctf2 = "ctf2";
+
+
/* Deprecated symbols */
LTTNG_EXPORT const char *config_element_perf;
--- /dev/null
+/*
+ * Copyright (C) 2022 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include <bits/stdint-intn.h>
+#include <common/mi-lttng.hpp>
+#include <common/payload-view.hpp>
+#include <common/payload.hpp>
+#include <lttng/lttng-error.h>
+#include <lttng/trace-format-descriptor-internal.hpp>
+#include <lttng/trace-format-descriptor.h>
+#include <memory>
+
+namespace lttng {
+/* Initialize deserializer map */
+trace_format_descriptor::deserializer_map trace_format_descriptor::_deserializer_map;
+
+template <class type, lttng_trace_format_descriptor_type enumType>
+class deserializer_register {
+private:
+ class initializer : public type {
+ public:
+ initializer()
+ {
+ type::_deserializer_map[enumType] = type::deserialize;
+ }
+ };
+
+public:
+ deserializer_register()
+ {
+ deserializer_register::initializer i;
+ }
+};
+
+/* Default destructor for the base type */
+trace_format_descriptor::~trace_format_descriptor() = default;
+
+static deserializer_register<trace_format_descriptor_ctf1, LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1>
+ ctf1Deserializer;
+static deserializer_register<trace_format_descriptor_ctf2, LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2>
+ ctf2Deserializer;
+
+enum lttng_error_code trace_format_descriptor::mi_serialize(struct mi_writer *writer) const
+{
+ int ret;
+ enum lttng_error_code ret_code;
+
+ LTTNG_ASSERT(writer);
+
+ /* Open trace format element. */
+ ret = mi_lttng_writer_open_element(writer, config_element_session_trace_format);
+ if (ret) {
+ goto mi_error;
+ }
+
+ /* Serialize underlying descriptor. */
+ ret_code = this->subtype_mi_serialize(writer);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+
+ /* Close trace format element. */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ goto mi_error;
+ }
+ ret_code = LTTNG_OK;
+ goto end;
+mi_error:
+ ret_code = LTTNG_ERR_MI_IO_FAIL;
+end:
+ return ret_code;
+}
+
+lttng_error_code trace_format_descriptor_ctf1::subtype_mi_serialize(mi_writer *writer) const
+{
+ int ret;
+ enum lttng_error_code ret_code;
+
+ LTTNG_ASSERT(writer);
+
+ /* Open ctf1 element. */
+ ret = mi_lttng_writer_open_element(writer, config_element_session_trace_format_ctf1);
+ if (ret) {
+ goto mi_error;
+ }
+
+ ret = mi_lttng_writer_write_element_unsigned_int(
+ writer, mi_lttng_element_version_major, _major);
+ if (ret) {
+ goto mi_error;
+ }
+
+ ret = mi_lttng_writer_write_element_unsigned_int(
+ writer, mi_lttng_element_version_minor, _minor);
+ if (ret) {
+ goto mi_error;
+ }
+
+ /* Close ctf1 element. */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ goto mi_error;
+ }
+ ret_code = LTTNG_OK;
+ goto end;
+mi_error:
+ ret_code = LTTNG_ERR_MI_IO_FAIL;
+end:
+ return ret_code;
+}
+
+lttng_error_code trace_format_descriptor_ctf2::subtype_mi_serialize(mi_writer *writer) const
+{
+ int ret;
+ enum lttng_error_code ret_code;
+
+ LTTNG_ASSERT(writer);
+
+ /* Open ctf2 element. */
+ ret = mi_lttng_writer_open_element(writer, config_element_session_trace_format_ctf2);
+ if (ret) {
+ goto mi_error;
+ }
+
+ ret = mi_lttng_writer_write_element_unsigned_int(
+ writer, mi_lttng_element_version_major, _major);
+ if (ret) {
+ goto mi_error;
+ }
+
+ ret = mi_lttng_writer_write_element_unsigned_int(
+ writer, mi_lttng_element_version_minor, _minor);
+ if (ret) {
+ goto mi_error;
+ }
+
+ /* Close ctf2 element. */
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ goto mi_error;
+ }
+ ret_code = LTTNG_OK;
+ goto end;
+mi_error:
+ ret_code = LTTNG_ERR_MI_IO_FAIL;
+end:
+ return ret_code;
+}
+
+enum lttng_error_code trace_format_descriptor::config_serialize(config_writer *writer) const
+{
+ int ret;
+ enum lttng_error_code ret_code;
+
+ LTTNG_ASSERT(writer);
+
+ /* Open trace format element. */
+ ret = config_writer_open_element(writer, config_element_session_trace_format);
+ if (ret) {
+ goto mi_error;
+ }
+
+ /* Serialize underlying descriptor. */
+ ret_code = this->subtype_config_serialize(writer);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+
+ /* Close trace format element. */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ goto mi_error;
+ }
+ ret_code = LTTNG_OK;
+ goto end;
+mi_error:
+ ret_code = LTTNG_ERR_MI_IO_FAIL;
+end:
+ return ret_code;
+}
+
+lttng_error_code trace_format_descriptor_ctf1::subtype_config_serialize(config_writer *writer) const
+{
+ int ret;
+ enum lttng_error_code ret_code;
+
+ LTTNG_ASSERT(writer);
+
+ /* Open ctf1 element. */
+ ret = config_writer_open_element(writer, config_element_session_trace_format_ctf1);
+ if (ret) {
+ goto error;
+ }
+
+ /* Close ctf1 element. */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ goto error;
+ }
+ ret_code = LTTNG_OK;
+ goto end;
+error:
+ ret_code = LTTNG_ERR_SAVE_IO_FAIL;
+end:
+ return ret_code;
+}
+
+lttng_error_code trace_format_descriptor_ctf2::subtype_config_serialize(config_writer *writer) const
+{
+ int ret;
+ enum lttng_error_code ret_code;
+
+ LTTNG_ASSERT(writer);
+
+ /* Open ctf2 element. */
+ ret = config_writer_open_element(writer, config_element_session_trace_format_ctf2);
+ if (ret) {
+ goto error;
+ }
+
+ /* Close ctf2 element. */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ goto error;
+ }
+ ret_code = LTTNG_OK;
+ goto end;
+error:
+ ret_code = LTTNG_ERR_SAVE_IO_FAIL;
+end:
+ return ret_code;
+}
+
+int trace_format_descriptor::serialize(lttng_payload *payload) const
+{
+ struct lttng_trace_format_descriptor_comm comm = {};
+
+ LTTNG_ASSERT(payload);
+
+ comm.type = (int8_t) this->type();
+
+ return lttng_dynamic_buffer_append(&payload->buffer, &comm, sizeof(comm));
+}
+
+ssize_t trace_format_descriptor_ctf1::deserialize(lttng_payload_view *view, uptr& descriptor)
+{
+ int ret = 0;
+
+ /* Nothing to deserialize */
+ (void) view;
+
+ trace_format_descriptor::uptr local_descriptor(new trace_format_descriptor_ctf1);
+ descriptor = std::move(local_descriptor);
+
+ return ret;
+}
+bool trace_format_descriptor_ctf1::equal_to(const trace_format_descriptor& rhs) const
+{
+ trace_format_descriptor_ctf1 const *p =
+ static_cast<trace_format_descriptor_ctf1 const *>(&rhs);
+
+ return _major == p->_major && _minor == p->_minor;
+}
+
+ssize_t trace_format_descriptor_ctf2::deserialize(lttng_payload_view *view, uptr& descriptor)
+{
+ int ret = 0;
+
+ /* Nothing to deserialize */
+ (void) view;
+
+ trace_format_descriptor::uptr local_descriptor(new trace_format_descriptor_ctf2);
+ descriptor = std::move(local_descriptor);
+
+ return ret;
+}
+bool trace_format_descriptor_ctf2::equal_to(const trace_format_descriptor& rhs) const
+{
+ trace_format_descriptor_ctf2 const *p =
+ static_cast<trace_format_descriptor_ctf2 const *>(&rhs);
+
+ return _major == p->_major && _minor == p->_minor;
+}
+
+ssize_t trace_format_descriptor::create_from_payload(lttng_payload_view *view, uptr& descriptor)
+{
+ ssize_t ret = 0, consumed = 0;
+ const struct lttng_trace_format_descriptor_comm *comm;
+ const struct lttng_payload_view comm_view =
+ lttng_payload_view_from_view(view, 0, sizeof(*comm));
+
+ if (!view) {
+ return -1;
+ }
+
+ if (!lttng_payload_view_is_valid(&comm_view)) {
+ /* Payload not large enough to contain the header. */
+ return -1;
+ }
+
+ comm = (typeof(comm)) comm_view.buffer.data;
+ consumed += sizeof(*comm);
+
+ lttng_trace_format_descriptor_type type = (lttng_trace_format_descriptor_type) comm->type;
+ ret = _deserializer_map[type](view, descriptor);
+ if (ret < 0) {
+ return ret;
+ }
+ consumed += ret;
+
+ ret = consumed;
+
+ return ret;
+}
+} // namespace lttng
+
+struct lttng_trace_format_descriptor *lttng_trace_format_ctf_1_descriptor_create()
+{
+ lttng::trace_format_descriptor *descriptor = new lttng::trace_format_descriptor_ctf1();
+ return reinterpret_cast<struct lttng_trace_format_descriptor *>(descriptor);
+}
+
+struct lttng_trace_format_descriptor *lttng_trace_format_ctf_2_descriptor_create()
+{
+ lttng::trace_format_descriptor *descriptor = new lttng::trace_format_descriptor_ctf2();
+ return reinterpret_cast<struct lttng_trace_format_descriptor *>(descriptor);
+}
+
+void lttng_trace_format_descriptor_destroy(lttng_trace_format_descriptor *descriptor)
+{
+ if (descriptor == nullptr) {
+ return;
+ }
+
+ lttng::trace_format_descriptor *_descriptor =
+ reinterpret_cast<lttng::trace_format_descriptor *>(descriptor);
+
+ delete _descriptor;
+}
+
+enum lttng_trace_format_descriptor_status lttng_trace_format_ctf_1_get_version(
+ const struct lttng_trace_format_descriptor *descriptor,
+ uint64_t *major,
+ uint64_t *minor)
+{
+ lttng_trace_format_descriptor_status status;
+ const lttng::trace_format_descriptor *tf;
+ const lttng::trace_format_descriptor_ctf1 *ctf1;
+
+ if (descriptor == nullptr || major == nullptr || minor == nullptr) {
+ status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
+ goto end;
+ }
+
+ tf = reinterpret_cast<const lttng::trace_format_descriptor *>(descriptor);
+
+ if (tf->type() != LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_1) {
+ status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
+ goto end;
+ }
+
+ ctf1 = static_cast<const lttng::trace_format_descriptor_ctf1 *>(tf);
+
+ *major = ctf1->getMajor();
+ *minor = ctf1->getMinor();
+ status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK;
+
+end:
+ return status;
+}
+
+enum lttng_trace_format_descriptor_status lttng_trace_format_ctf_2_get_version(
+ const struct lttng_trace_format_descriptor *descriptor,
+ uint64_t *major,
+ uint64_t *minor)
+{
+ lttng_trace_format_descriptor_status status;
+ const lttng::trace_format_descriptor *tf;
+ const lttng::trace_format_descriptor_ctf2 *ctf2;
+
+ if (descriptor == nullptr || major == nullptr || minor == nullptr) {
+ status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
+ goto end;
+ }
+
+ tf = reinterpret_cast<const lttng::trace_format_descriptor *>(descriptor);
+
+ if (tf->type() != LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_CTF_2) {
+ status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID;
+ goto end;
+ }
+
+ ctf2 = static_cast<const lttng::trace_format_descriptor_ctf2 *>(tf);
+
+ *major = ctf2->getMajor();
+ *minor = ctf2->getMinor();
+ status = LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK;
+
+end:
+ return status;
+}
+enum lttng_trace_format_descriptor_type lttng_trace_format_get_type(
+ const struct lttng_trace_format_descriptor *descriptor)
+{
+ if (!descriptor) {
+ return LTTNG_TRACE_FORMAT_DESCRIPTOR_TYPE_UNKNOWN;
+ }
+
+ auto tf = reinterpret_cast<const lttng::trace_format_descriptor *>(descriptor);
+
+ return tf->type();
+}
lttng_trace_archive_location_relay_get_host
lttng_trace_archive_location_relay_get_protocol_type
lttng_trace_archive_location_relay_get_relative_path
+lttng_trace_format_ctf_1_get_version
+lttng_trace_format_ctf_2_get_version
+lttng_trace_format_descriptor_destroy
+lttng_trace_format_get_type
lttng_track_pid
lttng_trigger_create
lttng_trigger_destroy
test_utils_expand_path \
test_utils_parse_size_suffix \
test_utils_parse_time_suffix \
+ test_trace_format_descriptor \
test_uuid
LIBTAP=$(top_builddir)/tests/utils/tap/libtap.la
test_relayd_backward_compat_group_by_session \
test_session \
test_string_utils \
+ test_trace_format_descriptor \
test_unix_socket \
test_uri \
test_utils_compat_poll \
# Action api
test_action_SOURCES = test_action.cpp
test_action_LDADD = $(LIBTAP) $(LIBCOMMON_GPL) $(LIBLTTNG_CTL) $(DL_LIBS)
+
+# Trace format descriptor
+test_trace_format_descriptor_SOURCES = test_trace_format_descriptor.cpp
+test_trace_format_descriptor_LDADD = $(LIBTAP) $(LIBCOMMON_GPL) $(LIBLTTNG_CTL) $(DL_LIBS)
--- /dev/null
+/*
+ * Unit tests for the trace format descriptor API.
+ *
+ * Copyright (C) 2022 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <tap/tap.h>
+
+#include <common/payload-view.hpp>
+#include <common/payload.hpp>
+#include <lttng/trace-format-descriptor-internal.hpp>
+#include <lttng/trace-format-descriptor.h>
+
+/* For error.h */
+int lttng_opt_quiet = 1;
+int lttng_opt_verbose;
+int lttng_opt_mi;
+
+#define NUM_TESTS 28
+
+static void test_trace_format_descriptor_base(void)
+{
+ lttng_trace_format_descriptor_status status;
+ uint64_t major;
+ uint64_t minor;
+
+ lttng_trace_format_descriptor *ctf1 = lttng_trace_format_ctf_1_descriptor_create();
+ lttng_trace_format_descriptor *ctf2 = lttng_trace_format_ctf_2_descriptor_create();
+ ok1(ctf1);
+ ok1(ctf2);
+
+ /* Ctf 1 */
+ status = lttng_trace_format_ctf_1_get_version(nullptr, nullptr, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_1_get_version(nullptr, nullptr, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_1_get_version(nullptr, &major, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_1_get_version(nullptr, &major, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_1_get_version(ctf1, nullptr, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_1_get_version(ctf1, nullptr, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_1_get_version(ctf1, &major, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+
+ /* Wrong object type */
+ status = lttng_trace_format_ctf_1_get_version(ctf2, &major, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+
+ status = lttng_trace_format_ctf_1_get_version(ctf1, &major, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK);
+ ok1(major == 1);
+ ok1(minor == 8);
+
+ /* Ctf 2 */
+ status = lttng_trace_format_ctf_2_get_version(nullptr, nullptr, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_2_get_version(nullptr, nullptr, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_2_get_version(nullptr, &major, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_2_get_version(nullptr, &major, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_2_get_version(ctf2, nullptr, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_2_get_version(ctf2, nullptr, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+ status = lttng_trace_format_ctf_2_get_version(ctf2, &major, nullptr);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+
+ /* Wrong object type */
+ status = lttng_trace_format_ctf_1_get_version(ctf2, &major, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_INVALID);
+
+ status = lttng_trace_format_ctf_2_get_version(ctf2, &major, &minor);
+ ok1(status == LTTNG_TRACE_FORMAT_DESCRIPTOR_STATUS_OK);
+ ok1(major == 2);
+ ok1(minor == 0);
+
+ lttng_trace_format_descriptor_destroy(ctf1);
+ lttng_trace_format_descriptor_destroy(ctf2);
+}
+
+static void test_trace_format_descriptor_ctf1_ser_des(void)
+{
+ struct lttng_payload buffer;
+ lttng_payload_init(&buffer);
+
+ lttng::trace_format_descriptor::uptr descriptor_from_buffer;
+ lttng::trace_format_descriptor::uptr ctf1(new lttng::trace_format_descriptor_ctf1);
+ lttng::trace_format_descriptor::uptr ctf2(new lttng::trace_format_descriptor_ctf2);
+
+ /* Ctf1 ser/des */
+ ctf1->serialize(&buffer);
+ {
+ struct lttng_payload_view view = lttng_payload_view_from_payload(&buffer, 0, -1);
+
+ (void) lttng::trace_format_descriptor::create_from_payload(
+ &view, descriptor_from_buffer);
+ }
+
+ ok1(*descriptor_from_buffer == *ctf1);
+ ok1(*descriptor_from_buffer != *ctf2);
+
+ lttng_payload_reset(&buffer);
+
+ /* Ctf2 ser/des */
+ ctf2->serialize(&buffer);
+ {
+ struct lttng_payload_view view = lttng_payload_view_from_payload(&buffer, 0, -1);
+
+ (void) lttng::trace_format_descriptor::create_from_payload(
+ &view, descriptor_from_buffer);
+ }
+
+ ok1(*descriptor_from_buffer != *ctf1);
+ ok1(*descriptor_from_buffer == *ctf2);
+
+ lttng_payload_reset(&buffer);
+}
+
+int main(void)
+{
+ plan_tests(NUM_TESTS);
+ test_trace_format_descriptor_base();
+ test_trace_format_descriptor_ctf1_ser_des();
+ return exit_status();
+}