Skip to content

Commit

Permalink
Added cmake tests that prevents people from changing message datatypes (
Browse files Browse the repository at this point in the history
#337)

* Added cmake tests for Message Structures

* Updated github workflows

* Corrected wrong meesage_metadata path

* Checking github workflows by changing structures

* Reverting changes

* Added MessageElementMetadata

* Updated Building.md

* Added exported function checks

* Added functionality to throw warning if user adds a new exported function

* Updated exported function list

* Renamed some variables and replaced os.path with pathlib

* Fixed pathlib error

* Probably fixed weird subprocess bug

* Added python virtual environment

* Fixed /bin/sh bug

* Updated github windows workflows to print CMakeTests logs

* Removed extra new lines from logs

* Modified github workflows to print CMakeTest logs

* Updated linux print logs to exit instead of throwing error

* Updated folder in linux workflows name

* Corrected formatting for linux
  • Loading branch information
yash-ni authored Jan 18, 2024
1 parent 63b9ff8 commit a5226b7
Show file tree
Hide file tree
Showing 14 changed files with 1,203 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/build_on_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ jobs:
shell: bash
run: make -j 16

- if: ${{always() }}
name: Print CMakeTests logs
run: |
folder="${{runner.workspace}}/grpc-labview/tests/CMakeTests/logs/"
# Check if the folder exists
if [ ! -d "$folder" ]; then
echo "CMakeTests log folder (grpc-labview/tests/CmakeTests/logs) does not exist."
echo "Exiting the script."
exit
fi
# Change to the folder
cd "$folder" || exit
# Iterate through files and print their contents
for file in *; do
if [ -f "$file" ]; then
cat "$file"
echo
fi
done
- name: Tar Build Artifacts
run: >-
tar -czvf liblabview-grpc-server-linux.tar.gz -C ${{runner.workspace}}/cmake/build
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/build_on_rt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,29 @@ jobs:
message("::error::${error_message}")
message(FATAL_ERROR "Build failed")
endif()
- if: ${{always() }}
name: Print CMakeTests logs
run: |
folder="${{runner.workspace}}/grpc-labview/tests/CMakeTests/logs/"
# Check if the folder exists
if [ ! -d "$folder" ]; then
echo "CMakeTests log folder (grpc-labview/tests/CmakeTests/logs) does not exist."
echo "Exiting the script."
exit
fi
# Change to the folder
cd "$folder" || exit
# Iterate through files and print their contents
for file in *; do
if [ -f "$file" ]; then
cat "$file"
echo
fi
done
- name: Tar Build Artifacts
run: >-
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/windows_x64_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@ jobs:
working-directory: ${{runner.workspace}}\grpc-labview\build
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config ${{env.BUILD_TYPE}} -j 16

- if: ${{ always() }}
name: Print CMakeTests logs
run: |
$directory = "${{runner.workspace}}/grpc-labview/tests/CMakeTests/logs"
# Check if the folder exists
if (Test-Path $directory -PathType Container) {
# Recursively iterate through all files in subfolders
Get-ChildItem -Path $directory -File -Recurse | Group-Object Directory | ForEach-Object {
$subfolderName = $_.Name
Write-Host "Folder: $subfolderName"
$_.Group | ForEach-Object {
$file = $_
# Print the content of the file
Get-Content $file.FullName
Write-Host ""
}
Write-Host ""
}
} else {
Write-Host "CMakeTests log folder (grpc-labview/tests/CmakeTests/logs) does not exist."
}
- name: Tar Build Artifacts
run: >-
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/windows_x86_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,32 @@ jobs:
working-directory: ${{runner.workspace}}\grpc-labview\build
run: cmake --build . --config ${{env.BUILD_TYPE}} -j 16

- if: ${{ always() }}
name: Print CMakeTests logs
run: |
$directory = "${{runner.workspace}}/grpc-labview/tests/CMakeTests/logs"
# Check if the folder exists
if (Test-Path $directory -PathType Container) {
# Recursively iterate through all files in subfolders
Get-ChildItem -Path $directory -File -Recurse | Group-Object Directory | ForEach-Object {
$subfolderName = $_.Name
Write-Host "Folder: $subfolderName"
$_.Group | ForEach-Object {
$file = $_
# Print the content of the file
Get-Content $file.FullName
Write-Host ""
}
Write-Host ""
}
} else {
Write-Host "CMakeTests log folder (grpc-labview/tests/CmakeTests/logs) does not exist."
}
- name: Tar Build Artifacts
run: >-
tar -czvf labview-grpc-server-windows-x86.tar.gz -C ${{runner.workspace}}\grpc-labview\build\Release
Expand Down
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ include_directories("${CMAKE_CURRENT_BINARY_DIR}" "./src" "./third_party/grpc" "
#----------------------------------------------------------------------
# LabVIEW support for grpc and protobuf
#----------------------------------------------------------------------

add_custom_target(Detect_Compatibility_Breaks
COMMAND ${CMAKE_COMMAND} -E echo "Detecting backward compatibility breakage ..."
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeTests/run_test.py
RESULT_VARIABLE shell_command_result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

add_library(labview_grpc_server SHARED
src/any_support.cc
src/cluster_copier.cc
Expand Down Expand Up @@ -186,3 +194,9 @@ target_link_libraries(test_server
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})

add_dependencies(labview_grpc_server Detect_Compatibility_Breaks)
add_dependencies(labview_grpc_generator Detect_Compatibility_Breaks)
add_dependencies(test_client Detect_Compatibility_Breaks)
add_dependencies(test_server Detect_Compatibility_Breaks)
add_dependencies(example_client Detect_Compatibility_Breaks)
1 change: 1 addition & 0 deletions docs/Building.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ To prepare for cmake + Microsoft Visual C++ compiler build
- Install Visual Studio 2019 (Visual C++ compiler will be used).
- Install [Git](https://git-scm.com/).
- Install [CMake](https://cmake.org/download/).
- Install [Python 3.7 or Higher](https://www.python.org/downloads/).


#### Building 64-bit
Expand Down
3 changes: 3 additions & 0 deletions tests/CMakeTests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exported_function_list.json
venv
logs/*
95 changes: 95 additions & 0 deletions tests/CMakeTests/run_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import subprocess
import sys
import os
from pathlib import Path
import datetime

# Setting global variables
if os.name == 'nt': # windows
venv_command = "python -m venv venv"
activate_script = "venv\\Scripts\\activate"
activate_command = f"call {activate_script}"
else:
venv_command = "python -m venv venv"
activate_script = "venv/bin/activate"
activate_command = f". {activate_script}"

def create_virtual_environment():
venv_folder_path = Path(__file__).parent / "venv"
if not venv_folder_path.exists():
subprocess.run(venv_command, shell=True)

def install_dependencies():
subprocess.run(f"{activate_command} && pip install pytest", shell=True)

def run_tests():

current_time = datetime.datetime.now().strftime("%d-%m-%Y_%H-%M-%S")
log_file_path = Path(__file__).parent / "logs" / f"CMakeTests_log_{current_time}.txt"
logs_folder_path = Path(__file__).parent / "logs"

if not logs_folder_path.exists():
logs_folder_path.mkdir(parents=True)

message_structures_test_path = Path(__file__).parent / "tests" / "message_structure_test.py"
exported_functions_test_path = Path(__file__).parent / "tests" / "exported_functions_test.py"
exported_functions_addition_test_path = Path(__file__).parent / "tests" / "exported_functions_addition_test.py"

result_message_structure = subprocess.run(f"{activate_command} && python -m pytest {str(message_structures_test_path)} -vv", shell=True, stdout=subprocess.PIPE)
result_message_structure_output = result_message_structure.stdout.decode('utf-8')
print(result_message_structure_output)

with open(log_file_path, "a") as log_file:
log_file.write("-----------------------------------------------------------------------")
log_file.write("\n----------------------- Message structure tests -----------------------")
log_file.write("\n-----------------------------------------------------------------------\n\n")
if os.name == 'nt':
log_file.write(result_message_structure_output.replace("\n", ""))
else:
log_file.write(result_message_structure_output)
if result_message_structure.returncode != 0:
result_message_structure = subprocess.run(["python", "-m", "pytest", str(message_structures_test_path), "-vv"])
if result_message_structure.returncode != 0:
print(f"Message structural tests failed with exit code {result_message_structure.returncode}. Exiting.")
sys.exit(result_message_structure.returncode)

result_exported_functions = subprocess.run(f"{activate_command} && python -m pytest {str(exported_functions_test_path)} -vv", shell=True,stdout=subprocess.PIPE)
result_exported_functions_output = result_exported_functions.stdout.decode('utf-8')
print(result_exported_functions_output)
with open(log_file_path, "a") as log_file:
log_file.write("\n------------------------------------------------------------------------")
log_file.write("\n----------------------- Exported functions tests -----------------------")
log_file.write("\n------------------------------------------------------------------------\n\n")
if os.name == 'nt':
log_file.write(result_exported_functions_output.replace("\n", ""))
else:
log_file.write(result_exported_functions_output)
if result_exported_functions.returncode != 0:
result_exported_functions = subprocess.run(["python", "-m", "pytest", str(exported_functions_test_path), "-vv"])
if result_exported_functions.returncode != 0:
print(f"Function structural tests failed with exit code {result_exported_functions.returncode}. Exiting.")
sys.exit(result_exported_functions.returncode)

result_exported_functions_addition = subprocess.run(f"{activate_command} && python {str(exported_functions_addition_test_path)}", shell=True, stdout=subprocess.PIPE)
result_exported_functions_addition_output = result_exported_functions_addition.stdout.decode('utf-8')
print(result_exported_functions_addition_output)
with open(log_file_path, "a") as log_file:
log_file.write("\n------------------------------------------------------------------------")
log_file.write("\n------------------- Exported function addition tests -------------------")
log_file.write("\n------------------------------------------------------------------------\n\n")
if os.name == 'nt':
log_file.write(result_exported_functions_addition_output.replace("\n", ""))
else:
log_file.write(result_exported_functions_addition_output)
if result_exported_functions_addition.returncode != 0:
result_exported_functions_addition = subprocess.run(["python", str(exported_functions_addition_test_path)])
if result_exported_functions_addition.returncode != 0:
print(f"Function structural tests failed with exit code {result_exported_functions_addition.returncode}. Exiting.")
sys.exit(result_exported_functions_addition.returncode)

print("All structural tests passed.")

if __name__ == "__main__":
create_virtual_environment()
install_dependencies()
run_tests()
Loading

0 comments on commit a5226b7

Please sign in to comment.