import * as vscode from 'vscode' ; import * as chai from 'chai' ; import * as sinon from 'sinon' ; import * as sinonChai from 'sinon-chai' ; import * as fs from 'fs-extra' ; import * as path from 'path' ; import { PackageRegistryEntry } from '../../extension/registries/PackageRegistryEntry' ; import { FabricEnvironmentConnection } from 'ibm-blockchain-platform-environment-v1' ; import { FabricGoDebugConfigurationProvider } from '../../extension/debug/FabricGoDebugConfigurationProvider' ; import { UserInputUtil } from '../../extension/commands/UserInputUtil' ; import { FabricSmartContractDefinition , FabricEnvironmentRegistryEntry , FabricRuntimeUtil , EnvironmentType , FabricEnvironmentRegistry } from 'ibm-blockchain-platform-common' ; import { Reporter } from '../../extension/util/Reporter' ; import { FabricEnvironmentManager } from '../../extension/fabric/environments/FabricEnvironmentManager' ; import { GlobalState } from '../../extension/util/GlobalState' ; import { ExtensionUtil } from '../../extension/util/ExtensionUtil' ; import { TestUtil } from '../TestUtil' ; import { EnvironmentFactory } from '../../extension/fabric/environments/EnvironmentFactory' ; import { FabricDebugConfigurationProvider } from '../../extension/debug/FabricDebugConfigurationProvider' ; import { LocalMicroEnvironment } from '../../extension/fabric/environments/LocalMicroEnvironment' ; import { LocalMicroEnvironmentManager } from '../../extension/fabric/environments/LocalMicroEnvironmentManager' ; const should = chai . should ( ) ; chai . use ( sinonChai ) ; describe ( 'FabricGoDebugConfigurationProvider' , ( ) => { let mySandbox ; describe ( 'provideDebugConfigurations' , ( ) => { it ( 'should provide a debug configuration' , async ( ) => { const provider = new FabricGoDebugConfigurationProvider ( ) ; const config = await provider . provideDebugConfigurations ( ) ; config . should . deep . equal ( [ { type : 'fabric:go' , request : 'launch' , name : 'Debug Smart Contract' } ] ) ; } ) ; } ) ; before ( async ( ) => { mySandbox = sinon . createSandbox ( ) ; await TestUtil . setupTests ( mySandbox ) ; } ) ; describe ( 'resolveDebugConfiguration' , ( ) => { let fabricDebugConfig ; let workspaceFolder ; let debugConfig ; let runtimeStub ; let packageEntry ; let mockRuntimeConnection ; let startDebuggingStub ; let sendTelemetryEventStub ; let showInputBoxStub ; let getExtensionLocalFabricSetting ; let showQuickPickItemStub ; let environmentRegistry ; let showQuickPickStub ; beforeEach ( async ( ) => { mySandbox = sinon . createSandbox ( ) ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await TestUtil . setupLocalFabric ( ) ; getExtensionLocalFabricSetting = mySandbox . stub ( ExtensionUtil , 'getExtensionLocalFabricSetting' ) ; getExtensionLocalFabricSetting . returns ( true ) ; fabricDebugConfig = new FabricGoDebugConfigurationProvider ( ) ; runtimeStub = mySandbox . createStubInstance ( LocalMicroEnvironment ) ; runtimeStub . getPeerChaincodeURL . resolves ( 'grpc://127.0.0.1:54321' ) ; runtimeStub . isRunning . resolves ( true ) ; runtimeStub . numberOfOrgs = 1 ; runtimeStub . getName . returns ( FabricRuntimeUtil . LOCAL_FABRIC ) ; runtimeStub . getAllOrganizationNames . resolves ( [ 'Org1MSP' , 'Org2MSP' ] ) ; mySandbox . stub ( LocalMicroEnvironmentManager . instance ( ) , 'getRuntime' ) . returns ( runtimeStub ) ; environmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistry . name = FabricRuntimeUtil . LOCAL_FABRIC ; environmentRegistry . managedRuntime = true ; environmentRegistry . environmentType = EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT ; environmentRegistry . numberOfOrgs = 1 ; mySandbox . stub ( FabricEnvironmentManager . instance ( ) , 'getEnvironmentRegistryEntry' ) . returns ( environmentRegistry ) ; workspaceFolder = { name : 'myFolder' , uri : vscode . Uri . file ( 'myPath' ) } ; mySandbox . stub ( fs , 'readJSON' ) ; mySandbox . stub ( fs , 'readFile' ) . resolves ( `{
                "name": "mySmartContract",
                "version": "0.0.1"
            }` ) ; debugConfig = { type : 'fabric:go' , name : 'Launch Program' } ; debugConfig . request = 'myLaunch' ; debugConfig . program = 'myProgram' ; debugConfig . cwd = 'myCwd' ; debugConfig . args = [ '--peer.address' , 'localhost:12345' ] ; debugConfig . mode = 'auto' ; mySandbox . stub ( vscode . workspace , 'findFiles' ) . resolves ( [ ] ) ; packageEntry = new PackageRegistryEntry ( ) ; packageEntry . name = 'banana' ; packageEntry . version = 'vscode-13232112018' ; packageEntry . path = path . join ( 'myPath' ) ; mockRuntimeConnection = mySandbox . createStubInstance ( FabricEnvironmentConnection ) ; mockRuntimeConnection . connect . resolves ( ) ; mockRuntimeConnection . getAllPeerNames . resolves ( 'peerOne' ) ; const instantiatedChaincodes = [ { name : 'myOtherContract' , version : 'vscode-debug-13232112018' , sequence : 1 } , { name : 'cake-network' , version : 'vscode-debug-174758735087' , sequence : 1 } ] ; mockRuntimeConnection . getAllCommittedSmartContractDefinitions . resolves ( instantiatedChaincodes ) ; mySandbox . stub ( FabricEnvironmentManager . instance ( ) , 'getConnection' ) . returns ( mockRuntimeConnection ) ; startDebuggingStub = mySandbox . stub ( vscode . debug , 'startDebugging' ) ; showInputBoxStub = mySandbox . stub ( UserInputUtil , 'showInputBox' ) . withArgs ( 'Enter a name for your Go package' ) . resolves ( 'mySmartContract' ) ; showInputBoxStub . withArgs ( 'Enter a version for your Go package' ) . resolves ( '0.0.1' ) ; sendTelemetryEventStub = mySandbox . stub ( Reporter . instance ( ) , 'sendTelemetryEvent' ) ; mySandbox . stub ( GlobalState , 'get' ) . returns ( { generatorVersion : '0.0.36' } ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub = mySandbox . stub ( UserInputUtil , 'showQuickPickItem' ) . resolves ( { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ) ; mySandbox . stub ( LocalMicroEnvironmentManager . instance ( ) , 'ensureRuntime' ) . resolves ( runtimeStub ) ; mySandbox . stub ( FabricDebugConfigurationProvider , 'connectToGateway' ) . resolves ( true ) ; showQuickPickStub = mySandbox . stub ( UserInputUtil , 'showQuickPick' ) ; FabricDebugConfigurationProvider . environmentName = FabricRuntimeUtil . LOCAL_FABRIC ; } ) ; afterEach ( ( ) => { mySandbox . restore ( ) ; } ) ; it ( 'should create a debug configuration' , async ( ) => { const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; should . equal ( config , undefined ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'myLaunch' , program : 'myProgram' , cwd : 'myCwd' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--peer.address' , 'localhost:12345' ] } ) ; sendTelemetryEventStub . should . have . been . calledWith ( 'Smart Contract Debugged' , { language : 'Go' } ) ; } ) ; it ( 'should set mode if not set' , async ( ) => { debugConfig . mode = null ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; should . equal ( config , undefined ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'myLaunch' , program : 'myProgram' , cwd : 'myCwd' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--peer.address' , 'localhost:12345' ] } ) ; sendTelemetryEventStub . should . have . been . calledWith ( 'Smart Contract Debugged' , { language : 'Go' } ) ; } ) ; it ( 'should set program if not set' , async ( ) => { debugConfig . program = null ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; should . equal ( config , undefined ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'myLaunch' , program : path . join ( path . sep , 'myPath' ) , cwd : 'myCwd' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--peer.address' , 'localhost:12345' ] } ) ; sendTelemetryEventStub . should . have . been . calledWith ( 'Smart Contract Debugged' , { language : 'Go' } ) ; } ) ; it ( 'should add cwd if not set' , async ( ) => { debugConfig . cwd = null ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; should . equal ( config , undefined ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'myLaunch' , program : 'myProgram' , cwd : path . sep + 'myPath' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--peer.address' , 'localhost:12345' ] } ) ; } ) ; it ( 'should add args if not defined' , async ( ) => { debugConfig . args = null ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; should . equal ( config , undefined ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'myLaunch' , program : 'myProgram' , cwd : 'myCwd' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--peer.address' , '127.0.0.1:54321' ] } ) ; sendTelemetryEventStub . should . have . been . calledWith ( 'Smart Contract Debugged' , { language : 'Go' } ) ; } ) ; it ( 'should add more args if some args exist' , async ( ) => { debugConfig . args = [ '--myArgs' , 'myValue' ] ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; should . equal ( config , undefined ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'myLaunch' , program : 'myProgram' , cwd : 'myCwd' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--myArgs' , 'myValue' , '--peer.address' , '127.0.0.1:54321' ] } ) ; sendTelemetryEventStub . should . have . been . calledWith ( 'Smart Contract Debugged' , { language : 'Go' } ) ; } ) ; it ( 'should return if peer address is undefined' , async ( ) => { debugConfig . args = [ '--myArgs' , 'myValue' ] ; runtimeStub . numberOfOrgs = 2 ; showQuickPickStub . resolves ( ) ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; should . equal ( config , undefined ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; startDebuggingStub . should . not . have . been . called ; runtimeStub . getAllOrganizationNames . should . have . been . calledOnceWithExactly ( false ) ; showQuickPickStub . should . have . been . calledOnceWithExactly ( 'Select the organization to debug for' , [ 'Org1MSP' , 'Org2MSP' ] ) ; sendTelemetryEventStub . should . not . have . been . called ; should . not . exist ( FabricDebugConfigurationProvider . orgName ) ; } ) ; it ( 'should set correct org if there are multiple' , async ( ) => { debugConfig . args = [ ] ; runtimeStub . numberOfOrgs = 2 ; showQuickPickStub . resolves ( 'Org2MSP' ) ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; should . equal ( config , undefined ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'myLaunch' , program : 'myProgram' , cwd : 'myCwd' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--peer.address' , '127.0.0.1:54321' ] } ) ; runtimeStub . getAllOrganizationNames . should . have . been . calledOnceWithExactly ( false ) ; showQuickPickStub . should . have . been . calledOnceWithExactly ( 'Select the organization to debug for' , [ 'Org1MSP' , 'Org2MSP' ] ) ; sendTelemetryEventStub . should . have . been . calledWith ( 'Smart Contract Debugged' , { language : 'Go' } ) ; FabricDebugConfigurationProvider . orgName . should . equal ( 'Org2' ) ; } ) ; it ( 'should add in request if not defined' , async ( ) => { debugConfig . request = null ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; should . equal ( config , undefined ) ; startDebuggingStub . should . have . been . calledOnceWithExactly ( sinon . match . any , { type : 'go' , mode : 'auto' , request : 'launch' , program : 'myProgram' , cwd : 'myCwd' , debugEvent : FabricGoDebugConfigurationProvider . debugEvent , env : { CORE_CHAINCODE_ID_NAME : `mySmartContract:0.0.1` } , args : [ '--peer.address' , 'localhost:12345' ] } ) ; sendTelemetryEventStub . should . have . been . calledWith ( 'Smart Contract Debugged' , { language : 'Go' } ) ; } ) ; it ( 'should return if no name provided' , async ( ) => { showInputBoxStub . withArgs ( 'Enter a name for your Go package' ) . resolves ( ) ; const config = await fabricDebugConfig . resolveDebugConfiguration ( workspaceFolder , debugConfig ) ; const localEnvironment = EnvironmentFactory . getEnvironment ( environmentRegistry ) as LocalMicroEnvironment ; showQuickPickItemStub . should . have . been . calledOnceWithExactly ( 'Select a local environment to debug' , [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEnvironment } ] ) ; should . not . exist ( config ) ; sendTelemetryEventStub . should . not . have . been . called ; } ) ; } ) ; } ) ;