Update the license headers throughout the repository to reference Google LLC rather than Google Inc, for the required license headers. PR Close #37205
		
			
				
	
	
		
			137 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright Google LLC All Rights Reserved.
 | |
|  *
 | |
|  * Use of this source code is governed by an MIT-style license that can be
 | |
|  * found in the LICENSE file at https://angular.io/license
 | |
|  */
 | |
| 
 | |
| /// <reference types="node" />
 | |
| 
 | |
| import {getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
 | |
| import * as cluster from 'cluster';
 | |
| 
 | |
| import {MockFileSystemNative, runInEachFileSystem} from '../../../../src/ngtsc/file_system/testing';
 | |
| import {ClusterExecutor} from '../../../src/execution/cluster/executor';
 | |
| import {ClusterMaster} from '../../../src/execution/cluster/master';
 | |
| import {AsyncLocker} from '../../../src/locking/async_locker';
 | |
| import {FileWriter} from '../../../src/writing/file_writer';
 | |
| import {PackageJsonUpdater} from '../../../src/writing/package_json_updater';
 | |
| import {MockLockFile} from '../../helpers/mock_lock_file';
 | |
| import {MockLogger} from '../../helpers/mock_logger';
 | |
| import {mockProperty} from '../../helpers/spy_utils';
 | |
| 
 | |
| runInEachFileSystem(() => {
 | |
|   describe('ClusterExecutor', () => {
 | |
|     const runAsClusterMaster = mockProperty(cluster, 'isMaster');
 | |
|     let masterRunSpy: jasmine.Spy;
 | |
|     let mockLogger: MockLogger;
 | |
|     let lockFileLog: string[];
 | |
|     let mockLockFile: MockLockFile;
 | |
|     let locker: AsyncLocker;
 | |
|     let executor: ClusterExecutor;
 | |
|     let createTaskCompletedCallback: jasmine.Spy;
 | |
| 
 | |
|     beforeEach(() => {
 | |
|       masterRunSpy = spyOn(ClusterMaster.prototype, 'run')
 | |
|                          .and.returnValue(Promise.resolve('CusterMaster#run()' as any));
 | |
|       createTaskCompletedCallback = jasmine.createSpy('createTaskCompletedCallback');
 | |
| 
 | |
|       mockLogger = new MockLogger();
 | |
|       lockFileLog = [];
 | |
|       mockLockFile = new MockLockFile(new MockFileSystemNative(), lockFileLog);
 | |
|       locker = new AsyncLocker(mockLockFile, mockLogger, 200, 2);
 | |
|       executor = new ClusterExecutor(
 | |
|           42, getFileSystem(), mockLogger, null as unknown as FileWriter,
 | |
|           null as unknown as PackageJsonUpdater, locker, createTaskCompletedCallback);
 | |
|     });
 | |
| 
 | |
|     describe('execute()', () => {
 | |
|       beforeEach(() => runAsClusterMaster(true));
 | |
| 
 | |
|       it('should log debug info about the executor', async () => {
 | |
|         const anyFn: () => any = () => undefined;
 | |
|         await executor.execute(anyFn, anyFn);
 | |
| 
 | |
|         expect(mockLogger.logs.debug).toEqual([
 | |
|           ['Running ngcc on ClusterExecutor (using 42 worker processes).'],
 | |
|         ]);
 | |
|       });
 | |
| 
 | |
|       it('should delegate to `ClusterMaster#run()`', async () => {
 | |
|         const analyzeEntryPointsSpy = jasmine.createSpy('analyzeEntryPoints');
 | |
|         const createCompilerFnSpy = jasmine.createSpy('createCompilerFn');
 | |
| 
 | |
|         expect(await executor.execute(analyzeEntryPointsSpy, createCompilerFnSpy))
 | |
|             .toBe('CusterMaster#run()' as any);
 | |
| 
 | |
|         expect(masterRunSpy).toHaveBeenCalledWith();
 | |
| 
 | |
|         expect(analyzeEntryPointsSpy).toHaveBeenCalledWith();
 | |
|         expect(createCompilerFnSpy).not.toHaveBeenCalled();
 | |
|       });
 | |
| 
 | |
|       it('should call LockFile.write() and LockFile.remove() if master runner completes successfully',
 | |
|          async () => {
 | |
|            const anyFn: () => any = () => undefined;
 | |
|            await executor.execute(anyFn, anyFn);
 | |
|            expect(lockFileLog).toEqual(['write()', 'remove()']);
 | |
|          });
 | |
| 
 | |
|       it('should call LockFile.write() and LockFile.remove() if master runner fails', async () => {
 | |
|         const anyFn: () => any = () => undefined;
 | |
|         masterRunSpy.and.returnValue(Promise.reject(new Error('master runner error')));
 | |
|         let error = '';
 | |
|         try {
 | |
|           await executor.execute(anyFn, anyFn);
 | |
|         } catch (e) {
 | |
|           error = e.message;
 | |
|         }
 | |
|         expect(error).toEqual('master runner error');
 | |
|         expect(lockFileLog).toEqual(['write()', 'remove()']);
 | |
|       });
 | |
| 
 | |
|       it('should not call master runner if LockFile.write() fails', async () => {
 | |
|         const anyFn: () => any = () => undefined;
 | |
|         spyOn(mockLockFile, 'write').and.callFake(() => {
 | |
|           lockFileLog.push('write()');
 | |
|           throw new Error('LockFile.write() error');
 | |
|         });
 | |
| 
 | |
|         executor = new ClusterExecutor(
 | |
|             42, getFileSystem(), mockLogger, null as unknown as FileWriter,
 | |
|             null as unknown as PackageJsonUpdater, locker, createTaskCompletedCallback);
 | |
|         let error = '';
 | |
|         try {
 | |
|           await executor.execute(anyFn, anyFn);
 | |
|         } catch (e) {
 | |
|           error = e.message;
 | |
|         }
 | |
|         expect(error).toEqual('LockFile.write() error');
 | |
|         expect(masterRunSpy).not.toHaveBeenCalled();
 | |
|       });
 | |
| 
 | |
|       it('should fail if LockFile.remove() fails', async () => {
 | |
|         const anyFn: () => any = () => undefined;
 | |
|         spyOn(mockLockFile, 'remove').and.callFake(() => {
 | |
|           lockFileLog.push('remove()');
 | |
|           throw new Error('LockFile.remove() error');
 | |
|         });
 | |
| 
 | |
|         executor = new ClusterExecutor(
 | |
|             42, getFileSystem(), mockLogger, null as unknown as FileWriter,
 | |
|             null as unknown as PackageJsonUpdater, locker, createTaskCompletedCallback);
 | |
|         let error = '';
 | |
|         try {
 | |
|           await executor.execute(anyFn, anyFn);
 | |
|         } catch (e) {
 | |
|           error = e.message;
 | |
|         }
 | |
|         expect(error).toEqual('LockFile.remove() error');
 | |
|         expect(lockFileLog).toEqual(['write()', 'remove()']);
 | |
|         expect(masterRunSpy).toHaveBeenCalled();
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| });
 |