252 lines
7.3 KiB
Markdown
252 lines
7.3 KiB
Markdown
# 업데이터 모듈 검증 가이드
|
|
|
|
## 1. 목적
|
|
|
|
통합 전에 `app/updater/` 모듈 단독으로 실행/오류 시나리오를 검증하기 위한 체크리스트입니다.
|
|
|
|
---
|
|
|
|
## 2. 검증 범위
|
|
|
|
- `update_manager.py`
|
|
- 버전 비교
|
|
- Supabase 조회
|
|
- config.json 생성
|
|
- updater.exe 복사 및 실행
|
|
- `updater_gui.py`
|
|
- config.json 로드/검증
|
|
- zip 다운로드
|
|
- 압축 해제/파일 교체
|
|
- 롤백 처리
|
|
- 메인 앱 재실행
|
|
|
|
---
|
|
|
|
## 3. 실행 전 준비
|
|
|
|
1. `%TEMP%` 쓰기 권한 확인
|
|
2. 설치 대상 경로 쓰기 권한 확인
|
|
3. `updater.exe` 배포 위치 확인 (메인 exe와 동일 경로)
|
|
4. Supabase `program_version` 테이블 데이터 확인
|
|
|
|
---
|
|
|
|
## 4. 핵심 시나리오
|
|
|
|
### 4.1 정상 시나리오
|
|
|
|
1. `check_for_updates()`가 최신 안정 버전을 조회
|
|
2. `prepare_update()`가 `%TEMP%/voc_updater_config.json` 생성
|
|
3. `prepare_update()`가 `%TEMP%/updater.exe` 복사
|
|
4. `launch_updater()`가 updater 프로세스 실행
|
|
5. updater가 zip 다운로드 후 대상 경로 교체
|
|
6. updater가 메인 프로그램 재실행
|
|
|
|
### 4.2 오류 시나리오
|
|
|
|
1. Supabase URL/키 누락
|
|
- 기대 결과: `ConfigError`
|
|
2. 다운로드 URL 누락
|
|
- 기대 결과: `prepare_update()` 실패 반환
|
|
3. updater.exe 누락
|
|
- 기대 결과: `prepare_update()` 실패 반환
|
|
4. 손상 zip 파일
|
|
- 기대 결과: 설치 실패 + 롤백
|
|
5. 대상 경로 권한 부족
|
|
- 기대 결과: 설치 실패 + 롤백
|
|
|
|
---
|
|
|
|
## 5. 반영된 에러 처리 강화
|
|
|
|
- `update_manager.py`
|
|
- Supabase URL/키 사전 검증 추가
|
|
- 설치 경로 판별 로직 정리 (`sys.frozen` 기준)
|
|
- config.json 원자적 저장(`.tmp` 생성 후 교체)
|
|
- updater.exe 누락 시 실패 반환 강화
|
|
- OS별 프로세스 생성 플래그 분기
|
|
- `updater_gui.py`
|
|
- config.json 필수 필드 검증 강화
|
|
- 압축 해제 임시 폴더 분리
|
|
- 임시 폴더 -> 대상 경로 복사 단계 명확화
|
|
- 실패 시 롤백 + 임시 폴더 정리
|
|
- OS별 재실행 플래그 분기
|
|
|
|
---
|
|
|
|
## 6. 통합 전 완료 조건
|
|
|
|
- 업데이터 단위 테스트 통과
|
|
- `py_compile` 통과
|
|
- 오류 시나리오에서 메시지/롤백 동작 확인
|
|
- 문서(`project_spec.md`, `api_contract.md`, `issue.md`) 동기화
|
|
|
|
---
|
|
|
|
## 7. 수동 리허설 절차 (샘플 zip)
|
|
|
|
### 7.1 목적
|
|
|
|
실제 통합 전에 updater.exe 단독 실행으로 "다운로드 -> 교체 -> 재실행" 경로를 눈으로 확인합니다.
|
|
|
|
### 7.2 준비물
|
|
|
|
1. 테스트용 설치 폴더 (예: `D:/tmp/voc_app_test`)
|
|
2. 샘플 업데이트 zip (루트에 `voc_noti.exe` 또는 테스트 파일 포함)
|
|
3. `%TEMP%/voc_updater_config.json` 파일
|
|
|
|
### 7.3 config.json 예시
|
|
|
|
```json
|
|
{
|
|
"download_url": "https://example.com/voc_test_update.zip",
|
|
"target_path": "D:/tmp/voc_app_test",
|
|
"version": "9.9.9",
|
|
"restart_exe": "voc_noti.exe"
|
|
}
|
|
```
|
|
|
|
### 7.4 실행 순서
|
|
|
|
1. `%TEMP%`에 config.json 배치
|
|
2. `updater.exe` 단독 실행
|
|
3. GUI에서 상태가 순서대로 진행되는지 확인
|
|
- 다운로드 중
|
|
- 압축 해제 중
|
|
- 파일 교체 중
|
|
- 완료
|
|
4. 대상 경로 파일 변경 여부 확인
|
|
5. 메인 앱 재실행 여부 확인
|
|
|
|
### 7.5 실패 리허설
|
|
|
|
1. 손상 zip URL로 config 구성
|
|
- 기대: 실패 메시지 + 재시도 버튼
|
|
2. 대상 경로 쓰기 권한 제거
|
|
- 기대: 설치 실패 + 기존 파일 유지(롤백)
|
|
|
|
### 7.6 확인 체크리스트
|
|
|
|
- [ ] 성공 시 업데이트 파일이 대상 경로에 반영됨
|
|
- [ ] 실패 시 기존 파일이 보존됨
|
|
- [ ] config/temp 파일이 종료 시 정리됨
|
|
- [ ] 상태 메시지가 한국어로 이해 가능하게 표시됨
|
|
|
|
---
|
|
|
|
## 8. 실행 증적 (2026-02-18)
|
|
|
|
### 8.1 단위 테스트
|
|
|
|
실행 명령:
|
|
|
|
```bash
|
|
python test/test_updater_module.py -v
|
|
```
|
|
|
|
결과:
|
|
- 총 13개 테스트 통과
|
|
- 포함 시나리오: 버전 비교, 연결 설정 fallback/remote, 테이블명 폴백, 권한 오류, 손상 zip, 롤백
|
|
|
|
### 8.2 실환경 연결 테스트 (m1tcloud)
|
|
|
|
실행 명령:
|
|
|
|
```bash
|
|
python -c "import json; from pathlib import Path; from app.updater.update_manager import create_update_manager_from_settings; s=json.loads(Path('app/data/settings.json').read_text(encoding='utf-8')); m=create_update_manager_from_settings(s); print(m.supabase_url, m.version_table); v=m.check_for_updates(); print(v.version if v else 'NONE')"
|
|
```
|
|
|
|
결과:
|
|
- URL: `https://kong.m1tcloud.cc`
|
|
- 테이블: `program_versions`
|
|
- 조회 버전: `3.5.5`
|
|
|
|
---
|
|
|
|
## 9. 메인 통합 리허설 절차
|
|
|
|
### 9.1 목적
|
|
|
|
업데이터 단독 검증 이후, 메인 앱 통합 경로(트레이 메뉴/백그라운드)가 정상 연결되는지 확인합니다.
|
|
|
|
### 9.2 확인 항목
|
|
|
|
1. 앱 시작 시 업데이터 초기화 로그
|
|
- `업데이터 초기화 완료`
|
|
2. 앱 시작 후 백그라운드 체크 시작 로그
|
|
- `백그라운드 업데이트 체크 시작 (주기: N시간)`
|
|
3. 트레이 메뉴에 `업데이트 확인` 항목 표시
|
|
4. 트레이 `업데이트 확인` 클릭 시:
|
|
- 최신 버전 없음: 토스트 안내
|
|
- 최신 버전 있음: 설치 여부 다이얼로그 표시
|
|
5. 설치 승인 시:
|
|
- `prepare_update` 성공
|
|
- `launch_updater` 성공
|
|
- 메인 앱 종료 처리
|
|
|
|
### 9.2.1 테스트 모드 즉시 확인 옵션
|
|
|
|
테스트 DB 모드에서 updater 연결을 즉시 검증하려면 아래 명령을 사용합니다.
|
|
|
|
```bash
|
|
python app/main.py --test --test-update-now
|
|
```
|
|
|
|
기대 동작:
|
|
- 앱 시작 후 약 1초 내 업데이트 확인 1회 실행
|
|
- 로그에 `수동 업데이트 확인 시작` 기록
|
|
- 최신/신규 버전 결과 로그 및 알림 표시
|
|
|
|
### 9.3 실패 시 기대 동작
|
|
|
|
- 연결 설정 오류: 사용자에게 설정 오류 메시지 표시 + 로그
|
|
- 네트워크 오류: 사용자에게 네트워크 오류 메시지 표시 + 로그
|
|
- updater.exe 누락: 업데이트 실행 실패 메시지 + 로그
|
|
|
|
### 9.5 중복 알림 방지 규칙
|
|
|
|
- 업데이트 안내창 표시 중에는 추가 안내창을 띄우지 않음
|
|
- 동일 버전 안내는 60초 이내 재표시하지 않음
|
|
- 테스트 모드 `--test --test-update-now` 사용 시 백그라운드 즉시 체크와 중복되지 않도록 단발 확인만 수행
|
|
|
|
### 9.4 코드 연결 지점
|
|
|
|
- `app/controllers/controller.py`
|
|
- `start_background()`에서 updater 백그라운드 시작
|
|
- `check_updates_manual()`/`_check_updates_once()` 수동 확인
|
|
- `_show_update_prompt()` 승인 후 실행
|
|
- `app/view/tray_icon.py`
|
|
- 트레이 메뉴 `업데이트 확인` 이벤트 연결
|
|
|
|
### 9.6 빌드 리허설
|
|
|
|
1. 업데이터 단독 빌드
|
|
- `python app/update_build_setup.py`
|
|
2. 산출물 확인
|
|
- `app/updater_build/dist/updater.exe` 존재
|
|
- `app/updater_build/config.json` 존재
|
|
3. 메인 패키징
|
|
- `python app/setup.py build`
|
|
4. 빌드 결과 폴더 확인
|
|
- 메인 exe와 같은 폴더에 `updater.exe` 존재
|
|
|
|
### 9.7 빌드 리허설 실행 증적 (2026-02-18)
|
|
|
|
실행 명령:
|
|
|
|
```bash
|
|
python app/update_build_setup.py
|
|
python app/setup.py build
|
|
```
|
|
|
|
확인 결과:
|
|
- `app/updater_build/dist/updater.exe` 생성 확인
|
|
- `app/updater_build/config.json` 복사 확인
|
|
- `app/build/exe.win-amd64-3.11/VOC_Monitor.exe` 생성 확인
|
|
- `app/build/exe.win-amd64-3.11/updater.exe` 포함 확인
|
|
- `app/build/exe.win-amd64-3.11/app/updater/config.json` 포함 확인
|
|
|
|
추가 스모크 검증:
|
|
- 빌드된 `updater.exe`를 개발 경로에 복사 후 `prepare_update()` 실행
|
|
- 결과: `PREPARE True` / `%TEMP%/updater.exe` 존재 확인
|