-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_config_manager.py
More file actions
199 lines (168 loc) · 7.22 KB
/
test_config_manager.py
File metadata and controls
199 lines (168 loc) · 7.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
"""
Smoke-Tests für ConfigManager
Testet grundlegende Funktionalität: Load, Save, Add, Update, Delete
"""
import os
import sys
import json
import tempfile
import importlib.util
from pathlib import Path
# Konstanten
JSON_INDENT = 2 # Einrückung für JSON-Formatierung
EXIT_SUCCESS = 0 # Exit-Code für erfolgreiche Ausführung
EXIT_FAILURE = 1 # Exit-Code für Fehler
# Import ConfigManager from main file
sys.path.insert(0, os.path.dirname(__file__))
# Mock PyQt6 imports if not available
try:
from PySide6.QtWidgets import QApplication
from PySide6.QtCore import Qt, QThread, Signal, QObject
except ImportError:
print("PyQt6 nicht verfügbar - Mock-Klassen werden verwendet")
class QThread: pass
class Signal:
def __init__(self, *args): pass
class QObject: pass
def load_prosync_module():
"""Lädt das Hauptmodul per importlib für echte ConfigManager-Checks."""
module_path = Path(__file__).with_name("ProSyncStart_V3.1.py")
spec = importlib.util.spec_from_file_location("prosync", module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def test_config_manager():
"""Smoke-Test für ConfigManager: Load, Save, Add, Update, Delete."""
print("=== ConfigManager Smoke-Test ===\n")
# Erstelle temporäre Config-Datei
temp_dir = tempfile.gettempdir()
test_config_path = os.path.join(temp_dir, "test_prosync_config.json")
# Cleanup falls vorhanden
if os.path.exists(test_config_path):
os.remove(test_config_path)
print(f"Test-Config: {test_config_path}\n")
# Manuelles ConfigManager-Mock (da wir die Klasse nicht importieren können ohne PyQt)
class SimpleConfigManager:
def __init__(self, path):
self.path = path
self.data = {"connections": []}
self.load()
def load(self):
if os.path.exists(self.path):
try:
with open(self.path, "r", encoding="utf-8") as f:
self.data = json.load(f)
except (json.JSONDecodeError, OSError, UnicodeDecodeError) as e:
print(f"Config load error: {e}")
self.save()
else:
self.save()
def save(self):
with open(self.path, "w", encoding="utf-8") as f:
json.dump(self.data, f, indent=JSON_INDENT, ensure_ascii=False)
def get_all(self):
return self.data.get("connections", [])
def get(self, conn_id):
for conn in self.data["connections"]:
if conn["id"] == conn_id:
return conn
return None
def add_or_update_connection(self, conn):
existing = self.get(conn["id"])
if existing:
# Update
for i, c in enumerate(self.data["connections"]):
if c["id"] == conn["id"]:
self.data["connections"][i] = conn
break
else:
# Add
self.data["connections"].append(conn)
self.save()
def delete(self, conn_id):
self.data["connections"] = [c for c in self.data["connections"] if c["id"] != conn_id]
self.save()
# Test 1: Initialisierung & Leere Config
print("Test 1: Initialisierung & Leere Config")
cfg = SimpleConfigManager(test_config_path)
assert os.path.exists(test_config_path), "Config-Datei wurde nicht erstellt"
assert len(cfg.get_all()) == 0, "Config sollte leer sein"
print("✓ PASS: Config wurde erstellt und ist leer\n")
# Test 2: Connection hinzufügen
print("Test 2: Connection hinzufügen")
conn1 = {
"id": "test-123",
"name": "Test Backup",
"source": "C:\\Test\\Source",
"target": "D:\\Test\\Target",
"mode": "mirror"
}
cfg.add_or_update_connection(conn1)
assert len(cfg.get_all()) == 1, "Eine Connection sollte vorhanden sein"
assert cfg.get("test-123") == conn1, "Connection sollte korrekt gespeichert sein"
print("✓ PASS: Connection erfolgreich hinzugefügt\n")
# Test 3: Connection aktualisieren
print("Test 3: Connection aktualisieren")
conn1_updated = conn1.copy()
conn1_updated["mode"] = "update"
conn1_updated["name"] = "Test Backup (Updated)"
cfg.add_or_update_connection(conn1_updated)
assert len(cfg.get_all()) == 1, "Immer noch eine Connection"
assert cfg.get("test-123")["mode"] == "update", "Mode sollte aktualisiert sein"
assert cfg.get("test-123")["name"] == "Test Backup (Updated)", "Name sollte aktualisiert sein"
print("✓ PASS: Connection erfolgreich aktualisiert\n")
# Test 4: Zweite Connection hinzufügen
print("Test 4: Zweite Connection hinzufügen")
conn2 = {
"id": "test-456",
"name": "DB Backup",
"source_file": "C:\\App\\data.db",
"target_file": "D:\\Backup\\data.db",
"mode": "one_way",
"type": "file"
}
cfg.add_or_update_connection(conn2)
assert len(cfg.get_all()) == 2, "Zwei Connections sollten vorhanden sein"
print("✓ PASS: Zweite Connection hinzugefügt\n")
# Test 5: Connection löschen
print("Test 5: Connection löschen")
cfg.delete("test-123")
assert len(cfg.get_all()) == 1, "Eine Connection sollte übrig sein"
assert cfg.get("test-123") is None, "test-123 sollte gelöscht sein"
assert cfg.get("test-456") is not None, "test-456 sollte noch existieren"
print("✓ PASS: Connection erfolgreich gelöscht\n")
# Test 6: Config neu laden (Persistenz-Test)
print("Test 6: Config neu laden (Persistenz)")
cfg2 = SimpleConfigManager(test_config_path)
assert len(cfg2.get_all()) == 1, "Nach Reload: Eine Connection"
assert cfg2.get("test-456") is not None, "test-456 sollte nach Reload existieren"
print("✓ PASS: Config wurde korrekt persistiert\n")
# Test 7: Korrupte Config-Datei (Error-Handling)
print("Test 7: Korrupte Config-Datei")
with open(test_config_path, "w", encoding="utf-8") as f:
f.write("INVALID JSON{{{")
cfg3 = SimpleConfigManager(test_config_path)
assert len(cfg3.get_all()) == 0, "Korrupte Config sollte auf leer zurückfallen"
print("✓ PASS: Korrupte Config wird korrekt behandelt\n")
# Test 8: Echte ConfigManager-Klasse sanitiert gültige Nicht-Objekt-JSONs
print("Test 8: Gültige Nicht-Objekt-Config")
with open(test_config_path, "w", encoding="utf-8") as f:
json.dump([], f)
prosync = load_prosync_module()
cfg4 = prosync.ConfigManager(test_config_path)
assert cfg4.data == {"app": {}, "connections": []}, "Nicht-Objekt-JSON sollte auf Standardstruktur zurückfallen"
assert cfg4.list_connections() == [], "Leere Standardstruktur sollte ohne Crash lesbar sein"
print("✓ PASS: Gültige Nicht-Objekt-Config wird korrekt behandelt\n")
# Cleanup
if os.path.exists(test_config_path):
os.remove(test_config_path)
print("=== ALLE TESTS BESTANDEN ✓ ===")
if __name__ == "__main__":
try:
test_config_manager()
sys.exit(EXIT_SUCCESS)
except Exception as e:
print(f"\n❌ TEST FEHLGESCHLAGEN: {e}")
import traceback
traceback.print_exc()
sys.exit(EXIT_FAILURE)