@Test void shouldThrowIfTheArchiveFormatIsInvalid() throws IOException, IncorrectFormat { doThrow( IncorrectFormat.class ).when( loader ).load( any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( null ) ); assertThat( commandFailed.getMessage(), containsString( archive.toString() ) ); assertThat( commandFailed.getMessage(), containsString( "valid Neo4j archive" ) ); }
@Test void shouldGiveAClearMessageIfTheArchivesParentDoesntExist() throws Exception { doThrow( new NoSuchFileException( archive.getParent().toString() ) ).when( dumper ).dump(any(), any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db" ) ); assertEquals( "unable to dump database: NoSuchFileException: " + archive.getParent(), commandFailed.getMessage() ); }
@Test void databaseThatRequireRecoveryIsNotDumpable() throws IOException { File logFile = new File( databaseDirectory.toFile(), TransactionLogFiles.DEFAULT_NAME + ".0" ); try ( FileWriter fileWriter = new FileWriter( logFile ) ) { fileWriter.write( "brb" ); } CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db" ) ); assertThat( commandFailed.getMessage(), startsWith( "Active logical log detected, this might be a source of inconsistencies." ) ); }
@Test void shouldWrapIOExceptionsCarefullyBecauseCriticalInformationIsOftenEncodedInTheirNameButMissingFromTheirMessage() throws Exception { doThrow( new IOException( "the-message" ) ).when( dumper ).dump(any(), any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db" ) ); assertEquals( "unable to dump database: IOException: the-message", commandFailed.getMessage() ); }
@Test void shouldGiveAClearMessageIfTheDatabasesDirectoryIsNotWritable() throws IOException, IncorrectFormat { doThrow( AccessDeniedException.class ).when( loader ).load( any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( null ) ); assertEquals( "you do not have permission to load a database -- is Neo4j running as a different user?", commandFailed.getMessage() ); }
@Test void shouldGiveAClearMessageIfTheDatabaseAlreadyExists() throws IOException, IncorrectFormat, IncorrectUsage { doThrow( FileAlreadyExistsException.class ).when( loader ).load( any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db" ) ); assertEquals( "database already exists: foo.db", commandFailed.getMessage() ); }
@Test void shouldGiveAClearErrorIfTheArchiveAlreadyExists() throws Exception { doThrow( new FileAlreadyExistsException( "the-archive-path" ) ).when( dumper ).dump( any(), any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db" ) ); assertEquals( "archive already exists: the-archive-path", commandFailed.getMessage() ); }
@Test void shouldGiveAClearMessageIfTheArchiveDoesntExist() throws IOException, IncorrectFormat { doThrow( new NoSuchFileException( archive.toString() ) ).when( loader ).load( any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( null ) ); assertEquals( "archive does not exist: " + archive, commandFailed.getMessage() ); }
@Test void shouldWrapIOExceptionsCarefullyBecauseCriticalInformationIsOftenEncodedInTheirNameButMissingFromTheirMessage() throws IOException, IncorrectFormat { doThrow( new FileSystemException( "the-message" ) ).when( loader ).load( any(), any(), any() ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( null ) ); assertEquals( "unable to load database: FileSystemException: the-message", commandFailed.getMessage() ); }
@Test void failsWhenInconsistenciesAreFound() throws Exception { ConsistencyCheckService consistencyCheckService = mock( ConsistencyCheckService.class ); Path homeDir = testDir.directory( "home" ).toPath(); File databasesFolder = getDatabasesFolder( homeDir ); CheckConsistencyCommand checkConsistencyCommand = new CheckConsistencyCommand( homeDir, testDir.directory( "conf" ).toPath(), consistencyCheckService ); DatabaseLayout databaseLayout = DatabaseLayout.of( databasesFolder, "mydb" ); when( consistencyCheckService .runFullConsistencyCheck( eq( databaseLayout ), any( Config.class ), any( ProgressMonitorFactory.class ), any( LogProvider.class ), any( FileSystemAbstraction.class ), eq( true ), any(), any( ConsistencyFlags.class ) ) ) .thenReturn( ConsistencyCheckService.Result.failure( new File( "/the/report/path" ) ) ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> checkConsistencyCommand.execute( new String[]{"--database=mydb", "--verbose"} ) ); assertThat( commandFailed.getMessage(), containsString( new File( "/the/report/path" ).toString() ) ); }
@Test void exitIfConfigFileIsMissing() throws IOException { Files.delete( configFile ); String[] args = {"--list"}; try ( RealOutsideWorld outsideWorld = new RealOutsideWorld() ) { DiagnosticsReportCommand diagnosticsReportCommand = new DiagnosticsReportCommand( homeDir, configDir, outsideWorld ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> diagnosticsReportCommand.execute( args ) ); assertThat( commandFailed.getMessage(), containsString( "Unable to find config file, tried: " ) ); } }
@Test void backupNeedsToBePath() { ConsistencyCheckService consistencyCheckService = mock( ConsistencyCheckService.class ); Path homeDir = testDir.directory( "home" ).toPath(); CheckConsistencyCommand checkConsistencyCommand = new CheckConsistencyCommand( homeDir, testDir.directory( "conf" ).toPath(), consistencyCheckService ); File backupPath = new File( homeDir.toFile(), "dir/does/not/exist" ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> checkConsistencyCommand.execute( new String[]{"--backup=" + backupPath} ) ); assertEquals( "Specified backup should be a directory: " + backupPath, commandFailed.getMessage() ); }
@Test void shouldGiveAClearMessageIfTheDatabaseDoesntExist() { CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "bobo.db" ) ); assertEquals( "database does not exist: bobo.db", commandFailed.getMessage() ); }
@Test void shouldRespectTheStoreLock() throws IOException { Path databaseDirectory = homeDir.resolve( "data/databases/foo.db" ); Files.createDirectories( databaseDirectory ); StoreLayout storeLayout = DatabaseLayout.of( databaseDirectory.toFile() ).getStoreLayout(); try ( FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction(); StoreLocker locker = new StoreLocker( fileSystem, storeLayout ) ) { locker.checkLock(); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db", "--force" ) ); assertEquals( "the database is in use -- stop Neo4j and try again", commandFailed.getMessage() ); } }
@Test void shouldRespectTheStoreLock() throws Exception { Path databaseDirectory = homeDir.resolve( "data/databases/foo.db" ); StoreLayout storeLayout = DatabaseLayout.of( databaseDirectory.toFile() ).getStoreLayout(); try ( FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction(); StoreLocker storeLocker = new StoreLocker( fileSystem, storeLayout ) ) { storeLocker.checkLock(); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db" ) ); assertEquals( "the database is in use -- stop Neo4j and try again", commandFailed.getMessage() ); } }
@Test @DisabledOnOs( OS.WINDOWS ) void shouldReportAHelpfulErrorIfWeDontHaveWritePermissionsForLock() throws Exception { StoreLayout storeLayout = DatabaseLayout.of( databaseDirectory.toFile() ).getStoreLayout(); try ( FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction(); StoreLocker storeLocker = new StoreLocker( fileSystem, storeLayout ) ) { storeLocker.checkLock(); try ( Closeable ignored = withPermissions( storeLayout.storeLockFile().toPath(), emptySet() ) ) { CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> execute( "foo.db" ) ); assertEquals( commandFailed.getMessage(), "you do not have permission to dump the database -- is Neo4j running as a different user?" ); } } }
@Test void errorOnInvalidPid() throws Exception { String[] args = {"--pid=a", "all"}; try ( RealOutsideWorld outsideWorld = new RealOutsideWorld() ) { DiagnosticsReportCommand diagnosticsReportCommand = new DiagnosticsReportCommand( homeDir, configDir, outsideWorld ); CommandFailed commandFailed = assertThrows( CommandFailed.class, () -> diagnosticsReportCommand.execute( args ) ); assertEquals( "Unable to parse --pid", commandFailed.getMessage() ); } } }