Skip to content

Commit 1049678

Browse files
author
高魏洪
committed
fix: code commit
1 parent ac0e0a8 commit 1049678

13 files changed

Lines changed: 1415 additions & 502 deletions

File tree

__tests__/e2e/ci-mac-linux.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ python deploy_and_test_model.py --model-id iic/cv_LightweightEdge_ocr-recognitoi
3535
python deploy_and_test_model.py --model-id Qwen/Qwen2.5-0.5B-Instruct --region cn-shanghai --auto-cleanup
3636
python deploy_and_test_model.py --model-id iic/cv_LightweightEdge_ocr-recognitoin-general_damo --region cn-shanghai --storage oss --auto-cleanup
3737
python deploy_and_test_model.py --model-id Qwen/Qwen2.5-0.5B-Instruct --region cn-shanghai --storage oss --auto-cleanup
38+
39+
echo "test model s_file.yaml"
40+
s model download -t s_file.yaml
41+
s deploy -y -t s_file.yaml
42+
s model remove -t s_file.yaml
43+
s remove -y -t s_file.yaml
3844
cd ..
3945

4046
echo "test go runtime"

__tests__/e2e/model/s_file.yaml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
edition: 3.0.0
2+
name: ai-model-app
3+
access: quanxi
4+
5+
vars:
6+
region: ${env('REGION', 'cn-hongkong')}
7+
8+
resources:
9+
fc3:
10+
component: ${env('fc_component_version', path('../../../'))}
11+
type: Function
12+
props:
13+
logConfig: auto
14+
functionName: fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
15+
instanceLifecycleConfig:
16+
preStop:
17+
handler: 'true'
18+
timeout: 300
19+
gpuConfig:
20+
gpuMemorySize: 16384
21+
gpuType: fc.gpu.tesla.1
22+
nasConfig: auto
23+
runtime: custom-container
24+
description: test model download files
25+
cpu: 8
26+
customContainerConfig:
27+
image: >-
28+
cap-demo-public-registry.cn-hangzhou.cr.aliyuncs.com/cap-app/image-generation-comfyui-agent:v1.1.0-beta.0
29+
port: 9000
30+
triggers:
31+
- triggerConfig:
32+
methods:
33+
- GET
34+
- POST
35+
- PUT
36+
- PATCH
37+
- DELETE
38+
- HEAD
39+
authType: anonymous
40+
disableURLInternet: false
41+
triggerName: fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
42+
qualifier: LATEST
43+
description: http trigger for fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
44+
triggerType: http
45+
version: 1.6.0
46+
timeout: 3600
47+
instanceConcurrency: 200
48+
diskSize: 61440
49+
memorySize: 32768
50+
internetAccess: true
51+
environmentVariables:
52+
BACKEND_TYPE: comfyui
53+
MODEL_ASSET_DIR: /mnt/fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
54+
REGION: ${vars.region}
55+
vpcConfig: auto
56+
region: ${vars.region}
57+
annotations:
58+
modelConfig:
59+
solution: funArt
60+
source:
61+
uri: 'oss://dipper-cache-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com'
62+
downloadStrategy:
63+
mode: once
64+
target:
65+
uri: 'nas://auto'
66+
files:
67+
- source:
68+
path: base/comfyui/v0.3.59-alpha
69+
target:
70+
path: ''
71+
- source:
72+
path: >-
73+
function-art/comfyui/models/checkpoints/v1-5-pruned-emaonly-fp16.safetensors
74+
target:
75+
path: models/checkpoints/v1-5-pruned-emaonly-fp16.safetensors

__tests__/ut/commands/artModelService_test.ts

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { IInputs } from '../../../src/interface';
33
import DevClient from '@alicloud/devs20230714';
44
import * as $OpenApi from '@alicloud/openapi-client';
55
import { sleep } from '../../../src/utils';
6+
import {
7+
initClient,
8+
_displayProgress,
9+
_displayProgressComplete,
10+
} from '../../../src/subCommands/model/utils';
611

712
// Mock dependencies
813
jest.mock('../../../src/logger', () => {
@@ -83,14 +88,14 @@ describe('ArtModelService', () => {
8388
securityToken: 'test-token',
8489
protocol: 'https',
8590
endpoint: 'devs-pre.cn-hangzhou.aliyuncs.com',
86-
readTimeout: 86400000,
87-
connectTimeout: 60000,
88-
userAgent: 'test-agent',
91+
readTimeout: 300000,
92+
connectTimeout: 300000,
93+
userAgent: 'Component:fun-art;Nodejs:;OS:darwin-',
8994
};
9095

9196
($OpenApi.Config as unknown as jest.Mock).mockImplementation((config) => config);
9297

93-
const client = await artModelService.initClient();
98+
const client = await initClient(mockInputs, 'cn-hangzhou', artModelService.logger, 'fun-art');
9499

95100
expect($OpenApi.Config).toHaveBeenCalledWith(expect.objectContaining(mockConfig));
96101
expect(client).toBeInstanceOf(DevClient);
@@ -101,27 +106,31 @@ describe('ArtModelService', () => {
101106

102107
($OpenApi.Config as unknown as jest.Mock).mockImplementation((config) => config);
103108

104-
await artModelService.initClient();
109+
const client = await initClient(mockInputs, 'cn-hangzhou', artModelService.logger, 'fun-art');
105110

106111
expect($OpenApi.Config).toHaveBeenCalledWith(
107112
expect.objectContaining({
108113
endpoint: 'custom.endpoint.com',
114+
userAgent: 'Component:fun-art;Nodejs:;OS:darwin-',
109115
}),
110116
);
117+
expect(client).toBeInstanceOf(DevClient);
111118
});
112119

113120
it('should use custom endpoint from artifact_endpoint environment variable', async () => {
114121
process.env.artifact_endpoint = 'custom2.endpoint.com';
115122

116123
($OpenApi.Config as unknown as jest.Mock).mockImplementation((config) => config);
117124

118-
await artModelService.initClient();
125+
const client = await initClient(mockInputs, 'cn-hangzhou', artModelService.logger, 'fun-art');
119126

120127
expect($OpenApi.Config).toHaveBeenCalledWith(
121128
expect.objectContaining({
122129
endpoint: 'custom2.endpoint.com',
130+
userAgent: 'Component:fun-art;Nodejs:;OS:darwin-',
123131
}),
124132
);
133+
expect(client).toBeInstanceOf(DevClient);
125134
});
126135
});
127136

@@ -135,7 +144,9 @@ describe('ArtModelService', () => {
135144
getFileManagerTask: jest.fn(),
136145
} as any;
137146

138-
artModelService.initClient = jest.fn().mockResolvedValue(mockDevClient);
147+
// Mock the initClient function from utils
148+
const utils = require('../../../src/subCommands/model/utils');
149+
jest.spyOn(utils, 'initClient').mockResolvedValue(mockDevClient);
139150
(sleep as jest.Mock).mockResolvedValue(undefined);
140151
});
141152

@@ -458,7 +469,9 @@ describe('ArtModelService', () => {
458469
fileManagerRm: jest.fn(),
459470
} as any;
460471

461-
artModelService.initClient = jest.fn().mockResolvedValue(mockDevClient);
472+
// Mock the initClient function from utils
473+
const utils = require('../../../src/subCommands/model/utils');
474+
jest.spyOn(utils, 'initClient').mockResolvedValue(mockDevClient);
462475
});
463476

464477
it('should successfully remove model files', async () => {
@@ -492,9 +505,9 @@ describe('ArtModelService', () => {
492505
});
493506
});
494507

495-
describe('getSource', () => {
508+
describe('getSourceAndDestination', () => {
496509
it('should correctly generate source and destination paths', () => {
497-
const result = artModelService.getSource(
510+
const result = artModelService.getSourceAndDestination(
498511
'modelscope://test-model',
499512
{ source: { path: 'file1.txt' }, target: { path: 'file1.txt' } },
500513
[{ mountDir: '/mnt/nas' }],
@@ -510,7 +523,7 @@ describe('ArtModelService', () => {
510523

511524
it('should handle invalid source URI', () => {
512525
expect(() => {
513-
artModelService.getSource(
526+
artModelService.getSourceAndDestination(
514527
'invalid://test-model',
515528
{ source: { path: 'file1.txt' }, target: { path: 'file1.txt' } },
516529
[{ mountDir: '/mnt/nas' }],
@@ -526,19 +539,17 @@ describe('ArtModelService', () => {
526539
describe('_getSourcePath', () => {
527540
it('should correctly generate source path with valid URI', () => {
528541
const result = (artModelService as any)._getSourcePath(
529-
{ path: 'file1.txt' },
542+
{ source: { path: 'file1.txt' } },
530543
'modelscope://test-model',
531-
/^(modelscope|oss|nas):\/\//,
532544
);
533545

534546
expect(result).toBe('modelscope://test-model/file1.txt');
535547
});
536548

537549
it('should handle URI ending with slash', () => {
538550
const result = (artModelService as any)._getSourcePath(
539-
{ path: 'file1.txt' },
551+
{ source: { path: 'file1.txt' } },
540552
'modelscope://test-model/',
541-
/^(modelscope|oss|nas):\/\//,
542553
);
543554

544555
expect(result).toBe('modelscope://test-model/file1.txt');
@@ -595,7 +606,8 @@ describe('ArtModelService', () => {
595606
it('should display progress correctly', () => {
596607
const stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation(() => true as any);
597608

598-
(artModelService as any)._displayProgress('file1.txt', 512, 1024);
609+
// Import and call the _displayProgress function directly from utils
610+
_displayProgress('file1.txt', 512, 1024);
599611

600612
expect(stdoutSpy).toHaveBeenCalledWith(
601613
expect.stringContaining(
@@ -611,7 +623,8 @@ describe('ArtModelService', () => {
611623
it('should display complete progress correctly', () => {
612624
const stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation(() => true as any);
613625

614-
(artModelService as any)._displayProgressComplete('file1.txt', 1024, 1024);
626+
// Import and call the _displayProgressComplete function directly from utils
627+
_displayProgressComplete('file1.txt', 1024, 1024);
615628

616629
expect(stdoutSpy).toHaveBeenCalledWith(
617630
expect.stringContaining(

__tests__/ut/commands/modelService_test.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { IInputs } from '../../../src/interface';
33
import DevClient from '@alicloud/devs20230714';
44
import * as $OpenApi from '@alicloud/openapi-client';
55
import { sleep } from '../../../src/utils';
6+
import {
7+
initClient,
8+
_displayProgress,
9+
_displayProgressComplete,
10+
} from '../../../src/subCommands/model/utils';
611

712
// Mock dependencies
813
jest.mock('../../../src/logger', () => {
@@ -83,14 +88,14 @@ describe('ModelService', () => {
8388
securityToken: 'test-token',
8489
protocol: 'https',
8590
endpoint: 'devs-pre.cn-hangzhou.aliyuncs.com',
86-
readTimeout: 86400000,
87-
connectTimeout: 60000,
88-
userAgent: 'test-agent',
91+
readTimeout: 300000,
92+
connectTimeout: 300000,
93+
userAgent: 'Component:fun-model;Nodejs:;OS:darwin-',
8994
};
9095

9196
($OpenApi.Config as unknown as jest.Mock).mockImplementation((config) => config);
9297

93-
const client = await modelService.initClient();
98+
const client = await initClient(mockInputs, 'cn-hangzhou', modelService.logger, 'fun-model');
9499

95100
expect($OpenApi.Config).toHaveBeenCalledWith(expect.objectContaining(mockConfig));
96101
expect(client).toBeInstanceOf(DevClient);
@@ -101,27 +106,32 @@ describe('ModelService', () => {
101106

102107
($OpenApi.Config as unknown as jest.Mock).mockImplementation((config) => config);
103108

104-
await modelService.initClient();
109+
// Since initClient is not a method of ModelService, we need to import and call it directly
110+
const client = await initClient(mockInputs, 'cn-hangzhou', modelService.logger, 'fun-model');
105111

106112
expect($OpenApi.Config).toHaveBeenCalledWith(
107113
expect.objectContaining({
108114
endpoint: 'custom.endpoint.com',
115+
userAgent: 'Component:fun-model;Nodejs:;OS:darwin-',
109116
}),
110117
);
118+
expect(client).toBeInstanceOf(DevClient);
111119
});
112120

113121
it('should use custom endpoint from artifact_endpoint environment variable', async () => {
114122
process.env.artifact_endpoint = 'custom2.endpoint.com';
115123

116124
($OpenApi.Config as unknown as jest.Mock).mockImplementation((config) => config);
117125

118-
await modelService.initClient();
126+
const client = await initClient(mockInputs, 'cn-hangzhou', modelService.logger, 'fun-model');
119127

120128
expect($OpenApi.Config).toHaveBeenCalledWith(
121129
expect.objectContaining({
122130
endpoint: 'custom2.endpoint.com',
131+
userAgent: 'Component:fun-model;Nodejs:;OS:darwin-',
123132
}),
124133
);
134+
expect(client).toBeInstanceOf(DevClient);
125135
});
126136
});
127137

@@ -135,7 +145,9 @@ describe('ModelService', () => {
135145
getFileManagerTask: jest.fn(),
136146
} as any;
137147

138-
modelService.initClient = jest.fn().mockResolvedValue(mockDevClient);
148+
// Mock the initClient function from utils
149+
const utils = require('../../../src/subCommands/model/utils');
150+
jest.spyOn(utils, 'initClient').mockResolvedValue(mockDevClient);
139151
(sleep as jest.Mock).mockResolvedValue(undefined);
140152
});
141153

@@ -395,7 +407,9 @@ describe('ModelService', () => {
395407
fileManagerRm: jest.fn(),
396408
} as any;
397409

398-
modelService.initClient = jest.fn().mockResolvedValue(mockDevClient);
410+
// Mock the initClient function from utils
411+
const utils = require('../../../src/subCommands/model/utils');
412+
jest.spyOn(utils, 'initClient').mockResolvedValue(mockDevClient);
399413
});
400414

401415
it('should successfully remove model', async () => {
@@ -423,7 +437,8 @@ describe('ModelService', () => {
423437
it('should display progress correctly', () => {
424438
const stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation(() => true as any);
425439

426-
(modelService as any)._displayProgress('[Model Download]', 512, 1024);
440+
// Import and call the _displayProgress function directly from utils
441+
_displayProgress('[Model Download]', 512, 1024);
427442

428443
expect(stdoutSpy).toHaveBeenCalledWith(
429444
expect.stringContaining(
@@ -439,7 +454,7 @@ describe('ModelService', () => {
439454
it('should display complete progress correctly', () => {
440455
const stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation(() => true as any);
441456

442-
(modelService as any)._displayProgressComplete('[Model Download]', 1024, 1024);
457+
_displayProgressComplete('[Model Download]', 1024, 1024);
443458

444459
expect(stdoutSpy).toHaveBeenCalledWith(
445460
expect.stringContaining(

0 commit comments

Comments
 (0)