Skip to content

Commit 01cc686

Browse files
committed
fix MacOS flaky tests
* do not skip recording, streaming, etc tests when running on MacOS * log when tests are being skipped * set CI env var for MacOS github runner * fix warning we cant assign null: `let secondContext: osn.IVideo = null;` * do not invoke `AddVideoContext` on CI builds in enhanced broadcasting tests * fix orphaned worker thread: The WorkerSignals::worker keeps polling Query. When a test fails before calling destroy(), the server-side recording gets freed when OBS shuts down, but the orphaned worker thread continues. When the next test file creates a fresh OBS connection, Controller::GetInstance().GetConnection() now returns the new session's connection. The orphaned worker sends Query(oldUID) to the new server, which has no knowledge of that uid → "Recording reference is not valid." * extend overall timeout for tests. MacOS tests can apparently go well over 30 mins? turn off fail-fast so the tests can continue running * fix issue where if macos-15-intel fails, arm64 is cancelled before it can finish
1 parent a01380b commit 01cc686

14 files changed

Lines changed: 67 additions & 182 deletions

.github/workflows/main.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ jobs:
9999
needs: build-macos
100100
runs-on: ${{ matrix.image }}
101101
strategy:
102+
fail-fast: false
102103
matrix:
103104
BuildReleases: [Release-x86_64, Release-arm64]
104105
include:
@@ -143,14 +144,15 @@ jobs:
143144
# `id` is essential for enabling steps context.
144145
# https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#steps-context
145146
id: run_tests
146-
timeout-minutes: 30
147+
timeout-minutes: 45
147148
run: 'yarn run test:ci'
148149
env:
149150
SLOBS_BE_STREAMKEY: ${{secrets.testsStreamKey}}
150151
SLOBS_TEST_USER_POOL_TOKEN: ${{secrets.testsUserPoolToken}}
151152
OSN_ACCESS_KEY_ID: ${{secrets.AWS_RELEASE_ACCESS_KEY_ID}}
152153
OSN_SECRET_ACCESS_KEY: ${{secrets.AWS_RELEASE_SECRET_ACCESS_KEY}}
153154
RELEASE_NAME: ${{matrix.ReleaseName}}
155+
CI: true
154156
# Run even after test failures so the PR still gets the flaky summary.
155157
- name: Publish flaky test check
156158
if: ${{ always() }}

obs-studio-client/source/worker-signals.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ class WorkerSignals {
8888
auto conn = Controller::GetInstance().GetConnection();
8989
if (conn) {
9090
std::vector<ipc::value> response = conn->call_synchronous_helper(name, "Query", {ipc::value(refID)});
91+
if (!response.empty()) {
92+
ErrorCode firstError = (ErrorCode)response[0].value_union.ui64;
93+
if (firstError == ErrorCode::InvalidReference) {
94+
// This typically happens if the worker thread is orphaned.
95+
std::string errorMessage = response.size() > 1 ? response[1].value_str : "";
96+
std::cout << "Worker thread exiting due to Invalid reference error encountered: " << errorMessage << std::endl;
97+
isWorkerRunning = false;
98+
break;
99+
}
100+
}
91101
if ((response.size() == 5) && signalsList.size() < maximum_signals_in_queue) {
92102
ErrorCode error = (ErrorCode)response[0].value_union.ui64;
93103
if (error == ErrorCode::Ok) {
@@ -140,4 +150,4 @@ class WorkerSignals {
140150
workerThread->join();
141151
}
142152
}
143-
};
153+
};

tests/osn-tests/src/test_nodeobs_autoconfig.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ describe(testName, function() {
5050
});
5151

5252
it('Run autoconfig', async function() {
53-
if (obs.isDarwin()) {
54-
this.skip();
55-
}
5653
const start = performance.now();
5754
let progressInfo: IConfigProgress;
5855
let settingValue: any;

tests/osn-tests/src/test_nodeobs_service.ts

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ describe(testName, function() {
100100
});
101101

102102
it('Simple mode - Start recording and stop', async function() {
103-
if (obs.isDarwin()) {
104-
this.skip();
105-
}
106103
// Preparing environment
107104
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
108105
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');
@@ -150,9 +147,6 @@ describe(testName, function() {
150147
});
151148

152149
it('Simple mode - Start replay buffer, save replay and stop', async function() {
153-
if (obs.isDarwin()) {
154-
this.skip();
155-
}
156150
// Preparing environment
157151
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
158152
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');
@@ -200,9 +194,6 @@ describe(testName, function() {
200194
});
201195

202196
it('Simple mode - Record while streaming', async function() {
203-
if (obs.isDarwin()) {
204-
this.skip();
205-
}
206197
// Preparing environment
207198
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
208199
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');
@@ -290,9 +281,6 @@ describe(testName, function() {
290281
});
291282

292283
it('Simple mode - Record replay while streaming and save', async function() {
293-
if (obs.isDarwin()) {
294-
this.skip();
295-
}
296284
// Preparing environment
297285
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
298286
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');
@@ -380,9 +368,6 @@ describe(testName, function() {
380368
});
381369

382370
it('Simple mode - Record and use replay buffer while streaming', async function() {
383-
if (obs.isDarwin()) {
384-
this.skip();
385-
}
386371
// Preparing environment
387372
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
388373
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');
@@ -510,9 +495,6 @@ describe(testName, function() {
510495
});
511496

512497
it('Advanced mode - Start and stop streaming', async function() {
513-
if (obs.isDarwin()) {
514-
this.skip();
515-
}
516498
// Preparing environment
517499
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Advanced');
518500
obs.setSetting(EOBSSettingsCategories.Output, 'Encoder', 'obs_x264');
@@ -564,9 +546,6 @@ describe(testName, function() {
564546
});
565547

566548
it('Advanced mode - Start recording and stop', async function() {
567-
if (obs.isDarwin()) {
568-
this.skip();
569-
}
570549
// Preparing environment
571550
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Advanced');
572551
obs.setSetting(EOBSSettingsCategories.Output, 'Encoder', 'obs_x264');
@@ -614,9 +593,6 @@ describe(testName, function() {
614593
});
615594

616595
it('Advanced mode - Start replay buffer, save replay and stop', async function() {
617-
if (obs.isDarwin()) {
618-
this.skip();
619-
}
620596
// Preparing environment
621597
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Advanced');
622598
obs.setSetting(EOBSSettingsCategories.Output, 'Encoder', 'obs_x264');
@@ -665,9 +641,6 @@ describe(testName, function() {
665641
});
666642

667643
it('Advanced mode - Record while streaming', async function() {
668-
if (obs.isDarwin()) {
669-
this.skip();
670-
}
671644
// Preparing environment
672645
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Advanced');
673646
obs.setSetting(EOBSSettingsCategories.Output, 'Encoder', 'obs_x264');
@@ -756,9 +729,6 @@ describe(testName, function() {
756729
});
757730

758731
it('Advanced mode - Record replay while streaming and save', async function() {
759-
if (obs.isDarwin()) {
760-
this.skip();
761-
}
762732
// Preparing environment
763733
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Advanced');
764734
obs.setSetting(EOBSSettingsCategories.Output, 'Encoder', 'obs_x264');
@@ -847,9 +817,6 @@ describe(testName, function() {
847817
});
848818

849819
it('Advanced mode - Record and use replay buffer while streaming', async function() {
850-
if (obs.isDarwin()) {
851-
this.skip();
852-
}
853820
// Preparing environment
854821
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Advanced');
855822
obs.setSetting(EOBSSettingsCategories.Output, 'Encoder', 'obs_x264');
@@ -978,10 +945,6 @@ describe(testName, function() {
978945
});
979946

980947
it('Fail test - Stream with invalid stream key', async function() {
981-
if (obs.isDarwin()) {
982-
this.skip();
983-
}
984-
985948
let signalInfo: IOBSOutputSignalInfo;
986949

987950
try {

tests/osn-tests/src/test_osn_advanced_recording.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ describe(testName, () => {
115115
});
116116

117117
it('Start advanced recording - Stream', async function () {
118-
if (obs.isDarwin()) {
119-
this.skip();
120-
}
121118
const recording = osn.AdvancedRecordingFactory.create();
122119
recording.path = path.join(path.normalize(__dirname), '..', 'osnData');
123120
recording.format = ERecordingFormat.MP4;
@@ -250,9 +247,6 @@ describe(testName, () => {
250247
});
251248

252249
it('Start advanced recording - Custom encoders', async function () {
253-
if (obs.isDarwin()) {
254-
this.skip();
255-
}
256250
const recording = osn.AdvancedRecordingFactory.create();
257251
recording.path = path.join(path.normalize(__dirname), '..', 'osnData');
258252
recording.format = ERecordingFormat.MP4;

tests/osn-tests/src/test_osn_advanced_replayBuffer.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,6 @@ describe(testName, () => {
109109
});
110110

111111
it('Start advanced replay buffer - Use Recording', async function() {
112-
if (obs.isDarwin()) {
113-
this.skip();
114-
}
115112
const replayBuffer = osn.AdvancedReplayBufferFactory.create();
116113
replayBuffer.path = path.join(path.normalize(__dirname), '..', 'osnData');
117114
replayBuffer.format = osn.ERecordingFormat.MP4;
@@ -244,9 +241,6 @@ describe(testName, () => {
244241
});
245242

246243
it('Start advanced replay buffer - Use Stream through Recording', async function() {
247-
if (obs.isDarwin()) {
248-
this.skip();
249-
}
250244
const replayBuffer = osn.AdvancedReplayBufferFactory.create();
251245
replayBuffer.path = path.join(path.normalize(__dirname), '..', 'osnData');
252246
replayBuffer.format = osn.ERecordingFormat.MP4;

tests/osn-tests/src/test_osn_advanced_streaming.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ describe(testName, () => {
9898
});
9999

100100
it('Stream with missing video encoder', async function() {
101-
if (obs.isDarwin()) {
102-
this.skip();
103-
}
104101
const stream = osn.AdvancedStreamingFactory.create();
105102
stream.service = osn.ServiceFactory.legacySettings;
106103
stream.video = obs.defaultVideoContext;
@@ -117,9 +114,6 @@ describe(testName, () => {
117114
});
118115

119116
it('Stream with missing service', async function() {
120-
if (obs.isDarwin()) {
121-
this.skip();
122-
}
123117
const stream = osn.AdvancedStreamingFactory.create();
124118
stream.videoEncoder = osn.VideoEncoderFactory.create('obs_x264', 'video-encoder');
125119
stream.video = obs.defaultVideoContext;
@@ -136,9 +130,6 @@ describe(testName, () => {
136130
});
137131

138132
it('Stream with missing canvas', async function() {
139-
if (obs.isDarwin()) {
140-
this.skip();
141-
}
142133
const stream = osn.AdvancedStreamingFactory.create();
143134
stream.service = osn.ServiceFactory.legacySettings;
144135
stream.videoEncoder = osn.VideoEncoderFactory.create('obs_x264', 'video-encoder');
@@ -155,9 +146,6 @@ describe(testName, () => {
155146
});
156147

157148
it('Start streaming', async function() {
158-
if (obs.isDarwin()) {
159-
this.skip();
160-
}
161149
const stream = osn.AdvancedStreamingFactory.create();
162150
stream.videoEncoder =
163151
osn.VideoEncoderFactory.create('obs_x264', 'video-encoder-adv-streaming-1');
@@ -245,9 +233,6 @@ describe(testName, () => {
245233
});
246234

247235
it('Stream with invalid stream key', async function() {
248-
if (obs.isDarwin()) {
249-
this.skip();
250-
}
251236
const stream = osn.AdvancedStreamingFactory.create();
252237
stream.videoEncoder =
253238
osn.VideoEncoderFactory.create('obs_x264', 'video-encoder-adv-streaming-2');

tests/osn-tests/src/test_osn_dual_output.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,6 @@ describe(testName, () => {
114114
}
115115

116116
it('Start Dual Output with advanced recording', async function() {
117-
if (obs.isDarwin()) {
118-
this.skip();
119-
}
120117
const recording = osn.AdvancedRecordingFactory.create();
121118
recording.path = path.join(path.normalize(__dirname), '..', 'osnData');
122119
recording.format = ERecordingFormat.MP4;
@@ -169,9 +166,6 @@ describe(testName, () => {
169166
});
170167

171168
it('Start Dual Output with recording and scene items', async function() {
172-
if (obs.isDarwin()) {
173-
this.skip();
174-
}
175169
const returnSource = osn.Global.getOutputSource(0);
176170

177171
const recording = osn.AdvancedRecordingFactory.create();
@@ -259,9 +253,6 @@ describe(testName, () => {
259253
});
260254

261255
it('Start Dual Output with advanced recording and audio scene items', async function() {
262-
if (obs.isDarwin()) {
263-
this.skip();
264-
}
265256
const returnSource = osn.Global.getOutputSource(0);
266257

267258
const recording = osn.AdvancedRecordingFactory.create();
@@ -363,9 +354,6 @@ describe(testName, () => {
363354

364355

365356
it('Start Dual Output with simple recording and audio scene items', async function() {
366-
if (obs.isDarwin()) {
367-
this.skip();
368-
}
369357
const returnSource = osn.Global.getOutputSource(0);
370358

371359
const recording = osn.SimpleRecordingFactory.create();
@@ -474,9 +462,6 @@ describe(testName, () => {
474462
});
475463

476464
it('Start Dual Output with legacy streaming to two services', async function() {
477-
if (obs.isDarwin()) {
478-
this.skip();
479-
}
480465
// Preparing environment
481466
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
482467
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');
@@ -519,9 +504,6 @@ describe(testName, () => {
519504
});
520505

521506
it('Start Dual Output with legacy streaming to two services and audio sources', async function() {
522-
if (obs.isDarwin()) {
523-
this.skip();
524-
}
525507
// Preparing environment
526508
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
527509
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');

0 commit comments

Comments
 (0)