   }
 
   // start the server
-  DispatchQueue.global().async {
-    do {
-      try runServer(server: server)
-    } catch (let error) {
-      XCTFail("server error \(error)")
-    }
-    serverRunningSemaphore.signal() // when the server exits, the test is finished
+  do {
+    serverRunningSemaphore = try runServer(server: server)
+  } catch (let error) {
+    XCTFail("server error \(error)")
   }
 
   // run the client

  verify_metadata(initialMetadata, expected: initialClientMetadata)

  let initialMetadataToSend = Metadata(initialServerMetadata)
  try requestHandler.receiveMessage(initialMetadata: initialMetadataToSend) { messageData in
    let messageString = String(data: messageData!, encoding: .utf8)
    XCTAssertEqual(messageString, clientPing)
  }

  // Receive remaining pings
  for _ in 0..<steps-1 {
    let receiveSem = DispatchSemaphore(value: 0)
    try requestHandler.receiveMessage(completion: { callStatus in
      let messageString = String(data: callStatus.resultData!, encoding: .utf8)

    }
    call.messageQueueEmpty.wait()
  }

  let closeSem = DispatchSemaphore(value: 0)
  try call.close {
    closeSem.signal()
  }
  _ = closeSem.wait()

  // Receive pongs
  for _ in 0..<steps {
