diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2f37b95..b11dcec 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -69,16 +69,27 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.x' + + # Install Python dependencies + - name: Install dependencies + run: | + python -m pip install --upgrade pip - # Run Python Discovery Test - - name: Run Discovery tests + - name: test with pytest working-directory: ./backend/Tests - run: python3 Discovery_Test.py + run: | + pip install pytest pytest-cov + pytest --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html - # Run Python test script - - name: Run API tests - working-directory: ./backend/Tests - run: python3 API_Test.py + # # Run Python Discovery Test + # - name: Run Discovery tests + # working-directory: ./backend/Tests + # run: python3 Discovery_Test.py + + # # Run Python test script + # - name: Run API tests + # working-directory: ./backend/Tests + # run: python3 API_Test.py # Stop backend process after tests - name: Stop backend diff --git a/.gitignore b/.gitignore index 9b135ed..d872665 100644 --- a/.gitignore +++ b/.gitignore @@ -415,4 +415,7 @@ FodyWeavers.xsd *.msi *.msix *.msm -*.msp \ No newline at end of file +*.msp + +# pytest cache files +junit/ \ No newline at end of file diff --git a/backend/Tests/API_Test.py b/backend/Tests/API_Test.py index b10abf9..677c603 100644 --- a/backend/Tests/API_Test.py +++ b/backend/Tests/API_Test.py @@ -1,5 +1,6 @@ import socket import time +import json IP = "127.0.0.1" PORT = 3391 @@ -8,6 +9,8 @@ BUFFER_SIZE = 1024 DISCOVERY_MESSAGE = "DISCOVER_LOCAL_HOMESERVER" +# approve testcase if API worked but context not found +DEFAULT_ALLOW_NOT_FOUND = True class bcolors: HEADER = '\033[95m' @@ -22,36 +25,99 @@ class bcolors: totalRunTime = 0.0 +def test_StartProcess(): + ans = ConnectToAPI('{"Path":"/api/process/start", "Type":"UPDATE", "Data":"Minecraft Server"}') + assert isAnswerSuccess(ans) + + +def test_GetProcesses(): + ans = ConnectToAPI('{"Path":"/api/processes", "Type":"GET", "Data":"Test"}') + assert isAnswerSuccess(ans) + + +def test_GetProcessStatus(): + ans = ConnectToAPI('{"Path":"/api/processes/status", "Type":"GET", "Data":"Test"}') + assert isAnswerSuccess(ans) + + +def test_LastLogs(): + ans = ConnectToAPI('{"Path":"/api/process/lastlogs", "Type":"GET", "Data":"Minecraft Server"}') + assert isAnswerSuccess(ans) + + +def test_LastErrors(): + ans = ConnectToAPI('{"Path":"/api/process/lasterrors", "Type":"GET", "Data":"Minecraft Server"}') + assert isAnswerSuccess(ans) + +def test_InvalidProcesses(): + ans = ConnectToAPI('{"Path":"/api/processes", "Type":"POST", "Data":"Invalid Data"}') + assert not isAnswerSuccess(ans, False) + +def test_InvalidPath(): + ans = ConnectToAPI('{"Path":"/api/fsdfasdf", "Type":"GET", "Data":"Invalid Data"}') + assert not isAnswerSuccess(ans, False) + +def test_InvalidType(): + ans = ConnectToAPI('{"Path":"/api/processes", "Type":"migga", "Data":"Invalid Data"}') + assert not isAnswerSuccess(ans, False) + +def test_StopProcess(): + ans = ConnectToAPI('{"Path":"/api/process/stop", "Type":"UPDATE", "Data":"Test"}') + assert isAnswerSuccess(ans) + +def test_ProcessInput(): + ans = ConnectToAPI('{"Path":"api/process/input", "Type":"POST", "Data":"{\\"ProcessTag\\": \\"Minecraft Server\\", \\"Input\\": \\"say hello API\\"}"}') + assert isAnswerSuccess(ans) + +def test_ProcessStop(): + ans = ConnectToAPI('{"Path":"/api/process/stop", "Type":"UPDATE", "Data":"Minecraft Server"}') + assert isAnswerSuccess(ans) + +def isAnswerSuccess(ans: json, Allow_not_found: bool = DEFAULT_ALLOW_NOT_FOUND) -> bool: + ''' + Getting the API answer and returning if the answer is status code is success +
ans: Server Answer +
Allow_not_found: Allowing the answer to be 404 if the API path found but context wasn't + ''' + # if the answer isn't unknown so the API worked but the data was not found + if (Allow_not_found and ans["StatusCode"] == 404): + if "unknown" not in ans["Data"]: + return True + + return ans["StatusCode"] < 300 + + +''' def main(): global totalRunTime print("Searching for server") print("=====================Starting API Tests=======================") - TestAPI('{"Path":"/api/process/start", "Type":"UPDATE", "Data":"Minecraft Server"}') - TestAPI('{"Path":"/api/processes", "Type":"GET", "Data":"Test"}') - TestAPI('{"Path":"/api/processes/status", "Type":"GET", "Data":"Test"}') - TestAPI('{"Path":"/api/process/lastlogs", "Type":"GET", "Data":"Minecraft Server"}') - TestAPI('{"Path":"/api/process/lasterrors", "Type":"GET", "Data":"Minecraft Server"}') - TestAPI('{"Path":"/api/processes", "Type":"POST", "Data":"Invalid Data"}') - TestAPI('{"Path":"/api/fsdfasdf", "Type":"GET", "Data":"Invalid Data"}') - TestAPI('{"Path":"/api/processes", "Type":"migga", "Data":"Invalid Data"}') - TestAPI('{"Path":"/api/process/stop", "Type":"UPDATE", "Data":"Test"}') + ConnectToAPI('{"Path":"/api/process/start", "Type":"UPDATE", "Data":"Minecraft Server"}') + ConnectToAPI('{"Path":"/api/processes", "Type":"GET", "Data":"Test"}') + ConnectToAPI('{"Path":"/api/processes/status", "Type":"GET", "Data":"Test"}') + ConnectToAPI('{"Path":"/api/process/lastlogs", "Type":"GET", "Data":"Minecraft Server"}') + ConnectToAPI('{"Path":"/api/process/lasterrors", "Type":"GET", "Data":"Minecraft Server"}') + ConnectToAPI('{"Path":"/api/fsdfasdf", "Type":"GET", "Data":"Invalid Data"}') + ConnectToAPI('{"Path":"/api/processes", "Type":"migga", "Data":"Invalid Data"}') + ConnectToAPI('{"Path":"/api/process/stop", "Type":"UPDATE", "Data":"Test"}') time.sleep(5) - TestAPI('{"Path":"api/process/input", "Type":"POST", "Data":"{\\"ProcessTag\\": \\"Minecraft Server\\", \\"Input\\": \\"say hello API\\"}"}') + ConnectToAPI('{"Path":"api/process/input", "Type":"POST", "Data":"{\\"ProcessTag\\": \\"Minecraft Server\\", \\"Input\\": \\"say hello API\\"}"}') time.sleep(10) - TestAPI('{"Path":"/api/process/stop", "Type":"UPDATE", "Data":"Minecraft Server"}') + ConnectToAPI('{"Path":"/api/process/stop", "Type":"UPDATE", "Data":"Minecraft Server"}') print(f"Execution time: {totalRunTime:.4f} seconds") +''' - -def TestAPI(message): +def ConnectToAPI(message): global totalRunTime print ("Testing API with message:", message) try: print("Trying to connect: " + str((IP, PORT)) ) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.settimeout(2) s.connect((IP, PORT)) s.sendall(message.encode()) @@ -63,10 +129,12 @@ def TestAPI(message): print(f"{bcolors.OKCYAN}{bcolors.BOLD} Answer time: {(elapsed_time * 1000):.0f} ms{bcolors.ENDC}") except Exception as err: - print(f"{bcolors.FAIL} Failed to message API: {err} {bcolors.ENDC}") + raise Exception (f"Failed to message API: {err}") print("\n\n") + return json.loads(data.decode()) if __name__ == "__main__": - main() \ No newline at end of file + print("Pls use pytest") + exit(-1) \ No newline at end of file diff --git a/backend/Tests/Discovery_Test.py b/backend/Tests/Discovery_Test.py index 652befd..46c099e 100644 --- a/backend/Tests/Discovery_Test.py +++ b/backend/Tests/Discovery_Test.py @@ -1,5 +1,6 @@ import socket import time +import sys IP = "127.0.0.1" PORT = 3391 @@ -20,14 +21,16 @@ class bcolors: UNDERLINE = '\033[4m' -def main(): - if discover_server(): - print(f"{bcolors.OKGREEN} Server found {IP} {bcolors.ENDC}") +def eprint(*args, **kwargs): + ''' + printing error + ''' + print(*args, file=sys.stderr, **kwargs) - else: - print(f"{bcolors.FAIL} Failed to find server! {bcolors.ENDC}") - exit(1) +def test_Discovery(): + '''Testing if we able to discover the server''' + assert discover_server() def discover_server(timeout=5): global IP @@ -63,11 +66,12 @@ def discover_server(timeout=5): Succeeded = True except socket.timeout: - print("No server response received within timeout.") + raise TimeoutError("No server response received within time window.") finally: client_socket.close() return Succeeded if __name__ == "__main__": - main() \ No newline at end of file + print("Pls run pytest") + exit(-1) \ No newline at end of file