diff --git a/myenv/bin/Activate.ps1 b/myenv/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/myenv/bin/Activate.ps1 @@ -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" diff --git a/myenv/bin/activate b/myenv/bin/activate new file mode 100644 index 0000000..4b64ad8 --- /dev/null +++ b/myenv/bin/activate @@ -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 diff --git a/myenv/bin/activate.csh b/myenv/bin/activate.csh new file mode 100644 index 0000000..4418a94 --- /dev/null +++ b/myenv/bin/activate.csh @@ -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 . +# Ported to Python 3.3 venv by Andrew Svetlov + +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 diff --git a/myenv/bin/activate.fish b/myenv/bin/activate.fish new file mode 100644 index 0000000..3afe220 --- /dev/null +++ b/myenv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /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 diff --git a/myenv/bin/fastapi b/myenv/bin/fastapi new file mode 100755 index 0000000..32db0da --- /dev/null +++ b/myenv/bin/fastapi @@ -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()) diff --git a/myenv/bin/httpx b/myenv/bin/httpx new file mode 100755 index 0000000..d35faf0 --- /dev/null +++ b/myenv/bin/httpx @@ -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()) diff --git a/myenv/bin/maturin b/myenv/bin/maturin new file mode 100755 index 0000000..c913b85 Binary files /dev/null and b/myenv/bin/maturin differ diff --git a/myenv/bin/normalizer b/myenv/bin/normalizer new file mode 100755 index 0000000..993c4ba --- /dev/null +++ b/myenv/bin/normalizer @@ -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()) diff --git a/myenv/bin/pip b/myenv/bin/pip new file mode 100755 index 0000000..1e80eaa --- /dev/null +++ b/myenv/bin/pip @@ -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()) diff --git a/myenv/bin/pip3 b/myenv/bin/pip3 new file mode 100755 index 0000000..1e80eaa --- /dev/null +++ b/myenv/bin/pip3 @@ -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()) diff --git a/myenv/bin/pip3.11 b/myenv/bin/pip3.11 new file mode 100755 index 0000000..1e80eaa --- /dev/null +++ b/myenv/bin/pip3.11 @@ -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()) diff --git a/myenv/bin/py.test b/myenv/bin/py.test new file mode 100755 index 0000000..b592e58 --- /dev/null +++ b/myenv/bin/py.test @@ -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()) diff --git a/myenv/bin/pytest b/myenv/bin/pytest new file mode 100755 index 0000000..b592e58 --- /dev/null +++ b/myenv/bin/pytest @@ -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()) diff --git a/myenv/bin/python b/myenv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/myenv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/myenv/bin/python3 b/myenv/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/myenv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/myenv/bin/python3.11 b/myenv/bin/python3.11 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/myenv/bin/python3.11 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/myenv/bin/uvicorn b/myenv/bin/uvicorn new file mode 100755 index 0000000..bc22bc3 --- /dev/null +++ b/myenv/bin/uvicorn @@ -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()) diff --git a/myenv/lib64 b/myenv/lib64 new file mode 120000 index 0000000..7951405 --- /dev/null +++ b/myenv/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/myenv/pyvenv.cfg b/myenv/pyvenv.cfg new file mode 100644 index 0000000..14d493d --- /dev/null +++ b/myenv/pyvenv.cfg @@ -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 diff --git a/nohup.out b/nohup.out new file mode 100644 index 0000000..6e50450 --- /dev/null +++ b/nohup.out @@ -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 diff --git a/src/node_test.log b/src/node_test.log new file mode 100644 index 0000000..fad9afe --- /dev/null +++ b/src/node_test.log @@ -0,0 +1 @@ +DEBUG:asyncio:Using selector: EpollSelector diff --git a/src/node_test1.py b/src/node_test1.py new file mode 100644 index 0000000..66a7a47 --- /dev/null +++ b/src/node_test1.py @@ -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() diff --git a/src/node_test2.py b/src/node_test2.py new file mode 100644 index 0000000..7e01de8 --- /dev/null +++ b/src/node_test2.py @@ -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)即可看到测试代码返回的节点 diff --git a/src/node_test3.py b/src/node_test3.py new file mode 100644 index 0000000..a92d921 --- /dev/null +++ b/src/node_test3.py @@ -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() diff --git a/src/node_test5.py b/src/node_test5.py new file mode 100644 index 0000000..3432bfe --- /dev/null +++ b/src/node_test5.py @@ -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"} \ No newline at end of file diff --git a/src/nohup.out b/src/nohup.out new file mode 100644 index 0000000..84f6a7a --- /dev/null +++ b/src/nohup.out @@ -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: : 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(': 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(': 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(': 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: : 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(': 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(': 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(': 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: : 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(': 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(': 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(': 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: : 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(': 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(': 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(': 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] diff --git a/src/pytest.ini b/src/pytest.ini new file mode 100644 index 0000000..6a7d170 --- /dev/null +++ b/src/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +asyncio_default_fixture_loop_scope = function \ No newline at end of file diff --git a/src/server_test1.py b/src/server_test1.py new file mode 100644 index 0000000..a78a93f --- /dev/null +++ b/src/server_test1.py @@ -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() diff --git a/src/tpre_test1.py b/src/tpre_test1.py new file mode 100644 index 0000000..fce532a --- /dev/null +++ b/src/tpre_test1.py @@ -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() \ No newline at end of file