ML - Target import table selectable by user (#10071)

ML - Target import table selectable by user
This commit is contained in:
Leila Lali
2020-04-21 08:02:48 -07:00
committed by GitHub
parent 4f1d4276a0
commit a34feb4448
30 changed files with 1172 additions and 317 deletions

View File

@@ -34,6 +34,6 @@ describe('Dashboard widget', () => {
const dashboard = new DashboardWidget(testContext.apiWrapper.object, '');
dashboard.register();
testContext.onClick.fire();
testContext.apiWrapper.verify(x => x.executeCommand(TypeMoq.It.isAny()), TypeMoq.Times.atMostOnce());
testContext.apiWrapper.verify(x => x.executeCommand(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
});
});

View File

@@ -0,0 +1,170 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as should from 'should';
import * as TypeMoq from 'typemoq';
import 'mocha';
import { createContext } from './utils';
import { RegisteredModel, ModelParameters } from '../../../modelManagement/interfaces';
import { azureResource } from '../../../typings/azure-resource';
import { Workspace } from '@azure/arm-machinelearningservices/esm/models';
import { WorkspaceModel } from '../../../modelManagement/interfaces';
import { ModelManagementController } from '../../../views/models/modelManagementController';
import { DatabaseTable, TableColumn } from '../../../prediction/interfaces';
const accounts: azdata.Account[] = [
{
key: {
accountId: '1',
providerId: ''
},
displayInfo: {
displayName: 'account',
userId: '',
accountType: '',
contextualDisplayName: ''
},
isStale: false,
properties: []
}
];
const subscriptions: azureResource.AzureResourceSubscription[] = [
{
name: 'subscription',
id: '2'
}
];
const groups: azureResource.AzureResourceResourceGroup[] = [
{
name: 'group',
id: '3'
}
];
const workspaces: Workspace[] = [
{
name: 'workspace',
id: '4'
}
];
const models: WorkspaceModel[] = [
{
id: '5',
name: 'model'
}
];
const localModels: RegisteredModel[] = [
{
id: 1,
artifactName: 'model',
title: 'model',
table: {
databaseName: 'db',
tableName: 'tb',
schema: 'dbo'
}
}
];
const dbNames: string[] = [
'db1',
'db2'
];
const tableNames: DatabaseTable[] = [
{
databaseName: 'db1',
schema: 'dbo',
tableName: 'tb1'
},
{
databaseName: 'db1',
tableName: 'tb2',
schema: 'dbo'
}
];
const columnNames: TableColumn[] = [
{
columnName: 'c1',
dataType: 'int'
},
{
columnName: 'c2',
dataType: 'varchar'
}
];
const modelParameters: ModelParameters = {
inputs: [
{
'name': 'p1',
'type': 'int'
},
{
'name': 'p2',
'type': 'varchar'
}
],
outputs: [
{
'name': 'o1',
'type': 'int'
}
]
};
describe('Model Controller', () => {
it('Should open deploy model wizard successfully ', async function (): Promise<void> {
let testContext = createContext();
let controller = new ModelManagementController(testContext.apiWrapper.object, '', testContext.azureModelService.object, testContext.deployModelService.object, testContext.predictService.object);
testContext.deployModelService.setup(x => x.getRecentImportTable()).returns(() => Promise.resolve({
databaseName: 'db',
tableName: 'table',
schema: 'dbo'
}));
testContext.deployModelService.setup(x => x.getDeployedModels(TypeMoq.It.isAny())).returns(() => Promise.resolve(localModels));
testContext.predictService.setup(x => x.getDatabaseList()).returns(() => Promise.resolve(dbNames));
testContext.predictService.setup(x => x.getTableList(TypeMoq.It.isAny())).returns(() => Promise.resolve(tableNames));
testContext.azureModelService.setup(x => x.getAccounts()).returns(() => Promise.resolve(accounts));
testContext.azureModelService.setup(x => x.getSubscriptions(TypeMoq.It.isAny())).returns(() => Promise.resolve(subscriptions));
testContext.azureModelService.setup(x => x.getGroups(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(groups));
testContext.azureModelService.setup(x => x.getWorkspaces(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(workspaces));
testContext.azureModelService.setup(x => x.getModels(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(models));
const view = await controller.registerModel(undefined);
should.notEqual(view, undefined);
});
it('Should open predict wizard successfully ', async function (): Promise<void> {
let testContext = createContext();
let controller = new ModelManagementController(testContext.apiWrapper.object, '', testContext.azureModelService.object, testContext.deployModelService.object, testContext.predictService.object);
testContext.deployModelService.setup(x => x.getRecentImportTable()).returns(() => Promise.resolve({
databaseName: 'db',
tableName: 'table',
schema: 'dbo'
}));
testContext.deployModelService.setup(x => x.getDeployedModels(TypeMoq.It.isAny())).returns(() => Promise.resolve(localModels));
testContext.predictService.setup(x => x.getDatabaseList()).returns(() => Promise.resolve([
'db', 'db1'
]));
testContext.predictService.setup(x => x.getTableList(TypeMoq.It.isAny())).returns(() => Promise.resolve([
{ tableName: 'tb', databaseName: 'db', schema: 'dbo' }
]));
testContext.azureModelService.setup(x => x.getAccounts()).returns(() => Promise.resolve(accounts));
testContext.azureModelService.setup(x => x.getSubscriptions(TypeMoq.It.isAny())).returns(() => Promise.resolve(subscriptions));
testContext.azureModelService.setup(x => x.getGroups(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(groups));
testContext.azureModelService.setup(x => x.getWorkspaces(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(workspaces));
testContext.azureModelService.setup(x => x.getModels(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(models));
testContext.predictService.setup(x => x.getTableColumnsList(TypeMoq.It.isAny())).returns(() => Promise.resolve(columnNames));
testContext.deployModelService.setup(x => x.loadModelParameters(TypeMoq.It.isAny())).returns(() => Promise.resolve(modelParameters));
testContext.azureModelService.setup(x => x.downloadModel(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve('file'));
testContext.deployModelService.setup(x => x.downloadModel(TypeMoq.It.isAny())).returns(() => Promise.resolve('file'));
const view = await controller.predictModel();
should.notEqual(view, undefined);
});
});

View File

@@ -34,6 +34,11 @@ describe('Predict Wizard', () => {
let testContext = createContext();
let view = new PredictWizard(testContext.apiWrapper.object, '');
view.importTable = {
databaseName: 'db',
tableName: 'tb',
schema: 'dbo'
};
await view.open();
let accounts: azdata.Account[] = [
{
@@ -79,7 +84,12 @@ describe('Predict Wizard', () => {
{
id: 1,
artifactName: 'model',
title: 'model'
title: 'model',
table: {
databaseName: 'db',
tableName: 'tb',
schema: 'dbo'
}
}
];
const dbNames: string[] = [

View File

@@ -7,21 +7,25 @@ import * as azdata from 'azdata';
import * as should from 'should';
import 'mocha';
import { createContext } from './utils';
import { ListModelsEventName, ListAccountsEventName, ListSubscriptionsEventName, ListGroupsEventName, ListWorkspacesEventName, ListAzureModelsEventName, ModelSourceType } from '../../../views/models/modelViewBase';
import { ListModelsEventName, ListAccountsEventName, ListSubscriptionsEventName, ListGroupsEventName, ListWorkspacesEventName, ListAzureModelsEventName, ModelSourceType, ListDatabaseNamesEventName, ListTableNamesEventName } from '../../../views/models/modelViewBase';
import { RegisteredModel } from '../../../modelManagement/interfaces';
import { azureResource } from '../../../typings/azure-resource';
import { Workspace } from '@azure/arm-machinelearningservices/esm/models';
import { ViewBase } from '../../../views/viewBase';
import { WorkspaceModel } from '../../../modelManagement/interfaces';
import { RegisterModelWizard } from '../../../views/models/registerModels/registerModelWizard';
import { ImportModelWizard } from '../../../views/models/manageModels/importModelWizard';
describe('Register Model Wizard', () => {
it('Should create view components successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisterModelWizard(testContext.apiWrapper.object, '');
let view = new ImportModelWizard(testContext.apiWrapper.object, '');
view.importTable = {
databaseName: 'db',
tableName: 'table',
schema: 'dbo'
};
await view.open();
await view.refresh();
should.notEqual(view.wizardView, undefined);
should.notEqual(view.modelSourcePage, undefined);
});
@@ -29,7 +33,12 @@ describe('Register Model Wizard', () => {
it('Should load data successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisterModelWizard(testContext.apiWrapper.object, '');
let view = new ImportModelWizard(testContext.apiWrapper.object, '');
view.importTable = {
databaseName: 'db',
tableName: 'tb',
schema: 'dbo'
};
await view.open();
let accounts: azdata.Account[] = [
{
@@ -75,12 +84,27 @@ describe('Register Model Wizard', () => {
{
id: 1,
artifactName: 'model',
title: 'model'
title: 'model',
table: {
databaseName: 'db',
tableName: 'tb',
schema: 'dbo'
}
}
];
view.on(ListModelsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListModelsEventName), { data: localModels });
});
view.on(ListDatabaseNamesEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListDatabaseNamesEventName), { data: [
'db', 'db1'
] });
});
view.on(ListTableNamesEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListTableNamesEventName), { data: [
'tb', 'tb1'
] });
});
view.on(ListAccountsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListAccountsEventName), { data: accounts });
});

View File

@@ -6,7 +6,7 @@
import * as should from 'should';
import 'mocha';
import { createContext } from './utils';
import { RegisteredModelsDialog } from '../../../views/models/registerModels/registeredModelsDialog';
import { ManageModelsDialog } from '../../../views/models/manageModels/manageModelsDialog';
import { ListModelsEventName } from '../../../views/models/modelViewBase';
import { RegisteredModel } from '../../../modelManagement/interfaces';
import { ViewBase } from '../../../views/viewBase';
@@ -15,7 +15,7 @@ describe('Registered Models Dialog', () => {
it('Should create view components successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisteredModelsDialog(testContext.apiWrapper.object, '');
let view = new ManageModelsDialog(testContext.apiWrapper.object, '');
view.open();
should.notEqual(view.dialogView, undefined);
@@ -25,13 +25,18 @@ describe('Registered Models Dialog', () => {
it('Should load data successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisteredModelsDialog(testContext.apiWrapper.object, '');
let view = new ManageModelsDialog(testContext.apiWrapper.object, '');
view.open();
let models: RegisteredModel[] = [
{
id: 1,
artifactName: 'model',
title: ''
title: '',
table: {
databaseName: 'db',
tableName: 'tb',
schema: 'dbo'
}
}
];
view.on(ListModelsEventName, () => {

View File

@@ -9,11 +9,17 @@ import * as TypeMoq from 'typemoq';
import { ApiWrapper } from '../../../common/apiWrapper';
import { createViewContext } from '../utils';
import { ModelViewBase } from '../../../views/models/modelViewBase';
import { AzureModelRegistryService } from '../../../modelManagement/azureModelRegistryService';
import { DeployedModelService } from '../../../modelManagement/deployedModelService';
import { PredictService } from '../../../prediction/predictService';
export interface TestContext {
apiWrapper: TypeMoq.IMock<ApiWrapper>;
view: azdata.ModelView;
onClick: vscode.EventEmitter<any>;
azureModelService: TypeMoq.IMock<AzureModelRegistryService>;
deployModelService: TypeMoq.IMock<DeployedModelService>;
predictService: TypeMoq.IMock<PredictService>;
}
export class ParentDialog extends ModelViewBase {
@@ -36,6 +42,9 @@ export function createContext(): TestContext {
return {
apiWrapper: viewTestContext.apiWrapper,
view: viewTestContext.view,
onClick: viewTestContext.onClick
onClick: viewTestContext.onClick,
azureModelService: TypeMoq.Mock.ofType(AzureModelRegistryService),
deployModelService: TypeMoq.Mock.ofType(DeployedModelService),
predictService: TypeMoq.Mock.ofType(PredictService)
};
}

View File

@@ -31,6 +31,11 @@ export function createViewContext(): ViewTestContext {
let button: azdata.ButtonComponent = Object.assign({}, componentBase, {
onDidClick: onClick.event
});
let link: azdata.HyperlinkComponent = Object.assign({}, componentBase, {
onDidClick: onClick.event,
label: '',
url: ''
});
let radioButton: azdata.RadioButtonComponent = Object.assign({}, componentBase, {
checked: true,
onDidClick: onClick.event
@@ -61,6 +66,11 @@ export function createViewContext(): ViewTestContext {
withProperties: () => buttonBuilder,
withValidation: () => buttonBuilder
};
let hyperLinkBuilder: azdata.ComponentBuilder<azdata.HyperlinkComponent> = {
component: () => link,
withProperties: () => hyperLinkBuilder,
withValidation: () => hyperLinkBuilder
};
let radioButtonBuilder: azdata.ComponentBuilder<azdata.ButtonComponent> = {
component: () => radioButton,
withProperties: () => radioButtonBuilder,
@@ -72,7 +82,7 @@ export function createViewContext(): ViewTestContext {
withValidation: () => checkBoxBuilder
};
let inputBox: () => azdata.InputBoxComponent = () => Object.assign({}, componentBase, {
onTextChanged: undefined!,
onTextChanged: onClick.event!,
onEnterKeyPressed: undefined!,
value: ''
});
@@ -216,7 +226,7 @@ export function createViewContext(): ViewTestContext {
toolbarContainer: undefined!,
loadingComponent: () => loadingBuilder,
fileBrowserTree: undefined!,
hyperlink: undefined!,
hyperlink: () => hyperLinkBuilder,
tabbedPanel: undefined!,
separator: undefined!
}