Skip to content

Commit 722a2a2

Browse files
authored
fix Mac tests / update build agent to pass along compiled artifacts (#1595)
* fix Mac tests / update build agent * (test_osn_input) add missing hotkeys for MAC_SCREEN_CAPTURE * (nodeobs_settings.cpp) fix "&& within ||" Xcode warning (test_nodeobs_settings) do not set ApplyServiceSettings to true on mac * If this property is enabled on Mac, then the encoder settings will be overwritten and cause the test to fail- because you're not allowed to change certain fields. rename macos_avcapture to fix test * avcapture plugins were renamed so they can be looked up directly in JS code need to update the tests- streamlabs/obs-studio@b53043d (Video.cpp - CreateVideo) add bounds check on input from JS (test_osn_input) ignore ndi_source (exists on client but not on agent) (deleteConfigFiles) check if folder exists first before trying to remove files * fix issue where it would stop deleting config files on the mac-Crashpad folder. now all config files are deleted properly and the ini files will be properly reset before next test (main.yml) update CI steps to pass along build artifacts (controller.cpp) print out error if unable to spawn obs64 (helpful on CI build agent)
1 parent 663009e commit 722a2a2

8 files changed

Lines changed: 82 additions & 67 deletions

File tree

.github/workflows/main.yml

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ jobs:
8282
run: node ci/bump-version.js "${{ steps.get_version.outputs.VERSION }}" "${{env.PACKAGE_PATH}}"
8383
env:
8484
PACKAGE_PATH: "${{env.SLFullDistributePath}}/${{env.InstallPath}}"
85+
- name: Upload compiled artifacts
86+
uses: actions/upload-artifact@v4
87+
with:
88+
name: build-artifacts-mac-${{matrix.Architecture}}
89+
path: |
90+
${{env.SLBUILDDIRECTORY}}/
91+
tests/osn-tests/osn/index.ts
8592
8693
run-tests-macos:
8794
name: 'Run macOS Tests'
@@ -119,25 +126,14 @@ jobs:
119126
- name: Install dependencies
120127
shell: bash
121128
run: './ci/install-dependencies-osx.sh'
122-
- name: 'Configure obs-studio-node'
123-
shell: bash
124-
run: './ci/configure-osn-osx.sh'
125-
env:
126-
BUILD_CONFIG: ${{matrix.BuildConfig}}
127-
RELEASE_NAME: ${{matrix.ReleaseName}}
128-
ARCHITECTURE: ${{matrix.Architecture}}
129-
tagartifact: ${{ steps.get_version.outputs.VERSION }}
130-
- name: 'Build obs-studio-node'
131-
run: ./ci/build-osn-osx.sh
129+
- name: Download build artifacts
130+
uses: actions/download-artifact@v4
131+
with:
132+
name: build-artifacts-mac-${{matrix.Architecture}}
133+
path: .
134+
- name: Set obs64 permissions
135+
run: 'chmod +x streamlabs-build.app/distribute/obs-studio-node/bin/obs64'
132136
shell: bash
133-
env:
134-
BUILD_CONFIG: ${{matrix.BuildConfig}}
135-
SENTRY_AUTH_TOKEN: ${{secrets.SENTRY_AUTH_TOKEN}}
136-
- name: Put version into package.json
137-
if: startsWith(github.ref, 'refs/tags/')
138-
run: node ci/bump-version.js "${{ steps.get_version.outputs.VERSION }}" "${{env.PACKAGE_PATH}}"
139-
env:
140-
PACKAGE_PATH: "${{env.SLFullDistributePath}}/${{env.InstallPath}}"
141137
- name: 'Run tests'
142138
timeout-minutes: 30
143139
continue-on-error: true
@@ -171,10 +167,11 @@ jobs:
171167
env:
172168
OS_TAG: "osx"
173169
steps:
174-
- name: 'Checkout'
175-
uses: actions/checkout@v3
170+
- name: Download build artifacts
171+
uses: actions/download-artifact@v4
176172
with:
177-
submodules: 'recursive'
173+
name: build-artifacts-mac-${{matrix.Architecture}}
174+
path: .
178175
- name: Get the version
179176
id: get_version
180177
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
@@ -223,6 +220,11 @@ jobs:
223220
uses: actions/checkout@v3
224221
with:
225222
submodules: 'recursive'
223+
- name: Download build artifacts
224+
uses: actions/download-artifact@v4
225+
with:
226+
name: build-artifacts-mac-${{matrix.Architecture}}
227+
path: .
226228
- name: Get the version
227229
id: get_version
228230
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
@@ -288,6 +290,13 @@ jobs:
288290
- name: 'Prepare tag artifact'
289291
if: startsWith(github.ref, 'refs/tags/')
290292
run: ./ci/prepare-artifact.cmd
293+
- name: Upload compiled artifacts
294+
uses: actions/upload-artifact@v4
295+
with:
296+
name: build-artifacts-windows
297+
path: |
298+
${{env.SLBUILDDIRECTORY}}/
299+
tests/osn-tests/osn/index.ts
291300
292301
run-tests-win64:
293302
name: 'Run Windows Tests'
@@ -300,6 +309,11 @@ jobs:
300309
uses: actions/checkout@v3
301310
with:
302311
submodules: 'recursive'
312+
- name: Download build artifacts
313+
uses: actions/download-artifact@v4
314+
with:
315+
name: build-artifacts-windows
316+
path: .
303317
- name: Get the version
304318
id: get_version
305319
run: |
@@ -310,18 +324,6 @@ jobs:
310324
run: |
311325
yarn install --immutable --immutable-cache --check-cache
312326
yarn add electron@${{env.ElectronVersion}} -D
313-
- name: Configure obs-studio-node
314-
run: ./ci/configure-osn.cmd
315-
env:
316-
ReleaseName: release
317-
tagartifact: ${{ steps.get_version.outputs.VERSION }}
318-
- name: Build obs-studio-node
319-
run: cmake --build ${{env.SLBUILDDIRECTORY}} --target install --config RelWithDebInfo
320-
- name: Put version into package.json
321-
if: startsWith(github.ref, 'refs/tags/')
322-
run: node ci/bump-version.js "${{ steps.get_version.outputs.VERSION }}" "${{env.PACKAGE_PATH}}"
323-
env:
324-
PACKAGE_PATH: "${{env.SLFullDistributePath}}/${{env.InstallPath}}"
325327
- name: 'Run tests'
326328
timeout-minutes: 20
327329
continue-on-error: false
@@ -341,10 +343,11 @@ jobs:
341343
env:
342344
OS_TAG: "win64"
343345
steps:
344-
- name: 'Checkout'
345-
uses: actions/checkout@v3
346+
- name: Download build artifacts
347+
uses: actions/download-artifact@v4
346348
with:
347-
submodules: 'recursive'
349+
name: build-artifacts-windows
350+
path: .
348351
- name: Get the version
349352
id: get_version
350353
run: |
@@ -383,6 +386,11 @@ jobs:
383386
fetch-depth: 2
384387
repository: stream-labs/symsrv-scripts
385388
path: symsrv-scripts
389+
- name: Download build artifacts
390+
uses: actions/download-artifact@v4
391+
with:
392+
name: build-artifacts-windows
393+
path: .
386394
- name: Get the version
387395
id: get_version
388396
run: |

obs-studio-client/source/controller.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,14 @@ std::shared_ptr<ipc::client> Controller::host(const std::string &uri)
313313
remove(uri.c_str());
314314

315315
int ret = posix_spawnp(&pid, serverBinaryPath.c_str(), NULL, NULL, argv, environ);
316+
if (ret != 0) {
317+
std::cerr << "Could not spawn the server at " << serverBinaryPath.c_str() << " with error code: " << ret << std::endl;
318+
return nullptr;
319+
}
316320
// Connect
317321
std::shared_ptr<ipc::client> cl = connect(uri);
318322
if (!cl) { // Assume the server broke or was not allowed to run.
323+
std::cerr << "Could not connect to ipc::server" << std::endl;
319324
disconnect();
320325
uint32_t exitcode;
321326
kill(pid, SIGKILL);

obs-studio-client/source/video.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,18 @@ void osn::Video::Destroy(const Napi::CallbackInfo &info)
110110

111111
inline void CreateVideo(const Napi::CallbackInfo &info, const std::vector<ipc::value> &response, Napi::Object &video, uint32_t index)
112112
{
113-
video.Set("fpsNum", response[index++].value_union.ui32);
114-
video.Set("fpsDen", response[index++].value_union.ui32);
115-
video.Set("baseWidth", response[index++].value_union.ui32);
116-
video.Set("baseHeight", response[index++].value_union.ui32);
117-
video.Set("outputWidth", response[index++].value_union.ui32);
118-
video.Set("outputHeight", response[index++].value_union.ui32);
119-
video.Set("outputFormat", response[index++].value_union.ui32);
120-
video.Set("colorspace", response[index++].value_union.ui32);
121-
video.Set("range", response[index++].value_union.ui32);
122-
video.Set("scaleType", response[index++].value_union.ui32);
113+
video.Set("fpsNum", response.at(index++).value_union.ui32);
114+
video.Set("fpsDen", response.at(index++).value_union.ui32);
115+
video.Set("baseWidth", response.at(index++).value_union.ui32);
116+
video.Set("baseHeight", response.at(index++).value_union.ui32);
117+
video.Set("outputWidth", response.at(index++).value_union.ui32);
118+
video.Set("outputHeight", response.at(index++).value_union.ui32);
119+
video.Set("outputFormat", response.at(index++).value_union.ui32);
120+
video.Set("colorspace", response.at(index++).value_union.ui32);
121+
video.Set("range", response.at(index++).value_union.ui32);
122+
video.Set("scaleType", response.at(index++).value_union.ui32);
123123
if (response.size() >= 12)
124-
video.Set("fpsType", response[index++].value_union.ui32);
124+
video.Set("fpsType", response.at(index++).value_union.ui32);
125125
}
126126

127127
inline void SerializeVideoData(const Napi::Object &video, std::vector<ipc::value> &args)

obs-studio-server/source/nodeobs_settings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2726,7 +2726,7 @@ void OBS_settings::saveAdvancedOutputStreamingSettings(std::vector<SubCategory>
27262726
} else if (type.compare("OBS_PROPERTY_BOOL") == 0) {
27272727
bool *value = reinterpret_cast<bool *>(param.currentValue.data());
27282728
if (i < indexEncoderSettings) {
2729-
if (name.compare("Rescale") == 0 && *value || name.compare("VodTrackEnabled") == 0 && *value) {
2729+
if ((name.compare("Rescale") == 0 && *value) || (name.compare("VodTrackEnabled") == 0 && *value)) {
27302730
indexEncoderSettings++;
27312731
}
27322732
config_set_bool(ConfigManager::getInstance().getBasic(), section.c_str(), name.c_str(), *value);

tests/osn-tests/src/test_nodeobs_settings.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,7 @@ describe(testName, function() {
10461046
break;
10471047
}
10481048
case 'ApplyServiceSettings': {
1049-
parameter.currentValue = true;
1049+
parameter.currentValue = false;
10501050
break;
10511051
}
10521052
case 'rate_control': {
@@ -1402,7 +1402,7 @@ describe(testName, function() {
14021402
// Checking if settings were updated correctly
14031403
const updatedCRFOutputSettings = obs.getSettingsContainer(EOBSSettingsCategories.Output);
14041404
expect(crfOutputSettings).to.eql(updatedCRFOutputSettings, GetErrorMessage(ETestErrorMsg.OutputSettings));
1405-
}
1405+
} // else if
14061406
});
14071407

14081408
it('Get and set NVENC encoder streaming and recording advanced output settings', function() {

tests/osn-tests/src/test_osn_input.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,21 @@ describe(testName, () => {
4444
});
4545

4646
it('Check list of input types', () => {
47-
// have to ignore vlc_source and mediasoupconnector as they are not available on CI
48-
const ignoreInputTypes = ["vlc_source", "mediasoupconnector"];
49-
let expectedInputTypes = ["audio_line", "image_source", "color_source", "color_source_v2", "color_source_v3", "slideshow", "mediasoupconnector", "browser_source", "ffmpeg_source", "text_ft2_source", "text_ft2_source_v2", "vlc_source", "window_capture", "screen_capture", "slideshow_v2"];
47+
// have to ignore vlc_source, mediasoupconnector, and ndi_source as they are not available on CI
48+
const ignoreInputTypes = ["vlc_source", "mediasoupconnector", "ndi_source"];
49+
let expectedInputTypes = ["audio_line", "image_source", "color_source", "color_source_v2", "color_source_v3", "slideshow", "mediasoupconnector", "browser_source", "ffmpeg_source", "text_ft2_source", "text_ft2_source_v2", "vlc_source", "window_capture", "slideshow_v2"];
5050

5151
if (obs.os == 'darwin') {
52-
let additionalDarwinTypes = ["macos-avcapture", "macos-avcapture-fast", "sck_audio_capture", "av_capture_input","av_capture_input_v2","display_capture","coreaudio_input_capture","coreaudio_output_capture"];
52+
let additionalDarwinTypes = ["macos_avcapture", "macos_avcapture_fast", "mac_screen_capture", "sck_audio_capture", "av_capture_input","av_capture_input_v2","display_capture","coreaudio_input_capture","coreaudio_output_capture"];
5353
expectedInputTypes.push(...additionalDarwinTypes);
5454
} else if (obs.os == 'win32') {
55-
let additionalWin32Types = [ "text_gdiplus", "text_gdiplus_v2", "text_gdiplus_v3", "monitor_capture", "game_capture", "dshow_input", "openvr_capture", "spout_capture", "wasapi_input_capture", "wasapi_output_capture", "wasapi_process_output_capture"];
55+
let additionalWin32Types = [ "text_gdiplus", "text_gdiplus_v2", "text_gdiplus_v3", "monitor_capture", "game_capture", "dshow_input", "openvr_capture", "spout_capture", "wasapi_input_capture", "wasapi_output_capture", "wasapi_process_output_capture", "screen_capture",];
5656
expectedInputTypes.push(...additionalWin32Types);
5757
}
5858
let missingDiff = expectedInputTypes.filter(x => !obs.inputTypes.includes(x));
5959
missingDiff = missingDiff.filter(x => !ignoreInputTypes.includes(x));
6060
let unexpectedDiff = obs.inputTypes.filter(x => !expectedInputTypes.includes(x));
61+
unexpectedDiff = unexpectedDiff.filter(x => !ignoreInputTypes.includes(x));
6162
if (missingDiff.length > 0 || unexpectedDiff.length > 0) {
6263
logInfo(testName, 'Unexpected input types: ' + JSON.stringify( unexpectedDiff));
6364
logInfo(testName, 'Missing input types: ' + JSON.stringify( missingDiff));

tests/osn-tests/src/test_osn_video.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ describe(testName, () => {
119119
expect(currentVideo.baseHeight).to.equal(2160, GetErrorMessage(ETestErrorMsg.VideoSetBaseHeight));
120120
expect(currentVideo.outputWidth).to.equal(1920, GetErrorMessage(ETestErrorMsg.VideoSetOutputWidth));
121121
expect(currentVideo.outputHeight).to.equal(1080, GetErrorMessage(ETestErrorMsg.VideoSetOutputHeight));
122+
// Note: OSN overrides ColorFormat, Colorspace, & Range with values from basic.ini. Not possible to change those atm from JS. See osn::Video::SetVideoContext
122123
expect(currentVideo.outputFormat).to.equal(osn.EVideoFormat.NV12, GetErrorMessage(ETestErrorMsg.VideoSetOutputFormat));
123124
expect(currentVideo.colorspace).to.equal(osn.EColorSpace.CS709, GetErrorMessage(ETestErrorMsg.VideoSetColorFormat));
124125
expect(currentVideo.range).to.equal(osn.ERangeType.Partial, GetErrorMessage(ETestErrorMsg.VideoSetRange));
@@ -151,6 +152,7 @@ describe(testName, () => {
151152
expect(firstVideo.baseHeight).to.equal(2160, GetErrorMessage(ETestErrorMsg.VideoSetBaseHeight));
152153
expect(firstVideo.outputWidth).to.equal(1920, GetErrorMessage(ETestErrorMsg.VideoSetOutputWidth));
153154
expect(firstVideo.outputHeight).to.equal(1080, GetErrorMessage(ETestErrorMsg.VideoSetOutputHeight));
155+
// Note: OSN overrides ColorFormat, Colorspace, & Range with values from basic.ini. Not possible to change those atm from JS. See osn::Video::SetVideoContext
154156
expect(firstVideo.outputFormat).to.equal(osn.EVideoFormat.NV12, GetErrorMessage(ETestErrorMsg.VideoSetOutputFormat));
155157
expect(firstVideo.colorspace).to.equal(osn.EColorSpace.CS709, GetErrorMessage(ETestErrorMsg.VideoSetColorFormat));
156158
expect(firstVideo.range).to.equal(osn.ERangeType.Partial, GetErrorMessage(ETestErrorMsg.VideoSetRange));

tests/osn-tests/util/general.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let showHideInputHotkeys: string[] = ['SHOW_SCENE_ITEM.WASAPI_OUTPUT_CAPTURE', '
3838
'HIDE_SCENE_ITEM.AV_CAPTURE_INPUT_V2','SHOW_SCENE_ITEM.SPOUT_CAPTURE','HIDE_SCENE_ITEM.SPOUT_CAPTURE',
3939
'SHOW_SCENE_ITEM.SLIDESHOW_V2', 'HIDE_SCENE_ITEM.SLIDESHOW_V2', 'SHOW_SCENE_ITEM.TEXT_GDIPLUS_V3', 'HIDE_SCENE_ITEM.TEXT_GDIPLUS_V3',
4040
'SHOW_SCENE_ITEM.MACOS_AVCAPTURE', 'HIDE_SCENE_ITEM.MACOS_AVCAPTURE', 'SHOW_SCENE_ITEM.MACOS_AVCAPTURE_FAST', 'HIDE_SCENE_ITEM.MACOS_AVCAPTURE_FAST',
41-
'SHOW_SCENE_ITEM.SCK_AUDIO_CAPTURE', 'HIDE_SCENE_ITEM.SCK_AUDIO_CAPTURE'];
41+
'SHOW_SCENE_ITEM.SCK_AUDIO_CAPTURE', 'HIDE_SCENE_ITEM.SCK_AUDIO_CAPTURE', 'SHOW_SCENE_ITEM.MAC_SCREEN_CAPTURE', 'HIDE_SCENE_ITEM.MAC_SCREEN_CAPTURE'];
4242

4343
export {showHideInputHotkeys};
4444

@@ -76,22 +76,21 @@ export function deleteConfigFiles(): void {
7676
const fs = require('fs');
7777
const path = require('path');
7878
const configFolderPath = path.join(path.normalize(__dirname), '..', 'osnData/slobs-client');
79-
let files;
80-
let currentFile: string;
81-
82-
try {
83-
files = fs.readdirSync(configFolderPath);
84-
79+
if (fs.existsSync(configFolderPath)) {
80+
let currentFile: string;
81+
let files = fs.readdirSync(configFolderPath);
8582
files.forEach(file => {
8683
if (file !== 'node-obs') {
8784
currentFile = file;
88-
fs.unlinkSync(path.join(configFolderPath, file));
85+
try {
86+
fs.unlinkSync(path.join(configFolderPath, file));
87+
} catch(error) {
88+
if (error.code === "EBUSY") {
89+
throw ('Error: the file ' + currentFile + ' or slobs-client folder is busy');
90+
}
91+
}
8992
}
9093
});
91-
} catch(error) {
92-
if (error.code === "EBUSY") {
93-
throw ('Error: the file ' + currentFile + ' or slobs-client folder is busy');
94-
}
9594
}
9695
}
9796

0 commit comments

Comments
 (0)