unittest.ts 2.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
 *  Unit test helper.
 *  It should be inside "test", but must be here for compatibility, until we refactor all test cases.
 *
 *  Use this module to replace NNI globals with mocked values:
 *
10
11
12
13
 *      import 'common/globals/unittest';
 *
 *  Or:
 *
14
15
16
17
 *      import globals from 'common/globals/unittest';
 *
 *  You can then edit these mocked globals and the injection will be visible to all modules.
 *  Remember to invoke `resetGlobals()` in "after()" hook if you do so.
18
19
 *
 *  Attention: TypeScript will remove "unused" import statements. Use the first format when "globals" is never used.
20
21
22
23
24
25
26
 **/

import os from 'os';
import path from 'path';

import type { NniManagerArgs } from './arguments';
import { NniPaths, createPaths } from './paths';
27
import type { LogStream } from './log_stream';
28
29
30
31
32
33
34
35
36

// copied from https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
type Mutable<Type> = {
    -readonly [Property in keyof Type]: Type[Property];
};

export interface MutableGlobals {
    args: Mutable<NniManagerArgs>;
    paths: Mutable<NniPaths>;
37
38
39
    logStream: LogStream;

    reset(): void;
40
41
42
43
44
45
46
47
48
49
50
}

export function resetGlobals(): void {
    const args: NniManagerArgs = {
        port: 8080,
        experimentId: 'unittest',
        action: 'create',
        experimentsDirectory: path.join(os.homedir(), 'nni-experiments'),
        logLevel: 'info',
        foreground: false,
        urlPrefix: '',
51
52
        tunerCommandChannel: null,
        mode: 'unittest'
53
54
    };
    const paths = createPaths(args);
55
56
57
    const logStream = {
        writeLine: (_line: string): void => { /* dummy */ },
        writeLineSync: (_line: string): void => { /* dummy */ },
58
59
60
61
        close: async (): Promise<void> => { /* dummy */ }
    };
    const shutdown = {
        register: (..._: any): void => { /* dummy */ },
62
    };
63

64
    const globalAsAny = global as any;
65
    const utGlobals = { args, paths, logStream, shutdown, reset: resetGlobals };
66
67
    if (globalAsAny.nni === undefined) {
        globalAsAny.nni = utGlobals;
68
    } else {
69
        Object.assign(globalAsAny.nni, utGlobals);
70
71
72
73
74
75
76
77
78
79
80
81
    }
}

function isUnitTest(): boolean {
    const event = process.env['npm_lifecycle_event'] ?? '';
    return event.startsWith('test') || event === 'mocha' || event === 'nyc';
}

if (isUnitTest()) {
    resetGlobals();
}

82
const globals: MutableGlobals = (global as any).nni;
83
export default globals;