test(Add unit tests):

This commit is contained in:
2024-09-23 18:46:25 +08:00
parent e8e7c59579
commit 43bc27cbc3
29 changed files with 1483 additions and 0 deletions

247
myenv/bin/Activate.ps1 Normal file
View File

@@ -0,0 +1,247 @@
<#
.Synopsis
Activate a Python virtual environment for the current PowerShell session.
.Description
Pushes the python executable for a virtual environment to the front of the
$Env:PATH environment variable and sets the prompt to signify that you are
in a Python virtual environment. Makes use of the command line switches as
well as the `pyvenv.cfg` file values present in the virtual environment.
.Parameter VenvDir
Path to the directory that contains the virtual environment to activate. The
default value for this is the parent of the directory that the Activate.ps1
script is located within.
.Parameter Prompt
The prompt prefix to display when this virtual environment is activated. By
default, this prompt is the name of the virtual environment folder (VenvDir)
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
.Example
Activate.ps1
Activates the Python virtual environment that contains the Activate.ps1 script.
.Example
Activate.ps1 -Verbose
Activates the Python virtual environment that contains the Activate.ps1 script,
and shows extra information about the activation as it executes.
.Example
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
Activates the Python virtual environment located in the specified location.
.Example
Activate.ps1 -Prompt "MyPython"
Activates the Python virtual environment that contains the Activate.ps1 script,
and prefixes the current prompt with the specified string (surrounded in
parentheses) while the virtual environment is active.
.Notes
On Windows, it may be required to enable this Activate.ps1 script by setting the
execution policy for the user. You can do this by issuing the following PowerShell
command:
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
For more information on Execution Policies:
https://go.microsoft.com/fwlink/?LinkID=135170
#>
Param(
[Parameter(Mandatory = $false)]
[String]
$VenvDir,
[Parameter(Mandatory = $false)]
[String]
$Prompt
)
<# Function declarations --------------------------------------------------- #>
<#
.Synopsis
Remove all shell session elements added by the Activate script, including the
addition of the virtual environment's Python executable from the beginning of
the PATH variable.
.Parameter NonDestructive
If present, do not remove this function from the global namespace for the
session.
#>
function global:deactivate ([switch]$NonDestructive) {
# Revert to original values
# The prior prompt:
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
}
# The prior PYTHONHOME:
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
}
# The prior PATH:
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
}
# Just remove the VIRTUAL_ENV altogether:
if (Test-Path -Path Env:VIRTUAL_ENV) {
Remove-Item -Path env:VIRTUAL_ENV
}
# Just remove VIRTUAL_ENV_PROMPT altogether.
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
}
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
}
# Leave deactivate function in the global namespace if requested:
if (-not $NonDestructive) {
Remove-Item -Path function:deactivate
}
}
<#
.Description
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
given folder, and returns them in a map.
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
two strings separated by `=` (with any amount of whitespace surrounding the =)
then it is considered a `key = value` line. The left hand string is the key,
the right hand is the value.
If the value starts with a `'` or a `"` then the first and last character is
stripped from the value before being captured.
.Parameter ConfigDir
Path to the directory that contains the `pyvenv.cfg` file.
#>
function Get-PyVenvConfig(
[String]
$ConfigDir
) {
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
# An empty map will be returned if no config file is found.
$pyvenvConfig = @{ }
if ($pyvenvConfigPath) {
Write-Verbose "File exists, parse `key = value` lines"
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
$pyvenvConfigContent | ForEach-Object {
$keyval = $PSItem -split "\s*=\s*", 2
if ($keyval[0] -and $keyval[1]) {
$val = $keyval[1]
# Remove extraneous quotations around a string value.
if ("'""".Contains($val.Substring(0, 1))) {
$val = $val.Substring(1, $val.Length - 2)
}
$pyvenvConfig[$keyval[0]] = $val
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
}
}
}
return $pyvenvConfig
}
<# Begin Activate script --------------------------------------------------- #>
# Determine the containing directory of this script
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
$VenvExecDir = Get-Item -Path $VenvExecPath
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
# Set values required in priority: CmdLine, ConfigFile, Default
# First, get the location of the virtual environment, it might not be
# VenvExecDir if specified on the command line.
if ($VenvDir) {
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
}
else {
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
Write-Verbose "VenvDir=$VenvDir"
}
# Next, read the `pyvenv.cfg` file to determine any required value such
# as `prompt`.
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
# Next, set the prompt from the command line, or the config file, or
# just use the name of the virtual environment folder.
if ($Prompt) {
Write-Verbose "Prompt specified as argument, using '$Prompt'"
}
else {
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
$Prompt = $pyvenvCfg['prompt'];
}
else {
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
$Prompt = Split-Path -Path $venvDir -Leaf
}
}
Write-Verbose "Prompt = '$Prompt'"
Write-Verbose "VenvDir='$VenvDir'"
# Deactivate any currently active virtual environment, but leave the
# deactivate function in place.
deactivate -nondestructive
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
# that there is an activated venv.
$env:VIRTUAL_ENV = $VenvDir
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
Write-Verbose "Setting prompt to '$Prompt'"
# Set the prompt to include the env name
# Make sure _OLD_VIRTUAL_PROMPT is global
function global:_OLD_VIRTUAL_PROMPT { "" }
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
function global:prompt {
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
_OLD_VIRTUAL_PROMPT
}
$env:VIRTUAL_ENV_PROMPT = $Prompt
}
# Clear PYTHONHOME
if (Test-Path -Path Env:PYTHONHOME) {
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
Remove-Item -Path Env:PYTHONHOME
}
# Add the venv to the PATH
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"

69
myenv/bin/activate Normal file
View File

@@ -0,0 +1,69 @@
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
PATH="${_OLD_VIRTUAL_PATH:-}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r 2> /dev/null
fi
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
PS1="${_OLD_VIRTUAL_PS1:-}"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
unset VIRTUAL_ENV_PROMPT
if [ ! "${1:-}" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="/home/muzhi/tpre-python/myenv"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
PS1="(myenv) ${PS1:-}"
export PS1
VIRTUAL_ENV_PROMPT="(myenv) "
export VIRTUAL_ENV_PROMPT
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r 2> /dev/null
fi

26
myenv/bin/activate.csh Normal file
View File

@@ -0,0 +1,26 @@
# This file must be used with "source bin/activate.csh" *from csh*.
# You cannot run it directly.
# Created by Davide Di Blasi <davidedb@gmail.com>.
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
# Unset irrelevant variables.
deactivate nondestructive
setenv VIRTUAL_ENV "/home/muzhi/tpre-python/myenv"
set _OLD_VIRTUAL_PATH="$PATH"
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
set _OLD_VIRTUAL_PROMPT="$prompt"
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
set prompt = "(myenv) $prompt"
setenv VIRTUAL_ENV_PROMPT "(myenv) "
endif
alias pydoc python -m pydoc
rehash

69
myenv/bin/activate.fish Normal file
View File

@@ -0,0 +1,69 @@
# This file must be used with "source <venv>/bin/activate.fish" *from fish*
# (https://fishshell.com/); you cannot run it directly.
function deactivate -d "Exit virtual environment and return to normal shell environment"
# reset old environment variables
if test -n "$_OLD_VIRTUAL_PATH"
set -gx PATH $_OLD_VIRTUAL_PATH
set -e _OLD_VIRTUAL_PATH
end
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
set -e _OLD_VIRTUAL_PYTHONHOME
end
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
set -e _OLD_FISH_PROMPT_OVERRIDE
# prevents error when using nested fish instances (Issue #93858)
if functions -q _old_fish_prompt
functions -e fish_prompt
functions -c _old_fish_prompt fish_prompt
functions -e _old_fish_prompt
end
end
set -e VIRTUAL_ENV
set -e VIRTUAL_ENV_PROMPT
if test "$argv[1]" != "nondestructive"
# Self-destruct!
functions -e deactivate
end
end
# Unset irrelevant variables.
deactivate nondestructive
set -gx VIRTUAL_ENV "/home/muzhi/tpre-python/myenv"
set -gx _OLD_VIRTUAL_PATH $PATH
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
# Unset PYTHONHOME if set.
if set -q PYTHONHOME
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
set -e PYTHONHOME
end
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
# fish uses a function instead of an env var to generate the prompt.
# Save the current fish_prompt function as the function _old_fish_prompt.
functions -c fish_prompt _old_fish_prompt
# With the original prompt function renamed, we can override with our own.
function fish_prompt
# Save the return status of the last command.
set -l old_status $status
# Output the venv prompt; color taken from the blue of the Python logo.
printf "%s%s%s" (set_color 4B8BBE) "(myenv) " (set_color normal)
# Restore the return status of the previous command.
echo "exit $old_status" | .
# Output the original/"old" prompt.
_old_fish_prompt
end
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
set -gx VIRTUAL_ENV_PROMPT "(myenv) "
end

8
myenv/bin/fastapi Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from fastapi.cli import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

8
myenv/bin/httpx Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from httpx import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

BIN
myenv/bin/maturin Executable file

Binary file not shown.

8
myenv/bin/normalizer Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from charset_normalizer.cli import cli_detect
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(cli_detect())

8
myenv/bin/pip Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

8
myenv/bin/pip3 Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

8
myenv/bin/pip3.11 Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

8
myenv/bin/py.test Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pytest import console_main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(console_main())

8
myenv/bin/pytest Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pytest import console_main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(console_main())

1
myenv/bin/python Symbolic link
View File

@@ -0,0 +1 @@
python3

1
myenv/bin/python3 Symbolic link
View File

@@ -0,0 +1 @@
/usr/bin/python3

1
myenv/bin/python3.11 Symbolic link
View File

@@ -0,0 +1 @@
python3

8
myenv/bin/uvicorn Executable file
View File

@@ -0,0 +1,8 @@
#!/home/muzhi/tpre-python/myenv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from uvicorn.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

1
myenv/lib64 Symbolic link
View File

@@ -0,0 +1 @@
lib

5
myenv/pyvenv.cfg Normal file
View File

@@ -0,0 +1,5 @@
home = /usr/bin
include-system-site-packages = false
version = 3.11.2
executable = /usr/bin/python3.11
command = /usr/bin/python3 -m venv /home/muzhi/tpre-python/myenv

4
nohup.out Normal file
View File

@@ -0,0 +1,4 @@
python: can't open file '/home/muzhi/tpre-python/server.py': [Errno 2] No such file or directory
python: can't open file '/home/muzhi/tpre-python/client.py': [Errno 2] No such file or directory
python: can't open file '/home/muzhi/tpre-python/node.py': [Errno 2] No such file or directory
python: can't open file '/home/muzhi/tpre-python/server.py': [Errno 2] No such file or directory

1
src/node_test.log Normal file
View File

@@ -0,0 +1 @@
DEBUG:asyncio:Using selector: EpollSelector

35
src/node_test1.py Normal file
View File

@@ -0,0 +1,35 @@
#测试 get_local_ip()函数
import unittest
from unittest.mock import patch, MagicMock
import node
class TestGetLocalIP(unittest.TestCase):
@patch.dict('os.environ', {'HOST_IP': '60.204.193.58'}) # 模拟设置 HOST_IP 环境变量
def test_get_ip_from_env(self):
# 调用被测函数
node.get_local_ip()
# 检查函数是否正确获取到 HOST_IP
self.assertEqual(node.ip, '60.204.193.58')
@patch('socket.socket') # Mock socket 连接行为
@patch.dict('os.environ', {}) # 模拟没有 HOST_IP 环境变量
def test_get_ip_from_socket(self, mock_socket):
# 模拟 socket 返回的 IP 地址
mock_socket_instance = MagicMock()
mock_socket.return_value = mock_socket_instance
mock_socket_instance.getsockname.return_value = ('110.41.155.96', 0)
# 调用被测函数
node.get_local_ip()
# 确认 socket 被调用过
mock_socket_instance.connect.assert_called_with(('8.8.8.8', 80))
mock_socket_instance.close.assert_called_once()
# 检查是否通过 socket 获取到正确的 IP 地址
self.assertEqual(node.ip, '110.41.155.96')
if __name__ == '__main__':
unittest.main()

34
src/node_test2.py Normal file
View File

@@ -0,0 +1,34 @@
#测试send_ip()函数
import os
import unittest
from unittest.mock import patch, Mock
import node # 导入要测试的模块
class TestSendIP(unittest.TestCase):
@patch.dict(os.environ, {'HOST_IP': '60.204.193.58'}) # 设置环境变量 HOST_IP
@patch('requests.get') # Mock requests.get 调用
def test_send_ip(self, mock_get):
# 设置模拟返回的 HTTP 响应
mock_response = Mock()
mock_response.text = "node123" # 模拟返回的节点ID
mock_response.status_code = 200
mock_get.return_value = mock_response # 设置 requests.get() 的返回值为 mock_response
# 保存原始的全局 id 值
original_id = node.id
# 调用待测函数
node.send_ip()
# 确保 requests.get 被正确调用
expected_url = f"{node.server_address}/get_node?ip={node.ip}"
mock_get.assert_called_once_with(expected_url, timeout=3)
# 检查 id 是否被正确更新
self.assertIs(node.id, mock_response) # 检查 id 是否被修改
self.assertEqual(node.id.text, "node123") # 检查更新后的 id 是否与 mock_response.text 匹配
if __name__ == "__main__":
unittest.main()
#node.py中
#print("中心服务器返回节点ID为: ", id.text)即可看到测试代码返回的节点

23
src/node_test3.py Normal file
View File

@@ -0,0 +1,23 @@
#测试init()函数
import unittest
from unittest.mock import patch, AsyncMock
import node
class TestNode(unittest.TestCase):
@patch('node.send_ip')
@patch('node.get_local_ip')
@patch('node.asyncio.create_task')
def test_init(self, mock_create_task, mock_get_local_ip, mock_send_ip):
# 调用 init 函数
node.init()
# 验证 get_local_ip 和 send_ip 被调用
mock_get_local_ip.assert_called_once()
mock_send_ip.assert_called_once()
# 确保 create_task 被调用来启动心跳包
mock_create_task.assert_called_once()
if __name__ == '__main__':
unittest.main()

89
src/node_test5.py Normal file
View File

@@ -0,0 +1,89 @@
import pytest
import httpx
import respx
import asyncio
from unittest.mock import patch, AsyncMock
from fastapi.testclient import TestClient
from node import app, send_heartbeat_internal, Req
client = TestClient(app)
server_address = "http://60.204.236.38:8000/server"
ip = "127.0.0.1"
@pytest.fixture(scope="session")
def anyio_backend():
return "asyncio"
@pytest.mark.asyncio
@respx.mock
async def test_send_heartbeat_internal_success():
# 模拟心跳请求
heartbeat_route = respx.get(f"{server_address}/heartbeat?ip={ip}").mock(
return_value=httpx.Response(200)
)
# 模拟 requests.get 以避免实际请求
with patch("requests.get", return_value=httpx.Response(200)) as mock_get:
# 模拟 asyncio.sleep 以避免实际延迟
with patch("asyncio.sleep", new_callable=AsyncMock) as mock_sleep:
task = asyncio.create_task(send_heartbeat_internal())
await asyncio.sleep(0.1) # 允许任务运行一段时间
task.cancel() # 取消任务以停止无限循环
try:
await task # 确保任务被等待
except asyncio.CancelledError:
pass # 捕获取消错误
assert mock_get.called
assert mock_get.call_count > 0
@pytest.mark.asyncio
@respx.mock
async def test_send_heartbeat_internal_failure():
# 模拟心跳请求以引发异常
heartbeat_route = respx.get(f"{server_address}/heartbeat?ip={ip}").mock(
side_effect=httpx.RequestError("Central server error")
)
# 模拟 requests.get 以避免实际请求
with patch("requests.get", side_effect=httpx.RequestError("Central server error")) as mock_get:
# 模拟 asyncio.sleep 以避免实际延迟
with patch("asyncio.sleep", new_callable=AsyncMock) as mock_sleep:
task = asyncio.create_task(send_heartbeat_internal())
await asyncio.sleep(0.1) # 允许任务运行一段时间
task.cancel() # 取消任务以停止无限循环
try:
await task # 确保任务被等待
except asyncio.CancelledError:
pass # 捕获取消错误
assert mock_get.called
assert mock_get.call_count > 0
def test_user_src():
# 模拟 ReEncrypt 函数
with patch("node.ReEncrypt", return_value=(("a", "b", "c", "d"), b"encrypted_data")):
# 模拟 send_user_des_message 函数
with patch("node.send_user_des_message", new_callable=AsyncMock) as mock_send_user_des_message:
message = {
"source_ip": "127.0.0.1",
"dest_ip": "127.0.0.2",
"capsule": (("x1", "y1"), ("x2", "y2"), 123),
"ct": 456,
"rk": ["rk1", "rk2"]
}
response = client.post("/user_src", json=message)
assert response.status_code == 200
assert response.json() == {"detail": "message received"}
mock_send_user_des_message.assert_called_once()
def test_send_user_des_message():
with respx.mock:
dest_ip = "127.0.0.2"
re_message = (("a", "b", "c", "d"), 123)
respx.post(f"http://{dest_ip}:8002/receive_messages").mock(
return_value=httpx.Response(200, json={"status": "success"})
)
response = client.post(f"http://{dest_ip}:8002/receive_messages", json={"Tuple": re_message, "ip": "127.0.0.1"})
assert response.status_code == 200
assert response.json() == {"status": "success"}

550
src/nohup.out Normal file
View File

@@ -0,0 +1,550 @@
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: Started reloader process [33991] using StatReload
INFO: Started server process [33994]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)
INFO: Started reloader process [34080] using StatReload
INFO: Started server process [34086]
INFO: Waiting for application startup.
ERROR: Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 536, in _make_request
response = conn.getresponse()
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 464, in getresponse
httplib_response = super().getresponse()
^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/http/client.py", line 1374, in getresponse
response.begin()
File "/usr/lib/python3.11/http/client.py", line 318, in begin
version, status, reason = self._read_status()
^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/http/client.py", line 279, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/socket.py", line 706, in readinto
return self._sock.recv_into(b)
^^^^^^^^^^^^^^^^^^^^^^^
TimeoutError: timed out
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 843, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/retry.py", line 474, in increment
raise reraise(type(error), error, _stacktrace)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/util.py", line 39, in reraise
raise value
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 789, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 538, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 369, in _raise_timeout
raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPConnectionPool(host='192.168.252.57', port=10809): Read timed out. (read timeout=3)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/starlette/routing.py", line 693, in lifespan
async with self.lifespan_context(app) as maybe_state:
File "/usr/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/node.py", line 14, in lifespan
init()
File "/home/muzhi/tpre-python/src/node.py", line 62, in init
send_ip()
File "/home/muzhi/tpre-python/src/node.py", line 40, in send_ip
id = requests.get(url, timeout=3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 713, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPConnectionPool(host='192.168.252.57', port=10809): Read timed out. (read timeout=3)
ERROR: Application startup failed. Exiting.
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8002 (Press CTRL+C to quit)
INFO: Started reloader process [34220] using StatReload
INFO: Started server process [34226]
INFO: Waiting for application startup.
ERROR: Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 536, in _make_request
response = conn.getresponse()
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 464, in getresponse
httplib_response = super().getresponse()
^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/http/client.py", line 1374, in getresponse
response.begin()
File "/usr/lib/python3.11/http/client.py", line 318, in begin
version, status, reason = self._read_status()
^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/http/client.py", line 279, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/socket.py", line 706, in readinto
return self._sock.recv_into(b)
^^^^^^^^^^^^^^^^^^^^^^^
TimeoutError: timed out
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 843, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/retry.py", line 474, in increment
raise reraise(type(error), error, _stacktrace)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/util.py", line 39, in reraise
raise value
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 789, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 538, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 369, in _raise_timeout
raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPConnectionPool(host='192.168.252.57', port=10809): Read timed out. (read timeout=3)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/starlette/routing.py", line 693, in lifespan
async with self.lifespan_context(app) as maybe_state:
File "/usr/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/client.py", line 32, in lifespan
init()
File "/home/muzhi/tpre-python/src/client.py", line 47, in init
get_node_list(2, server_address) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/client.py", line 407, in get_node_list
response = requests.get(url, timeout=3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 713, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPConnectionPool(host='192.168.252.57', port=10809): Read timed out. (read timeout=3)
ERROR: Application startup failed. Exiting.
Init Database Successful
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: Started reloader process [3954] using StatReload
INFO: Started server process [3956]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)
INFO: Started reloader process [4053] using StatReload
INFO: Started server process [4058]
INFO: Waiting for application startup.
ERROR: Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 196, in _new_conn
sock = connection.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 85, in create_connection
raise err
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 789, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 495, in _make_request
conn.request(
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 398, in request
self.endheaders()
File "/usr/lib/python3.11/http/client.py", line 1277, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.11/http/client.py", line 1037, in _send_output
self.send(msg)
File "/usr/lib/python3.11/http/client.py", line 975, in send
self.connect()
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 236, in connect
self.sock = self._new_conn()
^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 211, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7f9e674ac2d0>: Failed to establish a new connection: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
urllib3.exceptions.ProxyError: ('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f9e674ac2d0>: Failed to establish a new connection: [Errno 111] Connection refused'))
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 843, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/retry.py", line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/get_node?ip=172.19.216.139 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f9e674ac2d0>: Failed to establish a new connection: [Errno 111] Connection refused')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/starlette/routing.py", line 693, in lifespan
async with self.lifespan_context(app) as maybe_state:
File "/usr/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/node.py", line 14, in lifespan
init()
File "/home/muzhi/tpre-python/src/node.py", line 62, in init
send_ip()
File "/home/muzhi/tpre-python/src/node.py", line 40, in send_ip
id = requests.get(url, timeout=3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 694, in send
raise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/get_node?ip=172.19.216.139 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f9e674ac2d0>: Failed to establish a new connection: [Errno 111] Connection refused')))
ERROR: Application startup failed. Exiting.
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8002 (Press CTRL+C to quit)
INFO: Started reloader process [4188] using StatReload
INFO: Started server process [4194]
INFO: Waiting for application startup.
ERROR: Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 196, in _new_conn
sock = connection.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 85, in create_connection
raise err
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 789, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 495, in _make_request
conn.request(
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 398, in request
self.endheaders()
File "/usr/lib/python3.11/http/client.py", line 1277, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.11/http/client.py", line 1037, in _send_output
self.send(msg)
File "/usr/lib/python3.11/http/client.py", line 975, in send
self.connect()
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 236, in connect
self.sock = self._new_conn()
^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 211, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7f8d8043cf50>: Failed to establish a new connection: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
urllib3.exceptions.ProxyError: ('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f8d8043cf50>: Failed to establish a new connection: [Errno 111] Connection refused'))
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 843, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/retry.py", line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/send_nodes_list?count=2 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f8d8043cf50>: Failed to establish a new connection: [Errno 111] Connection refused')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/starlette/routing.py", line 693, in lifespan
async with self.lifespan_context(app) as maybe_state:
File "/usr/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/client.py", line 32, in lifespan
init()
File "/home/muzhi/tpre-python/src/client.py", line 47, in init
get_node_list(2, server_address) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/client.py", line 407, in get_node_list
response = requests.get(url, timeout=3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 694, in send
raise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/send_nodes_list?count=2 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f8d8043cf50>: Failed to establish a new connection: [Errno 111] Connection refused')))
ERROR: Application startup failed. Exiting.
Init Database Successful
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [3956]
INFO: Stopping reloader process [3954]
INFO: Stopping reloader process [4053]
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: Started reloader process [4449] using StatReload
INFO: Started server process [4452]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)
INFO: Started reloader process [4576] using StatReload
INFO: Started server process [4582]
INFO: Waiting for application startup.
ERROR: Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 196, in _new_conn
sock = connection.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 85, in create_connection
raise err
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 789, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 495, in _make_request
conn.request(
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 398, in request
self.endheaders()
File "/usr/lib/python3.11/http/client.py", line 1277, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.11/http/client.py", line 1037, in _send_output
self.send(msg)
File "/usr/lib/python3.11/http/client.py", line 975, in send
self.connect()
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 236, in connect
self.sock = self._new_conn()
^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 211, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7fde503d84d0>: Failed to establish a new connection: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
urllib3.exceptions.ProxyError: ('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fde503d84d0>: Failed to establish a new connection: [Errno 111] Connection refused'))
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 843, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/retry.py", line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/get_node?ip=172.19.216.139 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fde503d84d0>: Failed to establish a new connection: [Errno 111] Connection refused')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/starlette/routing.py", line 693, in lifespan
async with self.lifespan_context(app) as maybe_state:
File "/usr/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/node.py", line 14, in lifespan
init()
File "/home/muzhi/tpre-python/src/node.py", line 62, in init
send_ip()
File "/home/muzhi/tpre-python/src/node.py", line 40, in send_ip
id = requests.get(url, timeout=3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 694, in send
raise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/get_node?ip=172.19.216.139 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fde503d84d0>: Failed to establish a new connection: [Errno 111] Connection refused')))
ERROR: Application startup failed. Exiting.
INFO: Will watch for changes in these directories: ['/home/muzhi/tpre-python/src']
INFO: Uvicorn running on http://0.0.0.0:8002 (Press CTRL+C to quit)
INFO: Started reloader process [4650] using StatReload
INFO: Started server process [4662]
INFO: Waiting for application startup.
ERROR: Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 196, in _new_conn
sock = connection.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 85, in create_connection
raise err
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 789, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 495, in _make_request
conn.request(
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 398, in request
self.endheaders()
File "/usr/lib/python3.11/http/client.py", line 1277, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.11/http/client.py", line 1037, in _send_output
self.send(msg)
File "/usr/lib/python3.11/http/client.py", line 975, in send
self.connect()
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 236, in connect
self.sock = self._new_conn()
^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connection.py", line 211, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7f4de1060750>: Failed to establish a new connection: [Errno 111] Connection refused
The above exception was the direct cause of the following exception:
urllib3.exceptions.ProxyError: ('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f4de1060750>: Failed to establish a new connection: [Errno 111] Connection refused'))
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 843, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/urllib3/util/retry.py", line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/send_nodes_list?count=2 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f4de1060750>: Failed to establish a new connection: [Errno 111] Connection refused')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/starlette/routing.py", line 693, in lifespan
async with self.lifespan_context(app) as maybe_state:
File "/usr/lib/python3.11/contextlib.py", line 204, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/client.py", line 32, in lifespan
init()
File "/home/muzhi/tpre-python/src/client.py", line 47, in init
get_node_list(2, server_address) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/src/client.py", line 407, in get_node_list
response = requests.get(url, timeout=3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/muzhi/tpre-python/myenv/lib/python3.11/site-packages/requests/adapters.py", line 694, in send
raise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPConnectionPool(host='192.168.252.57', port=10809): Max retries exceeded with url: http://60.204.236.38:8000/server/send_nodes_list?count=2 (Caused by ProxyError('Unable to connect to proxy', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f4de1060750>: Failed to establish a new connection: [Errno 111] Connection refused')))
ERROR: Application startup failed. Exiting.
Init Database Successful
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [4452]
INFO: Stopping reloader process [4449]
INFO: Stopping reloader process [4576]
INFO: Stopping reloader process [4188]
INFO: Stopping reloader process [4650]

2
src/pytest.ini Normal file
View File

@@ -0,0 +1,2 @@
[pytest]
asyncio_default_fixture_loop_scope = function

122
src/server_test1.py Normal file
View File

@@ -0,0 +1,122 @@
import sqlite3
import pytest
from fastapi.testclient import TestClient
from server import app, validate_ip
# 创建 TestClient 实例
client = TestClient(app)
# 准备测试数据库数据
def setup_db():
# 创建数据库并插入测试数据
with sqlite3.connect("server.db") as db:
db.execute("""
CREATE TABLE IF NOT EXISTS nodes (
id INTEGER PRIMARY KEY,
ip TEXT NOT NULL,
last_heartbeat INTEGER NOT NULL
)
""")
db.execute("INSERT INTO nodes (ip, last_heartbeat) VALUES ('192.168.0.1', 1234567890)")
db.execute("INSERT INTO nodes (ip, last_heartbeat) VALUES ('192.168.0.2', 1234567890)")
db.commit()
# 清空数据库
def clear_db():
with sqlite3.connect("server.db") as db:
db.execute("DROP TABLE IF EXISTS nodes") # 删除旧表
db.commit()
# 测试 IP 验证功能
def test_validate_ip():
assert validate_ip("192.168.0.1") is True
assert validate_ip("256.256.256.256") is False
assert validate_ip("::1") is True
assert validate_ip("invalid_ip") is False
# 测试首页路由
def test_home():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Hello, World!"}
# 测试 show_nodes 路由
def test_show_nodes():
setup_db()
response = client.get("/server/show_nodes")
assert response.status_code == 200
data = response.json()
assert len(data) == 2
assert data[0][1] == "192.168.0.1"
assert data[1][1] == "192.168.0.2"
# 测试 get_node 路由
def test_get_node():
# 确保数据库和表的存在
setup_db()
valid_ip = "192.168.0.3"
invalid_ip = "256.256.256.256"
# 测试有效的 IP 地址
response = client.get(f"/server/get_node?ip={valid_ip}")
assert response.status_code == 200
# 测试无效的 IP 地址
response = client.get(f"/server/get_node?ip={invalid_ip}")
assert response.status_code == 400
# 测试 delete_node 路由
def test_delete_node():
setup_db()
valid_ip = "192.168.0.1"
invalid_ip = "192.168.0.255"
response = client.get(f"/server/delete_node?ip={valid_ip}")
assert response.status_code == 200
assert "Node with IP 192.168.0.1 deleted successfully." in response.text
response = client.get(f"/server/delete_node?ip={invalid_ip}")
assert response.status_code == 404
# 测试 heartbeat 路由
def test_receive_heartbeat():
setup_db()
valid_ip = "192.168.0.2"
invalid_ip = "256.256.256.256"
response = client.get(f"/server/heartbeat?ip={valid_ip}")
assert response.status_code == 200
assert response.json() == {"status": "received"}
response = client.get(f"/server/heartbeat?ip={invalid_ip}")
assert response.status_code == 400
assert response.json() == {"message": "invalid ip format"}
# 测试 send_nodes_list 路由
def test_send_nodes_list():
setup_db()
response = client.get("/server/send_nodes_list?count=1")
assert response.status_code == 200
data = response.json()
assert len(data) == 1
assert data[0] == "192.168.0.1"
response = client.get("/server/send_nodes_list?count=2")
assert response.status_code == 200
data = response.json()
assert len(data) == 2
# 运行完测试后清理数据库
@pytest.fixture(autouse=True)
def run_around_tests():
clear_db()
yield
clear_db()

131
src/tpre_test1.py Normal file
View File

@@ -0,0 +1,131 @@
from tpre import (
hash2, hash3, hash4, multiply, g, sm2p256v1,
GenerateKeyPair, Encrypt, Decrypt, GenerateReKey,
Encapsulate, ReEncrypt, DecryptFrags
)
from tpre import MergeCFrag
import random
import unittest
class TestHash2(unittest.TestCase):
def setUp(self):
self.double_G = (
multiply(g, random.randint(0, sm2p256v1.N - 1)),
multiply(g, random.randint(0, sm2p256v1.N - 1)),
)
def test_digest_type(self):
digest = hash2(self.double_G)
self.assertEqual(type(digest), int)
def test_digest_size(self):
digest = hash2(self.double_G)
self.assertLess(digest, sm2p256v1.N)
class TestHash3(unittest.TestCase):
def setUp(self):
self.triple_G = (
multiply(g, random.randint(0, sm2p256v1.N - 1)),
multiply(g, random.randint(0, sm2p256v1.N - 1)),
multiply(g, random.randint(0, sm2p256v1.N - 1)),
)
def test_digest_type(self):
digest = hash3(self.triple_G)
self.assertEqual(type(digest), int)
def test_digest_size(self):
digest = hash3(self.triple_G)
self.assertLess(digest, sm2p256v1.N)
class TestHash4(unittest.TestCase):
def setUp(self):
self.triple_G = (
multiply(g, random.randint(0, sm2p256v1.N - 1)),
multiply(g, random.randint(0, sm2p256v1.N - 1)),
multiply(g, random.randint(0, sm2p256v1.N - 1)),
)
self.Zp = random.randint(0, sm2p256v1.N - 1)
def test_digest_type(self):
digest = hash4(self.triple_G, self.Zp)
self.assertEqual(type(digest), int)
def test_digest_size(self):
digest = hash4(self.triple_G, self.Zp)
self.assertLess(digest, sm2p256v1.N)
# class TestGenerateKeyPair(unittest.TestCase):
# def test_key_pair(self):
# public_key, secret_key = GenerateKeyPair()
# self.assertIsInstance(public_key, tuple)
# self.assertIsInstance(secret_key, int)
# self.assertEqual(len(public_key), 2)
# class TestEncryptDecrypt(unittest.TestCase):
# def setUp(self):
# self.public_key, self.secret_key = GenerateKeyPair()
# self.message = b"Hello, world!"
# def test_encrypt_decrypt(self):
# encrypted_message = Encrypt(self.public_key, self.message)
# decrypted_message = Decrypt(self.secret_key, encrypted_message)
# self.assertEqual(decrypted_message, self.message)
# class TestGenerateReKey(unittest.TestCase):
# def test_generate_rekey(self):
# sk_A = random.randint(0, sm2p256v1.N - 1)
# pk_B, _ = GenerateKeyPair()
# id_tuple = tuple(random.randint(0, sm2p256v1.N - 1) for _ in range(5))
# rekey = GenerateReKey(sk_A, pk_B, 5, 3, id_tuple)
# self.assertIsInstance(rekey, list)
# self.assertEqual(len(rekey), 5)
class TestEncapsulate(unittest.TestCase):
def test_encapsulate(self):
pk_A, _ = GenerateKeyPair()
K, capsule = Encapsulate(pk_A)
self.assertIsInstance(K, int)
self.assertIsInstance(capsule, tuple)
self.assertEqual(len(capsule), 3)
# class TestReEncrypt(unittest.TestCase):
# def test_reencrypt(self):
# sk_A = random.randint(0, sm2p256v1.N - 1)
# pk_B, _ = GenerateKeyPair()
# id_tuple = tuple(random.randint(0, sm2p256v1.N - 1) for _ in range(5))
# rekey = GenerateReKey(sk_A, pk_B, 5, 3, id_tuple)
# pk_A, _ = GenerateKeyPair()
# message = b"Hello, world!"
# encrypted_message = Encrypt(pk_A, message)
# reencrypted_message = ReEncrypt(rekey[0], encrypted_message)
# self.assertIsInstance(reencrypted_message, tuple)
# self.assertEqual(len(reencrypted_message), 2)
# class TestDecryptFrags(unittest.TestCase):
# def test_decrypt_frags(self):
# sk_A = random.randint(0, sm2p256v1.N - 1)
# pk_B, sk_B = GenerateKeyPair()
# id_tuple = tuple(random.randint(0, sm2p256v1.N - 1) for _ in range(5))
# rekey = GenerateReKey(sk_A, pk_B, 5, 3, id_tuple)
# pk_A, _ = GenerateKeyPair()
# message = b"Hello, world!"
# encrypted_message = Encrypt(pk_A, message)
# reencrypted_message = ReEncrypt(rekey[0], encrypted_message)
# cfrags = [reencrypted_message]
# merged_cfrags = MergeCFrag(cfrags)
# decrypted_message = DecryptFrags(sk_B, pk_B, pk_A, merged_cfrags)
# self.assertEqual(decrypted_message, message)
# if __name__ == "__main__":
# unittest.main()