diff --git a/.github/workflows/darwin-tests.yaml b/.github/workflows/darwin-tests.yaml new file mode 100644 index 00000000000000..ae11fd43430b23 --- /dev/null +++ b/.github/workflows/darwin-tests.yaml @@ -0,0 +1,121 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# 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. + +name: Darwin Tests + +on: + push: + pull_request: + workflow_dispatch: + +concurrency: + group: + ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == + 'pull_request' && github.event.number) || (github.event_name == + 'workflow_dispatch' && github.run_number) || github.sha }} + cancel-in-progress: true + +jobs: + test_suites_chip_tool_darwin: + name: Test Suites - Darwin + timeout-minutes: 120 + + strategy: + matrix: + build_variant: [no-ble-asan] + env: + BUILD_VARIANT: ${{matrix.build_variant}} + + if: github.actor != 'restyled-io[bot]' + runs-on: macos-latest + + steps: + - name: Checkout submodules + run: scripts/checkout_submodules.py --shallow --platform darwin + - name: Setup Environment + # coreutils for stdbuf + run: brew install openssl pkg-config coreutils + - name: + Try to ensure the directories for core dumping and diagnostic + log collection exist and we can write them. + run: | + sudo chown ${USER} /cores || true + mkdir -p ~/Library/Logs/DiagnosticReports || true + mkdir objdir-clone || true + - name: Fix pkgconfig link + working-directory: /usr/local/lib/pkgconfig + run: | + pwd + ls -la /usr/local/Cellar/ + ls -la /usr/local/Cellar/openssl@1.1 + OPEN_SSL_VERSION=`ls -la /usr/local/Cellar/openssl@1.1 | cat | tail -n1 | awk '{print $NF}'` + ln -s /usr/local/Cellar/openssl@1.1/$OPEN_SSL_VERSION/lib/pkgconfig/* . + - name: Bootstrap + timeout-minutes: 25 + run: scripts/build/gn_bootstrap.sh + - name: Uploading bootstrap logs + uses: actions/upload-artifact@v2 + if: ${{ always() }} && ${{ !env.ACT }} + with: + name: + bootstrap-logs-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + path: | + .environment/gn_out/.ninja_log + .environment/pigweed-venv/*.log + - name: Build Apps + timeout-minutes: 30 + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target darwin-x64-chip-tool-darwin-${BUILD_VARIANT} \ + --target darwin-x64-all-clusters-${BUILD_VARIANT} \ + build \ + --copy-artifacts-to objdir-clone \ + " + - name: Run Tests + timeout-minutes: 45 + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/tests/run_test_suite.py \ + --chip-tool ./out/darwin-x64-chip-tool-darwin-${BUILD_VARIANT}/chip-tool-darwin \ + --target-skip-glob '{TestGroupMessaging,TV_*}' \ + run \ + --iterations 1 \ + --all-clusters-app ./out/darwin-x64-all-clusters-${BUILD_VARIANT}/chip-all-clusters-app \ + " + - name: Uploading core files + uses: actions/upload-artifact@v2 + if: ${{ failure() }} && ${{ !env.ACT }} + with: + name: + crash-core-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + path: /cores/ + # Cores are big; don't hold on to them too long. + retention-days: 5 + - name: Uploading diagnostic logs + uses: actions/upload-artifact@v2 + if: ${{ failure() }} && ${{ !env.ACT }} + with: + name: + crash-log-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + path: ~/Library/Logs/DiagnosticReports/ + - name: Uploading objdir for debugging + uses: actions/upload-artifact@v2 + if: ${{ failure() }} && ${{ !env.ACT }} + with: + name: + crash-objdir-darwin-${{ matrix.build_variant }}${{ matrix.chip_tool }} + path: objdir-clone/ + # objdirs are big; don't hold on to them too long. + retention-days: 5 diff --git a/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.h b/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.h index 891b733515116a..a29cadfbfdd626 100644 --- a/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.h +++ b/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.h @@ -73,9 +73,7 @@ class CHIPCommandBridge : public Command void StopWaiting(); CHIPDeviceController * mController; -#if CONFIG_USE_SEPARATE_EVENTLOOP std::condition_variable cvWaitingForResponse; std::mutex cvWaitingForResponseMutex; bool mWaitingForResponse{ true }; -#endif // CONFIG_USE_SEPARATE_EVENTLOOP }; diff --git a/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.mm b/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.mm index 67bed2b270961c..f468c1993f3f16 100644 --- a/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.mm +++ b/examples/chip-tool-darwin/commands/common/CHIPCommandBridge.mm @@ -89,16 +89,8 @@ return CHIP_NO_ERROR; } -#if !CONFIG_USE_SEPARATE_EVENTLOOP -static void OnResponseTimeout(chip::System::Layer *, void * appState) -{ - (reinterpret_cast(appState))->SetCommandExitStatus(CHIP_ERROR_TIMEOUT); -} -#endif // !CONFIG_USE_SEPARATE_EVENTLOOP - CHIP_ERROR CHIPCommandBridge::StartWaiting(chip::System::Clock::Timeout duration) { -#if CONFIG_USE_SEPARATE_EVENTLOOP chip::DeviceLayer::PlatformMgr().StartEventLoopTask(); auto waitingUntil = std::chrono::system_clock::now() + std::chrono::duration_cast(duration); { @@ -108,23 +100,15 @@ static void OnResponseTimeout(chip::System::Layer *, void * appState) } } LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().StopEventLoopTask()); -#else - ReturnLogErrorOnFailure(chip::DeviceLayer::SystemLayer().StartTimer(duration, OnResponseTimeout, this)); - chip::DeviceLayer::PlatformMgr().RunEventLoop(); -#endif // CONFIG_USE_SEPARATE_EVENTLOOP return mCommandExitStatus; } void CHIPCommandBridge::StopWaiting() { -#if CONFIG_USE_SEPARATE_EVENTLOOP { std::lock_guard lk(cvWaitingForResponseMutex); mWaitingForResponse = false; } cvWaitingForResponse.notify_all(); -#else // CONFIG_USE_SEPARATE_EVENTLOOP - LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().StopEventLoopTask()); -#endif // CONFIG_USE_SEPARATE_EVENTLOOP } diff --git a/examples/chip-tool-darwin/commands/tests/TestCommandBridge.h b/examples/chip-tool-darwin/commands/tests/TestCommandBridge.h index f1a03e750fe70a..6ef4b2e01753ea 100644 --- a/examples/chip-tool-darwin/commands/tests/TestCommandBridge.h +++ b/examples/chip-tool-darwin/commands/tests/TestCommandBridge.h @@ -34,7 +34,6 @@ class TestCommandBridge : public CHIPCommandBridge, public ValueChecker, public TestCommandBridge(const char * _Nonnull commandName) : CHIPCommandBridge(commandName) { - AddArgument("node-id", 0, UINT64_MAX, &mNodeId); AddArgument("delayInMs", 0, UINT64_MAX, &mDelayInMs); AddArgument("PICS", &mPICSFilePath); } @@ -101,7 +100,6 @@ class TestCommandBridge : public CHIPCommandBridge, public ValueChecker, public protected: dispatch_queue_t _Nullable mCallbackQueue; CHIPDevice * _Nullable mConnectedDevice; - chip::NodeId mNodeId; void Wait() { @@ -230,7 +228,7 @@ class TestCommandBridge : public CHIPCommandBridge, public ValueChecker, public template bool CheckValue(const char * _Nonnull itemName, NSError * _Nullable current, T expected) { - NSNumber * currentValue = @([CHIPError errorToCHIPErrorCode:current].AsInteger()); + NSNumber * currentValue = @(current.code); return CheckValue(itemName, currentValue, @(expected)); } diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 031104bc1b5319..c45628ce494f82 100644 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -239,6 +239,9 @@ def HostTargets(): for target in targets: app_targets.append(target.Extend( 'all-clusters', app=HostApp.ALL_CLUSTERS)) + if (HostBoard.NATIVE.PlatformName() == 'darwin'): + app_targets.append(target.Extend( + 'chip-tool-darwin', app=HostApp.CHIP_TOOL_DARWIN)) app_targets.append(target.Extend('chip-tool', app=HostApp.CHIP_TOOL)) app_targets.append(target.Extend('thermostat', app=HostApp.THERMOSTAT)) app_targets.append(target.Extend('minmdns', app=HostApp.MIN_MDNS)) @@ -257,7 +260,7 @@ def HostTargets(): builder.AppendVariant(name="test-group", validator=AcceptNameWithSubstrings( ['-all-clusters', '-chip-tool']), test_group=True), builder.AppendVariant(name="same-event-loop", validator=AcceptNameWithSubstrings( - ['-chip-tool']), separate_event_loop=False), + ['-chip-tool', '-chip-tool-darwin']), separate_event_loop=False), builder.AppendVariant(name="no-interactive", validator=AcceptNameWithSubstrings( ['-chip-tool']), interactive_mode=False), builder.AppendVariant(name="ipv6only", enable_ipv4=False), diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 8cb51f0b8ea051..4a7d583ebe46c8 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -22,6 +22,7 @@ class HostApp(Enum): ALL_CLUSTERS = auto() CHIP_TOOL = auto() + CHIP_TOOL_DARWIN = auto() THERMOSTAT = auto() RPC_CONSOLE = auto() MIN_MDNS = auto() @@ -41,6 +42,8 @@ def ExamplePath(self): return 'all-clusters-app/linux' elif self == HostApp.CHIP_TOOL: return 'chip-tool' + elif self == HostApp.CHIP_TOOL_DARWIN: + return 'chip-tool-darwin' elif self == HostApp.THERMOSTAT: return 'thermostat/linux' elif self == HostApp.RPC_CONSOLE: @@ -71,6 +74,9 @@ def OutputNames(self): elif self == HostApp.CHIP_TOOL: yield 'chip-tool' yield 'chip-tool.map' + elif self == HostApp.CHIP_TOOL_DARWIN: + yield 'chip-tool-darwin' + yield 'chip-tool-darwin.map' elif self == HostApp.THERMOSTAT: yield 'thermostat-app' yield 'thermostat-app.map' diff --git a/scripts/tests/chiptest/test_definition.py b/scripts/tests/chiptest/test_definition.py index ca2c4e58bab172..25a45ebf2f2e65 100644 --- a/scripts/tests/chiptest/test_definition.py +++ b/scripts/tests/chiptest/test_definition.py @@ -15,6 +15,7 @@ import logging import os +import sys import threading import time import typing @@ -239,16 +240,20 @@ def Run(self, runner, apps_register, paths: ApplicationPaths, pics_file: str): # so it will be commissionable again. app.factoryReset() app.start(str(randrange(1, 4096))) - - runner.RunSubprocess( - tool_cmd + ['pairing', 'qrcode', TEST_NODE_ID, app.setupCode] + - ['--paa-trust-store-path', DEVELOPMENT_PAA_LIST], - name='PAIR', dependencies=[apps_register]) - + pairing_cmd = tool_cmd + ['pairing', 'qrcode', TEST_NODE_ID, app.setupCode] + if sys.platform != 'darwin': + pairing_cmd.append('--paa-trust-store-path') + pairing_cmd.append(DEVELOPMENT_PAA_LIST) + + runner.RunSubprocess(pairing_cmd, + name='PAIR', dependencies=[apps_register]) + + test_cmd = tool_cmd + ['tests', self.run_name] + ['--PICS', pics_file] + if sys.platform != 'darwin': + test_cmd.append('--paa-trust-store-path') + test_cmd.append(DEVELOPMENT_PAA_LIST) runner.RunSubprocess( - tool_cmd + ['tests', self.run_name] + - ['--paa-trust-store-path', DEVELOPMENT_PAA_LIST] + - ['--PICS', pics_file], + test_cmd, name='TEST', dependencies=[apps_register]) except Exception: