diff --git a/.github/workflows/build_release_artifacts.yml b/.github/workflows/build_release_artifacts.yml index a2695179..3547b5fa 100644 --- a/.github/workflows/build_release_artifacts.yml +++ b/.github/workflows/build_release_artifacts.yml @@ -9,58 +9,57 @@ jobs: name: Download and Build artifacts runs-on: self-hosted steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2 - - uses: actions/setup-python@v4 - with: - python-version: '3.10' + - uses: actions/setup-python@v4 + with: + python-version: "3.10" - - uses: actions/download-artifact@v3 - id: download_artifacts - with: - path: ${{ runner.temp }}\grpc-labview-artifacts + - uses: actions/download-artifact@v3 + id: download_artifacts + with: + path: ${{ runner.temp }}\grpc-labview-artifacts - - name: Stage Artifacts - run: - python ${{runner.workspace}}\grpc-labview\build-it\stage_artifacts.py --downloaded_path ${{ steps.download_artifacts.outputs.download-path }} --staging_path ${{ runner.temp }}\grpc-labview-staged-artifacts - - - if: ${{ !startsWith(github.ref, 'refs/tags/v') }} - name: Build VI Packages for Testing - run: - python ${{runner.workspace}}\grpc-labview\build-it\build.py --target All --pathToBinaries ${{ runner.temp }}\grpc-labview-staged-artifacts\TopLevelDlls + - name: Stage Artifacts + run: python ${{runner.workspace}}\grpc-labview\build-it\stage_artifacts.py --downloaded_path ${{ steps.download_artifacts.outputs.download-path }} --staging_path ${{ runner.temp }}\grpc-labview-staged-artifacts - - if: startsWith(github.ref, 'refs/tags/v') - name: Build VI Packages for release - run: - python ${{runner.workspace}}\grpc-labview\build-it\build.py --libraryVersion ${{github.ref_name}} --target All --pathToBinaries ${{ runner.temp }}\grpc-labview-staged-artifacts\TopLevelDlls + - if: ${{ !startsWith(github.ref, 'refs/tags/v') }} + name: Build VI Packages for Testing + run: python ${{runner.workspace}}\grpc-labview\build-it\build.py --target All --pathToBinaries ${{ runner.temp }}\grpc-labview-staged-artifacts\TopLevelDlls - - if: startsWith(github.ref, 'refs/tags/v') - name: Zip Release Artifacts - run: | - cd "${{runner.workspace}}/grpc-labview/labview source/Builds" - tar -cavf grpc-labview.zip *.vip + - if: startsWith(github.ref, 'refs/tags/v') + name: Build VI Packages for release + run: python ${{runner.workspace}}\grpc-labview\build-it\build.py --libraryVersion ${{github.ref_name}} --target All --pathToBinaries ${{ runner.temp }}\grpc-labview-staged-artifacts\TopLevelDlls - - name: Run CI Tests - run: - python ${{runner.workspace}}\grpc-labview\tests\run_tests.py - - - if: startsWith(github.ref, 'refs/tags/v') - name: Create Draft Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - name: Verison ${{ github.ref }} - draft: true + - if: startsWith(github.ref, 'refs/tags/v') + name: Zip Release Artifacts + run: | + cd "${{runner.workspace}}/grpc-labview/labview source/Builds" + tar -cavf grpc-labview.zip *.vip - - if: startsWith(github.ref, 'refs/tags/v') - name: Upload Release Artifacts to Draft Release - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: + - name: Run CI Tests + run: python ${{runner.workspace}}\grpc-labview\tests\run_tests.py + + - name: Run New Testing Suite's Tests + run: python ${{runner.workspace}}\grpc-labview\tests\New_ATS\pylib\run_tests.py + + - if: startsWith(github.ref, 'refs/tags/v') + name: Create Draft Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + name: Verison ${{ github.ref }} + draft: true + + - if: startsWith(github.ref, 'refs/tags/v') + name: Upload Release Artifacts to Draft Release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ${{runner.workspace}}/grpc-labview/labview source/Builds/grpc-labview.zip asset_name: grpc-labview.zip diff --git a/tests/New_ATS/.gitignore b/tests/New_ATS/.gitignore new file mode 100644 index 00000000..288eadbf --- /dev/null +++ b/tests/New_ATS/.gitignore @@ -0,0 +1,11 @@ +*.lvproj +venv +*.lvlpv +*.aliases +*.pyi +*_pb2_grpc.py +*_pb2.py +*.aliases +*.lvproj +*.lvlps +Generated_server \ No newline at end of file diff --git a/tests/New_ATS/Copy RunServer.vi b/tests/New_ATS/Copy RunServer.vi new file mode 100644 index 00000000..a543c70a Binary files /dev/null and b/tests/New_ATS/Copy RunServer.vi differ diff --git a/tests/New_ATS/Copy StartSync.vi b/tests/New_ATS/Copy StartSync.vi new file mode 100644 index 00000000..10098f66 Binary files /dev/null and b/tests/New_ATS/Copy StartSync.vi differ diff --git a/tests/New_ATS/CreatePythonVirtualEnv.bat b/tests/New_ATS/CreatePythonVirtualEnv.bat new file mode 100644 index 00000000..19392d53 --- /dev/null +++ b/tests/New_ATS/CreatePythonVirtualEnv.bat @@ -0,0 +1,18 @@ +@echo off +pushd %~dp0 +set script_dir=%CD% +popd + +echo Searching for a virtual environment... +echo. + +IF NOT exist %script_dir%\venv ( + echo Virtual Environment not found + echo Creating Virtual Environment at \venv + call python -m venv %script_dir%\venv + echo Installing grpcio-tools into Virtual Environment + call %script_dir%\venv\Scripts\python.exe -m pip install grpcio-tools pytest + echo Successfully Installed Virtual Environment +) ELSE ( + echo Virtual Environment found +) \ No newline at end of file diff --git a/tests/New_ATS/Generate Path from String Array.vi b/tests/New_ATS/Generate Path from String Array.vi new file mode 100644 index 00000000..e65b2802 Binary files /dev/null and b/tests/New_ATS/Generate Path from String Array.vi differ diff --git a/tests/New_ATS/Main_CLIWrapper.vi b/tests/New_ATS/Main_CLIWrapper.vi new file mode 100644 index 00000000..0ddc1dbb Binary files /dev/null and b/tests/New_ATS/Main_CLIWrapper.vi differ diff --git a/tests/New_ATS/RunPythonClient.bat b/tests/New_ATS/RunPythonClient.bat new file mode 100644 index 00000000..0f3fa190 --- /dev/null +++ b/tests/New_ATS/RunPythonClient.bat @@ -0,0 +1,9 @@ +@echo off +set python_client_path=%1 +pushd %~dp0 +set script_dir=%CD% +popd + +echo Running Python Client +echo %script_dir%\venv\Scripts\python.exe -m pytest %python_client_path% -vv +call %script_dir%\venv\Scripts\python.exe -m pytest %python_client_path% -vv \ No newline at end of file diff --git a/tests/New_ATS/RunService_CLIWrapper.vi b/tests/New_ATS/RunService_CLIWrapper.vi new file mode 100644 index 00000000..dce05d45 Binary files /dev/null and b/tests/New_ATS/RunService_CLIWrapper.vi differ diff --git a/tests/New_ATS/Start RunService.vi b/tests/New_ATS/Start RunService.vi new file mode 100644 index 00000000..0e06b1d3 Binary files /dev/null and b/tests/New_ATS/Start RunService.vi differ diff --git a/tests/New_ATS/Stop RunService.vi b/tests/New_ATS/Stop RunService.vi new file mode 100644 index 00000000..e04f7cb4 Binary files /dev/null and b/tests/New_ATS/Stop RunService.vi differ diff --git a/tests/New_ATS/TestMain.vi b/tests/New_ATS/TestMain.vi new file mode 100644 index 00000000..5c8a8fb3 Binary files /dev/null and b/tests/New_ATS/TestMain.vi differ diff --git a/tests/New_ATS/TestProto.vi b/tests/New_ATS/TestProto.vi new file mode 100644 index 00000000..d9344e99 Binary files /dev/null and b/tests/New_ATS/TestProto.vi differ diff --git a/tests/New_ATS/TestResults.ctl b/tests/New_ATS/TestResults.ctl new file mode 100644 index 00000000..5d0ec9af Binary files /dev/null and b/tests/New_ATS/TestResults.ctl differ diff --git a/tests/New_ATS/Tests/all-datatypes-oneof/Impl/Run Service.vi b/tests/New_ATS/Tests/all-datatypes-oneof/Impl/Run Service.vi new file mode 100644 index 00000000..e8769837 Binary files /dev/null and b/tests/New_ATS/Tests/all-datatypes-oneof/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/all-datatypes-oneof/Impl/Start Sync.vi b/tests/New_ATS/Tests/all-datatypes-oneof/Impl/Start Sync.vi new file mode 100644 index 00000000..a30b04c3 Binary files /dev/null and b/tests/New_ATS/Tests/all-datatypes-oneof/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof.proto b/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof.proto new file mode 100644 index 00000000..db541f3c --- /dev/null +++ b/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package Greeter; + +service GreeterService { + rpc GetFeature(req) returns (res) {} +} + +message res { + int32 res_latitude = 1; + oneof res_oneof { + int32 res_int32 = 2; + int64 res_int64 = 3; + uint32 res_uint32 = 4; + uint64 res_uint64 = 5; + sint32 res_sint32 = 6; + sint64 res_sint64 = 7; + fixed32 res_fixed32 = 8; // fixed32 -> uint32 (always encoded using 4 bytes) + fixed64 res_fixed64 = 9; // fixed64 -> uint64 (always encoded using 8 bytes) + sfixed32 res_sfixed32 = 10; // sfixed32 -> int32 (same as above but using two's complement representation) + sfixed64 res_sfixed64 = 11; // sfixed64 -> int64 (,,) + float res_float = 12; + double res_double = 13; + bool res_bool = 14; + string res_string = 15; + bytes res_bytes = 16; + } +} + +message req { + int32 req_latitude = 1; + oneof req_oneof { + int32 req_int32 = 2; + int64 req_int64 = 3; + uint32 req_uint32 = 4; + uint64 req_uint64 = 5; + sint32 req_sint32 = 6; + sint64 req_sint64 = 7; + fixed32 req_fixed32 = 8; // fixed32 -> uint32 (always encoded using 4 bytes) + fixed64 req_fixed64 = 9; // fixed64 -> uint64 (always encoded using 8 bytes) + sfixed32 req_sfixed32 = 10; // sfixed32 -> int32 (same as above but using two's complement representation) + sfixed64 req_sfixed64 = 11; // sfixed64 -> int64 (,,) + float req_float = 12; + double req_double = 13; + bool req_bool = 14; + string req_string = 15; + bytes req_bytes = 16; + } +} \ No newline at end of file diff --git a/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof_client.py b/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof_client.py new file mode 100644 index 00000000..370a5128 --- /dev/null +++ b/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof_client.py @@ -0,0 +1,100 @@ +import grpc +import all_datatypes_oneof_pb2 +import all_datatypes_oneof_pb2_grpc +import json +import pytest +import os + +def get_GetFeature_output(test_input): + + req_latitude = test_input.get('req_latitude') + req_int32 = test_input['req_oneof'].get('req_int32') + req_int64 = test_input['req_oneof'].get('req_int64') + req_uint32 = test_input['req_oneof'].get('req_uint32') + req_uint64 = test_input['req_oneof'].get('req_uint64') + req_sint32 = test_input['req_oneof'].get('req_sint32') + req_sint64 = test_input['req_oneof'].get('req_sint64') + req_fixed32 = test_input['req_oneof'].get('req_fixed32') + req_fixed64 = test_input['req_oneof'].get('req_fixed64') + req_sfixed32 = test_input['req_oneof'].get('req_sfixed32') + req_sfixed64 = test_input['req_oneof'].get('req_sfixed64') + req_float = test_input['req_oneof'].get('req_float') + req_double = test_input['req_oneof'].get('req_double') + req_bool = test_input['req_oneof'].get('req_bool') + req_string = test_input['req_oneof'].get('req_string') + req_bytes = test_input['req_oneof'].get('req_bytes') + if req_bytes is not None: + req_bytes=req_bytes.encode('utf-8') + + with grpc.insecure_channel('localhost:50051') as channel: + stub = all_datatypes_oneof_pb2_grpc.GreeterServiceStub(channel) + request = all_datatypes_oneof_pb2.req( + req_latitude=req_latitude, + req_int32=req_int32, + req_int64=req_int64, + req_uint32=req_uint32, + req_uint64=req_uint64, + req_sint32=req_sint32, + req_sint64=req_sint64, + req_fixed32=req_fixed32, + req_fixed64=req_fixed64, + req_sfixed32=req_sfixed32, + req_sfixed64=req_sfixed64, + req_double=req_double, + req_float=req_float, + req_bool=req_bool, + req_string=req_string, + req_bytes=req_bytes + ) + response = stub.GetFeature(request) + + response_dict = {} + response_dict['res_latitude'] = response.res_latitude + response_dict['res_oneof'] = {} + if(response.HasField('res_int32')): + response_dict['res_oneof']['res_int32'] = response.res_int32 + if(response.HasField('res_int64')): + response_dict['res_oneof']['res_int64'] = response.res_int64 + if(response.HasField('res_uint32')): + response_dict['res_oneof']['res_uint32'] = response.res_uint32 + if(response.HasField('res_uint64')): + response_dict['res_oneof']['res_uint64'] = response.res_uint64 + if(response.HasField('res_sint32')): + response_dict['res_oneof']['res_sint32'] = response.res_sint32 + if(response.HasField('res_sint64')): + response_dict['res_oneof']['res_sint64'] = response.res_sint64 + if(response.HasField('res_fixed32')): + response_dict['res_oneof']['res_fixed32'] = response.res_fixed32 + if(response.HasField('res_fixed64')): + response_dict['res_oneof']['res_fixed64'] = response.res_fixed64 + if(response.HasField('res_sfixed32')): + response_dict['res_oneof']['res_sfixed32'] = response.res_sfixed32 + if(response.HasField('res_sfixed64')): + response_dict['res_oneof']['res_sfixed64'] = response.res_sfixed64 + if(response.HasField('res_float')): + response_dict['res_oneof']['res_float'] = response.res_float + if(response.HasField('res_double')): + response_dict['res_oneof']['res_double'] = response.res_double + if(response.HasField('res_bool')): + response_dict['res_oneof']['res_bool'] = response.res_bool + if(response.HasField('res_string')): + response_dict['res_oneof']['res_string'] = response.res_string + if(response.HasField('res_bytes')): + response_dict['res_oneof']['res_bytes'] = response.res_bytes.decode('utf-8') + return(response_dict) + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +GetFeature_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/GetFeature.json' + +@pytest.mark.parametrize('testcase', read_json(GetFeature_json_file_path)) +def test_SayHello(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_GetFeature_output(test_input) == expected + +if __name__ == "__main__": + print(get_GetFeature_output({"req_latitude":100, "req_oneof":{"req_string":"wow"}})) \ No newline at end of file diff --git a/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof_server.py b/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof_server.py new file mode 100644 index 00000000..d70e3ba2 --- /dev/null +++ b/tests/New_ATS/Tests/all-datatypes-oneof/all-datatypes-oneof_server.py @@ -0,0 +1,51 @@ +from concurrent import futures + +import grpc +import all_datatypes_oneof_pb2 +import all_datatypes_oneof_pb2_grpc + +class GreeterService(all_datatypes_oneof_pb2_grpc.GreeterServiceServicer): + def GetFeature(self, request, context): + response = all_datatypes_oneof_pb2.res(res_latitude=request.req_latitude+1) + if request.HasField('req_int32'): + response.res_int32 = request.req_int32 + 1 + if request.HasField('req_int64'): + response.res_int64 = request.req_int64 + 1 + if request.HasField('req_uint32'): + response.res_uint32 = request.req_uint32 + 1 + if request.HasField('req_uint64'): + response.res_uint64 = request.req_uint64 + 1 + if request.HasField('req_sint32'): + response.res_sint32 = request.req_sint32 + 1 + if request.HasField('req_sint64'): + response.res_sint64 = request.req_sint64 + 1 + if request.HasField('req_fixed32'): + response.res_fixed32 = request.req_fixed32 + 1 + if request.HasField('req_fixed64'): + response.res_fixed64 = request.req_fixed64 + 1 + if request.HasField('req_sfixed32'): + response.res_sfixed32 = request.req_sfixed32 + 1 + if request.HasField('req_sfixed64'): + response.res_sfixed64 = request.req_sfixed64 + 1 + if request.HasField('req_float'): + response.res_float = request.req_float + 1 + if request.HasField('req_double'): + response.res_double = request.req_double + 1 + if request.HasField('req_bool'): + response.res_bool = False if request.req_bool else True + if request.HasField('req_string'): + response.res_string = request.req_string + "_response" + if request.HasField('req_bytes'): + response.res_bytes = request.req_bytes + return response + +def server(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=2)) + all_datatypes_oneof_pb2_grpc.add_GreeterServiceServicer_to_server(GreeterService(), server) + server.add_insecure_port('[::]:50051') + print("gRPC starting") + server.start() + server.wait_for_termination() + +if __name__ == "__main__": + server() \ No newline at end of file diff --git a/tests/New_ATS/Tests/all-datatypes-oneof/testcases/GetFeature.json b/tests/New_ATS/Tests/all-datatypes-oneof/testcases/GetFeature.json new file mode 100644 index 00000000..3363e1b5 --- /dev/null +++ b/tests/New_ATS/Tests/all-datatypes-oneof/testcases/GetFeature.json @@ -0,0 +1,184 @@ +[ + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_int32": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_int32": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_int64": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_int64": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_uint32": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_uint32": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_uint64": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_uint64": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_sint32": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_sint32": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_sint64": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_sint64": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_fixed32": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_fixed32": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_fixed64": 50 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_fixed64": 51 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_float": 50.5 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_float": 51.5 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_double": 50.5 + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_double": 51.5 + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_bool": false + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_bool": true + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_string": "Labview" + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_string": "Labview_response" + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_bytes": "Hello" + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_bytes": "Hello" + } + } + } +] diff --git a/tests/New_ATS/Tests/enum-oneof/Impl/Run Service.vi b/tests/New_ATS/Tests/enum-oneof/Impl/Run Service.vi new file mode 100644 index 00000000..2fa2f432 Binary files /dev/null and b/tests/New_ATS/Tests/enum-oneof/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/enum-oneof/Impl/Start Sync.vi b/tests/New_ATS/Tests/enum-oneof/Impl/Start Sync.vi new file mode 100644 index 00000000..ffd026ef Binary files /dev/null and b/tests/New_ATS/Tests/enum-oneof/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/enum-oneof/enum-oneof.proto b/tests/New_ATS/Tests/enum-oneof/enum-oneof.proto new file mode 100644 index 00000000..f7241f8f --- /dev/null +++ b/tests/New_ATS/Tests/enum-oneof/enum-oneof.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package Greeter; + +service GreeterService { + rpc GetFeature(req) returns (res) {} +} + +enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; +} + +message res { + int32 res_latitude = 1; + oneof res_oneof { + Color res_color = 2; + string res_name = 3; + } +} + +message req { + int32 req_latitude = 1; + oneof req_oneof { + string req_name = 2; + Color req_color = 3; + } +} \ No newline at end of file diff --git a/tests/New_ATS/Tests/enum-oneof/enum-oneof_client.py b/tests/New_ATS/Tests/enum-oneof/enum-oneof_client.py new file mode 100644 index 00000000..6ccfc2be --- /dev/null +++ b/tests/New_ATS/Tests/enum-oneof/enum-oneof_client.py @@ -0,0 +1,35 @@ +import grpc +import enum_oneof_pb2 +import enum_oneof_pb2_grpc +import json +import pytest +import os + +def get_GetFeature_output(test_input): + req_latitude = int(test_input.get('req_latitude')) + req_name = test_input['req_oneof'].get('req_name') + req_color = test_input['req_oneof'].get('req_color') + with grpc.insecure_channel('localhost:50051') as channel: + stub = enum_oneof_pb2_grpc.GreeterServiceStub(channel) + request = enum_oneof_pb2.req(req_latitude=req_latitude, req_name=req_name, req_color=req_color) + response = stub.GetFeature(request) + response_dict = {} + response_dict['res_latitude'] = response.res_latitude + response_dict['res_oneof'] = {} + response_dict['res_oneof']['res_color'] = enum_oneof_pb2.Color(response.res_color) if response.HasField('res_color') else None + response_dict['res_oneof']['res_name'] = response.res_name if response.HasField('res_name') else None + + return(response_dict) + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +GetFeature_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/GetFeature.json' + +@pytest.mark.parametrize('testcase', read_json(GetFeature_json_file_path)) +def test_SayHello(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_GetFeature_output(test_input) == expected \ No newline at end of file diff --git a/tests/New_ATS/Tests/enum-oneof/testcases/GetFeature.json b/tests/New_ATS/Tests/enum-oneof/testcases/GetFeature.json new file mode 100644 index 00000000..c2c13cd6 --- /dev/null +++ b/tests/New_ATS/Tests/enum-oneof/testcases/GetFeature.json @@ -0,0 +1,34 @@ +[ + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_name": "Enum", + "req_color": null + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_name": "Enum_response", + "res_color": null + } + } + }, + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_name": null, + "req_color": "GREEN" + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_name": null, + "res_color": "GREEN" + } + } + } +] diff --git a/tests/New_ATS/Tests/helloworld/Impl/Run Service.vi b/tests/New_ATS/Tests/helloworld/Impl/Run Service.vi new file mode 100644 index 00000000..fc5cac4f Binary files /dev/null and b/tests/New_ATS/Tests/helloworld/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/helloworld/Impl/Start Sync.vi b/tests/New_ATS/Tests/helloworld/Impl/Start Sync.vi new file mode 100644 index 00000000..5ffccf2b Binary files /dev/null and b/tests/New_ATS/Tests/helloworld/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/helloworld/helloworld.proto b/tests/New_ATS/Tests/helloworld/helloworld.proto new file mode 100644 index 00000000..1ebfa48c --- /dev/null +++ b/tests/New_ATS/Tests/helloworld/helloworld.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package helloworld; + +// The greeting service definition. +service GreeterService { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} \ No newline at end of file diff --git a/tests/New_ATS/Tests/helloworld/helloworld_client.py b/tests/New_ATS/Tests/helloworld/helloworld_client.py new file mode 100644 index 00000000..fa70cdc2 --- /dev/null +++ b/tests/New_ATS/Tests/helloworld/helloworld_client.py @@ -0,0 +1,31 @@ +import grpc +import helloworld_pb2 +import helloworld_pb2_grpc +import json +import pytest +import os + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +SayHello_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/SayHello.json' + +def get_SayHello_output(test_input): + name = test_input['name'] + with grpc.insecure_channel('localhost:50051') as channel: + stub = helloworld_pb2_grpc.GreeterServiceStub(channel) + request = helloworld_pb2.HelloRequest(name=name) + response = stub.SayHello(request) + return {"message":response.message} + +@pytest.mark.parametrize('testcase', read_json(SayHello_json_file_path)) +def test_SayHello(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_SayHello_output(test_input) == expected + +if __name__ == "__main__": + res = get_SayHello_output({'name': "Yash"}) + print(res) \ No newline at end of file diff --git a/tests/New_ATS/Tests/helloworld/helloworld_server.py b/tests/New_ATS/Tests/helloworld/helloworld_server.py new file mode 100644 index 00000000..2218e714 --- /dev/null +++ b/tests/New_ATS/Tests/helloworld/helloworld_server.py @@ -0,0 +1,21 @@ +from concurrent import futures + +import grpc +import helloworld_pb2 +import helloworld_pb2_grpc + +class Greeter(helloworld_pb2_grpc.GreeterServiceServicer): + def SayHello(self, request, context): + print("Got request " + str(request)) + return helloworld_pb2.HelloReply(message=f'Hello {request.name}!!!') + +def server(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=2)) + helloworld_pb2_grpc.add_GreeterServiceServicer_to_server(Greeter(), server) + server.add_insecure_port('[::]:50051') + print("gRPC starting") + server.start() + server.wait_for_termination() + +if __name__ == "__main__": + server() \ No newline at end of file diff --git a/tests/New_ATS/Tests/helloworld/testcases/SayHello.json b/tests/New_ATS/Tests/helloworld/testcases/SayHello.json new file mode 100644 index 00000000..7f84af43 --- /dev/null +++ b/tests/New_ATS/Tests/helloworld/testcases/SayHello.json @@ -0,0 +1,18 @@ +[ + { + "input": { "name": "Yash" }, + "output": { "message": "Hello Yash!!!" } + }, + { + "input": { "name": "Sachin" }, + "output": { "message": "Hello Sachin!!!" } + }, + { + "input": { "name": "Shivangi" }, + "output": { "message": "Hello Shivangi!!!" } + }, + { + "input": { "name": "Chakith" }, + "output": { "message": "Hello Chakith!!!" } + } +] diff --git a/tests/New_ATS/Tests/message-oneof/Impl/Run Service.vi b/tests/New_ATS/Tests/message-oneof/Impl/Run Service.vi new file mode 100644 index 00000000..7bbc3bae Binary files /dev/null and b/tests/New_ATS/Tests/message-oneof/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/message-oneof/Impl/Start Sync.vi b/tests/New_ATS/Tests/message-oneof/Impl/Start Sync.vi new file mode 100644 index 00000000..ff837fc2 Binary files /dev/null and b/tests/New_ATS/Tests/message-oneof/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/message-oneof/message-oneof.proto b/tests/New_ATS/Tests/message-oneof/message-oneof.proto new file mode 100644 index 00000000..a1c0ad31 --- /dev/null +++ b/tests/New_ATS/Tests/message-oneof/message-oneof.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package Greeter; + +service GreeterService { + rpc GetFeature(req) returns (res) {} +} + +message req { + int32 req_id = 1; + oneof req_oneof { + string req_name = 2; + MessageA message_a = 3; + } +} + +message res { + int32 res_id = 1; + oneof res_oneof { + string res_name = 2; + MessageA message_a = 3; + } +} + +message MessageA { + string data_a1 = 1; +} diff --git a/tests/New_ATS/Tests/message-oneof/message-oneof_client.py b/tests/New_ATS/Tests/message-oneof/message-oneof_client.py new file mode 100644 index 00000000..a0e2224f --- /dev/null +++ b/tests/New_ATS/Tests/message-oneof/message-oneof_client.py @@ -0,0 +1,40 @@ +import grpc +import message_oneof_pb2 +import message_oneof_pb2_grpc +import json +import pytest +import os + +def get_GetFeature_output(test_input): + req_id = test_input.get('req_id') + req_name = test_input['req_oneof'].get('req_name') + data_a1 = message_a = None + if test_input['req_oneof'].get('message_a'): + data_a1 = test_input['req_oneof']['message_a']['data_a1'] + message_a = message_oneof_pb2.MessageA(data_a1=data_a1) + with grpc.insecure_channel('localhost:50051') as channel: + stub = message_oneof_pb2_grpc.GreeterServiceStub(channel) + request = message_oneof_pb2.req(req_id=req_id, req_name=req_name, message_a=message_a) + response = stub.GetFeature(request) + response_dict = {} + response_dict['res_id'] = response.res_id + response_dict['res_oneof'] = {} + if(response.HasField('res_name')): + response_dict['res_oneof']['res_name'] = response.res_name + if(response.HasField('message_a')): + response_dict['res_oneof']['message_a'] = {} + response_dict['res_oneof']['message_a']['data_a1'] = response.message_a.data_a1 + return(response_dict) + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +GetFeature_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/GetFeature.json' + +@pytest.mark.parametrize('testcase', read_json(GetFeature_json_file_path)) +def test_SayHello(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_GetFeature_output(test_input) == expected diff --git a/tests/New_ATS/Tests/message-oneof/testcases/GetFeature.json b/tests/New_ATS/Tests/message-oneof/testcases/GetFeature.json new file mode 100644 index 00000000..a72e41a5 --- /dev/null +++ b/tests/New_ATS/Tests/message-oneof/testcases/GetFeature.json @@ -0,0 +1,34 @@ +[ + { + "input": { + "req_id": 100, + "req_oneof": { + "req_name": "Yash" + } + }, + "output": { + "res_id": 2, + "res_oneof": { + "res_name": "Yash_response" + } + } + }, + { + "input": { + "req_id": 100, + "req_oneof": { + "message_a": { + "data_a1": "Hello" + } + } + }, + "output": { + "res_id": 3, + "res_oneof": { + "message_a": { + "data_a1": "Hello_nested" + } + } + } + } +] diff --git a/tests/New_ATS/Tests/multiple-field-oneof/Impl/Run Service.vi b/tests/New_ATS/Tests/multiple-field-oneof/Impl/Run Service.vi new file mode 100644 index 00000000..c191dd54 Binary files /dev/null and b/tests/New_ATS/Tests/multiple-field-oneof/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/multiple-field-oneof/Impl/Start Sync.vi b/tests/New_ATS/Tests/multiple-field-oneof/Impl/Start Sync.vi new file mode 100644 index 00000000..a8475041 Binary files /dev/null and b/tests/New_ATS/Tests/multiple-field-oneof/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/multiple-field-oneof/multiple-field-oneof.proto b/tests/New_ATS/Tests/multiple-field-oneof/multiple-field-oneof.proto new file mode 100644 index 00000000..4928a221 --- /dev/null +++ b/tests/New_ATS/Tests/multiple-field-oneof/multiple-field-oneof.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package Greeter; + +service GreeterService { + rpc GetFeature(req) returns (res) {} +} + +message res { + int32 res_latitude = 1; + oneof res_oneof { + string res_name = 2; + int32 res_num = 3; + bool flag = 4; + float price = 5; + } +} + +message req { + int32 req_latitude = 1; + oneof req_oneof { + string req_name = 2; + int32 req_num = 3; + bool flag = 4; + float price = 5; + } +} \ No newline at end of file diff --git a/tests/New_ATS/Tests/multiple-field-oneof/multiple-field-oneof_client.py b/tests/New_ATS/Tests/multiple-field-oneof/multiple-field-oneof_client.py new file mode 100644 index 00000000..cdda6dc7 --- /dev/null +++ b/tests/New_ATS/Tests/multiple-field-oneof/multiple-field-oneof_client.py @@ -0,0 +1,47 @@ +import grpc +import multiple_field_oneof_pb2 +import multiple_field_oneof_pb2_grpc +import json +import pytest +import os + +def get_GetFeature_output(test_input): + req_latitude = test_input.get('req_latitude') + req_name = test_input['req_oneof'].get('req_name') + req_num = test_input['req_oneof'].get('req_num') + flag = test_input['req_oneof'].get('flag') + price = test_input['req_oneof'].get('price') + with grpc.insecure_channel('localhost:50051') as channel: + stub = multiple_field_oneof_pb2_grpc.GreeterServiceStub(channel) + request = multiple_field_oneof_pb2.req(req_latitude=req_latitude, req_name=req_name, req_num=req_num, flag=flag, price=price) + response = stub.GetFeature(request) + response_dict = {} + response_dict['res_latitude'] = response.res_latitude + response_dict['res_oneof'] = {} + if response.HasField('res_num'): + response_dict['res_oneof']['res_num'] = response.res_num + if response.HasField('res_name'): + response_dict['res_oneof']['res_name'] = response.res_name + if response.HasField('flag'): + response_dict['res_oneof']['flag'] = response.flag + if response.HasField('price'): + response_dict['res_oneof']['price'] = response.price + + return(response_dict) + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +GetFeature_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/GetFeature.json' + +@pytest.mark.parametrize('testcase', read_json(GetFeature_json_file_path)) +def test_SayHello(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_GetFeature_output(test_input) == expected + +if __name__ == "__main__": + response = get_GetFeature_output({"req_latitude":100, "req_oneof":{"price":123.3}}) + print(response) \ No newline at end of file diff --git a/tests/New_ATS/Tests/multiple-field-oneof/testcases/GetFeature.json b/tests/New_ATS/Tests/multiple-field-oneof/testcases/GetFeature.json new file mode 100644 index 00000000..5a2b44fe --- /dev/null +++ b/tests/New_ATS/Tests/multiple-field-oneof/testcases/GetFeature.json @@ -0,0 +1,58 @@ +[ + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_name": "Yash" + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_name": "Yash_response" + } + } + }, + { + "input": { + "req_latitude": 470, + "req_oneof": { + "req_num": 120 + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "res_num": 121 + } + } + }, + { + "input": { + "req_latitude": 470, + "req_oneof": { + "flag": false + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "flag": true + } + } + }, + { + "input": { + "req_latitude": 470, + "req_oneof": { + "price": 100.5 + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "price": 101.5 + } + } + } +] diff --git a/tests/New_ATS/Tests/nested-oneof/Impl/Run Service.vi b/tests/New_ATS/Tests/nested-oneof/Impl/Run Service.vi new file mode 100644 index 00000000..349809d1 Binary files /dev/null and b/tests/New_ATS/Tests/nested-oneof/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/nested-oneof/Impl/Start Sync.vi b/tests/New_ATS/Tests/nested-oneof/Impl/Start Sync.vi new file mode 100644 index 00000000..45e6d38d Binary files /dev/null and b/tests/New_ATS/Tests/nested-oneof/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/nested-oneof/nested-oneof.proto b/tests/New_ATS/Tests/nested-oneof/nested-oneof.proto new file mode 100644 index 00000000..d9d0023c --- /dev/null +++ b/tests/New_ATS/Tests/nested-oneof/nested-oneof.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package Greeter; + +service GreeterService { + rpc GetFeature(req) returns (res) {} +} + +message req { + int32 req_id = 1; + oneof req_oneof { + MessageA message_a = 2; + double req_price = 3; + } +} + +message res { + int32 res_id = 1; + oneof res_oneof { + MessageA message_a = 2; + double res_price = 3; + } +} + +message MessageA { + oneof oneof_a { + string data_a1 = 1; + string data_a2 = 2; + } +} diff --git a/tests/New_ATS/Tests/nested-oneof/nested-oneof_client.py b/tests/New_ATS/Tests/nested-oneof/nested-oneof_client.py new file mode 100644 index 00000000..ccd5c08d --- /dev/null +++ b/tests/New_ATS/Tests/nested-oneof/nested-oneof_client.py @@ -0,0 +1,53 @@ +import grpc +import nested_oneof_pb2 +import nested_oneof_pb2_grpc +import json +import pytest +import os + +def get_GetFeature_output(test_input): + req_id = test_input.get('req_id') + req_price = test_input['req_oneof'].get('req_price') + data_a1 = data_a2 = None + if test_input['req_oneof'].get('message_a'): + data_a1 = test_input['req_oneof'].get('message_a').get(data_a1) + data_a2 = test_input['req_oneof'].get('message_a').get(data_a2) + with grpc.insecure_channel('localhost:50051') as channel: + stub = nested_oneof_pb2_grpc.GreeterServiceStub(channel) + request = nested_oneof_pb2.req() + request.req_id = 100 + # request.message_a.data_a1 = "Yash" + request.message_a.data_a2 = "Yash" + # request.req_price = req_price + response = stub.GetFeature(request) + print(response) + response_dict = {} + response_dict['res_id'] = response.res_id + response_dict['res_oneof'] = {} + if response.HasField('res_price'): + response_dict['res_oneof']['res_price'] = response.res_price + if response.HasField('message_a'): + response_dict['res_oneof']['message_a'] = {} + if response.message_a.HasField('data_a1'): + response_dict['res_oneof']['message_a']['data_a1'] = response.message_a.data_a1 + if response.message_a.HasField('data_a2'): + response_dict['res_oneof']['message_a']['data_a2'] = response.message_a.data_a2 + return(response_dict) + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +GetFeature_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/GetFeature.json' + +@pytest.mark.parametrize('testcase', read_json(GetFeature_json_file_path)) +def test_SayHello(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_GetFeature_output(test_input) == expected + +if __name__ == "__main__": + # response = get_GetFeature_output({"req_id":100, "req_oneof":{"req_price":20.06}}) + response = get_GetFeature_output({"req_id":100, "req_oneof":{"message_a":{"data_a1":"Yash"}}}) + print(response) \ No newline at end of file diff --git a/tests/New_ATS/Tests/nested-oneof/testcases/GetFeature.json b/tests/New_ATS/Tests/nested-oneof/testcases/GetFeature.json new file mode 100644 index 00000000..818b3d13 --- /dev/null +++ b/tests/New_ATS/Tests/nested-oneof/testcases/GetFeature.json @@ -0,0 +1,60 @@ +[ + { + "input": { + "req_id": 100, + "req_oneof": { + "req_price": 200.1 + } + }, + "output": { + "res_id": 101, + "res_oneof": { + "res_price": 201.1 + } + } + }, + { + "input": { + "req_id": 470, + "req_oneof": { + "message_a": { + "oneof_a": { + "data_a1": "Yash" + } + } + } + }, + "output": { + "res_id": 471, + "res_oneof": { + "message_a": { + "oneof_a": { + "data_a1": "Yash_response" + } + } + } + } + }, + { + "input": { + "req_id": 560, + "req_oneof": { + "message_a": { + "oneof_a": { + "data_a2": "Ankush" + } + } + } + }, + "output": { + "res_id": 561, + "res_oneof": { + "message_a": { + "oneof_a": { + "data_a2": "Ankush_response" + } + } + } + } + } +] diff --git a/tests/New_ATS/Tests/sibling-oneof/Impl/Run Service.vi b/tests/New_ATS/Tests/sibling-oneof/Impl/Run Service.vi new file mode 100644 index 00000000..7bbc3bae Binary files /dev/null and b/tests/New_ATS/Tests/sibling-oneof/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/sibling-oneof/Impl/Start Sync.vi b/tests/New_ATS/Tests/sibling-oneof/Impl/Start Sync.vi new file mode 100644 index 00000000..04549c79 Binary files /dev/null and b/tests/New_ATS/Tests/sibling-oneof/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/sibling-oneof/sibling-oneof.proto b/tests/New_ATS/Tests/sibling-oneof/sibling-oneof.proto new file mode 100644 index 00000000..5f044a26 --- /dev/null +++ b/tests/New_ATS/Tests/sibling-oneof/sibling-oneof.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package Greeter; + +service GreeterService { + rpc GetFeature(req) returns (res) {} +} + +message res { + int32 res_latitude = 1; + oneof res_oneof { + int32 res_id = 2; + string res_name = 3; + } + MessageA message_a = 4; +} + +message req { + int32 req_latitude = 1; + MessageA message_a = 2; + oneof req_oneof { + int32 req_id = 3; + string req_name = 4; + } +} + +message MessageA { + string data_a1 = 1; +} \ No newline at end of file diff --git a/tests/New_ATS/Tests/sibling-oneof/sibling-oneof_client.py b/tests/New_ATS/Tests/sibling-oneof/sibling-oneof_client.py new file mode 100644 index 00000000..de4dd33a --- /dev/null +++ b/tests/New_ATS/Tests/sibling-oneof/sibling-oneof_client.py @@ -0,0 +1,48 @@ +import grpc +import sibling_oneof_pb2 +import sibling_oneof_pb2_grpc +import json +import pytest +import os + +def get_GetFeature_output(test_input): + req_latitude = test_input.get('req_latitude') + message_a = req_id = req_name = None + if test_input.get('message_a'): + data_a1 = test_input['message_a'].get('data_a1') + message_a = sibling_oneof_pb2.MessageA(data_a1=data_a1) + if test_input.get('req_oneof'): + req_name = test_input['req_oneof'].get('req_name') + req_id = test_input['req_oneof'].get('req_id') + + with grpc.insecure_channel('localhost:50051') as channel: + stub = sibling_oneof_pb2_grpc.GreeterServiceStub(channel) + request = sibling_oneof_pb2.req(req_latitude=req_latitude, req_id=req_id, req_name=req_name, message_a=message_a) + response = stub.GetFeature(request) + response_dict = {} + response_dict['res_latitude'] = response.res_latitude + response_dict['message_a'] = {} + response_dict['message_a']['data_a1'] = response.message_a.data_a1 + response_dict['res_oneof'] = {} + if(response.HasField('res_name')): + response_dict['res_oneof']['res_name'] = response.res_name + if(response.HasField('res_id')): + response_dict['res_oneof']['res_id'] = response.res_id + return(response_dict) + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +GetFeature_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/GetFeature.json' + +@pytest.mark.parametrize('testcase', read_json(GetFeature_json_file_path)) +def test_GetFeature(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_GetFeature_output(test_input) == expected + +if __name__ == "__main__": + # print(get_GetFeature_output({"req_latitude":30, "message_a":{"data_a1":"Labview"}, "req_oneof":{"req_name":"Yash"}})) + print(get_GetFeature_output({"req_latitude":10, "messsage_a":{"data_a1":"Wow"}, "req_oneof":{"req_name":"Yash"}})) \ No newline at end of file diff --git a/tests/New_ATS/Tests/sibling-oneof/sibling-oneof_server.py b/tests/New_ATS/Tests/sibling-oneof/sibling-oneof_server.py new file mode 100644 index 00000000..75bdd29e --- /dev/null +++ b/tests/New_ATS/Tests/sibling-oneof/sibling-oneof_server.py @@ -0,0 +1,26 @@ +from concurrent import futures + +import grpc +import sibling_oneof_pb2 +import sibling_oneof_pb2_grpc + +class GreeterService(sibling_oneof_pb2_grpc.GreeterServiceServicer): + def GetFeature(self, request, context): + response = sibling_oneof_pb2.res(res_latitude=request.req_latitude+1) + if request.HasField('req_id'): + response.res_id = request.req_id + 1 + if request.HasField('req_name'): + response.res_name = request.req_name + "_response" + response.message_a.data_a1 = request.message_a.data_a1 + "_response" + return response + +def server(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=2)) + sibling_oneof_pb2_grpc.add_GreeterServiceServicer_to_server(GreeterService(), server) + server.add_insecure_port('[::]:50051') + print("gRPC starting") + server.start() + server.wait_for_termination() + +if __name__ == "__main__": + server() \ No newline at end of file diff --git a/tests/New_ATS/Tests/sibling-oneof/testcases/GetFeature.json b/tests/New_ATS/Tests/sibling-oneof/testcases/GetFeature.json new file mode 100644 index 00000000..4f192934 --- /dev/null +++ b/tests/New_ATS/Tests/sibling-oneof/testcases/GetFeature.json @@ -0,0 +1,98 @@ +[ + { + "input": { + "req_latitude": 100, + "message_a": { "data_a1": "Yash" } + }, + "output": { + "res_latitude": 101, + "message_a": { "data_a1": "Yash_response" }, + "res_oneof": {} + } + }, + { + "input": { + "req_latitude": 470, + "req_oneof": { + "req_id": 120 + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "res_id": 121 + }, + "message_a": { "data_a1": "_response" } + } + }, + { + "input": { + "req_latitude": 470, + "req_oneof": { + "req_name": "Abcd" + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "res_name": "Abcd_response" + }, + "message_a": { "data_a1": "_response" } + } + }, + { + "input": { + "req_latitude": 470, + "message_a": { + "data_a1": "xyz" + }, + "req_oneof": { + "req_id": 120 + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "res_id": 121 + }, + "message_a": { + "data_a1": "xyz_response" + } + } + }, + { + "input": { + "req_latitude": 470, + "message_a": { + "data_a1": "xyz" + }, + "req_oneof": { + "req_name": "Abcd" + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "res_name": "Abcd_response" + }, + "message_a": { + "data_a1": "xyz_response" + } + } + }, + { + "input": { + "req_latitude": 100, + "message_a": { + "data_a1": "xyz" + } + }, + "output": { + "res_latitude": 101, + "message_a": { + "data_a1": "xyz_response" + }, + "res_oneof": {} + } + } +] diff --git a/tests/New_ATS/Tests/simple-oneof/Impl/Run Service.vi b/tests/New_ATS/Tests/simple-oneof/Impl/Run Service.vi new file mode 100644 index 00000000..a67b3cf5 Binary files /dev/null and b/tests/New_ATS/Tests/simple-oneof/Impl/Run Service.vi differ diff --git a/tests/New_ATS/Tests/simple-oneof/Impl/Start Sync.vi b/tests/New_ATS/Tests/simple-oneof/Impl/Start Sync.vi new file mode 100644 index 00000000..7cbd14d0 Binary files /dev/null and b/tests/New_ATS/Tests/simple-oneof/Impl/Start Sync.vi differ diff --git a/tests/New_ATS/Tests/simple-oneof/simple-oneof.proto b/tests/New_ATS/Tests/simple-oneof/simple-oneof.proto new file mode 100644 index 00000000..bd615689 --- /dev/null +++ b/tests/New_ATS/Tests/simple-oneof/simple-oneof.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package Greeter; + +service GreeterService { + rpc GetFeature(req) returns (res) {} +} + +message res { + int32 res_latitude = 1; + oneof res_oneof { + string res_name = 3; + int32 res_num = 4; + } +} + +message req { + int32 req_latitude = 1; + oneof req_oneof { + string req_name = 3; + int32 req_num = 4; + } +} \ No newline at end of file diff --git a/tests/New_ATS/Tests/simple-oneof/simple-oneof_client.py b/tests/New_ATS/Tests/simple-oneof/simple-oneof_client.py new file mode 100644 index 00000000..13dbc09f --- /dev/null +++ b/tests/New_ATS/Tests/simple-oneof/simple-oneof_client.py @@ -0,0 +1,36 @@ +import grpc +import simple_oneof_pb2 +import simple_oneof_pb2_grpc +import json +import pytest +import os + +def get_GetFeature_output(test_input): + req_latitude = int(test_input.get('req_latitude')) + req_name = test_input['req_oneof'].get('req_name') + req_num = test_input['req_oneof'].get('req_num') + with grpc.insecure_channel('localhost:50051') as channel: + stub = simple_oneof_pb2_grpc.GreeterServiceStub(channel) + request = simple_oneof_pb2.req(req_latitude=req_latitude, req_name=req_name, req_num=req_num) + response = stub.GetFeature(request) + response_dict = {} + response_dict['res_latitude'] = response.res_latitude + response_dict['res_oneof'] = {} + if response.HasField('res_num'): + response_dict['res_oneof']['res_num'] = response.res_num + if response.HasField('res_name'): + response_dict['res_oneof']['res_name'] = response.res_name + return(response_dict) + +def read_json(filepath): + with open(filepath, 'r') as file: + test_data = json.load(file) + return test_data + +GetFeature_json_file_path = f'{os.path.dirname(os.path.abspath(__file__))}/testcases/GetFeature.json' + +@pytest.mark.parametrize('testcase', read_json(GetFeature_json_file_path)) +def test_SayHello(testcase): + test_input = testcase['input'] + expected = testcase['output'] + assert get_GetFeature_output(test_input) == expected \ No newline at end of file diff --git a/tests/New_ATS/Tests/simple-oneof/testcases/GetFeature.json b/tests/New_ATS/Tests/simple-oneof/testcases/GetFeature.json new file mode 100644 index 00000000..ad52ed42 --- /dev/null +++ b/tests/New_ATS/Tests/simple-oneof/testcases/GetFeature.json @@ -0,0 +1,30 @@ +[ + { + "input": { + "req_latitude": 100, + "req_oneof": { + "req_name": "Yash" + } + }, + "output": { + "res_latitude": 101, + "res_oneof": { + "res_name": "Yash_response" + } + } + }, + { + "input": { + "req_latitude": 470, + "req_oneof": { + "req_num": 120 + } + }, + "output": { + "res_latitude": 471, + "res_oneof": { + "res_num": 121 + } + } + } +] diff --git a/tests/New_ATS/pylib/Logger.py b/tests/New_ATS/pylib/Logger.py new file mode 100644 index 00000000..15d339ad --- /dev/null +++ b/tests/New_ATS/pylib/Logger.py @@ -0,0 +1,39 @@ +import logging +import datetime +import os +import random +class LoggerImpl: + def __init__(self): + self.logger = logging.getLogger('SignatureChecker') + self.logger.setLevel(logging.DEBUG) + # create a file handler which logs even DEBUG messages + pyDir = os.path.dirname(os.path.realpath(__file__))+ "/logs" + try: + os.mkdir(pyDir) + except Exception: + pass + random.seed(); + self.logFileName = os.path.join(pyDir, 'gRPC_TestSuite_Log_%s.txt' %(datetime.datetime.now().strftime("%Y-%B-%d_%H-%M-%S_"+str(random.randint(10000, 99999))))) + fh = logging.FileHandler(self.logFileName, mode='w') + fh.setLevel(logging.DEBUG) + # create console handler with a higher level logger + ch = logging.StreamHandler() + ch.setLevel(logging.INFO) + # add the handlers to the loggers + self.logger.addHandler(fh) + self.logger.addHandler(ch) + def GetLogger(self): + return self.logger + def GetLogFileName(self): + return os.path.abspath(self.logFileName) + +class Logger: + _loggerImpl = LoggerImpl() + def GetLogger(self): + return self._loggerImpl.GetLogger() + def GetLogFileName(self): + return self._loggerImpl.GetLogFileName() +def GetLogger(): + return Logger().GetLogger() +def GetLogFileName(): + return Logger().GetLogFileName() \ No newline at end of file diff --git a/tests/New_ATS/pylib/run_tests.py b/tests/New_ATS/pylib/run_tests.py new file mode 100644 index 00000000..e1b985bc --- /dev/null +++ b/tests/New_ATS/pylib/run_tests.py @@ -0,0 +1,142 @@ +import json +import pathlib +import shutil +import subprocess +import os + +def check_for_pre_requisites(test_config): + # check if LabVIEW CLI is installed + if not test_config["lvcli_path"].exists(): + raise Exception(f'LabVIEW CLI is not installed at {test_config["lvcli_path"]}') + +def generate_server(test_config): + # 1. Delete the Generated_server folder. TODO: Take a boolean in the config to say whether the build should be a clean build + if test_config['generated_server'].exists(): + shutil.rmtree(test_config['generated_server']) + + # 2. Generate the server + # todo: call the LabVIEW VI from LabVIEW CLI + main_wrapper_vi_path = test_config['test_suite_folder'] / 'Main_CLIWrapper.vi' + # subprocess.run([f'{labviewCLI_path} -OperationName RunVI', + CLI_command = ' '.join([ + f'{test_config["lvcli_path"]}', + f'-LabVIEWPath "{test_config["labview_path"]}"', + '-OperationName RunVI', + f"-VIPath {main_wrapper_vi_path}", + f"{test_config['proto_path']}", + f"{test_config['project_path']}", + f"{test_config['gen_type']}"]) + subprocess.run(CLI_command) + + +def run_test(test_config): + # 1. Check for pre_requisites + check_for_pre_requisites(test_config) + + # 2. Generate the server + generate_server(test_config) + + # 3. Copy the 'Run Service.vi' from the Impl folder to the Generated_server folder + run_service_impl_path = test_config['impl'] / 'Run Service.vi' + run_service_gen_path = test_config['generated_server'] / 'Run Service.vi' + shutil.copyfile(run_service_impl_path, run_service_gen_path) + + # 4. Copy the 'Start Sync.vi' from the Impl folder to the "Generated_server/RPC Service/GreeterService/Server API" folder + start_sync_impl_path = test_config['impl'] / 'Start Sync.vi' + start_sync_gen_path = test_config['generated_server'] / 'RPC Service' / 'GreeterService' / 'Server API' / 'Start Sync.vi' + shutil.copyfile(start_sync_impl_path, start_sync_gen_path) + + # 5. Quit LabVIEW if it is running + subprocess.run(['taskkill', '/f', '/im', 'labview.exe']) + + # 6. Start Run Service.vi from command prompt by launching labview.exe form lv_folder with the following arguments: + # this must be non-blocking + # subprocess.Popen([str(labview_path), str(test_config['generated_server'] / 'Run Service.vi')]) # shoud be non-blocking + # TODO Need to add support for passing multiple protofiles + runservice_wrapper_vi_path = test_config['test_suite_folder'] / 'RunService_CLIWrapper.vi' + CLI_command = ' '.join([ + f'{test_config["lvcli_path"]}', + f'-LabVIEWPath "{test_config["labview_path"]}"', + '-OperationName RunVI', + f"-VIPath {runservice_wrapper_vi_path}", + f"{test_config['test_folder']}"]) + + # TODO Check whether labviewCLI is installed or not before running the command + subprocess.run(CLI_command) + + # 7. Create python virtual environment + run_command = ' '.join([ + str(test_config['test_suite_folder'] / 'CreatePythonVirtualEnv.bat') + ]) + subprocess.run(run_command) + + # 7. Generate python grpc classes + generate_command = ' '.join([ + "python -m grpc_tools.protoc", + f"--proto_path={test_config['test_folder']}", + f"--python_out={test_config['test_folder']}", + f"--pyi_out={test_config['test_folder']}", + f"--grpc_python_out={test_config['test_folder']}", + f"{test_config['test_name']}.proto" + ]) + subprocess.run(generate_command) + + # 8. Call the TestServer() from test_folder/test_name_client.py and get the return value + client_py_path = test_config['test_folder'] / str(test_config['test_name'] + '_client.py') + run_command = ' '.join([ + str(test_config['test_suite_folder'] / 'RunPythonClient.bat'), + str(client_py_path)]) + return_value = subprocess.run(run_command) + + if return_value.returncode == 0: + print(f'{test_config["test_name"]} passed') + else: + print(f'{test_config["test_name"]} failed') + + # 8. Quit LabVIEW if it is running + subprocess.run(['taskkill', '/f', '/im', 'labview.exe']) + + # 9. Delete python grpc generated files + # for filename in os.listdir(test_config['test_folder']): + # if "pb2" in filename: + # os.remove(test_config['test_folder'] / filename) + + +# Desc: Run the tests in the testlist.json file +def main(): + # read the list of tests from testlist.json + test_list_json_path = pathlib.Path(__file__).parent.absolute() / 'testlist.json' + with open(test_list_json_path) as f: + tests = json.load(f) + for test in tests: + test_config = {} + gen_type = test["gen_type"].strip() + labview_version = test["labview_version"].strip() + labview_bitness = test["labview_bitness"].strip() + # globals + program_files_w_bitness = 'C:\\Program Files' + if labview_bitness == '32': + program_files_w_bitness += ' (x86)' + test_config['lv_folder'] = pathlib.Path(program_files_w_bitness + f'\\National Instruments\\LabVIEW {labview_version}') + test_config['labview_path'] = test_config['lv_folder'] / 'labview.exe' + test_config['lvcli_path'] = test_config['lv_folder'].parent.absolute() / 'Shared' / 'LabVIEW CLI' / 'LabVIEWCLI.exe' + test_config['test_suite_pylib_folder'] = pathlib.Path(__file__).parent.absolute() + test_config['test_suite_folder'] = test_config['test_suite_pylib_folder'].parent.absolute() + test_config['tests_folder'] = test_config['test_suite_folder'] / 'Tests' + tests_folder = test_config['tests_folder'] + # locals + for test_name in test['name']: + print(f'\nRunning test for "{test_name}"...') + test_config['test_name'] = test_name.strip() + test_config['test_folder'] = tests_folder / test_name + test_config['proto_path'] = test_config['test_folder'] / str(test_name + '.proto') + test_config['project_path'] = test_config['test_folder'] / str(test_name + '.lvproj') + generated_server_path = test_config['test_folder'] / 'Generated_server' + test_config['generated_server'] = generated_server_path + test_config['impl'] = test_config['test_folder'] / 'Impl' + test_config['gen_type'] = gen_type + run_test(test_config) + + +if __name__ == '__main__': + main() diff --git a/tests/New_ATS/pylib/stash_server_impl.py b/tests/New_ATS/pylib/stash_server_impl.py new file mode 100644 index 00000000..5240865b --- /dev/null +++ b/tests/New_ATS/pylib/stash_server_impl.py @@ -0,0 +1,51 @@ +import json +import pathlib +import shutil +import subprocess +import os +import sys + +def backup_server_impl(test_folder_path): + # check if the test_folder_path exists + if not os.path.exists(test_folder_path): + print(f'{test_folder_path} does not exist') + return + + # check if the test_folder_path is a directory + if not os.path.isdir(test_folder_path): + print(f'{test_folder_path} is not a directory') + return + + # check if the test_folder_path has a subfolder named Impl + impl_path = os.path.join(test_folder_path, 'Impl') + if not os.path.exists(impl_path): + os.mkdir(impl_path) + + # copy the contents of the Generated_server folder to the Impl folder + generated_server_path = os.path.join(test_folder_path, 'Generated_server') + if not os.path.exists(generated_server_path): + print(f'{generated_server_path} does not exist. Regenerate the server to backup') + return + + run_service_path = os.path.join(generated_server_path, 'Run Service.vi') + if not os.path.exists(run_service_path): + print(f'{run_service_path} does not exist. Regenerate the server to backup') + return + + # copy the run_service.vi at run_service_path to impl/run_service.vi + shutil.copyfile(run_service_path, os.path.join(impl_path, 'Run Service.vi')) + + start_sync_path = os.path.join(generated_server_path, 'RPC Service', 'GreeterService', 'Server API', 'Start Sync.vi') + if not os.path.exists(start_sync_path): + print(f'{start_sync_path} does not exist. Regenerate the server to backup') + return + + # copy the start_sync.vi at start_sync_path to impl/start_sync.vi + shutil.copyfile(start_sync_path, os.path.join(impl_path, 'Start Sync.vi')) + +if __name__ == '__main__': + # check if there are zero arguments + if len(sys.argv) < 2: + print("Usage stash_server_impl.py ") + exit(1) + backup_server_impl(os.path.join(os.getcwd(), sys.argv[1])) diff --git a/tests/New_ATS/pylib/test.py b/tests/New_ATS/pylib/test.py new file mode 100644 index 00000000..50631015 --- /dev/null +++ b/tests/New_ATS/pylib/test.py @@ -0,0 +1,3 @@ +from Logger import GetLogger + +GetLogger().info("Hello world") \ No newline at end of file diff --git a/tests/New_ATS/pylib/testlist.json b/tests/New_ATS/pylib/testlist.json new file mode 100644 index 00000000..28559dc4 --- /dev/null +++ b/tests/New_ATS/pylib/testlist.json @@ -0,0 +1,8 @@ +[ + { + "name": [], + "gen_type": "0", + "labview_version": "2019", + "labview_bitness": "32" + } +]