diff --git a/ci-scripts/checkTutorial.py b/ci-scripts/checkTutorial.py new file mode 100644 index 0000000000000000000000000000000000000000..c3bf24c4603f24b5307f6e1e1c2d4a540295df95 --- /dev/null +++ b/ci-scripts/checkTutorial.py @@ -0,0 +1,126 @@ +""" +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 + +------------------------------------------------------------------------------ +""" + +from subprocess import PIPE,STDOUT +import time +import subprocess +import logging +import argparse +import re +import sys + +logging.basicConfig( + level=logging.DEBUG, + format="%(message)s" +) + +## Global variables +DOCUMENT_FOLDER = '../docs' +SLEEP_BETWEEN_COMMANDS = 2 +SLEEP_BETWEEN_HEADERS = 5 +DOCKER_COMPOSE_DIRECTORY='../docker-compose' + + +def _parse_args() -> argparse.Namespace: + """Parse the command line args + + Returns: + argparse.Namespace: the created parser + """ + example_text = '''example: + python3 checkTutorial.py --tutorial DEPLOY_SA5G_BASIC_STATIC_UE_IP.md''' + + parser = argparse.ArgumentParser(description='Run the tutorials to see they are executing fine', + epilog=example_text, + formatter_class=argparse.RawDescriptionHelpFormatter) + + # Tutorial Name + parser.add_argument( + '--tutorial', '-t', + action='store', + required=True, + help='name of the tutorial markdown file', + ) + return parser.parse_args() + + +def subprocess_call(command,cwd): + popen = subprocess.Popen(command,shell=True,universal_newlines=True,cwd=cwd,stdout=PIPE) + for stdout_line in iter(popen.stdout.readline, ""): + yield stdout_line + popen.stdout.close() + return_code = popen.wait() + if return_code: + raise subprocess.CalledProcessError(return_code, command) + + +def extract_h2_blocks(headers,text): + text = text.split('\n') + positions = [] + header_blocks = dict() + temp_header_blocks = dict() + for header in headers: + header_blocks.update({header:[]}) + for position,line in enumerate(text): + if header in line: + temp_header_blocks[position]=header + positions.append(position) + for key,value in enumerate(positions): + if key < len(positions)-1: + for n in range(positions[key],positions[key+1]): + header_blocks[temp_header_blocks[value]].append(text[n]) + else: + for n in range(positions[key],len(text)-key): + header_blocks[temp_header_blocks[value]].append(text[n]) + + return header_blocks + +def execute_shell_command(h2_blocks): + for value in h2_blocks: + logging.info('\033[0;32m {}\033[0m'.format(value)) + shell_blocks = re.findall(r"`{3} shell\n([\S\s]+?)`{3}",'\n'.join(h2_blocks[value])) + for block in shell_blocks: + commands = re.findall(r"docker-compose-host \$: (.*)",block) + for command in commands: + logging.info('\033[0;31m Executing command "{}"\033[0m'.format(command)) + for output in subprocess_call(command=command, cwd=DOCKER_COMPOSE_DIRECTORY): + print(output) + time.sleep(SLEEP_BETWEEN_COMMANDS) + time.sleep(SLEEP_BETWEEN_HEADERS) + return 0 + +def check_tutorial(name): + filename = DOCUMENT_FOLDER + '/' + name + with open(filename, 'r') as f: + text = f.read() + h2 = re.findall(r"## (.*)\n",text) + h2_blocks = extract_h2_blocks(h2,text) + rc = execute_shell_command(h2_blocks) + print("Finish checking the tutorial {} with exit code {}".format(name,str(rc))) + sys.exit(rc) + +if __name__ == '__main__': + # Parse the arguments to get the deployment instruction + args = _parse_args() + check_tutorial(args.tutorial) + diff --git a/docs/DEPLOY_SA5G_BASIC_STATIC_UE_IP.md b/docs/DEPLOY_SA5G_BASIC_STATIC_UE_IP.md index cf7a94604bf92c6a4c160867c57b1f8d7525027d..a6727fce12a316f1010c7385ea08c05312d27eba 100644 --- a/docs/DEPLOY_SA5G_BASIC_STATIC_UE_IP.md +++ b/docs/DEPLOY_SA5G_BASIC_STATIC_UE_IP.md @@ -42,7 +42,7 @@ Please follow the tutorial step by step to create a stable working testbed. 5. [Reference Logs and PCAPs](#5-reference-logs) 6. [Notes](#6-notes) -## 1. Pre-requisites ## +## 1. Pre-requisites Read the tutorial on [how to deploy a Basic OAI-5G core network](./DEPLOY_SA5G_BASIC_DS_TESTER_DEPLOYMENT.md) you can choose to deploy with or without NRF. In this tutorial we are choosing with nrf scenarion. @@ -52,7 +52,7 @@ Create a folder where you can store all the result files of the tutorial and lat docker-compose-host $: mkdir -p /tmp/oai/static-ue-ip ``` -## 2. Configuring the OAI-5G Core Network Functions ## +## 2. Configuring the OAI-5G Core Network Functions Edit the correct docker-compose file of Basic OAI 5G core network, set the parameter `USE_LOCAL_SUBSCRIPTION_INFO` to `no` in the smf service configuration of the docker-compose file. @@ -89,7 +89,7 @@ Make sure you perform this for all the UEs, if there is a user information prese For now these two entries are present in the database file -## 3. Deploying OAI 5g Core Network ## +## 3. Deploying OAI 5g Core Network In the previous tutorial we explain how to deploy the core network using our [python deployer](../docker-compose/core-network.py). Here we will only provide quick commands needed to deploy the core network, to learn how to use the python dployer please follow @@ -147,13 +147,19 @@ docker-compose-host $: tshark -i demo-oai -f -w /tmp/oai/static-ue-ip/capture.p ``` -## 4. Deploying RAN Emulator ## +## 4. Deploying RAN Emulator - **Scenario Execution**: + On the ran emulator host instantiate the ran emulator of your choice here we will show it using gnbsim. We are running everything on one host thus the ran-emulator-host and docker-compose-host is the same for the moment. ``` shell docker-compose-host $: docker-compose -f docker-compose-gnbsim.yaml up -d gnbsim ``` + <!--- + ``` shell + docker-compose-host $: sleep 5 + ``` + --> + + (Optional) in case you want you can also run another instance of gnbsim to check dynamic ip-address allocation is also working or not ``` console docker-compose-host $: docker-compose -f docker-compose-gnbsim.yaml up -d gnbsim2 @@ -169,13 +175,13 @@ docker-compose-host $: docker logs gnbsim2 | grep "UE address:" ``` shell -docker-compose-host $: docker exec -it oai-ext-dn ping 12.1.1.4 +docker-compose-host $: docker exec -it oai-ext-dn ping 12.1.1.4 -c4 PING 12.1.1.4 (12.1.1.4) 56(84) bytes of data. 64 bytes from 12.1.1.4: icmp_seq=1 ttl=63 time=0.297 ms 64 bytes from 12.1.1.4: icmp_seq=2 ttl=63 time=0.824 ms 64 bytes from 12.1.1.4: icmp_seq=3 ttl=63 time=0.723 ms 64 bytes from 12.1.1.4: icmp_seq=4 ttl=63 time=0.849 ms -^C + --- 12.1.1.4 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3072ms rtt min/avg/max/mdev = 0.297/0.673/0.849/0.223 ms @@ -190,7 +196,7 @@ docker-compose-host $: pkill tshark - **Collect the logs of all the components**: -```shell +``` shell docker-compose-host $: docker logs oai-amf > /tmp/oai/static-ue-ip/amf.log 2>&1 docker-compose-host $: docker logs oai-smf > /tmp/oai/static-ue-ip/smf.log 2>&1 docker-compose-host $: docker logs oai-nrf > /tmp/oai/static-ue-ip/nrf.log 2>&1 @@ -236,7 +242,7 @@ Removing network demo-oai-public-net - If you replicate then your log files and pcap file will be present in `/tmp/oai/static-ue-ip/` if you want to compare it with our provided logs and pcaps. Then follow the next section -## 5. Reference logs ## +## 5. Reference logs | PCAP and Logs |