Skip to content

Commit

Permalink
Concurrent mic publish tests (#349)
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroshihorie authored Mar 7, 2024
1 parent 255af25 commit 6da53bb
Show file tree
Hide file tree
Showing 9 changed files with 381 additions and 11 deletions.
17 changes: 14 additions & 3 deletions .github/workflows/testing-matrix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: Testing Matrix
on:
workflow_dispatch:
push:
branches: [ main ]
branches: [main]
pull_request:
branches: [ main ]
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand All @@ -17,13 +17,24 @@ jobs:
fail-fast: false
matrix:
xcode-version: [14.2, 15.2]
destination: ['platform=iOS Simulator,OS=17.2,name=iPhone 14 Pro', 'platform=macOS', 'platform=macOS,variant=Mac Catalyst']
destination:
[
"platform=iOS Simulator,OS=17.2,name=iPhone 14 Pro",
"platform=macOS",
"platform=macOS,variant=Mac Catalyst",
]

runs-on: macos-13

steps:
- uses: actions/checkout@v4

- name: Install LiveKit Server
run: brew install livekit

- name: Run LiveKit Server
run: livekit-server --dev &

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode-version }}
Expand Down
49 changes: 49 additions & 0 deletions LiveKit.xctestplan
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"configurations" : [
{
"id" : "C13DBD7E-A26D-4166-987B-8BB0E3A8A56F",
"name" : "Test Scheme Action",
"options" : {

}
}
],
"defaultOptions" : {
"environmentVariableEntries" : [
{
"key" : "LIVEKIT_TESTING_URL",
"value" : "$(LIVEKIT_TESTING_URL)"
},
{
"key" : "LIVEKIT_TESTING_API_KEY",
"value" : "$(LIVEKIT_TESTING_API_KEY)"
},
{
"key" : "LIVEKIT_TESTING_API_SECRET",
"value" : "$(LIVEKIT_TESTING_API_SECRET)"
}
],
"targetForVariableExpansion" : {
"containerPath" : "container:",
"identifier" : "LiveKit",
"name" : "LiveKit"
}
},
"testTargets" : [
{
"target" : {
"containerPath" : "container:",
"identifier" : "LiveKitTests",
"name" : "LiveKitTests"
}
},
{
"target" : {
"containerPath" : "container:",
"identifier" : "LiveKitTestsObjC",
"name" : "LiveKitTestsObjC"
}
}
],
"version" : 1
}
17 changes: 13 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ let package = Package(
// LK-Prefixed Dynamic WebRTC XCFramework
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "114.5735.13"),
.package(url: "https://github.com/apple/swift-protobuf.git", .upToNextMajor(from: "1.25.2")),
.package(url: "https://github.com/apple/swift-log.git", .upToNextMajor(from: "1.5.3")),
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.3.0"),
.package(url: "https://github.com/apple/swift-log.git", .upToNextMajor(from: "1.5.4")),
// Only used for DocC generation
.package(url: "https://github.com/apple/swift-docc-plugin", .upToNextMajor(from: "1.3.0")),
// Only used for Testing
.package(url: "https://github.com/vapor/jwt-kit.git", .upToNextMajor(from: "4.13.2")),
],
targets: [
.systemLibrary(name: "CHeaders"),
Expand All @@ -37,11 +40,17 @@ let package = Package(
),
.testTarget(
name: "LiveKitTests",
dependencies: ["LiveKit"]
dependencies: [
"LiveKit",
.product(name: "JWTKit", package: "jwt-kit"),
]
),
.testTarget(
name: "LiveKitTestsObjC",
dependencies: ["LiveKit"]
dependencies: [
"LiveKit",
.product(name: "JWTKit", package: "jwt-kit"),
]
),
]
)
1 change: 0 additions & 1 deletion Sources/LiveKit/Core/Transport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

import Foundation
import SwiftProtobuf

@_implementationOnly import LiveKitWebRTC

Expand Down
6 changes: 5 additions & 1 deletion Tests/LiveKitTests/Basic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@
@testable import LiveKit
import XCTest

class Basic: XCTestCase {}
class Basic: XCTestCase {
func testReadVersion() {
print("LiveKitSDK.version: \(LiveKitSDK.version)")
}
}
108 changes: 108 additions & 0 deletions Tests/LiveKitTests/PublishTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright 2024 LiveKit
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Combine
import CoreMedia
@testable import LiveKit
import XCTest

class PublishTests: XCTestCase {
let room1 = Room()
let room2 = Room()

var watchRoom1: AnyCancellable?
var watchRoom2: AnyCancellable?

override func setUp() async throws {
let url = testUrl()

let token1 = try testToken(for: "room01", identity: "identity01")
try await room1.connect(url: url, token: token1)

let token2 = try testToken(for: "room01", identity: "identity02")
try await room2.connect(url: url, token: token2)

let room1ParticipantCountIs2 = expectation(description: "Room1 Participant count is 2")
room1ParticipantCountIs2.assertForOverFulfill = false

let room2ParticipantCountIs2 = expectation(description: "Room2 Participant count is 2")
room2ParticipantCountIs2.assertForOverFulfill = false

watchRoom1 = room1.objectWillChange.sink { _ in
if self.room1.allParticipants.count == 2 {
room1ParticipantCountIs2.fulfill()
}
}

watchRoom2 = room2.objectWillChange.sink { _ in
if self.room2.allParticipants.count == 2 {
room2ParticipantCountIs2.fulfill()
}
}

// Wait until both room's participant count is 2
await fulfillment(of: [room1ParticipantCountIs2, room2ParticipantCountIs2], timeout: 30)
}

override func tearDown() async throws {
await room1.disconnect()
await room2.disconnect()
watchRoom1?.cancel()
watchRoom2?.cancel()
}

func testResolveSid() async throws {
XCTAssert(room1.connectionState == .connected)

let sid = try await room1.sid()
print("Room.sid(): \(String(describing: sid))")
XCTAssert(sid.stringValue.starts(with: "RM_"))
}

func testConcurrentMicPublish() async throws {
// Lock
struct State {
var firstMicPublication: LocalTrackPublication?
}

let _state = StateSync(State())

// Run Tasks concurrently
try await withThrowingTaskGroup(of: Void.self) { group in
for _ in 1 ... 100 {
group.addTask {
let result = try await self.room1.localParticipant.setMicrophone(enabled: true)

if let result {
_state.mutate {
if let firstMicPublication = $0.firstMicPublication {
XCTAssert(result == firstMicPublication, "Duplicate mic track has been published")
} else {
$0.firstMicPublication = result
print("Did publish first mic track: \(String(describing: result))")
}
}
}
}
}

try await group.waitForAll()
}

// Reset
await room1.localParticipant.unpublishAll()
}
}
Loading

0 comments on commit 6da53bb

Please sign in to comment.