module UPF_Tests {

/* Integration Tests for OsmoUPF
 * (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This test suite acts as a PFCP Control Plane Function to test OsmoUPF.
 */

import from Misc_Helpers all;
import from General_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from Native_Functions all;
import from TCCConversion_Functions all;

import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

import from StatsD_Types all;
import from StatsD_CodecPort all;
import from StatsD_CodecPort_CtrlFunct all;
import from StatsD_Checker all;

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

import from CPF_ConnectionHandler all;

import from PFCP_Types all;
import from PFCP_Emulation all;
import from PFCP_Templates all;

modulepar {
	/* IP address at which the UPF can be reached */
	charstring mp_pfcp_ip_upf := "127.0.0.1";
	charstring mp_pfcp_ip_local := "127.0.0.2";

	/* When testing with gtp mockup, actions will not show. */
	boolean mp_verify_gtp_actions := false;
}

type component test_CT extends CTRL_Adapter_CT {
	port PFCPEM_PT PFCP;

	port TELNETasp_PT UPFVTY;

	/* global test case guard timer (actual timeout value is set in f_init()) */
	timer T_guard := 15.0;
}

/* global altstep for global guard timer; */
altstep as_Tguard() runs on test_CT {
	[] T_guard.timeout {
			setverdict(fail, "Timeout of T_guard");
			mtc.stop;
		}
}

friend function f_logp(TELNETasp_PT pt, charstring log_msg)
{
	// log on TTCN3 log output
	log(log_msg);
	// log in stderr log
	f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
}

private function f_str_split(charstring str, charstring delim := "\n") return ro_charstring
{
	var integer pos := 0;
	var ro_charstring parts := {};
	var integer delim_pos;
	var integer end := lengthof(str);
	while (pos < end) {
		delim_pos := f_strstr(str, delim, pos);
		if (delim_pos < 0) {
			delim_pos := end;
		}
		parts := parts & { substr(str, pos, delim_pos - pos) };
		pos := delim_pos + 1;
	}
	return parts;
}

private function f_get_name_val(out charstring val, charstring str, charstring name, charstring sep := ":", charstring delim := " ") return boolean {
	var charstring labl := name & sep;
	var integer namepos := f_strstr(str, labl);
	if (namepos < 0) {
		return false;
	}
	var integer valpos := namepos + lengthof(labl);
	var integer valend := f_strstr(str, delim, valpos);
	if (valend < 0) {
		valend := lengthof(str);
	}
	val := substr(str, valpos, valend - valpos);
	return true;
}

private function f_get_name_val_oct8(out OCT8 val, charstring str, charstring name) return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name, ":0x")) {
		return false;
	}
	if (lengthof(token) > 16) {
		log("token too long: ", name, " in ", str);
		return false;
	}
	var charstring padded := substr("0000000000000000", 0, 16 - lengthof(token)) & token;
	val := str2oct(padded);
	return true;
}

private function f_get_name_val_oct4(out OCT4 val, charstring str, charstring name) return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name, ":0x")) {
		return false;
	}
	if (lengthof(token) > 8) {
		log("token too long: ", name, " in ", str);
		return false;
	}
	var charstring padded := substr("00000000", 0, 8 - lengthof(token)) & token;
	val := str2oct(padded);
	return true;
}

private function f_get_name_val_int(out integer val, charstring str, charstring name) return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name)) {
		return false;
	}
	val := str2int(token);
	return true;
}

private function f_get_name_val_2int(out integer val1, out integer val2, charstring str, charstring name, charstring delim := ",") return boolean {
	var charstring token;
	if (not f_get_name_val(token, str, name)) {
		return false;
	}
	var ro_charstring nrl := f_str_split(token, delim);
	if (lengthof(nrl) != 2) {
		return false;
	}
	val1 := str2int(nrl[0]);
	val2 := str2int(nrl[1]);
	return true;
}

/* A PFCP session as seen by the system under test, osmo-upf. up_seid is what osmo-upf sees as its local SEID
 * ("SEID-l"). cp_seid is this tester's side's SEID, which osmo-upf sees as the remote SEID. */
type record PFCP_session {
	OCT8 up_seid,
	OCT8 cp_seid,
	GTP_Action gtp
}

type record GTP_Action {
	charstring kind,
	charstring gtp_access_ip,
	OCT4 teid_access_r,
	OCT4 teid_access_l,
	charstring core_ip,
	charstring pfcp_peer,
	OCT8 seid_l
};

type record of GTP_Action GTP_Action_List;

private function f_parse_gtp_action(out GTP_Action ret, charstring str) return boolean {
	var GTP_Action a;
	if (not f_get_name_val(a.kind, str, "GTP")) {
		return false;
	}
	if (not f_get_name_val(a.gtp_access_ip, str, "GTP-access")) {
		return false;
	}
	if (not f_get_name_val_oct4(a.teid_access_r, str, "TEID-r")) {
		return false;
	}
	if (not f_get_name_val_oct4(a.teid_access_l, str, "TEID-l")) {
		return false;
	}
	if (not f_get_name_val(a.pfcp_peer, str, "PFCP-peer")) {
		return false;
	}
	if (not f_get_name_val_oct8(a.seid_l, str, "SEID-l")) {
		return false;
	}
	if (not f_get_name_val(a.core_ip, str, "IP-core")) {
		return false;
	}
	ret := a;
	return true;
}

private function f_vty_get_gtp_actions(TELNETasp_PT vty_pt) return GTP_Action_List {
	var charstring gtp_str := f_vty_transceive_ret(vty_pt, "show gtp");
	var ro_charstring lines := f_str_split(gtp_str, "\n");
	var GTP_Action_List gtps := {};
	for (var integer i := 0; i < lengthof(lines); i := i + 1) {
		var charstring line := lines[i];
		var GTP_Action a;
		if (not f_parse_gtp_action(a, line)) {
			continue;
		}
		gtps := gtps & { a };
	}
	log("GTP-actions: ", gtps);
	return gtps;
}

private function f_find_gtp_action(GTP_Action_List actions, template GTP_Action find) return boolean {
	for (var integer i := 0; i < lengthof(actions); i := i + 1) {
		if (match(actions[i], find)) {
			return true;
		}
	}
	return false;
}

private function f_expect_gtp_action(GTP_Action_List actions, template GTP_Action expect) {
	if (f_find_gtp_action(actions, expect)) {
		log("VTY confirms: GTP action active: ", expect);
		setverdict(pass);
		return;
	}
	log("Expected to find ", expect, " in ", actions);
	setverdict(fail, "on VTY, a GTP action failed to show as active");
	mtc.stop;
}

private function f_expect_no_gtp_action(GTP_Action_List actions, template GTP_Action expect) {
	if (f_find_gtp_action(actions, expect)) {
		log("Expected to *not* find ", expect, " in ", actions);
		setverdict(fail, "a GTP action failed to show as inactive");
		mtc.stop;
	}
	log("VTY confirms: GTP action inactive: ", expect);
	setverdict(pass);
	return;
}

private function f_vty_expect_gtp_action(TELNETasp_PT vty_pt, template GTP_Action expect) {
	if (not mp_verify_gtp_actions) {
		/* In GTP mockup mode, GTP actions don't show on VTY. Cannot verify. */
		setverdict(pass);
		return;
	}
	var GTP_Action_List actions := f_vty_get_gtp_actions(vty_pt);
	f_expect_gtp_action(actions, expect);
}

private function f_vty_expect_no_gtp_actions(TELNETasp_PT vty_pt) {
	var GTP_Action_List actions := f_vty_get_gtp_actions(vty_pt);
	if (lengthof(actions) > 0) {
		setverdict(fail, "VTY says that there are still active GTP actions");
		mtc.stop;
	}
	setverdict(pass);
}

type record PFCP_Session_Status {
	charstring peer,
	OCT8 seid_r,
	OCT8 seid_l,
	charstring state,
	integer pdr_active_count,
	integer pdr_count,
	integer far_active_count,
	integer far_count,
	integer gtp_active_count
};

template PFCP_Session_Status PFCP_session_active := {
	peer := ?,
	seid_r := ?,
	seid_l := ?,
	state := "ESTABLISHED",
	pdr_active_count := (1..99999),
	pdr_count := (1..99999),
	far_active_count := (1..99999),
	far_count := (1..99999),
	gtp_active_count := (1..99999)
};

template PFCP_Session_Status PFCP_session_inactive := {
	peer := ?,
	seid_r := ?,
	seid_l := ?,
	state := "ESTABLISHED",
	pdr_active_count := 0,
	pdr_count := (1..99999),
	far_active_count := 0,
	far_count := (1..99999),
	gtp_active_count := 0
};

type record of PFCP_Session_Status PFCP_Session_Status_List;

private function f_parse_session_status(out PFCP_Session_Status ret, charstring str) return boolean {
	var PFCP_Session_Status st;
	if (not f_get_name_val(st.peer, str, "peer")) {
		return false;
	}
	if (not f_get_name_val_oct8(st.seid_l, str, "SEID-l")) {
		return false;
	}
	f_get_name_val_oct8(st.seid_r, str, "SEID-r");
	f_get_name_val(st.state, str, "state");

	/* parse 'PDR-active:1/2' */
	if (not f_get_name_val_2int(st.pdr_active_count, st.pdr_count, str, "PDR-active", "/")) {
		return false;
	}
	/* parse 'FAR-active:1/2' */
	if (not f_get_name_val_2int(st.far_active_count, st.far_count, str, "FAR-active", "/")) {
		return false;
	}

	f_get_name_val_int(st.gtp_active_count, str, "GTP-active");
	ret := st;
	return true;
}

private function f_vty_get_sessions(TELNETasp_PT vty_pt) return PFCP_Session_Status_List {
	var charstring sessions_str := f_vty_transceive_ret(vty_pt, "show session");
	var ro_charstring lines := f_str_split(sessions_str, "\n");
	var PFCP_Session_Status_List sessions := {};
	for (var integer i := 0; i < lengthof(lines); i := i + 1) {
		var charstring line := lines[i];
		var PFCP_Session_Status st;
		if (not f_parse_session_status(st, line)) {
			continue;
		}
		sessions := sessions & { st };
	}
	log("Sessions: ", sessions);
	return sessions;
}

private function f_vty_get_session_status(TELNETasp_PT vty_pt, PFCP_session s, out PFCP_Session_Status ret) return boolean {
	var PFCP_Session_Status_List sessions := f_vty_get_sessions(vty_pt);
	return f_get_session_status(sessions, s, ret);
}

private function f_get_session_status(PFCP_Session_Status_List sessions, PFCP_session s, out PFCP_Session_Status ret)
return boolean {
	var PFCP_Session_Status_List matches := {};
	for (var integer i := 0; i < lengthof(sessions); i := i + 1) {
		var PFCP_Session_Status st := sessions[i];
		if (st.seid_l != s.up_seid) {
			continue;
		}
		if (st.seid_r != s.cp_seid) {
			continue;
		}
		matches := matches & { st };
	}
	if (lengthof(matches) < 1) {
		log("no session with SEID-l = ", s.up_seid);
		return false;
	}
	if (lengthof(matches) > 1) {
		log("multiple sessions have ", s, ": ", matches);
		return false;
	}
	ret := matches[0];
	return true;
}

private function f_vty_expect_session_status(TELNETasp_PT vty_pt, PFCP_session s, template PFCP_Session_Status expect_st) {
	var PFCP_Session_Status st;
	if (not f_vty_get_session_status(vty_pt, s, st)) {
		log("Session ", s, " not found in VTY session list");
		setverdict(fail, "Session not found in VTY list");
		mtc.stop;
	}
	log("Session ", s, " status: ", st);
	if (not match(st, expect_st)) {
		log("ERROR: Session ", st, " does not match ", expect_st);
		setverdict(fail, "VTY shows unexpected state of PFCP session");
		mtc.stop;
	}

	setverdict(pass);
}

private function f_vty_expect_session_active(TELNETasp_PT vty_pt, PFCP_session s)
{
	f_vty_expect_session_status(vty_pt, s, PFCP_session_active);
	f_vty_expect_gtp_action(vty_pt, s.gtp);
	setverdict(pass);
}

private function f_vty_expect_no_active_sessions(TELNETasp_PT vty_pt) {
	var PFCP_Session_Status_List stl := f_vty_get_sessions(vty_pt);
	var integer active := 0;
	for (var integer i := 0; i < lengthof(stl); i := i + 1) {
		if (match(stl[i], PFCP_session_active)) {
			log("Active session: ", stl[i]);
			active := active + 1;
		}
	}
	if (active > 0) {
		setverdict(fail, "There are still active sessions");
		mtc.stop;
	}
	setverdict(pass);
}

function f_init_vty(charstring id := "foo") runs on test_CT {
	if (UPFVTY.checkstate("Mapped")) {
		/* skip initialization if already executed once */
		return;
	}
	map(self:UPFVTY, system:UPFVTY);
	f_vty_set_prompts(UPFVTY);
	f_vty_transceive(UPFVTY, "enable");
}

/* global initialization function */
function f_init(float guard_timeout := 30.0) runs on test_CT {
	var integer bssap_idx;

	T_guard.start(guard_timeout);
	activate(as_Tguard());

	f_init_vty("VirtCPF");
}

friend function f_shutdown_helper() runs on test_CT {
	all component.stop;
	setverdict(pass);
	mtc.stop;
}

private function f_gen_test_hdlr_pars() runs on test_CT return TestHdlrParams {
	var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
	pars.remote_upf_addr := mp_pfcp_ip_upf;
	pars.local_addr := mp_pfcp_ip_local;
	pars.local_node_id := valueof(ts_PFCP_Node_ID_ipv4(f_inet_addr(mp_pfcp_ip_local)));
	return pars;
}

type function void_fn(charstring id) runs on CPF_ConnHdlr;

function f_start_handler_create(TestHdlrParams pars)
runs on test_CT return CPF_ConnHdlr {
	var charstring id := testcasename();
	var CPF_ConnHdlr vc_conn;
	vc_conn := CPF_ConnHdlr.create(id);
	return vc_conn;
}

function f_start_handler_run(CPF_ConnHdlr vc_conn, void_fn fn, TestHdlrParams pars)
runs on test_CT return CPF_ConnHdlr {
	var charstring id := testcasename();
	/* Emit a marker to appear in the SUT's own logging output */
	f_logp(UPFVTY, id & "() start");
	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars_tmpl := omit)
runs on test_CT return CPF_ConnHdlr {
	var TestHdlrParams pars;
	if (isvalue(pars_tmpl)) {
		pars := valueof(pars_tmpl);
	} else {
		pars := valueof(f_gen_test_hdlr_pars());
	}
	return f_start_handler_run(f_start_handler_create(pars), fn, pars);
}

/* first function inside ConnHdlr component; sets g_pars + starts function */
private function f_handler_init(void_fn fn, charstring id, TestHdlrParams pars)
runs on CPF_ConnHdlr {
	f_CPF_ConnHdlr_init(id, pars);
	fn.apply(id);
}

/* Run a PFCP Association procedure */
private function f_assoc_setup() runs on CPF_ConnHdlr {
	PFCP.send(ts_PFCP_Assoc_Setup_Req(g_pars.local_node_id, g_recovery_timestamp));
	PFCP.receive(tr_PFCP_Assoc_Setup_Resp(cause := tr_PFCP_Cause(REQUEST_ACCEPTED)));
}

/* Release a PFCP Association */
private function f_assoc_release() runs on CPF_ConnHdlr {
	PFCP.send(ts_PFCP_Assoc_Release_Req(g_pars.local_node_id));
	PFCP.receive(tr_PFCP_Assoc_Release_Resp(cause := tr_PFCP_Cause(REQUEST_ACCEPTED)));
}

type record PFCP_Ruleset {
	Create_PDR_list pdr,
	Create_FAR_list far
};

/* Add to r a rule set that does GTP decapsulation (half of encapsulation/decapsulation) */
private function f_ruleset_add_GTP_decaps(inout PFCP_Ruleset r,
					  template F_TEID local_f_teid := omit) {
	var integer pdr_id := lengthof(r.pdr) + 1;
	var integer far_id := lengthof(r.far) + 1;

	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				ACCESS,
				local_F_TEID := local_f_teid),
			ts_PFCP_Outer_Header_Removal(GTP_U_UDP_IPV4),
			far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(CORE))
			)
		)
		};
}

/* Add to r a rule set that does GTP encapsulation (half of encapsulation/decapsulation) */
private function f_ruleset_add_GTP_encaps(inout PFCP_Ruleset r,
					  charstring ue_addr_v4 := "192.168.23.42",
					  OCT4 remote_teid,
					  charstring gtp_dest_addr_v4) {

	var integer pdr_id := lengthof(r.pdr) + 1;
	var integer far_id := lengthof(r.far) + 1;

	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				CORE,
				ue_addr_v4 := ts_PFCP_UE_IP_Address_v4(ue_addr_v4, is_destination := true)
				),
			far_id := far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(
				ACCESS,
				ts_PFCP_Outer_Header_Creation_GTP_ipv4(
					remote_teid,
					gtp_dest_addr_v4)
				))
			)
		)
		};
}

/* Return two PDR+FAR rulesets that involve a src=CP-Function. Such rulesets are emitted by certain third party CPF, and
 * osmo-upf should ACK the creation but ignore the rules (no-op). This function models rulesets seen in the field, so we
 * can confirm that osmo-upf ACKs and ignores. */
private function f_ruleset_noop() return PFCP_Ruleset
{
	var PFCP_Ruleset r := { {}, {} };
	var integer pdr_id := lengthof(r.pdr) + 1;
	var integer far_id := lengthof(r.far) + 1;

	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				CP_FUNCTION,
				local_F_TEID := ts_PFCP_F_TEID_choose_v4('17'O)),
			ts_PFCP_Outer_Header_Removal(GTP_U_UDP_IPV4),
			far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(ACCESS))
			)
		)
		};

	/* And another one (sic) */
	pdr_id := lengthof(r.pdr) + 1;
	far_id := lengthof(r.far) + 1;

	r.pdr := r.pdr & {
		valueof(
		ts_PFCP_Create_PDR(
			pdr_id,
			ts_PFCP_PDI(
				CP_FUNCTION,
				local_F_TEID := ts_PFCP_F_TEID_choose_v4('2a'O)),
			far_id := far_id
			)
		)
		};
	r.far := r.far & {
		valueof(
		ts_PFCP_Create_FAR(
			far_id,
			ts_PFCP_Apply_Action_FORW(),
			valueof(ts_PFCP_Forwarding_Parameters(ACCESS))
			)
		)
		};
	return r;
}

/* Return a rule set that does GTP encapsulation/decapsulation */
private function f_ruleset_endecaps(GTP_Action gtp) return PFCP_Ruleset
{
	var PFCP_Ruleset rules := { {}, {} };
	f_ruleset_add_GTP_decaps(rules, ts_PFCP_F_TEID_ipv4(gtp.teid_access_l, gtp.gtp_access_ip));
	f_ruleset_add_GTP_encaps(rules, gtp.core_ip, gtp.teid_access_r, gtp.gtp_access_ip);
	return rules;
}

/* Run a PFCP Session Establishment procedure */
private function f_session_est(inout PFCP_session s, PFCP_Ruleset rules) runs on CPF_ConnHdlr {

	PFCP.send(ts_PFCP_Session_Est_Req(g_pars.local_addr, s.cp_seid, rules.pdr, rules.far));

	var PDU_PFCP pfcp;
	PFCP.receive(tr_PFCP_Session_Est_Resp(s.cp_seid)) -> value pfcp;
	s.up_seid := pfcp.message_body.pfcp_session_establishment_response.UP_F_SEID.seid;
	s.gtp.seid_l := s.up_seid;
	log("established PFCP session: ", s);
}

private function f_create_PFCP_session() runs on CPF_ConnHdlr return PFCP_session
{
	var PFCP_session s := {
		up_seid := -,
		cp_seid := f_next_seid(),
		gtp := {
			kind := "endecaps",
			gtp_access_ip := "127.0.0.2",
			teid_access_r := f_next_remote_teid(),
			teid_access_l := f_next_local_teid(),
			core_ip := f_next_ue_addr(),
			pfcp_peer := g_pars.local_addr,
			seid_l := '0000000000000000'O
		}
	};
	return s;
}

/* Do a PFCP Session Establishment with default values (see f_create_PFCP_session()) */
private function f_session_est_default() runs on CPF_ConnHdlr return PFCP_session
{
	var PFCP_session s := f_create_PFCP_session();
	f_session_est(s, f_ruleset_endecaps(s.gtp));
	return s;
}

private function f_session_del(PFCP_session s) runs on CPF_ConnHdlr {
	PFCP.send(ts_PFCP_Session_Del_Req(s.up_seid));
	PFCP.receive(tr_PFCP_Session_Del_Resp(s.cp_seid));
}

private function f_tc_assoc(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	f_assoc_release();
	setverdict(pass);
}

/* Verify that the CPF can send a Node-ID of the IPv4 type */
testcase TC_assoc_node_id_v4() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 5.0);
	vc_conn := f_start_handler(refers(f_tc_assoc));
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify that the CPF can send a Node-ID of the FQDN type */
testcase TC_assoc_node_id_fqdn() runs on test_CT {
	var CPF_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();

	pars.local_node_id := valueof(ts_PFCP_Node_ID_fqdn("\7example\3com"));

	f_init(guard_timeout := 5.0);
	vc_conn := f_start_handler(refers(f_tc_assoc), pars);
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify PFCP Session Establishment and Deletion */
private function f_tc_session_est(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_session_est_default();
	f_sleep(1.0);
	f_vty_expect_session_active(UPFVTY, s);
	f_session_del(s);
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	f_assoc_release();
	setverdict(pass);
}
testcase TC_session_est() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);
	vc_conn := f_start_handler(refers(f_tc_session_est));
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify that releasing a PFCP Association also releases all its sessions and GTP actions. */
private function f_tc_session_term_by_assoc_rel(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_session_est_default();
	f_sleep(1.0);
	f_vty_expect_session_active(UPFVTY, s);
	f_assoc_release();
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	setverdict(pass);
}
testcase TC_session_term_by_assoc_rel() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);
	vc_conn := f_start_handler(refers(f_tc_session_term_by_assoc_rel));
	vc_conn.done;
	f_shutdown_helper();
}

/* Verify that PFCP Sessions with a src-interface other than ACCESS or CORE are ACKed by osmo-upf but have no effect. */
private function f_tc_session_est_noop(charstring id) runs on CPF_ConnHdlr {
	f_assoc_setup();
	var PFCP_session s := f_create_PFCP_session();
	f_session_est(s, f_ruleset_noop());

	f_sleep(1.0);
	f_vty_expect_session_status(UPFVTY, s, PFCP_session_inactive);

	f_session_del(s);
	f_vty_expect_no_active_sessions(UPFVTY);
	f_vty_expect_no_gtp_actions(UPFVTY);
	f_assoc_release();
	setverdict(pass);
}
testcase TC_session_est_noop() runs on test_CT {
	var CPF_ConnHdlr vc_conn;

	f_init(guard_timeout := 15.0);
	vc_conn := f_start_handler(refers(f_tc_session_est_noop));
	vc_conn.done;
	f_shutdown_helper();
}

control {
	execute( TC_assoc_node_id_v4() );
	execute( TC_assoc_node_id_fqdn() );
	execute( TC_session_est() );
	execute( TC_session_term_by_assoc_rel() );
	execute( TC_session_est_noop() );
}

}
