localTrainingService.test.ts 4.06 KB
Newer Older
liuzhe-lz's avatar
liuzhe-lz committed
1
2
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Deshui Yu's avatar
Deshui Yu committed
3
4
5

'use strict';

SparkSnail's avatar
SparkSnail committed
6
7
8
9
10
import * as assert from 'assert';
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import * as fs from 'fs';
import * as tmp from 'tmp';
Deshui Yu's avatar
Deshui Yu committed
11
import * as component from '../../common/component';
SparkSnail's avatar
SparkSnail committed
12
13
14
import { TrialJobApplicationForm, TrialJobDetail, TrainingService } from '../../common/trainingService';
import { cleanupUnitTest, delay, prepareUnitTest } from '../../common/utils';
import { TrialConfigMetadataKey } from '../common/trialConfigMetadataKey';
15
import { LocalTrainingService } from '../local/localTrainingService';
SparkSnail's avatar
SparkSnail committed
16
17

// TODO: copy mockedTrail.py to local folder
18
const localCodeDir: string = tmp.dirSync().name.split('\\').join('\\\\');
SparkSnail's avatar
SparkSnail committed
19
20
const mockedTrialPath: string = './training_service/test/mockedTrial.py'
fs.copyFileSync(mockedTrialPath, localCodeDir + '/mockedTrial.py')
Deshui Yu's avatar
Deshui Yu committed
21
22

describe('Unit Test for LocalTrainingService', () => {
SparkSnail's avatar
SparkSnail committed
23
24
    let trialConfig: any = `{"command":"sleep 1h && echo hello","codeDir":"${localCodeDir}","gpuNum":1}`

25
    let localTrainingService: LocalTrainingService;
SparkSnail's avatar
SparkSnail committed
26
27
28
29
30
31
32
33
34
35
36
37

    before(() => {
        chai.should();
        chai.use(chaiAsPromised);
        prepareUnitTest();
    });

    after(() => {
        cleanupUnitTest();
    });

    beforeEach(() => {
38
        localTrainingService = component.get(LocalTrainingService);
SparkSnail's avatar
SparkSnail committed
39
40
41
42
43
44
45
46
47
48
49
        localTrainingService.run();
    });

    afterEach(() => {
        localTrainingService.cleanUp();
    });

    it('List empty trial jobs', async () => {
        //trial jobs should be empty, since there are no submitted jobs
        chai.expect(await localTrainingService.listTrialJobs()).to.be.empty;
    });
50

SparkSnail's avatar
SparkSnail committed
51
52
53
54
55
56
57
58
59
60
61
62
    it('setClusterMetadata and getClusterMetadata', async () => {
        await localTrainingService.setClusterMetadata(TrialConfigMetadataKey.TRIAL_CONFIG, trialConfig);
        localTrainingService.getClusterMetadata(TrialConfigMetadataKey.TRIAL_CONFIG).then((data)=>{
            chai.expect(data).to.be.equals(trialConfig);
        });
    });

    it('Submit job and Cancel job', async () => {
        await localTrainingService.setClusterMetadata(TrialConfigMetadataKey.TRIAL_CONFIG, trialConfig);

        // submit job
        const form: TrialJobApplicationForm = {
63
            sequenceId: 0,
SparkSnail's avatar
SparkSnail committed
64
65
66
67
68
69
70
71
72
73
            hyperParameters: {
                value: 'mock hyperparameters',
                index: 0
            }
        };
        const jobDetail: TrialJobDetail = await localTrainingService.submitTrialJob(form);
        chai.expect(jobDetail.status).to.be.equals('WAITING');
        await localTrainingService.cancelTrialJob(jobDetail.id);
        chai.expect(jobDetail.status).to.be.equals('USER_CANCELED');
    }).timeout(20000);
74

SparkSnail's avatar
SparkSnail committed
75
76
77
78
79
80
81
    it('Read metrics, Add listener, and remove listener', async () => {
        // set meta data
        const trialConfig: string = `{\"command\":\"python3 mockedTrial.py\", \"codeDir\":\"${localCodeDir}\",\"gpuNum\":0}`
        await localTrainingService.setClusterMetadata(TrialConfigMetadataKey.TRIAL_CONFIG, trialConfig);

        // submit job
        const form: TrialJobApplicationForm = {
82
            sequenceId: 0,
SparkSnail's avatar
SparkSnail committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
            hyperParameters: {
                value: 'mock hyperparameters',
                index: 0
            }
        };
        const jobDetail: TrialJobDetail = await localTrainingService.submitTrialJob(form);
        chai.expect(jobDetail.status).to.be.equals('WAITING');
        localTrainingService.listTrialJobs().then((jobList)=>{
            chai.expect(jobList.length).to.be.equals(1);
        });
        // Add metrics listeners
        const listener1 = function f1(metric: any) {
            chai.expect(metric.id).to.be.equals(jobDetail.id);
        }
        localTrainingService.addTrialJobMetricListener(listener1);
        // Wait to collect metric
        await delay(1000);

        await localTrainingService.cancelTrialJob(jobDetail.id);
        localTrainingService.removeTrialJobMetricListener(listener1);
    }).timeout(20000);
Deshui Yu's avatar
Deshui Yu committed
104

SparkSnail's avatar
SparkSnail committed
105
106
    it('Test multiphaseSupported', () => {
        chai.expect(localTrainingService.isMultiPhaseJobSupported).to.be.equals(true)
Deshui Yu's avatar
Deshui Yu committed
107
    })
108
});