-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconnectivity_test.py
More file actions
184 lines (147 loc) · 5.71 KB
/
connectivity_test.py
File metadata and controls
184 lines (147 loc) · 5.71 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
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "neo4j>=5.20.0",
# "python-dotenv",
# ]
# ///
"""Neo4j Connectivity Test Suite
Validates network and driver connectivity to Neo4j.
Reads credentials from .env file in the same directory.
"""
import os
import socket
import sys
import time
from pathlib import Path
from dotenv import load_dotenv
# Load .env from the script's directory
env_path = Path(__file__).parent / ".env"
if not env_path.exists():
print(f"[ERROR] .env file not found at {env_path}")
print("Copy .env.sample to .env and fill in your Neo4j credentials:")
print(" cp .env.sample .env")
sys.exit(1)
load_dotenv(env_path)
# Configuration
NEO4J_HOST = os.getenv("NEO4J_HOST")
NEO4J_USER = os.getenv("NEO4J_USER")
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
NEO4J_DATABASE = os.getenv("NEO4J_DATABASE", "neo4j")
NEO4J_URI = f"neo4j+s://{NEO4J_HOST}"
# Validate required variables
missing = [v for v in ("NEO4J_HOST", "NEO4J_USER", "NEO4J_PASSWORD") if not os.getenv(v)]
if missing:
print(f"[ERROR] Missing required variables in .env: {', '.join(missing)}")
sys.exit(1)
# ── Section 1: Environment Information ──────────────────────────
def test_environment():
print("=" * 60)
print("ENVIRONMENT INFORMATION")
print("=" * 60)
print(f"\nPython Version: {sys.version}")
try:
import neo4j
print(f"Neo4j Python Driver: {neo4j.__version__}")
except ImportError:
print("Neo4j Python Driver: NOT INSTALLED")
# ── Section 2: Network Connectivity Test (TCP Layer) ────────────
def test_tcp_connectivity():
print("\n" + "=" * 60)
print("TEST: Network Connectivity (TCP)")
print("=" * 60)
print(f"\nTarget: {NEO4J_HOST}:7687 (Bolt protocol port)")
print("Testing: Can we reach Neo4j at the network level?")
try:
start_time = time.time()
sock = socket.create_connection((NEO4J_HOST, 7687), timeout=10)
elapsed = (time.time() - start_time) * 1000
sock.close()
print("\n" + "=" * 60)
print(">>> CONNECTIVITY VERIFIED <<<")
print("=" * 60)
print(f"\n[PASS] TCP connection established in {elapsed:.1f}ms")
print(f"\nConnection Details:")
print(f" - Host: {NEO4J_HOST}")
print(f" - Port: 7687 (Bolt)")
print(f" - TCP Latency: {elapsed:.1f}ms")
print("\n" + "-" * 60)
print("RESULT: Network path to Neo4j is OPEN")
print(" Firewall rules allow Bolt protocol traffic")
print("-" * 60)
print("\nStatus: PASS")
return True
except Exception as e:
print(f"\n[FAIL] Cannot reach {NEO4J_HOST}:7687 - {e}")
print("\nStatus: FAIL")
return False
# ── Section 3: Neo4j Python Driver Test ─────────────────────────
def test_python_driver():
print("\n" + "=" * 60)
print("TEST: Neo4j Python Driver")
print("=" * 60)
print(f"\nTarget: {NEO4J_URI}")
print("Testing: Can we authenticate and execute queries via Bolt protocol?")
from neo4j import GraphDatabase
try:
start_time = time.time()
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
# Verify connectivity
driver.verify_connectivity()
connect_time = (time.time() - start_time) * 1000
print("\n" + "=" * 60)
print(">>> AUTHENTICATION SUCCESSFUL <<<")
print("=" * 60)
print(f"\n[PASS] Driver connected and authenticated in {connect_time:.1f}ms")
# Test simple query
with driver.session() as session:
query_start = time.time()
result = session.run("RETURN 1 AS test")
record = result.single()
query_time = (time.time() - query_start) * 1000
print(f"[PASS] Query executed: RETURN 1 = {record['test']} ({query_time:.1f}ms)")
# Get Neo4j version
result = session.run(
"CALL dbms.components() YIELD name, versions RETURN name, versions"
)
neo4j_info = [f"{r['name']} {r['versions']}" for r in result]
total_time = (time.time() - start_time) * 1000
driver.close()
print(f"\nConnection Details:")
print(f" - URI: {NEO4J_URI}")
print(f" - User: {NEO4J_USER}")
print(f" - Database: {NEO4J_DATABASE}")
print(f" - Neo4j Server: {', '.join(neo4j_info)}")
print(f" - Connection Time: {connect_time:.1f}ms")
print(f" - Total Test Time: {total_time:.1f}ms")
print("\n" + "-" * 60)
print("RESULT: Neo4j Python Driver connection WORKING")
print(" Credentials valid, Bolt protocol functional")
print("-" * 60)
print("\nStatus: PASS")
return True
except Exception as e:
print(f"\n[FAIL] Connection failed: {e}")
print("\nStatus: FAIL")
return False
# ── Main ────────────────────────────────────────────────────────
def main():
print(f"\nConfiguration loaded from {env_path}:")
print(f" Neo4j Host: {NEO4J_HOST}")
print(f" Neo4j URI: {NEO4J_URI}")
print()
test_environment()
tcp_ok = test_tcp_connectivity()
driver_ok = test_python_driver()
# Summary
print("\n" + "=" * 60)
print("SUMMARY")
print("=" * 60)
print(f" TCP Connectivity: {'PASS' if tcp_ok else 'FAIL'}")
print(f" Python Driver: {'PASS' if driver_ok else 'FAIL'}")
print()
if not (tcp_ok and driver_ok):
sys.exit(1)
if __name__ == "__main__":
main()