-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More conservative write #8750
Closed
Closed
More conservative write #8750
Changes from 10 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
242e799
Write to final file only of no exception during write happened
koppor 125e09e
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor 69ba879
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor 048729b
Add log on disk
koppor 2fb0657
Add writing to a local tmp file (instead of somewhere on a network dr…
koppor 1671496
Fix logger
koppor 977e2e2
Change file handling during writing
koppor 292de7a
Initial AtomicFileWriterTest
koppor 3e5f117
Add test case
koppor 902b52e
Revert "Add log on disk"
koppor a9172e6
Merge branch 'main' into more-conservative-save
koppor e948789
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor 67e181c
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor 84d09d2
Fix checkstyle
koppor 1c76e6d
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor 36f4cf1
Remove "keepBackup" from AtomicFileOutputStream
koppor 2d21fe5
Add ADR-0026
koppor be4d336
Add links to ADR
koppor 75e0aed
Use more clear method
koppor 40157de
Fix typos
koppor 9054614
Add getUniqueFilePrefix(Path)
koppor 7bbf120
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor 45d01ac
Fix checkstyle
koppor b8fc4f6
Fix org.jabref.logic.autosaveandbackup.BackupManager#performBackup to…
koppor ba392b3
Fix typos
koppor 4becafb
Move path determination method to FileUtil (will be reused at BackupM…
koppor a35a6de
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor ee078fd
Introduce BackupFileType
koppor bc7853c
Rename method
koppor d1dc0f4
Add test for getPathOfBackupFileAndCreateDirectory()
koppor 8a08df7
Start to implement multiple backups
koppor 34b9dd9
Merge remote-tracking branch 'origin/main' into more-conservative-save
koppor 60ad4d1
Fix AtomicFileOutputStreamTest
koppor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
src/test/java/org/jabref/logic/exporter/AtomicFileOutputStreamTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package org.jabref.logic.exporter; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.nio.file.FileSystem; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
|
||
import com.google.common.base.Strings; | ||
import com.google.common.jimfs.Configuration; | ||
import com.google.common.jimfs.Jimfs; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
koppor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
class AtomicFileOutputStreamTest { | ||
|
||
/** | ||
* Tests whether a failing write to a file keeps the respective .sav file | ||
*/ | ||
@Test | ||
public void savFileExistsOnDiskFull() throws Exception { | ||
String fiftyChars = Strings.repeat("1234567890", 5); | ||
String fiveThousandChars = Strings.repeat("A", 5_000); | ||
|
||
FileSystem fileSystem = Jimfs.newFileSystem( | ||
Configuration.unix().toBuilder() | ||
.setMaxSize(1_000) | ||
.setBlockSize(1_000).build()); | ||
|
||
Path out = fileSystem.getPath("out.bib"); | ||
Files.writeString(out, fiftyChars); | ||
|
||
// Running out of disk space should occur | ||
assertThrows(IOException.class, () -> { | ||
AtomicFileOutputStream atomicFileOutputStream = new AtomicFileOutputStream(out, false); | ||
InputStream inputStream = new ByteArrayInputStream(fiveThousandChars.getBytes()); | ||
inputStream.transferTo(atomicFileOutputStream); | ||
atomicFileOutputStream.close(); | ||
}); | ||
|
||
// Written file still has the contents as before the error | ||
assertEquals(fiftyChars, Files.readString(out)); | ||
} | ||
|
||
@Test | ||
void tempAndBackupDifferentPaths() { | ||
Path testFile = Path.of("test.bib"); | ||
assertNotEquals(AtomicFileOutputStream.getPathOfTemporaryFile(testFile), AtomicFileOutputStream.getPathOfBackupFile(testFile)); | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
src/test/java/org/jabref/logic/exporter/AtomicFileWriterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.jabref.logic.exporter; | ||
|
||
import java.io.StringWriter; | ||
koppor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.Set; | ||
|
||
import org.jabref.logic.util.OS; | ||
koppor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import org.jabref.model.database.BibDatabase; | ||
import org.jabref.model.database.BibDatabaseContext; | ||
import org.jabref.model.entry.BibEntry; | ||
import org.jabref.model.entry.BibEntryTypesManager; | ||
import org.jabref.model.entry.field.StandardField; | ||
import org.jabref.model.metadata.MetaData; | ||
import org.jabref.model.metadata.SaveOrderConfig; | ||
import org.jabref.preferences.GeneralPreferences; | ||
|
||
import com.google.common.base.Strings; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.io.TempDir; | ||
import org.mockito.Answers; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
class AtomicFileWriterTest { | ||
|
||
@Test | ||
void encodingIssueDoesNotLeadToCrash(@TempDir Path tempDir) throws Exception { | ||
Path target = tempDir.resolve("test.txt"); | ||
AtomicFileWriter atomicFileWriter = new AtomicFileWriter(target, StandardCharsets.US_ASCII); | ||
atomicFileWriter.write("ñ"); | ||
atomicFileWriter.close(); | ||
assertTrue(atomicFileWriter.hasEncodingProblems()); | ||
assertEquals(Set.of('ñ'), atomicFileWriter.getEncodingProblems()); | ||
} | ||
|
||
@Test | ||
void bibFileIsKeptAtError(@TempDir Path tempDir) throws Exception { | ||
Path target = tempDir.resolve("test.bib"); | ||
|
||
String fiveThousandChars = Strings.repeat("A", 5_000); | ||
Files.writeString(target, fiveThousandChars); | ||
|
||
AtomicFileWriter fileWriter = new AtomicFileWriter(target, StandardCharsets.UTF_8); | ||
BibDatabase database = new BibDatabase(); | ||
MetaData metaData = new MetaData(); | ||
BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(database, metaData); | ||
BibWriter bibWriter = new BibWriter(fileWriter, "\n"); | ||
|
||
GeneralPreferences generalPreferences = mock(GeneralPreferences.class); | ||
SavePreferences savePreferences = mock(SavePreferences.class, Answers.RETURNS_DEEP_STUBS); | ||
when(savePreferences.getSaveOrder()).thenReturn(new SaveOrderConfig()); | ||
when(savePreferences.takeMetadataSaveOrderInAccount()).thenReturn(true); | ||
BibEntryTypesManager entryTypesManager = new BibEntryTypesManager(); | ||
BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(bibWriter, generalPreferences, savePreferences, entryTypesManager); | ||
|
||
BibEntry bibEntry = new BibEntry().withField(StandardField.NOTE, "{"); | ||
database.insertEntry(bibEntry); | ||
|
||
assertThrows(Exception.class, () -> databaseWriter.saveDatabase(bibDatabaseContext)); | ||
fileWriter.close(); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then hard-exiting JabRef during a write operation may leave the file corrupt and kind of defeats the purpose of the atomic writer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: I'll create an ADR. - The intended implementation fixes #8887.