Deleted (7 files): - test_discovery.py, test_windsurf_integration.py (trivial assert True stubs) - pytest_simple.ini (unused --collect-only config) - conftest_path.py (duplicate of conftest.py path setup) - conftest_fixtures.py, conftest_full.py (unused conftest variants) Moved to integration/ (6 files): - test_blockchain_final.py, test_blockchain_nodes.py, test_blockchain_simple.py - test_basic_integration.py, test_integration_simple.py, test_working_integration.py Moved to fixtures/: - mock_blockchain_node.py tests/ root now has only conftest.py and README.md.
97 lines
2.8 KiB
Python
97 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Mock blockchain node server for testing purposes.
|
|
Implements the minimal API endpoints required by the test suite.
|
|
"""
|
|
|
|
import json
|
|
import threading
|
|
import time
|
|
from typing import Dict, Any
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.responses import JSONResponse
|
|
import uvicorn
|
|
|
|
# Create FastAPI app
|
|
app = FastAPI(title="Mock Blockchain Node", version="0.1.0")
|
|
|
|
# Mock state
|
|
mock_chain_state = {
|
|
"height": 100,
|
|
"hash": "0xabcdef1234567890",
|
|
"balances": {
|
|
"aitbc1alice00000000000000000000000000000000000": 1000,
|
|
"aitbc1bob0000000000000000000000000000000000000": 500,
|
|
"aitbc1charl0000000000000000000000000000000000": 100
|
|
},
|
|
"transactions": []
|
|
}
|
|
|
|
@app.get("/openapi.json")
|
|
async def openapi():
|
|
"""Return OpenAPI spec"""
|
|
return {
|
|
"openapi": "3.0.0",
|
|
"info": {
|
|
"title": "AITBC Blockchain API",
|
|
"version": "0.1.0"
|
|
},
|
|
"paths": {}
|
|
}
|
|
|
|
@app.get("/rpc/head")
|
|
async def get_chain_head():
|
|
"""Get current chain head"""
|
|
return JSONResponse(mock_chain_state)
|
|
|
|
@app.get("/rpc/getBalance/{address}")
|
|
async def get_balance(address: str):
|
|
"""Get balance for an address"""
|
|
balance = mock_chain_state["balances"].get(address, 0)
|
|
return JSONResponse({"balance": balance})
|
|
|
|
@app.post("/rpc/admin/mintFaucet")
|
|
async def mint_faucet(request: Dict[str, Any]):
|
|
"""Mint tokens to an address (devnet only)"""
|
|
address = request.get("address")
|
|
amount = request.get("amount", 0)
|
|
|
|
if address in mock_chain_state["balances"]:
|
|
mock_chain_state["balances"][address] += amount
|
|
else:
|
|
mock_chain_state["balances"][address] = amount
|
|
|
|
return JSONResponse({"success": True, "new_balance": mock_chain_state["balances"][address]})
|
|
|
|
@app.post("/rpc/sendTx")
|
|
async def send_transaction(request: Dict[str, Any]):
|
|
"""Send a transaction"""
|
|
# Generate mock transaction hash
|
|
tx_hash = f"0x{hash(str(request)) % 1000000000000000000000000000000000000000000000000000000000000000:x}"
|
|
|
|
# Add to transactions list
|
|
mock_chain_state["transactions"].append({
|
|
"hash": tx_hash,
|
|
"type": request.get("type", "TRANSFER"),
|
|
"sender": request.get("sender"),
|
|
"timestamp": time.time()
|
|
})
|
|
|
|
return JSONResponse({"tx_hash": tx_hash, "status": "pending"})
|
|
|
|
@app.get("/health")
|
|
async def health():
|
|
"""Health check endpoint"""
|
|
return JSONResponse({"status": "ok", "height": mock_chain_state["height"]})
|
|
|
|
def run_mock_server(port: int):
|
|
"""Run the mock server on specified port"""
|
|
uvicorn.run(app, host="127.0.0.1", port=port, log_level="warning")
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8081
|
|
print(f"Starting mock blockchain node on port {port}")
|
|
run_mock_server(port)
|