Для приложения Spring Boot, которое будет проверять файлы резервных копий на NAS-устройстве Synology RS815 +, мы хотели иметь возможность легко протестировать файлы, хранящиеся на этом NAS, без необходимости копировать 7 ТБ, хранящиеся на нем.
В идеале мы хотели создать такую же файловую структуру для использования веб-приложения в профиле разработки Spring, а также использовать эти файловые структуры в тесте JUnit.
Представляем FileStructureCreator
Мы начали с создания нового класса FileStructureCreator
который выглядит следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
@Getter @Setter public class FileStructureCreator implements Closeable { public static final Path baseTestPath = Paths.get( "testFiles" ); private Path fileStructureBasePath; public static FileStructureCreator create(Path file) { return createStructure(file, false ); } public static FileStructureCreator createTempDirectory(Path file) { return createStructure(file, true ); } @SneakyThrows private static FileStructureCreator createStructure(Path file, boolean createTempDirectory) { FileStructureCreator fileStructureCreator = new FileStructureCreator(); if (!Files.exists(baseTestPath)) { Files.createDirectory(baseTestPath); } String path = baseTestPath.toString() + (createTempDirectory ? "/" + UUID.randomUUID().toString() : "" ) + "/" ; Path basePath = Paths.get(path); fileStructureCreator.setFileStructureBasePath(basePath); FileUtils.forceMkdir(basePath.toFile()); try (Stream<String> stream = Files.lines(file)) { stream.forEach(line -> { Metadata fileMetaData = Metadata.from(line); Path fileEntry = Paths.get(path + fileMetaData.getWindowsSafeFilename()); try { FileUtils.forceMkdir(fileEntry.getParent().toFile()); if (!Files.exists(fileEntry)) { Files.write(fileEntry, line.getBytes()); Files.setLastModifiedTime(fileEntry, FileTime.from(fileMetaData.getModificationTime())); } } catch (IOException ignore) { throw new RuntimeException( "Exception creating directory: " + fileEntry.getParent()); } }); } return fileStructureCreator; } @Override @SneakyThrows public void close() { if (fileStructureBasePath != null ) { FileUtils.deleteDirectory(fileStructureBasePath.toFile()); } } } |
Это в основном создает всю структуру каталогов и необходимые файлы. Нам просто нужно передать ему базовый файл, который содержит метаданные файловой структуры.
Метаданные содержат метку времени, размер файла и путь к этому файлу. Это выглядит так:
1
2
3
4
5
6
7
|
2016-04-05T10:30:15.012345678 5120 backupftp/@eaDir /sharesnap_share_configuration/SYNO @. quota 2018-02-26T00:00:09.012345678 169 backupftp/@eaDir /sharesnap_share_configuration/share_configuration |
На нашем Synology NAS мы можем легко сгенерировать файл со всей древовидной структурой (определенной) директории, выполнив эту команду:
1
2
|
find backupftp -type f -printf "%TY-%Tm-%TdT%TH:%TM:%.12TS\t%s\t%p\n" >test/backupftp.files.txt |
Скопируйте созданный файл с вашего Synology NAS в ваш проект.
В тесте JUnit мы используем класс FileStructureCreator
как в примере ниже. Обратите внимание, что FileStructureCreator
реализует AutoCloseable
, поэтому мы можем использовать блок try / catch для очистки файлов после завершения теста.
01
02
03
04
05
06
07
08
09
10
11
|
@Value ( "classpath:/TestDiskConsistencyPolicy-notEnoughFileSets.txt" ) private Path notEnoughFileSets; @Test (expected = RuntimeException. class ) public void backupSetWithNoFileSetsThrowException() { try ( FileStructureCreator creator = FileStructureCreator.createTempDirectory(notEnoughFileSets) ) { BackupSet backupSet = BackupSet.builder().uri(creator.getFileStructureBasePath().toString()).build(); new DiskConsistencyPolicy(backupSet).execute(); assertTrue( "Expecting a RuntimeException here" , false ); } } |
Для приложения Spring Boot мы просто определяем класс @Configuration
который будет создавать структуры данных для наших @Configuration
файловых ресурсов, как определено на Synology NAS.
01
02
03
04
05
06
07
08
09
10
11
12
|
@Configuration @Profile ( "dev" ) public class TestFilesInstaller { @Bean public FileStructureCreator ftpFiles( @Value ( "classpath:/backupftp.files.txt" ) Path file) { return FileStructureCreator.create(file); } @Bean public FileStructureCreator nfsFiles( @Value ( "classpath:/backupnfs.files.txt" ) Path file) { return FileStructureCreator.create(file); } } |
Поскольку они определены как @Bean
, метод close()
будет автоматически вызываться при close()
приложения, удаляя все файлы с диска при остановке приложения Spring Boot.
Просто … не запускайте профиль разработчика в производство; Я дам вам понять, что происходит. 😉
В будущем мы покажем вам, как создать средство проверки резервных копий для мониторинга и проверки резервных копий на вашем NAS.
См. Оригинальную статью здесь: Файлы-макеты для тестирования JUnit веб-приложения Spring Boot на Synology NAS
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |