1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import * as fs from 'fs'; 17import mocha from 'mocha'; 18import { TimeTracker, TimeSumPrinter } from '../../../src/utils/PrinterUtils'; 19import { assert, expect } from 'chai'; 20import { isFileExist } from '../../../src/initialization/utils'; 21const sinon = require('sinon'); 22 23describe('test Cases for <PrinterUtils>.', function () { 24 describe('Tester Cases for <TimeTracker>.', function () { 25 let printer: TimeTracker; 26 27 beforeEach(() => { 28 printer = new TimeTracker(); 29 }) 30 31 describe('Tester Cases for <setOutputPath>.', function () { 32 /** test for setOutputPath */ 33 it('Tester: <setOutputPath> case for TimeTracker#setOutputPath', function () { 34 let path = 'test/ut/utils/demo1.txt'; 35 printer.setOutputPath(path); 36 let content: string = printer.getOutputPath(); 37 assert.strictEqual(content, path); 38 }); 39 }); 40 41 describe('Tester Cases for <print>.', function () { 42 /** test for print */ 43 it('Tester: <available outputPath> case for TimeTracker#print', function () { 44 let path = 'test/ut/utils/testTimeTrackerPrint.txt'; 45 printer.setOutputPath(path); 46 printer.print('available outputPath case'); 47 let content: string = fs.readFileSync(path, 'utf-8'); 48 assert.strictEqual(content, 'available outputPath case\n'); 49 fs.unlinkSync(path); 50 }); 51 52 it('Tester: <unavailable outputPath> case for TimeTracker#print', function () { 53 let path = 'test/ut/utils/demo2.txt'; 54 let message = 'unavailable outputPath case'; 55 var spy = sinon.spy(console, 'log'); 56 printer.print(message); 57 assert(spy.calledWith(message), message); 58 assert.strictEqual(isFileExist(path), false); 59 spy.restore(); 60 }); 61 }); 62 63 describe('Tester Cases for <startEvent>.', function () { 64 /** test for startEvent */ 65 it('Tester: <start test event> case for TimeTracker#startEvent', function () { 66 let eventName = 'test event'; 67 let path = 'test/ut/utils/testTimeTrackerPrint.txt'; 68 let message = 'start test event'; 69 printer.setOutputPath(path); 70 printer.startEvent(eventName, undefined, message); 71 const eventData = printer.getEventStack().get(eventName); 72 expect(eventData?.duration).to.equal(0); 73 expect(eventData?.endMemory).to.equal(0); 74 expect(eventData?.memoryUsage).to.equal(0); 75 assert.strictEqual(isFileExist(path), false); 76 }); 77 78 it('Tester: <start create ast event> case for TimeTracker#startEvent', function () { 79 let eventName = 'Create AST'; 80 let path = 'test/ut/utils/testTimeTrackerPrint.txt'; 81 let message = 'start Create AST event'; 82 printer.setOutputPath(path); 83 printer.startEvent(eventName, undefined, message); 84 let content: string = fs.readFileSync(path, 'utf-8'); 85 const eventData = printer.getEventStack().get(eventName); 86 expect(eventData?.duration).to.equal(0); 87 expect(eventData?.endMemory).to.equal(0); 88 expect(eventData?.memoryUsage).to.equal(0); 89 assert.strictEqual(content, 'start Create AST event\n'); 90 fs.unlinkSync(path); 91 }); 92 }); 93 94 describe('Tester Cases for <endEvent>.', function () { 95 /** test for endEvent */ 96 it('should throw an error if the event has not started', function () { 97 let eventName = ''; 98 let path = 'test/ut/utils/demo1.txt'; 99 printer.setOutputPath(path); 100 printer.startEvent('test event'); 101 expect(() => printer.endEvent(eventName)).to.throw(`Event "${eventName}" not started`); 102 }); 103 104 it('should calculate duration and memory usage correctly', () => { 105 const eventName = 'test Event'; 106 printer.getEventStack().set(eventName, 107 { start: 0, duration: 0, startMemory: 0, endMemory: 0, memoryUsage: 0}); 108 printer.endEvent(eventName); 109 const eventData = printer.getEventStack().get(eventName); 110 expect(eventData?.duration).to.not.equal(0); 111 expect(eventData?.endMemory).to.not.equal(0); 112 expect(eventData?.memoryUsage).to.not.equal(0); 113 }); 114 115 it('should update filesTimeSum and maxTimeUsage when isFilesPrinter is true', () => { 116 const eventName = 'file Event'; 117 const startMemory = process.memoryUsage().heapUsed; 118 printer.getEventStack().set(eventName, 119 { start: 0, duration: 0, startMemory: startMemory, endMemory: 0, memoryUsage: 0}); 120 printer.endEvent(eventName, undefined, true); 121 expect(printer.getFilesTimeSum()).to.not.equal(0); 122 expect(printer.getMaxTimeUsage()).to.not.equal(0); 123 expect(printer.getMaxTimeFile()).to.equal(eventName); 124 }); 125 126 it('should update maxMemoryUsage and maxMemoryFile when isFilesPrinter is true', () => { 127 const eventName = 'file Event'; 128 const startTime = Date.now(); 129 printer.getEventStack().set(eventName, 130 { start: startTime, duration: 0, startMemory: 0, endMemory: 0, memoryUsage: 0}); 131 printer.endEvent(eventName, undefined, true); 132 expect(printer.getMaxMemoryUsage()).to.not.equal(0); 133 expect(printer.getMaxMemoryFile()).to.equal(eventName); 134 }); 135 136 it('should output data and print max time and memory usage for ALL_FILES_OBFUSCATION', () => { 137 const eventName = 'All files obfuscation'; 138 let path = 'test/ut/utils/demo1.txt'; 139 printer.setOutputPath(path); 140 printer.getEventStack().set(eventName, { start: 0, duration: 0, startMemory: 0, endMemory: 0, memoryUsage: 0}); 141 printer.endEvent(eventName); 142 let content: string = fs.readFileSync(path, 'utf-8'); 143 const lines = content.split('\n'); 144 const firstLine = lines[0].split(':'); 145 const secondLine = lines[2].split(':'); 146 const thirdLine = lines[3].split(':'); 147 assert.strictEqual(firstLine[0], 'All files obfuscation'); 148 assert.strictEqual(secondLine[0], 'Max time cost'); 149 assert.strictEqual(thirdLine[0], 'Max memory usage'); 150 fs.unlinkSync(path); 151 }); 152 153 it('should output data for CREATE_PRINTER', () => { 154 const eventName = 'Create Printer'; 155 const startMemory = process.memoryUsage().heapUsed; 156 let path = 'test/ut/utils/demo1.txt'; 157 printer.setOutputPath(path); 158 printer.getEventStack().set(eventName, 159 { start: Date.now(), duration: 0, startMemory: startMemory, endMemory: 0, memoryUsage: 0}); 160 printer.endEvent(eventName); 161 let content: string = fs.readFileSync(path, 'utf-8'); 162 const firstLine = content.split(':'); 163 assert.strictEqual(firstLine[0], ' Create Printer'); 164 fs.unlinkSync(path); 165 }); 166 }); 167 168 describe('Tester Cases for <getCurrentEventData>.', function () { 169 it('should return a string with formatted event data', () => { 170 const eventName = 'test event'; 171 printer.getEventStack().set(eventName, 172 { start: 0, duration: 10, startMemory: 1024, endMemory: 2048, memoryUsage: 1024}); 173 const actualOutput: string = printer.getCurrentEventData(); 174 const expectOutput: string = 'test event: timeCost:10.000s startMemory:0.001MB endMemory:0.002MB memoryUsage:0.001MB\n'; 175 expect(actualOutput).to.equal(expectOutput); 176 }); 177 }); 178 179 describe('Tester Cases for <getEventStack>', () => { 180 181 it('should return the event stack', () => { 182 printer.startEvent('test event'); 183 const eventStack = printer.getEventStack(); 184 expect(eventStack).to.have.keys(['test event']); 185 expect(eventStack.get('test event')?.start).to.closeTo(Date.now(), 10); 186 expect(eventStack.get('test event')?.duration).to.equal(0); 187 expect(eventStack.get('test event')?.endMemory).to.equal(0); 188 expect(eventStack.get('test event')?.memoryUsage).to.equal(0); 189 }); 190 }); 191 }); 192 193 194 describe('Tester Cases for <TimeSumPrinter>.', function () { 195 let printer: TimeSumPrinter; 196 197 beforeEach(() => { 198 printer = new TimeSumPrinter(); 199 }) 200 201 describe('Tester Cases for <addEventDuration>.', function () { 202 /** test for addEventDuration */ 203 it('should add duration to the event sum', function () { 204 printer.addEventDuration('test event1', 10); 205 printer.addEventDuration('test event2', 20); 206 printer.addEventDuration('test event1', 30); 207 const event1Duration = printer.getEventSum().get('test event1'); 208 const event2Duration = printer.getEventSum().get('test event2'); 209 expect(event1Duration).to.equal(40); 210 expect(event2Duration).to.equal(20); 211 }); 212 }); 213 214 describe('Tester Cases for <summarizeEventDuration>.', function () { 215 /** test for summarizeEventDuration */ 216 it('should print the summarized event data', function () { 217 let path = 'test/ut/utils/demo1.txt'; 218 printer.setOutputPath(path); 219 printer.addEventDuration('test event1', 10); 220 printer.addEventDuration('test event2', 20); 221 printer.addEventDuration('test event1', 30); 222 printer.summarizeEventDuration(); 223 let content: string = fs.readFileSync(path, 'utf-8'); 224 const expectOutput = "test event1: 40.000s\ntest event2: 20.000s\n\n"; 225 expect(content).to.equal(expectOutput); 226 fs.unlinkSync(path); 227 }); 228 }); 229 230 describe('Tester Cases for <getCurrentEventData>.', function () { 231 it('should return a string with formatted event data', () => { 232 const eventName = 'test event'; 233 printer.getEventSum().set(eventName, 10); 234 const actualOutput: string = printer.getCurrentEventData(); 235 const expectOutput: string = 'test event: 10.000s\n'; 236 expect(actualOutput).to.equal(expectOutput); 237 }); 238 }); 239 240 describe('Tester Cases for <getEventSum>', () => { 241 it('should return the event sum', () => { 242 printer.addEventDuration('test event', 10); 243 const eventSum = printer.getEventSum(); 244 expect(eventSum).to.have.keys(['test event']); 245 expect(eventSum.get('test event')).to.equal(10); 246 }); 247 }); 248 }); 249}); 250 251 252 253 254