forked from wangbo/easyai
fix(deploy): 修复组件版本解析和安装升级验收流程
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Exercise the actual installer with real Compose parsing and failing Docker transports."""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
root = Path(__file__).resolve().parent.parent
|
||||
real_docker = shutil.which('docker')
|
||||
with tempfile.TemporaryDirectory(prefix='easyai-install-failures-') as temporary:
|
||||
base = Path(temporary)
|
||||
for phase in ('storage', 'manifest', 'pull', 'health'):
|
||||
project = base / phase
|
||||
project.mkdir()
|
||||
for name in ('scripts', 'system-update'):
|
||||
shutil.copytree(root / name, project / name, ignore=shutil.ignore_patterns('__pycache__'))
|
||||
for name in ('start.sh', 'docker-compose.yml', 'easyai-proxy.conf.sample'):
|
||||
shutil.copy2(root / name, project / name)
|
||||
for sample in root.glob('.env*.sample'):
|
||||
shutil.copy2(sample, project / sample.name)
|
||||
sample = project / '.env.sample'
|
||||
sample.write_text(sample.read_text().replace('UPDATE_MANIFEST_SOURCE=remote', 'UPDATE_MANIFEST_SOURCE=local'))
|
||||
binaries = project / 'bin'
|
||||
binaries.mkdir()
|
||||
commands = project / 'commands.jsonl'
|
||||
docker = binaries / 'docker'
|
||||
docker.write_text('''#!/usr/bin/env python3
|
||||
import json,os,subprocess,sys
|
||||
args=sys.argv[1:]
|
||||
with open(os.environ['TEST_COMMANDS'],'a') as log: log.write(json.dumps(args)+'\\n')
|
||||
if args[:1]==['--config']: args=args[2:]
|
||||
if args[:2]==['compose','config'] or args[:2]==['compose','version']:
|
||||
sys.exit(subprocess.call([os.environ['REAL_DOCKER'],*args]))
|
||||
if args[:2]==['manifest','inspect']:
|
||||
if os.environ['TEST_PHASE']=='manifest': print('manifest unknown',file=sys.stderr);sys.exit(1)
|
||||
print(json.dumps({'Descriptor':{'platform':{'os':'linux','architecture':'amd64'}}}));sys.exit(0)
|
||||
if args[:2]==['compose','pull']: sys.exit(18 if os.environ['TEST_PHASE']=='pull' else 0)
|
||||
if args[:3]==['compose','ps','-q']: print('test-'+args[-1]);sys.exit(0)
|
||||
if args[:1]==['inspect']:
|
||||
if '--format' in args: print('true|unhealthy');sys.exit(0)
|
||||
sys.exit(1)
|
||||
if args[:2]==['container','inspect']:
|
||||
if os.environ['TEST_PHASE']=='storage' and args[-1]=='easyai-server':
|
||||
print(json.dumps([{'Config':{'Labels':{'com.docker.compose.project':'unrelated-project'}},'Mounts':[]}]))
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
''')
|
||||
docker.chmod(0o755)
|
||||
for name, code in [('sudo', '#!/bin/sh\nexec "$@"\n'), ('curl', '#!/bin/sh\nexit 0\n')]:
|
||||
path = binaries / name
|
||||
path.write_text(code)
|
||||
path.chmod(0o755)
|
||||
env = {k: v for k, v in os.environ.items() if not k.startswith(('UPDATE_', 'DEPLOY_', 'COMPOSE_'))}
|
||||
env.update({'PATH': str(binaries) + os.pathsep + env['PATH'], 'REAL_DOCKER': real_docker,
|
||||
'TEST_COMMANDS': str(commands), 'TEST_PHASE': phase, 'CI': 'true',
|
||||
'DEPLOY_ACCESS': 'ip', 'DEPLOY_IP': '127.0.0.1', 'DEPLOY_NON_INTERACTIVE': '1',
|
||||
'DEPLOY_HEALTH_TIMEOUT_SECONDS': '1'})
|
||||
result = subprocess.run(['bash', 'start.sh'], cwd=project, env=env, capture_output=True, text=True, errors='replace', timeout=120)
|
||||
assert result.returncode != 0, (phase, result.stdout, result.stderr)
|
||||
assert '应用启动成功' not in result.stdout and '部署完成' not in result.stdout, result.stdout
|
||||
calls = [json.loads(line) for line in commands.read_text().splitlines()]
|
||||
if phase in ('storage', 'manifest'):
|
||||
assert not any(call[:2] in (['compose', 'pull'], ['compose', 'up']) for call in calls)
|
||||
if phase == 'pull':
|
||||
assert ['compose', 'pull'] in calls, (result.stdout, result.stderr, calls)
|
||||
assert not any(call[:2] == ['compose', 'up'] for call in calls)
|
||||
if phase == 'health':
|
||||
assert ['compose', 'up', '-d'] in calls
|
||||
assert '部署未完成' in result.stdout + result.stderr
|
||||
print(phase + ': installer failed without reporting success or continuing to the next stage')
|
||||
Reference in New Issue
Block a user