From bdbd615ea420a73ceb265e678438ed8f88bfb0d7 Mon Sep 17 00:00:00 2001 From: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Date: Wed, 30 Oct 2019 19:52:06 +0100 Subject: [PATCH 1/6] Rename FileWriter to SizeLimitedFileImpl. Move SizeLimitedFile to SizeLimitedFile.swift --- Logger.xcodeproj/project.pbxproj | 16 ++++++------- Logger/Loggers/DiskLogger/DiskLogger.swift | 19 +-------------- ...FileWriter.swift => SizeLimitedFile.swift} | 23 ++++++++++++++++--- ...Tests.swift => SizeLimitedFileTests.swift} | 10 ++++---- 4 files changed, 34 insertions(+), 34 deletions(-) rename Logger/Loggers/DiskLogger/{FileWriter.swift => SizeLimitedFile.swift} (74%) rename UnitTests/{FileWriterTests.swift => SizeLimitedFileTests.swift} (86%) diff --git a/Logger.xcodeproj/project.pbxproj b/Logger.xcodeproj/project.pbxproj index 46251ca..1866e24 100644 --- a/Logger.xcodeproj/project.pbxproj +++ b/Logger.xcodeproj/project.pbxproj @@ -15,13 +15,13 @@ 2EBF4B4B2122AF53008E4117 /* ConsoleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B482122AF53008E4117 /* ConsoleLogger.swift */; }; 2EBF4B4C2122AF53008E4117 /* NullLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B492122AF53008E4117 /* NullLogger.swift */; }; 2EBF4B572122B598008E4117 /* DiskLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B542122B598008E4117 /* DiskLogger.swift */; }; - 2EBF4B582122B598008E4117 /* FileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B552122B598008E4117 /* FileWriter.swift */; }; + 2EBF4B582122B598008E4117 /* SizeLimitedFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */; }; 2EBF4B592122B598008E4117 /* FileRotate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B562122B598008E4117 /* FileRotate.swift */; }; 2ED077D721329CA30058EEFC /* LoggetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D621329CA30058EEFC /* LoggetTests.swift */; }; 2ED077D92132A4820058EEFC /* AgregateLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */; }; 2ED077DB2132B0320058EEFC /* FileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077DA2132B0320058EEFC /* FileSystem.swift */; }; 2ED103E12135C61100EB3683 /* FileRotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E02135C61100EB3683 /* FileRotateTests.swift */; }; - 2ED103E32135D3FB00EB3683 /* FileWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E22135D3FB00EB3683 /* FileWriterTests.swift */; }; + 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */; }; 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */; }; /* End PBXBuildFile section */ @@ -58,13 +58,13 @@ 2EBF4B482122AF53008E4117 /* ConsoleLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsoleLogger.swift; sourceTree = ""; }; 2EBF4B492122AF53008E4117 /* NullLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NullLogger.swift; sourceTree = ""; }; 2EBF4B542122B598008E4117 /* DiskLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiskLogger.swift; sourceTree = ""; }; - 2EBF4B552122B598008E4117 /* FileWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileWriter.swift; sourceTree = ""; }; + 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SizeLimitedFile.swift; sourceTree = ""; }; 2EBF4B562122B598008E4117 /* FileRotate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileRotate.swift; sourceTree = ""; }; 2ED077D621329CA30058EEFC /* LoggetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggetTests.swift; sourceTree = ""; }; 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgregateLoggerTests.swift; sourceTree = ""; }; 2ED077DA2132B0320058EEFC /* FileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystem.swift; sourceTree = ""; }; 2ED103E02135C61100EB3683 /* FileRotateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRotateTests.swift; sourceTree = ""; }; - 2ED103E22135D3FB00EB3683 /* FileWriterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileWriterTests.swift; sourceTree = ""; }; + 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeLimitedFileTests.swift; sourceTree = ""; }; 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskLoggerTests.swift; sourceTree = ""; }; 2EDA8AE8213ACCFF00FE5840 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; /* End PBXFileReference section */ @@ -95,7 +95,7 @@ 2ED077D621329CA30058EEFC /* LoggetTests.swift */, 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */, 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */, - 2ED103E22135D3FB00EB3683 /* FileWriterTests.swift */, + 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */, 2ED103E02135C61100EB3683 /* FileRotateTests.swift */, 2E58D35E21316C3500BEF81A /* Info.plist */, ); @@ -146,7 +146,7 @@ isa = PBXGroup; children = ( 2EBF4B542122B598008E4117 /* DiskLogger.swift */, - 2EBF4B552122B598008E4117 /* FileWriter.swift */, + 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */, 2EBF4B562122B598008E4117 /* FileRotate.swift */, 2ED077DA2132B0320058EEFC /* FileSystem.swift */, ); @@ -246,7 +246,7 @@ buildActionMask = 2147483647; files = ( 2E58D35D21316C3500BEF81A /* LogStringConvertibleTests.swift in Sources */, - 2ED103E32135D3FB00EB3683 /* FileWriterTests.swift in Sources */, + 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */, 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */, 2ED077D92132A4820058EEFC /* AgregateLoggerTests.swift in Sources */, 2ED103E12135C61100EB3683 /* FileRotateTests.swift in Sources */, @@ -258,7 +258,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2EBF4B582122B598008E4117 /* FileWriter.swift in Sources */, + 2EBF4B582122B598008E4117 /* SizeLimitedFile.swift in Sources */, 2EBF4B572122B598008E4117 /* DiskLogger.swift in Sources */, 2EBF4B4C2122AF53008E4117 /* NullLogger.swift in Sources */, 2EBF4B3E2122AA34008E4117 /* Logger.swift in Sources */, diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index 340fa48..a6952de 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -24,23 +24,6 @@ import Foundation -/// Write failed as allowed size limit would be exceeded. -public struct SizeLimitedFileQuotaReached: Error {} - -/// Allows writing to a file while respecting allowed size limit. -protocol SizeLimitedFile { - - /// Synchronously writes `data` at the end of the file. - /// - /// - Parameter data: The data to be written. - /// - Throws: Throws an error if no free space is left on the file system, or if any other writing error occurs. - /// Throws `SizeLimitedFileQuotaReached` if allowed size limit would be exceeded. - func write(_ data: Data) throws - - /// Writes all in-memory data to permanent storage and closes the file. - func synchronizeAndCloseFile() -} - protocol SizeLimitedFileFactory { /// Returns newly initialized SizeLimitedFile instance. @@ -174,7 +157,7 @@ private class FileRotateFactory: LogrotateFactory { private class FileWriterFactory: SizeLimitedFileFactory { func makeInstance(fileURL: URL, fileSizeLimit: UInt64) throws -> SizeLimitedFile { - return try FileWriter(fileURL: fileURL, fileSizeLimit: fileSizeLimit, fileFactory: FileHandleFactory()) + return try SizeLimitedFileImpl(fileURL: fileURL, fileSizeLimit: fileSizeLimit, fileFactory: FileHandleFactory()) } } diff --git a/Logger/Loggers/DiskLogger/FileWriter.swift b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift similarity index 74% rename from Logger/Loggers/DiskLogger/FileWriter.swift rename to Logger/Loggers/DiskLogger/SizeLimitedFile.swift index be1ff30..29fc221 100644 --- a/Logger/Loggers/DiskLogger/FileWriter.swift +++ b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift @@ -35,14 +35,31 @@ protocol FileFactory { func makeInstance(forWritingTo: URL) throws -> File } +/// Write failed as allowed size limit would be exceeded. +public struct SizeLimitedFileQuotaReached: Error {} + /// Allows writing to a file while respecting allowed size limit. -final class FileWriter { +protocol SizeLimitedFile { + + /// Synchronously writes `data` at the end of the file. + /// + /// - Parameter data: The data to be written. + /// - Throws: Throws an error if no free space is left on the file system, or if any other writing error occurs. + /// Throws `SizeLimitedFileQuotaReached` if allowed size limit would be exceeded. + func write(_ data: Data) throws + + /// Writes all in-memory data to permanent storage and closes the file. + func synchronizeAndCloseFile() +} + +/// Allows writing to a file while respecting allowed size limit. +final class SizeLimitedFileImpl { private let file: File private let sizeLimit: UInt64 private var currentSize: UInt64 - /// Initializes new FileWriter instance. + /// Initializes new SizeLimitedFileImpl instance. /// /// - Parameters: /// - fileURL: URL of the file. @@ -55,7 +72,7 @@ final class FileWriter { } } -extension FileWriter: SizeLimitedFile { +extension SizeLimitedFileImpl: SizeLimitedFile { func write(_ data: Data) throws { let dataSize = UInt64(data.count) diff --git a/UnitTests/FileWriterTests.swift b/UnitTests/SizeLimitedFileTests.swift similarity index 86% rename from UnitTests/FileWriterTests.swift rename to UnitTests/SizeLimitedFileTests.swift index 222991c..c6e7987 100644 --- a/UnitTests/FileWriterTests.swift +++ b/UnitTests/SizeLimitedFileTests.swift @@ -25,20 +25,20 @@ import XCTest @testable import Logger -class FileWriterTests: XCTestCase { +class SizeLimitedFileTests: XCTestCase { let logURL = URL(fileURLWithPath: "/var/log/application.log") func testFileOpeningFailure() { let factory = UnopenableFileFactory() - XCTAssertThrowsError(try FileWriter(fileURL: logURL, fileSizeLimit: 0, fileFactory: factory), "file open failure") { (error) in + XCTAssertThrowsError(try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 0, fileFactory: factory), "file open failure") { (error) in XCTAssertTrue(error is UnopenableFileFactory.OpenFileError) } } func testKeepingFileSizeLimit() throws { let factory = FileMockFactory() - let writer = try FileWriter(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) + let writer = try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) let data = Data([0]) try writer.write(data) @@ -47,7 +47,7 @@ class FileWriterTests: XCTestCase { func testExceedingFileSizeLimit() throws { let factory = FileMockFactory() - let writer = try FileWriter(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) + let writer = try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) let data = Data([0, 0]) XCTAssertThrowsError(try writer.write(data), "file size limit exceeded") { (error) in @@ -59,7 +59,7 @@ class FileWriterTests: XCTestCase { func testSynchronizingAndClosingFile() throws { let factory = FileMockFactory() - let writer = try FileWriter(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) + let writer = try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) writer.synchronizeAndCloseFile() XCTAssertTrue(factory.mock.synchronizeFileCallCount == 1 && factory.mock.closeFileCallCount == 1) } From 81393b67dae30e786a8746765a8dc574fd5078aa Mon Sep 17 00:00:00 2001 From: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Date: Wed, 30 Oct 2019 20:02:45 +0100 Subject: [PATCH 2/6] Rename FileRotate to LogrotateImpl. Move Logrotate to Logrotate.swift --- Logger.xcodeproj/project.pbxproj | 16 +++++++------- Logger/Loggers/DiskLogger/DiskLogger.swift | 16 +------------- .../{Filerotate.swift => Logrotate.swift} | 18 +++++++++++++-- ...RotateTests.swift => LogrotateTests.swift} | 22 +++++++++---------- 4 files changed, 36 insertions(+), 36 deletions(-) rename Logger/Loggers/DiskLogger/{Filerotate.swift => Logrotate.swift} (83%) rename UnitTests/{FileRotateTests.swift => LogrotateTests.swift} (84%) diff --git a/Logger.xcodeproj/project.pbxproj b/Logger.xcodeproj/project.pbxproj index 1866e24..387575a 100644 --- a/Logger.xcodeproj/project.pbxproj +++ b/Logger.xcodeproj/project.pbxproj @@ -16,11 +16,11 @@ 2EBF4B4C2122AF53008E4117 /* NullLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B492122AF53008E4117 /* NullLogger.swift */; }; 2EBF4B572122B598008E4117 /* DiskLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B542122B598008E4117 /* DiskLogger.swift */; }; 2EBF4B582122B598008E4117 /* SizeLimitedFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */; }; - 2EBF4B592122B598008E4117 /* FileRotate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B562122B598008E4117 /* FileRotate.swift */; }; + 2EBF4B592122B598008E4117 /* Logrotate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B562122B598008E4117 /* Logrotate.swift */; }; 2ED077D721329CA30058EEFC /* LoggetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D621329CA30058EEFC /* LoggetTests.swift */; }; 2ED077D92132A4820058EEFC /* AgregateLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */; }; 2ED077DB2132B0320058EEFC /* FileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077DA2132B0320058EEFC /* FileSystem.swift */; }; - 2ED103E12135C61100EB3683 /* FileRotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E02135C61100EB3683 /* FileRotateTests.swift */; }; + 2ED103E12135C61100EB3683 /* LogrotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E02135C61100EB3683 /* LogrotateTests.swift */; }; 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */; }; 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */; }; /* End PBXBuildFile section */ @@ -59,11 +59,11 @@ 2EBF4B492122AF53008E4117 /* NullLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NullLogger.swift; sourceTree = ""; }; 2EBF4B542122B598008E4117 /* DiskLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiskLogger.swift; sourceTree = ""; }; 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SizeLimitedFile.swift; sourceTree = ""; }; - 2EBF4B562122B598008E4117 /* FileRotate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileRotate.swift; sourceTree = ""; }; + 2EBF4B562122B598008E4117 /* Logrotate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logrotate.swift; sourceTree = ""; }; 2ED077D621329CA30058EEFC /* LoggetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggetTests.swift; sourceTree = ""; }; 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgregateLoggerTests.swift; sourceTree = ""; }; 2ED077DA2132B0320058EEFC /* FileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystem.swift; sourceTree = ""; }; - 2ED103E02135C61100EB3683 /* FileRotateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRotateTests.swift; sourceTree = ""; }; + 2ED103E02135C61100EB3683 /* LogrotateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogrotateTests.swift; sourceTree = ""; }; 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeLimitedFileTests.swift; sourceTree = ""; }; 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskLoggerTests.swift; sourceTree = ""; }; 2EDA8AE8213ACCFF00FE5840 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; @@ -96,7 +96,7 @@ 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */, 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */, 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */, - 2ED103E02135C61100EB3683 /* FileRotateTests.swift */, + 2ED103E02135C61100EB3683 /* LogrotateTests.swift */, 2E58D35E21316C3500BEF81A /* Info.plist */, ); path = UnitTests; @@ -147,7 +147,7 @@ children = ( 2EBF4B542122B598008E4117 /* DiskLogger.swift */, 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */, - 2EBF4B562122B598008E4117 /* FileRotate.swift */, + 2EBF4B562122B598008E4117 /* Logrotate.swift */, 2ED077DA2132B0320058EEFC /* FileSystem.swift */, ); path = DiskLogger; @@ -249,7 +249,7 @@ 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */, 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */, 2ED077D92132A4820058EEFC /* AgregateLoggerTests.swift in Sources */, - 2ED103E12135C61100EB3683 /* FileRotateTests.swift in Sources */, + 2ED103E12135C61100EB3683 /* LogrotateTests.swift in Sources */, 2ED077D721329CA30058EEFC /* LoggetTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -265,7 +265,7 @@ 2EBF4B4B2122AF53008E4117 /* ConsoleLogger.swift in Sources */, 2ED077DB2132B0320058EEFC /* FileSystem.swift in Sources */, 2EBF4B4A2122AF53008E4117 /* AgregateLogger.swift in Sources */, - 2EBF4B592122B598008E4117 /* FileRotate.swift in Sources */, + 2EBF4B592122B598008E4117 /* Logrotate.swift in Sources */, 2EBF4B452122ACD6008E4117 /* LogStringConvertible.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index a6952de..df97e21 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -35,20 +35,6 @@ protocol SizeLimitedFileFactory { func makeInstance(fileURL: URL, fileSizeLimit: UInt64) throws -> SizeLimitedFile } -/// Allows log files rotation. -protocol Logrotate { - - /// Rotates log files `rotations` number of times. - /// - /// First deletes file at `.`. - /// Next moves files located at: - /// - /// `, .1, .2 ... .` - /// - /// to `.1, .2 ... .` - func rotate() throws -} - protocol LogrotateFactory { /// Returns newly initialized Logrotate instance. @@ -151,7 +137,7 @@ public final class DiskLogger: Logger { private class FileRotateFactory: LogrotateFactory { func makeInstance(fileURL: URL, rotations: Int) -> Logrotate { - return FileRotate(fileURL: fileURL, rotations: rotations, fileSystem: FileManager.default) + return LogrotateImpl(fileURL: fileURL, rotations: rotations, fileSystem: FileManager.default) } } diff --git a/Logger/Loggers/DiskLogger/Filerotate.swift b/Logger/Loggers/DiskLogger/Logrotate.swift similarity index 83% rename from Logger/Loggers/DiskLogger/Filerotate.swift rename to Logger/Loggers/DiskLogger/Logrotate.swift index 0963cfa..93d4e84 100644 --- a/Logger/Loggers/DiskLogger/Filerotate.swift +++ b/Logger/Loggers/DiskLogger/Logrotate.swift @@ -24,7 +24,21 @@ import Foundation -final class FileRotate { +/// Allows log files rotation. +protocol Logrotate { + + /// Rotates log files `rotations` number of times. + /// + /// First deletes file at `.`. + /// Next moves files located at: + /// + /// `, .1, .2 ... .` + /// + /// to `.1, .2 ... .` + func rotate() throws +} + +final class LogrotateImpl { private let fileURL: URL private let rotations: Int @@ -43,7 +57,7 @@ final class FileRotate { } } -extension FileRotate: Logrotate { +extension LogrotateImpl: Logrotate { func rotate() throws { let range = 1...rotations diff --git a/UnitTests/FileRotateTests.swift b/UnitTests/LogrotateTests.swift similarity index 84% rename from UnitTests/FileRotateTests.swift rename to UnitTests/LogrotateTests.swift index 13ca7c0..f5f576c 100644 --- a/UnitTests/FileRotateTests.swift +++ b/UnitTests/LogrotateTests.swift @@ -25,7 +25,7 @@ import XCTest @testable import Logger -class FileRotateTests: XCTestCase { +class LogrotateTests: XCTestCase { let logURL = URL(fileURLWithPath: "/var/log/application.log") let log1URL = URL(fileURLWithPath: "/var/log/application.log.1") @@ -34,7 +34,7 @@ class FileRotateTests: XCTestCase { func test_1rotation_0files() { let fileSystem = FileSystemMock(files: []) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -44,7 +44,7 @@ class FileRotateTests: XCTestCase { func test_1rotation_1file() { let fileSystem = FileSystemMock(files: [logURL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -54,7 +54,7 @@ class FileRotateTests: XCTestCase { func test_1rotation_2files() { let fileSystem = FileSystemMock(files: [logURL, log1URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -64,7 +64,7 @@ class FileRotateTests: XCTestCase { func test_1rotation_3files() { let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -74,7 +74,7 @@ class FileRotateTests: XCTestCase { func test_2rotations_0files() { let fileSystem = FileSystemMock(files: []) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -84,7 +84,7 @@ class FileRotateTests: XCTestCase { func test_2rotations_1file() { let fileSystem = FileSystemMock(files: [logURL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -94,7 +94,7 @@ class FileRotateTests: XCTestCase { func test_2rotations_2files() { let fileSystem = FileSystemMock(files: [logURL, log1URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -104,7 +104,7 @@ class FileRotateTests: XCTestCase { func test_2rotations_3files() { let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -114,7 +114,7 @@ class FileRotateTests: XCTestCase { func test_2rotations_4files() { let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL, log3URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) try? logrotate.rotate() let actual = fileSystem.files @@ -124,7 +124,7 @@ class FileRotateTests: XCTestCase { func testErrorPropagation() { let fileSystem = BrokenFileSystem() - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) XCTAssertThrowsError(try logrotate.rotate(), "An error when removing or moving an item") { (error) in XCTAssertTrue(error is BrokenFileSystem.IOError) From 1eb496f343615fce2bc70af144960847a1348917 Mon Sep 17 00:00:00 2001 From: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Date: Wed, 30 Oct 2019 20:05:14 +0100 Subject: [PATCH 3/6] Rename FileSystem to OSFileManager --- Logger.xcodeproj/project.pbxproj | 8 +-- Logger/Loggers/DiskLogger/DiskLogger.swift | 14 ++--- Logger/Loggers/DiskLogger/Logrotate.swift | 14 ++--- .../{FileSystem.swift => OSFileManager.swift} | 4 +- UnitTests/DiskLoggerTests.swift | 14 ++--- UnitTests/LogrotateTests.swift | 62 +++++++++---------- 6 files changed, 58 insertions(+), 58 deletions(-) rename Logger/Loggers/DiskLogger/{FileSystem.swift => OSFileManager.swift} (95%) diff --git a/Logger.xcodeproj/project.pbxproj b/Logger.xcodeproj/project.pbxproj index 387575a..8376b6e 100644 --- a/Logger.xcodeproj/project.pbxproj +++ b/Logger.xcodeproj/project.pbxproj @@ -19,7 +19,7 @@ 2EBF4B592122B598008E4117 /* Logrotate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B562122B598008E4117 /* Logrotate.swift */; }; 2ED077D721329CA30058EEFC /* LoggetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D621329CA30058EEFC /* LoggetTests.swift */; }; 2ED077D92132A4820058EEFC /* AgregateLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */; }; - 2ED077DB2132B0320058EEFC /* FileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077DA2132B0320058EEFC /* FileSystem.swift */; }; + 2ED077DB2132B0320058EEFC /* OSFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077DA2132B0320058EEFC /* OSFileManager.swift */; }; 2ED103E12135C61100EB3683 /* LogrotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E02135C61100EB3683 /* LogrotateTests.swift */; }; 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */; }; 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */; }; @@ -62,7 +62,7 @@ 2EBF4B562122B598008E4117 /* Logrotate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logrotate.swift; sourceTree = ""; }; 2ED077D621329CA30058EEFC /* LoggetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggetTests.swift; sourceTree = ""; }; 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgregateLoggerTests.swift; sourceTree = ""; }; - 2ED077DA2132B0320058EEFC /* FileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystem.swift; sourceTree = ""; }; + 2ED077DA2132B0320058EEFC /* OSFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSFileManager.swift; sourceTree = ""; }; 2ED103E02135C61100EB3683 /* LogrotateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogrotateTests.swift; sourceTree = ""; }; 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeLimitedFileTests.swift; sourceTree = ""; }; 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskLoggerTests.swift; sourceTree = ""; }; @@ -148,7 +148,7 @@ 2EBF4B542122B598008E4117 /* DiskLogger.swift */, 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */, 2EBF4B562122B598008E4117 /* Logrotate.swift */, - 2ED077DA2132B0320058EEFC /* FileSystem.swift */, + 2ED077DA2132B0320058EEFC /* OSFileManager.swift */, ); path = DiskLogger; sourceTree = ""; @@ -263,7 +263,7 @@ 2EBF4B4C2122AF53008E4117 /* NullLogger.swift in Sources */, 2EBF4B3E2122AA34008E4117 /* Logger.swift in Sources */, 2EBF4B4B2122AF53008E4117 /* ConsoleLogger.swift in Sources */, - 2ED077DB2132B0320058EEFC /* FileSystem.swift in Sources */, + 2ED077DB2132B0320058EEFC /* OSFileManager.swift in Sources */, 2EBF4B4A2122AF53008E4117 /* AgregateLogger.swift in Sources */, 2EBF4B592122B598008E4117 /* Logrotate.swift in Sources */, 2EBF4B452122ACD6008E4117 /* LogStringConvertible.swift in Sources */, diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index df97e21..3ffc4e2 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -51,7 +51,7 @@ public final class DiskLogger: Logger { private let fileURL: URL private let fileSizeLimit: UInt64 private let rotations: Int - private let fileSystem: FileSystem + private let fileManager: OSFileManager private let sizeLimitedFileFactory: SizeLimitedFileFactory private let logrotateFactory: LogrotateFactory private let formatter: DateFormatter @@ -66,14 +66,14 @@ public final class DiskLogger: Logger { /// - fileSizeLimit: Maximum size log file can reach in bytes. Attempt to exceeding that limit triggers log files rotation. /// - rotations: Number of times log files are rotated before being removed. public convenience init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int) { - self.init(fileURL: fileURL, fileSizeLimit: fileSizeLimit, rotations: rotations, fileSystem: FileManager.default, sizeLimitedFileFactory: FileWriterFactory(), logrotateFactory: FileRotateFactory()) + self.init(fileURL: fileURL, fileSizeLimit: fileSizeLimit, rotations: rotations, fileManager: FileManager.default, sizeLimitedFileFactory: FileWriterFactory(), logrotateFactory: FileRotateFactory()) } - init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int, fileSystem: FileSystem, sizeLimitedFileFactory: SizeLimitedFileFactory, logrotateFactory: LogrotateFactory) { + init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int, fileManager: OSFileManager, sizeLimitedFileFactory: SizeLimitedFileFactory, logrotateFactory: LogrotateFactory) { self.fileURL = fileURL self.fileSizeLimit = fileSizeLimit self.rotations = rotations - self.fileSystem = fileSystem + self.fileManager = fileManager self.sizeLimitedFileFactory = sizeLimitedFileFactory self.logrotateFactory = logrotateFactory formatter = DateFormatter() @@ -113,8 +113,8 @@ public final class DiskLogger: Logger { private func openSizeLimitedFile() throws { guard sizeLimitedFile == nil else { return } - if fileSystem.itemExists(at: fileURL) == false { - _ = fileSystem.createFile(at: fileURL) + if fileManager.itemExists(at: fileURL) == false { + _ = fileManager.createFile(at: fileURL) } sizeLimitedFile = try sizeLimitedFileFactory.makeInstance(fileURL: fileURL, fileSizeLimit: fileSizeLimit) } @@ -137,7 +137,7 @@ public final class DiskLogger: Logger { private class FileRotateFactory: LogrotateFactory { func makeInstance(fileURL: URL, rotations: Int) -> Logrotate { - return LogrotateImpl(fileURL: fileURL, rotations: rotations, fileSystem: FileManager.default) + return LogrotateImpl(fileURL: fileURL, rotations: rotations, fileManager: FileManager.default) } } diff --git a/Logger/Loggers/DiskLogger/Logrotate.swift b/Logger/Loggers/DiskLogger/Logrotate.swift index 93d4e84..4d640c7 100644 --- a/Logger/Loggers/DiskLogger/Logrotate.swift +++ b/Logger/Loggers/DiskLogger/Logrotate.swift @@ -42,18 +42,18 @@ final class LogrotateImpl { private let fileURL: URL private let rotations: Int - private let fileSystem: FileSystem + private let fileManager: OSFileManager /// Initializes new Logrotate instance. /// /// - Parameters: /// - fileURL: URL of the log file. /// - rotations: Number of times log files are rotated before being removed. - init(fileURL: URL, rotations: Int, fileSystem: FileSystem) { + init(fileURL: URL, rotations: Int, fileManager: OSFileManager) { precondition(rotations > 0) self.fileURL = fileURL self.rotations = rotations - self.fileSystem = fileSystem + self.fileManager = fileManager } } @@ -68,12 +68,12 @@ extension LogrotateImpl: Logrotate { let toDelete = rotatedURLs.last! let toMove = zip(allURLs, rotatedURLs).reversed() - if fileSystem.itemExists(at: toDelete) { - try fileSystem.removeItem(at: toDelete) + if fileManager.itemExists(at: toDelete) { + try fileManager.removeItem(at: toDelete) } for (oldURL, newURL) in toMove { - guard fileSystem.itemExists(at: oldURL) else { continue } - try fileSystem.moveItem(at: oldURL, to: newURL) + guard fileManager.itemExists(at: oldURL) else { continue } + try fileManager.moveItem(at: oldURL, to: newURL) } } } diff --git a/Logger/Loggers/DiskLogger/FileSystem.swift b/Logger/Loggers/DiskLogger/OSFileManager.swift similarity index 95% rename from Logger/Loggers/DiskLogger/FileSystem.swift rename to Logger/Loggers/DiskLogger/OSFileManager.swift index b47b316..02ae5be 100644 --- a/Logger/Loggers/DiskLogger/FileSystem.swift +++ b/Logger/Loggers/DiskLogger/OSFileManager.swift @@ -24,14 +24,14 @@ import Foundation -public protocol FileSystem { +public protocol OSFileManager { func itemExists(at URL: URL) -> Bool func removeItem(at URL: URL) throws func moveItem(at srcURL: URL, to dstURL: URL) throws func createFile(at URL: URL) -> Bool } -extension FileManager: FileSystem { +extension FileManager: OSFileManager { public func itemExists(at URL: URL) -> Bool { return fileExists(atPath: URL.path) diff --git a/UnitTests/DiskLoggerTests.swift b/UnitTests/DiskLoggerTests.swift index aaededc..4a08210 100644 --- a/UnitTests/DiskLoggerTests.swift +++ b/UnitTests/DiskLoggerTests.swift @@ -33,13 +33,13 @@ class DiskLoggerTests: XCTestCase { let expectation = XCTestExpectation(description: "write(_:) was called on SizeLimitedFile") expectation.expectedFulfillmentCount = 1 - let filesystem = FileSystemStub() + let fimeManager = FileManagerStub() let sizeLimitedFileFactory = SizeLimitedFileMockFactory(writeCall: expectation) let logrotateFactory = LogrotateMockFactory() let logger = DiskLogger(fileURL: logURL, fileSizeLimit: 1024, rotations: 1, - fileSystem: filesystem, + fileManager: fimeManager, sizeLimitedFileFactory: sizeLimitedFileFactory, logrotateFactory: logrotateFactory) @@ -61,13 +61,13 @@ class DiskLoggerTests: XCTestCase { let expectation = XCTestExpectation(description: "write(_:) was called on SizeLimitedFile") expectation.expectedFulfillmentCount = 2 - let filesystem = FileSystemStub() + let fimeManager = FileManagerStub() let sizeLimitedFileFactory = SizeLimitedFileMockFactory(writeCall: expectation) let logrotateFactory = LogrotateMockFactory() let logger = DiskLogger(fileURL: logURL, fileSizeLimit: 91, rotations: 1, - fileSystem: filesystem, + fileManager: fimeManager, sizeLimitedFileFactory: sizeLimitedFileFactory, logrotateFactory: logrotateFactory) @@ -90,13 +90,13 @@ class DiskLoggerTests: XCTestCase { let expectation = XCTestExpectation(description: "write(_:) was called on SizeLimitedFile") expectation.expectedFulfillmentCount = 2 - let filesystem = FileSystemStub() + let fimeManager = FileManagerStub() let sizeLimitedFileFactory = UnwritableFileStubFactory(writeCall: expectation) let logrotateFactory = LogrotateMockFactory() let logger = DiskLogger(fileURL: logURL, fileSizeLimit: 91, rotations: 1, - fileSystem: filesystem, + fileManager: fimeManager, sizeLimitedFileFactory: sizeLimitedFileFactory, logrotateFactory: logrotateFactory) @@ -116,7 +116,7 @@ class DiskLoggerTests: XCTestCase { } } -private class FileSystemStub: FileSystem { +private class FileManagerStub: OSFileManager { func itemExists(at URL: URL) -> Bool { return false } diff --git a/UnitTests/LogrotateTests.swift b/UnitTests/LogrotateTests.swift index f5f576c..0aa968b 100644 --- a/UnitTests/LogrotateTests.swift +++ b/UnitTests/LogrotateTests.swift @@ -33,98 +33,98 @@ class LogrotateTests: XCTestCase { let log3URL = URL(fileURLWithPath: "/var/log/application.log.3") func test_1rotation_0files() { - let fileSystem = FileSystemMock(files: []) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: []) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set() XCTAssertEqual(actual, expected) } func test_1rotation_1file() { - let fileSystem = FileSystemMock(files: [logURL]) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL]) XCTAssertEqual(actual, expected) } func test_1rotation_2files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL]) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL]) XCTAssertEqual(actual, expected) } func test_1rotation_3files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL]) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL, log2URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL]) XCTAssertEqual(actual, expected) } func test_2rotations_0files() { - let fileSystem = FileSystemMock(files: []) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: []) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set() XCTAssertEqual(actual, expected) } func test_2rotations_1file() { - let fileSystem = FileSystemMock(files: [logURL]) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL]) XCTAssertEqual(actual, expected) } func test_2rotations_2files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL]) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL]) XCTAssertEqual(actual, expected) } func test_2rotations_3files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL]) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL, log2URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL]) XCTAssertEqual(actual, expected) } func test_2rotations_4files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL, log3URL]) - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL, log2URL, log3URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL, log3URL]) XCTAssertEqual(actual, expected) } func testErrorPropagation() { - let fileSystem = BrokenFileSystem() - let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = BrokenFileSystem() + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) XCTAssertThrowsError(try logrotate.rotate(), "An error when removing or moving an item") { (error) in XCTAssertTrue(error is BrokenFileSystem.IOError) @@ -132,7 +132,7 @@ class LogrotateTests: XCTestCase { } } -private class FileSystemMock: FileSystem { +private class FileManagerMock: OSFileManager { private(set) var files = Set() @@ -159,7 +159,7 @@ private class FileSystemMock: FileSystem { } } -private class BrokenFileSystem: FileSystem { +private class BrokenFileSystem: OSFileManager { struct IOError: Error { } From 3f90ca9fa680132bec15990d56a5390ec3bf5f0c Mon Sep 17 00:00:00 2001 From: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Date: Wed, 30 Oct 2019 20:24:02 +0100 Subject: [PATCH 4/6] Rename File to OSFileHandle. Move OSFileHandle to OSFileHandle.swift --- Logger.xcodeproj/project.pbxproj | 4 ++++ Logger/Loggers/DiskLogger/DiskLogger.swift | 9 +------- Logger/Loggers/DiskLogger/OSFileHandle.swift | 23 +++++++++++++++++++ .../Loggers/DiskLogger/SizeLimitedFile.swift | 11 ++------- UnitTests/SizeLimitedFileTests.swift | 6 ++--- 5 files changed, 33 insertions(+), 20 deletions(-) create mode 100644 Logger/Loggers/DiskLogger/OSFileHandle.swift diff --git a/Logger.xcodeproj/project.pbxproj b/Logger.xcodeproj/project.pbxproj index 8376b6e..317817a 100644 --- a/Logger.xcodeproj/project.pbxproj +++ b/Logger.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 2ED103E12135C61100EB3683 /* LogrotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E02135C61100EB3683 /* LogrotateTests.swift */; }; 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */; }; 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */; }; + 2ED83781236A19A60008C01F /* OSFileHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED83780236A19A60008C01F /* OSFileHandle.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -66,6 +67,7 @@ 2ED103E02135C61100EB3683 /* LogrotateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogrotateTests.swift; sourceTree = ""; }; 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeLimitedFileTests.swift; sourceTree = ""; }; 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskLoggerTests.swift; sourceTree = ""; }; + 2ED83780236A19A60008C01F /* OSFileHandle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSFileHandle.swift; sourceTree = ""; }; 2EDA8AE8213ACCFF00FE5840 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; /* End PBXFileReference section */ @@ -149,6 +151,7 @@ 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */, 2EBF4B562122B598008E4117 /* Logrotate.swift */, 2ED077DA2132B0320058EEFC /* OSFileManager.swift */, + 2ED83780236A19A60008C01F /* OSFileHandle.swift */, ); path = DiskLogger; sourceTree = ""; @@ -259,6 +262,7 @@ buildActionMask = 2147483647; files = ( 2EBF4B582122B598008E4117 /* SizeLimitedFile.swift in Sources */, + 2ED83781236A19A60008C01F /* OSFileHandle.swift in Sources */, 2EBF4B572122B598008E4117 /* DiskLogger.swift in Sources */, 2EBF4B4C2122AF53008E4117 /* NullLogger.swift in Sources */, 2EBF4B3E2122AA34008E4117 /* Logger.swift in Sources */, diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index 3ffc4e2..395ba57 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -148,14 +148,7 @@ private class FileWriterFactory: SizeLimitedFileFactory { } private class FileHandleFactory: FileFactory { - func makeInstance(forWritingTo: URL) throws -> File { + func makeInstance(forWritingTo: URL) throws -> OSFileHandle { return try FileHandle(forWritingTo: forWritingTo) } } - -extension FileHandle: File { - - func swift_write(_ data: Data) throws { - try __write(data, error: ()) - } -} diff --git a/Logger/Loggers/DiskLogger/OSFileHandle.swift b/Logger/Loggers/DiskLogger/OSFileHandle.swift new file mode 100644 index 0000000..dfe5bb9 --- /dev/null +++ b/Logger/Loggers/DiskLogger/OSFileHandle.swift @@ -0,0 +1,23 @@ +// +// OSFileHandle.swift +// Logger +// +// Created by Wojciech Nagrodzki on 30/10/2019. +// Copyright © 2019 Wojciech Nagrodzki. All rights reserved. +// + +import Foundation + +protocol OSFileHandle { + func seekToEndOfFile() -> UInt64 + func swift_write(_ data: Data) throws + func synchronizeFile() + func closeFile() +} + +extension FileHandle: OSFileHandle { + + func swift_write(_ data: Data) throws { + try __write(data, error: ()) + } +} diff --git a/Logger/Loggers/DiskLogger/SizeLimitedFile.swift b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift index 29fc221..c93b5c0 100644 --- a/Logger/Loggers/DiskLogger/SizeLimitedFile.swift +++ b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift @@ -24,15 +24,8 @@ import Foundation -protocol File { - func seekToEndOfFile() -> UInt64 - func swift_write(_ data: Data) throws - func synchronizeFile() - func closeFile() -} - protocol FileFactory { - func makeInstance(forWritingTo: URL) throws -> File + func makeInstance(forWritingTo: URL) throws -> OSFileHandle } /// Write failed as allowed size limit would be exceeded. @@ -55,7 +48,7 @@ protocol SizeLimitedFile { /// Allows writing to a file while respecting allowed size limit. final class SizeLimitedFileImpl { - private let file: File + private let file: OSFileHandle private let sizeLimit: UInt64 private var currentSize: UInt64 diff --git a/UnitTests/SizeLimitedFileTests.swift b/UnitTests/SizeLimitedFileTests.swift index c6e7987..e65dde0 100644 --- a/UnitTests/SizeLimitedFileTests.swift +++ b/UnitTests/SizeLimitedFileTests.swift @@ -69,7 +69,7 @@ private class UnopenableFileFactory: FileFactory { struct OpenFileError: Error {} - func makeInstance(forWritingTo: URL) throws -> File { + func makeInstance(forWritingTo: URL) throws -> OSFileHandle { throw OpenFileError() } } @@ -78,12 +78,12 @@ private class FileMockFactory: FileFactory { let mock = FileMock() - func makeInstance(forWritingTo: URL) throws -> File { + func makeInstance(forWritingTo: URL) throws -> OSFileHandle { return mock } } -private class FileMock: File { +private class FileMock: OSFileHandle { private(set) var writtenData = Data() private(set) var synchronizeFileCallCount = 0 From b49971f8398dd3ea55ed13e33f7be8cf55b820bc Mon Sep 17 00:00:00 2001 From: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Date: Wed, 30 Oct 2019 20:27:33 +0100 Subject: [PATCH 5/6] Rename FileFactory to FileHandleFactory --- Logger/Loggers/DiskLogger/DiskLogger.swift | 4 ++-- Logger/Loggers/DiskLogger/SizeLimitedFile.swift | 4 ++-- UnitTests/SizeLimitedFileTests.swift | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index 395ba57..667643d 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -143,11 +143,11 @@ private class FileRotateFactory: LogrotateFactory { private class FileWriterFactory: SizeLimitedFileFactory { func makeInstance(fileURL: URL, fileSizeLimit: UInt64) throws -> SizeLimitedFile { - return try SizeLimitedFileImpl(fileURL: fileURL, fileSizeLimit: fileSizeLimit, fileFactory: FileHandleFactory()) + return try SizeLimitedFileImpl(fileURL: fileURL, fileSizeLimit: fileSizeLimit, fileFactory: FileHandleFactoryImpl()) } } -private class FileHandleFactory: FileFactory { +private class FileHandleFactoryImpl: FileHandleFactory { func makeInstance(forWritingTo: URL) throws -> OSFileHandle { return try FileHandle(forWritingTo: forWritingTo) } diff --git a/Logger/Loggers/DiskLogger/SizeLimitedFile.swift b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift index c93b5c0..d95e5f4 100644 --- a/Logger/Loggers/DiskLogger/SizeLimitedFile.swift +++ b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift @@ -24,7 +24,7 @@ import Foundation -protocol FileFactory { +protocol FileHandleFactory { func makeInstance(forWritingTo: URL) throws -> OSFileHandle } @@ -58,7 +58,7 @@ final class SizeLimitedFileImpl { /// - fileURL: URL of the file. /// - fileSizeLimit: Maximum size the file can reach in bytes. /// - Throws: An error that may occur while the file is being opened for writing. - init(fileURL: URL, fileSizeLimit: UInt64, fileFactory: FileFactory) throws { + init(fileURL: URL, fileSizeLimit: UInt64, fileFactory: FileHandleFactory) throws { file = try fileFactory.makeInstance(forWritingTo: fileURL) self.sizeLimit = fileSizeLimit currentSize = file.seekToEndOfFile() diff --git a/UnitTests/SizeLimitedFileTests.swift b/UnitTests/SizeLimitedFileTests.swift index e65dde0..a51f3fc 100644 --- a/UnitTests/SizeLimitedFileTests.swift +++ b/UnitTests/SizeLimitedFileTests.swift @@ -65,7 +65,7 @@ class SizeLimitedFileTests: XCTestCase { } } -private class UnopenableFileFactory: FileFactory { +private class UnopenableFileFactory: FileHandleFactory { struct OpenFileError: Error {} @@ -74,7 +74,7 @@ private class UnopenableFileFactory: FileFactory { } } -private class FileMockFactory: FileFactory { +private class FileMockFactory: FileHandleFactory { let mock = FileMock() From 28716deefe30fec48948adebc8d633e285d6071b Mon Sep 17 00:00:00 2001 From: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Date: Wed, 30 Oct 2019 20:27:56 +0100 Subject: [PATCH 6/6] Rename FileRotateFactory to LogrotateFactoryImpl, and FileWriterFactory to SizeLimitedFileFactoryImpl --- Logger/Loggers/DiskLogger/DiskLogger.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index 667643d..9e14117 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -66,7 +66,7 @@ public final class DiskLogger: Logger { /// - fileSizeLimit: Maximum size log file can reach in bytes. Attempt to exceeding that limit triggers log files rotation. /// - rotations: Number of times log files are rotated before being removed. public convenience init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int) { - self.init(fileURL: fileURL, fileSizeLimit: fileSizeLimit, rotations: rotations, fileManager: FileManager.default, sizeLimitedFileFactory: FileWriterFactory(), logrotateFactory: FileRotateFactory()) + self.init(fileURL: fileURL, fileSizeLimit: fileSizeLimit, rotations: rotations, fileManager: FileManager.default, sizeLimitedFileFactory: SizeLimitedFileFactoryImpl(), logrotateFactory: LogrotateFactoryImpl()) } init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int, fileManager: OSFileManager, sizeLimitedFileFactory: SizeLimitedFileFactory, logrotateFactory: LogrotateFactory) { @@ -135,13 +135,13 @@ public final class DiskLogger: Logger { } } -private class FileRotateFactory: LogrotateFactory { +private class LogrotateFactoryImpl: LogrotateFactory { func makeInstance(fileURL: URL, rotations: Int) -> Logrotate { return LogrotateImpl(fileURL: fileURL, rotations: rotations, fileManager: FileManager.default) } } -private class FileWriterFactory: SizeLimitedFileFactory { +private class SizeLimitedFileFactoryImpl: SizeLimitedFileFactory { func makeInstance(fileURL: URL, fileSizeLimit: UInt64) throws -> SizeLimitedFile { return try SizeLimitedFileImpl(fileURL: fileURL, fileSizeLimit: fileSizeLimit, fileFactory: FileHandleFactoryImpl()) }