172 lines
5.8 KiB
Python
172 lines
5.8 KiB
Python
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
# Copyright (c) 2025 Linux CAN project
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
|
|
import pytest
|
|
import subprocess
|
|
import os
|
|
import re
|
|
|
|
# --- Helper Functions ---
|
|
|
|
def run_ccbt(bin_path, args):
|
|
"""
|
|
Helper to run can-calc-bit-timing.
|
|
Returns the subprocess.CompletedProcess object.
|
|
"""
|
|
cmd = [os.path.join(bin_path, "can-calc-bit-timing")] + args
|
|
return subprocess.run(cmd, capture_output=True, text=True)
|
|
|
|
# --- Tests ---
|
|
|
|
def test_usage_on_invalid_option(bin_path):
|
|
"""
|
|
Description:
|
|
Tests that providing an invalid option (like -h) results in an error
|
|
message and prints the usage information.
|
|
Note: The tool does not support -h explicitly, it treats it as invalid.
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -h
|
|
> invalid option -- 'h'
|
|
> Usage: can-calc-bit-timing [options] ...
|
|
"""
|
|
result = run_ccbt(bin_path, ["-h"])
|
|
|
|
# Expect failure code usually for invalid options
|
|
assert result.returncode != 0
|
|
assert "Usage: can-calc-bit-timing" in result.stderr or "Usage: can-calc-bit-timing" in result.stdout
|
|
|
|
def test_list_controllers(bin_path):
|
|
"""
|
|
Description:
|
|
Tests the -l option to list all supported CAN controller names.
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -l
|
|
> ...
|
|
> mcp251x
|
|
> ...
|
|
"""
|
|
result = run_ccbt(bin_path, ["-l"])
|
|
|
|
assert result.returncode == 0
|
|
# Check for a common controller known to be in the list (e.g., mcp251x or sja1000)
|
|
# The list is usually quite long.
|
|
assert "mcp251x" in result.stdout or "sja1000" in result.stdout
|
|
|
|
def test_basic_calculation_stdout(bin_path):
|
|
"""
|
|
Description:
|
|
Tests a basic bit timing calculation for a standard bitrate (500k)
|
|
and clock (8MHz). Verifies that a table is produced.
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -c 8000000 -b 500000
|
|
> Bit rate : 500000 Rate error : 0.00% ...
|
|
"""
|
|
# 8MHz clock, 500kbit/s
|
|
result = run_ccbt(bin_path, ["-c", "8000000", "-b", "500000"])
|
|
|
|
assert result.returncode == 0
|
|
# Output should contain column headers like "SampP" (Sample Point) and the bitrate
|
|
assert "SampP" in result.stdout
|
|
assert "500000" in result.stdout
|
|
|
|
def test_quiet_mode(bin_path):
|
|
"""
|
|
Description:
|
|
Tests the -q option (quiet mode), which should suppress the header line.
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -q -c 8000000 -b 500000
|
|
> (Output should start with data, not the 'Bit timing parameters...' header)
|
|
"""
|
|
# Run without -q first to confirm header exists
|
|
res_std = run_ccbt(bin_path, ["-c", "8000000", "-b", "500000"])
|
|
assert "Bit timing parameters" in res_std.stdout
|
|
|
|
# Run with -q
|
|
res_quiet = run_ccbt(bin_path, ["-q", "-c", "8000000", "-b", "500000"])
|
|
assert res_quiet.returncode == 0
|
|
assert "Bit timing parameters" not in res_quiet.stdout
|
|
# Data should still be there
|
|
assert "500000" in res_quiet.stdout
|
|
|
|
def test_verbose_output(bin_path):
|
|
"""
|
|
Description:
|
|
Tests the -v option for verbose output.
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -v -c 8000000 -b 500000
|
|
"""
|
|
result = run_ccbt(bin_path, ["-v", "-c", "8000000", "-b", "500000"])
|
|
assert result.returncode == 0
|
|
# Verbose mode usually prints more details, but the table should definitely be there.
|
|
# We check for "SampP" to ensure valid calculation output.
|
|
assert "SampP" in result.stdout
|
|
|
|
def test_data_bitrate_fd(bin_path):
|
|
"""
|
|
Description:
|
|
Tests the -d option to specify a data bitrate (CAN FD).
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -c 40000000 -b 1000000 -d 2000000
|
|
"""
|
|
# 40MHz clock, 1M nominal, 2M data
|
|
result = run_ccbt(bin_path, ["-c", "40000000", "-b", "1000000", "-d", "2000000"])
|
|
|
|
assert result.returncode == 0
|
|
# Should calculate for both
|
|
assert "SampP" in result.stdout
|
|
assert "1000000" in result.stdout
|
|
assert "2000000" in result.stdout
|
|
|
|
def test_specific_sample_point(bin_path):
|
|
"""
|
|
Description:
|
|
Tests the -s option to define a specific sample point (e.g., 875 for 87.5%).
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -c 8000000 -b 500000 -s 875
|
|
> ... Sample Point : 87.5% ...
|
|
"""
|
|
# 875 means 87.5%
|
|
result = run_ccbt(bin_path, ["-c", "8000000", "-b", "500000", "-s", "875"])
|
|
|
|
assert result.returncode == 0
|
|
assert "87.5%" in result.stdout
|
|
|
|
def test_specific_algorithm(bin_path):
|
|
"""
|
|
Description:
|
|
Tests the --alg option to select a different algorithm.
|
|
Assuming 'v4_8' is a valid algorithm key based on source files
|
|
(can-calc-bit-timing-v4_8.c). Note: Valid keys depend on compilation.
|
|
We check if it accepts the flag without crashing, even if default is used.
|
|
|
|
Manual reproduction:
|
|
$ can-calc-bit-timing -c 8000000 -b 500000 --alg v4.8
|
|
(Note: algorithm naming convention might vary, using a safe check)
|
|
"""
|
|
# Trying to list supported algorithms first would be ideal if possible,
|
|
# but based on file list, let's try a standard calculation with a potentially valid alg string.
|
|
# If the alg string is invalid, it usually warns or errors.
|
|
|
|
# We simply check that the flag is parsed.
|
|
# "default" should always be valid.
|
|
result = run_ccbt(bin_path, ["-c", "8000000", "-b", "500000", "--alg", "default"])
|
|
assert result.returncode == 0
|