From 22534008bebee205aec70a7cf4f084bbcbb6529d Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 18 Nov 2021 17:28:43 -0500 Subject: [PATCH] Remove happy tests (#11373) * Remove happy test references from build system and test driver * Remove happy submodule * Remove test that can only run when using happy * Remove more happy usages from buiuld.gn and workflow scripts * remove happy from gni * Restyle fixes * Remove one more run happy tests variable * Enable dnssd for darwin only for now * whitespace update to kick the build * Restyle fixes * undo unintended changes to third party repos * Fix typo * Remove more happy specific scripts --- .github/workflows/unit_integration_test.yaml | 15 +- .gitmodules | 4 - BUILD.gn | 10 - build/chip/happy_test.gni | 54 -- build/chip/tests.gni | 3 - scripts/tests/gn_tests.sh | 4 - scripts/tests/happy_test_wrapper.py | 66 -- scripts/tests/happy_tests.sh | 70 -- src/BUILD.gn | 8 - src/inet/tests/BUILD.gn | 20 - src/inet/tests/TestInetLayerMulticast.cpp | 842 ------------------ .../tests/TestInetLayerMulticastDriver.cpp | 33 - src/platform/tests/BUILD.gn | 8 +- src/test_driver/efr32/args.gni | 1 - src/test_driver/happy/README.md | 46 - src/test_driver/happy/bin/set_test_path.py | 50 -- src/test_driver/happy/conf/main_conf.json | 14 - src/test_driver/happy/lib/Chip.py | 90 -- src/test_driver/happy/lib/ChipState.py | 55 -- src/test_driver/happy/lib/ChipStateLoad.py | 116 --- src/test_driver/happy/lib/ChipStateUnload.py | 128 --- src/test_driver/happy/lib/ChipTest.py | 268 ------ src/test_driver/happy/lib/ChipUtilities.py | 83 -- src/test_driver/happy/lib/set_test_path.py | 1 - .../happy/test-templates/ChipInetMulticast.py | 376 -------- .../happy/tests/standalone/inet/BUILD.gn | 24 - .../tests/standalone/inet/set_test_path.py | 1 - .../test_inet_multicast_five_nodes_on_wifi.py | 232 ----- .../standalone/five_nodes_on_wifi.json | 306 ------- .../standalone/five_nodes_on_wifi.sh | 39 - third_party/happy/BUILD.gn | 21 - third_party/happy/repo | 1 - 32 files changed, 9 insertions(+), 2980 deletions(-) delete mode 100644 build/chip/happy_test.gni delete mode 100755 scripts/tests/happy_test_wrapper.py delete mode 100755 scripts/tests/happy_tests.sh delete mode 100644 src/inet/tests/TestInetLayerMulticast.cpp delete mode 100644 src/inet/tests/TestInetLayerMulticastDriver.cpp delete mode 100644 src/test_driver/happy/README.md delete mode 100644 src/test_driver/happy/bin/set_test_path.py delete mode 100644 src/test_driver/happy/conf/main_conf.json delete mode 100644 src/test_driver/happy/lib/Chip.py delete mode 100644 src/test_driver/happy/lib/ChipState.py delete mode 100644 src/test_driver/happy/lib/ChipStateLoad.py delete mode 100644 src/test_driver/happy/lib/ChipStateUnload.py delete mode 100644 src/test_driver/happy/lib/ChipTest.py delete mode 100644 src/test_driver/happy/lib/ChipUtilities.py delete mode 120000 src/test_driver/happy/lib/set_test_path.py delete mode 100644 src/test_driver/happy/test-templates/ChipInetMulticast.py delete mode 100644 src/test_driver/happy/tests/standalone/inet/BUILD.gn delete mode 120000 src/test_driver/happy/tests/standalone/inet/set_test_path.py delete mode 100644 src/test_driver/happy/tests/standalone/inet/test_inet_multicast_five_nodes_on_wifi.py delete mode 100644 src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.json delete mode 100755 src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.sh delete mode 100644 third_party/happy/BUILD.gn delete mode 160000 third_party/happy/repo diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index 67b5439c51e1a7..2ba8094c51bff8 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -40,7 +40,6 @@ jobs: image: connectedhomeip/chip-build:0.5.28 volumes: - "/tmp/log_output:/tmp/test_logs" - - "/tmp/happy_test_logs:/tmp/happy_test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -52,10 +51,7 @@ jobs: - name: Bootstrap timeout-minutes: 10 run: | - mkdir -p /tmp/happy_test_logs ; mkdir -p /tmp/log_output ; - scripts/tests/happy_tests.sh install_packages ; - scripts/tests/happy_tests.sh bootstrap ; scripts/build/gn_bootstrap.sh ; - name: Uploading bootstrap logs uses: actions/upload-artifact@v2 @@ -82,20 +78,13 @@ jobs: *) ;; esac - scripts/build/gn_gen.sh --args="$GN_ARGS chip_enable_happy_tests=true" + scripts/build/gn_gen.sh --args="$GN_ARGS" - name: Run Build timeout-minutes: 8 run: scripts/run_in_build_env.sh "ninja -C out/$BUILD_TYPE" - name: Run Tests timeout-minutes: 15 - run: RUN_HAPPY_TESTS=1 scripts/tests/gn_tests.sh - - name: Uploading Happy Test Log - uses: actions/upload-artifact@v2 - if: ${{ always() }} && ${{ !env.ACT }} - with: - name: - happy_log-${{ steps.outsuffix.outputs.value }}-${{ matrix.type }} - path: /tmp/happy_test_logs/ + run: scripts/tests/gn_tests.sh # TODO Log Upload https://github.com/project-chip/connectedhomeip/issues/2227 # TODO https://github.com/project-chip/connectedhomeip/issues/1512 # - name: Run Code Coverage diff --git a/.gitmodules b/.gitmodules index bee8a7489182fa..85e0f84d9a05ce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -46,10 +46,6 @@ path = third_party/cirque/repo url = https://github.com/openweave/cirque.git branch = master -[submodule "happy"] - path = third_party/happy/repo - url = https://github.com/openweave/happy.git - branch = master [submodule "nanopb"] path = third_party/nanopb/repo url = https://github.com/nanopb/nanopb.git diff --git a/BUILD.gn b/BUILD.gn index ea34c93a7ed710..fb27e5768c16c5 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -57,7 +57,6 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { "$dir_pw_watch/py", "integrations/mobly:chip_mobly", "scripts:requirements", - "third_party/happy", ] } @@ -163,15 +162,6 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { ] } } - - # We don't always want to run happy tests, make them a seperate group. - if (chip_enable_happy_tests) { - group("happy_tests") { - if (chip_link_tests) { - deps = [ "//src:happy_tests" ] - } - } - } } else { # This is the unified build. Configure various real toolchains. import("${chip_root}/build/chip/chip_build.gni") diff --git a/build/chip/happy_test.gni b/build/chip/happy_test.gni deleted file mode 100644 index 18392e9f9b9803..00000000000000 --- a/build/chip/happy_test.gni +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/build.gni") -import("//build_overrides/chip.gni") - -import("${chip_root}/build/chip/tests.gni") - -assert(chip_build_tests) -assert(chip_enable_happy_tests) - -template("happy_test") { - _suite_name = target_name - _deps = invoker.deps - _test_output_dir = "${root_out_dir}/tests" - - _tests = [] - if (defined(invoker.tests)) { - foreach(_test, invoker.tests) { - action("${_test}_test") { - script = rebase_path("${chip_root}/scripts/tests/happy_test_wrapper.py") - data_deps = _deps - inputs = [ "${_test}.py" ] - outputs = [ "${_test_output_dir}/${_test}.testout" ] - - # GN will run python under virtual env, which will cause test failed to run - args = [ - "--ci=True", - "--silent=True", - "--test-bin-dir", - rebase_path("${_test_output_dir}"), - rebase_path("${_test}.py"), - ] - } - - _tests += [ ":${_test}_test" ] - } - } - - group("${_suite_name}") { - deps = _tests - } -} diff --git a/build/chip/tests.gni b/build/chip/tests.gni index 9d4089874027e9..70218c49728ed8 100644 --- a/build/chip/tests.gni +++ b/build/chip/tests.gni @@ -20,9 +20,6 @@ import("${chip_root}/src/platform/device.gni") declare_args() { # Enable building tests. chip_build_tests = current_os != "freertos" - - # Enable happy tests. - chip_enable_happy_tests = false } declare_args() { diff --git a/scripts/tests/gn_tests.sh b/scripts/tests/gn_tests.sh index 99b9a8913a0fd2..13eae351bfb55a 100755 --- a/scripts/tests/gn_tests.sh +++ b/scripts/tests/gn_tests.sh @@ -36,7 +36,3 @@ env set -x ninja -v -C "$CHIP_ROOT/out/$BUILD_TYPE" -k 0 check - -if [ "x$RUN_HAPPY_TESTS" == "x1" ]; then - ninja -v -C "$CHIP_ROOT/out/$BUILD_TYPE" -k 0 happy_tests -fi diff --git a/scripts/tests/happy_test_wrapper.py b/scripts/tests/happy_test_wrapper.py deleted file mode 100755 index d3542a0c7c0b2c..00000000000000 --- a/scripts/tests/happy_test_wrapper.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2020 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. - -# This is a wrapper for running happy tests. - -import argparse -import os -import subprocess -import sys -import tempfile - -CHIP_PATH = os.path.realpath(os.path.join( - os.path.dirname(__file__), "../..")) -HAPPY_TEST_PATH = os.path.join(CHIP_PATH, "src/test_driver/happy/tests") - -test_environ = os.environ.copy() - -parser = argparse.ArgumentParser(description='Warpper to run happy tests') -parser.add_argument('test_script', type=str, - help='The name of test') -parser.add_argument('--test-bin-dir', dest='bin_dir', type=str, nargs='?', default='.', - help='The path of test binaries') -parser.add_argument('--ci', dest='ci', type=bool, nargs='?', default=False, - help='Set this if running script under venv but happy is installed globally') -parser.add_argument('--silent', dest='silent', type=bool, nargs='?', default=False, - help='Set this will mute output when the test finished successfully') - -if __name__ == '__main__': - if os.getuid() != 0: - os.execvpe("unshare", ["unshare", "--map-root-user", - "-n", "-m", "python3"] + sys.argv, test_environ) - print("Failed to run script in new user namespace", file=sys.stderr) - exit(1) - if os.system("mount --make-private /") != 0 or os.system("mount -t tmpfs tmpfs /run") != 0: - print("Failed to setup private mount points", file=sys.stderr) - exit(1) - args = parser.parse_args() - # GN will run Python in venv, which will break happy test - if args.ci: - test_environ["HAPPY_LOG_DIR"] = "/tmp/happy_test_logs" - test_environ["TEST_BIN_DIR"] = args.bin_dir - test_environ["HAPPY_MAIN_CONFIG_FILE"] = os.path.realpath( - os.path.join(CHIP_PATH, "src/test_driver/happy/conf/main_conf.json")) - if args.silent: - fp, fname = tempfile.mkstemp() - run_res = subprocess.run(["python3", args.test_script], - stdout=fp, stderr=fp, env=test_environ) - if run_res.returncode != 0: - with open(fname, 'rb') as test_output: - os.write(sys.stderr.fileno(), test_output.read()) - exit(run_res.returncode) - else: - os.execvpe("python3", ["python3", args.test_script], test_environ) diff --git a/scripts/tests/happy_tests.sh b/scripts/tests/happy_tests.sh deleted file mode 100755 index 283515cb17d7c3..00000000000000 --- a/scripts/tests/happy_tests.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash - -# -# Copyright (c) 2020 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. -# - -# This file is used to test a single happy test using (almost) the same -# method as ninja does. Suggest passing $HAPPY_LOG_DIR to set path for logs. - -SOURCE="${BASH_SOURCE[0]}" -SOURCE_DIR="$(cd "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)" -REPO_DIR="$SOURCE_DIR/../../" - -export HAPPY_LOG_DIR="${HAPPY_LOG_DIR:-$(mktemp -d)}" - -set -x -env - -function happytest_install_packages() { - if [ "$(whoami)" != "root" ]; then - echo "install_packages should be invoked under root" - return 1 - fi - echo "Install packages: avahi-daemon bridge-utils iproute2 net-tools python3-lockfile python3-pip python3-psutil python3-setuptools strace" - apt-get update && apt-get install -y avahi-daemon \ - bridge-utils \ - iproute2 \ - net-tools \ - python3-lockfile \ - python3-pip \ - python3-psutil \ - python3-setuptools \ - strace -} - -function happytest_bootstrap() { - echo "Bootstrapping Happy Test" - set -e - service dbus start - service avahi-daemon start - # Bootstrap Happy - cd "$REPO_DIR/third_party/happy/repo" - - python3 setup.py install --user -} - -function happytest_run() { - "$REPO_DIR/scripts/tests/happy_test_wrapper.py" --test-bin-dir "$REPO_DIR/out/$BUILD_TYPE/tests" "$1" -} - -subcommand="$1" -shift - -case $subcommand in - *) - happytest_"$subcommand" "$@" - ;; -esac diff --git a/src/BUILD.gn b/src/BUILD.gn index 7fc30141f8018b..bdc11442fc672e 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -125,14 +125,6 @@ if (chip_build_tests) { } } - if (chip_enable_happy_tests) { - group("happy_tests") { - deps = [ - "${chip_root}/src/test_driver/happy/tests/standalone/inet:inet_tests", - ] - } - } - chip_test_group("fake_platform_tests") { deps = [ "${chip_root}/src/lib/dnssd/platform/tests" ] } diff --git a/src/inet/tests/BUILD.gn b/src/inet/tests/BUILD.gn index dc78d690da115e..5c1ad61f70711c 100644 --- a/src/inet/tests/BUILD.gn +++ b/src/inet/tests/BUILD.gn @@ -86,23 +86,3 @@ chip_test_suite("tests") { sources += [ "TestLwIPDNS.cpp" ] } } - -if (chip_enable_happy_tests) { - # The following binaries should be executed by happy. - chip_test_suite("happy_tests") { - output_name = "libHappyTestInetCommon" - - sources = [ "TestInetLayerMulticast.cpp" ] - - public_configs = [ ":tests_config" ] - - public_deps = [ - ":tests_lib", - "${chip_root}/src/inet", - "${chip_root}/src/lib/core", - "${nlunit_test_root}:nlunit-test", - ] - - tests = [ "TestInetLayerMulticast" ] - } -} diff --git a/src/inet/tests/TestInetLayerMulticast.cpp b/src/inet/tests/TestInetLayerMulticast.cpp deleted file mode 100644 index cbde782f5b4a7f..00000000000000 --- a/src/inet/tests/TestInetLayerMulticast.cpp +++ /dev/null @@ -1,842 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2018-2019 Google LLC - * All rights reserved. - * - * 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. - */ - -/** - * @file - * This file implements a process to effect a functional test for - * the InetLayer Internet Protocol stack abstraction interfaces - * for handling IP (v4 or v6) multicast on UDP endpoints. - * - */ - -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS -#endif - -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include - -#include "TestInetCommon.h" -#include "TestInetCommonOptions.h" -#include "TestInetLayerCommon.hpp" -#include "TestSetupFaultInjection.h" -#include "TestSetupSignalling.h" - -using namespace chip; -using namespace chip::ArgParser; -using namespace chip::Inet; -using namespace chip::System; - -/* Preprocessor Macros */ - -#define kToolName "TestInetLayerMulticast" - -#define kToolOptNoLoopback 'L' -#define kToolOptGroup 'g' - -#define kToolOptExpectedGroupRxPackets (kToolOptBase + 0) -#define kToolOptExpectedGroupTxPackets (kToolOptBase + 1) - -/* Type Definitions */ - -enum OptFlags -{ - kOptFlagNoLoopback = 0x00010000 -}; - -struct GroupAddress -{ - uint32_t mGroup; - TransferStats mStats; - IPAddress mMulticastAddress; -}; - -template -struct GroupAddresses -{ - size_t mSize; - const size_t mCapacity = tCapacity; - GroupAddress mAddresses[tCapacity]; -}; - -template -struct TestState -{ - GroupAddresses & mGroupAddresses; - TestStatus mStatus; -}; - -/* Function Declarations */ - -static void HandleSignal(int aSignal); -static bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue); -static bool HandleNonOptionArgs(const char * aProgram, int argc, char * argv[]); -static bool ParseGroupOpt(const char * aProgram, const char * aValue, bool aIPv6, uint32_t & aOutLastGroupIndex); -static bool ParseAndUpdateExpectedGroupPackets(const char * aProgram, const char * aValue, uint32_t aGroup, - const char * aDescription, uint32_t & aOutExpected); - -static void StartTest(); -static void CleanupTest(); - -/* Global Variables */ - -// clang-format off -static const uint32_t kOptFlagsDefault = (kOptFlagUseIPv6 | kOptFlagUseUDPIP); - -static UDPEndPoint * sUDPIPEndPoint = nullptr; - -static GroupAddresses<4> sGroupAddresses; - -static TestState<4> sTestState = -{ - sGroupAddresses, - { false, false } -}; - -static uint32_t sLastGroupIndex = 0; - -static OptionDef sToolOptionDefs[] = -{ - { "interface", kArgumentRequired, kToolOptInterface }, - { "group", kArgumentRequired, kToolOptGroup }, - { "group-expected-rx-packets", kArgumentRequired, kToolOptExpectedGroupRxPackets }, - { "group-expected-tx-packets", kArgumentRequired, kToolOptExpectedGroupTxPackets }, - { "interval", kArgumentRequired, kToolOptInterval }, -#if INET_CONFIG_ENABLE_IPV4 - { "ipv4", kNoArgument, kToolOptIPv4Only }, -#endif // INET_CONFIG_ENABLE_IPV4 - { "ipv6", kNoArgument, kToolOptIPv6Only }, - { "listen", kNoArgument, kToolOptListen }, - { "no-loopback", kNoArgument, kToolOptNoLoopback }, - { "send-size", kArgumentRequired, kToolOptSendSize }, - { "udp", kNoArgument, kToolOptUDPIP }, - { } -}; - -static const char * sToolOptionHelp = - " -I, --interface \n" - " The network interface to bind to and from which to send and receive all packets.\n" - "\n" - " -L, --no-loopback\n" - " Suppress the loopback of multicast packets.\n" - "\n" - " -g, --group \n" - " Multicast group number to join.\n" - "\n" - " --group-expected-rx-packets \n" - " Expect to receive this number of packets for the previously-specified multicast group.\n" - "\n" - " --group-expected-tx-packets \n" - " Expect to send this number of packets for the previously-specified multicast group.\n" - "\n" - " -i, --interval \n" - " Wait interval milliseconds between sending each packet (default: 1000 ms).\n" - "\n" - " -l, --listen\n" - " Act as a server (i.e., listen) for packets rather than send them.\n" - "\n" -#if INET_CONFIG_ENABLE_IPV4 - " -4, --ipv4\n" - " Use IPv4 only.\n" - "\n" -#endif // INET_CONFIG_ENABLE_IPV4 - " -6, --ipv6\n" - " Use IPv6 only (default).\n" - "\n" - " -s, --send-size \n" - " Send size bytes of user data (default: 59 bytes)\n" - "\n" - " -u, --udp\n" - " Use UDP over IP.\n" - "\n"; - -static OptionSet sToolOptions = -{ - HandleOption, - sToolOptionDefs, - "GENERAL OPTIONS", - sToolOptionHelp -}; - -static HelpOptions sHelpOptions( - kToolName, - "Usage: " kToolName " [ ] [ -g [ ... ] -I ]\n", - CHIP_VERSION_STRING "\n" CHIP_TOOL_COPYRIGHT -); - -static OptionSet * sToolOptionSets[] = -{ - &sToolOptions, - &gNetworkOptions, - &gFaultInjectionOptions, - &sHelpOptions, - nullptr -}; -// clang-format on - -static void CheckSucceededOrFailed(const GroupAddress & aAddress, bool & aOutSucceeded, bool & aOutFailed) -{ - const TransferStats & lStats = aAddress.mStats; - -#if DEBUG - printf("Group %u: %u/%u sent, %u/%u received\n", aAddress.mGroup, lStats.mTransmit.mActual, lStats.mTransmit.mExpected, - lStats.mReceive.mActual, lStats.mReceive.mExpected); -#endif - - if (((lStats.mTransmit.mExpected > 0) && (lStats.mTransmit.mActual > lStats.mTransmit.mExpected)) || - ((lStats.mReceive.mExpected > 0) && (lStats.mReceive.mActual > lStats.mReceive.mExpected))) - { - aOutFailed = true; - } - else if (((lStats.mTransmit.mExpected > 0) && (lStats.mTransmit.mActual < lStats.mTransmit.mExpected)) || - ((lStats.mReceive.mExpected > 0) && (lStats.mReceive.mActual < lStats.mReceive.mExpected))) - { - aOutSucceeded = false; - } -} - -template -static void CheckSucceededOrFailed(TestState & aTestState, bool & aOutSucceeded, bool & aOutFailed) -{ - for (size_t i = 0; i < aTestState.mGroupAddresses.mSize; i++) - { - const GroupAddress & lGroup = aTestState.mGroupAddresses.mAddresses[i]; - - CheckSucceededOrFailed(lGroup, aOutSucceeded, aOutFailed); - } - - if (aOutSucceeded || aOutFailed) - { - if (aOutSucceeded) - aTestState.mStatus.mSucceeded = true; - - if (aOutFailed) - SetStatusFailed(aTestState.mStatus); - } -} - -static void HandleSignal(int aSignal) -{ - switch (aSignal) - { - - case SIGUSR1: - SetStatusFailed(sTestState.mStatus); - break; - } -} - -namespace TestInetLayerMulticast { -int main(int argc, char * argv[]) -{ - bool lSuccessful = true; - CHIP_ERROR lStatus; - - InitTestInetCommon(); - - SetupFaultInjectionContext(argc, argv); - - SetSignalHandler(HandleSignal); - - if (argc == 1) - { - sHelpOptions.PrintBriefUsage(stderr); - lSuccessful = false; - goto exit; - } - - if (!ParseArgsFromEnvVar(kToolName, TOOL_OPTIONS_ENV_VAR_NAME, sToolOptionSets, nullptr, true) || - !ParseArgs(kToolName, argc, argv, sToolOptionSets, HandleNonOptionArgs)) - { - lSuccessful = false; - goto exit; - } - - InitSystemLayer(); - - InitNetwork(); - - // At this point, we should have valid network interfaces, - // including LwIP TUN/TAP shim interfaces. Validate the - // -I/--interface argument, if present. - - if (gInterfaceName != nullptr) - { - lStatus = InterfaceId::InterfaceNameToId(gInterfaceName, gInterfaceId); - if (lStatus != CHIP_NO_ERROR) - { - PrintArgError("%s: unknown network interface %s\n", kToolName, gInterfaceName); - lSuccessful = false; - goto shutdown; - } - } - - // If any multicast groups have been specified, ensure that a - // network interface identifier has been specified and is valid. - - if ((sGroupAddresses.mSize > 0) && !gInterfaceId.IsPresent()) - { - PrintArgError("%s: a network interface is required when specifying one or more multicast groups\n", kToolName); - lSuccessful = false; - goto shutdown; - } - - StartTest(); - - while (Common::IsTesting(sTestState.mStatus)) - { - bool lSucceeded = true; - bool lFailed = false; - - constexpr uint32_t kSleepTimeMilliseconds = 10; - ServiceNetwork(kSleepTimeMilliseconds); - - CheckSucceededOrFailed(sTestState, lSucceeded, lFailed); - -#if DEBUG - printf("%s %s number of expected packets\n", ((lSucceeded) ? "successfully" : ((lFailed) ? "failed to" : "has not yet")), - ((lSucceeded) - ? (Common::IsReceiver() ? "received" : "sent") - : ((lFailed) ? (Common::IsReceiver() ? "receive" : "send") : Common::IsReceiver() ? "received" : "sent"))); -#endif - } - - CleanupTest(); - -shutdown: - ShutdownNetwork(); - ShutdownSystemLayer(); - - lSuccessful = Common::WasSuccessful(sTestState.mStatus); - -exit: - return (lSuccessful ? EXIT_SUCCESS : EXIT_FAILURE); -} -} // namespace TestInetLayerMulticast - -static bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue) -{ - bool retval = true; - - switch (aIdentifier) - { - - case kToolOptInterval: - if (!ParseInt(aValue, gSendIntervalMs)) - { - PrintArgError("%s: invalid value specified for send interval: %s\n", aProgram, aValue); - retval = false; - } - break; - - case kToolOptListen: - gOptFlags |= kOptFlagListen; - break; - - case kToolOptNoLoopback: - gOptFlags |= kOptFlagNoLoopback; - break; - - case kToolOptGroup: - if (!ParseGroupOpt(aProgram, aValue, gOptFlags & kOptFlagUseIPv6, sLastGroupIndex)) - { - retval = false; - } - break; - - case kToolOptExpectedGroupRxPackets: { - GroupAddress & lGroupAddress = sGroupAddresses.mAddresses[sLastGroupIndex]; - - if (!ParseAndUpdateExpectedGroupPackets(aProgram, aValue, lGroupAddress.mGroup, "received", - lGroupAddress.mStats.mReceive.mExpected)) - { - retval = false; - } - } - break; - - case kToolOptExpectedGroupTxPackets: { - GroupAddress & lGroupAddress = sGroupAddresses.mAddresses[sLastGroupIndex]; - - if (!ParseAndUpdateExpectedGroupPackets(aProgram, aValue, lGroupAddress.mGroup, "sent", - lGroupAddress.mStats.mTransmit.mExpected)) - { - retval = false; - } - } - break; - -#if INET_CONFIG_ENABLE_IPV4 - case kToolOptIPv4Only: - if (gOptFlags & kOptFlagUseIPv6) - { - PrintArgError("%s: the use of --ipv4 is exclusive with --ipv6. Please select only one of the two options.\n", aProgram); - retval = false; - } - gOptFlags |= kOptFlagUseIPv4; - break; -#endif // INET_CONFIG_ENABLE_IPV4 - - case kToolOptIPv6Only: - if (gOptFlags & kOptFlagUseIPv4) - { - PrintArgError("%s: the use of --ipv6 is exclusive with --ipv4. Please select only one of the two options.\n", aProgram); - retval = false; - } - gOptFlags |= kOptFlagUseIPv6; - break; - - case kToolOptInterface: - - // NOTE: When using LwIP on a hosted OS, the interface will - // not actually be available until AFTER InitNetwork, - // consequently, we cannot do any meaningful validation - // here. Simply save the value off and we will validate it - // later. - - gInterfaceName = aValue; - break; - - case kToolOptSendSize: - if (!ParseInt(aValue, gSendSize)) - { - PrintArgError("%s: invalid value specified for send size: %s\n", aProgram, aValue); - return false; - } - break; - - case kToolOptUDPIP: - gOptFlags |= kOptFlagUseUDPIP; - break; - - default: - PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName); - retval = false; - break; - } - - return (retval); -} - -bool HandleNonOptionArgs(const char * aProgram, int argc, char * argv[]) -{ - if ((gOptFlags & (kOptFlagListen | kOptFlagNoLoopback)) == (kOptFlagListen | kOptFlagNoLoopback)) - { - PrintArgError("%s: the listen option is exclusive with the loopback suppression option. Please select one or the other.\n", - aProgram); - return false; - } - - // If there were any additional, non-parsed arguments, it's an error. - - if (argc > 0) - { - PrintArgError("%s: unexpected argument: %s\n", aProgram, argv[0]); - return false; - } - - // If no IP version or transport flags were specified, use the defaults. - - if (!(gOptFlags & (kOptFlagUseIPv4 | kOptFlagUseIPv6 | kOptFlagUseUDPIP))) - { - gOptFlags |= kOptFlagsDefault; - } - - return true; -} - -// Create an IPv4 administratively-scoped multicast address - -static IPAddress MakeIPv4Multicast(uint32_t aGroupIdentifier) -{ - IPAddress lAddress; - - lAddress.Addr[0] = 0; - lAddress.Addr[1] = 0; - lAddress.Addr[2] = nlByteOrderSwap32HostToBig(0xFFFF); - lAddress.Addr[3] = nlByteOrderSwap32HostToBig((239 << 24) | (aGroupIdentifier & 0xFFFFFF)); - - return (lAddress); -} - -// Create an IPv6 site-scoped multicast address - -static IPAddress MakeIPv6Multicast(uint32_t aGroupIdentifier) -{ - return (IPAddress::MakeIPv6Multicast(IPv6MulticastFlag::kTransient, kIPv6MulticastScope_Site, aGroupIdentifier)); -} - -static void SetGroup(GroupAddress & aGroupAddress, uint32_t aGroupIdentifier, uint32_t aExpectedRx, uint32_t aExpectedTx) -{ - aGroupAddress.mGroup = aGroupIdentifier; - aGroupAddress.mStats.mReceive.mExpected = aExpectedRx; - aGroupAddress.mStats.mReceive.mActual = 0; - aGroupAddress.mStats.mTransmit.mExpected = aExpectedTx; - aGroupAddress.mStats.mTransmit.mActual = 0; -} - -static bool ParseGroupOpt(const char * aProgram, const char * aValue, bool aIPv6, uint32_t & aOutLastGroupIndex) -{ - uint32_t lGroupIdentifier; - - if (sGroupAddresses.mSize == sGroupAddresses.mCapacity) - { - PrintArgError("%s: the maximum number of allowed groups (%zu) have been specified\n", aProgram, sGroupAddresses.mCapacity); - return false; - } - - if (!ParseInt(aValue, lGroupIdentifier)) - { - PrintArgError("%s: unrecognized group %s\n", aProgram, aValue); - return false; - } - - aOutLastGroupIndex = sGroupAddresses.mSize++; - - SetGroup(sGroupAddresses.mAddresses[aOutLastGroupIndex], lGroupIdentifier, lGroupIdentifier, lGroupIdentifier); - - return true; -} - -static bool ParseAndUpdateExpectedGroupPackets(const char * aProgram, const char * aValue, uint32_t aGroup, - const char * aDescription, uint32_t & aOutExpected) -{ - uint32_t lExpectedGroupPackets; - - if (!ParseInt(aValue, lExpectedGroupPackets)) - { - PrintArgError("%s: invalid value specified for expected group %u %s packets: %s\n", aProgram, aGroup, aDescription, aValue); - return false; - } - - aOutExpected = lExpectedGroupPackets; - - return true; -} - -static GroupAddress * FindGroupAddress(const IPAddress & aSourceAddress) -{ - GroupAddress * lResult = nullptr; - - for (size_t i = 0; i < sGroupAddresses.mSize; i++) - { - GroupAddress & lGroupAddress = sGroupAddresses.mAddresses[i]; - - if (lGroupAddress.mMulticastAddress == aSourceAddress) - { - lResult = &lGroupAddress; - break; - } - } - - return (lResult); -} - -static void PrintReceivedStats(const GroupAddress & aGroupAddress) -{ - printf("%u/%u received for multicast group %u\n", aGroupAddress.mStats.mReceive.mActual, - aGroupAddress.mStats.mReceive.mExpected, aGroupAddress.mGroup); -} - -static bool HandleDataReceived(const PacketBufferHandle & aBuffer, GroupAddress & aGroupAddress, bool aCheckBuffer) -{ - constexpr bool lStatsByPacket = true; - if (!Common::HandleDataReceived(aBuffer, aGroupAddress.mStats, lStatsByPacket, aCheckBuffer)) - { - return false; - } - - PrintReceivedStats(aGroupAddress); - - return true; -} - -static bool HandleDataReceived(const PacketBufferHandle & aBuffer, const IPPacketInfo & aPacketInfo, bool aCheckBuffer) -{ - GroupAddress * const lGroupAddress = FindGroupAddress(aPacketInfo.DestAddress); - if (lGroupAddress != nullptr) - { - return HandleDataReceived(aBuffer, *lGroupAddress, aCheckBuffer); - } - return true; -} - -// UDP Endpoint Callbacks - -static void HandleUDPMessageReceived(UDPEndPoint * aEndPoint, PacketBufferHandle && aBuffer, const IPPacketInfo * aPacketInfo) -{ - const bool lCheckBuffer = true; - bool lStatus; - - VerifyOrExit(aEndPoint != nullptr, lStatus = false); - VerifyOrExit(!aBuffer.IsNull(), lStatus = false); - VerifyOrExit(aPacketInfo != nullptr, lStatus = false); - - Common::HandleUDPMessageReceived(aEndPoint, aBuffer, aPacketInfo); - - lStatus = HandleDataReceived(std::move(aBuffer), *aPacketInfo, lCheckBuffer); - -exit: - if (!lStatus) - { - SetStatusFailed(sTestState.mStatus); - } -} - -static void HandleUDPReceiveError(UDPEndPoint * aEndPoint, CHIP_ERROR aError, const IPPacketInfo * aPacketInfo) -{ - Common::HandleUDPReceiveError(aEndPoint, aError, aPacketInfo); - - SetStatusFailed(sTestState.mStatus); -} - -static bool IsTransportReadyForSend() -{ - bool lStatus = false; - - if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) - { - lStatus = (sUDPIPEndPoint != nullptr); - } - - return (lStatus); -} - -static CHIP_ERROR PrepareTransportForSend() -{ - CHIP_ERROR lStatus = CHIP_NO_ERROR; - - return (lStatus); -} - -static CHIP_ERROR DriveSendForDestination(const IPAddress & aAddress, uint16_t aSize) -{ - PacketBufferHandle lBuffer; - - if ((gOptFlags & kOptFlagUseUDPIP) == kOptFlagUseUDPIP) - { - const uint8_t lFirstValue = 0; - - // For UDP, we'll send n aSize or smaller datagrams, each - // patterned from zero to aSize - 1. - - lBuffer = Common::MakeDataBuffer(aSize, lFirstValue); - VerifyOrReturnError(!lBuffer.IsNull(), CHIP_ERROR_NO_MEMORY); - - return sUDPIPEndPoint->SendTo(aAddress, kUDPPort, std::move(lBuffer)); - } - - return CHIP_NO_ERROR; -} - -static CHIP_ERROR DriveSendForGroup(GroupAddress & aGroupAddress) -{ - if (aGroupAddress.mStats.mTransmit.mActual < aGroupAddress.mStats.mTransmit.mExpected) - { - ReturnErrorOnFailure(DriveSendForDestination(aGroupAddress.mMulticastAddress, gSendSize)); - - aGroupAddress.mStats.mTransmit.mActual++; - - printf("%u/%u transmitted for multicast group %u\n", aGroupAddress.mStats.mTransmit.mActual, - aGroupAddress.mStats.mTransmit.mExpected, aGroupAddress.mGroup); - } - - return CHIP_NO_ERROR; -} - -template -static CHIP_ERROR DriveSendForGroups(GroupAddresses & aGroupAddresses) -{ - // Iterate over each multicast group for which this node is a - // member and send a packet. - for (size_t i = 0; i < aGroupAddresses.mSize; i++) - { - ReturnErrorOnFailure(DriveSendForGroup(aGroupAddresses.mAddresses[i])); - } - - return CHIP_NO_ERROR; -} - -void DriveSend() -{ - CHIP_ERROR lStatus = CHIP_NO_ERROR; - - if (!Common::IsSender()) - goto exit; - - if (!gSendIntervalExpired) - goto exit; - - if (!IsTransportReadyForSend()) - { - lStatus = PrepareTransportForSend(); - SuccessOrExit(lStatus); - } - else - { - gSendIntervalExpired = false; - gSystemLayer.StartTimer(System::Clock::Milliseconds32(gSendIntervalMs), Common::HandleSendTimerComplete, nullptr); - - lStatus = DriveSendForGroups(sGroupAddresses); - SuccessOrExit(lStatus); - } - -exit: - if (lStatus != CHIP_NO_ERROR) - { - SetStatusFailed(sTestState.mStatus); - } -} - -static void StartTest() -{ - IPAddressType lIPAddressType = IPAddressType::kIPv6; - IPVersion lIPVersion = kIPVersion_6; - IPAddress lAddress = IPAddress::Any; - UDPEndPoint * lEndPoint = nullptr; - const bool lUseLoopback = ((gOptFlags & kOptFlagNoLoopback) == 0); - CHIP_ERROR lStatus; - -#if INET_CONFIG_ENABLE_IPV4 - if (gOptFlags & kOptFlagUseIPv4) - { - lIPAddressType = IPAddressType::kIPv4; - lIPVersion = kIPVersion_4; - } -#endif // INET_CONFIG_ENABLE_IPV4 - - // clang-format off - printf("Using %sIP%s, device interface: %s (w/%c LwIP)\n", - "UDP/", - ((gOptFlags & kOptFlagUseIPv4) ? "v4" : "v6"), - ((gInterfaceName) ? gInterfaceName : ""), - (CHIP_SYSTEM_CONFIG_USE_LWIP ? '\0' : 'o')); - // clang-format ob - - // Allocate the endpoints for sending or receiving. - - if (gOptFlags & kOptFlagUseUDPIP) - { - lStatus = gInet.NewUDPEndPoint(&sUDPIPEndPoint); - INET_FAIL_ERROR(lStatus, "InetLayer::NewUDPEndPoint failed"); - - lStatus = sUDPIPEndPoint->Bind(lIPAddressType, lAddress, kUDPPort); - INET_FAIL_ERROR(lStatus, "UDPEndPoint::Bind failed"); - - if (gInterfaceId.IsPresent()) - { - lStatus = sUDPIPEndPoint->BindInterface(lIPAddressType, gInterfaceId); - INET_FAIL_ERROR(lStatus, "UDPEndPoint::BindInterface failed"); - } - - lStatus = sUDPIPEndPoint->Listen(HandleUDPMessageReceived, HandleUDPReceiveError); - INET_FAIL_ERROR(lStatus, "UDPEndPoint::Listen failed"); - - lEndPoint = sUDPIPEndPoint; - } - - // If loopback suppression has been requested, attempt to disable - // it; otherwise, attempt to enable it. - - lStatus = lEndPoint->SetMulticastLoopback(lIPVersion, lUseLoopback); - INET_FAIL_ERROR(lStatus, "SetMulticastLoopback failed"); - - // Configure and join the multicast groups - - for (size_t i = 0; i < sGroupAddresses.mSize; i++) - { - char lAddressBuffer[INET6_ADDRSTRLEN]; - GroupAddress & lGroupAddress = sGroupAddresses.mAddresses[i]; - IPAddress & lMulticastAddress = lGroupAddress.mMulticastAddress; - - if ((lEndPoint != nullptr) && gInterfaceId.IsPresent()) - { - if (gOptFlags & kOptFlagUseIPv4) - { - lMulticastAddress = MakeIPv4Multicast(lGroupAddress.mGroup); - } - else - { - lMulticastAddress = MakeIPv6Multicast(lGroupAddress.mGroup); - } - - lMulticastAddress.ToString(lAddressBuffer, sizeof(lAddressBuffer)); - - printf("Will join multicast group %s\n", lAddressBuffer); - - lStatus = lEndPoint->JoinMulticastGroup(gInterfaceId, lMulticastAddress); - INET_FAIL_ERROR(lStatus, "Could not join multicast group"); - } - } - - if (Common::IsReceiver()) - printf("Listening...\n"); - else - DriveSend(); -} - -static void CleanupTest() -{ - UDPEndPoint * lEndPoint = nullptr; - CHIP_ERROR lStatus; - - gSendIntervalExpired = false; - gSystemLayer.CancelTimer(Common::HandleSendTimerComplete, nullptr); - - // Leave the multicast groups - - if (gOptFlags & kOptFlagUseUDPIP) - { - lEndPoint = sUDPIPEndPoint; - } - - for (size_t i = 0; i < sGroupAddresses.mSize; i++) - { - char lAddressBuffer[INET6_ADDRSTRLEN]; - GroupAddress & lGroupAddress = sGroupAddresses.mAddresses[i]; - IPAddress & lMulticastAddress = lGroupAddress.mMulticastAddress; - - if ((lEndPoint != nullptr) && gInterfaceId.IsPresent()) - { - lMulticastAddress.ToString(lAddressBuffer, sizeof(lAddressBuffer)); - - printf("Will leave multicast group %s\n", lAddressBuffer); - - lStatus = lEndPoint->LeaveMulticastGroup(gInterfaceId, lMulticastAddress); - INET_FAIL_ERROR(lStatus, "Could not leave multicast group"); - } - } - - // Release the resources associated with the allocated end points. - - if (sUDPIPEndPoint != nullptr) - { - sUDPIPEndPoint->Free(); - } -} diff --git a/src/inet/tests/TestInetLayerMulticastDriver.cpp b/src/inet/tests/TestInetLayerMulticastDriver.cpp deleted file mode 100644 index 46494276ded537..00000000000000 --- a/src/inet/tests/TestInetLayerMulticastDriver.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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. - */ - -/** - * @file - * TestInetLayerMulticast has its own main function, so we do not need - * a seperate driver. This file is left blank intendedly. - * - */ - -namespace TestInetLayerMulticast { -int main(int argc, char * argv[]); -} - -int main(int argc, char * argv[]) -{ - return TestInetLayerMulticast::main(argc, argv); -} diff --git a/src/platform/tests/BUILD.gn b/src/platform/tests/BUILD.gn index f56ea9ce816700..64c1925b22daff 100644 --- a/src/platform/tests/BUILD.gn +++ b/src/platform/tests/BUILD.gn @@ -18,6 +18,12 @@ import("//build_overrides/nlunit_test.gni") import("${chip_root}/src/platform/device.gni") +declare_args() { + # Platform DNSsd should always be running on darwin. On Linux + # this depends on avahi being available and running. + chip_enable_dnssd_tests = chip_device_platform == "darwin" +} + if (chip_device_platform != "none" && chip_device_platform != "fake") { import("${chip_root}/build/chip/chip_test_suite.gni") @@ -39,7 +45,7 @@ if (chip_device_platform != "none" && chip_device_platform != "fake") { "${nlunit_test_root}:nlunit-test", ] - if (chip_mdns != "none" && chip_enable_happy_tests && + if (chip_mdns != "none" && chip_enable_dnssd_tests && (chip_device_platform == "linux" || chip_device_platform == "darwin")) { test_sources += [ "TestDnssd.cpp" ] public_deps += [ "${chip_root}/src/lib/dnssd" ] diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 32c35610abe3ec..2b52b3a1297aec 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -23,6 +23,5 @@ efr32_sdk_target = get_label_info(":sdk", "label_no_toolchain") chip_enable_pw_rpc = true cpp_standard = "gnu++17" chip_build_tests = true -chip_enable_happy_tests = false chip_enable_openthread = true chip_monolithic_tests = true diff --git a/src/test_driver/happy/README.md b/src/test_driver/happy/README.md deleted file mode 100644 index 6ed3eef1a67e64..00000000000000 --- a/src/test_driver/happy/README.md +++ /dev/null @@ -1,46 +0,0 @@ -## Happy Tests - -> Happy simulates complex network topologies. On a single Linux machine, Happy -> can create multiple nodes with network stacks that are independent from each -> other. Some nodes may be connected to simulated Thread networks, others may -> connect to simulated Wi-Fi, WAN (Internet), or cellular networks. - -**You need to run happy tests on Linux platforms.** - -### Usage - -- We suggest using - [rootless Docker](https://docs.docker.com/engine/security/rootless/) if you - have concerns about `--privileged` option on docker run. In your - project-chip checkout path, run: - - $ docker run --rm --privileged \ - --entrypoint /bin/bash \ - --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" \ - -it --mount type=bind,source=`pwd`,target=`pwd` \ - connectedhomeip/chip-build:latest - - Mount your checkout to the same path as your local path avoids errors during - bootstrap. - -- Install packages - - $ sudo scripts/tests/happy_tests.sh install_packages - -- Install happy framework - - $ scripts/tests/happy_tests.sh bootstrap - -- Build CHIP - - $ scripts/build/gn_bootstrap.sh - $ scripts/build/gn_gen.sh --args="chip_enable_happy_tests=true" - $ ninja -C ./out - -- Run Tests - - $ RUN_HAPPY_TESTS=1 scripts/tests/gn_tests.sh - -- Run a single test - - $ scripts/tests/happy_test_wrapper.py" --test-bin-dir "out/tests" {test script path} diff --git a/src/test_driver/happy/bin/set_test_path.py b/src/test_driver/happy/bin/set_test_path.py deleted file mode 100644 index 52fff7bce2b5f7..00000000000000 --- a/src/test_driver/happy/bin/set_test_path.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2017 Nest Labs, Inc. -# All rights reserved. -# -# 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 os -import sys - -# -# This module is imported by test scripts in the following directories: -# - happy/tests/standalone -# - happy/tests/service -# -# os.path.abspath(__file__) will return the path of the file that imports -# this module, so the path to "src/test-apps/happy" is derived relative -# to the above test scripts. -# - -# look for the 'happy' folder in the file path - -path = os.path.abspath(__file__) -path_parts = path.split('/') -happy_idx = path_parts.index('happy') -wrapper_home = '/'.join(str(x) for x in path_parts[0:happy_idx+1]) - -wrapper_dirs = [".", - wrapper_home, - wrapper_home + "/test-templates", - wrapper_home + "/lib", - wrapper_home + "/bin"] - -for wrapper_dir in wrapper_dirs: - if os.path.exists(wrapper_dir): - sys.path.append(wrapper_dir) diff --git a/src/test_driver/happy/conf/main_conf.json b/src/test_driver/happy/conf/main_conf.json deleted file mode 100644 index cd078f829c744d..00000000000000 --- a/src/test_driver/happy/conf/main_conf.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "configuration_file": "~/.happy_conf.json", - "log_directory": "/tmp/happy_test_logs", - "default_happy_log_dir": "/tmp/happy_test_logs", - "log_level_file": "DEBUG", - "log_level_console": "INFO", - "default_state": "happy", - "process_log_prefix": "%(happy_log_dir)s/%(state_id)s_", - "state_environ": "HAPPY_STATE_ID", - "state_file_prefix": "/run/", - "state_file_suffix": "_state.json", - "default_isp_suffix": "isp", - "default_rt_suffix": "rt" -} diff --git a/src/test_driver/happy/lib/Chip.py b/src/test_driver/happy/lib/Chip.py deleted file mode 100644 index d0d43e746e7cf4..00000000000000 --- a/src/test_driver/happy/lib/Chip.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2015-2017 Nest Labs, Inc. -# All rights reserved. -# -# 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. -# - -## -# @file -# Implements CHIP class that wraps around standalone CHIP code library. -# - -import os -import sys - -from happy.Utils import * -from ChipState import ChipState - - -class Chip(ChipState): - def __init__(self): - ChipState.__init__(self) - - self.chip_happy_conf_path = None - self.chip_build_path = None - - self.max_running_time = 1800 - - def __check_chip_path(self): - # Pick chip path from configuration - if "chip_path" in self.configuration.keys(): - self.chip_happy_conf_path = self.configuration["chip_path"] - emsg = "Found chip path: %s." % (self.chip_happy_conf_path) - self.logger.debug("[localhost] Chip: %s" % (emsg)) - - # Check if Chip build path is set - if "TEST_BIN_DIR" in os.environ.keys(): - self.chip_build_path = os.environ['TEST_BIN_DIR'] - emsg = "Found chip TEST_BIN_DIR: %s." % (self.chip_build_path) - self.logger.debug("[localhost] Chip: %s" % (emsg)) - - if self.chip_build_path is not None: - self.chip_path = self.chip_build_path - else: - self.chip_path = self.chip_happy_conf_path - - if self.chip_path is None: - emsg = "Unknown path to Chip directory (repository)." - self.logger.error("[localhost] Chip: %s" % (emsg)) - self.logger.info( - "Set chip_path with happy-configuration and try again.") - sys.exit(1) - - if not os.path.exists(self.chip_path): - emsg = "Chip path %s does not exist." % (self.chip_path) - self.logger.error("[localhost] Chip: %s" % (emsg)) - self.logger.info( - "Set correct chip_path with happy-configuration and try again.") - sys.exit(1) - - if self.chip_path[-1] == "/": - self.chip_path = self.chip_path[:-1] - - def __get_cmd_path(self, cmd_end): - cmd_path = self.chip_path + "/" + str(cmd_end) - if not os.path.exists(cmd_path): - emsg = "Chip path %s does not exist." % (cmd_path) - self.logger.error("[localhost] Chip: %s" % (emsg)) - sys.exit(1) - # return None - else: - return cmd_path - - def getChipInetLayerMulticastPath(self): - self.__check_chip_path() - cmd_path = self.__get_cmd_path("TestInetLayerMulticast") - return cmd_path diff --git a/src/test_driver/happy/lib/ChipState.py b/src/test_driver/happy/lib/ChipState.py deleted file mode 100644 index 026ed58aba7a49..00000000000000 --- a/src/test_driver/happy/lib/ChipState.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2015-2018 Nest Labs, Inc. -# All rights reserved. -# -# 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. -# - -## -# @file -# Implements ChipState class that implements methods to retrieve -# parts of state setup that relate to Chip plugin. -# - -import json -from happy.State import State -from happy.utils.IP import IP - -options = {} -options["quiet"] = False - - -def option(): - return options.copy() - - -class ChipState(State): - """ - Displays CHIP-related parameters for CHIP nodes in a Happy network - topology. - chip-state [-h --help] [-q --quiet] - Examples: - $ chip-state - Displays CHIP-related parameters for all CHIP nodes in the - current Happy topology. - return: - 0 success - 1 fail - """ - - def __init__(self, opts=options): - State.__init__(self) - self.quiet = opts["quiet"] diff --git a/src/test_driver/happy/lib/ChipStateLoad.py b/src/test_driver/happy/lib/ChipStateLoad.py deleted file mode 100644 index d53766bb3c1f35..00000000000000 --- a/src/test_driver/happy/lib/ChipStateLoad.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2016-2017 Nest Labs, Inc. -# All rights reserved. -# -# 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. -# - -## -# @file -# Implements ChipStateLoad class that sets up virtual network topology. -# - -import json -import os -import sys - -from happy.ReturnMsg import ReturnMsg -from happy.Utils import * - -import happy.HappyStateLoad - -from Chip import Chip -from ChipState import ChipState - -options = {} -options["quiet"] = False -options["json_file"] = None - -LOG_TEXT_PREFIX = "[localhost] ChipStateLoad: " - - -def option(): - return options.copy() - - -class ChipStateLoad(ChipState): - def __init__(self, opts=options): - ChipState.__init__(self) - - self.quiet = opts["quiet"] - self.new_json_file = opts["json_file"] - - def __pre_check(self): - if self.new_json_file is None: - emsg = "Missing name of file that specifies virtual network topology." - self.logger.error(LOG_TEXT_PREFIX + emsg) - self.exit() - - if not os.path.exists(self.new_json_file): - emsg = "Cannot find the configuration file {}".format( - self.new_json_file) - self.logger.error(LOG_TEXT_PREFIX + emsg) - self.exit() - - self.new_json_file = os.path.realpath(self.new_json_file) - - emsg = "Loading Chip Topology from file {}.".format(self.new_json_file) - self.logger.debug(LOG_TEXT_PREFIX + emsg) - - def __load_JSON(self): - emsg = "Import state file {}.".format(self.new_json_file) - self.logger.debug(LOG_TEXT_PREFIX + emsg) - - try: - with open(self.new_json_file, 'r') as jfile: - json_data = jfile.read() - - self.chip_topology = json.loads(json_data) - - except Exception: - emsg = "Failed to load JSON state file: {}".format( - self.new_json_file) - self.logger.error(LOG_TEXT_PREFIX + emsg) - self.exit() - - def __load_network_topology(self): - emsg = "Loading network topology." - self.logger.debug(LOG_TEXT_PREFIX + emsg) - - options = happy.HappyStateLoad.option() - options["quiet"] = self.quiet - options["json_file"] = self.new_json_file - - happyLoad = happy.HappyStateLoad.HappyStateLoad(options) - happyLoad.run() - - self.readState() - - def __post_check(self): - pass - - def run(self): - with self.getStateLockManager(): - - self.__pre_check() - - self.__load_JSON() - - self.__load_network_topology() - - self.__post_check() - - return ReturnMsg(0) diff --git a/src/test_driver/happy/lib/ChipStateUnload.py b/src/test_driver/happy/lib/ChipStateUnload.py deleted file mode 100644 index c0f11339cbb43a..00000000000000 --- a/src/test_driver/happy/lib/ChipStateUnload.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2016-2017 Nest Labs, Inc. -# All rights reserved. -# -# 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. -# - -## -# @file -# Implements ChipStateUnload class that tears down virtual network topology. -# - -import json -import os -import sys - -from happy.ReturnMsg import ReturnMsg -from happy.Utils import * - -import happy.HappyStateUnload - -from ChipState import ChipState - -options = {} -options["quiet"] = False -options["json_file"] = None - - -def option(): - return options.copy() - - -class ChipStateUnload(ChipState): - """ - Deletes a Chip-enabled virtual network topology based on the state described - in a JSON file. If the current Happy state does not match the specified JSON - file, a partial deletion of the topology might occur. - chip-state-unload [-h --help] [-q --quiet] [-f --file ] - -f --file Required. A valid JSON file with the topology to delete. - Example: - $ chip-state-unload mychipstate.json - Deletes the Chip-enabled network topology based on the state described in - mychipstate.json. - return: - 0 success - 1 fail - """ - - def __init__(self, opts=options): - ChipState.__init__(self) - - self.quiet = opts["quiet"] - self.old_json_file = opts["json_file"] - - def __pre_check(self): - # Check if the name of the new node is given - if self.old_json_file is None: - emsg = "Missing name of file that specifies virtual network topology." - self.logger.error("[localhost] HappyStateUnload: %s" % (emsg)) - self.exit() - - # Check if json file exists - if not os.path.exists(self.old_json_file): - emsg = "Cannot find the configuration file %s" % ( - self.old_json_file) - self.logger.error("[localhost] HappyStateUnload: %s" % emsg) - self.exit() - - self.old_json_file = os.path.realpath(self.old_json_file) - - emsg = "Unloading Chip Fabric from file %s." % (self.old_json_file) - self.logger.debug("[localhost] HappyStateUnload: %s" % emsg) - - def __load_JSON(self): - emsg = "Import state file %s." % (self.old_json_file) - self.logger.debug("[localhost] ChipStateUnload: %s" % (emsg)) - - try: - with open(self.old_json_file, 'r') as jfile: - json_data = jfile.read() - - self.chip_topology = json.loads(json_data) - - except Exception: - emsg = "Failed to load JSON state file: %s" % (self.old_json_file) - self.logger.error("[localhost] HappyStateUnload: %s" % emsg) - self.exit() - - def __unload_network_topology(self): - emsg = "Unloading network topology." - self.logger.debug("[localhost] ChipStateUnload: %s" % (emsg)) - - options = happy.HappyStateUnload.option() - options["quiet"] = self.quiet - options["json_file"] = self.old_json_file - - happyUnload = happy.HappyStateUnload.HappyStateUnload(options) - happyUnload.run() - - def __post_check(self): - emsg = "Unloading Chip Topologym completed." - self.logger.debug("[localhost] ChipStateUnload: %s" % (emsg)) - - def run(self): - with self.getStateLockManager(): - - self.__pre_check() - - self.__load_JSON() - - self.__post_check() - - self.__unload_network_topology() - - return ReturnMsg(0) diff --git a/src/test_driver/happy/lib/ChipTest.py b/src/test_driver/happy/lib/ChipTest.py deleted file mode 100644 index d3e37564f4a79c..00000000000000 --- a/src/test_driver/happy/lib/ChipTest.py +++ /dev/null @@ -1,268 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2015-2017 Nest Labs, Inc. -# All rights reserved. -# -# 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. -# - -# -# @file -# Implements ChipTest class that provides generic CHIP testing features. -# - -import os -import random -import sys -import time -import datetime - -from happy.Utils import * -from Chip import Chip - -import happy.HappyProcessOutput -import happy.HappyProcessStart -import happy.HappyProcessStop -import happy.HappyProcessStrace -import happy.HappyProcessWait -import happy.State - -gready_to_service_events_str = "CHIP node ready to service event" - - -class ChipTest(Chip): - def __init__(self): - self.ready_to_service_events_str = gready_to_service_events_str - Chip.__init__(self) - if "JITTER_DISTRIBUTION_CURVE" in os.environ.keys(): - self.jitter_distribution_curve = int( - os.environ["JITTER_DISTRIBUTION_CURVE"]) - else: - self.jitter_distribution_curve = None - - def start_chip_process(self, node_id, cmd, tag, quiet=None, strace=True, env={}, sync_on_output=None, rootMode=False): - emsg = "start_chip_process %s at %s node." % (tag, node_id) - self.logger.debug("[%s] ChipTest: %s" % (node_id, emsg)) - - options = happy.HappyProcessStart.option() - options["node_id"] = node_id - options["tag"] = tag - options["command"] = cmd - options["strace"] = strace - options["env"] = env - options["sync_on_output"] = sync_on_output - options["rootMode"] = rootMode - - if env: - options["with_stderr"] = True - - proc = happy.HappyProcessStart.HappyProcessStart(options) - proc.run() - - time.sleep(0.1) - - def stop_chip_process(self, node_id, tag, quiet=None): - emsg = "stop_chip_process %s at %s node." % (tag, node_id) - self.logger.debug("[%s] ChipTest: %s" % (node_id, emsg)) - - options = happy.HappyProcessStop.option() - options["node_id"] = node_id - options["tag"] = tag - - stop_server = happy.HappyProcessStop.HappyProcessStop(options) - stop_server.run() - - def start_simple_chip_server(self, cmd_path, server_addr, node_id, tag, quiet=None, listen=True, strace=True, env={}, - sync_on_output=gready_to_service_events_str, use_persistent_storage=True, reset_persistent_storage=True): - cmd = cmd_path - - if server_addr != None: - cmd += " --node-addr " + str(server_addr) - - if listen: - cmd += " --listen" - - persistent_storage_file = self.getHappyLogDir() + "/" + self.getStateId() + \ - "_persistent_state." + tag - - if use_persistent_storage: - cmd += " --persistent-cntr-file " + persistent_storage_file - - if reset_persistent_storage: - if os.path.isfile(persistent_storage_file): - self.logger.debug("[%s] ChipTest: deleting existing persistent storage file: %s" % ( - node_id, persistent_storage_file)) - os.remove(persistent_storage_file) - - self.logger.debug( - "[%s] CHIP start server on address %s." % (node_id, server_addr)) - emsg = "CHIP start server with cmd: %s." % cmd - self.logger.debug("[%s] CHIP: %s" % (node_id, emsg)) - - self.start_chip_process( - node_id, cmd, tag, quiet, strace, env=env, sync_on_output=sync_on_output) - - def jitter(self, jitter_distribution_curve): - if isinstance(jitter_distribution_curve, int) and jitter_distribution_curve >= 0: - fibonacci_numbers = [0, 10] - if jitter_distribution_curve == 0: - delayTimeSec = fibonacci_numbers[0] - elif jitter_distribution_curve == 1: - delayTimeSec = fibonacci_numbers[1] - else: - jitter_distribution_curve -= 2 - for i in xrange(jitter_distribution_curve): - fibonacci_numbers.append( - fibonacci_numbers[i+1]+fibonacci_numbers[i]) - delayTimeSec = random.choice(fibonacci_numbers) - self.logger.debug("Test Delay %d seconds" % delayTimeSec) - time.sleep(delayTimeSec) - else: - self.logger.debug( - "Expect that jitter_distribution_curve is integer and not less than 0 %d" % jitter_distribution_curve) - - def start_simple_chip_client(self, cmd_path, client_addr, server_addr, server_id, node_id, tag, - quiet=None, strace=True, env={}, use_persistent_storage=True, reset_persistent_storage=True): - cmd = cmd_path - - if client_addr != None: - cmd += " --node-addr " + str(client_addr) - - if server_addr != None: - cmd += " --dest-addr " + str(server_addr) - - persistent_storage_file = self.getHappyLogDir() + "/" + self.getStateId() + \ - "_persistent_state." + tag - - if use_persistent_storage: - cmd += " --persistent-cntr-file " + persistent_storage_file - - if reset_persistent_storage: - if os.path.isfile(persistent_storage_file): - self.logger.debug("[%s] ChipTest: deleting existing persistent storage file: %s" % ( - node_id, persistent_storage_file)) - os.remove(persistent_storage_file) - - if server_id != None: - cmd += " " + str(server_id) - - if self.jitter_distribution_curve is not None: - self.jitter(self.jitter_distribution_curve) - - self.logger.debug("[%s] CHIP start client on address %s" % - (node_id, client_addr)) - emsg = "CHIP start client with cmd: %s" % cmd - self.logger.debug("[%s] CHIP: %s" % (node_id, emsg)) - - self.start_chip_process(node_id, cmd, tag, quiet, strace, env=env) - - def wait_for_test_to_end(self, node_id, tag, quiet=None, timeout=None): - emsg = "wait_for_test_to_end for %s at %s node." % (tag, node_id) - self.logger.debug("[%s] ChipTest: %s" % (node_id, emsg)) - - if timeout == None: - timeout = self.max_running_time - - options = happy.HappyProcessWait.option() - options["node_id"] = node_id - options["tag"] = tag - options["timeout"] = timeout - - wait_for_client = happy.HappyProcessWait.HappyProcessWait(options) - wait_for_client.run() - - def wait_for_test_time_secs(self, node_id, tag, secs=None): - emsg = "wait_for_test_time_secs for %d secs, tag %s " % (secs, tag) - self.logger.debug("[%s] ChipTest: %s" % (node_id, emsg)) - - poll_interval_sec = 0.1 - max_poll_time_sec = secs + 60 - time_slept = 0 - - state = happy.State.State() - state.readState() - process = state.getNodeProcess(tag, node_id) - tail = open(process["out"], "r") - self.logger.debug( - "[%s] wait_for_test_time_secs: polling for output" % (self.node_id)) - - initial_timestamp = None - - while (True): - line = tail.readline() - if not line: - time.sleep(poll_interval_sec) - time_slept += poll_interval_sec - if poll_interval_sec < 20: - poll_interval_sec *= 2 - if (time_slept > max_poll_time_sec): - self.logger.debug("[%s] wait_for_test_time_secs: can't find a timestamp %d secs after %s" % - (self.node_id, secs, str(initial_timestamp))) - self.exit() - else: - try: - # Not every line begins with a timestamp; if they do, it look like this: - # 2017-09-27 20:42:48-0700.402 - # Note that for the purpose of time deltas we don't care about the timezone, - # so the first 19 chars are enough - cur_timestamp = datetime.datetime.strptime( - line[0:19], "%Y-%m-%d %H:%M:%S") - if initial_timestamp is None: - initial_timestamp = cur_timestamp - except Exception: - # if this line does not start with a timestamp, continue - continue - else: - # read the timestamp and check - delta = cur_timestamp - initial_timestamp - # print "delta = " + str(delta.seconds) - if delta.seconds >= secs: - break - - tail.close() - return - - def get_test_output(self, node_id, tag, quiet=False): - emsg = "get_test_output for %s at %s node." % (tag, node_id) - self.logger.debug("[%s] ChipTest: %s" % (node_id, emsg)) - - options = happy.HappyProcessOutput.option() - options["node_id"] = node_id - options["tag"] = tag - options["quiet"] = quiet - - client_output = happy.HappyProcessOutput.HappyProcessOutput(options) - ret = client_output.run() - - value = ret.Value() - data = ret.Data() - - return (value, data) - - def get_test_strace(self, node_id, tag, quiet=None): - emsg = "get_test_strace for %s at %s node." % (tag, node_id) - self.logger.debug("[%s] ChipTest: %s" % (node_id, emsg)) - - options = happy.HappyProcessStrace.option() - options["node_id"] = node_id - options["tag"] = tag - - client_strace = happy.HappyProcessStrace.HappyProcessStrace(options) - ret = client_strace.run() - - value = ret.Value() - data = ret.Data() - - return (value, data) diff --git a/src/test_driver/happy/lib/ChipUtilities.py b/src/test_driver/happy/lib/ChipUtilities.py deleted file mode 100644 index 90c67dc4f80187..00000000000000 --- a/src/test_driver/happy/lib/ChipUtilities.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2016-2017 Nest Labs, Inc. -# All rights reserved. -# -# 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. -# - -# -# @file -# Implements utilities to parse standard content output by the -# Chip standalone test clients and servers (resource stats, leak -# detection, fault-injection, etc) -# - -import sys -import re -import pprint -import traceback -import unittest - -import happy.HappyStateDelete - - -from happy.Utils import * - - -def cleanup_after_exception(): - print("Deleting Happy state..") - opts = happy.HappyStateDelete.option() - state_delete = happy.HappyStateDelete.HappyStateDelete(opts) - state_delete.run() - print("Happy state deleted.") - - -def run_unittest(): - """ - Wrapper for unittest.main() that ensures the Happy state is deleted in case - of failure or error. - This is meant to be used with mock-to-mock test cases that always delete the topology they create. - If the test case can reuse an existing topology and therefore does not always delete the topology, - it should handle exceptions in setUp and tearDown explicitly. - Unittest traps all exceptions but not KeyboardInterrupt. - So, a KeyboardInterrupt will cause the Happy state not to be deleted. - An exception raised during a test results in the test ending with an "error" - as opposed to a "failure" (see the docs for more details). tearDown is invoked - in that case. - If an exception is raised during setUp, tearDown is not invoked, and so the - Happy state is not cleaned up. - Note that an invocation of sys.exit() from the Happy code results in an - exception itself (and then it depends if that is happening during setUp, - during the test, or during tearDown). - So, - 1. we must cleanup in case of KeyboardInterrupt, and - 2. to keep it simple, we cleanup in case of any SystemExit that carries - an error (we don't care if unittest was able to run tearDown or not). - """ - try: - unittest.main() - - except KeyboardInterrupt: - print("\n\nChipUtilities.run_unittest caught KeyboardInterrupt") - cleanup_after_exception() - raise - - except SystemExit as e: - if e.args[0] not in [0, False]: - print( - "\n\nChipUtilities.run_unittest caught some kind of test error or failure") - cleanup_after_exception() - raise e diff --git a/src/test_driver/happy/lib/set_test_path.py b/src/test_driver/happy/lib/set_test_path.py deleted file mode 120000 index b62cf2e7919e8d..00000000000000 --- a/src/test_driver/happy/lib/set_test_path.py +++ /dev/null @@ -1 +0,0 @@ -../bin/set_test_path.py \ No newline at end of file diff --git a/src/test_driver/happy/test-templates/ChipInetMulticast.py b/src/test_driver/happy/test-templates/ChipInetMulticast.py deleted file mode 100644 index 2038b641f9c287..00000000000000 --- a/src/test_driver/happy/test-templates/ChipInetMulticast.py +++ /dev/null @@ -1,376 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2018-2019 Google LLC. -# All rights reserved. -# -# 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. -# - -# -# @file -# Implements ChipInet class that tests Inet Layer multicast -# among multiple nodes. -# - -import os -import sys -import time - -from happy.ReturnMsg import ReturnMsg -from happy.Utils import * -from happy.utils.IP import IP -from happy.HappyNode import HappyNode -from happy.HappyNetwork import HappyNetwork - -from ChipTest import ChipTest - - -options = {} -options["configuration"] = None -options["interface"] = None -options["ipversion"] = None -options["transport"] = None -options["interval"] = None -options["quiet"] = False -options["tap"] = None - - -def option(): - return options.copy() - - -class ChipInetMulticast(HappyNode, HappyNetwork, ChipTest): - """ - Note: - Supports two networks: IPv4 and IPv6 - Supports one transport: UDP - return: - 0 success - 1 failure - """ - - def __init__(self, opts=options): - HappyNode.__init__(self) - HappyNetwork.__init__(self) - ChipTest.__init__(self) - - # Dictionary that will eventually contain 'node' and 'tag' for - # the sender node process. - - self.sender = {} - - # Array that will eventually contain 'node' and 'tag' - # dictionaries for the receiver node processes. - - self.receivers = [] - - self.configuration = opts["configuration"] - self.interface = opts["interface"] - self.ipversion = opts["ipversion"] - self.transport = opts["transport"] - self.interval = opts["interval"] - self.quiet = opts["quiet"] - self.tap = opts["tap"] - - def __log_error_and_exit(self, error): - self.logger.error("[localhost] ChipInetMulticast: %s" % (error)) - sys.exit(1) - - def __checkNodeExists(self, node, description): - if not self._nodeExists(node): - emsg = "The %s '%s' does not exist in the test topology." % ( - description, node) - self.__log_error_and_exit(emsg) - - def __pre_check(self): - """Sanity check the instantiated options and configuration""" - # Sanity check the transport - if self.transport != "udp": - emsg = "Transport type must be 'udp'." - self.__log_error_and_exit(emsg) - - # Sanity check the IP version - if self.ipversion != "4" and self.ipversion != "6": - emsg = "The IP version must be one of '4' or '6'." - self.__log_error_and_exit(emsg) - - # Sanity check the configuration - if self.configuration == None: - emsg = "The test configuration is missing." - self.__log_error_and_exit(emsg) - - # There must be exactly one sender - if self.configuration['sender'] == None or len(self.configuration['sender']) != 1: - emsg = "The test configuration must have exactly one sender, 'sender'." - self.__log_error_and_exit(emsg) - - # There must be at least one receiver - if self.configuration["receivers"] == None or len(self.configuration["receivers"]) < 1: - emsg = "The test configuration must at least one receiver in 'receivers'." - self.__log_error_and_exit(emsg) - - # Each specified sender and receiver node must exist in the - # loaded Happy configuration. - - for node in self.configuration['sender'].keys(): - self.__checkNodeExists(node, "sender") - - for node in self.configuration['receivers'].keys(): - self.__checkNodeExists(node, "receiver") - - if not self.interval == None and not self.interval.isdigit(): - emsg = "Please specify a valid send interval in milliseconds." - self.__log_error_and_exit(emsg) - - def __gather_process_results(self, process, quiet): - """Gather and return the exit status and output as a tuple for the - specified process node and tag. - """ - node = process['node'] - tag = process['tag'] - - status, output = self.get_test_output(node, tag, quiet) - - return (status, output) - - def __gather_sender_results(self, quiet): - """Gather and return the exit status and output as a tuple for the - sender process. - """ - status, output = self.__gather_process_results(self.sender, quiet) - - return (status, output) - - def __gather_receiver_results(self, receiver, quiet): - """Gather and return the exit status and output as a tuple for the - specified receiver process. - """ - status, output = self.__gather_process_results(receiver, quiet) - - return (status, output) - - def __gather_receivers_results(self, quiet): - """Gather and return the exit status and output as a tuple for all - receiver processes. - """ - receiver_results = {} - receivers_results = [] - - for receiver in self.receivers: - receiver_results['status'], receiver_results['output'] = \ - self.__gather_receiver_results(receiver, quiet) - receivers_results.append(receiver_results) - - return (receivers_results) - - def __gather_results(self): - """Gather and return the exit status and output as a dictionary for all - sender and receiver processes. - """ - quiet = True - results = {} - sender_results = {} - receivers_results = [] - - sender_results['status'], sender_results['output'] = \ - self.__gather_sender_results(quiet) - - receivers_results = self.__gather_receivers_results(quiet) - - results['sender'] = sender_results - results['receivers'] = receivers_results - - return (results) - - def __process_results(self, results): - status = True - output = {} - output['sender'] = "" - output['receivers'] = [] - - # Iterate through the sender and receivers return status. If - # all had successful (0) status, then the cumulative return - # status is successful (True). If any had unsuccessful status, - # then the cumulative return status is unsuccessful (False). - # - # For the output, simply key it by sender and receivers. - - # Sender - - status = (results['sender']['status'] == 0) - - output['sender'] = results['sender']['output'] - - # Receivers - - for receiver_results in results['receivers']: - status = (status and (receiver_results['status'] == 0)) - output['receivers'].append(receiver_results['output']) - - return (status, output) - - def __start_node(self, node, attributes, extra, tag): - """Start the test process on the specified node with the provided - tag using the provided attributes and extra command line - options. - """ - cmd = self.getChipInetLayerMulticastPath() - - # Generate and accumulate the multicast group-related command - # line options. - - for group in attributes['groups']: - cmd += " --group %u" % (group['id']) - cmd += " --group-expected-tx-packets %u" % (group['send']) - cmd += " --group-expected-rx-packets %u" % (group['receive']) - - # Generate and accumulate the transport and IP version command - # line arguments. - - cmd += " --ipv" + self.ipversion - - cmd += " --" + self.transport - - # If present, generate and accumulate the LwIP hosted OS - # network tap device interface. - - if self.tap: - cmd += " --tap-device " + self.tap - - # If present, generate and accumulate the LwIP hosted OS - # network local IPv4 address. - - if self.ipversion == "4" and attributes.has_key('tap-ipv4-local-addr'): - cmd += " --local-addr " + attributes['tap-ipv4-local-addr'] - - # Generate and accumulate, if present, the bound network - # interface command line option. - - if not self.interface == None: - cmd += " --interface " + self.interface - - # Accumulate any extra command line options specified. - - cmd += extra - - self.logger.debug( - "[localhost] ChipInetMulticast: Will start process on node '%s' with tag '%s' and command '%s'" % (node, tag, cmd)) - - self.start_chip_process( - node, cmd, tag, sync_on_output=self.ready_to_service_events_str) - - def __start_receiver(self, node, attributes, identifier): - """Start a receiver test process on the specified node with the - provided attributes and tag identifier. - """ - receiver = {} - tag = "INET-MCAST-RX-%u" % (identifier) - - extra_cmd = " --listen" - - self.__start_node(node, attributes, extra_cmd, tag) - - receiver['node'] = node - receiver['tag'] = tag - - self.receivers.append(receiver) - - def __start_receivers(self): - """Start all receiver test processes.""" - receiver = {} - identifier = 0 - for receiver in self.configuration['receivers']: - self.__start_receiver( - receiver, self.configuration['receivers'][receiver], identifier) - identifier += 1 - - def __start_sender(self): - """Start the sender test process.""" - node = list(self.configuration['sender'])[0] - attributes = self.configuration['sender'][node] - tag = "INET-MCAST-TX-0" - - extra_cmd = "" - - if not self.interval == None: - extra_cmd += " --interval " + str(self.interval) - - extra_cmd += " --no-loopback" - - self.__start_node(node, attributes, extra_cmd, tag) - - self.sender['node'] = node - self.sender['tag'] = tag - - def __wait_for_sender(self): - """Block and wait for the sender test process.""" - node = self.sender['node'] - tag = self.sender['tag'] - - self.logger.debug( - "[localhost] ChipInetMulticast: Will wait for sender on node %s with tag %s..." % (node, tag)) - - self.wait_for_test_to_end(node, tag) - - def __stop_receiver(self, receiver): - node = receiver['node'] - tag = receiver['tag'] - - self.logger.debug( - "[localhost] ChipInetMulticast: Will stop receiver on node %s with tag %s..." % (node, tag)) - - self.stop_chip_process(node, tag) - - def __stop_receivers(self): - """Stop all receiver test processes.""" - for receiver in self.receivers: - self.__stop_receiver(receiver) - - def run(self): - results = {} - - self.logger.debug("[localhost] ChipInetMulticast: Run.") - - self.__pre_check() - - self.__start_receivers() - - self.logger.debug("[%s] ChipInetMulticast: %u receivers should be running." % ( - "localhost", len(self.receivers))) - - for receiver in self.receivers: - emsg = "receiver %s should be running." % (receiver['tag']) - self.logger.debug("[%s] ChipInetMulticast: %s" % - (receiver['node'], emsg)) - - self.__start_sender() - - self.__wait_for_sender() - - self.__stop_receivers() - - # Gather results from the sender and receivers - - results = self.__gather_results() - - # Process the results from the sender and receivers into a - # singular status value and a results dictionary containing - # process output. - - status, results = self.__process_results(results) - - self.logger.debug("[localhost] ChipInetMulticast: Done.") - - return ReturnMsg(status, results) diff --git a/src/test_driver/happy/tests/standalone/inet/BUILD.gn b/src/test_driver/happy/tests/standalone/inet/BUILD.gn deleted file mode 100644 index 7d808fa0c43d3d..00000000000000 --- a/src/test_driver/happy/tests/standalone/inet/BUILD.gn +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/build.gni") -import("//build_overrides/chip.gni") - -import("${chip_root}/build/chip/happy_test.gni") - -happy_test("inet_tests") { - deps = [ "${chip_root}/src/inet/tests:happy_tests" ] - - tests = [ "test_inet_multicast_five_nodes_on_wifi" ] -} diff --git a/src/test_driver/happy/tests/standalone/inet/set_test_path.py b/src/test_driver/happy/tests/standalone/inet/set_test_path.py deleted file mode 120000 index 61a115a426ee1b..00000000000000 --- a/src/test_driver/happy/tests/standalone/inet/set_test_path.py +++ /dev/null @@ -1 +0,0 @@ -../../../bin/set_test_path.py \ No newline at end of file diff --git a/src/test_driver/happy/tests/standalone/inet/test_inet_multicast_five_nodes_on_wifi.py b/src/test_driver/happy/tests/standalone/inet/test_inet_multicast_five_nodes_on_wifi.py deleted file mode 100644 index c0787b82e5fc53..00000000000000 --- a/src/test_driver/happy/tests/standalone/inet/test_inet_multicast_five_nodes_on_wifi.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2016-2017 Nest Labs, Inc. -# All rights reserved. -# -# 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. -# - -## -# @file -# Calls CHIP Inet Multicast test among sender and receiver nodes. -# - -import itertools -import os -import unittest -import set_test_path - -from happy.Utils import * -import happy.HappyNodeList - -import ChipStateLoad -import ChipStateUnload -import ChipUtilities -import ChipInetMulticast - - -class test_chip_inet_multicast_five_nodes_on_wifi(unittest.TestCase): - def setUp(self): - self.using_lwip = False - - self.topology_file = os.path.join(os.path.dirname(os.path.realpath( - __file__)), "../../../topologies/standalone/five_nodes_on_wifi.json") - self.interface = "wlan0" - self.tap = None - - self.show_strace = False - - options = ChipStateLoad.option() - options["quiet"] = True - options["json_file"] = self.topology_file - - setup_network = ChipStateLoad.ChipStateLoad(options) - ret = setup_network.run() - - def tearDown(self): - """cleaning up""" - options = ChipStateUnload.option() - options["quiet"] = True - options["json_file"] = self.topology_file - - teardown_network = ChipStateUnload.ChipStateUnload(options) - teardown_network.run() - - def test_chip_inet_multicast(self): - options = happy.HappyNodeList.option() - options["quiet"] = True - - # This test validates UDP over IPv6 with one sender and four receivers. - # Each receiver varies in the number of multicast groups it participates - # in. - # - # The ipv4-local-addr configuration key-value pairs are only - # used for LwIP hosted OS topologies where a network tap - # device is configured. - - configuration = { - 'sender': { - '00-WifiNode-TxFourMulticastAddresses': { - 'groups': [ - { - 'id': 1, - 'send': 1, - 'receive': 0 - }, - { - 'id': 2, - 'send': 2, - 'receive': 0 - }, - { - 'id': 3, - 'send': 3, - 'receive': 0 - }, - { - 'id': 4, - 'send': 5, - 'receive': 0 - }, - ], - 'tap-ipv4-local-addr': "192.168.1.0" - } - }, - 'receivers': { - '01-WifiNode-RxOneMulticastAddress': { - 'groups': [ - { - 'id': 1, - 'send': 0, - 'receive': 1 - } - ], - 'tap-ipv4-local-addr': "192.168.1.1" - }, - '02-WifiNode-RxTwoMulticastAddresses': { - 'groups': [ - { - 'id': 1, - 'send': 0, - 'receive': 1 - }, - { - 'id': 2, - 'send': 0, - 'receive': 2 - } - ], - 'tap-ipv4-local-addr': "192.168.1.2" - }, - '03-WifiNode-RxThreeMulticastAddresses': { - 'groups': [ - { - 'id': 1, - 'send': 0, - 'receive': 1 - }, - { - 'id': 2, - 'send': 0, - 'receive': 2 - }, - { - 'id': 3, - 'send': 0, - 'receive': 3 - } - ], - 'tap-ipv4-local-addr': "192.168.1.3" - }, - '04-WifiNode-RxFourMulticastAddresses': { - 'groups': [ - { - 'id': 1, - 'send': 0, - 'receive': 1 - }, - { - 'id': 2, - 'send': 0, - 'receive': 2 - }, - { - 'id': 3, - 'send': 0, - 'receive': 3 - }, - { - 'id': 4, - 'send': 0, - 'receive': 5 - } - ], - 'tap-ipv4-local-addr': "192.168.1.4" - } - } - } - - # Topology-independent test parameters: - TEST_TRANSPORT = "udp" - TEST_IP_NETWORK = "6" - - # Run the test. - value, data = self.__run_inet_multicast_test( - configuration, self.interface, TEST_IP_NETWORK, TEST_TRANSPORT) - - # Process and report the results. - self.__process_result( - configuration, self.interface, TEST_IP_NETWORK, TEST_TRANSPORT, value, data) - - def __process_result(self, configuration, interface, network, transport, value, data): - nodes = len(configuration['sender']) + len(configuration['receivers']) - - print("Inet multicast test using %sIPv%s w/ device interface: %s (w/%s LwIP) with %u nodes:" % ("UDP/" if transport == - "udp" else "", network, "" if interface == None else interface, "" if self.using_lwip else "o", nodes)) - - if value: - print("PASSED") - else: - print("FAILED") - raise ValueError("Chip Inet Multicast Test Failed") - - def __run_inet_multicast_test(self, configuration, interface, network, transport): - """ Run Inet Multicast test on configured topology - The default interval is 1 s (1000 ms). This is a good - default for interactive test operation; however, for - automated continuous integration, we prefer it to run much - faster. Consequently, use 250 ms as the interval. - """ - - options = ChipInetMulticast.option() - options["quiet"] = False - options["configuration"] = configuration - options["interface"] = interface - options["ipversion"] = network - options["transport"] = transport - options["interval"] = str(250) - options["tap"] = self.tap - - chip_inet_multicast = ChipInetMulticast.ChipInetMulticast(options) - ret = chip_inet_multicast.run() - - value = ret.Value() - data = ret.Data() - - return value, data - - -if __name__ == "__main__": - ChipUtilities.run_unittest() diff --git a/src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.json b/src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.json deleted file mode 100644 index 497e5725b87425..00000000000000 --- a/src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "identifiers": { - "000": { - "id": "00-WifiNode-TxFourMulticastAddresses" - }, - "001": { - "id": "01-WifiNode-RxOneMulticastAddress" - }, - "002": { - "id": "02-WifiNode-RxTwoMulticastAddresses" - }, - "003": { - "id": "03-WifiNode-RxThreeMulticastAddresses" - }, - "004": { - "id": "04-WifiNode-RxFourMulticastAddresses" - }, - "005": { - "id": "WifiNetwork" - }, - "006": { - "id": "wifi0node" - }, - "007": { - "id": "wifi0net" - }, - "008": { - "id": "wifi0tap" - }, - "009": { - "id": "wifi0bridge" - }, - "010": { - "id": "wifi0" - }, - "011": { - "id": "wifi1node" - }, - "012": { - "id": "wifi1net" - }, - "013": { - "id": "wifi1tap" - }, - "014": { - "id": "wifi1bridge" - }, - "015": { - "id": "wifi1" - }, - "016": { - "id": "wifi2node" - }, - "017": { - "id": "wifi2net" - }, - "018": { - "id": "wifi2tap" - }, - "019": { - "id": "wifi2bridge" - }, - "020": { - "id": "wifi2" - }, - "021": { - "id": "wifi3node" - }, - "022": { - "id": "wifi3net" - }, - "023": { - "id": "wifi3tap" - }, - "024": { - "id": "wifi3bridge" - }, - "025": { - "id": "wifi3" - }, - "026": { - "id": "wifi4node" - }, - "027": { - "id": "wifi4net" - }, - "028": { - "id": "wifi4tap" - }, - "029": { - "id": "wifi4bridge" - }, - "030": { - "id": "wifi4" - } - }, - "link": { - "wifi0": { - "fix_hw_addr": null, - "network": "WifiNetwork", - "network_end": "happy007", - "node": "00-WifiNode-TxFourMulticastAddresses", - "node_end": "happy006", - "number": 0, - "tap": false, - "type": "wifi" - }, - "wifi1": { - "fix_hw_addr": null, - "network": "WifiNetwork", - "network_end": "happy012", - "node": "01-WifiNode-RxOneMulticastAddress", - "node_end": "happy011", - "number": 1, - "tap": false, - "type": "wifi" - }, - "wifi2": { - "fix_hw_addr": null, - "network": "WifiNetwork", - "network_end": "happy017", - "node": "02-WifiNode-RxTwoMulticastAddresses", - "node_end": "happy016", - "number": 2, - "tap": false, - "type": "wifi" - }, - "wifi3": { - "fix_hw_addr": null, - "network": "WifiNetwork", - "network_end": "happy022", - "node": "03-WifiNode-RxThreeMulticastAddresses", - "node_end": "happy021", - "number": 3, - "tap": false, - "type": "wifi" - }, - "wifi4": { - "fix_hw_addr": null, - "network": "WifiNetwork", - "network_end": "happy027", - "node": "04-WifiNode-RxFourMulticastAddresses", - "node_end": "happy026", - "number": 4, - "tap": false, - "type": "wifi" - } - }, - "netns": { - "00-WifiNode-TxFourMulticastAddresses": "000", - "01-WifiNode-RxOneMulticastAddress": "001", - "02-WifiNode-RxTwoMulticastAddresses": "002", - "03-WifiNode-RxThreeMulticastAddresses": "003", - "04-WifiNode-RxFourMulticastAddresses": "004", - "WifiNetwork": "005", - "wifi0": "010", - "wifi0bridge": "009", - "wifi0net": "007", - "wifi0node": "006", - "wifi0tap": "008", - "wifi1": "015", - "wifi1bridge": "014", - "wifi1net": "012", - "wifi1node": "011", - "wifi1tap": "013", - "wifi2": "020", - "wifi2bridge": "019", - "wifi2net": "017", - "wifi2node": "016", - "wifi2tap": "018", - "wifi3": "025", - "wifi3bridge": "024", - "wifi3net": "022", - "wifi3node": "021", - "wifi3tap": "023", - "wifi4": "030", - "wifi4bridge": "029", - "wifi4net": "027", - "wifi4node": "026", - "wifi4tap": "028" - }, - "network": { - "WifiNetwork": { - "gateway": null, - "interface": { - "wifi0": {}, - "wifi1": {}, - "wifi2": {}, - "wifi3": {}, - "wifi4": {} - }, - "prefix": { - "192.168.1": { - "mask": 24 - }, - "2001:0db8:0001:0002": { - "mask": 64 - } - }, - "state": "UP", - "type": "wifi" - } - }, - "node": { - "00-WifiNode-TxFourMulticastAddresses": { - "interface": { - "wlan0": { - "ip": { - "192.168.1.2": { - "mask": 24 - }, - "2001:0db8:0001:0002:6a39:38ff:fe17:a76c": { - "mask": 64 - } - }, - "link": "wifi0", - "type": "wifi" - } - }, - "process": {}, - "route": {}, - "tmux": {}, - "type": null - }, - "01-WifiNode-RxOneMulticastAddress": { - "interface": { - "wlan0": { - "ip": { - "192.168.1.3": { - "mask": 24 - }, - "2001:0db8:0001:0002:fe6a:fbff:fe18:7f26": { - "mask": 64 - } - }, - "link": "wifi1", - "type": "wifi" - } - }, - "process": {}, - "route": {}, - "tmux": {}, - "type": null - }, - "02-WifiNode-RxTwoMulticastAddresses": { - "interface": { - "wlan0": { - "ip": { - "192.168.1.4": { - "mask": 24 - }, - "2001:0db8:0001:0002:0289:1bff:feec:3e24": { - "mask": 64 - } - }, - "link": "wifi2", - "type": "wifi" - } - }, - "process": {}, - "route": {}, - "tmux": {}, - "type": null - }, - "03-WifiNode-RxThreeMulticastAddresses": { - "interface": { - "wlan0": { - "ip": { - "192.168.1.5": { - "mask": 24 - }, - "2001:0db8:0001:0002:bacf:b4ff:fe58:3014": { - "mask": 64 - } - }, - "link": "wifi3", - "type": "wifi" - } - }, - "process": {}, - "route": {}, - "tmux": {}, - "type": null - }, - "04-WifiNode-RxFourMulticastAddresses": { - "interface": { - "wlan0": { - "ip": { - "192.168.1.6": { - "mask": 24 - }, - "2001:0db8:0001:0002:06ce:33ff:fe39:08af": { - "mask": 64 - } - }, - "link": "wifi4", - "type": "wifi" - } - }, - "process": {}, - "route": {}, - "tmux": {}, - "type": null - } - } -} diff --git a/src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.sh b/src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.sh deleted file mode 100755 index cbdc49a0e6a7e8..00000000000000 --- a/src/test_driver/happy/topologies/standalone/five_nodes_on_wifi.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -# -# Copyright (c) 2020 Project CHIP Authors -# Copyright (c) 2018 Google LLC. -# All rights reserved. -# -# 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. -# - -# Steps to manually build five_nodes_on_wifi.json - -happy-node-add 00-WifiNode-TxFourMulticastAddresses -happy-node-add 01-WifiNode-RxOneMulticastAddress -happy-node-add 02-WifiNode-RxTwoMulticastAddresses -happy-node-add 03-WifiNode-RxThreeMulticastAddresses -happy-node-add 04-WifiNode-RxFourMulticastAddresses - -happy-network-add WifiNetwork wifi -happy-network-address WifiNetwork 2001:db8:1:2:: -happy-network-address WifiNetwork 192.168.1.0 - -happy-node-join 00-WifiNode-TxFourMulticastAddresses WifiNetwork -happy-node-join 01-WifiNode-RxOneMulticastAddress WifiNetwork -happy-node-join 02-WifiNode-RxTwoMulticastAddresses WifiNetwork -happy-node-join 03-WifiNode-RxThreeMulticastAddresses WifiNetwork -happy-node-join 04-WifiNode-RxFourMulticastAddresses WifiNetwork - -# happy-state -s five_nodes_on_wifi.json diff --git a/third_party/happy/BUILD.gn b/third_party/happy/BUILD.gn deleted file mode 100644 index 6857850759a301..00000000000000 --- a/third_party/happy/BUILD.gn +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2020 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. - -import("//build_overrides/pigweed.gni") -import("$dir_pw_build/python.gni") - -pw_python_package("happy") { - setup = [ "repo/setup.py" ] - static_analysis = [] -} diff --git a/third_party/happy/repo b/third_party/happy/repo deleted file mode 160000 index 72a4b6e57cb0bb..00000000000000 --- a/third_party/happy/repo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 72a4b6e57cb0bb1cb4157ab11779f7be5a6e7f6d