Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions test/groovy/LRS_libci_pipeline.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException

pipeline {
agent { label 'rs-orin-01.realsenseai.com' }

options {
timestamps()
timeout(time: 30, unit: 'MINUTES')
}

parameters {
booleanParam(name: 'REBOOT', defaultValue: false)
}

stages {
stage('Get artifacts') {
when {
expression { params.REBOOT == true }
}
steps {
script {
copyArtifacts filter: '**/*.tar.bz2',
projectName: 'D4xx_Kernel_Module_Jetson_JP6',
flatten: true,
target: 'artifacts/'
}
}
}
stage('Install artifacts') {
when {
expression { params.REBOOT == true }
}
steps {
sh """#!/bin/sh
tar -xf artifacts/rootfs.tar.bz2
# external script on agent to install artifacts
sudo install.tegra.artifacts.sh
"""
script {
build job: env.JOB_NAME,
wait: false,
parameters: [ booleanParam(name: 'REBOOT', value: false) ]
}
}
post {
success {
sh 'nohup sudo reboot &'
}
}
}
stage('Pytest') {
when {
expression { params.REBOOT == false }
}
steps {
sh """#!/bin/sh
pytest --tb=no -s test
"""
}
}
}
}
4 changes: 4 additions & 0 deletions test/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
markers =
d457: realsense D457 camera

3 changes: 2 additions & 1 deletion test/run_ci.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def run_test(cmd):
timeout=200,
check=True )
except Exception as e:
print( "Exception occurred.")
print("Exception occurred: {}".format( e ))

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent spacing: there's an extra space before the closing parenthesis in .format( e ). Should be .format(e) to match Python style conventions.

Copilot uses AI. Check for mistakes.


def run_tests_on_d457():
Expand All @@ -73,6 +73,7 @@ def run_tests_on_d457():
except getopt.GetoptError as err:
print( err )
usage()
sys.exit ( 1 )

for opt, arg in opts:
if opt in ('-h', '--help'):
Expand Down
97 changes: 97 additions & 0 deletions test/test_fps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import subprocess
import pytest
import re

@pytest.mark.d457
@pytest.mark.parametrize("frames", {150})
@pytest.mark.parametrize("device", {'0', '2'})
def test_fps(device, frames):
try:
print(f"\nDevice: {device}")
formats = get_formats(device)
for w, h in formats:
print(f"Format: {w}x{h}")
for FPS in formats[(w, h)]:
cmd = [ "v4l2-ctl",
f"-d{device}",
f"--set-fmt-video=width={w},height={h}",
]
subprocess.check_call(cmd)
print(f"FPS/{FPS}:", end=' ')
cmd = [ "v4l2-ctl",
f"-d{device}",
"-p",
f"{FPS}",
]
subprocess.check_call(cmd, stdout=subprocess.DEVNULL)
cmd = [ "v4l2-ctl",
f"-d{device}",
"--stream-mmap",
"--stream-count",
f"{frames}",
"--verbose",
]
timeout = 4.0 * frames / FPS

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout multiplier of 4.0 is a magic number. Consider extracting it as a named constant (e.g., TIMEOUT_MULTIPLIER) to clarify its purpose and make it easier to adjust.

Copilot uses AI. Check for mistakes.
output = subprocess.run(cmd,
check=True,
text=True,
capture_output=True,
timeout=timeout).stderr.splitlines()
last = None
skip = True # skip first FPS measurement
kpi = 5 # [%]

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KPI threshold of 5% is a magic number that should be extracted as a constant or test parameter to improve maintainability and make it easier to adjust.

Copilot uses AI. Check for mistakes.
count = 0
for line in output:
m = re.search(r"cap dqbuf:.*seq:\s*(\d*) bytesused:", line)
if m:
count += 1
frame = int(m.group(1))
# print(f"{frame}", end='')
if last:
assert frame > last, f"Repeated frame: {frame}"
assert (frame - last) < 3 , f"Frames dropped between: {last} and {frame}"

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion allows up to 2 dropped frames, but the PR description states that only 1 drop is allowed. Change < 3 to < 2 to match the specification.

Suggested change
assert (frame - last) < 3 , f"Frames dropped between: {last} and {frame}"
assert (frame - last) < 2 , f"Frames dropped between: {last} and {frame}"

Copilot uses AI. Check for mistakes.
m = re.search(r"delta:\s*(\d+\.\d+) ms", line)
if m:
fps = 1000 / float(m.group(1))
# print(f"/{fps:.2f}", end='')
if not skip:
assert fps > FPS * (1 - kpi/100), f"FPS too low: {fps:.2f}/{FPS}"
assert fps < FPS * (1 + kpi/100), f"FPS too high: {fps:.2f}/{FPS}"
else:
# print('?', end='')
skip = False
# print(end=',')
last = frame
print()
assert last, "No frames arrived"
assert count == frames, f"Missing frames: {count} < {frames}"
except subprocess.TimeoutExpired:
assert False, "No frames arrived"

def get_formats(device):
cmd = [ "v4l2-ctl",
"-d" + device,
"--list-formats-ext",
]
output = subprocess.run(cmd,
check=True,
text=True,
capture_output=True
).stdout.splitlines()
formats = {}
last = None
for line in output:
m = re.search(r"\s*Size: Discrete\s*(\d+)x(\d+)", line)
if m:
w = int(m.group(1))
h = int(m.group(2))
last = (w, h)
if not last in formats:
formats[last] = set()
continue
m = re.search(r"\s*Interval: Discrete.*\((\d+\.\d+)\s+fps\)", line)
if m:
fps = float(m.group(1))
if last:
formats[last].add(fps)
return formats
16 changes: 9 additions & 7 deletions test/test_fw_version.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
@pytest.mark.parametrize("device", {'0'})
def test_fw_version(device):
try:
result = subprocess.check_call(["v4l2-ctl", "-d"+device, "-C", "fw_version"])
key = "fw_version"
result = subprocess.check_call(["v4l2-ctl", "-d"+device, "-C", key])
assert result == 0

std_output = subprocess.check_output(["v4l2-ctl", "-d"+device, "-C", "fw_version"])
assert "fw version: " in std_output, "Couldn't fetch FW version"
std_output = subprocess.check_output(["v4l2-ctl", "-d"+device, "-C", key])
key += ": "
assert key in std_output.decode(), "Couldn't fetch FW version"

# Remove the 'fw version: ' string from std output
fw_version = int(std_output.replace("fw version: ", ""))
fw_version = int(std_output.decode().replace(key, ""))

fw_version_str = str(fw_version>>24 & 0xFF) + "." + str(fw_version>>16 & 0xFF) + "." + str(fw_version>>8 & 0xFF) + "." + str(fw_version & 0xFF)
print ("fw_version:", fw_version_str)
Expand All @@ -21,14 +23,14 @@ def test_fw_version(device):
assert fw_version == (fw_version & 0x05FFFFFF), "Expected FW version is 5.x.x.x, but received {}".format(fw_version_str)

# Get DFU device name
dfu_device = subprocess.check_output(["ls", "/sys/class/d4xx-class/"])
dfu_device = subprocess.check_output(["ls", "/sys/class/d4xx-class/"]).decode()
assert "d4xx-dfu-" in dfu_device, "D4xx DFU device not found"

# Get FW version from DFU device info
dfu_device_info = subprocess.check_output(["cat", "/dev/"+dfu_device.strip()])
dfu_device_info = subprocess.check_output(["cat", "/dev/"+dfu_device.strip()]).decode()

# Check whether the DFU info also has same FW version
assert fw_version_str in dfu_device_info, "FW versions read through v4l2-ctl utility and DFU device info doesn't match"

except Exception as e:
assert False, e
assert False, "Exception caught during test: {}".format(e)
4 changes: 1 addition & 3 deletions test/test_metadata/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ set -x

rm -rf test_metadata test_metadata.o

gcc test_metadata.c framesextract.c -o test_metadata

./test_metadata "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8"
gcc -g -O0 test_metadata.c framesextract.c -o test_metadata
Binary file removed test/test_metadata/test_metadata
Binary file not shown.
Loading