Files
swift-mirror/test/attr/attr_backDeployed_evolution.swift

213 lines
8.3 KiB
Swift

//
// At a high level, this test is designed to verify that use of declarations
// annotated with @backDeployed behave as expected when running a client binary
// on an older OS that does not have the back deployed APIs. The
// BackDeployHelper framework has a number of APIs that are available in the
// OSes identified by the "BackDeploy 1.0" availability macro and are back
// deployed before OSes identified "BackDeploy 2.0". Verification is performed
// the following way:
//
// 1. Build the helper framework with both BackDeploy 1.0 defined to an
// OS version before Swift ABI stability and 2.0 defined to an OS version
// after Swift ABI stability. Note that stradling ABI stability is not
// a necessary requirement of this test; it's just convenient to use OS
// versions that correspond to existing lit substitutions.
// 2. Build the client executable with a deployment target set to the same
// OS version as BackDeploy 2.0.
// 3. Run the client executable, verifying that the copies of the functions in
// the framework are used (verified by runtime logic using #dsohandle).
// 4. Build a new copy of the helper framework, this time with BackDeploy 2.0
// set to a distant future OS version.
// 5. Build a new copy of the client executable using the new framework and
// the deployment target set to the same OS version as BackDeploy 1.0.
// 6. Run the new executable, verifying with #dsohandle that client copies of
// the APIs are used.
// 7. Re-build the framework in place, this time stripping the definitions of
// the back deployed APIs entirely.
// 8. Re-run the unmodified executable, with the same expectations as in (6).
// However, this time we're also verifying that the executable can run even
// without the original API symbols present in the linked dylib.
//
// REQUIRES: executable_test
// REQUIRES: OS=macosx
// The deployment targets and availability versions hardcoded into this test
// aren't compatible with the environment of the back deployment CI bots.
// UNSUPPORTED: back_deployment_runtime
// Remote test execution does not support dynamically loaded libraries.
// UNSUPPORTED: remote_run
// ---- (0) Prepare SDK
// RUN: %empty-directory(%t)
// RUN: %empty-directory(%t/SDK_ABI)
// RUN: %empty-directory(%t/SDK_BD)
// ---- (1) Build framework with BackDeploy 2.0 in the past
// RUN: mkdir -p %t/SDK_ABI/Frameworks/BackDeployHelper.framework/Modules/BackDeployHelper.swiftmodule
// RUN: %target-build-swift-dylib(%t/SDK_ABI/Frameworks/BackDeployHelper.framework/BackDeployHelper) \
// RUN: -emit-module-path %t/SDK_ABI/Frameworks/BackDeployHelper.framework/Modules/BackDeployHelper.swiftmodule/%module-target-triple.swiftmodule \
// RUN: -module-name BackDeployHelper -emit-module %S/Inputs/BackDeployHelper.swift \
// RUN: -target %target-cpu-apple-macosx10.15 \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 1.0:macOS 10.14.3' \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 2.0:macOS 10.15' \
// RUN: -Xlinker -install_name -Xlinker @rpath/BackDeployHelper.framework/BackDeployHelper \
// RUN: -enable-library-evolution
// ---- (2) Build executable
// RUN: %target-build-swift -emit-executable %s -g -o %t/test_ABI \
// RUN: -target %target-cpu-apple-macosx10.14.3 \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 1.0:macOS 10.14.3' \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 2.0:macOS 10.15' \
// RUN: -F %t/SDK_ABI/Frameworks/ -framework BackDeployHelper \
// RUN: %target-rpath(@executable_path/SDK_ABI/Frameworks)
// ---- (3) Run executable
// RUN: %target-codesign %t/test_ABI
// RUN: %target-run %t/test_ABI | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-ABI %s
// ---- (4) Build framework with BackDeploy 2.0 in the future
// RUN: mkdir -p %t/SDK_BD/Frameworks/BackDeployHelper.framework/Modules/BackDeployHelper.swiftmodule
// RUN: %target-build-swift-dylib(%t/SDK_BD/Frameworks/BackDeployHelper.framework/BackDeployHelper) \
// RUN: -emit-module-path %t/SDK_BD/Frameworks/BackDeployHelper.framework/Modules/BackDeployHelper.swiftmodule/%module-target-triple.swiftmodule \
// RUN: -module-name BackDeployHelper -emit-module %S/Inputs/BackDeployHelper.swift \
// RUN: -target %target-cpu-apple-macosx10.15 \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 1.0:macOS 10.14.3' \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 2.0:macOS 999.0' \
// RUN: -Xlinker -install_name -Xlinker @rpath/BackDeployHelper.framework/BackDeployHelper \
// RUN: -enable-library-evolution
// ---- (5) Build executable
// RUN: %target-build-swift -emit-executable %s -g -o %t/test_BD \
// RUN: -target %target-cpu-apple-macosx10.14.3 \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 1.0:macOS 10.14.3' \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 2.0:macOS 999.0' \
// RUN: -F %t/SDK_BD/Frameworks/ -framework BackDeployHelper \
// RUN: %target-rpath(@executable_path/SDK_BD/Frameworks)
// ---- (6) Run executable
// RUN: %target-codesign %t/test_BD
// RUN: %target-run %t/test_BD | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-BD %s
// ---- (7) Re-build framework with the back deployed APIs stripped
// RUN: %empty-directory(%t/SDK_BD)
// RUN: mkdir -p %t/SDK_BD/Frameworks/BackDeployHelper.framework/Modules/BackDeployHelper.swiftmodule
// RUN: %target-build-swift-dylib(%t/SDK_BD/Frameworks/BackDeployHelper.framework/BackDeployHelper) \
// RUN: -emit-module-path %t/SDK_BD/Frameworks/BackDeployHelper.framework/Modules/BackDeployHelper.swiftmodule/%module-target-triple.swiftmodule \
// RUN: -module-name BackDeployHelper -emit-module %S/Inputs/BackDeployHelper.swift \
// RUN: -target %target-cpu-apple-macosx10.15 \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 1.0:macOS 10.14.3' \
// RUN: -Xfrontend -define-availability \
// RUN: -Xfrontend 'BackDeploy 2.0:macOS 999.0' \
// RUN: -Xlinker -install_name -Xlinker @rpath/BackDeployHelper.framework/BackDeployHelper \
// RUN: -enable-library-evolution -DSTRIP_V2_APIS
// ---- (8) Re-run executable
// RUN: %target-codesign %t/test_BD
// RUN: %target-run %t/test_BD | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-BD %s
import BackDeployHelper
// CHECK: client: check
testPrint(handle: #dsohandle, "check")
// CHECK: library: check
testPrint(handle: libraryHandle(), "check")
if isV2OrLater() {
precondition(!v2APIsAreStripped())
}
// CHECK-ABI: library: trivial
// CHECK-BD: client: trivial
trivial()
precondition(try! pleaseThrow(false))
do {
_ = try pleaseThrow(true)
fatalError("Should have thrown")
} catch {
precondition(error as? BadError == BadError.bad)
}
precondition(BadError(fromEmoji: "💥") == nil)
precondition(BadError(fromEmoji: "❗️") == .bad)
precondition(BadError(fromEmoji: "‼️") == .reallyBad)
do {
let defaulted = IntArray()
precondition(defaulted.values == [])
let empty = IntArray.empty
precondition(empty.values == [])
var array = IntArray([5])
// CHECK-ABI: library: [5]
// CHECK-BD: client: [5]
array.print()
array.append(42)
genericAppend(&array, 3)
let countable = array.toCountable()
precondition(existentialCount(countable) == 3)
array[1] += 1
precondition(array[1] == 43)
// CHECK-ABI: library: [5, 43, 3]
// CHECK-BD: client: [5, 43, 3]
array.print()
// CHECK-ABI: library: [5, 43, 3]
// CHECK-BD: client: [5, 43, 3]
array.rawValues.print()
precondition(array.removeLast() == 3)
}
do {
let defaulted = ReferenceIntArray()
precondition(defaulted.values == [])
let empty = ReferenceIntArray.empty
precondition(empty.values == [])
var array = ReferenceIntArray([7])
// CHECK-ABI: library: [7]
// CHECK-BD: client: [7]
array.print()
do {
let copy = array.copy()
precondition(array !== copy)
precondition(copy.values == [7])
}
array.append(39)
genericAppend(&array, 1)
let countable = array.toCountable()
precondition(existentialCount(countable) == 3)
array[1] += 1
precondition(array[1] == 40)
// CHECK-ABI: library: [7, 40, 1]
// CHECK-BD: client: [7, 40, 1]
array.print()
// CHECK-ABI: library: [7, 40, 1]
// CHECK-BD: client: [7, 40, 1]
array.rawValues.print()
precondition(array.removeLast() == 1)
}