File size: 4,195 Bytes
94a0de3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d6dcc3
94a0de3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python3
"""真实集成烟测:本机启动 Gradio,上传工程/JSON,渲染PNG并验证下载。

运行:BLENDER_BIN=/path/to/blender python scripts/smoke_test.py
默认明确使用 CPU;不声称测试了 ZeroGPU。需要先安装 requirements。
"""
from __future__ import annotations
import json
import os
from pathlib import Path
import sys
import tempfile
import zipfile

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
os.environ['RENDER_BACKEND'] = 'cpu'
os.environ.setdefault('GRADIO_ANALYTICS_ENABLED', 'False')
os.environ['NO_PROXY'] = ','.join(filter(None, [os.environ.get('NO_PROXY', ''), '127.0.0.1', 'localhost']))


def main():
    from gradio_client import Client, handle_file
    from PIL import Image
    with tempfile.TemporaryDirectory(prefix='blender-space-smoke-') as tmp:
        temp = Path(tmp)
        os.environ['RENDER_DATA_DIR'] = str(temp / 'jobs-data')
        import app
        import service
        from blender_runtime import ensure_blender
        binary = ensure_blender()
        demo_file = ROOT / 'examples/demo.blend'
        if not demo_file.is_file():
            raise RuntimeError('缺少 examples/demo.blend,请先运行 scripts/create_demo.py。')
        project = temp / 'project.zip'
        with zipfile.ZipFile(project, 'w') as archive:
            archive.write(demo_file, 'scene/demo.blend')
        config = temp / 'render.json'
        config.write_text(json.dumps({'blend_file':'scene/demo.blend','mode':'image',
                                    'width':640,'height':360,'samples':16,'batch_size':1}), encoding='utf-8')
        demo = app.build_app().queue()
        _, url, _ = demo.launch(server_name='127.0.0.1', server_port=7867,
                               prevent_thread_lock=True, quiet=True, mcp_server=True,
                               allowed_paths=[str(service.PUBLIC_ROOT)],
                               theme=app.gr.themes.Soft(), css=app.CSS)
        try:
            client = Client(url, verbose=False, download_files=str(temp / 'downloads'),
                            httpx_kwargs={'trust_env':False})
            environment = client.predict(api_name='/environment_info')
            probe, _, _ = client.predict(api_name='/cpu_self_test')
            assert probe['ok'] and probe['backend'] == 'CPU' and not probe['gpu_verified']
            job_id, prepared = client.predict([handle_file(str(project))], '{}', handle_file(str(config)),
                                              api_name='/prepare_job')
            checked = client.predict(job_id, api_name='/inspect_job')
            assert checked['status'] == 'ready', checked
            status = client.predict(job_id, api_name='/render_chunk')
            assert status['status'] == 'complete' and not status['error'], status
            summary, files, image, video = client.predict(job_id, api_name='/finalize_job')
            assert summary['export_complete'] and image and not video, summary
            with Image.open(image) as rendered:
                assert rendered.size == (640,360)
                rendered.verify()
            archive_file = next(Path(f) for f in files if str(f).endswith('.zip'))
            with zipfile.ZipFile(archive_file) as result_zip:
                assert 'frames/frame_000001.png' in result_zip.namelist()
                assert result_zip.testzip() is None
            artifacts = ROOT / 'test-artifacts'
            artifacts.mkdir(exist_ok=True)
            import shutil
            shutil.copy2(image, artifacts / 'cpu-render-preview.png')
            report = {'ok':True,'backend':'CPU','blender':probe['blender_version'],
                      'api_upload_zip':True,'api_upload_config':True,'api_render_png':True,
                      'image_dimensions':[640,360],'api_download_zip_verified':True,
                      'zero_gpu_tested':False,'environment':environment}
            (artifacts / 'api-smoke-report.json').write_text(json.dumps(report,ensure_ascii=False,indent=2),encoding='utf-8')
            print(json.dumps(report,ensure_ascii=False,indent=2))
        finally:
            demo.close()


if __name__ == '__main__':
    main()