Completed
Push — master ( 347a51...ad246f )
by Maxence
02:23
created

Test::testUnlockingProcess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
declare(strict_types=1);
3
4
5
/**
6
 * FullTextSearch - Full text search framework for Nextcloud
7
 *
8
 * This file is licensed under the Affero General Public License version 3 or
9
 * later. See the COPYING file.
10
 *
11
 * @author Maxence Lange <[email protected]>
12
 * @copyright 2018
13
 * @license GNU AGPL version 3 or any later version
14
 *
15
 * This program is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
 *
28
 */
29
30
31
namespace OCA\FullTextSearch\Command;
32
33
34
use Exception;
35
use OC\Core\Command\InterruptedException;
36
use OCA\FullTextSearch\ACommandBase;
37
use OCA\FullTextSearch\Exceptions\InterruptException;
38
use OCA\FullTextSearch\Exceptions\ProviderDoesNotExistException;
39
use OCA\FullTextSearch\Exceptions\ProviderIsNotCompatibleException;
40
use OCA\FullTextSearch\Exceptions\ProviderIsNotUniqueException;
41
use OCA\FullTextSearch\Exceptions\RunnerAlreadyUpException;
42
use OCA\FullTextSearch\Exceptions\TickDoesNotExistException;
43
use OCA\FullTextSearch\Model\IndexOptions;
44
use OCA\FullTextSearch\Model\Runner;
45
use OCA\FullTextSearch\Model\SearchRequest;
46
use OCA\FullTextSearch\Model\SearchResult;
47
use OCA\FullTextSearch\Provider\TestProvider;
48
use OCA\FullTextSearch\Service\IndexService;
49
use OCA\FullTextSearch\Service\MiscService;
50
use OCA\FullTextSearch\Service\PlatformService;
51
use OCA\FullTextSearch\Service\ProviderService;
52
use OCA\FullTextSearch\Service\RunningService;
53
use OCA\FullTextSearch\Service\TestService;
54
use OCP\AppFramework\QueryException;
55
use OCP\FullTextSearch\IFullTextSearchPlatform;
56
use OCP\FullTextSearch\IFullTextSearchProvider;
57
use OCP\FullTextSearch\Model\DocumentAccess;
58
use Symfony\Component\Console\Input\InputInterface;
59
use Symfony\Component\Console\Input\InputOption;
60
use Symfony\Component\Console\Output\OutputInterface;
61
62
63
/**
64
 * Class Test
65
 *
66
 * @package OCA\FullTextSearch\Command
67
 */
68
class Test extends ACommandBase {
69
70
	const DELAY_STABILIZE_PLATFORM = 3;
71
72
	/** @var RunningService */
73
	private $runningService;
74
75
	/** @var PlatformService */
76
	private $platformService;
77
78
	/** @var ProviderService */
79
	private $providerService;
80
81
	/** @var IndexService */
82
	private $indexService;
83
84
	/** @var TestService */
85
	private $testService;
86
87
	/** @var MiscService */
88
	private $miscService;
89
90
91
	/** @var Runner */
92
	private $runner;
93
94
	/** @var boolean */
95
	private $isJson = false;
96
97
98
	/**
99
	 * Index constructor.
100
	 *
101
	 * @param RunningService $runningService
102
	 * @param ProviderService $providerService
103
	 * @param IndexService $indexService
104
	 * @param PlatformService $platformService
105
	 * @param TestService $testService
106
	 * @param MiscService $miscService
107
	 */
108 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
109
		RunningService $runningService, PlatformService $platformService,
110
		ProviderService $providerService, IndexService $indexService, TestService $testService,
111
		MiscService $miscService
112
	) {
113
		parent::__construct();
114
115
		$this->runningService = $runningService;
116
		$this->platformService = $platformService;
117
		$this->providerService = $providerService;
118
		$this->indexService = $indexService;
119
		$this->testService = $testService;
120
		$this->miscService = $miscService;
121
	}
122
123
124
	/**
125
	 *
126
	 */
127
	protected function configure() {
128
		parent::configure();
129
		$this->setName('fulltextsearch:test')
130
			 ->setDescription('Testing the platform setup')
131
			 ->addOption('json', 'j', InputOption::VALUE_NONE, 'return result as JSON')
132
			 ->addOption(
133
				 'platform_delay', 'd', InputOption::VALUE_REQUIRED,
134
				 'change DELAY_STABILIZE_PLATFORM'
135
			 );
136
	}
137
138
139
	/**
140
	 * @param InputInterface $input
141
	 * @param OutputInterface $output
142
	 *
143
	 * @throws Exception
144
	 */
145
	protected function execute(InputInterface $input, OutputInterface $output) {
146
		$this->isJson = ($input->getOption('json') === true);
147
		$platformDelay = ($input->getOption('platform_delay') > 0) ? $input->getOption(
148
			'platform_delay'
149
		) : self::DELAY_STABILIZE_PLATFORM;
150
151
		$this->output($output, '.Testing your current setup:');
152
153
		try {
154
			$testProvider = $this->testCreatingProvider($output);
155
			$this->testMockedProvider($output, $testProvider);
156
			$testPlatform = $this->testLoadingPlatform($output);
157
			$this->testLockingProcess($output, $testPlatform, $testProvider);
158
		} catch (Exception $e) {
159
			$this->outputResult($output, false);
160
			throw $e;
161
		}
162
163
		try {
164
			$this->testResetTest($output, $testProvider);
165
			$this->pause($output, $platformDelay);
166
			$this->testInitIndexing($output, $testPlatform);
167
			$this->testIndexingDocuments($output, $testPlatform, $testProvider);
168
			$this->pause($output, $platformDelay);
169
			$this->testContentLicense($output, $testPlatform);
170
			$this->testSearchSimple($output, $testPlatform, $testProvider);
171
			$this->testUpdatingDocumentsAccess($output, $testPlatform, $testProvider);
172
			$this->pause($output, $platformDelay);
173
			$this->testSearchAccess($output, $testPlatform, $testProvider);
174
			$this->testSearchShare($output, $testPlatform, $testProvider);
175
176
			$this->testResetTest($output, $testProvider);
177
			$this->testUnlockingProcess($output);
178
		} catch (Exception $e) {
179
			$this->outputResult($output, false);
180
			$this->output($output, 'Error detected, unlocking process');
181
			$this->runner->stop();
182
			$this->outputResult($output, true);
183
184
			throw $e;
185
		}
186
187
		$this->output($output, '', true);
188
	}
189
190
191
	/**
192
	 * @return IFullTextSearchProvider
193
	 * @throws ProviderIsNotCompatibleException
194
	 * @throws QueryException
195
	 * @throws ProviderDoesNotExistException
196
	 * @throws ProviderIsNotUniqueException
197
	 */
198
	private function generateMockProvider(): IFullTextSearchProvider {
199
		$this->providerService->loadProvider(
200
			'fulltextsearch', 'OCA\FullTextSearch\Provider\TestProvider'
201
		);
202
		$providerWrapper = $this->providerService->getProvider(TestProvider::TEST_PROVIDER_ID);
203
204
		return $providerWrapper->getProvider();
205
	}
206
207
208
	/**
209
	 * @param OutputInterface $output
210
	 * @param string $line
211
	 * @param bool $isNewLine
212
	 */
213
	private function output(OutputInterface $output, string $line, bool $isNewLine = true) {
214
		if ($isNewLine) {
215
			$output->write(' ', true);
216
		}
217
218
		$output->write($line . ' ', false);
219
	}
220
221
222
	/**
223
	 * @param OutputInterface $output
224
	 * @param bool $result
225
	 */
226
	private function outputResult(OutputInterface $output, bool $result) {
227
		$isNewLine = false;
228
		$line = $this->convertBoolToLine($result, $isNewLine);
229
230
		$this->output($output, $line, $isNewLine);
231
	}
232
233
234
	/**
235
	 * @param bool $result
236
	 * @param bool $isNewLine
237
	 *
238
	 * @return string
239
	 */
240
	private function convertBoolToLine(bool $result, bool &$isNewLine): string {
241
		$isNewLine = false;
242
		if ($result === false) {
243
			return '<error>fail</error>';
244
		}
245
246
		return '<info>ok</info>';
247
	}
248
249
250
	/**
251
	 * @param OutputInterface $output
252
	 *
253
	 * @return IFullTextSearchProvider
254
	 * @throws ProviderDoesNotExistException
255
	 * @throws ProviderIsNotCompatibleException
256
	 * @throws ProviderIsNotUniqueException
257
	 * @throws QueryException
258
	 */
259
	private function testCreatingProvider(OutputInterface $output): IFullTextSearchProvider {
260
		$this->output($output, 'Creating mocked content provider.');
261
		$testProvider = $this->generateMockProvider();
262
		$this->outputResult($output, true);
263
264
		return $testProvider;
265
	}
266
267
268
	/**
269
	 * @param OutputInterface $output
270
	 * @param IFullTextSearchProvider $testProvider
271
	 */
272
	private function testMockedProvider(
273
		OutputInterface $output, IFullTextSearchProvider $testProvider
274
	) {
275
		$this->output($output, 'Testing mocked provider: get indexable documents.');
276
		$testProvider->setIndexOptions(new IndexOptions());
277
		$indexableDocuments =
278
			$testProvider->generateIndexableDocuments(TestService::DOCUMENT_USER1);
279
		$this->output($output, '(' . sizeof($indexableDocuments) . ' items)', false);
280
		$this->outputResult($output, true);
281
	}
282
283
284
	/**
285
	 * @param OutputInterface $output
286
	 *
287
	 * @return IFullTextSearchPlatform
288
	 * @throws Exception
289
	 */
290
	private function testLoadingPlatform(OutputInterface $output): IFullTextSearchPlatform {
291
		$this->output($output, 'Loading search platform.');
292
		$wrapper = $this->platformService->getPlatform();
293
		$testPlatform = $wrapper->getPlatform();
294
295
		$this->output($output, '(' . $testPlatform->getName() . ')', false);
296
		$this->outputResult($output, true);
297
298
		$this->output($output, 'Testing search platform.');
299
		if (!$testPlatform->testPlatform()) {
300
			throw new Exception ('Search platform (' . $testPlatform->getName() . ') down ?');
301
		}
302
		$this->outputResult($output, true);
303
304
		return $testPlatform;
305
	}
306
307
	/**
308
	 * @param OutputInterface $output
309
	 * @param IFullTextSearchPlatform $testPlatform
310
	 * @param IFullTextSearchProvider $testProvider
311
	 *
312
	 * @throws RunnerAlreadyUpException
313
	 */
314
	private function testLockingProcess(
315
		OutputInterface $output, IFullTextSearchPlatform $testPlatform,
316
		IFullTextSearchProvider $testProvider
317
	) {
318
		$this->output($output, 'Locking process');
319
		$this->runner = new Runner($this->runningService, 'test');
320
		$this->runner->sourceIsCommandLine($this, $output);
321
		$this->runner->start();
322
		$this->indexService->setRunner($this->runner);
323
		$testPlatform->setRunner($this->runner);
324
		$testProvider->setRunner($this->runner);
325
		$this->outputResult($output, true);
326
	}
327
328
329
	/**
330
	 * @param OutputInterface $output
331
	 * @param IFullTextSearchProvider $testProvider
332
	 *
333
	 * @throws Exception
334
	 */
335
	private function testResetTest(OutputInterface $output, IFullTextSearchProvider $testProvider
336
	) {
337
		$this->output($output, 'Removing test.');
338
		$this->indexService->resetIndex($testProvider->getId());
339
		$this->outputResult($output, true);
340
	}
341
342
343
	/**
344
	 * @param OutputInterface $output
345
	 * @param IFullTextSearchPlatform $testPlatform
346
	 */
347
	private function testInitIndexing(OutputInterface $output, IFullTextSearchPlatform $testPlatform
348
	) {
349
		$this->output($output, 'Initializing index mapping.');
350
		$testPlatform->initializeIndex();
351
		$this->outputResult($output, true);
352
	}
353
354
355
	/**
356
	 * @param OutputInterface $output
357
	 * @param IFullTextSearchPlatform $testPlatform
358
	 * @param IFullTextSearchProvider $testProvider
359
	 *
360
	 * @throws Exception
361
	 */
362
	private function testIndexingDocuments(
363
		OutputInterface $output, IFullTextSearchPlatform $testPlatform,
364
		IFullTextSearchProvider $testProvider
365
	) {
366
		$this->output($output, 'Indexing generated documents.');
367
		$options = new IndexOptions(
368
			[
369
				'provider' => TestProvider::TEST_PROVIDER_ID
370
			]
371
		);
372
		$this->indexService->indexProviderContentFromUser(
373
			$testPlatform, $testProvider, TestService::DOCUMENT_USER1, $options
374
		);
375
		$this->outputResult($output, true);
376
	}
377
378
379
	/**
380
	 * @param OutputInterface $output
381
	 * @param IFullTextSearchPlatform $testPlatform
382
	 *
383
	 * @throws Exception
384
	 */
385
	private function testContentLicense(
386
		OutputInterface $output, IFullTextSearchPlatform $testPlatform
387
	) {
388
389
		try {
390
			$this->output($output, 'Retreiving content from a big index (license).');
391
			$indexDocument = $testPlatform->getDocument(
392
				TestProvider::TEST_PROVIDER_ID, TestService::DOCUMENT_TYPE_LICENSE
393
			);
394
395
			$this->output(
396
				$output, '(size: ' . $indexDocument->getContentSize() . ')', false
397
			);
398
			$this->outputResult($output, true);
399
		} catch (Exception $e) {
400
			throw new Exception(
401
				"Issue while getting test document '" . TestService::DOCUMENT_TYPE_LICENSE
402
				. "' from search platform: " . $e->getMessage()
403
			);
404
		}
405
406
		$this->output($output, 'Comparing document with source.');
407
		$this->testService->compareIndexDocument(
408
			$this->testService->generateIndexDocumentContentLicense(new IndexOptions()),
409
			$indexDocument
410
		);
411
		$this->outputResult($output, true);
412
	}
413
414
415
	/**
416
	 * @param OutputInterface $output
417
	 * @param IFullTextSearchPlatform $testPlatform
418
	 * @param IFullTextSearchProvider $testProvider
419
	 *
420
	 * @throws Exception
421
	 */
422
	private function testSearchSimple(
423
		OutputInterface $output, IFullTextSearchPlatform $testPlatform,
424
		IFullTextSearchProvider $testProvider
425
	) {
426
427
		$this->output($output, 'Searching basic keywords:');
428
429
		$access = new DocumentAccess();
430
		$access->setViewerId(TestService::DOCUMENT_USER1);
431
432
		$this->search(
433
			$output, $testPlatform, $testProvider, $access, 'test',
434
			[TestService::DOCUMENT_TYPE_SIMPLE]
435
		);
436
		$this->search(
437
			$output, $testPlatform, $testProvider, $access, 'document is a simple test',
438
//			[TestService::DOCUMENT_TYPE_SIMPLE]
439
			[TestService::DOCUMENT_TYPE_SIMPLE, TestService::DOCUMENT_TYPE_LICENSE]
440
		);
441
		$this->search(
442
			$output, $testPlatform, $testProvider, $access, '"document is a test"',
443
			[]
444
		);
445
		$this->search(
446
			$output, $testPlatform, $testProvider, $access, '"document is a simple test"',
447
			[TestService::DOCUMENT_TYPE_SIMPLE]
448
		);
449
		$this->search(
450
			$output, $testPlatform, $testProvider, $access, 'document is a simple -test',
451
			[TestService::DOCUMENT_TYPE_LICENSE]
452
		);
453
		$this->search(
454
			$output, $testPlatform, $testProvider, $access, 'document is a simple +test',
455
			[TestService::DOCUMENT_TYPE_SIMPLE]
456
		);
457
		$this->search(
458
			$output, $testPlatform, $testProvider, $access, '-document is a simple test',
459
			[]
460
		);
461
	}
462
463
464
	/**
465
	 * @param OutputInterface $output
466
	 * @param IFullTextSearchPlatform $testPlatform
467
	 * @param IFullTextSearchProvider $testProvider
468
	 *
469
	 * @throws Exception
470
	 */
471
	private function testUpdatingDocumentsAccess(
472
		OutputInterface $output, IFullTextSearchPlatform $testPlatform,
473
		IFullTextSearchProvider $testProvider
474
	) {
475
		$this->output($output, 'Updating documents access.');
476
		$options = new IndexOptions(
477
			[
478
				'provider'                            => TestProvider::TEST_PROVIDER_ID,
479
				TestService::DOCUMENT_INDEXING_OPTION => TestService::DOCUMENT_INDEXING_ACCESS
480
			]
481
		);
482
		$testProvider->setIndexOptions($options);
483
		$this->indexService->indexProviderContentFromUser(
484
			$testPlatform, $testProvider, TestService::DOCUMENT_USER1, $options
485
		);
486
		$this->outputResult($output, true);
487
	}
488
489
490
	/**
491
	 * @param OutputInterface $output
492
	 * @param IFullTextSearchPlatform $platform
493
	 * @param IFullTextSearchProvider $provider
494
	 *
495
	 * @throws Exception
496
	 */
497
	private function testSearchAccess(
498
		OutputInterface $output, IFullTextSearchPlatform $platform,
499
		IFullTextSearchProvider $provider
500
	) {
501
		$this->output($output, 'Searching with group access rights:');
502
503
		$this->searchGroups($output, $platform, $provider, [], []);
504
		$this->searchGroups(
505
			$output, $platform, $provider, [TestService::DOCUMENT_GROUP1],
506
			[TestService::DOCUMENT_TYPE_LICENSE]
507
		);
508
		$this->searchGroups(
509
			$output, $platform, $provider,
510
			[TestService::DOCUMENT_GROUP1, TestService::DOCUMENT_GROUP2],
511
			[TestService::DOCUMENT_TYPE_LICENSE]
512
		);
513
		$this->searchGroups(
514
			$output, $platform, $provider,
515
			[TestService::DOCUMENT_NOTGROUP, TestService::DOCUMENT_GROUP2],
516
			[TestService::DOCUMENT_TYPE_LICENSE]
517
		);
518
		$this->searchGroups($output, $platform, $provider, [TestService::DOCUMENT_NOTGROUP], []);
519
	}
520
521
522
	/**
523
	 * @param OutputInterface $output
524
	 * @param IFullTextSearchPlatform $platform
525
	 * @param IFullTextSearchProvider $provider
526
	 *
527
	 * @throws Exception
528
	 */
529
	private function testSearchShare(
530
		OutputInterface $output, IFullTextSearchPlatform $platform,
531
		IFullTextSearchProvider $provider
532
	) {
533
534
		$this->output($output, 'Searching with share rights:');
535
536
		$this->searchUsers($output, $platform, $provider, TestService::DOCUMENT_NOTUSER, []);
537
		$this->searchUsers($output, $platform, $provider, TestService::DOCUMENT_USER2, ['license']);
538
		$this->searchUsers($output, $platform, $provider, TestService::DOCUMENT_USER3, ['license']);
539
	}
540
541
542
	/**
543
	 * @param OutputInterface $output
544
	 *
545
	 * @throws TickDoesNotExistException
546
	 */
547
	private function testUnlockingProcess(OutputInterface $output) {
548
		$this->output($output, 'Unlocking process');
549
		$this->runner->stop();
550
		$this->outputResult($output, true);
551
	}
552
553
554
	/**
555
	 * @param OutputInterface $output
556
	 * @param IFullTextSearchPlatform $testPlatform
557
	 * @param IFullTextSearchProvider $testProvider
558
	 * @param DocumentAccess $access
559
	 * @param string $search
560
	 * @param array $expected
561
	 * @param string $moreOutput
562
	 *
563
	 * @throws Exception
564
	 */
565
	private function search(
566
		OutputInterface $output, IFullTextSearchPlatform $testPlatform,
567
		IFullTextSearchProvider $testProvider,
568
		DocumentAccess $access, string $search, array $expected, string $moreOutput = ''
569
	) {
570
		$this->output(
571
			$output,
572
			" - '" . $search . "'" . (($moreOutput === '') ? '' : ' - ' . $moreOutput . ' - ')
573
		);
574
		$request = new SearchRequest();
575
576
		$request->setSearch($search);
577
578
		$searchResult = new SearchResult($request);
579
		$searchResult->setProvider($testProvider);
580
		$searchResult->setPlatform($testPlatform);
581
582
		$testPlatform->searchRequest($searchResult, $access);
583
584
		$this->output(
585
			$output,
586
			'(result: ' . $searchResult->getCount() . ', expected: ' . json_encode($expected) . ')',
587
			false
588
		);
589
		$this->compareSearchResult($searchResult, $expected);
590
		$this->outputResult($output, true);
591
	}
592
593
594
	/**
595
	 * @param OutputInterface $output
596
	 * @param IFullTextSearchPlatform $testPlatform
597
	 * @param IFullTextSearchProvider $testProvider
598
	 * @param array $groups
599
	 * @param array $expected
600
	 *
601
	 * @throws Exception
602
	 */
603 View Code Duplication
	private function searchGroups(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
604
		OutputInterface $output, IFullTextSearchPlatform $testPlatform,
605
		IFullTextSearchProvider $testProvider, array $groups, array $expected
606
	) {
607
608
		$access = new DocumentAccess();
609
		$access->setViewerId(TestService::DOCUMENT_NOTUSER);
610
		$access->setGroups($groups);
611
612
		$this->search(
613
			$output, $testPlatform, $testProvider, $access, 'license',
614
			$expected, json_encode($groups)
615
		);
616
	}
617
618
619
	/**
620
	 * @param OutputInterface $output
621
	 * @param IFullTextSearchPlatform $testPlatform
622
	 * @param IFullTextSearchProvider $testProvider
623
	 * @param string $user
624
	 * @param array $expected
625
	 *
626
	 * @throws Exception
627
	 */
628 View Code Duplication
	private function searchUsers(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
629
		OutputInterface $output, IFullTextSearchPlatform $testPlatform,
630
		IFullTextSearchProvider $testProvider, string $user, array $expected
631
	) {
632
		$access = new DocumentAccess();
633
		$access->setViewerId($user);
634
		$this->search(
635
			$output, $testPlatform, $testProvider, $access, 'license',
636
			$expected, $user
637
		);
638
	}
639
640
641
	/**
642
	 * @param SearchResult $searchResult
643
	 * @param array $entries
644
	 *
645
	 * @throws Exception
646
	 */
647
	private function compareSearchResult(SearchResult $searchResult, array $entries) {
648
		$documents = $searchResult->getDocuments();
649
		if (sizeof($documents) !== sizeof($entries)) {
650
			throw new \Exception('Unexpected SearchResult: ' . json_encode($searchResult));
651
		}
652
653
		foreach ($documents as $document) {
654
			if (!in_array($document->getId(), $entries)) {
655
				throw new \Exception('Unexpected Document: ' . json_encode($document));
656
			}
657
		}
658
	}
659
660
661
	/**
662
	 * @param OutputInterface $output
663
	 * @param int $s
664
	 *
665
	 * @throws InterruptException
666
	 */
667
	private function pause(OutputInterface $output, int $s) {
668
		$this->output($output, 'Pausing ' . $s . ' seconds');
669
670
		for ($i = 1; $i <= $s; $i++) {
671
			if (time_nanosleep(1, 0) !== true) {
672
				throw new InterruptException('Interrupted by user');
673
			}
674
675
			$this->output($output, (string)$i, false);
676
		}
677
678
		$this->outputResult($output, true);
679
	}
680
681
682
	/**
683
	 * @throws TickDoesNotExistException
684
	 */
685
	public function abort() {
686
		try {
687
			$this->abortIfInterrupted();
688
		} catch (InterruptedException $e) {
0 ignored issues
show
Bug introduced by
The class OC\Core\Command\InterruptedException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
689
			$this->runner->stop();
690
			exit();
691
		}
692
	}
693
694
}
695
696
697
698