Skip to content

Commit

Permalink
Created integration test suite and moved some tests into it.
Browse files Browse the repository at this point in the history
  • Loading branch information
erikdoe committed Mar 21, 2024
1 parent 194ed65 commit bc6dd46
Show file tree
Hide file tree
Showing 8 changed files with 481 additions and 69 deletions.
345 changes: 340 additions & 5 deletions CCMenu.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

18 changes: 16 additions & 2 deletions CCMenu.xcodeproj/xcshareddata/xcschemes/CCMenu.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
buildConfiguration = "Testing"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO">
<CommandLineArguments>
<CommandLineArgument
argument = "-ignoreDefaults 1"
argument = "-ignoreDefaults true"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-pauseMonitor true"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
Expand All @@ -44,6 +48,16 @@
ReferencedContainer = "container:CCMenu.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3C95D34D2BAC601C007AED1E"
BuildableName = "CCMenuIntegrationTests.xctest"
BlueprintName = "CCMenuIntegrationTests"
ReferencedContainer = "container:CCMenu.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
16 changes: 16 additions & 0 deletions CCMenu/Resources/CCMenuTesting.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>
6 changes: 0 additions & 6 deletions CCMenu/Source/Server Monitor/GitHubFeedReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ class GitHubFeedReader {
public func updatePipelineStatus() async {
do {
let token = try Keychain().getToken(forService: "GitHub")
if let pauseUntil = pipeline.feed.pauseUntil {
guard Date().timeIntervalSince1970 >= Double(pauseUntil) else {
return
}
pipeline.feed.clearPauseUntil()
}
guard let request = GitHubAPI.requestForFeed(feed: pipeline.feed, token: token) else {
throw GithHubFeedReaderError.invalidURLError
}
Expand Down
11 changes: 8 additions & 3 deletions CCMenu/Source/Server Monitor/ServerMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class ServerMonitor {
newPipelines.forEach({ p in Task { await updateStatus(pipeline: p) } })
}

private func updateStatus(pipelines: [Pipeline]) async {
func updateStatus(pipelines: [Pipeline]) async {
if Date().timeIntervalSince(lastPoll).rounded() < pollInterval {
return
}
Expand All @@ -63,10 +63,15 @@ class ServerMonitor {

private func updateStatus(pipeline p: Pipeline) async {
if !networkMonitor.isConnected && pipelineIsRemote(p) && pipelineHasSomeStatus(p) {
debugPrint("skipping/down \(p.feed.url)")
return
}
debugPrint("checking \(p.feed.url)")
var p = p
if let pauseUntil = p.feed.pauseUntil {
if Date().timeIntervalSince1970 <= Double(pauseUntil) {
return
}
p.feed.clearPauseUntil()
}
// TODO: Multiple request will pile up if requests take longer than poll intervall
switch(p.feed.type) {
case .cctray:
Expand Down
101 changes: 101 additions & 0 deletions CCMenuIntegrationTests/ServerMonitorIntegrationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) Erik Doernenburg and contributors
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use these files except in compliance with the License.
*/

import XCTest
import Hummingbird
@testable import CCMenu

final class ServerMonitorIntegrationTests: XCTestCase {

var webapp: HBApplication!

override func setUpWithError() throws {
webapp = HBApplication(configuration: .init(address: .hostname("localhost", port: 8086), logLevel: .error))
try webapp.start()
}

override func tearDownWithError() throws {
webapp.stop()
}


func testDoesntPollWhenPipelineIsPaused() async throws {
var requestCounter = 0
webapp.router.get("/runs", options: .editResponse) { r -> String in
requestCounter += 1
r.response.status = .forbidden
return "{ }"
}

let model = PipelineModel()
var pipeline = Pipeline(name: "CCMenu2", feed: Pipeline.Feed(type: .github, url: "http://localhost:8086/runs", name: nil))
pipeline.feed.pauseUntil = Int(Date(timeIntervalSinceNow: +600).timeIntervalSince1970)
model.add(pipeline: pipeline)

let monitor = await ServerMonitor(model: model)
await monitor.updateStatus(pipelines: model.pipelines)

XCTAssertEqual(0, requestCounter)
}

func testPollsAndClearsPausedIfPausedUntilIsInThePast() async throws {
webapp.router.get("/cctray.xml") { _ in """
<Projects>
<Project activity='Sleeping' lastBuildLabel='build.888' lastBuildStatus='Success' lastBuildTime='2024-02-11T23:19:26+01:00' name='connectfour'></Project>
</Projects>
"""}

let model = PipelineModel()
var pipeline = Pipeline(name: "connectfour", feed: Pipeline.Feed(type: .cctray, url: "http://localhost:8086/cctray.xml", name: "connectfour"))
pipeline.feed.pauseUntil = Int(Date(timeIntervalSinceNow: -5).timeIntervalSince1970)
model.add(pipeline: pipeline)

let monitor = await ServerMonitor(model: model)
await monitor.updateStatus(pipelines: model.pipelines)

XCTAssertNil(model.pipelines.first?.feed.pauseUntil)
XCTAssertEqual("build.888", model.pipelines.first?.status.lastBuild?.label)
}

func testShowsErrorWhenConnectionFails() async throws {
webapp.stop()

let model = PipelineModel()
model.add(pipeline: Pipeline(name: "connectfour", feed: Pipeline.Feed(type: .cctray, url: "http://localhost:8086/cctray.xml", name: "connectfour")))

let monitor = await ServerMonitor(model: model)
await monitor.updateStatus(pipelines: model.pipelines)

XCTAssertEqual("Could not connect to the server.", model.pipelines.first?.connectionError)
}

func testShowsErrorForHTTPError() async throws {
let model = PipelineModel()
model.add(pipeline: Pipeline(name: "connectfour", feed: Pipeline.Feed(type: .cctray, url: "http://localhost:8086/cctray.xml", name: "connectfour")))

let monitor = await ServerMonitor(model: model)
await monitor.updateStatus(pipelines: model.pipelines)

XCTAssertEqual("The server responded: not found", model.pipelines.first?.connectionError)
}

func testShowsErrorWhenFeedDoesntContainProject() async throws {
webapp.router.get("/cctray.xml") { _ in """
<Projects>
<Project activity='Sleeping' lastBuildStatus='Success' lastBuildTime='2024-02-11T23:19:26+01:00' name='other-project'></Project>
</Projects>
"""}

let model = PipelineModel()
model.add(pipeline: Pipeline(name: "connectfour", feed: Pipeline.Feed(type: .cctray, url: "http://localhost:8086/cctray.xml", name: "connectfour")))

let monitor = await ServerMonitor(model: model)
await monitor.updateStatus(pipelines: model.pipelines)

XCTAssertEqual("The server did not provide a status for this pipeline.", model.pipelines.first?.connectionError)
}

}
24 changes: 0 additions & 24 deletions CCMenuTests/ServerMonitorTests.swift

This file was deleted.

29 changes: 0 additions & 29 deletions CCMenuUITests/CCTrayTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,6 @@ class CCTrayTests: XCTestCase {
waitForExpectations(timeout: 2)
}

func testShowsErrorWhenFeedDoesntContainProject() throws {
webapp.router.get("/cctray.xml") { _ in """
<Projects>
<Project activity='Sleeping' lastBuildStatus='Success' lastBuildTime='2024-02-11T23:19:26+01:00' name='other-project'></Project>
</Projects>
"""}

let app = TestHelper.launchApp(pipelines: "CCTrayPipeline.json", pauseMonitor: false)
let window = app.windows["Pipelines"]

// Find the status description field (there's only one because there's only one pipeline), then
// wait for the update to the status text displaying the error message
let descriptionText = window.tables.staticTexts["Status description"]
expectation(for: NSPredicate(format: "value CONTAINS 'The server did not provide a status'"), evaluatedWith: descriptionText)
waitForExpectations(timeout: 5)
}

func testShowsErrorForHTTPError() throws {
let app = TestHelper.launchApp(pipelines: "CCTrayPipeline.json", pauseMonitor: false)
let window = app.windows["Pipelines"]

// Find the status description field (there's only one because there's only one pipeline), then
// wait for the error meesage from the embedded server, which is not found because we didn't
// register any routes
let descriptionText = window.tables.staticTexts["Status description"]
expectation(for: NSPredicate(format: "value CONTAINS 'The server responded: not found'"), evaluatedWith: descriptionText)
waitForExpectations(timeout: 5)
}

func testAddsPipeline() throws {
webapp.router.get("/cctray.xml") { _ in """
<Projects>
Expand Down

0 comments on commit bc6dd46

Please sign in to comment.