How can these sync methods be effectively unit tested? - multithreading

Based on answers to this question, I feel happy with the simplicity and ease of use of the following two methods for synchronization:
func synchronized(lock: AnyObject, closure: () -> Void) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
func synchronized<T>(lock: AnyObject, closure: () -> T) -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return closure()
}
But to be sure they're actually doing what I want, I want to wrap these in piles of unit tests. How can I write unit tests that will effectively test these methods (and show they are actually synchronizing the code)?
Ideally, I'd also like these unit tests to be as simple and as clear as possible. Presumably, this test should be code that, if run outside the synchronization block, would give one set of results, but give an entirely separate set of results inside these synchronized blocks.

Here is a runnable XCTest that verifies the synchronization. If you synchronize delayedAddToArray, it will work, otherwise it will fail.
class DelayedArray:NSObject {
func synchronized(lock: AnyObject, closure: () -> Void) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
private var array = [String]()
func delayedAddToArray(expectation:XCTestExpectation) {
synchronized(self) {
let arrayCount = self.array.count
self.array.append("hi")
sleep(5)
XCTAssert(self.array.count == arrayCount + 1)
expectation.fulfill()
}
}
}
func testExample() {
let expectation = self.expectationWithDescription("desc")
let expectation2 = self.expectationWithDescription("desc2")
let delayedArray:DelayedArray = DelayedArray()
// This is an example of a functional test case.
let thread = NSThread(target: delayedArray, selector: "delayedAddToArray:", object: expectation)
let secondThread = NSThread(target: delayedArray, selector: "delayedAddToArray:", object: expectation2)
thread.start()
sleep(1)
secondThread.start()
self.waitForExpectationsWithTimeout(15, handler: nil)
}

Related

NSPersistentContainer, performBackgroundTask, calling perform does nothing

I'm just started working on a new project and thought I'd try out Core Data's NSPersistentContainer instead of writing my own stack.
I just stumbled upon this issue where calling the perform method of the managedObjectContext actually does nothing if the task was started as part of NSPersistentContainer's performBackgroundTask.
Here's a snippet of what I'm currently doing to demonstrate the issue. Note that I have a DispatchGroup to ensure that the tasks are performed in sequence.
// DataImporter.swift
class func importData(url: URL, context: NSManagedObjectContext, completion: () -> ()) {
context.perform {
// Code inside here never gets call
DispatchQueue.main.async(execute: {
completion()
})
}
}
// ViewController.swift
func multipleImportTasks() {
persistentContainer.performBackgroundTask { managedObjectContext in
let group = DispatchGroup()
group.enter()
let fileUrl1 = Data(someData)
DataImporter.importData(fileUrl1, context: managedObjectContext, completion: {
group.leave()
})
group.wait()
group.enter()
let fileUrl2 = Data(someData)
DataImporter.importData(fileUrl2, context: managedObjectContext, completion: {
group.leave()
})
group.notify(queue: DispatchQueue.main, execute: {
print("all done")
})
}
}
Its because of group.wait() call. group.wait() will block current thread and context.perform will also try run on same thread.

Compare Strings in Swift unit test

How do you test whether two Strings are equal in a Swift unit test? I've tried the == operator but it doesn't recognize it:
import XCTest
#testable import MyProject
class MyProject: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
XCTAssertNil(nil, "This test works")
}
func toJSONTest() {
let currentLocation = deviceLocation(timestamp: "2015-11-02 16:32:15 +0000",latitude: "40.2736577695212",longitude: "-111.715408331498")
var MyProjectStatuses = [MyProjectStatus(id: "", currentLocation: currentLocation)]
let json = ""
XCTAssertTrue(json == "")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
// Put the code you want to measure the time of here.
}
}
}
And the actual method being tested from MyProject.swift:
func toJSON ()->String{
var json = ""
json = "{\"myproject_status\":"
json = json + "{\"id\":\"" + self.Id + "\""
return json
}
This part:
XCTAssertTrue(json == "")
Throws:
Operator is not a known binary operator
The problem is that toJSONTest is not a test. Change the name to testToJSON.
This works fine on my machine:
func testToJSON() {
let json = ""
XCTAssertTrue(json == "")
}
The test runs, and passes. However, I would probably write it like this:
func testToJSON() {
let json = ""
XCTAssertEqual(json, "", "They are not equal")
}
Although this question is explicitly about how to compare two Strings in a Swift unit test, what's implicit in the question is how to compare two JSON Strings. I just wanted to point out that the right thing to do when comparing two JSON strings is to parse the JSON Strings to a Foundation object with the JSONSerialization class and then to compare the resulting Foundation objects. This approach takes care of the problem of the two JSON Strings having slightly different formatting or fields in a different order. So, for example, it's important that "{\"a\":1,\"b\":2}" and "{\"b\":2,\"a\":1}" are deemed to be equal because they are logically equal.
Here's a Swift function I put together which helps with this comparison:
class JSONAssert {
class func assertEquals(expected: String, actual: String) {
let expectedData = Data(expected.utf8)
let actualData = Data(actual.utf8)
let expectedObject: Any
let actualObject: Any
do {
expectedObject = try JSONSerialization.jsonObject(with: expectedData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `expected` (i.e. \(expected)): \(error)")
return
}
do {
actualObject = try JSONSerialization.jsonObject(with: actualData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `actual` (i.e. \(actual)): \(error)")
return
}
guard let expectedDictionary = expectedObject as? NSDictionary else {
XCTFail("Failed casting expected object (i.e. \(expectedObject)) to an NSDictionary")
return
}
guard let actualDictionary = actualObject as? NSDictionary else {
XCTFail("Failed casting actual object (i.e. \(actualObject)) to an NSDictionary")
return
}
XCTAssertEqual(expectedDictionary, actualDictionary)
}
}

Thread safe access to a variable in a class

in an application where there could be multiple threads running, and not sure about the possibilities if these methods will be accessed under a multhreaded environment or not but to be safe, I've done a test class to demonstrate a situation.
One method has was programmed to be thread safe (please also comment if it's done right) but the rest were not.
In a situation like this, where there is only one single line of code inside remove and add, is it necessary to make them thread safe or is it going to be exaggeration.
import Foundation
class Some {}
class Test {
var dict = [String: Some]()
func has(key: String) -> Bool {
var has = false
dispatch_sync(dispatch_queue_create("has", nil), { [unowned self] in
has = self.dict[key] != nil
})
return has
}
func remove(key: String) -> Some {
var ob = dict[key]
dict[key] = nil
return ob
}
func add(key: String, ob: Some) {
dict[key] = ob
}
}
Edit after comments
class Some {}
class Test {
var dict = [String: Some]()
private let queue: dispatch_queue_t = dispatch_queue_create("has", DISPATCH_QUEUE_CONCURRENT)
func has(key: String) -> Bool {
var has = false
dispatch_sync(queue) {
has = self.dict[key] != nil
}
return has
}
func remove(key: String) -> Some? { //returns
var removed: Some?
dispatch_barrier_sync(queue) {
removed = self.dict.removeValueForKey(key)
}
return removed
}
func add(key: String, ob: Some) { //not async
dispatch_barrier_sync(queue) {
self.dict[key] = ob
}
}
}
The way you are checking whether a key exists is incorrect. You are creating a new queue every time, which means the operations are not happening synchronously.
The way I would do it is like so:
class Some {}
class Test {
var dict = [String: Some]()
private let queue: dispatch_queue_t = dispatch_queue_create("has", DISPATCH_QUEUE_CONCURRENT)
func has(key: String) -> Bool {
var has = false
dispatch_sync(queue) { [weak self] in
guard let strongSelf = self else { return }
has = strongSelf.dict[key] != nil
}
return has
}
func remove(key: String) {
dispatch_barrier_async(queue) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.dict[key] = nil
}
}
func add(key: String, ob: Some) {
dispatch_barrier_async(queue) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.dict[key] = ob
}
}
}
Firstly, I am creating a serial queue that is going to be used to access the dictionary as a property of the object, rather than creating a new one every time. The queue is private as it is only used internally.
When I want to get a value out of the class, I am just dispatching a block synchronously to the queue and waits for the block to finish before returning whether or not the queue exists. Since this is not mutating the dictionary, it is safe for multiple blocks of this sort to run on the concurrent queue.
When I want to add or remove values from the dictionary, I am adding the block to the queue but with a barrier. What this does is that it stops all other blocks on the queue while it is running. When it is finished, all the other blocks can run concurrently. I am using an async dispatch, because I don't need to wait for a return value.
Imagine you have multiple threads trying to see whether or not key values exist or adding or removing values. If you have lots of reads, then they happen concurrently, but when one of the blocks is run that will change the dictionary, all other blocks wait until this change is completed and then start running again.
In this way, you have the speed and convenience of running concurrently when getting values, and the thread safety of blocking while the dictionary is being mutated.
Edited to add
self is marked as weak in the block so that it doesn't create a reference cycle. As #MartinR mentioned in the comments; it is possible that the object is deallocated while blocks are still in the queue, If this happens then self is undefined, and you'll probably get a runtime error trying to access the dictionary, as it may also be deallocated.
By setting declaring self within the block to be weak, if the object exists, then self will not be nil, and can be conditionally unwrapped into strongSelf which points to self and also creates a strong reference, so that self will not be deallocated while the instructions in the block are carried out. When these instructions complete, strongSelf will go out of scope and release the strong reference to self.
This is sometimes known as the "strong self, weak self dance".
Edited Again : Swift 3 version
class Some {}
class Test {
var dict = [String: Some]()
private let queue = DispatchQueue(label: "has", qos: .default, attributes: .concurrent)
func has(key: String) -> Bool {
var has = false
queue.sync { [weak self] in
guard let strongSelf = self else { return }
has = strongSelf.dict[key] != nil
}
return has
}
func remove(key: String) {
queue.async(flags: .barrier) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.dict[key] = nil
}
}
func add(key: String, ob: Some) {
queue.async(flags: .barrier) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.dict[key] = ob
}
}
}
Here is another swift 3 solution which provides thread-safe access to AnyObject.
It allocates recursive pthread_mutex associated with 'object' if needed.
class LatencyManager
{
private var latencies = [String : TimeInterval]()
func set(hostName: String, latency: TimeInterval) {
synchronizedBlock(lockedObject: latencies as AnyObject) { [weak self] in
self?.latencies[hostName] = latency
}
}
/// Provides thread-safe access to given object
private func synchronizedBlock(lockedObject: AnyObject, block: () -> Void) {
objc_sync_enter(lockedObject)
block()
objc_sync_exit(lockedObject)
}
}
Then you can call for example set(hostName: "stackoverflow.com", latency: 1)
UPDATE
You can simply define a method in a swift file (not in a class):
/// Provides thread-safe access to given object
public func synchronizedAccess(to object: AnyObject, _ block: () -> Void)
{
objc_sync_enter(object)
block()
objc_sync_exit(object)
}
And use it like this:
synchronizedAccess(to: myObject) {
myObject.foo()
}

How can a Groovy closure curry itself for repetition?

I'm implementing Groovy step definitions for Cucumber-JVM and I want a step to be able store itself so that the next step can repeat it n times.
Given(~'the (\\S+) is in the blender') { String thing ->
// do stuff...
context.repeatable = self.curry(thing)
}
What should "self" be in the above code?
I can't use "this" as that refers to the enclosing object (whatever that is in this case, maybe the script).
Since curry is a method of the Closure class, directly invoking curry applies to the closure, both if it is named:
def context
test = { String thing ->
context = curry(thing)
thing.toUpperCase()
}
test('hello')
println context.call()
test('world')
println context.call()
=>
HELLO
WORLD
or anonymous:
def context
['test'].each { String thing ->
context = curry(thing)
thing.toUpperCase()
}
println context.call()
=>
TEST
You can try using unreferenced curry method passing the received parameters:
clos = { String text ->
if (text) {
println "text=$text"
a = curry null
a()
} else {
println "done"
}
}
clos "closure text"
Will print:
text=closure text
done
Update
You can also use clone():
closure = {
def clone = clone()
}

Thread-safe raising of F# events

I'm trying to do an F# async computation that calls an C# callback when ready. The code is the following:
type Worker() =
let locker = obj()
let computedValue = ref None
let started = ref false
let completed = Event<_>()
let doNothing() = ()
member x.Compute(callBack:Action<_>) =
let workAlreadyStarted, action =
lock locker (fun () ->
match !computedValue with
| Some value ->
true, (fun () -> callBack.Invoke value)
| None ->
completed.Publish.Add callBack.Invoke
if !started then
true, doNothing
else
started := true
false, doNothing)
action()
if not workAlreadyStartedthen
async {
// heavy computation to calc result
let result = "result"
lock locker (fun () ->
computedValue := Some result
completed.Trigger result)
} |> Async.Start
But there's a problem, I want to trigger the completed event outside the lock, but I want to make sure that the triggering is thread safe (Actually, in this small example I could just trigger the event outside the lock as I know no one else will subscribe to it, but that's not always the case).
In C# events this is very easy to accomplish:
object locker = new object();
event Action<string> MyEvent;
void Raise()
{
Action<string> myEventCache;
lock (locker)
{
myEventCache = MyEvent;
}
if (myEventCache != null)
{
myEventCache("result");
}
}
How can I do the equivalent with F# events, freezing the list of subscribers inside the lock but invoking it outside the lock?
This isn't as straightforward in F# because Event<_> doesn't expose its subscriber list, which is mutated by Add/Remove.
You can avoid this mutation by creating a new event for each handler.
let mutable completed = Event<_>()
//...
let ev = Event<_>()
let iev = ev.Publish
iev.Add(completed.Trigger)
iev.Add(callBack.Invoke)
completed <- ev
//...
let ev = lock locker <| fun () ->
computedValue := Some result
completed
ev.Trigger(result)

Resources