Files
mongo/buildscripts/msi_validation.py
Andrew Bradshaw 0d88fe0c46 SERVER-101849 Test windows MSI before pushing (#36742)
GitOrigin-RevId: f5f87df2338b63b6aa98e93bba0bbadbb00fb611
2025-06-03 20:50:36 +00:00

121 lines
3.8 KiB
Python

# This script validates the msi can be installed, uninstalled, and checks for the default install location and some of the possible install files
import glob
import os
import subprocess
import sys
import tempfile
common_files = [
"*\\*\\bin\\mongos.exe",
"*\\*\\bin\\mongos.pdb",
"*\\*\\bin\\mongod.exe",
"*\\*\\bin\\mongod.pdb",
"*\\*\\bin\\mongod.cfg",
"*\\*\\bin\\InstallCompass.ps1",
"*\\*\\MPL-2",
"*\\*\\README",
"*\\*\\THIRD-PARTY-NOTICES",
]
community_files = [
"*\\*\\LICENSE-Community.txt",
]
enterprise_files = [
"*\\*\\bin\\mongodecrypt.exe",
"*\\*\\bin\\mongokerberos.exe",
"*\\*\\bin\\mongoldap.exe",
"*\\*\\bin\\sasl2.dll",
"*\\*\\bin\\sasl2.pdb",
"*\\*\\LICENSE-Enterprise.txt",
"*\\*\\THIRD-PARTY-NOTICES.windows",
]
def execute_msi(msi_path, install=True):
"""
Run an MSI file to either install or uninstall.
:param msi_path: Path to the MSI file.
:return: None
"""
if not os.path.exists(msi_path):
print(f"Error: The file '{msi_path}' does not exist.")
sys.exit(1)
features = ["ServerNoService", "Router", "MiscellaneousTools", "InstallCompassFeature"]
# Should look like ADDLOCAL=feature1,feature2
features_install_string = "" if len(features) == 0 else "ADDLOCAL=" + ",".join(features)
try:
temp_log = tempfile.NamedTemporaryFile(mode="w", suffix=".log", delete=False)
process_type = "Install" if install else "Uninstall"
install_commands = [
"msiexec",
"/i" if install else "/x",
msi_path,
features_install_string,
"/quiet",
"/norestart",
"/l*v",
temp_log.name,
]
print(f"{process_type} '{msi_path}' with command: {' '.join(install_commands)}...")
subprocess.run(install_commands, check=True)
print(f"{process_type} completed successfully.")
with open(temp_log.name, "r") as file:
print(file.read())
except subprocess.CalledProcessError as e:
print(f"Error while {process_type} MSI: {e}")
with open(temp_log.name, "r") as file:
print(file.read())
sys.exit(1)
def validate_files(is_enterprise):
"""
Validate the files exist from the msi, and if its an exe the help command launches
"""
install_path = os.path.join(os.environ.get("ProgramFiles"), "MongoDB")
files_to_check = common_files + (enterprise_files if is_enterprise else community_files)
print("Validating some of the expected files exist in Program Files install directory.")
for file in files_to_check:
file_path = os.path.join(install_path, file)
print(f"Checking if {file_path} exists.")
file_match = glob.glob(file_path)
if file_match:
print(f"File exists: {file_match[0]}")
if file_match[0].endswith(".exe"):
validate_help(file_match[0])
else:
print(f"Error: {file_path} could not be found.")
sys.exit(1)
def validate_help(exe_path):
try:
install_commands = [exe_path, "--help"]
print(f"Calling '{exe_path}' with command: {' '.join(install_commands)}...")
subprocess.run(install_commands, check=True)
print(f"{exe_path} called help successfully.")
except subprocess.CalledProcessError as e:
print(f"Error while calling help for {exe_path}: {e}")
sys.exit(1)
def main():
if len(sys.argv) != 2:
print("Usage: python msi_validation.py <path_to_msi>")
sys.exit(1)
msi_path = sys.argv[1]
is_enterprise = "enterprise" in os.path.basename(msi_path).lower()
execute_msi(msi_path, install=True)
validate_files(is_enterprise)
execute_msi(msi_path, install=False)
if __name__ == "__main__":
main()