From 0aa06742972c077cc0e4dffeb1ef766341964b6c Mon Sep 17 00:00:00 2001 From: hardy Date: Sun, 26 Sep 2021 21:49:31 +0200 Subject: [PATCH 01/34] get test results into dahsboard : part 1 formatting --- ci-scripts/ran_dashboard.py | 91 +++++++++++++++++++++++++++---- ci-scripts/ran_dashboard_cfg.yaml | 12 ++++ 2 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 ci-scripts/ran_dashboard_cfg.yaml diff --git a/ci-scripts/ran_dashboard.py b/ci-scripts/ran_dashboard.py index d9ce62b3b6..7525c8684e 100644 --- a/ci-scripts/ran_dashboard.py +++ b/ci-scripts/ran_dashboard.py @@ -57,7 +57,7 @@ class gDashboard: #worksheet self.sheet = self.ss.worksheet(worksheet) self.ss.del_worksheet(self.sheet) #start by deleting the old sheet - self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="20") #create a new one + self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="30") #create a new one self.d = {} #data dictionary @@ -78,10 +78,21 @@ class gDashboard: row =[dt_string] self.sheet.insert_row(row, index=1, value_input_option='RAW') - #line 2 empty + #line 2 is for the test names (links to jenkins pipeline), updated at the end + #line 3 is for the column names i=3 row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts"] + + #test 1 + row.append("# PASS") + row.append("# FAIL") + row.append("Last Fail") + #test 2 + row.append("# PASS") + row.append("# FAIL") + row.append("Last Fail") + self.sheet.insert_row(row, index=i, value_input_option='RAW') #line 4 onward, MR data lines @@ -143,15 +154,29 @@ class gDashboard: found=True n+=1 + #add test results, notice : NSA only for the moment (code to be refactored for multiple tests afterwards) + cmd="python3 /home/oaicicd/mysql/sql_connect_dev.py "+str(self.d[x]['iid']) + + process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) + output = process.stdout.readline() + + tmp=output.decode("utf-8") + tmp=tmp.replace('\'','"') + tmp=tmp.rstrip() + testres = json.loads(tmp) + #build final row to be inserted, the first column is left empty for now, will be filled afterward with hyperlinks to gitlab MR row =["", str(date_time_obj.date()),str(self.d[x]['author']['name']),str(self.d[x]['title']),\ assignee, reviewer,\ - milestone1,milestone2,milestone3,review_form,milestone4,conflicts] + milestone1,milestone2,milestone3,review_form,milestone4,conflicts,\ + testres['PASS'],testres['FAIL']] + #insert the row to worksheet self.sheet.insert_row(row, index=i, value_input_option='RAW') - + + #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) i=3 @@ -162,10 +187,39 @@ class gDashboard: hyperlink= '\"'+"https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/"+ str(self.d[x]['iid']) +'\"' text= '\"'+str(self.d[x]['iid'])+'"' requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) + + cmd="python3 /home/oaicicd/mysql/sql_connect_dev.py "+str(self.d[x]['iid']) + process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) + output = process.stdout.readline() + tmp=output.decode("utf-8") + tmp=tmp.replace('\'','"') + tmp=tmp.rstrip() + testres = json.loads(tmp) + if len(testres['fails list'])>0: + colIndex=14 + hyperlink= '\"'+ testres['fails link'][0] +'\"' + text= '\"'+testres['fails list'][0]+'"' + requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) i=i+1 body = {"requests": requests} self.ss.batch_update(body) + #line 2 is for the test names + #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) + requests=[] + rowIndex=1 + colIndex=12 + hyperlink= '\"'+"https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-Mini-Module/"+'\"' + text= '\"'+'NSA Mini'+'"' + requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) + rowIndex=1 + colIndex=15 + hyperlink= '\"'+"https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module/"+'\"' + text= '\"'+'NR SA'+'"' + requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) + + body = {"requests": requests} + self.ss.batch_update(body) def addHyperlink(self, hyperlink, text, destinationSheetName, rowIndex, colIndex): @@ -207,17 +261,17 @@ class gDashboard: "copyPaste": { "source": { "sheetId": sourceSheetId, - "startRowIndex": 0, + "startRowIndex": 1, "endRowIndex": 40, "startColumnIndex": 0, - "endColumnIndex": 12 + "endColumnIndex": 19 }, "destination": { "sheetId": destinationSheetId, - "startRowIndex": 0, + "startRowIndex": 1, "endRowIndex": 40, "startColumnIndex": 0, - "endColumnIndex": 12 + "endColumnIndex": 19 }, "pasteType": "PASTE_FORMAT" } @@ -280,9 +334,26 @@ class gDashboard: } ) - body = {"requests": requests} - self.ss.batch_update(body) + #group MR related columns +# sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId'] +# requests.append( +# { +# "addDimensionGroup": { +# "range": { +# "dimension": "COLUMNS", +# "sheetId": sheetId, +# "startIndex": 3, +# "endIndex": 12 +# }, +# } +# } +# ) +# + body = {"requests": requests} + self.ss.batch_update(body) + + def main(): diff --git a/ci-scripts/ran_dashboard_cfg.yaml b/ci-scripts/ran_dashboard_cfg.yaml new file mode 100644 index 0000000000..3f5011f9af --- /dev/null +++ b/ci-scripts/ran_dashboard_cfg.yaml @@ -0,0 +1,12 @@ +LTE-2x2 : #short name used in the dashboard + job : 'RAN-LTE-2x2-Module-OAIEPC' #job name from Jenkins, used in the database + link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-2x2-Module-OAIEPC' +NSA-B200 : + job : 'RAN-NSA-B200-Module-LTEBOX' + link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-B200-Module-LTEBOX' +NSA-2x2 : + job : 'RAN-NSA-2x2-Module-OAIEPC' + link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-2x2-Module-OAIEPC' +SA-N310 : + job : 'RAN-SA-Module-CN5G' + link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G' \ No newline at end of file From d4e135960b9c309ba6ddca2be17d8a69d16f8b43 Mon Sep 17 00:00:00 2001 From: hardy Date: Sun, 10 Oct 2021 22:10:04 +0200 Subject: [PATCH 02/34] major update / refactoring for ran dashboard, including mysql db and test results table --- .../mysql4testresults/docker-compose.yml | 12 ++ ci-scripts/mysql4testresults/sql_connect.py | 33 ++++ .../{ => ran_dashboard}/ran_dashboard.py | 177 ++++++++++-------- .../ran_dashboard_cfg.yaml | 0 ci-scripts/ran_dashboard/sqlconnect.py | 64 +++++++ 5 files changed, 209 insertions(+), 77 deletions(-) create mode 100644 ci-scripts/mysql4testresults/docker-compose.yml create mode 100644 ci-scripts/mysql4testresults/sql_connect.py rename ci-scripts/{ => ran_dashboard}/ran_dashboard.py (71%) rename ci-scripts/{ => ran_dashboard}/ran_dashboard_cfg.yaml (100%) create mode 100644 ci-scripts/ran_dashboard/sqlconnect.py diff --git a/ci-scripts/mysql4testresults/docker-compose.yml b/ci-scripts/mysql4testresults/docker-compose.yml new file mode 100644 index 0000000000..1c60057ab2 --- /dev/null +++ b/ci-scripts/mysql4testresults/docker-compose.yml @@ -0,0 +1,12 @@ +version: '2' +services: + mysql: + container_name: oaicicd_mysql + restart: always + image: mysql:latest + environment: + MYSQL_ROOT_PASSWORD: 'ucZBc2XRYdvEm59F' + ports: + - "3307:3306" + volumes: + - /home/oaicicd/mysql/data:/var/lib/mysql diff --git a/ci-scripts/mysql4testresults/sql_connect.py b/ci-scripts/mysql4testresults/sql_connect.py new file mode 100644 index 0000000000..333e573e78 --- /dev/null +++ b/ci-scripts/mysql4testresults/sql_connect.py @@ -0,0 +1,33 @@ +import pymysql +import sys +from datetime import datetime + +#This is the script used to write the test results to the mysql DB +#Called by Jenkins pipeline (jenkinsfile) +#Must be located in /home/oaicicid/mysql on the database host +#Usage from Jenkinsfile : +#python3 /home/oaicicd/mysql/sql_connect.py ${JOB_NAME} ${params.eNB_MR} ${params.eNB_Branch} ${env.BUILD_ID} ${env.BUILD_URL} ${StatusForDb} '' + +class SQLConnect: + def __init__(self): + self.connection = pymysql.connect( + host='172.22.0.2', + user='root', + password = 'ucZBc2XRYdvEm59F', + db='oaicicd_tests', + port=3306 + ) + + def put(self,TEST,MR,BRANCH,BUILD,BUILD_LINK,STATUS): + now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + cur=self.connection.cursor() + cur.execute ('INSERT INTO test_results (TEST,MR,BRANCH,BUILD,BUILD_LINK,STATUS,DATE) VALUES (%s,%s,%s,%s,%s,%s,%s);' , (TEST, MR, BRANCH, BUILD, BUILD_LINK, STATUS, now)) + self.connection.commit() + self.connection.close() + + +if __name__ == "__main__": + mydb=SQLConnect() + mydb.put(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4],sys.argv[5],sys.argv[6]) + + diff --git a/ci-scripts/ran_dashboard.py b/ci-scripts/ran_dashboard/ran_dashboard.py similarity index 71% rename from ci-scripts/ran_dashboard.py rename to ci-scripts/ran_dashboard/ran_dashboard.py index 7525c8684e..5fddba1b87 100644 --- a/ci-scripts/ran_dashboard.py +++ b/ci-scripts/ran_dashboard/ran_dashboard.py @@ -42,6 +42,11 @@ import datetime #now() and date formating from datetime import datetime import re import gitlab +import yaml +import os +import pickle + +from sqlconnect import SQLConnect #----------------------------------------------------------- # Class Declaration @@ -58,58 +63,76 @@ class gDashboard: self.sheet = self.ss.worksheet(worksheet) self.ss.del_worksheet(self.sheet) #start by deleting the old sheet self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="30") #create a new one - - self.d = {} #data dictionary + + #init with data sources : git, yaml config file, test results databases + cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ + self.git = self.__getGitData(cmd) #git data from Gitlab + self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml + self.db = self.__loadFromDB() #test results from database - def fetchData(self,cmd): + def __loadCfg(self,yaml_file): + with open(yaml_file,'r') as f: + tests = yaml.load(f) + return tests + + def __getGitData(self,cmd): #cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) output = process.stdout.readline() tmp=output.decode("utf-8") - self.d = json.loads(tmp) + d = json.loads(tmp) + return d + + def __loadFromDB(self): + mr_list=[] + for x in range(len(self.git)): + mr_list.append(str(self.git[x]['iid'])) + mydb=SQLConnect() + for MR in mr_list: + mydb.get(MR) + mydb.close_connection() + return mydb.data + def gBuild(self, destinationSheetName): - #line 1 : update date/time, format dd/mm/YY H:M:S + ###line 1 : update date/time, format dd/mm/YY H:M:S now = datetime.now() dt_string = "Update : " + now.strftime("%d/%m/%Y %H:%M") row =[dt_string] self.sheet.insert_row(row, index=1, value_input_option='RAW') - #line 2 is for the test names (links to jenkins pipeline), updated at the end + ###line 2 is for the test short names (links to jenkins pipeline), updated at the end - #line 3 is for the column names + ###line 3 is for the column names i=3 row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts"] - #test 1 - row.append("# PASS") - row.append("# FAIL") - row.append("Last Fail") - #test 2 - row.append("# PASS") - row.append("# FAIL") - row.append("Last Fail") + #tests + for t in range(0,len(self.tests)): + row.append("# PASS") + row.append("# FAIL") + row.append("Last Fail") self.sheet.insert_row(row, index=i, value_input_option='RAW') - #line 4 onward, MR data lines - for x in range(len(self.d)): + ###line 4 onward, MR data lines + for x in range(len(self.git)): i=i+1 - date_time_str = self.d[x]['created_at'] + date_time_str = self.git[x]['created_at'] date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ') milestone1=milestone2=milestone3=milestone4="" - if self.d[x]['milestone']!=None: - if self.d[x]['milestone']['title']=="REVIEW_CAN_START": + if self.git[x]['milestone']!=None: + if self.git[x]['milestone']['title']=="REVIEW_CAN_START": milestone1="X" - elif self.d[x]['milestone']['title']=="REVIEW_IN_PROGRESS": + elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS": milestone2="X" - elif self.d[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED": + elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED": milestone3="X" - elif self.d[x]['milestone']['title']=="OK_TO_BE_MERGED": + elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED": milestone4="X" else: pass @@ -117,18 +140,18 @@ class gDashboard: pass #check if empty or not - if self.d[x]['assignee']!=None: - assignee = str(self.d[x]['assignee']['name']) + if self.git[x]['assignee']!=None: + assignee = str(self.git[x]['assignee']['name']) else: assignee = "" #check if empty or not - if len(self.d[x]['reviewers'])!=0: - reviewer = str(self.d[x]['reviewers'][0]['name']) + if len(self.git[x]['reviewers'])!=0: + reviewer = str(self.git[x]['reviewers'][0]['name']) else: reviewer = "" - if self.d[x]['has_conflicts']==True: + if self.git[x]['has_conflicts']==True: conflicts = "YES" else: conflicts = "" @@ -141,12 +164,12 @@ class gDashboard: project = gl.projects.get(project_id) #get the opened MR in the project mrs = project.mergerequests.list(state='opened') + review_form='' for m in range (0,len(mrs)): - if mrs[m].iid==self.d[x]['iid']:#check the iid is the one we are on + if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on mr_notes = mrs[m].notes.list(all=True) n=0 found=False - review_form="" while found==False and n0: - colIndex=14 - hyperlink= '\"'+ testres['fails link'][0] +'\"' - text= '\"'+testres['fails list'][0]+'"' - requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) - i=i+1 + mr=str(self.git[x]['iid']) + colIndex=14 + for t in self.tests: + job=self.tests[t]['job'] + if job in self.db[mr]: + if len(self.db[mr][job]['last_fail'])>0: + hyperlink= '\"'+ self.db[mr][job]['last_fail'][1] +'\"' + text= '\"'+self.db[mr][job]['last_fail'][0]+'"' + requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) + colIndex+=3 + i=i+1 #increment row index for next MR + + + body = {"requests": requests} self.ss.batch_update(body) - #line 2 is for the test names + ###line 2 is for the test names #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) requests=[] rowIndex=1 colIndex=12 - hyperlink= '\"'+"https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-Mini-Module/"+'\"' - text= '\"'+'NSA Mini'+'"' - requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) - rowIndex=1 - colIndex=15 - hyperlink= '\"'+"https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module/"+'\"' - text= '\"'+'NR SA'+'"' - requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) + for t in self.tests : + hyperlink= '\"'+self.tests[t]['link']+'\"' + short_name= '\"'+ t +'\"' + requests.append(self.addHyperlink(hyperlink, short_name, destinationSheetName, rowIndex, colIndex)) + colIndex+=3 body = {"requests": requests} self.ss.batch_update(body) @@ -264,14 +289,14 @@ class gDashboard: "startRowIndex": 1, "endRowIndex": 40, "startColumnIndex": 0, - "endColumnIndex": 19 + "endColumnIndex": 26 }, "destination": { "sheetId": destinationSheetId, "startRowIndex": 1, "endRowIndex": 40, "startColumnIndex": 0, - "endColumnIndex": 19 + "endColumnIndex": 26 }, "pasteType": "PASTE_FORMAT" } @@ -358,8 +383,6 @@ class gDashboard: def main(): my_gDashboard=gDashboard("/opt/dashboard/g_creds.json", 'OAI RAN Dashboard', 'MR Status') - cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ - my_gDashboard.fetchData(cmd) my_gDashboard.gBuild("MR Status") my_gDashboard.gFormat("Formating" , "MR Status") diff --git a/ci-scripts/ran_dashboard_cfg.yaml b/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml similarity index 100% rename from ci-scripts/ran_dashboard_cfg.yaml rename to ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml diff --git a/ci-scripts/ran_dashboard/sqlconnect.py b/ci-scripts/ran_dashboard/sqlconnect.py new file mode 100644 index 0000000000..272ff4e50f --- /dev/null +++ b/ci-scripts/ran_dashboard/sqlconnect.py @@ -0,0 +1,64 @@ +import pymysql +import sys +from datetime import datetime +import pickle + + +#This is the script/package used by the dashboard to retrieve the MR test results from the database + +class SQLConnect: + def __init__(self): + self.connection = pymysql.connect( + host='172.22.0.2', + user='root', + password = 'ucZBc2XRYdvEm59F', + db='oaicicd_tests', + port=3306 + ) + self.data={} + + + #retrieve data from mysql database and organize it in a dictionary (per MR passed as argument) + def get(self,MR): + self.data[MR]={} + cur=self.connection.cursor() + + #get counters per test + sql = "select TEST,STATUS, count(*) AS COUNT from test_results where MR=(%s) group by TEST, STATUS;" + cur.execute(sql,MR) + response=cur.fetchall() + if len(response)==0:#no test results yet + self.data[MR]['PASS']='' + self.data[MR]['FAIL']='' + else: + for i in range(0,len(response)): + test=response[i][0] + status=response[i][1] + count=response[i][2] + if test in self.data[MR]: + self.data[MR][test][status]=count + else: + self.data[MR][test]={} + self.data[MR][test][status]=count + + #get last failing build and link + sql = "select TEST,BUILD, BUILD_LINK from test_results where MR=(%s) and STATUS='FAIL' order by DATE DESC;" + cur.execute(sql,MR) + response=cur.fetchall() + if len(response)!=0: + for i in range(0,len(response)): + test=response[i][0] + build=response[i][1] + link=response[i][2] + if 'last_fail' not in self.data[MR][test]: + self.data[MR][test]['last_fail']=[] + self.data[MR][test]['last_fail'].append(build) + self.data[MR][test]['last_fail'].append(link) + + + + #close database connection + def close_connection(self): + self.connection.close() + + From 8dd7e58977d1b370374dbf33bb93a78c8715718c Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 14 Oct 2021 08:42:30 +0200 Subject: [PATCH 03/34] change to specific run dir --- ci-scripts/Jenkinsfile-git-dashboard | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ci-scripts/Jenkinsfile-git-dashboard b/ci-scripts/Jenkinsfile-git-dashboard index 6ebd46bc76..0eb82f05b4 100644 --- a/ci-scripts/Jenkinsfile-git-dashboard +++ b/ci-scripts/Jenkinsfile-git-dashboard @@ -33,9 +33,10 @@ pipeline { stages { stage ("gDashboard") { steps { - script { - //retrieve MR data from gitlab and export to gSheet - sh returnStdout: true, script: 'python3 ci-scripts/ran_dashboard.py' + script { + dir ("ci-scripts/ran_dashboard") { + //retrieve MR data from gitlab and export to gSheet + sh returnStdout: true, script: 'python3 ran_dashboard.py' } } } From 90f3e9e2315015e72a6ed13194d6662515ae86e6 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 14 Oct 2021 08:45:00 +0200 Subject: [PATCH 04/34] fix missing bracket --- ci-scripts/Jenkinsfile-git-dashboard | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-scripts/Jenkinsfile-git-dashboard b/ci-scripts/Jenkinsfile-git-dashboard index 0eb82f05b4..8c5d773192 100644 --- a/ci-scripts/Jenkinsfile-git-dashboard +++ b/ci-scripts/Jenkinsfile-git-dashboard @@ -37,6 +37,7 @@ pipeline { dir ("ci-scripts/ran_dashboard") { //retrieve MR data from gitlab and export to gSheet sh returnStdout: true, script: 'python3 ran_dashboard.py' + } } } } From 8ccb745d42d47e2d5337f588c890e1b818fb2e01 Mon Sep 17 00:00:00 2001 From: hardy Date: Fri, 15 Oct 2021 11:21:03 +0200 Subject: [PATCH 05/34] add delay to overcome google api quota --- ci-scripts/ran_dashboard/ran_dashboard.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci-scripts/ran_dashboard/ran_dashboard.py b/ci-scripts/ran_dashboard/ran_dashboard.py index 5fddba1b87..11d14407eb 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard.py +++ b/ci-scripts/ran_dashboard/ran_dashboard.py @@ -45,6 +45,8 @@ import gitlab import yaml import os import pickle +import time + from sqlconnect import SQLConnect @@ -203,6 +205,7 @@ class gDashboard: #insert the final row to worksheet self.sheet.insert_row(row, index=i, value_input_option='RAW') + time.sleep(20) #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) From 4b7de3945007d1e6d9f02028871eb5f7000aa7bd Mon Sep 17 00:00:00 2001 From: hardy Date: Fri, 15 Oct 2021 15:11:45 +0200 Subject: [PATCH 06/34] add last_pass --- ci-scripts/ran_dashboard/ran_dashboard.py | 23 +++++++----- ci-scripts/ran_dashboard/sqlconnect.py | 45 ++++++++++++++++++++++- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/ci-scripts/ran_dashboard/ran_dashboard.py b/ci-scripts/ran_dashboard/ran_dashboard.py index 11d14407eb..23860f7714 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard.py +++ b/ci-scripts/ran_dashboard/ran_dashboard.py @@ -30,6 +30,8 @@ # Import #----------------------------------------------------------- +#author Remi + #import google spreadsheet API import gspread from oauth2client.service_account import ServiceAccountCredentials @@ -110,12 +112,13 @@ class gDashboard: ###line 3 is for the column names i=3 - row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts"] + row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","Review Form","OK MERGE","Merge conflicts",""] #tests for t in range(0,len(self.tests)): row.append("# PASS") row.append("# FAIL") + row.append("Last Pass") row.append("Last Fail") self.sheet.insert_row(row, index=i, value_input_option='RAW') @@ -182,7 +185,7 @@ class gDashboard: #build final row to be inserted, the first column is left empty for now, will be filled afterward with hyperlinks to gitlab MR row =["", str(date_time_obj.date()),str(self.git[x]['author']['name']), str(self.git[x]['title']),\ assignee, reviewer,\ - milestone1,milestone2,milestone3,review_form,milestone4,conflicts] + milestone1,milestone2,milestone3,review_form,milestone4,conflicts,""] #and append the test results coming from self.db mr=str(self.git[x]['iid']) for t in self.tests: @@ -205,7 +208,7 @@ class gDashboard: #insert the final row to worksheet self.sheet.insert_row(row, index=i, value_input_option='RAW') - time.sleep(20) + time.sleep(10) #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) @@ -223,15 +226,17 @@ class gDashboard: for t in self.tests: job=self.tests[t]['job'] if job in self.db[mr]: + if len(self.db[mr][job]['last_pass'])>0: + hyperlink= '\"'+ self.db[mr][job]['last_pass'][1] +'\"' + text= '\"'+self.db[mr][job]['last_pass'][0]+'"' + requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) if len(self.db[mr][job]['last_fail'])>0: hyperlink= '\"'+ self.db[mr][job]['last_fail'][1] +'\"' text= '\"'+self.db[mr][job]['last_fail'][0]+'"' - requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) - colIndex+=3 + requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex+1)) + colIndex+=4 #move to next test i=i+1 #increment row index for next MR - - body = {"requests": requests} self.ss.batch_update(body) @@ -292,14 +297,14 @@ class gDashboard: "startRowIndex": 1, "endRowIndex": 40, "startColumnIndex": 0, - "endColumnIndex": 26 + "endColumnIndex": 30 }, "destination": { "sheetId": destinationSheetId, "startRowIndex": 1, "endRowIndex": 40, "startColumnIndex": 0, - "endColumnIndex": 26 + "endColumnIndex": 30 }, "pasteType": "PASTE_FORMAT" } diff --git a/ci-scripts/ran_dashboard/sqlconnect.py b/ci-scripts/ran_dashboard/sqlconnect.py index 272ff4e50f..9045c25ca9 100644 --- a/ci-scripts/ran_dashboard/sqlconnect.py +++ b/ci-scripts/ran_dashboard/sqlconnect.py @@ -1,9 +1,39 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ +#--------------------------------------------------------------------- +# Merge Requests Dashboard for RAN on googleSheet +# +# Required Python Version +# Python 3.x +# +#--------------------------------------------------------------------- + +#author Remi + + import pymysql import sys from datetime import datetime import pickle - #This is the script/package used by the dashboard to retrieve the MR test results from the database class SQLConnect: @@ -55,6 +85,19 @@ class SQLConnect: self.data[MR][test]['last_fail'].append(build) self.data[MR][test]['last_fail'].append(link) + #get last passing build and link + sql = "select TEST,BUILD, BUILD_LINK from test_results where MR=(%s) and STATUS='PASS' order by DATE DESC;" + cur.execute(sql,MR) + response=cur.fetchall() + if len(response)!=0: + for i in range(0,len(response)): + test=response[i][0] + build=response[i][1] + link=response[i][2] + if 'last_pass' not in self.data[MR][test]: + self.data[MR][test]['last_pass']=[] + self.data[MR][test]['last_pass'].append(build) + self.data[MR][test]['last_pass'].append(link) #close database connection From 64850ccfc239bffedff0d00852c4dbb3c9fd3a36 Mon Sep 17 00:00:00 2001 From: hardy Date: Fri, 15 Oct 2021 15:17:33 +0200 Subject: [PATCH 07/34] fix empty columns count --- ci-scripts/ran_dashboard/ran_dashboard.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci-scripts/ran_dashboard/ran_dashboard.py b/ci-scripts/ran_dashboard/ran_dashboard.py index 23860f7714..6391ae101d 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard.py +++ b/ci-scripts/ran_dashboard/ran_dashboard.py @@ -200,11 +200,15 @@ class gDashboard: row.append(self.db[mr][job]['FAIL']) else: row.append('') + #leave 2 columns for last_pass and last_fail links + row.append('') row.append('') else: + #4 columns are empty row.append('') row.append('') row.append('') + row.append('') #insert the final row to worksheet self.sheet.insert_row(row, index=i, value_input_option='RAW') From 72a2fc67f3056dc5c4d375d733cefa97381690fe Mon Sep 17 00:00:00 2001 From: hardy Date: Fri, 15 Oct 2021 15:40:41 +0200 Subject: [PATCH 08/34] fix key error in data model --- ci-scripts/ran_dashboard/ran_dashboard.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/ran_dashboard/ran_dashboard.py b/ci-scripts/ran_dashboard/ran_dashboard.py index 6391ae101d..1be96802ac 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard.py +++ b/ci-scripts/ran_dashboard/ran_dashboard.py @@ -230,11 +230,11 @@ class gDashboard: for t in self.tests: job=self.tests[t]['job'] if job in self.db[mr]: - if len(self.db[mr][job]['last_pass'])>0: + if 'last_pass' in self.db[mr][job]: hyperlink= '\"'+ self.db[mr][job]['last_pass'][1] +'\"' text= '\"'+self.db[mr][job]['last_pass'][0]+'"' requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) - if len(self.db[mr][job]['last_fail'])>0: + if 'last_fail' in self.db[mr][job]: hyperlink= '\"'+ self.db[mr][job]['last_fail'][1] +'\"' text= '\"'+self.db[mr][job]['last_fail'][0]+'"' requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex+1)) From d2dff05c8cd79f9a01b9cd122e3762ae55640816 Mon Sep 17 00:00:00 2001 From: hardy Date: Fri, 15 Oct 2021 16:03:51 +0200 Subject: [PATCH 09/34] fix column shift for the test results --- ci-scripts/ran_dashboard/ran_dashboard.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/ran_dashboard/ran_dashboard.py b/ci-scripts/ran_dashboard/ran_dashboard.py index 1be96802ac..36742f3672 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard.py +++ b/ci-scripts/ran_dashboard/ran_dashboard.py @@ -226,7 +226,7 @@ class gDashboard: requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex)) mr=str(self.git[x]['iid']) - colIndex=14 + colIndex=15 for t in self.tests: job=self.tests[t]['job'] if job in self.db[mr]: @@ -248,12 +248,12 @@ class gDashboard: #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas) requests=[] rowIndex=1 - colIndex=12 + colIndex=13 for t in self.tests : hyperlink= '\"'+self.tests[t]['link']+'\"' short_name= '\"'+ t +'\"' requests.append(self.addHyperlink(hyperlink, short_name, destinationSheetName, rowIndex, colIndex)) - colIndex+=3 + colIndex+=4 body = {"requests": requests} self.ss.batch_update(body) From 707a8000dbab537b9a4e962f461688d6bd58fcd9 Mon Sep 17 00:00:00 2001 From: hardy Date: Wed, 20 Oct 2021 15:49:16 +0200 Subject: [PATCH 10/34] google sheet dashboard is deprecated, replaced by Html dashboard hosted on AWS S3 --- ci-scripts/Jenkinsfile-git-dashboard | 5 +- ci-scripts/ran_dashboard/Hdashboard.py | 401 ++++++++++++++++++ ci-scripts/ran_dashboard/mr_styles.css | 136 ++++++ ci-scripts/ran_dashboard/ran_dashboard.py | 2 +- .../ran_dashboard/ran_dashboard_cfg.yaml | 19 +- ci-scripts/ran_dashboard/readme.txt | 3 + ci-scripts/ran_dashboard/test_styles.css | 103 +++++ 7 files changed, 661 insertions(+), 8 deletions(-) create mode 100644 ci-scripts/ran_dashboard/Hdashboard.py create mode 100755 ci-scripts/ran_dashboard/mr_styles.css create mode 100644 ci-scripts/ran_dashboard/readme.txt create mode 100755 ci-scripts/ran_dashboard/test_styles.css diff --git a/ci-scripts/Jenkinsfile-git-dashboard b/ci-scripts/Jenkinsfile-git-dashboard index 8c5d773192..87e781fe8a 100644 --- a/ci-scripts/Jenkinsfile-git-dashboard +++ b/ci-scripts/Jenkinsfile-git-dashboard @@ -35,8 +35,9 @@ pipeline { steps { script { dir ("ci-scripts/ran_dashboard") { - //retrieve MR data from gitlab and export to gSheet - sh returnStdout: true, script: 'python3 ran_dashboard.py' + //retrieve MR data from gitlab / mySQL db, build HTML pages and load them to AWS S3 bucket (configured as static web page hosting) + //deprecated method : sh returnStdout: true, script: 'python3 ran_dashboard.py' + sh returnStdout: true, script: 'python3 Hdashboard.py' } } } diff --git a/ci-scripts/ran_dashboard/Hdashboard.py b/ci-scripts/ran_dashboard/Hdashboard.py new file mode 100644 index 0000000000..5e34ae50bf --- /dev/null +++ b/ci-scripts/ran_dashboard/Hdashboard.py @@ -0,0 +1,401 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ +#--------------------------------------------------------------------- +# Merge Requests Dashboard for RAN on googleSheet +# +# Required Python Version +# Python 3.x +# +#--------------------------------------------------------------------- + +#----------------------------------------------------------- +# Import +#----------------------------------------------------------- + + +#Author Remi +import boto3 +import shlex +import subprocess +import json #json structures +import datetime #now() and date formating +from datetime import datetime +import re +import gitlab +import yaml +import os +import time + + +from sqlconnect import SQLConnect + +#----------------------------------------------------------- +# Class Declaration +#----------------------------------------------------------- + +class Dashboard: + def __init__(self): + + + #init with data sources : git, yaml config file, test results databases + print("Collecting Data") + cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ + self.git = self.__getGitData(cmd) #git data from Gitlab + self.tests = self.__loadCfg('ran_dashboard_cfg.yaml') #tests table setup from yaml + self.db = self.__loadFromDB() #test results from database + + + def __loadCfg(self,yaml_file): + with open(yaml_file,'r') as f: + tests = yaml.load(f) + return tests + + def __getGitData(self,cmd): + #cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """ + process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) + output = process.stdout.readline() + tmp=output.decode("utf-8") + d = json.loads(tmp) + return d + + def __loadFromDB(self): + mr_list=[] + for x in range(len(self.git)): + mr_list.append(str(self.git[x]['iid'])) + mydb=SQLConnect() + for MR in mr_list: + mydb.get(MR) + mydb.close_connection() + return mydb.data + + def Test_initHTML(self, date): + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('Test Dashboard\n') + self.f_html.write('\n') + self.f_html.write('
\n') + self.f_html.write('
\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('
OAI RAN TEST Status Dashboard
Update : '+date+'
\n') + self.f_html.write('
\n') + self.f_html.write('
\n') + + def Test_terminateHTML(self): + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.close() + + + def MR_initHTML(self,date): + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('MR Dashboard\n') + self.f_html.write('\n') + self.f_html.write('
\n') + self.f_html.write('
\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('
OAI RAN MR Status Dashboard
Update : '+date+'
\n') + self.f_html.write('
\n') + self.f_html.write('
\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + + def MR_terminateHTML(self): + self.f_html.write('
MRCreated_AtAuthorTitleAssigneeReviewerCAN STARTIN PROGRESSCOMPLETEDReview FormOK MergeMerge Conflicts
\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.close() + + + def MR_rowHTML(self,row): + self.f_html.write('\n') + self.f_html.write(''+row[1]+'\n') + self.f_html.write(''+row[2]+'\n') + self.f_html.write(''+row[3]+'\n') + self.f_html.write(''+row[4]+'\n') + self.f_html.write(''+row[5]+'\n') + self.f_html.write(''+row[6]+'\n') + if row[7]=='X': + self.f_html.write(''+row[7]+'\n') + else: + self.f_html.write('\n') + if row[8]=='X': + self.f_html.write(''+row[8]+'\n') + else: + self.f_html.write('\n') + if row[9]=='X': + self.f_html.write(''+row[9]+'\n') + else: + self.f_html.write('\n') + if row[10]=='X': + self.f_html.write(''+row[10]+'\n') + else: + self.f_html.write('\n') + if row[11]=='X': + self.f_html.write(''+row[11]+'\n') + else: + self.f_html.write('\n') + if row[12]=='YES': + self.f_html.write(''+row[12]+'\n') + else: + self.f_html.write('\n') + self.f_html.write('\n') + + + def Build(self, type, htmlfilename): + if type=='MR': + self.Build_MR_Table(htmlfilename) + elif type=='Tests': + self.Build_Test_Table(htmlfilename) + else : + print("Undefined Dashboard Type, options : MR or Tests") + + + def Build_Test_Table(self,htmlfilename): + print("Building Tests Dashboard...") + + self.f_html=open(htmlfilename,'w') + + ###update date/time, format dd/mm/YY H:M:S + now = datetime.now() + dt_string = now.strftime("%d/%m/%Y %H:%M") + #HTML table header + self.Test_initHTML(dt_string) + + + #1 table per MR if test results exist + for x in range(len(self.git)): + mr=str(self.git[x]['iid']) + if 'PASS' not in self.db[mr]: + self.f_html.write('

'+mr+''+' '+self.git[x]['title'] + '

\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write(' \n') + self.f_html.write(' \n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + + #parsing the tests + for t in self.tests: + + row=[] + short_name= t + hyperlink= self.tests[t]['link'] + job=self.tests[t]['job'] + + + if job in self.db[mr]: + if 'PASS' in self.db[mr][job]: + row.append(self.db[mr][job]['PASS']) + else: + row.append('') + if 'FAIL' in self.db[mr][job]: + row.append(self.db[mr][job]['FAIL']) + else: + row.append('') + #2 columns for last_pass and last_fail links + if 'last_pass' in self.db[mr][job]: + lastpasshyperlink= self.db[mr][job]['last_pass'][1] + lastpasstext= self.db[mr][job]['last_pass'][0] + else: + lastpasshyperlink='' + lastpasstext='' + + if 'last_fail' in self.db[mr][job]: + lastfailhyperlink= self.db[mr][job]['last_fail'][1] + lastfailtext= self.db[mr][job]['last_fail'][0] + else: + lastfailhyperlink='' + lastfailtext='' + + + + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + if row[0]!='': + self.f_html.write('\n') + else: + self.f_html.write('\n') + if row[1]!='': + self.f_html.write('\n') + else: + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + self.f_html.write('\n') + + self.f_html.write('
Test NameBenchTest# Pass# FailLast PassLast Fail
'+short_name+''+self.tests[t]['bench']+''+self.tests[t]['test']+''+str(row[0])+''+str(row[1])+''+lastpasstext+''+lastfailtext+'
\n') + + #terminate HTML table and close file + self.Test_terminateHTML() + + + def Build_MR_Table(self,htmlfilename): + + print("Building Merge Requests Dashboard...") + + self.f_html=open(htmlfilename,'w') + + ###update date/time, format dd/mm/YY H:M:S + now = datetime.now() + dt_string = now.strftime("%d/%m/%Y %H:%M") + + #HTML table header + self.MR_initHTML(dt_string) + + + ###MR data lines + for x in range(len(self.git)): + + + hyperlink= 'https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/'+ str(self.git[x]['iid']) + text= str(self.git[x]['iid']) + + + date_time_str = self.git[x]['created_at'] + date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ') + + milestone1=milestone2=milestone3=milestone4="" + if self.git[x]['milestone']!=None: + if self.git[x]['milestone']['title']=="REVIEW_CAN_START": + milestone1="X" + elif self.git[x]['milestone']['title']=="REVIEW_IN_PROGRESS": + milestone2="X" + elif self.git[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED": + milestone3="X" + elif self.git[x]['milestone']['title']=="OK_TO_BE_MERGED": + milestone4="X" + else: + pass + else: + pass + + #check if empty or not + if self.git[x]['assignee']!=None: + assignee = str(self.git[x]['assignee']['name']) + else: + assignee = "" + + #check if empty or not + if len(self.git[x]['reviewers'])!=0: + reviewer = str(self.git[x]['reviewers'][0]['name']) + else: + reviewer = "" + + if self.git[x]['has_conflicts']==True: + conflicts = "YES" + else: + conflicts = "" + + + #add a column flagging that the review form is present + #we use gitlab API to parse the MR notes + gl = gitlab.Gitlab.from_config('OAI') + project_id = 223 + project = gl.projects.get(project_id) + #get the opened MR in the project + mrs = project.mergerequests.list(state='opened',per_page=100) + review_form='' + for m in range (0,len(mrs)): + if mrs[m].iid==self.git[x]['iid']:#check the iid is the one we are on + mr_notes = mrs[m].notes.list(all=True) + n=0 + found=False + while found==False and n Date: Wed, 3 Nov 2021 14:44:25 +0100 Subject: [PATCH 11/34] fix tests description --- ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml b/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml index 3e341b7c58..011925491d 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml +++ b/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml @@ -2,7 +2,7 @@ LTE-2x2 : #short name used in the dashboard job : 'RAN-LTE-2x2-Module-OAIEPC' #job name from Jenkins, used in the database link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-2x2-Module-OAIEPC' bench : 'Obelix-N310-OAIEPC-Quectel(nrmodule2)' - test : 'TM2, TDD, 20MHz, MCS9, 26Mb DL, 7Mb UL' + test : 'TM2, TDD, 40MHz, MCS9, 26Mb DL, 7Mb UL' NSA-B200 : job : 'RAN-NSA-B200-Module-LTEBOX' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-B200-Module-LTEBOX' @@ -12,10 +12,10 @@ NSA-2x2 : job : 'RAN-NSA-2x2-Module-OAIEPC' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-2x2-Module-OAIEPC' bench : 'Asterix-N310-Obelix-N310-OAIEPC-Quectel(nrmodule2)' - test : 'TM2, TDD, 20MHz, MCS9, 20Mb DL, 3Mb UL' + test : 'TM2, TDD, 40MHz, MCS9, 20Mb DL, 3Mb UL' SA-N310 : job : 'RAN-SA-Module-CN5G' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G' bench : 'Asterix-N310-OAICN5G-Quectel(nrmodule2)' - test : 'TM2, TDD, 20MHz, 20Mb DL, 3Mb UL' + test : 'TM2, TDD, 40MHz, 20Mb DL, 3Mb UL' From ed84d40f728815608c3e3ac555fcf2b710b02446 Mon Sep 17 00:00:00 2001 From: mjoang Date: Fri, 1 Oct 2021 15:52:07 -0400 Subject: [PATCH 12/34] add mutex to protect ul_config_pdu against race condition. --- nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h | 2 ++ openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 2 ++ openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 3 +++ openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 4 +++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index e1bb2579eb..0e923931ad 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -16,6 +16,7 @@ #ifndef _FAPI_NR_UE_INTERFACE_H_ #define _FAPI_NR_UE_INTERFACE_H_ +#include #include "stddef.h" #include "platform_types.h" @@ -349,6 +350,7 @@ typedef struct { uint16_t slot; uint8_t number_pdus; fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM]; + pthread_mutex_t mutex_ul_config; } fapi_nr_ul_config_request_t; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 697f5b19d1..58cdbcf296 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -153,6 +153,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config; + pthread_mutex_lock(&ul_config->mutex_ul_config); for (i = 0; i < ul_config->number_pdus; ++i){ AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type); @@ -229,6 +230,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ } } memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t)); + pthread_mutex_unlock(&ul_config->mutex_ul_config); } } return 0; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index af0c84dc4b..73b5a35b62 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -40,6 +40,7 @@ #include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "executables/softmodem-common.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" +#include static NR_UE_MAC_INST_t *nr_ue_mac_inst; @@ -74,6 +75,8 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { num_slots_ul++; LOG_D(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul); nr_ue_mac_inst->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t)); + for (int i=0; iul_config_request[i].mutex_ul_config), NULL); } } else { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index f813efad92..1f8f6b8574 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -30,6 +30,7 @@ #include #include +#include /* exe */ #include @@ -59,11 +60,12 @@ static prach_association_pattern_t prach_assoc_pattern; static ssb_list_info_t ssb_list; void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){ - + pthread_mutex_lock(&ul_config->mutex_ul_config); ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type; ul_config->slot = slot_tx; ul_config->sfn = frame_tx; ul_config->number_pdus++; + pthread_mutex_unlock(&ul_config->mutex_ul_config); LOG_D(NR_MAC, "In %s: Set config request for UL transmission in [%d.%d], number of UL PDUs: %d\n", __FUNCTION__, ul_config->sfn, ul_config->slot, ul_config->number_pdus); From f150e37deb22e425514d5567cf78d6c5fa397a82 Mon Sep 17 00:00:00 2001 From: mjoang Date: Thu, 7 Oct 2021 10:33:25 -0400 Subject: [PATCH 13/34] Fix a logical error that sends obsolete buffer erroneously on UL and causes crash in gNB. --- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 58cdbcf296..0c992f2e3e 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -184,14 +184,17 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; - if (scheduled_response->tx_request){ - fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[i]; - LOG_D(PHY,"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",scheduled_response->frame,slot,tx_req_body->pdu_length,current_harq_pid); - memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length); - - harq_process_ul_ue->status = ACTIVE; - - scheduled_response->tx_request->number_of_pdus = 0; + if (scheduled_response->tx_request && scheduled_response->tx_request->number_of_pdus) { + for (int j=0; jtx_request->number_of_pdus; j++) { + fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[j]; + if (tx_req_body->pdu_index == i) { + LOG_D(PHY,"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",scheduled_response->frame,slot,tx_req_body->pdu_length,current_harq_pid); + memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length); + harq_process_ul_ue->status = ACTIVE; + scheduled_response->tx_request->number_of_pdus--; + break; + } + } } } else { From 0e8d5798feb917b405e7dd002e827cbfc8867fbf Mon Sep 17 00:00:00 2001 From: mjoang Date: Thu, 7 Oct 2021 12:54:10 -0400 Subject: [PATCH 14/34] Fix a logical error that sends obsolete buffer erroneously on UL and causes crash in gNB. --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 33 +++++++++++++-------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 1f8f6b8574..5630e09121 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -951,16 +951,20 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); - uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; + uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES]; nr_scheduled_response_t scheduled_response; fapi_nr_tx_request_t tx_req; + tx_req.slot = slot_tx; + tx_req.sfn = frame_tx; + tx_req.number_of_pdus = 0; for (int j = 0; j < ul_config->number_pdus; j++) { + uint8_t *ulsch_input_buffer = &(ulsch_input_buffer_array[tx_req.number_of_pdus][MAX_ULSCH_PAYLOAD_BYTES]); fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j]; if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { - + int mac_pdu_exist=0; uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d (ra_state %d)\n", ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, @@ -976,6 +980,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in LOG_D(NR_MAC,"Flipping NDI for harq_id %d (Msg3)\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; + mac_pdu_exist = 1; } else { if ((mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator || @@ -986,6 +991,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in // Getting IP traffic to be transmitted nr_ue_get_sdu(mod_id, cc_id,frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); + mac_pdu_exist=1; } LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); @@ -995,20 +1001,19 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } // Config UL TX PDU - tx_req.slot = slot_tx; - tx_req.sfn = frame_tx; - tx_req.number_of_pdus++; - tx_req.tx_request_body[0].pdu_length = TBS_bytes; - tx_req.tx_request_body[0].pdu_index = j; - tx_req.tx_request_body[0].pdu = ulsch_input_buffer; - + if (mac_pdu_exist) { + tx_req.tx_request_body[tx_req.number_of_pdus].pdu_length = TBS_bytes; + tx_req.tx_request_body[tx_req.number_of_pdus].pdu_index = j; + tx_req.tx_request_body[tx_req.number_of_pdus].pdu = ulsch_input_buffer; + tx_req.number_of_pdus++; + } if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){ - LOG_I(NR_MAC,"[RAPROC] RA-Msg3 retransmitted\n"); + LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); } if (ra->ra_state == WAIT_RAR && !ra->cfra){ - LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n"); + LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); } } @@ -2725,7 +2730,11 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, if (sdu_length > 0) { - LOG_D(NR_MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__, + LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", + __FUNCTION__, + module_idP, + frameP, + subframe, num_sdus + 1, sdu_length, lcid, From 764da1379e452bc6966556074422ae45cef184c4 Mon Sep 17 00:00:00 2001 From: mjoang Date: Tue, 12 Oct 2021 14:28:48 -0400 Subject: [PATCH 15/34] protect ul_config_pdu against race condition --- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 1 + openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 9 ++++++- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 25 +++++++++++++++----- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 0c992f2e3e..4e7191241c 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -175,6 +175,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu; current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id; NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch0->harq_processes[current_harq_pid]; + harq_process_ul_ue->status = 0; if (harq_process_ul_ue){ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index d555014bc8..50710b325f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -668,7 +668,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); return -1; } - + pthread_mutex_lock(&ul_config->mutex_ul_config); AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; @@ -676,6 +676,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr // Config PUSCH PDU ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); + pthread_mutex_unlock(&ul_config->mutex_ul_config); } @@ -729,12 +730,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr return -1; } + pthread_mutex_lock(&ul_config->mutex_ul_config); + AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); // Config PUSCH PDU ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); + pthread_mutex_unlock(&ul_config->mutex_ul_config); } else AssertFatal(1==0,"Cannot schedule PUSCH\n"); break; @@ -3921,12 +3925,15 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t rnti = ra->t_crnti; } + pthread_mutex_lock(&ul_config->mutex_ul_config); + AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); // Config Msg3 PDU nr_config_pusch_pdu(mac, pusch_config_pdu, NULL, &rar_grant, rnti, NULL); + pthread_mutex_unlock(&ul_config->mutex_ul_config); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 5630e09121..f6d27c54cd 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -60,12 +60,10 @@ static prach_association_pattern_t prach_assoc_pattern; static ssb_list_info_t ssb_list; void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){ - pthread_mutex_lock(&ul_config->mutex_ul_config); ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type; ul_config->slot = slot_tx; ul_config->sfn = frame_tx; ul_config->number_pdus++; - pthread_mutex_unlock(&ul_config->mutex_ul_config); LOG_D(NR_MAC, "In %s: Set config request for UL transmission in [%d.%d], number of UL PDUs: %d\n", __FUNCTION__, ul_config->sfn, ul_config->slot, ul_config->number_pdus); @@ -947,7 +945,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in // Schedule ULSCH only if the current frame and slot match those in ul_config_req // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) - if (ul_config && (ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){ + if (ul_config){ + pthread_mutex_lock(&ul_config->mutex_ul_config); + if ((ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){ + pthread_mutex_unlock(&ul_config->mutex_ul_config); LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); @@ -958,13 +959,14 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in tx_req.sfn = frame_tx; tx_req.number_of_pdus = 0; + pthread_mutex_lock(&ul_config->mutex_ul_config); for (int j = 0; j < ul_config->number_pdus; j++) { - uint8_t *ulsch_input_buffer = &(ulsch_input_buffer_array[tx_req.number_of_pdus][MAX_ULSCH_PAYLOAD_BYTES]); + uint8_t *ulsch_input_buffer = &(ulsch_input_buffer_array[tx_req.number_of_pdus][MAX_ULSCH_PAYLOAD_BYTES]); fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j]; if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { - int mac_pdu_exist=0; + int mac_pdu_exist = 0; uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d (ra_state %d)\n", ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, @@ -991,7 +993,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in // Getting IP traffic to be transmitted nr_ue_get_sdu(mod_id, cc_id,frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); - mac_pdu_exist=1; + mac_pdu_exist = 1; } LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); @@ -1018,11 +1020,16 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } } } + pthread_mutex_unlock(&ul_config->mutex_ul_config); fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ mac->if_module->scheduled_response(&scheduled_response); } + } + else { + pthread_mutex_unlock(&ul_config->mutex_ul_config); + } } } @@ -2151,6 +2158,8 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in pucch->resource_set_id = find_pucch_resource_set(mac, N_UCI); select_pucch_resource(mac, pucch); fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); + pthread_mutex_lock(&ul_config->mutex_ul_config); + AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu; nr_ue_configure_pucch(mac, slotP, @@ -2160,6 +2169,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in O_SR, O_ACK, O_CSI); LOG_D(NR_MAC,"Configuring pucch, is_common = %d\n",pucch->is_common); fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); + pthread_mutex_unlock(&ul_config->mutex_ul_config); nr_scheduled_response_t scheduled_response; fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) @@ -2220,6 +2230,8 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s format0 = format & 0xff; // single PRACH format format1 = (format >> 8) & 0xff; // dual PRACH format + pthread_mutex_lock(&ul_config->mutex_ul_config); + AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); @@ -2302,6 +2314,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s AssertFatal(1 == 0, "Invalid PRACH format"); } } // if format1 + pthread_mutex_unlock(&ul_config->mutex_ul_config); fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); From 698b75eba75cdea73af2da7e0d1487e33a0d1b63 Mon Sep 17 00:00:00 2001 From: mjoang Date: Thu, 4 Nov 2021 16:39:54 -0400 Subject: [PATCH 16/34] fix a bug from review on memsetting the complete structure (including the mutex). --- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 4e7191241c..a3856e0f65 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -233,7 +233,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ break; } } - memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t)); + ul_config->sfn = 0; + ul_config->slot = 0; + ul_config->number_pdus = 0; + for (int i=0; i < FAPI_NR_UL_CONFIG_LIST_NUM; i++) + memset(&(ul_config->ul_config_list[i]), 0, sizeof(fapi_nr_ul_config_request_pdu_t)); pthread_mutex_unlock(&ul_config->mutex_ul_config); } } From 03dda0a94271bc7e5a867cdbd8aa79ffebf933ae Mon Sep 17 00:00:00 2001 From: mjoang Date: Thu, 4 Nov 2021 19:35:07 -0400 Subject: [PATCH 17/34] fix a a bug to handle tx_req_body if the number is > 1 --- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 4e7191241c..2548de6dac 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -185,14 +185,13 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; - if (scheduled_response->tx_request && scheduled_response->tx_request->number_of_pdus) { + if (scheduled_response->tx_request) { for (int j=0; jtx_request->number_of_pdus; j++) { fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[j]; if (tx_req_body->pdu_index == i) { LOG_D(PHY,"%d.%d Copying %d bytes to harq_process_ul_ue->a (harq_pid %d)\n",scheduled_response->frame,slot,tx_req_body->pdu_length,current_harq_pid); memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length); harq_process_ul_ue->status = ACTIVE; - scheduled_response->tx_request->number_of_pdus--; break; } } @@ -233,7 +232,13 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ break; } } - memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t)); + if (scheduled_response->tx_request) + scheduled_response->tx_request->number_of_pdus = 0; + ul_config->sfn = 0; + ul_config->slot = 0; + ul_config->number_pdus = 0; + for (int i=0; i < FAPI_NR_UL_CONFIG_LIST_NUM; i++) + memset(&(ul_config->ul_config_list[i]), 0, sizeof(fapi_nr_ul_config_request_pdu_t)); pthread_mutex_unlock(&ul_config->mutex_ul_config); } } From 1b2d5b0c9627332984642cc89a8adeb0be9fa763 Mon Sep 17 00:00:00 2001 From: mjoang Date: Fri, 5 Nov 2021 09:38:28 -0400 Subject: [PATCH 18/34] minor change to clear ul_config_list array --- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 2548de6dac..f6e4d90bee 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -237,8 +237,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ul_config->sfn = 0; ul_config->slot = 0; ul_config->number_pdus = 0; - for (int i=0; i < FAPI_NR_UL_CONFIG_LIST_NUM; i++) - memset(&(ul_config->ul_config_list[i]), 0, sizeof(fapi_nr_ul_config_request_pdu_t)); + memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list)); pthread_mutex_unlock(&ul_config->mutex_ul_config); } } From b965cbbb0a0a7d50f11323b03364b15c0ad5db09 Mon Sep 17 00:00:00 2001 From: Mario Joa-Ng Date: Tue, 9 Nov 2021 13:24:26 -0500 Subject: [PATCH 19/34] Using rnti to assign different pucch resource to different UE. --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index c619f6181f..9ca28ebb44 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -72,6 +72,8 @@ #include "NR_RRCReestablishmentRequest.h" #include "NR_UE-CapabilityRequestFilterNR.h" #include "PHY/defs_nr_common.h" +#include "common/utils/nr/nr_common.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" #if defined(NR_Rel16) #include "NR_SCS-SpecificCarrier.h" #include "NR_TDD-UL-DL-ConfigCommon.h" @@ -1001,7 +1003,7 @@ void fill_initial_SpCellConfig(rnti_t rnti, NR_SpCellConfig_t *SpCellConfig, NR_ServingCellConfigCommon_t *scc, rrc_gNB_carrier_data_t *carrier) { - + int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); SpCellConfig->servCellIndex = NULL; SpCellConfig->reconfigurationWithSync = NULL; SpCellConfig->rlmInSyncOutOfSyncThreshold = NULL; @@ -1030,7 +1032,9 @@ void fill_initial_SpCellConfig(rnti_t rnti, // one symbol (13) NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); pucchres0->pucch_ResourceId=0; - pucchres0->startingPRB=0; + //pucchres0->startingPRB=0; + pucchres0->startingPRB=(8+rnti) % curr_bwp; + LOG_D(NR_RRC, "pucchres0->startPRB %ld rnti %d curr_bwp %d\n", pucchres0->startingPRB, rnti, curr_bwp); pucchres0->intraSlotFrequencyHopping=NULL; pucchres0->secondHopPRB=NULL; pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; @@ -1182,9 +1186,9 @@ void fill_initial_SpCellConfig(rnti_t rnti, AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30, "SCS != 30kHz\n"); AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5, - "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); - - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8 + 10*((rnti>>1)&3) + (rnti&1); + "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); + + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8; schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); *schedulingRequestResourceConfig->resource = 0; ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); From d0488b5d513add9ffd6b5acc4f59bc96d5fa78d5 Mon Sep 17 00:00:00 2001 From: mjoang Date: Wed, 10 Nov 2021 15:36:37 -0500 Subject: [PATCH 20/34] small change on adding mutex to protect ul_config_pdu against race condition. --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 9 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 157 ++++++++++--------- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 50710b325f..0f0a9a6a4b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -673,11 +673,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + pthread_mutex_unlock(&ul_config->mutex_ul_config); // Config PUSCH PDU ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - pthread_mutex_unlock(&ul_config->mutex_ul_config); - } break; @@ -735,11 +734,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + pthread_mutex_unlock(&ul_config->mutex_ul_config); // Config PUSCH PDU ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - pthread_mutex_unlock(&ul_config->mutex_ul_config); - } else AssertFatal(1==0,"Cannot schedule PUSCH\n"); break; } @@ -3930,11 +3928,10 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + pthread_mutex_unlock(&ul_config->mutex_ul_config); // Config Msg3 PDU nr_config_pusch_pdu(mac, pusch_config_pdu, NULL, &rar_grant, rnti, NULL); - pthread_mutex_unlock(&ul_config->mutex_ul_config); - } } else { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index f6d27c54cd..6536bf704a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -946,90 +946,90 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in // Schedule ULSCH only if the current frame and slot match those in ul_config_req // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) if (ul_config){ - pthread_mutex_lock(&ul_config->mutex_ul_config); - if ((ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){ - pthread_mutex_unlock(&ul_config->mutex_ul_config); - - LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); - - uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES]; - nr_scheduled_response_t scheduled_response; - fapi_nr_tx_request_t tx_req; - tx_req.slot = slot_tx; - tx_req.sfn = frame_tx; - tx_req.number_of_pdus = 0; - pthread_mutex_lock(&ul_config->mutex_ul_config); - for (int j = 0; j < ul_config->number_pdus; j++) { - uint8_t *ulsch_input_buffer = &(ulsch_input_buffer_array[tx_req.number_of_pdus][MAX_ULSCH_PAYLOAD_BYTES]); + if ((ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){ + pthread_mutex_unlock(&ul_config->mutex_ul_config); - fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j]; + LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); - if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { - int mac_pdu_exist = 0; - uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; - LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d (ra_state %d)\n", - ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, - mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id], - ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator, - TBS_bytes,ra->ra_state); - if (ra->ra_state == WAIT_RAR && !ra->cfra){ - memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes); - LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n"); - for (int k = 0; k < TBS_bytes; k++) { - LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); - } - LOG_D(NR_MAC,"Flipping NDI for harq_id %d (Msg3)\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); - mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; - mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; - mac_pdu_exist = 1; - } else { + uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES]; + nr_scheduled_response_t scheduled_response; + fapi_nr_tx_request_t tx_req; + tx_req.slot = slot_tx; + tx_req.sfn = frame_tx; + tx_req.number_of_pdus = 0; - if ((mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator || - mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1) && - ((get_softmodem_params()->phy_test == 1) || - (ra->ra_state == RA_SUCCEEDED) || - (ra->ra_state == WAIT_RAR && ra->cfra))){ + pthread_mutex_lock(&ul_config->mutex_ul_config); + for (int j = 0; j < ul_config->number_pdus; j++) { + uint8_t *ulsch_input_buffer = &(ulsch_input_buffer_array[tx_req.number_of_pdus][MAX_ULSCH_PAYLOAD_BYTES]); - // Getting IP traffic to be transmitted - nr_ue_get_sdu(mod_id, cc_id,frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); + fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j]; + + if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { + int mac_pdu_exist = 0; + uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; + LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d (ra_state %d)\n", + ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, + mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id], + ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator, + TBS_bytes,ra->ra_state); + if (ra->ra_state == WAIT_RAR && !ra->cfra){ + memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes); + LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n"); + for (int k = 0; k < TBS_bytes; k++) { + LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); + } + LOG_D(NR_MAC,"Flipping NDI for harq_id %d (Msg3)\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); + mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; + mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; mac_pdu_exist = 1; + } else { + + if ((mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator || + mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1) && + ((get_softmodem_params()->phy_test == 1) || + (ra->ra_state == RA_SUCCEEDED) || + (ra->ra_state == WAIT_RAR && ra->cfra))){ + + // Getting IP traffic to be transmitted + nr_ue_get_sdu(mod_id, cc_id,frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); + mac_pdu_exist = 1; + } + + LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); + mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; + mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; + } - LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); - mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; - mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; - - } - - // Config UL TX PDU - if (mac_pdu_exist) { - tx_req.tx_request_body[tx_req.number_of_pdus].pdu_length = TBS_bytes; - tx_req.tx_request_body[tx_req.number_of_pdus].pdu_index = j; - tx_req.tx_request_body[tx_req.number_of_pdus].pdu = ulsch_input_buffer; - tx_req.number_of_pdus++; - } - if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){ - LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); - // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission - nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); - } - if (ra->ra_state == WAIT_RAR && !ra->cfra){ - LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); - nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); + // Config UL TX PDU + if (mac_pdu_exist) { + tx_req.tx_request_body[tx_req.number_of_pdus].pdu_length = TBS_bytes; + tx_req.tx_request_body[tx_req.number_of_pdus].pdu_index = j; + tx_req.tx_request_body[tx_req.number_of_pdus].pdu = ulsch_input_buffer; + tx_req.number_of_pdus++; + } + if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){ + LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); + // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission + nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); + } + if (ra->ra_state == WAIT_RAR && !ra->cfra){ + LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); + nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); + } } } - } - pthread_mutex_unlock(&ul_config->mutex_ul_config); + pthread_mutex_unlock(&ul_config->mutex_ul_config); - fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - mac->if_module->scheduled_response(&scheduled_response); + fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ + mac->if_module->scheduled_response(&scheduled_response); + } + } + else { + pthread_mutex_unlock(&ul_config->mutex_ul_config); } - } - else { - pthread_mutex_unlock(&ul_config->mutex_ul_config); - } } } @@ -2161,6 +2161,10 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in pthread_mutex_lock(&ul_config->mutex_ul_config); AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu; + + fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); + pthread_mutex_unlock(&ul_config->mutex_ul_config); + nr_ue_configure_pucch(mac, slotP, rnti, @@ -2168,8 +2172,6 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in pucch_pdu, O_SR, O_ACK, O_CSI); LOG_D(NR_MAC,"Configuring pucch, is_common = %d\n",pucch->is_common); - fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); - pthread_mutex_unlock(&ul_config->mutex_ul_config); nr_scheduled_response_t scheduled_response; fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) @@ -2233,12 +2235,13 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s pthread_mutex_lock(&ul_config->mutex_ul_config); AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); - + pthread_mutex_unlock(&ul_config->mutex_ul_config); LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus); + memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); + ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); prach_config_pdu->phys_cell_id = mac->physCellId; @@ -2314,7 +2317,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s AssertFatal(1 == 0, "Invalid PRACH format"); } } // if format1 - pthread_mutex_unlock(&ul_config->mutex_ul_config); + fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); From eca68ea84a0a22153dc7de89ad38290e11f35fb9 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Mon, 15 Nov 2021 09:10:51 +0000 Subject: [PATCH 21/34] Change variable types in statistics to accommodate more bytes and to avoid negative values --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 2 +- openair2/LAYER2/NR_MAC_gNB/main.c | 16 +++++++------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 22 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index e226a2992d..77c3731ef9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -582,7 +582,7 @@ static void handle_dl_harq(module_id_t mod_id, harq->ndi ^= 1; NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; stats->dlsch_errors++; - LOG_D(NR_MAC, "retransmission error for UE %d (total %d)\n", UE_id, stats->dlsch_errors); + LOG_D(NR_MAC, "retransmission error for UE %d (total %lu)\n", UE_id, stats->dlsch_errors); } else { add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid); harq->round++; diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 0089263620..df63001bff 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -94,7 +94,7 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen) avg_rsrp, stats->num_rsrp_meas); - stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, pucch0_DTX %d, BLER %.5f MCS %d\n", + stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %lu/%lu/%lu/%lu, dlsch_errors %lu, pucch0_DTX %d, BLER %.5f MCS %d\n", UE_id, stats->dlsch_rounds[0], stats->dlsch_rounds[1], stats->dlsch_rounds[2], stats->dlsch_rounds[3], @@ -105,25 +105,25 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen) stats->num_rsrp_meas = 0; stats->cumul_rsrp = 0 ; - stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); - stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n", + stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %lu\n", UE_id, stats->dlsch_total_bytes); + stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %lu/%lu/%lu/%lu, ulsch_DTX %d, ulsch_errors %lu\n", UE_id, stats->ulsch_rounds[0], stats->ulsch_rounds[1], stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ulsch_DTX, stats->ulsch_errors); stroff+=sprintf(output+stroff, - "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", + "UE %d: ulsch_total_bytes_scheduled %lu, ulsch_total_bytes_received %lu\n", UE_id, stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); for (int lc_id = 0; lc_id < 63; lc_id++) { if (stats->lc_bytes_tx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %lu bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %lu bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); } if (stats->lc_bytes_rx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %lu bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %lu bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 81be37872b..41acc734ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -618,19 +618,19 @@ typedef struct { } NRUEcontext_t; typedef struct { - int lc_bytes_tx[64]; - int lc_bytes_rx[64]; - int dlsch_rounds[8]; - int dlsch_errors; - int dlsch_total_bytes; + uint64_t lc_bytes_tx[64]; + uint64_t lc_bytes_rx[64]; + uint64_t dlsch_rounds[8]; + uint64_t dlsch_errors; + uint64_t dlsch_total_bytes; int dlsch_current_bytes; - int ulsch_rounds[8]; - int ulsch_errors; - int ulsch_DTX; - int ulsch_total_bytes_scheduled; - int ulsch_total_bytes_rx; + uint64_t ulsch_rounds[8]; + uint64_t ulsch_errors; + uint32_t ulsch_DTX; + uint64_t ulsch_total_bytes_scheduled; + uint64_t ulsch_total_bytes_rx; int ulsch_current_bytes; - int pucch0_DTX; + uint32_t pucch0_DTX; int cumul_rsrp; uint8_t num_rsrp_meas; } NR_mac_stats_t; From c29da837bdd6691f7f48830c37feb947f55b7728 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 15 Nov 2021 15:36:14 +0100 Subject: [PATCH 22/34] fix(ci): fix typo in main pipeline Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-GitLab-Container | 17 ++++++----------- ci-scripts/cls_containerize.py | 2 ++ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index da85a8a282..654ad23230 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -246,17 +246,12 @@ pipeline { script { triggerSlaveJob ('RAN-DockerHub-Push', 'Push-to-Docker-Hub') } - post { - always { - script { - echo "Push to Docker-Hub OK" - } - } - failure { - script { - echo "Push to Docker-Hub KO" - currentBuild.result = 'FAILURE' - } + } + post { + failure { + script { + echo "Push to Docker-Hub KO" + currentBuild.result = 'FAILURE' } } } diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index dac2408062..26ce687c62 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -227,6 +227,8 @@ class Containerize(): if result is not None: forceSharedImageBuild = True sharedTag = 'ci-temp' + else: + forceSharedImageBuild = True # Let's remove any previous run artifacts if still there mySSH.command(self.cli + ' image prune --force', '\$', 30) From 4ab1c441729864a8860c0b05ba38ee7fa30d2938 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 15 Nov 2021 16:16:38 +0100 Subject: [PATCH 23/34] fix(ci): fix the iptables check Signed-off-by: Raphael Defosseux --- ci-scripts/cls_containerize.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 26ce687c62..a451c2b75d 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -923,7 +923,7 @@ class Containerize(): if result is None: mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10) # Check if iptables forwarding is accepted - mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10) + mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10) result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore()) if result is None: mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10) @@ -951,7 +951,7 @@ class Containerize(): if result is None: mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10) # Check if iptables forwarding is accepted - mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10) + mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10) result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore()) if result is None: mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10) @@ -979,7 +979,7 @@ class Containerize(): if result is None: mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10) # Check if iptables forwarding is accepted - mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10) + mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10) result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore()) if result is None: mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10) @@ -1002,7 +1002,7 @@ class Containerize(): if result is None: mySSH.command('echo ' + password + ' | sudo -S sysctl net.ipv4.conf.all.forwarding=1', '\$', 10) # Check if iptables forwarding is accepted - mySSH.command('echo ' + password + ' | sudo -S iptables -L', '\$', 10) + mySSH.command('echo ' + password + ' | sudo -S iptables -L FORWARD', '\$', 10) result = re.search('Chain FORWARD .*policy ACCEPT', mySSH.getBefore()) if result is None: mySSH.command('echo ' + password + ' | sudo -S iptables -P FORWARD ACCEPT', '\$', 10) From cfbfd90fca79b170c93ea5c1e69e57938b76690e Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Mon, 15 Nov 2021 17:08:43 +0000 Subject: [PATCH 24/34] Revert "Change variable types in statistics to accommodate more bytes and to avoid negative values" This reverts commit eca68ea84a0a22153dc7de89ad38290e11f35fb9. --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 2 +- openair2/LAYER2/NR_MAC_gNB/main.c | 16 +++++++------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 22 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 77c3731ef9..e226a2992d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -582,7 +582,7 @@ static void handle_dl_harq(module_id_t mod_id, harq->ndi ^= 1; NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; stats->dlsch_errors++; - LOG_D(NR_MAC, "retransmission error for UE %d (total %lu)\n", UE_id, stats->dlsch_errors); + LOG_D(NR_MAC, "retransmission error for UE %d (total %d)\n", UE_id, stats->dlsch_errors); } else { add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid); harq->round++; diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index df63001bff..0089263620 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -94,7 +94,7 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen) avg_rsrp, stats->num_rsrp_meas); - stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %lu/%lu/%lu/%lu, dlsch_errors %lu, pucch0_DTX %d, BLER %.5f MCS %d\n", + stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, pucch0_DTX %d, BLER %.5f MCS %d\n", UE_id, stats->dlsch_rounds[0], stats->dlsch_rounds[1], stats->dlsch_rounds[2], stats->dlsch_rounds[3], @@ -105,25 +105,25 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen) stats->num_rsrp_meas = 0; stats->cumul_rsrp = 0 ; - stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %lu\n", UE_id, stats->dlsch_total_bytes); - stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %lu/%lu/%lu/%lu, ulsch_DTX %d, ulsch_errors %lu\n", + stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); + stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n", UE_id, stats->ulsch_rounds[0], stats->ulsch_rounds[1], stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ulsch_DTX, stats->ulsch_errors); stroff+=sprintf(output+stroff, - "UE %d: ulsch_total_bytes_scheduled %lu, ulsch_total_bytes_received %lu\n", + "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", UE_id, stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); for (int lc_id = 0; lc_id < 63; lc_id++) { if (stats->lc_bytes_tx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %lu bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %lu bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); } if (stats->lc_bytes_rx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %lu bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %lu bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 41acc734ec..81be37872b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -618,19 +618,19 @@ typedef struct { } NRUEcontext_t; typedef struct { - uint64_t lc_bytes_tx[64]; - uint64_t lc_bytes_rx[64]; - uint64_t dlsch_rounds[8]; - uint64_t dlsch_errors; - uint64_t dlsch_total_bytes; + int lc_bytes_tx[64]; + int lc_bytes_rx[64]; + int dlsch_rounds[8]; + int dlsch_errors; + int dlsch_total_bytes; int dlsch_current_bytes; - uint64_t ulsch_rounds[8]; - uint64_t ulsch_errors; - uint32_t ulsch_DTX; - uint64_t ulsch_total_bytes_scheduled; - uint64_t ulsch_total_bytes_rx; + int ulsch_rounds[8]; + int ulsch_errors; + int ulsch_DTX; + int ulsch_total_bytes_scheduled; + int ulsch_total_bytes_rx; int ulsch_current_bytes; - uint32_t pucch0_DTX; + int pucch0_DTX; int cumul_rsrp; uint8_t num_rsrp_meas; } NR_mac_stats_t; From 43e224292cdd05b565081385b9a421edca848755 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Mon, 15 Nov 2021 16:36:34 +0000 Subject: [PATCH 25/34] Change variable types in statistics to accommodate more bytes and to avoid negative values --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 6 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 2 +- openair2/LAYER2/NR_MAC_gNB/main.c | 30 +++++++++---------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 24 +++++++-------- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 94641ec344..0e01702d77 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -420,9 +420,9 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t return old_mcs; // no update // last update is longer than x frames ago - const int dtx = stats->dlsch_rounds[0] - bler_stats->dlsch_rounds[0]; - const int dretx = stats->dlsch_rounds[1] - bler_stats->dlsch_rounds[1]; - const int dretx2 = stats->dlsch_rounds[2] - bler_stats->dlsch_rounds[2]; + const int dtx = (int)(stats->dlsch_rounds[0] - bler_stats->dlsch_rounds[0]); + const int dretx = (int)(stats->dlsch_rounds[1] - bler_stats->dlsch_rounds[1]); + const int dretx2 = (int)(stats->dlsch_rounds[2] - bler_stats->dlsch_rounds[2]); const float bler_window = dtx > 0 ? (float) dretx / dtx : bler_stats->bler; const float rd2_bler_wnd = dtx > 0 ? (float) dretx2 / dtx : bler_stats->rd2_bler; bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index e226a2992d..45dac6fd2f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -582,7 +582,7 @@ static void handle_dl_harq(module_id_t mod_id, harq->ndi ^= 1; NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; stats->dlsch_errors++; - LOG_D(NR_MAC, "retransmission error for UE %d (total %d)\n", UE_id, stats->dlsch_errors); + LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors); } else { add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid); harq->round++; diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 0089263620..84ee7dc1a3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -94,36 +94,36 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen) avg_rsrp, stats->num_rsrp_meas); - stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, pucch0_DTX %d, BLER %.5f MCS %d\n", - UE_id, - stats->dlsch_rounds[0], stats->dlsch_rounds[1], - stats->dlsch_rounds[2], stats->dlsch_rounds[3], - stats->dlsch_errors, - stats->pucch0_DTX, - sched_ctrl->dl_bler_stats.bler, - sched_ctrl->dl_bler_stats.mcs); + stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", + UE_id, + stats->dlsch_rounds[0], stats->dlsch_rounds[1], + stats->dlsch_rounds[2], stats->dlsch_rounds[3], + stats->dlsch_errors, + stats->pucch0_DTX, + sched_ctrl->dl_bler_stats.bler, + sched_ctrl->dl_bler_stats.mcs); stats->num_rsrp_meas = 0; stats->cumul_rsrp = 0 ; - stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); - stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n", + stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dlsch_total_bytes); + stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64"\n", UE_id, stats->ulsch_rounds[0], stats->ulsch_rounds[1], stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ulsch_DTX, stats->ulsch_errors); stroff+=sprintf(output+stroff, - "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", + "UE %d: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", UE_id, stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); for (int lc_id = 0; lc_id < 63; lc_id++) { if (stats->lc_bytes_tx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); } if (stats->lc_bytes_rx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 81be37872b..27f42f4b1d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -427,7 +427,7 @@ typedef struct NR_DL_bler_stats { float bler; float rd2_bler; uint8_t mcs; - int dlsch_rounds[8]; + uint64_t dlsch_rounds[8]; } NR_DL_bler_stats_t; // @@ -618,19 +618,19 @@ typedef struct { } NRUEcontext_t; typedef struct { - int lc_bytes_tx[64]; - int lc_bytes_rx[64]; - int dlsch_rounds[8]; - int dlsch_errors; - int dlsch_total_bytes; + uint64_t lc_bytes_tx[64]; + uint64_t lc_bytes_rx[64]; + uint64_t dlsch_rounds[8]; + uint64_t dlsch_errors; + uint64_t dlsch_total_bytes; int dlsch_current_bytes; - int ulsch_rounds[8]; - int ulsch_errors; - int ulsch_DTX; - int ulsch_total_bytes_scheduled; - int ulsch_total_bytes_rx; + uint64_t ulsch_rounds[8]; + uint64_t ulsch_errors; + uint32_t ulsch_DTX; + uint64_t ulsch_total_bytes_scheduled; + uint64_t ulsch_total_bytes_rx; int ulsch_current_bytes; - int pucch0_DTX; + uint32_t pucch0_DTX; int cumul_rsrp; uint8_t num_rsrp_meas; } NR_mac_stats_t; From 41e2b21d08504b80ba3b18647f091f3b53de297a Mon Sep 17 00:00:00 2001 From: mjoang Date: Mon, 15 Nov 2021 13:54:25 -0500 Subject: [PATCH 26/34] Change missing mutex init per review. --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 2 ++ openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 9 +++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index cef13b87fb..6702897c09 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -660,6 +660,8 @@ int nr_rrc_mac_config_req_ue( if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) num_slots_ul++; LOG_I(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul); mac->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t)); + for (int i=0; iul_config_request[i].mutex_ul_config), NULL); // Setup the SSB to Rach Occasions mapping according to the config build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); mac->if_module->phy_config_request(&mac->phy_config); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 6536bf704a..91ac5a7422 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -948,7 +948,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in if (ul_config){ pthread_mutex_lock(&ul_config->mutex_ul_config); if ((ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){ - pthread_mutex_unlock(&ul_config->mutex_ul_config); LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); @@ -959,7 +958,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in tx_req.sfn = frame_tx; tx_req.number_of_pdus = 0; - pthread_mutex_lock(&ul_config->mutex_ul_config); for (int j = 0; j < ul_config->number_pdus; j++) { uint8_t *ulsch_input_buffer = &(ulsch_input_buffer_array[tx_req.number_of_pdus][MAX_ULSCH_PAYLOAD_BYTES]); @@ -1020,16 +1018,15 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } } } - pthread_mutex_unlock(&ul_config->mutex_ul_config); + pthread_mutex_unlock(&ul_config->mutex_ul_config); // avoid double lock fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ mac->if_module->scheduled_response(&scheduled_response); } + pthread_mutex_lock(&ul_config->mutex_ul_config); } - else { - pthread_mutex_unlock(&ul_config->mutex_ul_config); - } + pthread_mutex_unlock(&ul_config->mutex_ul_config); } } From ce1bc7cefb45c809adaa7bd604dbc9ee01150c75 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 16 Nov 2021 15:03:01 +0100 Subject: [PATCH 27/34] fix(ci): implement proper automatic un-deploy of RAN containers Signed-off-by: Raphael Defosseux --- ci-scripts/cls_containerize.py | 2 + ci-scripts/cls_oaicitest.py | 108 ++++++++++-------- ci-scripts/main.py | 22 ++-- ci-scripts/ran.py | 20 +++- .../xml_files/container_nsa_b200_quectel.xml | 4 +- .../container_nsa_b200_terminate.xml | 51 +++++++++ 6 files changed, 141 insertions(+), 66 deletions(-) create mode 100644 ci-scripts/xml_files/container_nsa_b200_terminate.xml diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index a451c2b75d..72c509c33b 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -580,6 +580,8 @@ class Containerize(): # Currently support only one mySSH.command('docker-compose --file ci-docker-compose.yml config', '\$', 5) result = re.search('container_name: (?P[a-zA-Z0-9\-\_]+)', mySSH.getBefore()) + if self.eNB_logFile[self.eNB_instance] == '': + self.eNB_logFile[self.eNB_instance] = 'enb_' + HTML.testCase_id + '.log' if result is not None: containerName = result.group('container_name') mySSH.command('docker kill --signal INT ' + containerName, '\$', 30) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index ab7d249f7e..cc6e235ab3 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -368,7 +368,7 @@ class OaiCiTest(): except: os.kill(os.getppid(),signal.SIGUSR1) - def InitializeUE(self,HTML,RAN,EPC, COTS_UE, InfraUE,ue_trace): + def InitializeUE(self,HTML,RAN,EPC, COTS_UE, InfraUE,ue_trace,CONTAINERS): if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': HELP.GenericHelp(CONST.Version) @@ -424,12 +424,12 @@ class OaiCiTest(): Module_UE.CheckModuleMTU() else: #status==-1 failed to retrieve IP address HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return - def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE,InfraUE): + def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS): if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') @@ -653,7 +653,7 @@ class OaiCiTest(): HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced' HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') logging.error('\033[91mInitialize OAI UE Failed! \033[0m') - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) def checkDevTTYisUnlocked(self): SSH = sshconnection.SSHConnection() @@ -731,7 +731,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) self.checkDevTTYisUnlocked() - def AttachCatM(self,HTML,RAN,COTS_UE,EPC,InfraUE): + def AttachCatM(self,HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') @@ -804,9 +804,9 @@ class OaiCiTest(): html_cell = '
CAT-M module Attachment Failed
' html_queue.put(html_cell) HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) - def PingCatM(self,HTML,RAN,EPC,COTS_UE,InfraUE): + def PingCatM(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') @@ -815,7 +815,7 @@ class OaiCiTest(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) if (pStatus < 0): HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return try: statusQueue = SimpleQueue() @@ -836,7 +836,7 @@ class OaiCiTest(): moduleIPAddr = result.group('ipaddr') else: HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return ping_time = re.findall("-c (\d+)",str(self.ping_args)) device_id = 'catm' @@ -900,7 +900,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) else: HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) except: os.kill(os.getppid(),signal.SIGUSR1) @@ -992,7 +992,7 @@ class OaiCiTest(): except: os.kill(os.getppid(),signal.SIGUSR1) - def AttachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE): + def AttachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS): if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': HELP.GenericHelp(CONST.Version) @@ -1002,7 +1002,7 @@ class OaiCiTest(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) if (pStatus < 0): HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return multi_jobs = [] status_queue = SimpleQueue() @@ -1021,7 +1021,7 @@ class OaiCiTest(): if (status_queue.empty()): HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return else: attach_status = True @@ -1050,7 +1050,7 @@ class OaiCiTest(): time.sleep(5) else: HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) else: #if an ID is specified, it is a module from the yaml infrastructure file #Attention, as opposed to InitializeUE, the connect manager process is not checked as it is supposed to be active already @@ -1086,7 +1086,7 @@ class OaiCiTest(): Module_UE.CheckModuleMTU() else: #status==-1 failed to retrieve IP address HTML.CreateHtmlTestRow('N/A', 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return def DetachUE_common(self, device_id, idx,COTS_UE): @@ -1111,7 +1111,7 @@ class OaiCiTest(): except: os.kill(os.getppid(),signal.SIGUSR1) - def DetachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE): + def DetachUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS): if self.ue_id=='':#no ID specified, then it is a COTS controlled by ADB if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': HELP.GenericHelp(CONST.Version) @@ -1121,7 +1121,7 @@ class OaiCiTest(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) if (pStatus < 0): HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return multi_jobs = [] cnt = 0 @@ -1396,7 +1396,7 @@ class OaiCiTest(): except: os.kill(os.getppid(),signal.SIGUSR1) - def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE,InfraUE): + def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') @@ -1443,7 +1443,7 @@ class OaiCiTest(): if (status_queue.empty()): HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) else: check_status = True html_queue = SimpleQueue() @@ -1459,7 +1459,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) else: HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) def GetAllUEIPAddresses(self): SSH = sshconnection.SSHConnection() @@ -1686,14 +1686,14 @@ class OaiCiTest(): html_queue.put(html_cell) HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - def PingNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE): + def PingNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS): SSH=sshconnection.SSHConnection() check_eNB = True check_OAI_UE = True pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) if (pStatus < 0): HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) if ping_from_eNB is not None: @@ -1779,10 +1779,10 @@ class OaiCiTest(): except: os.kill(os.getppid(),signal.SIGUSR1) - def Ping(self,HTML,RAN,EPC,COTS_UE, InfraUE): + def Ping(self,HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS): result = re.search('noS1', str(RAN.Initialize_eNB_args)) if result is not None: - self.PingNoS1(HTML,RAN,EPC,COTS_UE,InfraUE) + self.PingNoS1(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS) return if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) @@ -1795,7 +1795,7 @@ class OaiCiTest(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) if (pStatus < 0): HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return if self.ue_id=="": @@ -1803,7 +1803,7 @@ class OaiCiTest(): ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return else: self.UEIPAddresses=[] @@ -1830,7 +1830,7 @@ class OaiCiTest(): if (status_queue.empty()): HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) else: ping_status = True html_queue = SimpleQueue() @@ -1847,7 +1847,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) else: HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) def Iperf_ComputeTime(self): result = re.search('-t (?P\d+)', str(self.iperf_args)) @@ -2647,7 +2647,7 @@ class OaiCiTest(): except: os.kill(os.getppid(),signal.SIGUSR1) - def IperfNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE): + def IperfNoS1(self,HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS): SSH = sshconnection.SSHConnection() if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': HELP.GenericHelp(CONST.Version) @@ -2657,7 +2657,7 @@ class OaiCiTest(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) if (pStatus < 0): HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return server_on_enb = re.search('-R', str(self.iperf_args)) if server_on_enb is not None: @@ -2756,12 +2756,12 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) else: HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) - def Iperf(self,HTML,RAN,EPC,COTS_UE, InfraUE): + def Iperf(self,HTML,RAN,EPC,COTS_UE, InfraUE,CONTAINERS): result = re.search('noS1', str(RAN.Initialize_eNB_args)) if result is not None: - self.IperfNoS1(HTML,RAN,EPC,COTS_UE,InfraUE) + self.IperfNoS1(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS) return if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': HELP.GenericHelp(CONST.Version) @@ -2774,14 +2774,14 @@ class OaiCiTest(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) if (pStatus < 0): HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return if self.ue_id=="":#is not a module, follow legacy code ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) return else: #is a module self.UEIPAddresses=[] @@ -2826,7 +2826,7 @@ class OaiCiTest(): if (status_queue.empty()): HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) else: iperf_status = True iperf_noperf = False @@ -2848,7 +2848,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) else: HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) def CheckProcessExist(self, check_eNB, check_OAI_UE,RAN,EPC): multi_jobs = [] @@ -3280,7 +3280,7 @@ class OaiCiTest(): else: HTML.CreateHtmlTestRow('QLog trace is disabled', 'OK', CONST.ALL_PROCESSES_OK) - def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC, InfraUE): + def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS): SSH = sshconnection.SSHConnection() SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) @@ -3321,11 +3321,11 @@ class OaiCiTest(): # Not an error then if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) else: if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC): self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) else: logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') HTML.htmlUEFailureMsg='' + ueAction + ' Completed\n' + HTML.htmlUEFailureMsg @@ -3334,26 +3334,26 @@ class OaiCiTest(): else: HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC,InfraUE): + def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS): if (self.ADBIPAddress != 'none'): self.testCase_id = 'AUTO-KILL-UE' - HTML.testCase_id=self.testCase_id + HTML.testCase_id = self.testCase_id self.desc = 'Automatic Termination of UE' - HTML.desc='Automatic Termination of UE' + HTML.desc = self.desc self.ShowTestID() self.TerminateUE(HTML,COTS_UE,InfraUE,self.ue_trace) if (self.Initialize_OAI_UE_args != ''): self.testCase_id = 'AUTO-KILL-OAI-UE' - HTML.testCase_id=self.testCase_id + HTML.testCase_id = self.testCase_id self.desc = 'Automatic Termination of OAI-UE' - HTML.desc='Automatic Termination of OAI-UE' + HTML.desc = self.desc self.ShowTestID() self.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE) if (RAN.Initialize_eNB_args != ''): self.testCase_id = 'AUTO-KILL-RAN' - HTML.testCase_id=self.testCase_id + HTML.testCase_id = self.testCase_id self.desc = 'Automatic Termination of all RAN nodes' - HTML.desc='Automatic Termination of RAN nodes' + HTML.desc = self.desc self.ShowTestID() #terminate all RAN nodes eNB/gNB/OCP for instance in range(0, len(RAN.air_interface)): @@ -3363,11 +3363,21 @@ class OaiCiTest(): RAN.TerminateeNB(HTML,EPC) if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: self.testCase_id = 'AUTO-KILL-flexran-ctl' - HTML.testCase_id=self.testCase_id + HTML.testCase_id = self.testCase_id self.desc = 'Automatic Termination of FlexRan CTL' - HTML.desc='Automatic Termination of FlexRan CTL' + HTML.desc = self.desc self.ShowTestID() self.TerminateFlexranCtrl(HTML,RAN,EPC) + if CONTAINERS.yamlPath[0] != '': + self.testCase_id = 'AUTO-KILL-CONTAINERS' + HTML.testCase_id = self.testCase_id + self.desc = 'Automatic Termination of all RAN containers' + HTML.desc = self.desc + self.ShowTestID() + for instance in range(0, len(CONTAINERS.yamlPath)): + if CONTAINERS.yamlPath[instance]!='': + CONTAINERS.eNB_instance=instance + CONTAINERS.UndeployObject(HTML,RAN) RAN.prematureExit=True def IdleSleep(self,HTML): diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 409647e216..e9acdc9152 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -544,7 +544,7 @@ elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') signal.signal(signal.SIGUSR1, receive_signal) - CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE) + CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) elif re.match('^TerminateHSS$', mode, re.IGNORECASE): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) @@ -809,39 +809,39 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re elif action == 'Terminate_eNB': RAN.TerminateeNB(HTML, EPC) elif action == 'Initialize_UE': - CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE, CiTestObj.ue_trace) + CiTestObj.InitializeUE(HTML,RAN, EPC, COTS_UE, InfraUE, CiTestObj.ue_trace, CONTAINERS) elif action == 'Terminate_UE': CiTestObj.TerminateUE(HTML,COTS_UE, InfraUE, CiTestObj.ue_trace) elif action == 'Attach_UE': - CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE,InfraUE) + CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS) elif action == 'Detach_UE': - CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE,InfraUE) + CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS) elif action == 'DataDisable_UE': CiTestObj.DataDisableUE(HTML) elif action == 'DataEnable_UE': CiTestObj.DataEnableUE(HTML) elif action == 'CheckStatusUE': - CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE,InfraUE) + CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS) elif action == 'Build_OAI_UE': CiTestObj.BuildOAIUE(HTML) elif action == 'Initialize_OAI_UE': - CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE,InfraUE) + CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE,InfraUE,CONTAINERS) elif action == 'Terminate_OAI_UE': - CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE) + CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) elif action == 'Initialize_CatM_module': CiTestObj.InitializeCatM(HTML) elif action == 'Terminate_CatM_module': CiTestObj.TerminateCatM(HTML) elif action == 'Attach_CatM_module': - CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC,InfraUE) + CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC,InfraUE,CONTAINERS) elif action == 'Detach_CatM_module': CiTestObj.TerminateCatM(HTML) elif action == 'Ping_CatM_module': - CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC,InfraUE) + CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC,InfraUE,CONTAINERS) elif action == 'Ping': - CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE) + CiTestObj.Ping(HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS) elif action == 'Iperf': - CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE) + CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE, InfraUE, CONTAINERS) elif action == 'Reboot_UE': CiTestObj.RebootUE(HTML,RAN,EPC) elif action == 'Initialize_HSS': diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 74f13d031b..3c8e6fee40 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -800,10 +800,21 @@ class RANManagement(): x2ap_pdu = 0 #NSA specific log markers nsa_markers ={'SgNBReleaseRequestAcknowledge': [],'FAILURE': [], 'scgFailureInformationNR-r15': [], 'SgNBReleaseRequest': []} + nodeB_prefix_found = False line_cnt=0 #log file line counter for line in enb_log_file.readlines(): line_cnt+=1 + # Detection of eNB/gNB from a container log + result = re.search('Starting eNB soft modem', str(line)) + if result is not None: + nodeB_prefix_found = True + nodeB_prefix = 'e' + result = re.search('Starting gNB soft modem', str(line)) + if result is not None: + nodeB_prefix_found = True + nodeB_prefix = 'g' + result = re.search('Run time:' ,str(line)) # Runtime statistics result = re.search('Run time:' ,str(line)) if result is not None: @@ -1037,10 +1048,11 @@ class RANManagement(): logging.debug(' File analysis (stdout, stats) completed') #post processing depending on the node type - if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): - nodeB_prefix = 'e' - else: - nodeB_prefix = 'g' + if not nodeB_prefix_found: + if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): + nodeB_prefix = 'e' + else: + nodeB_prefix = 'g' if nodeB_prefix == 'g': if ulschReceiveOK > 0: diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml index 76610c2656..cc8312d7a3 100644 --- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml @@ -115,8 +115,8 @@ Iperf - iperf (DL/20Mbps/UDP)(60 sec)(single-ue profile) - -u -b 20M -t 60 + iperf (DL/40Mbps/UDP)(60 sec)(single-ue profile) + -u -b 40M -t 60 DL idefix 3 diff --git a/ci-scripts/xml_files/container_nsa_b200_terminate.xml b/ci-scripts/xml_files/container_nsa_b200_terminate.xml new file mode 100644 index 0000000000..4b446988cd --- /dev/null +++ b/ci-scripts/xml_files/container_nsa_b200_terminate.xml @@ -0,0 +1,51 @@ + + + TEST-NSA-FR1-TM1-B200-terminate + NSA tear-down in case of problem + tasks + 1 + + 030202 + 030201 + + + + + Undeploy_Object + Undeploy eNB + ci-scripts/yaml_files/nsa_b200_enb + 0 + 0 + + + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/nsa_b200_gnb + 1 + 1 + + + + From b16d5a6f10ab8473fb60d9335e1b891e6b2a8d69 Mon Sep 17 00:00:00 2001 From: hardy Date: Tue, 16 Nov 2021 15:57:54 +0100 Subject: [PATCH 28/34] update test description in test dashboard --- ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml b/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml index 011925491d..d9339bc14a 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml +++ b/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml @@ -7,15 +7,15 @@ NSA-B200 : job : 'RAN-NSA-B200-Module-LTEBOX' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-B200-Module-LTEBOX' bench : 'Nepes-B200-Obelix-B200-LTEBOX-Quectel(idefix)' - test : 'TM1, 20MHz, 20Mb DL, 3Mb UL' + test : 'TM1, 20MHz, 60Mb DL, 3Mb UL' NSA-2x2 : job : 'RAN-NSA-2x2-Module-OAIEPC' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-2x2-Module-OAIEPC' bench : 'Asterix-N310-Obelix-N310-OAIEPC-Quectel(nrmodule2)' - test : 'TM2, TDD, 40MHz, MCS9, 20Mb DL, 3Mb UL' + test : 'TM2, TDD, 40MHz, 60Mb DL, 3Mb UL' SA-N310 : job : 'RAN-SA-Module-CN5G' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G' bench : 'Asterix-N310-OAICN5G-Quectel(nrmodule2)' - test : 'TM2, TDD, 40MHz, 20Mb DL, 3Mb UL' + test : 'TM2, TDD, 40MHz, 60Mb DL, 3Mb UL' From 1ee7b96d64f2e8ea4859352d61faea12011fe68a Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 17 Nov 2021 09:49:53 +0100 Subject: [PATCH 29/34] fix(ci): 4g/5g RF simulation tests may fail due to lost socket on ue container. Repeat in case of failure Signed-off-by: Raphael Defosseux --- ci-scripts/cls_containerize.py | 11 +++++++---- ci-scripts/xml_files/container_4g_rfsim.xml | 1 + ci-scripts/xml_files/container_5g_rfsim.xml | 1 + docker/scripts/enb_entrypoint.sh | 18 +++++++++--------- docker/scripts/gnb_entrypoint.sh | 4 ++-- docker/scripts/lte_ru_entrypoint.sh | 4 ++-- docker/scripts/lte_ue_entrypoint.sh | 2 +- docker/scripts/nr_ue_entrypoint.sh | 2 +- 8 files changed, 24 insertions(+), 19 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 72c509c33b..8ee6113628 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -722,7 +722,7 @@ class Containerize(): cmd = 'mkdir -p ../cmake_targets/log' deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) - cmd = 'docker exec ' + self.pingContName + ' /bin/bash -c "ping ' + self.pingOptions + '" 2>&1 | tee ../cmake_targets/log/ping_' + HTML.testCase_id + '.log' + cmd = 'docker exec ' + self.pingContName + ' /bin/bash -c "ping ' + self.pingOptions + '" 2>&1 | tee ../cmake_targets/log/ping_' + HTML.testCase_id + '.log || true' logging.debug(cmd) deployStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100) @@ -788,18 +788,18 @@ class Containerize(): logStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) # Start the server process - cmd = 'docker exec -d ' + self.svrContName + ' /bin/bash -c "nohup iperf ' + self.svrOptions + ' > /tmp/iperf_server.log 2>&1"' + cmd = 'docker exec -d ' + self.svrContName + ' /bin/bash -c "nohup iperf ' + self.svrOptions + ' > /tmp/iperf_server.log 2>&1" || true' logging.debug(cmd) serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) time.sleep(5) # Start the client process - cmd = 'docker exec ' + self.cliContName + ' /bin/bash -c "iperf ' + self.cliOptions + '" 2>&1 | tee ../cmake_targets/log/iperf_client_' + HTML.testCase_id + '.log' + cmd = 'docker exec ' + self.cliContName + ' /bin/bash -c "iperf ' + self.cliOptions + '" 2>&1 | tee ../cmake_targets/log/iperf_client_' + HTML.testCase_id + '.log || true' logging.debug(cmd) clientStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=100) # Stop the server process - cmd = 'docker exec ' + self.svrContName + ' /bin/bash -c "pkill iperf"' + cmd = 'docker exec ' + self.svrContName + ' /bin/bash -c "pkill iperf" || true' logging.debug(cmd) serverStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=10) time.sleep(5) @@ -816,6 +816,7 @@ class Containerize(): else: message = 'Server Report and Connection refused Not Found!' self.IperfExit(HTML, False, message) + logging.error('\u001B[1;37;41m Iperf Test FAIL\u001B[0m') return # Computing the requested bandwidth in float @@ -888,6 +889,8 @@ class Containerize(): self.IperfExit(HTML, iperfStatus, 'problem?') if iperfStatus: logging.info('\u001B[1m Iperf Test PASS\u001B[0m') + else: + logging.error('\u001B[1;37;41m Iperf Test FAIL\u001B[0m') def IperfExit(self, HTML, status, message): html_queue = SimpleQueue() diff --git a/ci-scripts/xml_files/container_4g_rfsim.xml b/ci-scripts/xml_files/container_4g_rfsim.xml index 5430b2b056..7f13d599b8 100644 --- a/ci-scripts/xml_files/container_4g_rfsim.xml +++ b/ci-scripts/xml_files/container_4g_rfsim.xml @@ -24,6 +24,7 @@ rfsim-4glte Testing 4G LTE RF sim in containers wrench + 2 100011 000011 diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index 660cd7cde8..11f85688ec 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -24,6 +24,7 @@ rfsim-5gnr Testing 5G NR RF sim in containers wrench + 4 100001 000001 diff --git a/docker/scripts/enb_entrypoint.sh b/docker/scripts/enb_entrypoint.sh index ff92e3c86f..c71a2cf12f 100755 --- a/docker/scripts/enb_entrypoint.sh +++ b/docker/scripts/enb_entrypoint.sh @@ -9,15 +9,15 @@ ENABLE_X2=${ENABLE_X2:-no} THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD} # Based another env var, pick one template to use -if [[ -v USE_FDD_CU ]]; then ln -s $PREFIX/etc/cu.fdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_FDD_DU ]]; then ln -s $PREFIX/etc/du.fdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_FDD_MONO ]]; then ln -s $PREFIX/etc/enb.fdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_TDD_MONO ]]; then ln -s $PREFIX/etc/enb.tdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_FDD_FAPI_RCC ]]; then ln -s $PREFIX/etc/rcc.nfapi.fdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_FDD_IF4P5_RCC ]]; then ln -s $PREFIX/etc/rcc.if4p5.fdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_TDD_IF4P5_RCC ]]; then ln -s $PREFIX/etc/rcc.if4p5.tdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_FDD_RRU ]]; then ln -s $PREFIX/etc/rru.fdd.conf $PREFIX/etc/enb.conf; fi -if [[ -v USE_TDD_RRU ]]; then ln -s $PREFIX/etc/rru.tdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_FDD_CU ]]; then cp $PREFIX/etc/cu.fdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_FDD_DU ]]; then cp $PREFIX/etc/du.fdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_FDD_MONO ]]; then cp $PREFIX/etc/enb.fdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_TDD_MONO ]]; then cp $PREFIX/etc/enb.tdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_FDD_FAPI_RCC ]]; then cp $PREFIX/etc/rcc.nfapi.fdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_FDD_IF4P5_RCC ]]; then cp $PREFIX/etc/rcc.if4p5.fdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_TDD_IF4P5_RCC ]]; then cp $PREFIX/etc/rcc.if4p5.tdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_FDD_RRU ]]; then cp $PREFIX/etc/rru.fdd.conf $PREFIX/etc/enb.conf; fi +if [[ -v USE_TDD_RRU ]]; then cp $PREFIX/etc/rru.tdd.conf $PREFIX/etc/enb.conf; fi # Only this template will be manipulated CONFIG_FILES=`ls $PREFIX/etc/enb.conf || true` diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh index 05b42d76bb..d2bdc636c9 100755 --- a/docker/scripts/gnb_entrypoint.sh +++ b/docker/scripts/gnb_entrypoint.sh @@ -7,8 +7,8 @@ ENABLE_X2=${ENABLE_X2:-yes} THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD} # Based another env var, pick one template to use -if [[ -v USE_NSA_TDD_MONO ]]; then ln -s $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi -if [[ -v USE_SA_TDD_MONO ]]; then ln -s $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi +if [[ -v USE_NSA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi +if [[ -v USE_SA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi # Only this template will be manipulated CONFIG_FILES=`ls $PREFIX/etc/gnb.conf || true` diff --git a/docker/scripts/lte_ru_entrypoint.sh b/docker/scripts/lte_ru_entrypoint.sh index 93122b0d02..297e437ac0 100755 --- a/docker/scripts/lte_ru_entrypoint.sh +++ b/docker/scripts/lte_ru_entrypoint.sh @@ -5,8 +5,8 @@ set -euo pipefail PREFIX=/opt/oai-lte-ru # Based another env var, pick one template to use -if [[ -v USE_FDD_RRU ]]; then ln -s $PREFIX/etc/rru.fdd.conf $PREFIX/etc/rru.conf; fi -if [[ -v USE_TDD_RRU ]]; then ln -s $PREFIX/etc/rru.tdd.conf $PREFIX/etc/rru.conf; fi +if [[ -v USE_FDD_RRU ]]; then cp $PREFIX/etc/rru.fdd.conf $PREFIX/etc/rru.conf; fi +if [[ -v USE_TDD_RRU ]]; then cp $PREFIX/etc/rru.tdd.conf $PREFIX/etc/rru.conf; fi # Only this template will be manipulated CONFIG_FILES=`ls $PREFIX/etc/rru.conf || true` diff --git a/docker/scripts/lte_ue_entrypoint.sh b/docker/scripts/lte_ue_entrypoint.sh index de7ae8b496..82e96dd07f 100755 --- a/docker/scripts/lte_ue_entrypoint.sh +++ b/docker/scripts/lte_ue_entrypoint.sh @@ -5,7 +5,7 @@ set -euo pipefail PREFIX=/opt/oai-lte-ue # Based another env var, pick one template to use -if [[ -v USE_NFAPI ]]; then ln -s $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi +if [[ -v USE_NFAPI ]]; then cp $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi # Only this template will be manipulated and the USIM one! CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/ue_usim.conf || true` diff --git a/docker/scripts/nr_ue_entrypoint.sh b/docker/scripts/nr_ue_entrypoint.sh index 91d25c9e1e..af2b8a8333 100755 --- a/docker/scripts/nr_ue_entrypoint.sh +++ b/docker/scripts/nr_ue_entrypoint.sh @@ -5,7 +5,7 @@ set -euo pipefail PREFIX=/opt/oai-nr-ue # Based another env var, pick one template to use -#if [[ -v USE_NFAPI ]]; then ln -s $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi +#if [[ -v USE_NFAPI ]]; then cp $PREFIX/etc/ue.nfapi.conf $PREFIX/etc/ue.conf; fi # Only this template will be manipulated and the USIM one! CONFIG_FILES=`ls $PREFIX/etc/ue.conf $PREFIX/etc/nr-ue-sim.conf || true` From 49d14273797e3a21040642e9ee89dabab929aadb Mon Sep 17 00:00:00 2001 From: hardy Date: Tue, 16 Nov 2021 15:33:26 +0100 Subject: [PATCH 30/34] nsa conf files, ulsch_max_frame_inactivity = 1; --- ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf | 1 + ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf index a4452b202d..c8dc1477b0 100644 --- a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf @@ -226,6 +226,7 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; + ulsch_max_frame_inactivity = 1; } ); diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 7bda7f7eb5..a72147ee99 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -226,6 +226,7 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; + ulsch_max_frame_inactivity = 1; } ); From e43f00796519adedd3236554f64cdb421c731e60 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 18 Nov 2021 15:32:03 +0100 Subject: [PATCH 31/34] add SA DL stages test + fix dashboard descr --- .../ran_dashboard/ran_dashboard_cfg.yaml | 8 +- ci-scripts/xml_files/fr1_sa_quectel.xml | 2 +- .../xml_files/fr1_sa_quectel_stages.xml | 156 ++++++++++++++++++ 3 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 ci-scripts/xml_files/fr1_sa_quectel_stages.xml diff --git a/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml b/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml index d9339bc14a..071b9e2e67 100644 --- a/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml +++ b/ci-scripts/ran_dashboard/ran_dashboard_cfg.yaml @@ -2,20 +2,20 @@ LTE-2x2 : #short name used in the dashboard job : 'RAN-LTE-2x2-Module-OAIEPC' #job name from Jenkins, used in the database link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-2x2-Module-OAIEPC' bench : 'Obelix-N310-OAIEPC-Quectel(nrmodule2)' - test : 'TM2, TDD, 40MHz, MCS9, 26Mb DL, 7Mb UL' + test : 'TDD, 40MHz, MCS9, 26Mb DL, 7Mb UL' NSA-B200 : job : 'RAN-NSA-B200-Module-LTEBOX' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-B200-Module-LTEBOX' bench : 'Nepes-B200-Obelix-B200-LTEBOX-Quectel(idefix)' - test : 'TM1, 20MHz, 60Mb DL, 3Mb UL' + test : '20MHz, 60Mb DL, 3Mb UL' NSA-2x2 : job : 'RAN-NSA-2x2-Module-OAIEPC' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-NSA-2x2-Module-OAIEPC' bench : 'Asterix-N310-Obelix-N310-OAIEPC-Quectel(nrmodule2)' - test : 'TM2, TDD, 40MHz, 60Mb DL, 3Mb UL' + test : 'TDD, 40MHz, 60Mb DL, 3Mb UL' SA-N310 : job : 'RAN-SA-Module-CN5G' link : 'https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G' bench : 'Asterix-N310-OAICN5G-Quectel(nrmodule2)' - test : 'TM2, TDD, 40MHz, 60Mb DL, 3Mb UL' + test : 'TDD, 40MHz, 60Mb DL, 3Mb UL' diff --git a/ci-scripts/xml_files/fr1_sa_quectel.xml b/ci-scripts/xml_files/fr1_sa_quectel.xml index f4473710cf..ff877287aa 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel.xml @@ -21,7 +21,7 @@ --> - TEST-SA-FR1-TM1 + TEST-SA-FR1-Tab1 SA Ping DL UL with QUECTEL tasks 1 diff --git a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml new file mode 100644 index 0000000000..b2236dd527 --- /dev/null +++ b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml @@ -0,0 +1,156 @@ + + + TEST-SA-FR1-Tab2 + SA Staged DL with QUECTEL + tasks + 1 + + 040000 + 000002 + 010000 + 000001 + 050000 + 000001 + 070000 + 000001 + 070001 + 000001 + 070002 + 000001 + 070003 + 000001 + 070004 + 000001 + 010002 + 080000 + + + + + Initialize_UE + Initialize Quectel + nrmodule2_quectel + yes + + + + + Terminate_UE + Terminate Quectel + nrmodule2_quectel + + + + + Initialize_eNB + Initialize gNB + -O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf --sa -q --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 + 0 + 0 + nr + yes + yes + 192.168.18.240 + + + + IdleSleep + Sleep + 5 + + + + IdleSleep + Sleep + 20 + + + + + Ping + Ping: 20pings in 20sec + nrmodule2_quectel + -c 20 + 5 + + + + + Iperf + iperf (DL/10Mbps/UDP)(30 sec)(single-ue profile) + -u -b 10M -t 30 + DL + nrmodule2_quectel + 5 + single-ue + + + Iperf + iperf (DL/20Mbps/UDP)(30 sec)(single-ue profile) + -u -b 20M -t 30 + DL + nrmodule2_quectel + 5 + single-ue + + + Iperf + iperf (DL/40Mbps/UDP)(30 sec)(single-ue profile) + -u -b 40M -t 30 + DL + nrmodule2_quectel + 5 + single-ue + + + Iperf + iperf (DL/60Mbps/UDP)(30 sec)(single-ue profile) + -u -b 60M -t 30 + DL + nrmodule2_quectel + 5 + single-ue + + + Iperf + iperf (DL/90Mbps/UDP)(30 sec)(single-ue profile) + -u -b 90M -t 30 + DL + nrmodule2_quectel + 5 + single-ue + + + + + + Terminate_eNB + Terminate gNB + 0 + 0 + nr + + + + From 1f42e2b2d9da97a097463d90b40473f2a5890484 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 18 Nov 2021 10:46:39 +0100 Subject: [PATCH 32/34] fix(ci): proper log collection on eNB/gNB runs Signed-off-by: Raphael Defosseux --- ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf | 2 +- ci-scripts/ran.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf index 454649f20d..64bcb4b35f 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf @@ -245,7 +245,7 @@ THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 3c8e6fee40..27fc272687 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -738,8 +738,8 @@ class RANManagement(): mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20) mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20) mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) - mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png', '\$', 60) - mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png', '\$', 5) + mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png log/*/*.log log/*/*.pcap', '\$', 60) + mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png log/*/*.log log/*/*.pcap', '\$', 15) mySSH.close() def AnalyzeLogFile_eNB(self, eNBlogFile, HTML): From f61e93fde0b67a7568a16c1341293d3080cf31fe Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 18 Nov 2021 14:15:29 +0100 Subject: [PATCH 33/34] fix(ci): same as previous commit Signed-off-by: Raphael Defosseux --- ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml b/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml index 60e82de50a..9bd08aeabc 100644 --- a/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml +++ b/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml @@ -30,7 +30,7 @@ services: FLEXRAN_ENABLED: 'no' FLEXRAN_INTERFACE_NAME: eth0 FLEXRAN_IPV4_ADDRESS: 192.168.18.210 - THREAD_PARALLEL_CONFIG: PARALLEL_RU_L1_TRX_SPLIT + THREAD_PARALLEL_CONFIG: PARALLEL_SINGLE_THREAD volumes: - /dev:/dev networks: From d377c63dd1c3997e1d089e4f0f28ed259cb78089 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 22 Nov 2021 16:33:33 +0100 Subject: [PATCH 34/34] fix(gNB): lower verbosity level when could not find pdsch_to_harq_feedback Signed-off-by: Raphael Defosseux --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 45dac6fd2f..d3521f9b17 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1334,7 +1334,7 @@ int nr_acknack_scheduling(int mod_id, pucch->ul_slot = (s + 1) % n_slots_frame; } if (ind_found==-1) { - LOG_W(NR_MAC, + LOG_D(NR_MAC, "%4d.%2d could not find pdsch_to_harq_feedback for UE %d: earliest " "ack slot %d\n", frame,