From 5ed00636f4684d74d70dc48261df812478ffbf2c Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 10 Oct 2024 09:30:22 -0700 Subject: [PATCH 1/4] Revert "additional env var to force saying we're in tty" This reverts commit c70f3d2b2468e48ff7386b92fd638214909f33f3. --- Tests/JavaKitTests/BasicRuntimeTests.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Tests/JavaKitTests/BasicRuntimeTests.swift b/Tests/JavaKitTests/BasicRuntimeTests.swift index e8e9ac82..ff368fbd 100644 --- a/Tests/JavaKitTests/BasicRuntimeTests.swift +++ b/Tests/JavaKitTests/BasicRuntimeTests.swift @@ -16,7 +16,6 @@ import JavaKit import JavaKitNetwork import JavaKitVM import Testing -import Foundation #if os(Linux) import Glibc @@ -95,10 +94,7 @@ var isLinux: Bool { /// Whether we're running on MacOS in an interactive terminal session. var isMacOSTerminal: Bool { - isMacOS && ( - isatty(STDOUT_FILENO) == 1 || - ProcessInfo.processInfo.environment["IS_TTY"] != nil // since 'swift test' still sometimes hides the fact we're in tty - ) + isMacOS && isatty(STDOUT_FILENO) == 1 } /// Whether we're running on MacOS. From e40db8b8af643649023147a3850fd585cf5b74e2 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 10 Oct 2024 09:30:57 -0700 Subject: [PATCH 2/4] Revert "Skipping the JVM tests on macOS terminal since unreliable (crashes in JVM create)" This reverts commit 6f6c3500d995dc90d296a15230e66ffbb742f674. --- .../VariableImportTests.swift | 3 ++- Tests/JavaKitTests/BasicRuntimeTests.swift | 19 ++++--------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/Tests/JExtractSwiftTests/VariableImportTests.swift b/Tests/JExtractSwiftTests/VariableImportTests.swift index 2f58c5c8..f59b8ff4 100644 --- a/Tests/JExtractSwiftTests/VariableImportTests.swift +++ b/Tests/JExtractSwiftTests/VariableImportTests.swift @@ -41,7 +41,7 @@ final class VariableImportTests { ) st.log.logLevel = .error - try st.analyze(swiftInterfacePath: "/fake/Fake.swiftinterface", text: class_interfaceFile) + try await st.analyze(swiftInterfacePath: "/fake/Fake.swiftinterface", text: class_interfaceFile) let identifier = "counterInt" let varDecl: ImportedVariable? = @@ -59,6 +59,7 @@ final class VariableImportTests { } assertOutput( + dump: true, output, expected: """ diff --git a/Tests/JavaKitTests/BasicRuntimeTests.swift b/Tests/JavaKitTests/BasicRuntimeTests.swift index ff368fbd..2e47b84f 100644 --- a/Tests/JavaKitTests/BasicRuntimeTests.swift +++ b/Tests/JavaKitTests/BasicRuntimeTests.swift @@ -17,19 +17,13 @@ import JavaKitNetwork import JavaKitVM import Testing -#if os(Linux) -import Glibc -#else -import Darwin -#endif - @MainActor let jvm = try! JavaVirtualMachine(vmOptions: []) @Suite @MainActor struct BasicRuntimeTests { - @Test("Object management", .disabled(if: isMacOSTerminal || isLinux, "JVM creation fails occasionally in terminal on macOS, and some issues on Linux")) + @Test("Object management", .disabled(if: isLinux, "Attempts to refcount a null pointer on Linux")) func javaObjectManagement() throws { let sneakyJavaThis: jobject do { @@ -55,7 +49,7 @@ struct BasicRuntimeTests { #expect(url.javaHolder === urlAgain.javaHolder) } - @Test("Java exceptions", .disabled(if: isMacOSTerminal || isLinux, "JVM creation fails occasionally in terminal on macOS, and some issues on Linux")) + @Test("Java exceptions", .disabled(if: isLinux, "Attempts to refcount a null pointer on Linux")) func javaExceptionsInSwift() throws { do { _ = try URL("bad url", environment: jvm.environment) @@ -64,13 +58,13 @@ struct BasicRuntimeTests { } } - @Test("Static methods", .disabled(if: isMacOSTerminal || isLinux, "JVM creation fails occasionally in terminal on macOS, and some issues on Linux")) + @Test("Static methods", .disabled(if: isMacOS, "Fails on macOS command line")) func staticMethods() throws { let urlConnectionClass = try JavaClass(in: jvm.environment) #expect(urlConnectionClass.getDefaultAllowUserInteraction() == false) } - @Test("Class instance lookup", .disabled(if: isMacOSTerminal || isLinux, "JVM creation fails occasionally in terminal on macOS, and some issues on Linux")) + @Test("Class instance lookup") func classInstanceLookup() throws { do { _ = try JavaClass(in: jvm.environment) @@ -92,11 +86,6 @@ var isLinux: Bool { #endif } -/// Whether we're running on MacOS in an interactive terminal session. -var isMacOSTerminal: Bool { - isMacOS && isatty(STDOUT_FILENO) == 1 -} - /// Whether we're running on MacOS. var isMacOS: Bool { #if os(macOS) From 48396488cf3276b748593bc9c93788ce59b257ab Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 10 Oct 2024 09:40:07 -0700 Subject: [PATCH 3/4] Temporarily switch JavaKitTests target to XCTest Command-line testing on macOS is broken for the JavaKitTests due to an interaction between the Java Virtual Machine, a helper test process for swift-testing (`swiftpm-testing-helper`), and some macOS security features. Work around the issue by replacing our use of swift-testing with XCTest, whose helper process doesn't seem to have this problem. Only do so for test targets that need to spin up an instance of the JVM, and keep using swift-testing everywhere we can. This makes me very sad, but is better than the current solution of disabling these tests when running from the terminal. Once we've found a solution for the underlying issue, we'll revert this change as get back to swift-testing and its much nicer testing output. Fixes issue #43 without disabling tests. --- Tests/JavaKitTests/BasicRuntimeTests.swift | 54 +++++++++++----------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/Tests/JavaKitTests/BasicRuntimeTests.swift b/Tests/JavaKitTests/BasicRuntimeTests.swift index 2e47b84f..ea51a4e2 100644 --- a/Tests/JavaKitTests/BasicRuntimeTests.swift +++ b/Tests/JavaKitTests/BasicRuntimeTests.swift @@ -15,23 +15,25 @@ import JavaKit import JavaKitNetwork import JavaKitVM -import Testing +import XCTest // NOTE: Workaround for https://github.com/swiftlang/swift-java/issues/43 @MainActor let jvm = try! JavaVirtualMachine(vmOptions: []) -@Suite @MainActor -struct BasicRuntimeTests { - @Test("Object management", .disabled(if: isLinux, "Attempts to refcount a null pointer on Linux")) - func javaObjectManagement() throws { +class BasicRuntimeTests: XCTestCase { + func testJavaObjectManagement() throws { + if isLinux { + throw XCTSkip("Attempts to refcount a null pointer on Linux") + } + let sneakyJavaThis: jobject do { let object = JavaObject(environment: jvm.environment) - #expect(object.toString().starts(with: "java.lang.Object")) + XCTAssert(object.toString().starts(with: "java.lang.Object")) // Make sure this object was promoted to a global reference. - #expect(object.javaEnvironment.pointee?.pointee.GetObjectRefType(object.javaEnvironment, object.javaThis) == JNIGlobalRefType) + XCTAssertEqual(object.javaEnvironment.pointee?.pointee.GetObjectRefType(object.javaEnvironment, object.javaThis), JNIGlobalRefType) // Keep track of the Java object. sneakyJavaThis = object.javaThis @@ -39,37 +41,42 @@ struct BasicRuntimeTests { // The reference should now be invalid, because we've deleted the // global reference. - #expect(jvm.environment.pointee?.pointee.GetObjectRefType(jvm.environment, sneakyJavaThis) == JNIInvalidRefType) + XCTAssertEqual(jvm.environment.pointee?.pointee.GetObjectRefType(jvm.environment, sneakyJavaThis), JNIInvalidRefType) // 'super' and 'as' don't require allocating a new holder. let url = try URL("http://swift.org", environment: jvm.environment) let superURL = url.super - #expect(url.javaHolder === superURL.javaHolder) + XCTAssert(url.javaHolder === superURL.javaHolder) let urlAgain = superURL.as(URL.self)! - #expect(url.javaHolder === urlAgain.javaHolder) + XCTAssert(url.javaHolder === urlAgain.javaHolder) } - @Test("Java exceptions", .disabled(if: isLinux, "Attempts to refcount a null pointer on Linux")) - func javaExceptionsInSwift() throws { + func testJavaExceptionsInSwift() throws { + if isLinux { + throw XCTSkip("Attempts to refcount a null pointer on Linux") + } + do { _ = try URL("bad url", environment: jvm.environment) } catch { - #expect(String(describing: error) == "no protocol: bad url") + XCTAssert(String(describing: error) == "no protocol: bad url") } } - @Test("Static methods", .disabled(if: isMacOS, "Fails on macOS command line")) - func staticMethods() throws { + func testStaticMethods() throws { + if isLinux { + throw XCTSkip("Attempts to refcount a null pointer on Linux") + } + let urlConnectionClass = try JavaClass(in: jvm.environment) - #expect(urlConnectionClass.getDefaultAllowUserInteraction() == false) + XCTAssert(urlConnectionClass.getDefaultAllowUserInteraction() == false) } - @Test("Class instance lookup") - func classInstanceLookup() throws { + func testClassInstanceLookup() throws { do { _ = try JavaClass(in: jvm.environment) } catch { - #expect(String(describing: error) == "org/swift/javakit/Nonexistent") + XCTAssertEqual(String(describing: error), "org/swift/javakit/Nonexistent") } } } @@ -85,12 +92,3 @@ var isLinux: Bool { return false #endif } - -/// Whether we're running on MacOS. -var isMacOS: Bool { - #if os(macOS) - return true - #else - return false - #endif -} From 6d4c9f1871d39c72639c1373ab41e682f3b561bf Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 10 Oct 2024 09:56:45 -0700 Subject: [PATCH 4/4] async'ify the XCTest test cases so they can hop to the main actor --- Tests/JavaKitTests/BasicRuntimeTests.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/JavaKitTests/BasicRuntimeTests.swift b/Tests/JavaKitTests/BasicRuntimeTests.swift index ea51a4e2..33f795b9 100644 --- a/Tests/JavaKitTests/BasicRuntimeTests.swift +++ b/Tests/JavaKitTests/BasicRuntimeTests.swift @@ -22,7 +22,7 @@ let jvm = try! JavaVirtualMachine(vmOptions: []) @MainActor class BasicRuntimeTests: XCTestCase { - func testJavaObjectManagement() throws { + func testJavaObjectManagement() async throws { if isLinux { throw XCTSkip("Attempts to refcount a null pointer on Linux") } @@ -51,7 +51,7 @@ class BasicRuntimeTests: XCTestCase { XCTAssert(url.javaHolder === urlAgain.javaHolder) } - func testJavaExceptionsInSwift() throws { + func testJavaExceptionsInSwift() async throws { if isLinux { throw XCTSkip("Attempts to refcount a null pointer on Linux") } @@ -63,7 +63,7 @@ class BasicRuntimeTests: XCTestCase { } } - func testStaticMethods() throws { + func testStaticMethods() async throws { if isLinux { throw XCTSkip("Attempts to refcount a null pointer on Linux") } @@ -72,7 +72,7 @@ class BasicRuntimeTests: XCTestCase { XCTAssert(urlConnectionClass.getDefaultAllowUserInteraction() == false) } - func testClassInstanceLookup() throws { + func testClassInstanceLookup() async throws { do { _ = try JavaClass(in: jvm.environment) } catch {