smoke-primary-runtime.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """Exercise the relocated Office payload with its own isolated interpreter."""
  2. import importlib.metadata
  3. import json
  4. from pathlib import Path
  5. import re
  6. import sys
  7. import tempfile
  8. import numpy
  9. import pandas
  10. from docx import Document
  11. from docx.shared import Inches as DocxInches
  12. from openpyxl import Workbook, load_workbook
  13. from openpyxl.styles import Font
  14. from PIL import Image
  15. from pptx import Presentation
  16. from pptx.chart.data import CategoryChartData
  17. from pptx.enum.chart import XL_CHART_TYPE
  18. from pptx.util import Inches
  19. def main():
  20. """Check installed versions and read back editable Office documents."""
  21. assert sys.version_info[:3] == tuple(map(int, sys.argv[2].split("."))), sys.version
  22. versions = json.loads(sys.argv[1])
  23. # Only pip belongs to the interpreter baseline; all other distributions must be declared.
  24. # Each target's native release-host smoke must confirm this baseline.
  25. expected_names = {re.sub(r"[-_.]+", "-", name).lower() for name in versions} | {"pip"}
  26. installed_names = {
  27. re.sub(r"[-_.]+", "-", distribution.metadata["Name"]).lower()
  28. for distribution in importlib.metadata.distributions()
  29. }
  30. assert installed_names == expected_names, {"unexpected": sorted(installed_names - expected_names), "missing": sorted(expected_names - installed_names)}
  31. for name, expected in versions.items():
  32. actual = importlib.metadata.version(name)
  33. assert actual == expected, (name, actual, expected)
  34. assert numpy.arange(4).sum() == 6
  35. assert pandas.DataFrame({"n": [1, 2]}).n.sum() == 3
  36. with tempfile.TemporaryDirectory(prefix="dsh-office-smoke-") as directory:
  37. root = Path(directory)
  38. image = root / "chart.png"
  39. Image.new("RGB", (80, 40), "#2878bc").save(image)
  40. with Image.open(image) as restored:
  41. assert restored.size == (80, 40)
  42. document = Document()
  43. document.add_heading("Office 文档", 0)
  44. document.add_paragraph("Editable text")
  45. document.add_table(rows=2, cols=2).cell(1, 1).text = "42"
  46. document.add_picture(str(image), width=DocxInches(1))
  47. document.save(root / "document.docx")
  48. reopened_document = Document(root / "document.docx")
  49. assert reopened_document.tables[0].cell(1, 1).text == "42"
  50. assert reopened_document.paragraphs[0].text == "Office 文档"
  51. presentation = Presentation()
  52. slide = presentation.slides.add_slide(presentation.slide_layouts[6])
  53. slide.shapes.add_textbox(Inches(1), Inches(1), Inches(4), Inches(1)).text = "Office 演示"
  54. slide.shapes.add_picture(str(image), Inches(1), Inches(2))
  55. chart_data = CategoryChartData()
  56. chart_data.categories = ["A", "B"]
  57. chart_data.add_series("Values", [2, 4])
  58. slide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, Inches(3), Inches(2), Inches(4), Inches(3), chart_data)
  59. presentation.save(root / "presentation.pptx")
  60. reopened_presentation = Presentation(root / "presentation.pptx")
  61. assert len(reopened_presentation.slides) == 1
  62. chart = next(shape.chart for shape in reopened_presentation.slides[0].shapes if shape.has_chart)
  63. assert list(chart.series[0].values) == [2.0, 4.0]
  64. workbook = Workbook()
  65. sheet = workbook.active
  66. sheet.append(["Value", "Formula"])
  67. sheet.append([42, "=A2*2"])
  68. sheet["A1"].font = Font(bold=True)
  69. workbook.save(root / "workbook.xlsx")
  70. reopened_workbook = load_workbook(root / "workbook.xlsx")
  71. try:
  72. assert reopened_workbook.active["A2"].value == 42
  73. assert reopened_workbook.active["B2"].value == "=A2*2"
  74. assert reopened_workbook.active["A1"].font.bold
  75. finally:
  76. reopened_workbook.close()
  77. assert pandas.read_excel(root / "workbook.xlsx")["Value"].iloc[0] == 42
  78. print("Office runtime versions and document round trips passed.")
  79. if __name__ == "__main__":
  80. main()