Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 27 additions & 5 deletions Sources/SKTestSupport/TestServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import SKCore
import LanguageServerProtocol
import LanguageServerProtocolJSONRPC
import SourceKitLSP
import class Foundation.Pipe
import Foundation
import LSPTestSupport

public final class TestSourceKitServer {
Expand All @@ -36,22 +36,40 @@ public final class TestSourceKitServer {

public static let serverOptions: SourceKitServer.Options = SourceKitServer.Options()

/// If the server is not using the global module cache, the path of the local
/// module cache.
///
/// This module cache will be deleted when the test server is destroyed.
private let moduleCache: URL?

public let client: TestClient
let connImpl: ConnectionImpl

public var hasShutdown: Bool = false

/// The server, if it is in the same process.
public let server: SourceKitServer?

public init(connectionKind: ConnectionKind = .local) {

/// - Parameters:
/// - useGlobalModuleCache: If `false`, the server will use its own module
/// cache in an empty temporary directory instead of the global module cache.
public init(connectionKind: ConnectionKind = .local, useGlobalModuleCache: Bool = true) {
if !useGlobalModuleCache {
moduleCache = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString)
} else {
moduleCache = nil
}
var serverOptions = Self.serverOptions
if let moduleCache {
serverOptions.buildSetup.flags.swiftCompilerFlags += ["-module-cache-path", moduleCache.path]
}

switch connectionKind {
case .local:
let clientConnection = LocalConnection()
let serverConnection = LocalConnection()
client = TestClient(server: serverConnection)
server = SourceKitServer(client: clientConnection, options: Self.serverOptions, onExit: {
server = SourceKitServer(client: clientConnection, options: serverOptions, onExit: {
clientConnection.close()
})

Expand All @@ -76,7 +94,7 @@ public final class TestSourceKitServer {
)

client = TestClient(server: clientConnection)
server = SourceKitServer(client: serverConnection, options: Self.serverOptions, onExit: {
server = SourceKitServer(client: serverConnection, options: serverOptions, onExit: {
serverConnection.close()
})

Expand All @@ -101,6 +119,10 @@ public final class TestSourceKitServer {

deinit {
close()

if let moduleCache {
try? FileManager.default.removeItem(at: moduleCache)
}
}

func close() {
Expand Down
21 changes: 7 additions & 14 deletions Tests/SourceKitLSPTests/SwiftInterfaceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ final class SwiftInterfaceTests: XCTestCase {
}

override func setUp() {
connection = TestSourceKitServer()
// This is the only test that references modules from the SDK (Foundation).
// `testSystemModuleInterface` has been flaky for a long while and a
// hypothesis is that it was failing because of a malformed global module
// cache that might still be present from previous CI runs. If we use a
// local module cache, we define away that source of bugs.
connection = TestSourceKitServer(useGlobalModuleCache: false)
sk = connection.client
_ = try! sk.sendSync(InitializeRequest(
processId: nil,
Expand All @@ -56,20 +61,8 @@ final class SwiftInterfaceTests: XCTestCase {
sk = nil
connection = nil
}

func testSystemModuleInterface() throws {
try XCTSkipIf(true, "Test is flaky - rdar://108256204")
// This test is failing non-deterministically in CI becaue the file contents
// of the generated interface just contain a newline.
// I cannot reproduce the failure locally. Add some logging to determine
// whether the issue is sourcekitd not returning an empty generated
// interface or something around how the file is handled.
// Remove this lowering of the log level once we have determined what the
// issue is (rdar://104871745).
let previousLogLevel = Logger.shared.currentLevel
defer { Logger.shared.setLogLevel(previousLogLevel.description) }
Logger.shared.setLogLevel("debug")

func testSystemModuleInterface() throws {
let url = URL(fileURLWithPath: "/\(UUID())/a.swift")
let uri = DocumentURI(url)

Expand Down