22 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33 * SPDX-License-Identifier: Apache-2.0
44 */
5-
5+ import * as vscode from 'vscode'
66import assert from 'assert'
7- import * as fs from 'fs-extra'
87import * as sinon from 'sinon'
9- import { makeTemporaryToolkitFolder , tryRemoveFolder } from '../../../shared/filesystemUtilities '
8+ import * as path from 'path '
109import { SshKeyPair } from '../../../awsService/ec2/sshKeyPair'
10+ import { createTestWorkspaceFolder , installFakeClock } from '../../testUtil'
11+ import { InstalledClock } from '@sinonjs/fake-timers'
1112import { ChildProcess } from '../../../shared/utilities/childProcess'
13+ import { fs } from '../../../shared'
1214
1315describe ( 'SshKeyUtility' , async function ( ) {
1416 let temporaryDirectory : string
1517 let keyPath : string
1618 let keyPair : SshKeyPair
19+ let clock : InstalledClock
1720
1821 before ( async function ( ) {
19- temporaryDirectory = await makeTemporaryToolkitFolder ( )
20- keyPath = `${ temporaryDirectory } /test-key`
21- keyPair = await SshKeyPair . getSshKeyPair ( keyPath )
22+ temporaryDirectory = ( await createTestWorkspaceFolder ( ) ) . uri . fsPath
23+ keyPath = path . join ( temporaryDirectory , 'testKeyPair' )
24+ clock = installFakeClock ( )
25+ } )
26+
27+ beforeEach ( async function ( ) {
28+ keyPair = await SshKeyPair . getSshKeyPair ( keyPath , 30000 )
29+ } )
30+
31+ afterEach ( async function ( ) {
32+ await keyPair . delete ( )
2233 } )
2334
2435 after ( async function ( ) {
25- await tryRemoveFolder ( temporaryDirectory )
36+ await keyPair . delete ( )
37+ clock . uninstall ( )
38+ sinon . restore ( )
2639 } )
2740
2841 describe ( 'generateSshKeys' , async function ( ) {
2942 it ( 'generates key in target file' , async function ( ) {
30- const contents = await fs . readFile ( keyPath , 'utf-8' )
43+ const contents = await vscode . workspace . fs . readFile ( vscode . Uri . file ( keyPath ) )
3144 assert . notStrictEqual ( contents . length , 0 )
3245 } )
3346
47+ it ( 'generates unique key each time' , async function ( ) {
48+ const beforeContent = await vscode . workspace . fs . readFile ( vscode . Uri . file ( keyPath ) )
49+ keyPair = await SshKeyPair . getSshKeyPair ( keyPath , 30000 )
50+ const afterContent = await vscode . workspace . fs . readFile ( vscode . Uri . file ( keyPath ) )
51+ assert . notStrictEqual ( beforeContent , afterContent )
52+ } )
53+
3454 it ( 'uses ed25519 algorithm to generate the keys' , async function ( ) {
3555 const process = new ChildProcess ( `ssh-keygen` , [ '-vvv' , '-l' , '-f' , keyPath ] )
3656 const result = await process . run ( )
@@ -48,10 +68,42 @@ describe('SshKeyUtility', async function () {
4868 assert . notStrictEqual ( key . length , 0 )
4969 } )
5070
51- it ( 'does not overwrite existing keys' , async function ( ) {
52- const generateStub = sinon . stub ( SshKeyPair , 'generateSshKeyPair' )
53- await SshKeyPair . getSshKeyPair ( keyPath )
54- sinon . assert . notCalled ( generateStub )
71+ it ( 'does overwrite existing keys on get call' , async function ( ) {
72+ const generateStub = sinon . spy ( SshKeyPair , 'generateSshKeyPair' )
73+ const keyBefore = await vscode . workspace . fs . readFile ( vscode . Uri . file ( keyPath ) )
74+ keyPair = await SshKeyPair . getSshKeyPair ( keyPath , 30000 )
75+
76+ const keyAfter = await vscode . workspace . fs . readFile ( vscode . Uri . file ( keyPath ) )
77+ sinon . assert . calledOnce ( generateStub )
78+
79+ assert . notStrictEqual ( keyBefore , keyAfter )
80+ sinon . restore ( )
81+ } )
82+
83+ it ( 'deletes key on delete' , async function ( ) {
84+ const pubKeyExistsBefore = await fs . existsFile ( keyPair . getPublicKeyPath ( ) )
85+ const privateKeyExistsBefore = await fs . existsFile ( keyPair . getPrivateKeyPath ( ) )
86+
87+ await keyPair . delete ( )
88+
89+ const pubKeyExistsAfter = await fs . existsFile ( keyPair . getPublicKeyPath ( ) )
90+ const privateKeyExistsAfter = await fs . existsFile ( keyPair . getPrivateKeyPath ( ) )
91+
92+ assert . strictEqual ( pubKeyExistsBefore && privateKeyExistsBefore , true )
93+ assert . strictEqual ( pubKeyExistsAfter && privateKeyExistsAfter , false )
94+ assert ( keyPair . isDeleted ( ) )
95+ } )
96+
97+ it ( 'deletes keys after timeout' , async function ( ) {
98+ // Stub methods interacting with file system to avoid flaky test.
99+ sinon . stub ( SshKeyPair , 'generateSshKeyPair' )
100+ const deleteStub = sinon . stub ( SshKeyPair . prototype , 'delete' )
101+
102+ keyPair = await SshKeyPair . getSshKeyPair ( keyPath , 50 )
103+ await clock . tickAsync ( 10 )
104+ sinon . assert . notCalled ( deleteStub )
105+ await clock . tickAsync ( 100 )
106+ sinon . assert . calledOnce ( deleteStub )
55107 sinon . restore ( )
56108 } )
57109} )
0 commit comments