From 4821882f6d16e27801fb5ef22813c9bebeb1dac3 Mon Sep 17 00:00:00 2001 From: Alonza0314 Date: Thu, 26 Dec 2024 15:50:48 +0000 Subject: [PATCH 1/4] feat: add charging check function in ulcl ti test --- config/ULCL/smfCfg.yaml | 2 +- config/ULCL/ueRoutingCfg.yaml | 4 +- test/api-webconsole-charging-record.sh | 55 ++++++++++++++++++++++++ test/goTest/ulclTrafficInfluence_test.go | 44 ++++++++++++++++++- 4 files changed, 100 insertions(+), 5 deletions(-) create mode 100755 test/api-webconsole-charging-record.sh diff --git a/config/ULCL/smfCfg.yaml b/config/ULCL/smfCfg.yaml index d11a1bd..015cff8 100644 --- a/config/ULCL/smfCfg.yaml +++ b/config/ULCL/smfCfg.yaml @@ -99,7 +99,7 @@ configuration: nrfUri: http://nrf.free5gc.org:8000 # a valid URI of NRF nrfCertPem: cert/nrf.pem # NRF Certificate urrPeriod: 10 # default usage report period in seconds - urrThreshold: 1000 # default usage report threshold in bytes + urrThreshold: 10 # default usage report threshold in bytes requestedUnit: 1000 ulcl: true logger: # log output setting diff --git a/config/ULCL/ueRoutingCfg.yaml b/config/ULCL/ueRoutingCfg.yaml index 9f0899d..12be4d1 100644 --- a/config/ULCL/ueRoutingCfg.yaml +++ b/config/ULCL/ueRoutingCfg.yaml @@ -14,9 +14,7 @@ ueRoutingInfo: # the list of UE routing information - A: I-UPF B: PSA-UPF specificPath: - - dest: 10.100.50.10/32 # n6gw - path: [I-UPF] - - dest: 10.100.100.10/32 # mec + - dest: 1.0.0.1/32 path: [I-UPF] pfdDataForApp: # PFDs for an Application diff --git a/test/api-webconsole-charging-record.sh b/test/api-webconsole-charging-record.sh new file mode 100755 index 0000000..94acafc --- /dev/null +++ b/test/api-webconsole-charging-record.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +########################## +# +# usage: +# ./api-webconsole-charging-record.sh +# +# e.g. ./api-webconsole-charging-record.sh [get] json/webconsole-login-data.json +# +########################## + +set -e + +# get token +echo "Getting token..." + +LOGIN_RESPONSE=$(curl -s -X POST http://webui:5000/api/login \ +-H "Content-Type: application/json" \ +-d @"$2") + +TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.access_token') + +if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then + echo "Failed to get token!" + echo "Server response: $LOGIN_RESPONSE" + exit 1 +fi + +if [[ ! "$TOKEN" =~ ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$ ]]; then + echo "Invalid token format!" + echo "Token: $TOKEN" + exit 1 +fi + +echo "Token obtained successfully!" + +# get charging record +echo "Getting charging record..." + +TOKEN=$(echo -n "$TOKEN" | tr -d '\n' | tr -d ' ') + +case "$1" in + "get") + CHARGING_RECORD_RESPONSE=$(curl -s -X GET "http://webui:5000/api/charging-record" \ + -H "Token: $TOKEN") + ;; + *) + echo "error: invalid parameter" + echo "usage: $0 [get]" + exit 1 + ;; +esac + +echo "Charging record obtained successfully!" +echo "$CHARGING_RECORD_RESPONSE" \ No newline at end of file diff --git a/test/goTest/ulclTrafficInfluence_test.go b/test/goTest/ulclTrafficInfluence_test.go index d36c649..4f5017d 100644 --- a/test/goTest/ulclTrafficInfluence_test.go +++ b/test/goTest/ulclTrafficInfluence_test.go @@ -1,7 +1,9 @@ package test import ( + "encoding/json" "os/exec" + "strings" "testing" "time" @@ -61,7 +63,7 @@ func TestULCLTrafficInfluence(t *testing.T) { if err != nil { t.Errorf("Delete ti data failed: expected delete success, but got %v, output: %s", err, output) } - time.Sleep(500 * time.Millisecond) + time.Sleep(3 * time.Millisecond) // reset TI t.Run("Reset TI", func(t *testing.T) { @@ -75,6 +77,46 @@ func TestULCLTrafficInfluence(t *testing.T) { } }) + // check charging record + t.Run("Check Charging Record", func(t *testing.T) { + checkChargingRecord(t) + }) + // deactivate PacketRusher pr.Deactivate() } + +func checkChargingRecord(t *testing.T) { + cmd := exec.Command("bash", "../api-webconsole-charging-record.sh", "get", "../json/webconsole-login-data.json") + output, err := cmd.CombinedOutput() + if err != nil { + t.Errorf("Get charging record failed: %v, output: %s", err, output) + return + } + + outputStr := string(output) + + lines := strings.Split(outputStr, "\n") + var jsonLine string + for i := len(lines) - 1; i >= 0; i-- { + if strings.TrimSpace(lines[i]) != "" { + jsonLine = lines[i] + break + } + } + + var chargingRecords []map[string]interface{} + if err := json.Unmarshal([]byte(jsonLine), &chargingRecords); err != nil { + t.Errorf("Failed to parse charging record JSON: %v\nJSON content: %s", err, jsonLine) + return + } + + if len(chargingRecords) == 0 { + t.Error("No charging records found") + return + } + + if chargingRecords[0]["TotalVol"].(float64) == 0 { + t.Error("Charging record is empty") + } +} From a931af348b495c0946056dc4cece5582b39c2d36 Mon Sep 17 00:00:00 2001 From: Alonza0314 Date: Fri, 24 Jan 2025 07:02:32 +0000 Subject: [PATCH 2/4] feat: split the subscription data with offline and online charging --- config/ULCL/smfCfg.yaml | 2 +- ...api-webconsole-subscribtion-data-action.sh | 8 +- ...webconsole-subscription-data-offline.json} | 94 +---------- .../webconsole-subscription-data-online.json | 151 ++++++++++++++++++ test/test-ulcl.sh | 30 +++- 5 files changed, 184 insertions(+), 101 deletions(-) rename test/json/{webconsole-subscription-data.json => webconsole-subscription-data-offline.json} (60%) create mode 100644 test/json/webconsole-subscription-data-online.json diff --git a/config/ULCL/smfCfg.yaml b/config/ULCL/smfCfg.yaml index 015cff8..47655d5 100644 --- a/config/ULCL/smfCfg.yaml +++ b/config/ULCL/smfCfg.yaml @@ -100,7 +100,7 @@ configuration: nrfCertPem: cert/nrf.pem # NRF Certificate urrPeriod: 10 # default usage report period in seconds urrThreshold: 10 # default usage report threshold in bytes - requestedUnit: 1000 + requestedUnit: 10 ulcl: true logger: # log output setting enable: true # true or false diff --git a/test/api-webconsole-subscribtion-data-action.sh b/test/api-webconsole-subscribtion-data-action.sh index 9f1b63a..05ab54a 100755 --- a/test/api-webconsole-subscribtion-data-action.sh +++ b/test/api-webconsole-subscribtion-data-action.sh @@ -3,9 +3,9 @@ ########################## # # usage: -# ./api-webconsole-subscribtion-data-action.sh +# ./api-webconsole-subscribtion-data-action.sh # -# e.g. ./api-webconsole-subscribtion-data-action.sh [post|delete] +# e.g. ./api-webconsole-subscribtion-data-action.sh [post|delete] json/webconsole-subscription-data-[offline|online].json # ########################## @@ -44,13 +44,13 @@ case "$1" in SUBSCRIBE_RESPONSE=$(curl -s -X POST "http://webui:5000/api/subscriber/imsi-208930000000001/20893" \ -H "Content-Type: application/json" \ -H "Token: $TOKEN" \ - -d @json/webconsole-subscription-data.json) + -d @"$2") ;; "delete") SUBSCRIBE_RESPONSE=$(curl -s -X DELETE "http://webui:5000/api/subscriber/imsi-208930000000001/20893" \ -H "Content-Type: application/json" \ -H "Token: $TOKEN" \ - -d @json/webconsole-subscription-data.json) + -d @"$2") ;; *) echo "error: invalid parameter" diff --git a/test/json/webconsole-subscription-data.json b/test/json/webconsole-subscription-data-offline.json similarity index 60% rename from test/json/webconsole-subscription-data.json rename to test/json/webconsole-subscription-data-offline.json index bdd9fee..3bd5d8c 100644 --- a/test/json/webconsole-subscription-data.json +++ b/test/json/webconsole-subscription-data-offline.json @@ -33,14 +33,8 @@ "sst": 1, "sd": "010203", "isDefault": true - }, - { - "sst": 1, - "sd": "112233", - "isDefault": false } - ], - "singleNssais": [] + ] }, "subscribedUeAmbr": { "downlink": "2 Gbps", @@ -81,40 +75,6 @@ } } } - }, - { - "singleNssai": { - "sst": 1, - "sd": "112233" - }, - "dnnConfigurations": { - "internet": { - "sscModes": { - "defaultSscMode": "SSC_MODE_1", - "allowedSscModes": [ - "SSC_MODE_2", - "SSC_MODE_3" - ] - }, - "pduSessionTypes": { - "defaultSessionType": "IPV4", - "allowedSessionTypes": [ - "IPV4" - ] - }, - "sessionAmbr": { - "uplink": "200 Mbps", - "downlink": "100 Mbps" - }, - "5gQosProfile": { - "5qi": 8, - "arp": { - "priorityLevel": 8 - }, - "priorityLevel": 8 - } - } - } } ], "SmfSelectionSubscriptionData": { @@ -125,13 +85,6 @@ "dnn": "internet" } ] - }, - "01112233": { - "dnnInfos": [ - { - "dnn": "internet" - } - ] } } }, @@ -152,17 +105,6 @@ "dnn": "internet" } } - }, - "01112233": { - "snssai": { - "sst": 1, - "sd": "112233" - }, - "smPolicyDnnData": { - "internet": { - "dnn": "internet" - } - } } } }, @@ -173,13 +115,6 @@ "snssai": "01010203", "dnn": "internet", "qosRef": 1 - }, - { - "filter": "1.1.1.1/32", - "precedence": 127, - "snssai": "01112233", - "dnn": "internet", - "qosRef": 2 } ], "QosFlows": [ @@ -192,16 +127,6 @@ "mbrDL": "208 Mbps", "gbrUL": "108 Mbps", "gbrDL": "108 Mbps" - }, - { - "snssai": "01112233", - "dnn": "internet", - "qosRef": 2, - "5qi": 7, - "mbrUL": "407 Mbps", - "mbrDL": "407 Mbps", - "gbrUL": "207 Mbps", - "gbrDL": "207 Mbps" } ], "ChargingDatas": [ @@ -221,23 +146,6 @@ "chargingMethod": "Offline", "quota": "100000", "unitCost": "1" - }, - { - "snssai": "01112233", - "dnn": "", - "filter": "", - "chargingMethod": "Online", - "quota": "100000", - "unitCost": "1" - }, - { - "snssai": "01112233", - "dnn": "internet", - "qosRef": 2, - "filter": "1.1.1.1/32", - "chargingMethod": "Online", - "quota": "5000", - "unitCost": "1" } ] } diff --git a/test/json/webconsole-subscription-data-online.json b/test/json/webconsole-subscription-data-online.json new file mode 100644 index 0000000..a5da177 --- /dev/null +++ b/test/json/webconsole-subscription-data-online.json @@ -0,0 +1,151 @@ +{ + "plmnID": "20893", + "ueId": "imsi-208930000000001", + "AuthenticationSubscription": { + "authenticationManagementField": "8000", + "authenticationMethod": "5G_AKA", + "milenage": { + "op": { + "encryptionAlgorithm": 0, + "encryptionKey": 0, + "opValue": "" + } + }, + "opc": { + "encryptionAlgorithm": 0, + "encryptionKey": 0, + "opcValue": "8e27b6af0e692e750f32667a3b14605d" + }, + "permanentKey": { + "encryptionAlgorithm": 0, + "encryptionKey": 0, + "permanentKeyValue": "8baf473f2f8fd09487cccbd7097c6862" + }, + "sequenceNumber": "000000000023" + }, + "AccessAndMobilitySubscriptionData": { + "gpsis": [ + "msisdn-" + ], + "nssai": { + "defaultSingleNssais": [ + { + "sst": 1, + "sd": "010203", + "isDefault": true + } + ] + }, + "subscribedUeAmbr": { + "downlink": "2 Gbps", + "uplink": "1 Gbps" + } + }, + "SessionManagementSubscriptionData": [ + { + "singleNssai": { + "sst": 1, + "sd": "010203" + }, + "dnnConfigurations": { + "internet": { + "sscModes": { + "defaultSscMode": "SSC_MODE_1", + "allowedSscModes": [ + "SSC_MODE_2", + "SSC_MODE_3" + ] + }, + "pduSessionTypes": { + "defaultSessionType": "IPV4", + "allowedSessionTypes": [ + "IPV4" + ] + }, + "sessionAmbr": { + "uplink": "200 Mbps", + "downlink": "100 Mbps" + }, + "5gQosProfile": { + "5qi": 8, + "arp": { + "priorityLevel": 8 + }, + "priorityLevel": 8 + } + } + } + } + ], + "SmfSelectionSubscriptionData": { + "subscribedSnssaiInfos": { + "01010203": { + "dnnInfos": [ + { + "dnn": "internet" + } + ] + } + } + }, + "AmPolicyData": { + "subscCats": [ + "free5gc" + ] + }, + "SmPolicyData": { + "smPolicySnssaiData": { + "01010203": { + "snssai": { + "sst": 1, + "sd": "010203" + }, + "smPolicyDnnData": { + "internet": { + "dnn": "internet" + } + } + } + } + }, + "FlowRules": [ + { + "filter": "1.1.1.1/32", + "precedence": 127, + "snssai": "01010203", + "dnn": "internet", + "qosRef": 1 + } + ], + "QosFlows": [ + { + "snssai": "01010203", + "dnn": "internet", + "qosRef": 1, + "5qi": 7, + "mbrUL": "208 Mbps", + "mbrDL": "208 Mbps", + "gbrUL": "108 Mbps", + "gbrDL": "108 Mbps" + } + ], + "ChargingDatas": [ + { + "snssai": "01010203", + "dnn": "", + "filter": "", + "chargingMethod": "Online", + "quota": "100000", + "unitCost": "1" + }, + { + "snssai": "01010203", + "dnn": "internet", + "qosRef": 1, + "filter": "1.1.1.1/32", + "chargingMethod": "Online", + "quota": "100000", + "unitCost": "1" + } + ] +} diff --git a/test/test-ulcl.sh b/test/test-ulcl.sh index f6ae082..786a0e4 100755 --- a/test/test-ulcl.sh +++ b/test/test-ulcl.sh @@ -9,8 +9,32 @@ # ########################## +echo "test TestULCLTrafficInfluence with offline charging" + +# post ue (ci-test PacketRusher) data to db +./api-webconsole-subscribtion-data-action.sh post json/webconsole-subscription-data-offline.json +if [ $? -ne 0 ]; then + echo "Failed to post subscription data" + exit 1 +fi + +# run test +cd goTest +go test -v -vet=off -run $1 +go_test_exit_code=$? +cd .. + +# delete ue (ci-test PacketRusher) data from db +./api-webconsole-subscribtion-data-action.sh delete json/webconsole-subscription-data-offline.json +if [ $? -ne 0 ]; then + echo "Failed to delete subscription data" + exit 1 +fi + +echo "test TestULCLTrafficInfluence with online charging" + # post ue (ci-test PacketRusher) data to db -./api-webconsole-subscribtion-data-action.sh post +./api-webconsole-subscribtion-data-action.sh post json/webconsole-subscription-data-online.json if [ $? -ne 0 ]; then echo "Failed to post subscription data" exit 1 @@ -23,11 +47,11 @@ go_test_exit_code=$? cd .. # delete ue (ci-test PacketRusher) data from db -./api-webconsole-subscribtion-data-action.sh delete +./api-webconsole-subscribtion-data-action.sh delete json/webconsole-subscription-data-online.json if [ $? -ne 0 ]; then echo "Failed to delete subscription data" exit 1 fi # return the test exit code -exit $go_test_exit_code \ No newline at end of file +exit $go_test_exit_code From b3cdd1391c834703811c54621195847da98d3b10 Mon Sep 17 00:00:00 2001 From: Alonza0314 Date: Mon, 24 Feb 2025 06:28:41 +0000 Subject: [PATCH 3/4] fix: incomplete terminated packetrusher and set requestedUnit to 1000 --- config/ULCL/smfCfg.yaml | 4 ++-- test/goTest/packetRusher/packetRusher.go | 7 +++++-- test/goTest/pinger/pinger.go | 6 +++--- test/json/webconsole-subscription-data-online.json | 6 +++--- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/config/ULCL/smfCfg.yaml b/config/ULCL/smfCfg.yaml index 47655d5..a5e50c0 100644 --- a/config/ULCL/smfCfg.yaml +++ b/config/ULCL/smfCfg.yaml @@ -99,8 +99,8 @@ configuration: nrfUri: http://nrf.free5gc.org:8000 # a valid URI of NRF nrfCertPem: cert/nrf.pem # NRF Certificate urrPeriod: 10 # default usage report period in seconds - urrThreshold: 10 # default usage report threshold in bytes - requestedUnit: 10 + urrThreshold: 300 # default usage report threshold in bytes + requestedUnit: 1000 ulcl: true logger: # log output setting enable: true # true or false diff --git a/test/goTest/packetRusher/packetRusher.go b/test/goTest/packetRusher/packetRusher.go index b916079..e2b7319 100644 --- a/test/goTest/packetRusher/packetRusher.go +++ b/test/goTest/packetRusher/packetRusher.go @@ -1,6 +1,7 @@ package packetrusher import ( + "os" "os/exec" ) @@ -44,8 +45,10 @@ func (pr *PacketRusher) Deactivate() { return } - pr.done <- true - close(pr.done) + if pr.cmd != nil && pr.cmd.Process != nil { + pr.cmd.Process.Signal(os.Interrupt) + pr.cmd.Wait() + } pr.isActive = false } diff --git a/test/goTest/pinger/pinger.go b/test/goTest/pinger/pinger.go index f31f5f1..c440ed4 100644 --- a/test/goTest/pinger/pinger.go +++ b/test/goTest/pinger/pinger.go @@ -7,16 +7,16 @@ import ( ) func Pinger(dstIP string, nic string) error { - cmd := exec.Command("ping", "-I", nic, "-c", "3", dstIP) + cmd := exec.Command("ping", "-I", nic, "-c", "3", "-s", "300", dstIP) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("ping failed: %v, output: %s", err, output) } - if !strings.Contains(string(output), " 0% packet loss") { + if strings.Contains(string(output), "0 reveived") { return fmt.Errorf("no response from %s: %s", dstIP, string(output)) } - + return nil } diff --git a/test/json/webconsole-subscription-data-online.json b/test/json/webconsole-subscription-data-online.json index a5da177..9662591 100644 --- a/test/json/webconsole-subscription-data-online.json +++ b/test/json/webconsole-subscription-data-online.json @@ -67,7 +67,7 @@ "downlink": "100 Mbps" }, "5gQosProfile": { - "5qi": 8, + "5qi": 9, "arp": { "priorityLevel": 8 }, @@ -111,7 +111,7 @@ "FlowRules": [ { "filter": "1.1.1.1/32", - "precedence": 127, + "precedence": 128, "snssai": "01010203", "dnn": "internet", "qosRef": 1 @@ -122,7 +122,7 @@ "snssai": "01010203", "dnn": "internet", "qosRef": 1, - "5qi": 7, + "5qi": 8, "mbrUL": "208 Mbps", "mbrDL": "208 Mbps", "gbrUL": "108 Mbps", From fbf2ff702734cb35b740375f1ddba1f0d43dcf0e Mon Sep 17 00:00:00 2001 From: Alonza0314 Date: Mon, 24 Feb 2025 06:39:46 +0000 Subject: [PATCH 4/4] docs: add charging data description --- doc/ulcl-traffic-influence.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/ulcl-traffic-influence.md b/doc/ulcl-traffic-influence.md index 57544c5..0d09766 100644 --- a/doc/ulcl-traffic-influence.md +++ b/doc/ulcl-traffic-influence.md @@ -21,6 +21,8 @@ 3. Reset Traffic Influence - Ping n6gw: expected ping success - Ping mec: expected ping failed +4. Check charging data record + - Check quota usage report data: expected quota usage report data is not 0 ## Test Steps