rs2322tcp/internal/client/virtual_port_manager_linux_test.go
2026-08-10 16:20:28 +02:00

221 lines
4.2 KiB
Go

//go:build linux
/*
* ============================================================================
* Projekt.....: rs2322tcp
* Datei.......: internal/client/virtual_port_manager_linux_test.go
* Copyright (C) 2026 Dieter Lang
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Beschreibung:
* Linux-spezifische Tests für die Erzeugung virtueller rs2322tcp-Ports.
* ============================================================================
*/
package client
import (
"os"
"testing"
"git.lang-dieter.de/rs2322tcp/internal/config"
)
///////////////////////////////////////////////////////////////////////////////
// Tests
///////////////////////////////////////////////////////////////////////////////
func TestVirtualPortManagerOpen(t *testing.T) {
tempHome := t.TempDir()
t.Setenv("HOME", tempHome)
manager := NewVirtualPortManager(
config.VirtualPortRangeConfig{
First: 100,
Last: 199,
},
)
port, err := manager.Open()
if err != nil {
t.Fatalf("Open() failed: %v", err)
}
if port == nil {
t.Fatal("Open() returned nil")
}
if port.Path() != "/dev/ttyUSB100" {
t.Errorf(
"Path() = %q, want %q",
port.Path(),
"/dev/ttyUSB100",
)
}
linkPath, err := virtualPortLinkPath(port.Path())
if err != nil {
t.Fatalf("virtualPortLinkPath() failed: %v", err)
}
target, err := os.Readlink(linkPath)
if err != nil {
t.Fatalf("Readlink() failed: %v", err)
}
if target == "" {
t.Fatal("internal virtual port link has empty target")
}
if err := port.Close(); err != nil {
t.Fatalf("Close() failed: %v", err)
}
if _, err := os.Lstat(linkPath); !os.IsNotExist(err) {
t.Fatalf(
"internal link still exists after Close(): %q",
linkPath,
)
}
}
func TestVirtualPortManagerOpenUsesNextPort(t *testing.T) {
tempHome := t.TempDir()
t.Setenv("HOME", tempHome)
manager := NewVirtualPortManager(
config.VirtualPortRangeConfig{
First: 100,
Last: 101,
},
)
first, err := manager.Open()
if err != nil {
t.Fatalf("first Open() failed: %v", err)
}
second, err := manager.Open()
if err != nil {
_ = first.Close()
t.Fatalf("second Open() failed: %v", err)
}
if first.Path() != "/dev/ttyUSB100" {
t.Errorf(
"first.Path() = %q, want %q",
first.Path(),
"/dev/ttyUSB100",
)
}
if second.Path() != "/dev/ttyUSB101" {
t.Errorf(
"second.Path() = %q, want %q",
second.Path(),
"/dev/ttyUSB101",
)
}
if err := first.Close(); err != nil {
t.Fatalf("first Close() failed: %v", err)
}
if err := second.Close(); err != nil {
t.Fatalf("second Close() failed: %v", err)
}
}
func TestVirtualPortManagerOpenReusesReleasedPort(t *testing.T) {
tempHome := t.TempDir()
t.Setenv("HOME", tempHome)
manager := NewVirtualPortManager(
config.VirtualPortRangeConfig{
First: 100,
Last: 100,
},
)
first, err := manager.Open()
if err != nil {
t.Fatalf("first Open() failed: %v", err)
}
if first.Path() != "/dev/ttyUSB100" {
t.Fatalf(
"first.Path() = %q, want %q",
first.Path(),
"/dev/ttyUSB100",
)
}
if err := first.Close(); err != nil {
t.Fatalf("first Close() failed: %v", err)
}
second, err := manager.Open()
if err != nil {
t.Fatalf("second Open() failed: %v", err)
}
if second.Path() != "/dev/ttyUSB100" {
t.Errorf(
"second.Path() = %q, want %q",
second.Path(),
"/dev/ttyUSB100",
)
}
if err := second.Close(); err != nil {
t.Fatalf("second Close() failed: %v", err)
}
}
func TestVirtualPortManagerOpenNoFreePort(t *testing.T) {
tempHome := t.TempDir()
t.Setenv("HOME", tempHome)
manager := NewVirtualPortManager(
config.VirtualPortRangeConfig{
First: 100,
Last: 100,
},
)
port, err := manager.Open()
if err != nil {
t.Fatalf("first Open() failed: %v", err)
}
defer port.Close()
if _, err := manager.Open(); err == nil {
t.Fatal("second Open() succeeded, want no-free-port error")
}
}
func TestManagedVirtualPortDataPath(t *testing.T) {
tempHome := t.TempDir()
t.Setenv("HOME", tempHome)
manager := NewVirtualPortManager(
config.VirtualPortRangeConfig{
First: 100,
Last: 100,
},
)
port, err := manager.Open()
if err != nil {
t.Fatalf("Open() failed: %v", err)
}
defer port.Close()
data := []byte{0x46, 0x41, 0x00, 0x10, 0x0D}
if _, err := port.Write(data); err != nil {
t.Fatalf("Write() failed: %v", err)
}
}