Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
104e225
Update Instabug version
IldarAbdullin-okta Sep 10, 2025
37ce854
Remove semgrep
IldarAbdullin-okta Sep 10, 2025
a9d1d20
Change xcode to 16.2
IldarAbdullin-okta Sep 10, 2025
19fb70e
Update simulator to iPhone 16
IldarAbdullin-okta Sep 10, 2025
9a35760
Updates XCode to 16.4.0
michaelbiviano-okta Sep 22, 2025
03740b3
Increase xcode version
IldarAbdullin-okta Sep 23, 2025
f4bf89d
Store xcresult files into artifacts
IldarAbdullin-okta Sep 24, 2025
cdb8090
Merge branch 'firebase_update' of https://github.com/okta/okta-utils-…
michaelbiviano-okta Sep 26, 2025
6dc9d02
tars xcresult files
michaelbiviano-okta Sep 29, 2025
9684a02
Attempting to pipe build output to artifact
michaelbiviano-okta Sep 30, 2025
b4d10ce
Attempting to pipe build output to artifact
michaelbiviano-okta Sep 30, 2025
6905044
Increases test timeout
michaelbiviano-okta Sep 30, 2025
8aed2f1
Increases test timeout
michaelbiviano-okta Sep 30, 2025
b07c72d
Removes debugging piped output
michaelbiviano-okta Sep 30, 2025
df71308
Updates sleep
michaelbiviano-okta Sep 30, 2025
e03f36b
Increases timeout
michaelbiviano-okta Sep 30, 2025
a26cafa
resets sleep
michaelbiviano-okta Oct 14, 2025
26c164d
Resets timeouts
michaelbiviano-okta Oct 14, 2025
3062d27
Removews temp artifact storage
michaelbiviano-okta Oct 14, 2025
4d9522d
Re-adds artifacts
michaelbiviano-okta Oct 14, 2025
5448e52
Increasses timeouts
michaelbiviano-okta Oct 14, 2025
b19bee9
Push to rebuild
michaelbiviano-okta Oct 14, 2025
ea1e032
Updates lumberjack tests
michaelbiviano-okta Oct 15, 2025
bbfb4fd
Updates timeouts and polling
michaelbiviano-okta Oct 16, 2025
d995659
Updates OktaLoggerFileLogger protocol conformance
michaelbiviano-okta Oct 16, 2025
d891518
Adds poll for purge complete
michaelbiviano-okta Oct 16, 2025
c55cd61
Removes artifact storage used for debugging
michaelbiviano-okta Oct 17, 2025
8768408
Re-adds artifacts for debugging
michaelbiviano-okta Oct 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ parameters:
executors:
apple-ci-arm-medium:
macos:
xcode: 15.2.0
xcode: 16.4.0
resource_class: macos.m1.medium.gen1

commands:
Expand All @@ -35,13 +35,24 @@ commands:
steps:
- run:
name: OktaSQLiteStorage unit tests"
command: set -o pipefail && xcodebuild -workspace "OktaLogger.xcworkspace" -scheme "OktaSQLiteStorageTests" -destination "platform=iOS Simulator,OS=latest,name=iPhone 15 Pro Max" test
command: set -o pipefail && xcodebuild -workspace "OktaLogger.xcworkspace" -scheme "OktaSQLiteStorageTests" -destination "platform=iOS Simulator,OS=latest,name=iPhone 16 Pro Max" test
- run:
name: OktaLogger unit tests"
command: set -o pipefail && xcodebuild -workspace "OktaLogger.xcworkspace" -scheme "OktaLoggerTests" -destination "platform=iOS Simulator,OS=latest,name=iPhone 15 Pro Max" test
command: set -o pipefail && xcodebuild -workspace "OktaLogger.xcworkspace" -scheme "OktaLoggerTests" -destination "platform=iOS Simulator,OS=latest,name=iPhone 16 Pro Max" test
- run:
when: always
name: Pack any xcresult, then remove.
command: |
pushd /Users/distiller/Library/Developer/Xcode/DerivedData/OktaLogger-brtczdmizdnmmgceswezmvcdqias/Logs/Test
find . -type d -name "*.xcresult" | xargs -I{} bash -c "tar zcf {}.tar.gz \"{}\" && rm -rf \"{}\""
popd
mkdir artifacts
mv /Users/distiller/Library/Developer/Xcode/DerivedData/OktaLogger-brtczdmizdnmmgceswezmvcdqias/Logs/Test/*.tar.gz artifacts
- store_artifacts:
path: "artifacts"
# - run:
# name: OktaAnalytics unit tests"
# command: set -o pipefail && xcodebuild -workspace "OktaLogger.xcworkspace" -scheme "OktaAnalyticsTests" -destination "platform=iOS Simulator,OS=latest,name=iPhone 14" test
# command: set -o pipefail && xcodebuild -workspace "OktaLogger.xcworkspace" -scheme "OktaAnalyticsTests" -destination "platform=iOS Simulator,OS=latest,name=iPhone 16" test
jobs:
setup:
executor: apple-ci-arm-medium
Expand Down Expand Up @@ -78,12 +89,6 @@ jobs:
run-on-non-main: <<pipeline.parameters.run-on-non-main>>

workflows:
semgrep:
jobs:
- general-platform-helpers/job-semgrep-scan:
context:
- static-analysis
name: semgrep-scan
build-test:
jobs:
- setup
Expand Down
2 changes: 1 addition & 1 deletion OktaLogger.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Pod::Spec.new do |s|
instabugLogger.ios.source_files = [
'Sources/OktaLogger/InstabugLogger/*'
]
instabugLogger.ios.dependency 'Instabug', '~> 13'
instabugLogger.ios.dependency 'Instabug', '~> 16'
instabugLogger.dependency 'OktaLogger/Core'
end

Expand Down
2 changes: 1 addition & 1 deletion Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ target 'OktaLogger' do
pod 'Firebase/AnalyticsWithoutAdIdSupport'
pod 'Firebase/Crashlytics', '~>11.3.0'
pod 'CocoaLumberjack/Swift', '~>3.6.0'
pod 'Instabug', '13.3.0'
pod 'Instabug', '16.0.3'
pod 'SwiftLint', '0.51'
end

Expand Down
16 changes: 8 additions & 8 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ PODS:
- GoogleUtilities/Privacy
- GRDB.swift/SQLCipher (6.20.2):
- SQLCipher (>= 3.4.2)
- Instabug (13.3.0)
- Instabug (16.0.3)
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
- nanopb/decode (3.30910.0)
- nanopb/encode (3.30910.0)
- OktaAnalytics (2.1):
- OktaAnalytics (2.2):
- AppCenter (~> 5)
- Firebase/AnalyticsWithoutAdIdSupport
- OktaLogger/Core (~> 1)
Expand All @@ -122,7 +122,7 @@ PODS:
- Firebase/Crashlytics (~> 11)
- OktaLogger/Core
- OktaLogger/InstabugLogger (1.3.20):
- Instabug (~> 13)
- Instabug (~> 16)
- OktaLogger/Core
- OktaSQLiteStorage (0.0.5):
- GRDB.swift/SQLCipher (= 6.20.2)
Expand All @@ -143,7 +143,7 @@ DEPENDENCIES:
- Firebase/AnalyticsWithoutAdIdSupport
- Firebase/Crashlytics (~> 11.3.0)
- GRDB.swift/SQLCipher (= 6.20.2)
- Instabug (= 13.3.0)
- Instabug (= 16.0.3)
- OktaAnalytics (from `.`)
- OktaLogger (from `.`)
- OktaLogger/Core (from `.`)
Expand Down Expand Up @@ -199,16 +199,16 @@ SPEC CHECKSUMS:
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
GRDB.swift: 3eb7447131d897afb420d6877a45fd8bfca313c1
Instabug: 4f26295103a330ec0236918359eef7ccaa74e2fa
Instabug: b6290ceceb5d98966aa6f10fbd7970026a916f65
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
OktaAnalytics: 4a9b265fc7f7634aa564505446cb3dad8fa72b8c
OktaLogger: 25cb42a2ff6defbb234f1dd7c1f066011678c762
OktaAnalytics: ef69be5de7b323a9dc21d76b27a7d5899104a114
OktaLogger: 6dbe971237ce7a4ef1d82694acdd3af08d410ca3
OktaSQLiteStorage: 4761bb59ed2d6fc2ba6184a4fdd79f2fbeadc50c
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
SQLCipher: f2e96b3822e3006b379181a0e4fd145f6de29b56
SwiftLint: 1b7561918a19e23bfed960e40759086e70f4dba5

PODFILE CHECKSUM: 5667fd7a1d4990d8e23a648ebfa747f6f3d8acbe
PODFILE CHECKSUM: ecdf063974058b530adeb0f4a28f92453ba0b076

COCOAPODS: 1.15.2
13 changes: 12 additions & 1 deletion Sources/OktaLogger/FileLoggers/OktaLoggerFileLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import LoggerCore
#endif

@objc
public class OktaLoggerFileLogger: OktaLoggerDestinationBase {
public class OktaLoggerFileLogger: OktaLoggerDestinationBase, FileLoggerDelegate {

var delegate: FileLoggerDelegate

Expand All @@ -43,10 +43,16 @@ public class OktaLoggerFileLogger: OktaLoggerDestinationBase {
Log file path
*/
@objc
@available(*, deprecated, message: "Use directoryPath() instead.")
public func logDirectoryAbsolutePath() -> String? {
return delegate.directoryPath()
}

@objc
func directoryPath() -> String? {
return delegate.directoryPath()
}

// MARK: Retrieve Logs
/**
Retrieve logs in the current thread. This method could be time consuming,
Expand Down Expand Up @@ -89,7 +95,12 @@ public class OktaLoggerFileLogger: OktaLoggerDestinationBase {
/**
Translate log message into DDLog message
*/
@available(*, deprecated, message: "Use log(_ level: OktaLoggerLogLevel, _ message: String) instead.")
func log(level: OktaLoggerLogLevel, message: String) {
delegate.log(level, message)
}

func log(_ level: OktaLoggerLogLevel, _ message: String) {
delegate.log(level, message)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and limitations under the License.
*/

import Instabug
import InstabugSDK
#if SWIFT_PACKAGE
import LoggerCore
#endif
Expand Down
174 changes: 104 additions & 70 deletions Tests/OktaLoggerTests/OktaLoggerFileLoggerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,32 @@ class OktaLoggerFileLoggerTests: XCTestCase {
}

// Verify that log files contains exactly 5 lines and purge logs
var receiveLogsExpectation = XCTestExpectation(description: "Should receive logs data")
var logs: [Data] = []
testObject.getLogs { result in
logs = result
receiveLogsExpectation.fulfill()
}
wait(for: [receiveLogsExpectation], timeout: 10.0)
XCTAssertEqual(FileTestsHelper.countLines(logs[0]), 5)
testObject.purgeLogs()
var expectedMessages = ["1:log message", "2:log message", "3:log message", "4:log message", "5:log message"]
var expectation = XCTestExpectation(description: "Should receive logs: \(expectedMessages.joined(separator: ", "))")
pollForLogCompletion(delegate: testObject, expectedMessages: expectedMessages, expectation: expectation)
wait(for: [expectation], timeout: Double(expectedMessages.count) * 3.0)

// Call log method 2 times
var logPaths = testObject.getLogPaths()
testObject.purgeLogs()
expectation = XCTestExpectation(description: "Logs should purge before second write")
pollForPurgeCompletion(urls: logPaths, expectation: expectation)
wait(for: [expectation], timeout: 10)

logger.debug(eventName: "AFTER_PURGE", message: "Debug log")
logger.info(eventName: "AFTER_PURGE", message: "Debug log")

// Verify that log files contains exactly 2 lines
receiveLogsExpectation = XCTestExpectation(description: "Should receive logs data")
logs = []
testObject.getLogs { result in
logs = result
receiveLogsExpectation.fulfill()
}
wait(for: [receiveLogsExpectation], timeout: 10.0)
XCTAssertEqual(FileTestsHelper.countLines(logs[0]), 2)
expectedMessages = ["Debug log", "Debug log"]
expectation = XCTestExpectation(description: "Should receive logs: \(expectedMessages.joined(separator: ", "))")
pollForLogCompletion(delegate: testObject, expectedMessages: expectedMessages, expectation: expectation)
wait(for: [expectation], timeout: Double(expectedMessages.count) * 3.0)

logPaths = testObject.getLogPaths()
testObject.purgeLogs()
expectation = XCTestExpectation(description: "Logs should purge on completion")
pollForPurgeCompletion(urls: logPaths, expectation: expectation)
wait(for: [expectation], timeout: 10)
}

func testLumberjackFileLogger() {
Expand All @@ -77,48 +79,41 @@ class OktaLoggerFileLoggerTests: XCTestCase {
for i in 1...5 {
testObject.log(.debug, "log \(i)")
}
sleep(2)
// Verify that log files contains exactly 5 lines and purge logs
var receiveLogsExpectation = XCTestExpectation(description: "Should receive logs data")
var logs: [Data] = []
testObject.getLogs { result in
logs = result
receiveLogsExpectation.fulfill()
}
wait(for: [receiveLogsExpectation], timeout: 10.0)
guard let testLog = logs.first else {
XCTFail("No logs")
return
}
XCTAssertEqual(FileTestsHelper.countLines(testLog), 5)

// Verify that log files contains exactly 5 lines
var expectedMessages = ["log 1", "log 2", "log 3", "log 4", "log 5"]
var expectation = XCTestExpectation(description: "Should receive logs: \(expectedMessages.joined(separator: ", "))")
pollForLogCompletion(delegate: testObject, expectedMessages: expectedMessages, expectation: expectation)
wait(for: [expectation], timeout: Double(expectedMessages.count) * 3.0)

// Verify that actual log files paths same as expected
var extectedPaths = FileTestsHelper.getPaths(testObject: testObject)
var expectedPaths = FileTestsHelper.getPaths(testObject: testObject)
var actualPaths = testObject.getLogPaths()
XCTAssertEqual(actualPaths, extectedPaths)
XCTAssertEqual(actualPaths, expectedPaths)

testObject.purgeLogs()
expectation = XCTestExpectation(description: "Logs should purge before second write")
pollForPurgeCompletion(urls: expectedPaths, expectation: expectation)
wait(for: [expectation], timeout: 10)

testObject.log(.debug, "After purge")
testObject.log(.info, "After purge")
sleep(2)
receiveLogsExpectation = XCTestExpectation(description: "Should receive logs data")
testObject.getLogs { result in
logs = result
receiveLogsExpectation.fulfill()
}

wait(for: [receiveLogsExpectation], timeout: 10.0)
guard let logAfterPurge = logs.first else {
XCTFail("No logs after purge")
return
}
XCTAssertEqual(FileTestsHelper.countLines(logAfterPurge), 2)
// Verify that log files contains exactly 2 lines
expectedMessages = ["After purge", "After purge"]
expectation = XCTestExpectation(description: "Should receive logs: \(expectedMessages.joined(separator: ", "))")
pollForLogCompletion(delegate: testObject, expectedMessages: expectedMessages, expectation: expectation)
wait(for: [expectation], timeout: Double(expectedMessages.count) * 3.0)

// Verify that actual log files paths same as expected
extectedPaths = FileTestsHelper.getPaths(testObject: testObject)
expectedPaths = FileTestsHelper.getPaths(testObject: testObject)
actualPaths = testObject.getLogPaths()
XCTAssertEqual(actualPaths, extectedPaths)
XCTAssertEqual(actualPaths, expectedPaths)

testObject.purgeLogs()
expectation = XCTestExpectation(description: "Logs should purge on completion")
pollForPurgeCompletion(urls: expectedPaths, expectation: expectation)
wait(for: [expectation], timeout: 10)
}

func testLumberjackCustomNameMultipleFilesLogger() {
Expand All @@ -141,38 +136,77 @@ class OktaLoggerFileLoggerTests: XCTestCase {
}

// Verify that log files contains exactly 5 lines and purge logs
var receiveLogsExpectation = XCTestExpectation(description: "Should receive logs data")
var logs: [Data] = []
testObject.getLogs { result in
logs = result
receiveLogsExpectation.fulfill()
}
wait(for: [receiveLogsExpectation], timeout: 20.0)
for logData in logs {
XCTAssertEqual(FileTestsHelper.countLines(logData), 2)
}
var expectedMessages = ["log 1", "log 1", "log 2", "log 2", "log 3", "log 3", "log 4", "log 4", "log 5", "log 5"]
var expectation = XCTestExpectation(description: "Should receive logs: \(expectedMessages.joined(separator: ", "))")
pollForLogCompletion(delegate: testObject, expectedMessages: expectedMessages, expectation: expectation)
wait(for: [expectation], timeout: Double(expectedMessages.count) * 3.0)

// Verify that actual log files paths same as expected
var extectedPaths = Set(FileTestsHelper.getPaths(testObject: testObject, withArchived: true))
// Verify that actual log files paths are same as expected
var expectedPaths = Set(FileTestsHelper.getPaths(testObject: testObject, withArchived: true))
var actualPaths = Set(testObject.getLogPaths())
XCTAssertEqual(actualPaths, extectedPaths)
XCTAssertEqual(actualPaths, expectedPaths)

testObject.purgeLogs()
expectation = XCTestExpectation(description: "Logs should purge")
pollForPurgeCompletion(urls: Array(expectedPaths), expectation: expectation)
wait(for: [expectation], timeout: 10)

testObject.log(.debug, "After purge")
testObject.log(.info, "After purge")
receiveLogsExpectation = XCTestExpectation(description: "Should receive logs data")
testObject.getLogs { result in
logs = result
receiveLogsExpectation.fulfill()
}
wait(for: [receiveLogsExpectation], timeout: 20.0)
XCTAssertEqual(FileTestsHelper.countLines(logs[0]), 2)

expectedMessages = ["After purge", "After purge"]
expectation = XCTestExpectation(description: "Should receive logs: \(expectedMessages.joined(separator: ", "))")
pollForLogCompletion(delegate: testObject, expectedMessages: expectedMessages, expectation: expectation)
wait(for: [expectation], timeout: Double(expectedMessages.count) * 3.0)

// Verify that actual log files paths same as expected
extectedPaths = Set(FileTestsHelper.getPaths(testObject: testObject, withArchived: true))
// Verify that actual log files paths are same as expected
expectedPaths = Set(FileTestsHelper.getPaths(testObject: testObject, withArchived: true))
actualPaths = Set(testObject.getLogPaths())
XCTAssertEqual(actualPaths, extectedPaths)
XCTAssertEqual(actualPaths, expectedPaths)

testObject.purgeLogs()
expectation = XCTestExpectation(description: "Logs should purge")
pollForPurgeCompletion(urls: Array(expectedPaths), expectation: expectation)
wait(for: [expectation], timeout: 10)
}

private func pollForLogCompletion(delegate: FileLoggerDelegate, expectedMessages: [String], expectation: XCTestExpectation) {
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 3) {
delegate.getLogs { result in
let messages: [String] = result.flatMap { log -> [String] in
guard let logString = String(data: log, encoding: .utf8) else {
return []
}

return logString.split(separator: "\n").map { String($0) }
}

if messages.count >= expectedMessages.count {
for (index, message) in messages.prefix(expectedMessages.count).enumerated() {
if !message.contains(expectedMessages[index]) {
XCTFail("Expected log message containing: \(expectedMessages[index]), but received: \(message)")
}
}

expectation.fulfill()
return
}

self.pollForLogCompletion(delegate: delegate, expectedMessages: expectedMessages, expectation: expectation)
}
}
}

private func pollForPurgeCompletion(urls: [URL], expectation: XCTestExpectation) {
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 3) {
let fileManager = FileManager.default
for url in urls {
if fileManager.fileExists(atPath: url.path) {
self.pollForPurgeCompletion(urls: urls, expectation: expectation)
return
}
}
expectation.fulfill()
}
}
}
Loading