| /* |
| * |
| * Copyright (c) 2021 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. |
| */ |
| |
| #include <AppConfig.h> |
| #include <FreeRTOS.h> |
| #include <PigweedLogger.h> |
| #include <PigweedLoggerMutex.h> |
| #include <cstring> |
| #include <init_efrPlatform.h> |
| #include <lib/support/CHIPMem.h> |
| #include <lib/support/CHIPPlatformMemory.h> |
| #include <lib/support/UnitTestRegistration.h> |
| #include <mbedtls/platform.h> |
| #include <nl_test_service/nl_test.rpc.pb.h> |
| #include <nlunit-test.h> |
| #include <pigweed/RpcService.h> |
| #include <platform/CHIPDeviceLayer.h> |
| #include <platform/KeyValueStoreManager.h> |
| #include <sl_system_kernel.h> |
| #include <task.h> |
| |
| extern "C" int printf(const char * format, ...) |
| { |
| va_list args; |
| va_start(args, format); |
| chip::Logging::LogV(chip::Logging::kLogModule_NotSpecified, chip::Logging::kLogCategory_Progress, format, args); |
| va_end(args); |
| return 0; |
| } |
| |
| namespace chip::rpc { |
| |
| class NlTest : public pw_rpc::nanopb::NlTest::Service<NlTest> |
| { |
| public: |
| void Run(const pw_protobuf_Empty & request, ServerWriter<chip_rpc_Event> & writer) |
| { |
| stream_writer = &writer; |
| nlTestSetLogger(&nl_test_logger); |
| |
| RunRegisteredUnitTests(); |
| |
| stream_writer = nullptr; |
| writer.Finish(); |
| } |
| |
| private: |
| static ServerWriter<chip_rpc_Event> * stream_writer; |
| nl_test_output_logger_t nl_test_logger = { |
| chip_nl_test_log_name, chip_nl_test_log_initialize, chip_nl_test_log_terminate, chip_nl_test_log_setup, |
| chip_nl_test_log_test, chip_nl_test_log_teardown, chip_nl_test_log_statTest, chip_nl_test_log_statAssert, |
| }; |
| |
| static void StreamLogEvent(const chip_rpc_Event & event) |
| { |
| if (!stream_writer) |
| { |
| return; |
| } |
| stream_writer->Write(event); |
| } |
| |
| static void chip_nl_test_log_name(struct _nlTestSuite * inSuite) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_suite_start_tag; |
| snprintf(event.type.test_suite_start.suite_name, sizeof(event.type.test_suite_start.suite_name), "%s", inSuite->name); |
| StreamLogEvent(event); |
| } |
| |
| static void chip_nl_test_log_initialize(struct _nlTestSuite * inSuite, int inResult, int inWidth) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_case_initialize_tag; |
| snprintf(event.type.test_case_initialize.suite_name, sizeof(event.type.test_case_initialize.suite_name), "%s", |
| inSuite->name); |
| event.type.test_case_initialize.failed = inResult == FAILURE; |
| StreamLogEvent(event); |
| } |
| static void chip_nl_test_log_terminate(struct _nlTestSuite * inSuite, int inResult, int inWidth) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_case_terminate_tag; |
| snprintf(event.type.test_case_terminate.suite_name, sizeof(event.type.test_case_terminate.suite_name), "%s", inSuite->name); |
| event.type.test_case_terminate.failed = inResult == FAILURE; |
| StreamLogEvent(event); |
| } |
| |
| static void chip_nl_test_log_setup(struct _nlTestSuite * inSuite, int inResult, int inWidth) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_suite_setup_tag; |
| snprintf(event.type.test_suite_setup.suite_name, sizeof(event.type.test_suite_setup.suite_name), "%s", inSuite->name); |
| event.type.test_suite_setup.failed = inResult == FAILURE; |
| StreamLogEvent(event); |
| } |
| |
| static void chip_nl_test_log_teardown(struct _nlTestSuite * inSuite, int inResult, int inWidth) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_suite_teardown_tag; |
| snprintf(event.type.test_suite_teardown.suite_name, sizeof(event.type.test_suite_teardown.suite_name), "%s", inSuite->name); |
| event.type.test_suite_teardown.failed = inResult == FAILURE; |
| StreamLogEvent(event); |
| } |
| |
| static void chip_nl_test_log_test(struct _nlTestSuite * inSuite, int inWidth, int inIndex) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_case_run_tag; |
| snprintf(event.type.test_case_run.suite_name, sizeof(event.type.test_case_run.suite_name), "%s", inSuite->name); |
| snprintf(event.type.test_case_run.test_case_name, sizeof(event.type.test_case_run.test_case_name), "%s", |
| inSuite->tests[inIndex].name); |
| event.type.test_case_run.failed = inSuite->flagError; |
| StreamLogEvent(event); |
| } |
| |
| static void chip_nl_test_log_statTest(struct _nlTestSuite * inSuite) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_suite_tests_run_summary_tag; |
| snprintf(event.type.test_suite_tests_run_summary.suite_name, sizeof(event.type.test_suite_tests_run_summary.suite_name), |
| "%s", inSuite->name); |
| event.type.test_suite_tests_run_summary.total_count = inSuite->runTests; |
| event.type.test_suite_tests_run_summary.failed_count = inSuite->failedTests; |
| StreamLogEvent(event); |
| } |
| |
| static void chip_nl_test_log_statAssert(struct _nlTestSuite * inSuite) |
| { |
| chip_rpc_Event event = chip_rpc_Event_init_default; |
| event.which_type = chip_rpc_Event_test_suite_asserts_summary_tag; |
| snprintf(event.type.test_suite_asserts_summary.suite_name, sizeof(event.type.test_suite_asserts_summary.suite_name), "%s", |
| inSuite->name); |
| event.type.test_suite_asserts_summary.total_count = inSuite->performedAssertions; |
| event.type.test_suite_asserts_summary.failed_count = inSuite->failedAssertions; |
| StreamLogEvent(event); |
| } |
| }; |
| |
| NlTest::ServerWriter<chip_rpc_Event> * NlTest::stream_writer = 0; |
| |
| } // namespace chip::rpc |
| |
| namespace { |
| |
| #define TEST_TASK_STACK_SIZE 16 * 1024 |
| #define TEST_TASK_PRIORITY 1 |
| |
| static TaskHandle_t sTestTaskHandle; |
| StaticTask_t sTestTaskBuffer; |
| StackType_t sTestTaskStack[TEST_TASK_STACK_SIZE]; |
| |
| chip::rpc::NlTest nl_test_service; |
| |
| void RegisterServices(pw::rpc::Server & server) |
| { |
| server.RegisterService(nl_test_service); |
| } |
| |
| void RunRpcService(void *) |
| { |
| Start(RegisterServices, &::chip::rpc::logger_mutex); |
| } |
| |
| } // namespace |
| |
| int main(void) |
| { |
| init_efrPlatform(); |
| PigweedLogger::init(); |
| mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); |
| |
| chip::Platform::MemoryInit(); |
| |
| chip::DeviceLayer::PlatformMgr().InitChipStack(); |
| |
| SILABS_LOG("***** CHIP EFR32 device tests *****\r\n"); |
| |
| // Start RPC service which runs the tests. |
| sTestTaskHandle = xTaskCreateStatic(RunRpcService, "RPC_TEST_TASK", ArraySize(sTestTaskStack), nullptr, TEST_TASK_PRIORITY, |
| sTestTaskStack, &sTestTaskBuffer); |
| SILABS_LOG("Starting FreeRTOS scheduler"); |
| sl_system_kernel_start(); |
| |
| // Should never get here. |
| SILABS_LOG("vTaskStartScheduler() failed"); |
| return -1; |
| } |