mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[android] Adapt POSIX test to Android
Android differs in subtle ways from Linux. For example sem_open is completely unimplemented, and always returns ENOSYS. None of the test using sem_open were going to work. Additionally the l_len field of the flock struct is typed as __kernel_off_t, which doesn't have the same size as off_t. Finally, the current working directory is always /, so creating relative files will fail. We have to find the executable directory and create the file there.
This commit is contained in:
@@ -1,12 +1,8 @@
|
||||
// RUN: %target-run-simple-swift %t
|
||||
// REQUIRES: executable_test
|
||||
|
||||
// Android Bionic does not provide a working implementation of
|
||||
// <semaphore.h>.
|
||||
// XFAIL: OS=linux-androideabi
|
||||
|
||||
import StdlibUnittest
|
||||
#if os(Linux)
|
||||
#if os(Linux) || os(Android)
|
||||
import Glibc
|
||||
#else
|
||||
import Darwin
|
||||
@@ -17,7 +13,38 @@ chdir(CommandLine.arguments[1])
|
||||
var POSIXTests = TestSuite("POSIXTests")
|
||||
|
||||
let semaphoreName = "TestSem"
|
||||
#if os(Android)
|
||||
// In Android, the cwd is the root directory, which is not writable.
|
||||
let fn: String = {
|
||||
let capacity = Int(PATH_MAX)
|
||||
let resolvedPath = UnsafeMutablePointer<Int8>.allocate(capacity: capacity)
|
||||
resolvedPath.initialize(repeating: 0, count: capacity)
|
||||
defer {
|
||||
resolvedPath.deinitialize(count: capacity)
|
||||
resolvedPath.deallocate()
|
||||
}
|
||||
guard let _ = realpath("/proc/self/exe", resolvedPath) else {
|
||||
fatalError("Couldn't obtain executable path")
|
||||
}
|
||||
|
||||
let length = strlen(resolvedPath)
|
||||
precondition(length != 0, "Couldn't obtain valid executable path")
|
||||
|
||||
// Search backwards for the last /, and turn it into a null byte.
|
||||
for idx in stride(from: length-1, through: 0, by: -1) {
|
||||
if Unicode.Scalar(UInt8(resolvedPath[idx])) == Unicode.Scalar("/") {
|
||||
resolvedPath[idx] = 0
|
||||
break
|
||||
}
|
||||
|
||||
precondition(idx != 0, "Couldn't obtain valid executable directory")
|
||||
}
|
||||
|
||||
return String(cString: resolvedPath) + "/test.txt"
|
||||
}()
|
||||
#else
|
||||
let fn = "test.txt"
|
||||
#endif
|
||||
|
||||
POSIXTests.setUp {
|
||||
sem_unlink(semaphoreName)
|
||||
@@ -25,13 +52,16 @@ POSIXTests.setUp {
|
||||
}
|
||||
|
||||
// Failed semaphore creation.
|
||||
#if !os(Android) // Android doesn’t implement sem_open and always return ENOSYS
|
||||
POSIXTests.test("sem_open fail") {
|
||||
let sem = sem_open(semaphoreName, 0)
|
||||
expectEqual(SEM_FAILED, sem)
|
||||
expectEqual(ENOENT, errno)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Successful semaphore creation.
|
||||
#if !os(Android) // Android doesn’t implement sem_open and always return ENOSYS
|
||||
POSIXTests.test("sem_open success") {
|
||||
let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1)
|
||||
expectNotEqual(SEM_FAILED, sem)
|
||||
@@ -42,8 +72,10 @@ POSIXTests.test("sem_open success") {
|
||||
let res2 = sem_unlink(semaphoreName)
|
||||
expectEqual(0, res2)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Successful semaphore creation with O_EXCL.
|
||||
#if !os(Android) // Android doesn’t implement sem_open and always return ENOSYS
|
||||
POSIXTests.test("sem_open O_EXCL success") {
|
||||
let sem = sem_open(semaphoreName, O_CREAT | O_EXCL, 0o777, 1)
|
||||
expectNotEqual(SEM_FAILED, sem)
|
||||
@@ -54,8 +86,10 @@ POSIXTests.test("sem_open O_EXCL success") {
|
||||
let res2 = sem_unlink(semaphoreName)
|
||||
expectEqual(0, res2)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Successful creation and re-obtaining of existing semaphore.
|
||||
#if !os(Android) // Android doesn’t implement sem_open and always return ENOSYS
|
||||
POSIXTests.test("sem_open existing") {
|
||||
let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1)
|
||||
expectNotEqual(SEM_FAILED, sem)
|
||||
@@ -71,8 +105,10 @@ POSIXTests.test("sem_open existing") {
|
||||
let res2 = sem_unlink(semaphoreName)
|
||||
expectEqual(0, res2)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fail because the semaphore already exists.
|
||||
#if !os(Android) // Android doesn’t implement sem_open and always return ENOSYS
|
||||
POSIXTests.test("sem_open existing O_EXCL fail") {
|
||||
let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1)
|
||||
expectNotEqual(SEM_FAILED, sem)
|
||||
@@ -87,6 +123,7 @@ POSIXTests.test("sem_open existing O_EXCL fail") {
|
||||
let res2 = sem_unlink(semaphoreName)
|
||||
expectEqual(0, res2)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fail because the file descriptor is invalid.
|
||||
POSIXTests.test("ioctl(CInt, UInt, CInt): fail") {
|
||||
@@ -99,7 +136,7 @@ POSIXTests.test("ioctl(CInt, UInt, CInt): fail") {
|
||||
expectEqual(EBADF, errno)
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
#if os(Linux) || os(Android)
|
||||
// Successful creation of a socket and listing interfaces
|
||||
POSIXTests.test("ioctl(CInt, UInt, UnsafeMutableRawPointer): listing interfaces success") {
|
||||
// Create a socket
|
||||
@@ -204,7 +241,13 @@ POSIXTests.test("fcntl(CInt, CInt, UnsafeMutableRawPointer): locking and unlocki
|
||||
// Lock for reading...
|
||||
var flck = flock()
|
||||
flck.l_type = Int16(F_RDLCK)
|
||||
#if os(Android)
|
||||
// In Android l_len is __kernel_off_t which is not the same size as off_t in
|
||||
// 64 bits.
|
||||
flck.l_len = __kernel_off_t(data.utf8.count)
|
||||
#else
|
||||
flck.l_len = off_t(data.utf8.count)
|
||||
#endif
|
||||
rc = fcntl(fd, F_SETLK, &flck)
|
||||
expectEqual(0, rc)
|
||||
|
||||
@@ -223,4 +266,3 @@ POSIXTests.test("fcntl(CInt, CInt, UnsafeMutableRawPointer): locking and unlocki
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user