/*
 * This file is part of the PCEPlib, a PCEP protocol library.
 *
 * Copyright (C) 2020 Volta Networks https://voltanet.io/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * Author : Brady Johnson <brady@voltanet.io>
 *
 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
#include <assert.h>

#include <CUnit/CUnit.h>

#include "pcep_msg_encoding.h"
#include "pcep_msg_messages.h"
#include "pcep_msg_objects.h"
#include "pcep_msg_tools.h"
#include "pcep_utils_double_linked_list.h"
#include "pcep_utils_memory.h"
#include "pcep_msg_messages_test.h"

/*
 * Notice:
 * All of these message Unit Tests encode the created messages by explicitly
 * calling pcep_encode_message() thus testing the message creation and the
 * message encoding.
 */

static struct pcep_versioning *versioning = NULL;

int pcep_messages_test_suite_setup(void)
{
	pceplib_memory_reset();
	return 0;
}

int pcep_messages_test_suite_teardown(void)
{
	printf("\n");
	pceplib_memory_dump();
	return 0;
}

void pcep_messages_test_setup()
{
	versioning = create_default_pcep_versioning();
}

void pcep_messages_test_teardown()
{
	destroy_pcep_versioning(versioning);
}

void test_pcep_msg_create_open()
{
	uint8_t keepalive = 30;
	uint8_t deadtimer = 60;
	uint8_t sid = 255;

	struct pcep_message *message =
		pcep_msg_create_open(keepalive, deadtimer, sid);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 1);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ pcep_object_get_length(PCEP_OBJ_CLASS_OPEN,
							 PCEP_OBJ_TYPE_OPEN));
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_OPEN);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	/* Just check the class and type, the rest of the hdr fields
	 * are verified in pcep-objects-test.c */
	struct pcep_object_open *open_obj =
		(struct pcep_object_open *)message->obj_list->head->data;
	CU_ASSERT_EQUAL(open_obj->header.object_class, PCEP_OBJ_CLASS_OPEN);
	CU_ASSERT_EQUAL(open_obj->header.object_type, PCEP_OBJ_TYPE_OPEN);

	CU_ASSERT_EQUAL(open_obj->open_deadtimer, deadtimer);
	CU_ASSERT_EQUAL(open_obj->open_keepalive, keepalive);
	CU_ASSERT_EQUAL(open_obj->open_sid, sid);
	CU_ASSERT_EQUAL(open_obj->open_version, PCEP_OBJECT_OPEN_VERSION);
	pcep_msg_free_message(message);
}


void test_pcep_msg_create_request()
{
	/* First test with NULL objects */
	struct pcep_message *message =
		pcep_msg_create_request(NULL, NULL, NULL);
	CU_ASSERT_PTR_NULL(message);

	/* Test IPv4 */
	struct pcep_object_rp *rp_obj =
		pcep_obj_create_rp(0, false, false, false, false, 10, NULL);
	struct in_addr src_addr = {}, dst_addr = {};
	struct pcep_object_endpoints_ipv4 *ipv4_obj =
		pcep_obj_create_endpoint_ipv4(&src_addr, &dst_addr);
	message = pcep_msg_create_request(rp_obj, ipv4_obj, NULL);

	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 2);
	CU_ASSERT_EQUAL(
		message->encoded_message_length,
		MESSAGE_HEADER_LENGTH
			+ pcep_object_get_length_by_hdr(&rp_obj->header)
			+ pcep_object_get_length_by_hdr(&ipv4_obj->header));
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCREQ);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);
	pcep_msg_free_message(message);

	/* Test IPv6 */
	rp_obj = pcep_obj_create_rp(0, false, false, false, false, 10, NULL);
	struct in6_addr src_addr_ipv6 = {}, dst_addr_ipv6 = {};
	struct pcep_object_endpoints_ipv6 *ipv6_obj =
		pcep_obj_create_endpoint_ipv6(&src_addr_ipv6, &dst_addr_ipv6);
	message = pcep_msg_create_request_ipv6(rp_obj, ipv6_obj, NULL);

	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 2);
	CU_ASSERT_EQUAL(
		message->encoded_message_length,
		MESSAGE_HEADER_LENGTH
			+ pcep_object_get_length_by_hdr(&rp_obj->header)
			+ pcep_object_get_length_by_hdr(&ipv6_obj->header));
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCREQ);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);
	pcep_msg_free_message(message);

	/* The objects get deleted with the message, so they need to be created
	 * again */
	rp_obj = pcep_obj_create_rp(0, false, false, false, false, 10, NULL);
	ipv4_obj = pcep_obj_create_endpoint_ipv4(&src_addr, &dst_addr);
	struct pcep_object_bandwidth *bandwidth_obj =
		pcep_obj_create_bandwidth(4.2);
	double_linked_list *obj_list = dll_initialize();
	dll_append(obj_list, bandwidth_obj);
	message = pcep_msg_create_request(rp_obj, ipv4_obj, obj_list);

	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 3);
	CU_ASSERT_EQUAL(
		message->encoded_message_length,
		MESSAGE_HEADER_LENGTH
			+ pcep_object_get_length_by_hdr(&rp_obj->header)
			+ pcep_object_get_length_by_hdr(&ipv4_obj->header)
			+ pcep_object_get_length_by_hdr(
				&bandwidth_obj->header));
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCREQ);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);
	pcep_msg_free_message(message);
}


void test_pcep_msg_create_request_svec()
{
}


void test_pcep_msg_create_reply_nopath()
{
	struct pcep_object_rp *rp_obj =
		pcep_obj_create_rp(0, false, false, false, false, 10, NULL);
	struct pcep_object_nopath *nopath_obj = pcep_obj_create_nopath(
		false, false, PCEP_NOPATH_TLV_ERR_NO_TLV);
	double_linked_list *obj_list = dll_initialize();
	dll_append(obj_list, nopath_obj);

	struct pcep_message *message = pcep_msg_create_reply(rp_obj, obj_list);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 2);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			(MESSAGE_HEADER_LENGTH
			 + pcep_object_get_length_by_hdr(&rp_obj->header)
			 + pcep_object_get_length_by_hdr(&nopath_obj->header)));
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCREP);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);
	pcep_msg_free_message(message);
}


void test_pcep_msg_create_reply()
{
	/* First test with NULL ero and rp objects */
	struct pcep_message *message = pcep_msg_create_reply(NULL, NULL);

	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 0);
	CU_ASSERT_EQUAL(message->encoded_message_length, MESSAGE_HEADER_LENGTH);
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCREP);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);
	pcep_msg_free_message(message);

	double_linked_list *ero_subobj_list = dll_initialize();
	struct pcep_object_ro_subobj *ero_subobj =
		(struct pcep_object_ro_subobj *)
			pcep_obj_create_ro_subobj_32label(true, 1, 10);
	dll_append(ero_subobj_list, ero_subobj);
	struct pcep_object_ro *ero = pcep_obj_create_ero(ero_subobj_list);

	double_linked_list *object_list = dll_initialize();
	dll_append(object_list, ero);
	struct pcep_object_rp *rp_obj =
		pcep_obj_create_rp(0, false, false, false, false, 10, NULL);
	message = pcep_msg_create_reply(rp_obj, object_list);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 2);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ pcep_object_get_length_by_hdr(&rp_obj->header)
				+ OBJECT_HEADER_LENGTH
				+ OBJECT_RO_SUBOBJ_HEADER_LENGTH
				+ 6 /* size of the 32label */);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCREP);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);
	pcep_msg_free_message(message);
}


void test_pcep_msg_create_close()
{
	uint8_t reason = PCEP_CLOSE_REASON_UNREC_MSG;

	struct pcep_message *message = pcep_msg_create_close(reason);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 1);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ pcep_object_get_length(PCEP_OBJ_CLASS_CLOSE,
							 PCEP_OBJ_TYPE_CLOSE));
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_CLOSE);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	/* Just check the class and type, the rest of the hdr fields
	 * are verified in pcep-objects-test.c */
	struct pcep_object_close *close_obj =
		(struct pcep_object_close *)message->obj_list->head->data;
	assert(close_obj != NULL);
	CU_ASSERT_EQUAL(close_obj->header.object_class, PCEP_OBJ_CLASS_CLOSE);
	CU_ASSERT_EQUAL(close_obj->header.object_type, PCEP_OBJ_TYPE_CLOSE);
	CU_ASSERT_EQUAL(close_obj->reason, reason);
	pcep_msg_free_message(message);
}


void test_pcep_msg_create_error()
{
	uint8_t error_type = PCEP_ERRT_RECEPTION_OF_INV_OBJECT;
	uint8_t error_value = PCEP_ERRV_KEEPALIVEWAIT_TIMED_OUT;

	struct pcep_message *message =
		pcep_msg_create_error(error_type, error_value);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 1);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ pcep_object_get_length(PCEP_OBJ_CLASS_ERROR,
							 PCEP_OBJ_TYPE_ERROR));
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_ERROR);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	/* Just check the class and type, the rest of the hdr fields
	 * are verified in pcep-objects-test.c */
	struct pcep_object_error *error_obj =
		(struct pcep_object_error *)message->obj_list->head->data;
	CU_ASSERT_EQUAL(error_obj->header.object_class, PCEP_OBJ_CLASS_ERROR);
	CU_ASSERT_EQUAL(error_obj->header.object_type, PCEP_OBJ_TYPE_ERROR);

	CU_ASSERT_EQUAL(error_obj->error_type, error_type);
	CU_ASSERT_EQUAL(error_obj->error_value, error_value);
	pcep_msg_free_message(message);
}


void test_pcep_msg_create_keepalive()
{
	struct pcep_message *message = pcep_msg_create_keepalive();
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 0);
	CU_ASSERT_EQUAL(message->encoded_message_length, MESSAGE_HEADER_LENGTH);
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_KEEPALIVE);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);
	pcep_msg_free_message(message);
}

void test_pcep_msg_create_report()
{
	double_linked_list *obj_list = dll_initialize();

	/* Should return NULL if obj_list is empty */
	struct pcep_message *message = pcep_msg_create_report(NULL);
	CU_ASSERT_PTR_NULL(message);

	struct pcep_object_lsp *lsp =
		pcep_obj_create_lsp(100, PCEP_LSP_OPERATIONAL_UP, true, true,
				    true, true, true, NULL);
	dll_append(obj_list, lsp);
	message = pcep_msg_create_report(obj_list);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 1);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ lsp->header.encoded_object_length);
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_REPORT);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	pcep_msg_free_message(message);
}

void test_pcep_msg_create_update()
{
	double_linked_list *obj_list = dll_initialize();
	double_linked_list *ero_subobj_list = dll_initialize();

	struct pcep_message *message = pcep_msg_create_update(NULL);
	CU_ASSERT_PTR_NULL(message);

	/* Should return NULL if obj_list is empty */
	message = pcep_msg_create_update(obj_list);
	CU_ASSERT_PTR_NULL(message);
	if (message != NULL) {
		pcep_msg_free_message(message);
		message = NULL;
	}

	struct pcep_object_srp *srp = pcep_obj_create_srp(false, 100, NULL);
	struct pcep_object_lsp *lsp =
		pcep_obj_create_lsp(100, PCEP_LSP_OPERATIONAL_UP, true, true,
				    true, true, true, NULL);
	dll_append(ero_subobj_list, pcep_obj_create_ro_subobj_asn(0x0102));
	struct pcep_object_ro *ero = pcep_obj_create_ero(ero_subobj_list);

	/* Should return NULL if obj_list does not have 3 entries */
	dll_append(obj_list, srp);
	dll_append(obj_list, lsp);
	message = pcep_msg_create_update(obj_list);
	CU_ASSERT_PTR_NULL(message);

	dll_append(obj_list, ero);
	if (message != NULL) {
		pcep_msg_free_message(message);
		message = NULL;
	}
	message = pcep_msg_create_update(obj_list);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 3);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ srp->header.encoded_object_length
				+ lsp->header.encoded_object_length
				+ ero->header.encoded_object_length);
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_UPDATE);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	pcep_msg_free_message(message);
}

void test_pcep_msg_create_initiate()
{
	double_linked_list *obj_list = dll_initialize();
	double_linked_list *ero_subobj_list = dll_initialize();

	/* Should return NULL if obj_list is empty */
	struct pcep_message *message = pcep_msg_create_initiate(NULL);
	CU_ASSERT_PTR_NULL(message);
	if (message != NULL) {
		pcep_msg_free_message(message);
		message = NULL;
	}

	struct pcep_object_srp *srp = pcep_obj_create_srp(false, 100, NULL);
	struct pcep_object_lsp *lsp =
		pcep_obj_create_lsp(100, PCEP_LSP_OPERATIONAL_UP, true, true,
				    true, true, true, NULL);
	dll_append(ero_subobj_list, pcep_obj_create_ro_subobj_asn(0x0102));
	struct pcep_object_ro *ero = pcep_obj_create_ero(ero_subobj_list);

	/* Should return NULL if obj_list does not have 2 entries */
	dll_append(obj_list, srp);
	message = pcep_msg_create_initiate(obj_list);
	CU_ASSERT_PTR_NULL(message);
	if (message != NULL) {
		pcep_msg_free_message(message);
		message = NULL;
	}

	dll_append(obj_list, lsp);
	dll_append(obj_list, ero);
	message = pcep_msg_create_initiate(obj_list);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->msg_header);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 3);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ srp->header.encoded_object_length
				+ lsp->header.encoded_object_length
				+ ero->header.encoded_object_length);
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_INITIATE);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	pcep_msg_free_message(message);
}

void test_pcep_msg_create_notify(void)
{
	struct pcep_object_notify *notify_obj = pcep_obj_create_notify(
		PCEP_NOTIFY_TYPE_PENDING_REQUEST_CANCELLED,
		PCEP_NOTIFY_VALUE_PCC_CANCELLED_REQUEST);

	/* Should return NULL if the notify obj is empty */
	struct pcep_message *message = pcep_msg_create_notify(NULL, NULL);
	CU_ASSERT_PTR_NULL(message);

	message = pcep_msg_create_notify(notify_obj, NULL);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 1);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ notify_obj->header.encoded_object_length);
	assert(message->msg_header != NULL);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCNOTF);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	pcep_msg_free_message(message);

	struct pcep_object_rp *rp_obj =
		pcep_obj_create_rp(0, false, false, false, false, 10, NULL);
	double_linked_list *obj_list = dll_initialize();
	dll_append(obj_list, rp_obj);
	notify_obj = pcep_obj_create_notify(
		PCEP_NOTIFY_TYPE_PENDING_REQUEST_CANCELLED,
		PCEP_NOTIFY_VALUE_PCC_CANCELLED_REQUEST);

	message = pcep_msg_create_notify(notify_obj, obj_list);
	CU_ASSERT_PTR_NOT_NULL(message);
	pcep_encode_message(message, versioning);
	assert(message != NULL);
	CU_ASSERT_PTR_NOT_NULL(message->obj_list);
	assert(message->obj_list != NULL);
	CU_ASSERT_EQUAL(message->obj_list->num_entries, 2);
	CU_ASSERT_EQUAL(message->encoded_message_length,
			MESSAGE_HEADER_LENGTH
				+ notify_obj->header.encoded_object_length
				+ rp_obj->header.encoded_object_length);
	CU_ASSERT_EQUAL(message->msg_header->type, PCEP_TYPE_PCNOTF);
	CU_ASSERT_EQUAL(message->msg_header->pcep_version,
			PCEP_MESSAGE_HEADER_VERSION);

	pcep_msg_free_message(message);
}
