From 2eb4c511290a35d7c3349fb871e3c700aa26679c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 2 Dec 2021 13:54:11 -0500 Subject: [PATCH] Separate out E2E build rules into different directories (#12303) * Add a lot more host build variants for build_examples * Fix single event loop logic for building * Switch build to build_examples and separate paths for linux in CI workflows * Do not blacklist ipv6 builds * Undo change in test yaml for event loop types * Undo double quoting * Fix separate event loop logic * Fix default of separate event loop: same event loop is the default * Fix typo in super call * Allow more build time since we are building 3 apps now * Do not yet update the tests.yaml file - want to make these changes gradually * Revert "Do not yet update the tests.yaml file - want to make these changes gradually" This reverts commit 90666bade531b87827ed0f0306ed5e4c953ccc4a. * Fix up the event loop name logic for test running * Make the matrix logic and scripts much more readable * Remove obsolete logic code * Fix yet another typo in variable replacement * Convert darwin to use build_examples AND test TV apps * Bump the time for darwin tests: it looks like ToT takes 29:45 and 30 is too tight * Disable ASAN builds for linux (according to build history they do not link * Add asan and tsan target support * Restyle fixes * Give a name to the chip tool without special variants * Use empty string for empty tool variant * Code review suggestions * fix typo * Minor bug fix, target list now works * one more typo fix * Typo fix * Match zap version to master * flip order of chip-tool/run to match master ordering * Do not build/test TV app on darwin. It does not seem to work. We can follow up later to figure it out --- .github/workflows/tests.yaml | 78 ++++++++++++++-------------------- scripts/build/build/targets.py | 72 ++++++++++++++++++++++++++++++- scripts/build/builders/host.py | 16 ++++++- 3 files changed, 118 insertions(+), 48 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0c8d4ecf3f5b76..3e392c1ae9bdc6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -30,11 +30,11 @@ jobs: strategy: matrix: - type: [tsan] - eventloop: [eventloop_same, eventloop_separate] + build_variant: [no-ble-tsan] + chip_tool: ["", -same-event-loop] env: - USE_SEPARATE_EVENTLOOP: ${{ matrix.eventloop == 'eventloop_separate' }} - USE_TSAN: ${{ matrix.type == 'tsan' }} + BUILD_VARIANT: ${{matrix.build_variant}} + CHIP_TOOL_VARIANT: ${{matrix.chip_tool}} if: github.actor != 'restyled-io[bot]' runs-on: ubuntu-latest @@ -66,33 +66,27 @@ jobs: path: | .environment/gn_out/.ninja_log .environment/pigweed-venv/*.log - - name: Build all clusters app - timeout-minutes: 5 + - name: Build Apps + timeout-minutes: 20 run: | - scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug/standalone/ chip_config_network_layer_ble=false is_tsan=${USE_TSAN} - - name: Build TV app - timeout-minutes: 5 - run: | - scripts/examples/gn_build_example.sh examples/tv-app/linux out/debug/standalone/ chip_config_network_layer_ble=false is_tsan=${USE_TSAN} - - name: Build chip-tool - timeout-minutes: 5 - run: | - scripts/examples/gn_build_example.sh examples/chip-tool out/debug/standalone/ is_tsan=${USE_TSAN} config_use_separate_eventloop=${USE_SEPARATE_EVENTLOOP} - - name: Copy objdir - run: | - # The idea is to not upload our objdir unless builds have - # actually succeeded, because that just wastes space. - rsync -a out/debug/standalone/ objdir-clone || true + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target linux-x64-chip-tool-${BUILD_VARIANT}${CHIP_TOOL_VARIANT} \ + --target linux-x64-all-clusters-${BUILD_VARIANT} \ + --target linux-x64-tv-app-${BUILD_VARIANT} \ + build \ + --copy-artifacts-to objdir-clone \ + " - name: Run Tests timeout-minutes: 30 run: | ./scripts/run_in_build_env.sh \ "./scripts/tests/run_test_suite.py \ - --chip-tool ./out/debug/standalone/chip-tool \ + --chip-tool ./out/linux-x64-chip-tool-${BUILD_VARIANT}${CHIP_TOOL_VARIANT}/chip-tool \ run \ --iterations 1 \ - --all-clusters-app ./out/debug/standalone/chip-all-clusters-app \ - --tv-app ./out/debug/standalone/chip-tv-app \ + --all-clusters-app ./out/linux-x64-all-clusters-${BUILD_VARIANT}/chip-all-clusters-app \ + --tv-app ./out/linux-x64-tv-app-${BUILD_VARIANT}/chip-tv-app \ " - name: Uploading core files uses: actions/upload-artifact@v2 @@ -116,13 +110,11 @@ jobs: strategy: matrix: - type: [tsan, asan] - eventloop: [eventloop_same, eventloop_separate] + build_variant: [no-ble-tsan, no-ble-asan] + chip_tool: ["", -same-event-loop] env: - USE_SEPARATE_EVENTLOOP: ${{ matrix.eventloop == 'eventloop_separate' }} - USE_TSAN: ${{ matrix.type == 'tsan' }} - - USE_ASAN: ${{ matrix.type == 'asan' }} + BUILD_VARIANT: ${{matrix.build_variant}} + CHIP_TOOL_VARIANT: ${{matrix.chip_tool}} if: github.actor != 'restyled-io[bot]' runs-on: macos-latest @@ -159,30 +151,26 @@ jobs: path: | .environment/gn_out/.ninja_log .environment/pigweed-venv/*.log - - name: Run Build Test Server - timeout-minutes: 10 - run: | - scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug/standalone/ chip_config_network_layer_ble=false is_tsan=${USE_TSAN} is_asan=${USE_ASAN} - - name: Build chip-tool - timeout-minutes: 10 + - name: Build Apps + timeout-minutes: 20 run: | - scripts/examples/gn_build_example.sh examples/chip-tool out/debug/standalone/ is_tsan=${USE_TSAN} is_asan=${USE_ASAN} config_use_separate_eventloop=${USE_SEPARATE_EVENTLOOP} - - name: Copy objdir - run: | - # The idea is to not upload our objdir unless builds have - # actually succeeded, because that just wastes space. - rsync -a out/debug/standalone/ objdir-clone || true + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target darwin-x64-chip-tool-${BUILD_VARIANT}${CHIP_TOOL_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/debug/standalone/chip-tool \ - --target-skip-glob 'TV_*' \ + --chip-tool ./out/darwin-x64-chip-tool-${BUILD_VARIANT}${CHIP_TOOL_VARIANT}/chip-tool \ + --target-skip-glob 'TV*' \ run \ --iterations 1 \ - --all-clusters-app ./out/debug/standalone/chip-all-clusters-app \ - --tv-app ./out/debug/standalone/chip-tv-app \ + --all-clusters-app ./out/darwin-x64-all-clusters-${BUILD_VARIANT}/chip-all-clusters-app \ " - name: Uploading core files uses: actions/upload-artifact@v2 diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 7d5adf9c0f593f..b6f90a30e8cc60 100644 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -14,6 +14,9 @@ import os +from typing import Any, List +from itertools import combinations + from builders.android import AndroidBoard, AndroidApp, AndroidBuilder from builders.efr32 import Efr32Builder, Efr32App, Efr32Board from builders.esp32 import Esp32Builder, Esp32Board, Esp32App @@ -93,6 +96,34 @@ def GlobBlacklistReason(self): return self.glob_blacklist_reason +class AcceptAnyName: + def Accept(self, name: str): + return True + + +class AcceptNameWithSubstring: + def __init__(self, substr: str): + self.substr = substr + + def Accept(self, name: str): + return self.substr in name + + +class HostBuildVariant: + def __init__(self, name: str, validator=AcceptAnyName(), conflicts: List[str] = [], **buildargs): + self.name = name + self.validator = validator + self.conflicts = conflicts + self.buildargs = buildargs + + +def HasConflicts(items: List[HostBuildVariant]) -> bool: + for a, b in combinations(items, 2): + if (a.name in b.conflicts) or (b.name in a.conflicts): + return True + return False + + def HostTargets(): target = Target(HostBoard.NATIVE.PlatformName(), HostBuilder) targets = [ @@ -119,10 +150,47 @@ def HostTargets(): app_targets.append(target.Extend('thermostat', app=HostApp.THERMOSTAT)) app_targets.append(target.Extend('minmdns', app=HostApp.MIN_MDNS)) + # Possible build variants. Note that number of potential + # builds is exponential here + variants = [ + HostBuildVariant(name="ipv6only", enable_ipv4=False), + HostBuildVariant(name="no-ble", enable_ble=False), + HostBuildVariant(name="tsan", conflicts=['asan'], use_tsan=True), + HostBuildVariant(name="asan", conflicts=['tsan'], use_asan=True), + HostBuildVariant(name="same-event-loop", + validator=AcceptNameWithSubstring('-chip-tool'), separate_event_loop=False), + ] + + glob_whitelist = set(['ipv6only']) + for target in app_targets: yield target - if ('rpc-console' not in target.name): - yield target.Extend('ipv6only', enable_ipv4=False) + + if 'rpc-console' in target.name: + # rpc console has only one build variant right now + continue + + # skip variants that do not work for this target + ok_variants = [v for v in variants if v.validator.Accept(target.name)] + + # Build every possible variant + for variant_count in range(1, len(ok_variants) + 1): + for subgroup in combinations(ok_variants, variant_count): + if HasConflicts(subgroup): + continue + + # Target ready to be created - no conflicts + variant_target = target.Clone() + for option in subgroup: + variant_target = variant_target.Extend( + option.name, **option.buildargs) + + # Only a few are whitelisted for globs + if '-'.join([o.name for o in subgroup]) not in glob_whitelist: + variant_target = variant_target.GlobBlacklist( + 'Reduce default build variants') + + yield variant_target def Esp32Targets(): diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index c5887cd2310199..f0cdabf91674b5 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -105,7 +105,9 @@ def PlatformName(self): class HostBuilder(GnBuilder): - def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, enable_ipv4=True): + def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, enable_ipv4=True, + enable_ble=True, use_tsan=False, use_asan=False, separate_event_loop=True + ): super(HostBuilder, self).__init__( root=os.path.join(root, 'examples', app.ExamplePath()), runner=runner) @@ -117,6 +119,18 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, enable_ip if not enable_ipv4: self.extra_gn_options.append('chip_inet_config_enable_ipv4=false') + if not enable_ble: + self.extra_gn_options.append('chip_config_network_layer_ble=false') + + if use_tsan: + self.extra_gn_options.append('is_tsan=true') + + if use_asan: + self.extra_gn_options.append('is_asan=true') + + if not separate_event_loop: + self.extra_gn_options.append('config_use_separate_eventloop=false') + def GnBuildArgs(self): if self.board == HostBoard.NATIVE: return self.extra_gn_options