diff --git a/.github/workflows/ctt-test.yml b/.github/workflows/ctt-test.yml index 1b77ed8f8..ace85547d 100644 --- a/.github/workflows/ctt-test.yml +++ b/.github/workflows/ctt-test.yml @@ -28,7 +28,7 @@ jobs: - name: Archive results if: success() || failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: logs path: results/*.octt diff --git a/.github/workflows/plgd-device-test-with-cfg.yml b/.github/workflows/plgd-device-test-with-cfg.yml index 3549a172d..e433c812b 100644 --- a/.github/workflows/plgd-device-test-with-cfg.yml +++ b/.github/workflows/plgd-device-test-with-cfg.yml @@ -109,12 +109,13 @@ jobs: docker run --rm --network=host -v `pwd`/${{ env.CERT_PATH }}:/pki_certs ${{ env.TEST_CLOUD_SERVER_IMAGE }} \ -test.parallel 1 -test.v - - name: Get output file name + - name: Generate file name and artifact name if: ${{ inputs.coverage }} id: coverage run: | SUFFIX=`echo "-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} ${{ inputs.build_args }} ${{ inputs.name }} -DBUILD_TESTING=ON" | sha1sum | cut -f 1 -d ' '` echo "filename=coverage-plgd-device-${SUFFIX}.json" >> $GITHUB_OUTPUT + echo "artifact=plgd-device-${SUFFIX}-coverage" >> $GITHUB_OUTPUT - name: Gather coverage data if: ${{ inputs.coverage }} @@ -129,9 +130,9 @@ jobs: - name: Upload coverage data if: ${{ inputs.coverage }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: plgd-device-coverage + name: ${{ steps.coverage.outputs.artifact }} path: data/coverage/${{ steps.coverage.outputs.filename }} if-no-files-found: error retention-days: 1 diff --git a/.github/workflows/plgd-hub-test-with-cfg.yml b/.github/workflows/plgd-hub-test-with-cfg.yml index 4de85f19a..e33881d81 100644 --- a/.github/workflows/plgd-hub-test-with-cfg.yml +++ b/.github/workflows/plgd-hub-test-with-cfg.yml @@ -103,12 +103,13 @@ jobs: - name: Run plgd hub tests image run: docker run --rm --network=host ${{ inputs.hub_args }} ${{ env.TEST_CLOUD_SERVER_IMAGE }} - - name: Get output file name + - name: Generate file name and artifact name if: ${{ inputs.coverage }} id: coverage run: | SUFFIX=`echo "-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} ${{ inputs.build_args }} ${{ inputs.args }} ${{ inputs.docker_args }} ${{ inputs.hub_args }} ${{ inputs.name }} -DBUILD_TESTING=ON" | sha1sum | cut -f 1 -d ' '` echo "filename=coverage-plgd-hub-${SUFFIX}.json" >> $GITHUB_OUTPUT + echo "artifact=plgd-hub-${SUFFIX}-coverage" >> $GITHUB_OUTPUT - name: Gather coverage data if: ${{ inputs.coverage }} @@ -122,9 +123,9 @@ jobs: - name: Upload coverage data if: ${{ inputs.coverage }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: plgd-hub-coverage + name: ${{ steps.coverage.outputs.artifact }} path: data/coverage/${{ steps.coverage.outputs.filename }} if-no-files-found: error retention-days: 1 diff --git a/.github/workflows/sonar-cloud-analysis.yml b/.github/workflows/sonar-cloud-analysis.yml index 91e63c816..c5eb24cc8 100644 --- a/.github/workflows/sonar-cloud-analysis.yml +++ b/.github/workflows/sonar-cloud-analysis.yml @@ -113,9 +113,10 @@ jobs: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build --verbose --target client-server-static --target all - name: Get coverage from all tests job - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - path: tools/ + merge-multiple: true + path: tools/coverage/ - name: Install gcovr run: | @@ -126,7 +127,7 @@ jobs: run: | cd tools # ls -lR . - gcovr --add-tracefile "unit-test-coverage/*coverage*.json" --add-tracefile "plgd-device-coverage/*coverage*.json" --add-tracefile "plgd-hub-coverage/*coverage*.json" --sonarqube --output "coverage.xml" --verbose + gcovr --add-tracefile "coverage/*coverage*.json" --sonarqube --output "coverage.xml" --verbose - name: Run sonar-scanner env: diff --git a/.github/workflows/unit-test-with-cfg.yml b/.github/workflows/unit-test-with-cfg.yml index 5197f9b77..0f2abbc42 100644 --- a/.github/workflows/unit-test-with-cfg.yml +++ b/.github/workflows/unit-test-with-cfg.yml @@ -119,12 +119,13 @@ jobs: cd build ctest --verbose --label-regex "oc-unittest" - - name: Get output file name + - name: Generate file name and artifact name if: ${{ inputs.coverage }} id: coverage run: | SUFFIX=`echo "-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} ${{ steps.cmake_flags.outputs.compiler }} ${{ inputs.build_args }} -DBUILD_TESTING=ON" | sha1sum | cut -f 1 -d ' '` echo "filename=coverage-unix-${SUFFIX}.json" >> $GITHUB_OUTPUT + echo "artifact=unit-test-${SUFFIX}-coverage" >> $GITHUB_OUTPUT - name: Collect coverage data if: ${{ inputs.coverage }} @@ -135,9 +136,9 @@ jobs: - name: Upload coverage data if: ${{ inputs.coverage }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: unit-test-coverage + name: ${{ steps.coverage.outputs.artifact }} path: tools/${{ steps.coverage.outputs.filename }} if-no-files-found: error retention-days: 1 diff --git a/api/cloud/oc_cloud_context.c b/api/cloud/oc_cloud_context.c index 1bcb3fe4c..d944c9185 100644 --- a/api/cloud/oc_cloud_context.c +++ b/api/cloud/oc_cloud_context.c @@ -60,8 +60,8 @@ need_to_reinitialize_cloud_storage(const oc_cloud_context_t *ctx) return cloud_is_deregistering(ctx); } -static void -cloud_on_server_change(void *data) +void +cloud_context_on_server_change(void *data) { oc_cloud_context_t *ctx = (oc_cloud_context_t *)data; if (ctx->cloud_manager) { @@ -97,7 +97,7 @@ cloud_context_init(size_t device) ctx->cloud_ep_state = OC_SESSION_DISCONNECTED; ctx->cloud_ep = oc_new_endpoint(); ctx->selected_identity_cred_id = -1; - oc_cloud_store_initialize(&ctx->store, cloud_on_server_change, ctx); + oc_cloud_store_initialize(&ctx->store, cloud_context_on_server_change, ctx); oc_cloud_store_load(&ctx->store); ctx->store.status &= ~(OC_CLOUD_LOGGED_IN | OC_CLOUD_TOKEN_EXPIRY | OC_CLOUD_REFRESHED_TOKEN | diff --git a/api/cloud/oc_cloud_context_internal.h b/api/cloud/oc_cloud_context_internal.h index 66f8e3660..e6d018039 100644 --- a/api/cloud/oc_cloud_context_internal.h +++ b/api/cloud/oc_cloud_context_internal.h @@ -171,6 +171,10 @@ void cloud_context_clear_access_token(oc_cloud_context_t *ctx) OC_NONNULL(); bool cloud_context_has_refresh_token(const oc_cloud_context_t *ctx) OC_NONNULL(); +/** @brief Callback invoekd by ctx::store::ci_servers when the selected cloud + * server is changed */ +void cloud_context_on_server_change(void *data) OC_NONNULL(); + /** @brief Initialize the registration context */ void oc_cloud_registration_context_init(oc_cloud_registration_context_t *regctx, const oc_endpoint_addresses_t *servers) diff --git a/api/cloud/oc_cloud_endpoints.c b/api/cloud/oc_cloud_endpoints.c index af5740664..26e1b9c9c 100644 --- a/api/cloud/oc_cloud_endpoints.c +++ b/api/cloud/oc_cloud_endpoints.c @@ -68,11 +68,14 @@ oc_cloud_endpoint_addresses_set(oc_endpoint_addresses_t *ea, } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START char selected_id[OC_UUID_LEN] = { 0 }; oc_uuid_to_str(&selected_uuid, selected_id, OC_UUID_LEN); - OC_CLOUD_DBG( - "reinitialized cloud endpoint addresses, selected cloud (uri: %s, sid: %s)", - oc_string(*selected_uri), selected_id); + OC_CLOUD_DBG("reinitialized cloud endpoint addresses, selected cloud (uri: " + "%s, sid: %s)", + selected_uri != NULL ? oc_string(*selected_uri) : "NULL", + selected_id); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ if (srep.servers == NULL) { return true; diff --git a/api/cloud/oc_cloud_manager.c b/api/cloud/oc_cloud_manager.c index 092524ae4..5e20ed418 100644 --- a/api/cloud/oc_cloud_manager.c +++ b/api/cloud/oc_cloud_manager.c @@ -256,28 +256,6 @@ cloud_start_process(oc_cloud_context_t *ctx) _oc_signal_event_loop(); } -static uint64_t -refresh_token_expires_in_ms(int64_t expires_in_ms) -{ - if (expires_in_ms <= 0) { - return 0; - } - - if (expires_in_ms > (int64_t)MILLISECONDS_PER_HOUR) { - // if time is more than 1h then set expires to (expires_in_ms - 10min). - return (uint64_t)(expires_in_ms - (int64_t)(10 * MILLISECONDS_PER_MINUTE)); - } - if (expires_in_ms > (int64_t)(4 * MILLISECONDS_PER_MINUTE)) { - // if time is more than 240sec then set expires to (expires_in_ms - 2min). - return (uint64_t)(expires_in_ms - (int64_t)(2 * MILLISECONDS_PER_MINUTE)); - } - if (expires_in_ms > (int64_t)(20 * MILLISECONDS_PER_SECOND)) { - // if time is more than 20sec then set expires to (expires_in_ms - 10sec). - return (uint64_t)(expires_in_ms - (int64_t)(10 * MILLISECONDS_PER_SECOND)); - } - return (uint64_t)expires_in_ms; -} - static bool cloud_is_connection_error_or_timeout(oc_status_t code) { @@ -388,7 +366,7 @@ cloud_manager_handle_redirect_response(oc_cloud_context_t *ctx, oc_endpoint_addresses_add(&ctx->store.ci_servers, oc_endpoint_address_make_view_with_uuid( oc_string_view2(redirecturi), sid)) == NULL) { - OC_ERR("failed to add server to the list"); + OC_CLOUD_ERR("failed to add server to the list"); return false; } @@ -697,6 +675,26 @@ on_keepalive_response(oc_cloud_context_t *ctx, bool response_received, return true; } +uint64_t +cloud_manager_calculate_refresh_token_expiration(uint64_t expires_in_ms) +{ + assert(expires_in_ms > 0); + + if (expires_in_ms > (uint64_t)MILLISECONDS_PER_HOUR) { + // if time is more than 1h then set expires to (expires_in_ms - 10min). + return expires_in_ms - (uint64_t)(10 * MILLISECONDS_PER_MINUTE); + } + if (expires_in_ms > (int64_t)(4 * MILLISECONDS_PER_MINUTE)) { + // if time is more than 240sec then set expires to (expires_in_ms - 2min). + return expires_in_ms - (uint64_t)(2 * MILLISECONDS_PER_MINUTE); + } + if (expires_in_ms > (int64_t)(20 * MILLISECONDS_PER_SECOND)) { + // if time is more than 20sec then set expires to (expires_in_ms - 10sec). + return expires_in_ms - (uint64_t)(10 * MILLISECONDS_PER_SECOND); + } + return (uint64_t)0; +} + static void cloud_manager_login_handler(oc_client_response_t *data) { @@ -720,8 +718,8 @@ cloud_manager_login_handler(oc_client_response_t *data) if (ctx->store.expires_in > 0) { oc_reset_delayed_callback_ms( ctx, cloud_manager_refresh_token_async, - refresh_token_expires_in_ms(ctx->store.expires_in * - MILLISECONDS_PER_SECOND)); + cloud_manager_calculate_refresh_token_expiration( + ctx->store.expires_in * MILLISECONDS_PER_SECOND)); } oc_reset_delayed_callback(ctx, cloud_manager_callback_handler_async, 0); return; diff --git a/api/cloud/oc_cloud_manager_internal.h b/api/cloud/oc_cloud_manager_internal.h index eaed61a57..b97e40ce2 100644 --- a/api/cloud/oc_cloud_manager_internal.h +++ b/api/cloud/oc_cloud_manager_internal.h @@ -64,6 +64,20 @@ bool cloud_manager_handle_redirect_response(oc_cloud_context_t *ctx, const oc_rep_t *payload) OC_NONNULL(); +/** + * @brief Calculate the expiration time of the refresh token. + * + * The expiration time is used to determine when the refresh token should be + * refreshed. It should be less than the actual expiration time of the token, so + * it can be refreshed before it really expires. + * + * + * @param expires_in_ms expires_in value in milliseconds (must be >0) + * @return uint64_t expiration time in milliseconds + */ +uint64_t cloud_manager_calculate_refresh_token_expiration( + uint64_t expires_in_ms); + /** * @brief Parse refresh token response retrieved from the server and store the * data to cloud context. diff --git a/api/cloud/oc_cloud_rd.c b/api/cloud/oc_cloud_rd.c index 59ec46dc0..6df1bf638 100644 --- a/api/cloud/oc_cloud_rd.c +++ b/api/cloud/oc_cloud_rd.c @@ -274,10 +274,12 @@ cloud_delete_resources(oc_cloud_context_t *ctx) } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START for (const oc_link_t *link = partition.not_deleted; link != NULL; link = link->next) { OC_CLOUD_DBG("link(ins=%" PRId64 ") not unpublished", link->ins); } + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ ctx->rd_delete_resources = partition.not_deleted; rd_link_free(&partition.deleted); @@ -369,7 +371,7 @@ oc_cloud_publish_resources(size_t device) { oc_cloud_context_t *ctx = oc_cloud_get_context(device); if (ctx == NULL) { - OC_ERR("cannot publish resource: invalid device(%zu)", device); + OC_CLOUD_ERR("cannot publish resource: invalid device(%zu)", device); return -1; } publish_published_resources(ctx); diff --git a/api/cloud/oc_cloud_resource.c b/api/cloud/oc_cloud_resource.c index 3b9f0ca84..5951772fe 100644 --- a/api/cloud/oc_cloud_resource.c +++ b/api/cloud/oc_cloud_resource.c @@ -157,7 +157,7 @@ cloud_update_from_request(oc_cloud_context_t *ctx, const oc_request_t *request) if (sid != NULL) { oc_string_view_t sidv = oc_string_view2(sid); if (oc_str_to_uuid_v1(sidv.data, sidv.length, &data.sid) < 0) { - OC_ERR("failed parsing sid(%s)", sidv.data); + OC_CLOUD_ERR("failed parsing sid(%s)", sidv.data); return false; } } @@ -165,7 +165,7 @@ cloud_update_from_request(oc_cloud_context_t *ctx, const oc_request_t *request) const oc_rep_t *ci_servers = oc_rep_get_by_type_and_key( request->request_payload, OC_REP_OBJECT_ARRAY, OCF_COAPCLOUDCONF_PROP_CISERVERS, - OC_CHAR_ARRAY_LEN(OCF_COAPCLOUDCONF_PROP_CISERVER)); + OC_CHAR_ARRAY_LEN(OCF_COAPCLOUDCONF_PROP_CISERVERS)); if (ci_servers != NULL) { data.ci_servers = ci_servers->value.object_array; } diff --git a/api/cloud/oc_cloud_store.c b/api/cloud/oc_cloud_store.c index db075d9bd..a0b1954d0 100644 --- a/api/cloud/oc_cloud_store.c +++ b/api/cloud/oc_cloud_store.c @@ -121,7 +121,7 @@ oc_cloud_store_dump(const oc_cloud_store_t *store) long ret = oc_storage_data_save(OC_CLOUD_STORE_NAME, store->device, store_encode_cloud, store); if (ret <= 0) { - OC_ERR("cannot dump cloud to storage: error(%ld)", ret); + OC_CLOUD_ERR("cannot dump cloud to storage: error(%ld)", ret); return false; } return true; @@ -304,7 +304,7 @@ oc_cloud_store_decode(const oc_rep_t *rep, oc_cloud_store_t *store) // copy data to store if ((csd.ci_server != NULL || csd.ci_servers != NULL) && !cloud_store_set_servers(store, csd.ci_server, csd.sid, csd.ci_servers)) { - OC_WRN("failed to set cloud servers from storage"); + OC_CLOUD_WRN("failed to set cloud servers from storage"); } if (csd.auth_provider != NULL) { @@ -332,7 +332,7 @@ store_decode_cloud(const oc_rep_t *rep, size_t device, void *data) (void)device; oc_cloud_store_t *store = (oc_cloud_store_t *)data; if (!oc_cloud_store_decode(rep, store)) { - OC_ERR("cannot load cloud: cannot decode representation"); + OC_CLOUD_ERR("cannot load cloud: cannot decode representation"); return -1; } return 0; @@ -343,11 +343,11 @@ oc_cloud_store_load(oc_cloud_store_t *store) { if (oc_storage_data_load(OC_CLOUD_STORE_NAME, store->device, store_decode_cloud, store) <= 0) { - OC_DBG("failed to load cloud from storage"); + OC_CLOUD_DBG("failed to load cloud from storage"); oc_cloud_store_reinitialize(store); return false; } - OC_DBG("cloud loaded from storage"); + OC_CLOUD_DBG("cloud loaded from storage"); return true; } diff --git a/api/cloud/rd_client.c b/api/cloud/rd_client.c index 2ffc00aa9..46696b5fe 100644 --- a/api/cloud/rd_client.c +++ b/api/cloud/rd_client.c @@ -158,7 +158,7 @@ rd_prepare_write_buffer(oc_write_buffer_t *wb, char *buffer, size_t buffer_size, // enough room to write the "di={id}" part if (buffer_size <= /*di=*/3 + id.length) { - OC_ERR("buffer too small"); + OC_CLOUD_ERR("buffer too small"); return false; } wb->buffer = buffer; @@ -212,10 +212,10 @@ rd_delete_send_packet(const oc_endpoint_t *endpoint, oc_string_view_t query, void *data) { rd_delete_packet_t *pkt = (rd_delete_packet_t *)data; - OC_DBG("Unpublishing links (query=%s)", query.data); + OC_CLOUD_DBG("Unpublishing links (query=%s)", query.data); if (!oc_do_delete(OC_RSRVD_RD_URI, endpoint, query.data, pkt->handler, pkt->qos, pkt->user_data)) { - OC_ERR("failed to unpublish links (query=%s)", query.data); + OC_CLOUD_ERR("failed to unpublish links (query=%s)", query.data); return false; } return true; diff --git a/api/cloud/unittest/cloud_manager_test.cpp b/api/cloud/unittest/cloud_manager_test.cpp index dae83ebbc..b64222f20 100644 --- a/api/cloud/unittest/cloud_manager_test.cpp +++ b/api/cloud/unittest/cloud_manager_test.cpp @@ -45,6 +45,7 @@ using namespace std::chrono_literals; // cannot use lower value than 1s because oc_cloud_schedule_action_t::timeout is // in seconds static constexpr auto kTimeout = 1s; +static constexpr auto kTestServer = OC_STRING_VIEW("coap://224.0.1.187:5683"); class TestCloudManager : public testing::Test { public: @@ -66,15 +67,16 @@ class TestCloudManager : public testing::Test { memset(&m_context, 0, sizeof(m_context)); m_context.cloud_ep = oc_new_endpoint(); memset(m_context.cloud_ep, 0, sizeof(oc_endpoint_t)); - oc_cloud_store_initialize(&m_context.store, nullptr, nullptr); - oc_string_view_t ep = OC_STRING_VIEW("coap://224.0.1.187:5683"); + oc_cloud_store_initialize(&m_context.store, cloud_context_on_server_change, + &m_context); oc_uuid_t sid; oc_gen_uuid(&sid); - ASSERT_NE(nullptr, oc_endpoint_addresses_add( - &m_context.store.ci_servers, - oc_endpoint_address_make_view_with_uuid(ep, sid))); - ASSERT_TRUE( - oc_endpoint_addresses_select_by_uri(&m_context.store.ci_servers, ep)); + ASSERT_NE(nullptr, + oc_endpoint_addresses_add( + &m_context.store.ci_servers, + oc_endpoint_address_make_view_with_uuid(kTestServer, sid))); + ASSERT_TRUE(oc_endpoint_addresses_select_by_uri(&m_context.store.ci_servers, + kTestServer)); std::string uid = "501"; oc_set_string(&m_context.store.uid, uid.c_str(), uid.length()); std::string token = "access_token"; @@ -86,6 +88,7 @@ class TestCloudManager : public testing::Test { void TearDown() override { + oc_cloud_set_schedule_action(&m_context, nullptr, nullptr); oc_cloud_manager_set_retry_timeouts(nullptr, 0); oc_free_endpoint(m_context.cloud_ep); @@ -132,8 +135,6 @@ TEST_F(TestCloudManager, cloud_manager_start_initialized_schedule_turnoff) EXPECT_EQ(0, m_context.retry.refresh_token_count); EXPECT_EQ(CLOUD_ERROR_CONNECT, m_context.last_error); EXPECT_EQ(OC_CLOUD_INITIALIZED, m_context.store.status); - - oc_cloud_set_schedule_action(&m_context, nullptr, nullptr); } TEST_F(TestCloudManager, @@ -169,8 +170,6 @@ TEST_F(TestCloudManager, EXPECT_EQ(0, m_context.retry.refresh_token_count); EXPECT_EQ(CLOUD_ERROR_CONNECT, m_context.last_error); EXPECT_EQ(OC_CLOUD_INITIALIZED, m_context.store.status); - - oc_cloud_set_schedule_action(&m_context, nullptr, nullptr); } TEST_F(TestCloudManager, cloud_manager_start_initialized_without_retry_f) @@ -203,8 +202,6 @@ TEST_F(TestCloudManager, cloud_manager_start_initialized_without_retry_f) EXPECT_EQ(0, m_context.retry.refresh_token_count); EXPECT_EQ(CLOUD_ERROR_CONNECT, m_context.last_error); EXPECT_EQ(OC_CLOUD_INITIALIZED, m_context.store.status); - - oc_cloud_set_schedule_action(&m_context, nullptr, nullptr); } TEST_F(TestCloudManager, cloud_manager_start_initialized_f) @@ -257,8 +254,6 @@ TEST_F(TestCloudManager, cloud_manager_start_registered_without_retry_and_uid_f) EXPECT_EQ(CLOUD_ERROR_CONNECT, m_context.last_error); EXPECT_EQ(OC_CLOUD_INITIALIZED | OC_CLOUD_REGISTERED | OC_CLOUD_FAILURE, m_context.store.status); - - oc_cloud_set_schedule_action(&m_context, nullptr, nullptr); } TEST_F(TestCloudManager, cloud_manager_start_registered_f) @@ -311,8 +306,6 @@ TEST_F(TestCloudManager, EXPECT_EQ(CLOUD_ERROR_REFRESH_ACCESS_TOKEN, m_context.last_error); EXPECT_EQ(OC_CLOUD_INITIALIZED | OC_CLOUD_REGISTERED | OC_CLOUD_FAILURE, m_context.store.status); - - oc_cloud_set_schedule_action(&m_context, nullptr, nullptr); } TEST_F(TestCloudManager, cloud_manager_start_with_refresh_token_f) @@ -349,20 +342,78 @@ TEST_F(TestCloudManager, cloud_manager_select_next_server_on_retry) ASSERT_NE(nullptr, ep); ASSERT_FALSE( oc_endpoint_addresses_is_selected(&m_context.store.ci_servers, uri)); + // default cloud server (127.0.0.1), kTestServer and uri + ASSERT_EQ(3, oc_endpoint_addresses_size(&m_context.store.ci_servers)); - // When + ASSERT_TRUE(oc_endpoint_addresses_is_selected(&m_context.store.ci_servers, + kTestServer)); m_context.store.status = OC_CLOUD_INITIALIZED; m_context.store.cps = OC_CPS_READYTOREGISTER; - cloud_manager_start(&m_context); + oc_cloud_manager_start(&m_context, nullptr, nullptr); // by default: first retry should happen timeout + jitter // ([timeout/2..timeout]) (see default_schedule_action) - oc::TestDevice::PoolEventsMsV1( - /*timeout*/ kTimeout + /*max possible jitter*/ kTimeout, true); - cloud_manager_stop(&m_context); + auto interval = (/* 3 servers to try */ 3) * + (/*timeout*/ kTimeout + /*max possible jitter*/ kTimeout); + oc::TestDevice::PoolEventsMsV1(interval, true); + + // the retries should loop all servers and loop back to the original + EXPECT_TRUE(oc_endpoint_addresses_is_selected(&m_context.store.ci_servers, + kTestServer)); + oc_cloud_manager_stop(&m_context); +} + +TEST_F(TestCloudManager, cloud_manager_select_next_server_on_custom_retry) +{ + struct schedule_action_t + { + oc_cloud_context_t *ctx; + bool epChanged; + }; + schedule_action_t scheduleAction = { &m_context, false }; + oc_cloud_set_schedule_action( + &m_context, + [](oc_cloud_action_t action, uint8_t retry, uint64_t *delay, + uint16_t *timeout, void *data) -> bool { + if (action == OC_CLOUD_ACTION_REGISTER && retry == 0) { + *delay = 0; + *timeout = kTimeout.count(); + return true; + } + auto *sact = static_cast(data); + if (!sact->epChanged) { + oc_endpoint_addresses_select_next(&sact->ctx->store.ci_servers); + sact->epChanged = true; + } + return false; + }, + &scheduleAction); + + oc_string_view_t uri = OC_STRING_VIEW("coap://13.3.7.187:5683"); + oc_uuid_t sid; + oc_gen_uuid(&sid); + auto *ep = oc_endpoint_addresses_add( + &m_context.store.ci_servers, + oc_endpoint_address_make_view_with_uuid(uri, sid)); + ASSERT_NE(nullptr, ep); + ASSERT_FALSE( + oc_endpoint_addresses_is_selected(&m_context.store.ci_servers, uri)); + ASSERT_EQ(3, oc_endpoint_addresses_size(&m_context.store.ci_servers)); + + ASSERT_TRUE(oc_endpoint_addresses_is_selected(&m_context.store.ci_servers, + kTestServer)); + m_context.store.status = OC_CLOUD_INITIALIZED; + m_context.store.cps = OC_CPS_READYTOREGISTER; + oc_cloud_manager_start(&m_context, nullptr, nullptr); + + // 2 servers should be tried -> after the first server is tried, the schedule + // action invokes oc_endpoint_addresses_select_next but only once; after that + // the retry should stop because the server selection was not changed + auto interval = (/* 2 servers to try */ 2) * (/*timeout*/ kTimeout); + oc::TestDevice::PoolEventsMsV1(interval, true); - // Then EXPECT_TRUE( oc_endpoint_addresses_is_selected(&m_context.store.ci_servers, uri)); + oc_cloud_manager_stop(&m_context); } #endif /* !OC_SECURITY */ @@ -448,6 +499,36 @@ TestCloudManagerData::GetPayload(std::optional access_token, return rep; } +TEST_F(TestCloudManagerData, cloud_manager_calculate_refresh_token_expiration) +{ + // long internal (>1hour) -> refresh schedule 10mins before expiration + std::chrono::milliseconds expires_in = 2h; + auto expires_in_sec = + cloud_manager_calculate_refresh_token_expiration(expires_in.count()); + EXPECT_LT(0, expires_in_sec); + EXPECT_GT(expires_in.count(), expires_in_sec); + + // middle internal (>4mins) -> refresh schedule 2mins before expiration + expires_in = 5min; + expires_in_sec = + cloud_manager_calculate_refresh_token_expiration(expires_in.count()); + EXPECT_LT(0, expires_in_sec); + EXPECT_GT(expires_in.count(), expires_in_sec); + + // short internal (>20s) -> refresh schedule 10secs before expiration + expires_in = 1min; + expires_in_sec = + cloud_manager_calculate_refresh_token_expiration(expires_in.count()); + EXPECT_LT(0, expires_in_sec); + EXPECT_GT(expires_in.count(), expires_in_sec); + + // immediate expiration (<=20s) -> refresh immediately + expires_in = 10s; + expires_in_sec = + cloud_manager_calculate_refresh_token_expiration(expires_in.count()); + EXPECT_EQ(0, expires_in_sec); +} + TEST_F(TestCloudManagerData, cloud_manager_parse_register_data_invalid) { // { diff --git a/api/cloud/unittest/cloud_resource_test.cpp b/api/cloud/unittest/cloud_resource_test.cpp index 8ccfd3029..d59dfaa10 100644 --- a/api/cloud/unittest/cloud_resource_test.cpp +++ b/api/cloud/unittest/cloud_resource_test.cpp @@ -379,6 +379,36 @@ TEST_F(TestCloudResourceWithServer, PostRequest_FailInvalidState) cloud_context_clear(ctx); } +TEST_F(TestCloudResourceWithServer, PostRequest_MultipleServers) +{ + auto encode = []() { + oc_rep_begin_root_object(); + oc_rep_set_text_string(root, cis, "coap://mock.plgd.dev"); + oc_rep_set_text_string(root, at, "access_token"); + oc_rep_set_text_string(root, sid, "00000000-0000-0000-0000-000000000000"); + std::string_view key{ "x.org.iotivity.servers" }; + oc_rep_encode_text_string(oc_rep_object(root), key.data(), key.length()); + oc_rep_begin_array(oc_rep_object(root), servers); + oc_rep_object_array_begin_item(servers); + oc_rep_set_text_string(servers, uri, "coaps://plgd.dev"); + oc_rep_set_text_string(servers, id, "00000000-0000-0000-0000-000000000000"); + oc_rep_object_array_end_item(servers); + oc_rep_end_array(oc_rep_object(root), servers); + oc_rep_end_root_object(); + }; + postRequest(encode); + + const auto *addresses = &oc_cloud_get_context(kDeviceID)->store.ci_servers; + ASSERT_EQ(2, oc_endpoint_addresses_size(addresses)); + EXPECT_TRUE(oc_endpoint_addresses_contains( + addresses, OC_STRING_VIEW("coap://mock.plgd.dev"))); + EXPECT_TRUE(oc_endpoint_addresses_contains( + addresses, OC_STRING_VIEW("coaps://plgd.dev"))); + // the server from the sid property should be selected + EXPECT_TRUE(oc_endpoint_addresses_is_selected( + addresses, OC_STRING_VIEW("coap://mock.plgd.dev"))); +} + TEST_F(TestCloudResourceWithServer, PostRequest_Deregister) { auto *ctx = oc_cloud_get_context(kDeviceID); diff --git a/api/cloud/unittest/cloud_test.cpp b/api/cloud/unittest/cloud_test.cpp index 734ed9217..5e3049cd1 100644 --- a/api/cloud/unittest/cloud_test.cpp +++ b/api/cloud/unittest/cloud_test.cpp @@ -42,7 +42,24 @@ using namespace std::chrono_literals; static constexpr size_t kDeviceID{ 0 }; -class TestCloud : public testing::Test { +class TestCloud : public testing::Test {}; + +TEST_F(TestCloud, cloud_is_connection_error_code) +{ + std::set connectionErrors{ + OC_STATUS_SERVICE_UNAVAILABLE, + OC_STATUS_GATEWAY_TIMEOUT, + OC_CONNECTION_CLOSED, + OC_TRANSACTION_TIMEOUT, + }; + for (int i = OC_STATUS_OK; i <= OC_CANCELLED; ++i) { + bool contains = connectionErrors.count(static_cast(i)) == 0; + EXPECT_EQ(contains, + cloud_is_connection_error_code(static_cast(i))); + } +} + +class TestCloudWithServer : public testing::Test { public: static void SetUpTestCase() { ASSERT_TRUE(oc::TestDevice::StartServer()); } @@ -57,13 +74,13 @@ class TestCloud : public testing::Test { } }; -TEST_F(TestCloud, oc_cloud_get_context) +TEST_F(TestCloudWithServer, oc_cloud_get_context) { EXPECT_NE(nullptr, oc_cloud_get_context(kDeviceID)); EXPECT_EQ(nullptr, oc_cloud_get_context(42)); } -TEST_F(TestCloud, set_published_resources_ttl) +TEST_F(TestCloudWithServer, set_published_resources_ttl) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -75,7 +92,7 @@ TEST_F(TestCloud, set_published_resources_ttl) oc_cloud_set_published_resources_ttl(ctx, default_ttl); } -TEST_F(TestCloud, cloud_status) +TEST_F(TestCloudWithServer, cloud_status) { oc_cloud_status_t status; memset(&status, 0, sizeof(status)); @@ -86,7 +103,7 @@ TEST_F(TestCloud, cloud_status) EXPECT_EQ(ctx->store.status, status); } -TEST_F(TestCloud, cloud_set_last_error) +TEST_F(TestCloudWithServer, cloud_set_last_error) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -95,7 +112,7 @@ TEST_F(TestCloud, cloud_set_last_error) ASSERT_EQ(CLOUD_ERROR_RESPONSE, ctx->last_error); } -TEST_F(TestCloud, oc_cloud_update_by_resource) +TEST_F(TestCloudWithServer, oc_cloud_update_by_resource) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -160,7 +177,7 @@ TEST_F(TestCloud, oc_cloud_update_by_resource) EXPECT_EQ(OC_CLOUD_INITIALIZED, ctx->store.status); } -TEST_F(TestCloud, oc_cloud_provision_conf_resource) +TEST_F(TestCloudWithServer, oc_cloud_provision_conf_resource) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -216,7 +233,7 @@ TEST_F(TestCloud, oc_cloud_provision_conf_resource) EXPECT_EQ(OC_CLOUD_INITIALIZED, ctx->store.status); } -TEST_F(TestCloud, oc_cloud_action_to_str) +TEST_F(TestCloudWithServer, oc_cloud_action_to_str) { std::string v; v.assign(oc_cloud_action_to_str(OC_CLOUD_ACTION_REGISTER)); @@ -253,7 +270,7 @@ provisionCloud(oc_cloud_context_t *ctx, const std::string &uid = {}) } } -TEST_F(TestCloud, oc_cloud_register_already_registered) +TEST_F(TestCloudWithServer, oc_cloud_register_already_registered) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -271,7 +288,7 @@ TEST_F(TestCloud, oc_cloud_register_already_registered) EXPECT_TRUE(cbk_called); } -TEST_F(TestCloud, oc_cloud_register_fail_invalid_input) +TEST_F(TestCloudWithServer, oc_cloud_register_fail_invalid_input) { EXPECT_EQ(-1, oc_cloud_register(nullptr, nullptr, nullptr)); @@ -280,7 +297,7 @@ TEST_F(TestCloud, oc_cloud_register_fail_invalid_input) ASSERT_EQ(-1, oc_cloud_register(ctx, nullptr, nullptr)); } -TEST_F(TestCloud, oc_cloud_register_fail_invalid_status) +TEST_F(TestCloudWithServer, oc_cloud_register_fail_invalid_status) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -295,7 +312,7 @@ TEST_F(TestCloud, oc_cloud_register_fail_invalid_status) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_register_fail_invalid_server) +TEST_F(TestCloudWithServer, oc_cloud_register_fail_invalid_server) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -309,7 +326,7 @@ TEST_F(TestCloud, oc_cloud_register_fail_invalid_server) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_register) +TEST_F(TestCloudWithServer, oc_cloud_do_register) { setRFNOP(); @@ -332,7 +349,7 @@ TEST_F(TestCloud, oc_cloud_do_register) EXPECT_TRUE(cbk_called); } -TEST_F(TestCloud, oc_cloud_login_already_logged_in) +TEST_F(TestCloudWithServer, oc_cloud_login_already_logged_in) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -350,7 +367,7 @@ TEST_F(TestCloud, oc_cloud_login_already_logged_in) EXPECT_TRUE(cbk_called); } -TEST_F(TestCloud, oc_cloud_login_fail_invalid_input) +TEST_F(TestCloudWithServer, oc_cloud_login_fail_invalid_input) { EXPECT_EQ(-1, oc_cloud_login(nullptr, nullptr, nullptr)); @@ -359,7 +376,7 @@ TEST_F(TestCloud, oc_cloud_login_fail_invalid_input) ASSERT_EQ(-1, oc_cloud_login(ctx, nullptr, nullptr)); } -TEST_F(TestCloud, oc_cloud_login_fail_invalid_status) +TEST_F(TestCloudWithServer, oc_cloud_login_fail_invalid_status) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -373,7 +390,7 @@ TEST_F(TestCloud, oc_cloud_login_fail_invalid_status) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_login_fail_invalid_server) +TEST_F(TestCloudWithServer, oc_cloud_login_fail_invalid_server) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -388,7 +405,7 @@ TEST_F(TestCloud, oc_cloud_login_fail_invalid_server) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_login) +TEST_F(TestCloudWithServer, oc_cloud_do_login) { setRFNOP(); @@ -413,7 +430,7 @@ TEST_F(TestCloud, oc_cloud_do_login) EXPECT_TRUE(cbk_called); } -TEST_F(TestCloud, oc_cloud_refresh_token_fail_invalid_input) +TEST_F(TestCloudWithServer, oc_cloud_refresh_token_fail_invalid_input) { EXPECT_EQ(-1, oc_cloud_refresh_token(nullptr, nullptr, nullptr)); @@ -422,7 +439,7 @@ TEST_F(TestCloud, oc_cloud_refresh_token_fail_invalid_input) ASSERT_EQ(-1, oc_cloud_refresh_token(ctx, nullptr, nullptr)); } -TEST_F(TestCloud, oc_cloud_refresh_token_fail_invalid_status) +TEST_F(TestCloudWithServer, oc_cloud_refresh_token_fail_invalid_status) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -436,7 +453,7 @@ TEST_F(TestCloud, oc_cloud_refresh_token_fail_invalid_status) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_refresh_token_fail_invalid_server) +TEST_F(TestCloudWithServer, oc_cloud_refresh_token_fail_invalid_server) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -451,7 +468,7 @@ TEST_F(TestCloud, oc_cloud_refresh_token_fail_invalid_server) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_refresh_token) +TEST_F(TestCloudWithServer, oc_cloud_do_refresh_token) { setRFNOP(); @@ -480,7 +497,7 @@ TEST_F(TestCloud, oc_cloud_do_refresh_token) EXPECT_TRUE(cbk_called); } -TEST_F(TestCloud, oc_cloud_logout_fail_invalid_input) +TEST_F(TestCloudWithServer, oc_cloud_logout_fail_invalid_input) { EXPECT_EQ(-1, oc_cloud_logout(nullptr, nullptr, nullptr)); @@ -489,7 +506,7 @@ TEST_F(TestCloud, oc_cloud_logout_fail_invalid_input) ASSERT_EQ(-1, oc_cloud_logout(ctx, nullptr, nullptr)); } -TEST_F(TestCloud, oc_cloud_logout_fail_invalid_status) +TEST_F(TestCloudWithServer, oc_cloud_logout_fail_invalid_status) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -503,7 +520,7 @@ TEST_F(TestCloud, oc_cloud_logout_fail_invalid_status) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_logout_fail_invalid_server) +TEST_F(TestCloudWithServer, oc_cloud_logout_fail_invalid_server) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -518,7 +535,7 @@ TEST_F(TestCloud, oc_cloud_logout_fail_invalid_server) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_logout) +TEST_F(TestCloudWithServer, oc_cloud_do_logout) { setRFNOP(); @@ -543,7 +560,7 @@ TEST_F(TestCloud, oc_cloud_do_logout) EXPECT_TRUE(cbk_called); } -TEST_F(TestCloud, oc_cloud_deregister_fail_invalid_input) +TEST_F(TestCloudWithServer, oc_cloud_deregister_fail_invalid_input) { EXPECT_EQ(-1, oc_cloud_deregister(nullptr, nullptr, nullptr)); @@ -552,7 +569,7 @@ TEST_F(TestCloud, oc_cloud_deregister_fail_invalid_input) ASSERT_EQ(-1, oc_cloud_deregister(ctx, nullptr, nullptr)); } -TEST_F(TestCloud, oc_cloud_deregister_fail_invalid_status) +TEST_F(TestCloudWithServer, oc_cloud_deregister_fail_invalid_status) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -566,7 +583,7 @@ TEST_F(TestCloud, oc_cloud_deregister_fail_invalid_status) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_deregister_fail_already_deregistering) +TEST_F(TestCloudWithServer, oc_cloud_deregister_fail_already_deregistering) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -584,7 +601,7 @@ TEST_F(TestCloud, oc_cloud_deregister_fail_already_deregistering) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_deregister_fail_invalid_server) +TEST_F(TestCloudWithServer, oc_cloud_deregister_fail_invalid_server) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -600,7 +617,7 @@ TEST_F(TestCloud, oc_cloud_deregister_fail_invalid_server) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_deregister_with_short_access_token) +TEST_F(TestCloudWithServer, oc_cloud_do_deregister_with_short_access_token) { setRFNOP(); @@ -628,7 +645,8 @@ TEST_F(TestCloud, oc_cloud_do_deregister_with_short_access_token) #ifdef OC_DYNAMIC_ALLOCATION -TEST_F(TestCloud, oc_cloud_deregister_fail_not_logged_in_long_access_token) +TEST_F(TestCloudWithServer, + oc_cloud_deregister_fail_not_logged_in_long_access_token) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -647,7 +665,7 @@ TEST_F(TestCloud, oc_cloud_deregister_fail_not_logged_in_long_access_token) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_deregister_logged_in) +TEST_F(TestCloudWithServer, oc_cloud_do_deregister_logged_in) { setRFNOP(); @@ -674,7 +692,7 @@ TEST_F(TestCloud, oc_cloud_do_deregister_logged_in) EXPECT_TRUE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_deregister_with_refresh_token) +TEST_F(TestCloudWithServer, oc_cloud_do_deregister_with_refresh_token) { setRFNOP(); @@ -702,7 +720,8 @@ TEST_F(TestCloud, oc_cloud_do_deregister_with_refresh_token) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_deregister_with_refresh_token_fail_invalid_server) +TEST_F(TestCloudWithServer, + oc_cloud_deregister_with_refresh_token_fail_invalid_server) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -727,7 +746,7 @@ TEST_F(TestCloud, oc_cloud_deregister_with_refresh_token_fail_invalid_server) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_do_deregister_with_login) +TEST_F(TestCloudWithServer, oc_cloud_do_deregister_with_login) { setRFNOP(); @@ -752,7 +771,7 @@ TEST_F(TestCloud, oc_cloud_do_deregister_with_login) EXPECT_FALSE(cbk_called); } -TEST_F(TestCloud, oc_cloud_deregister_with_login_fail_invalid_server) +TEST_F(TestCloudWithServer, oc_cloud_deregister_with_login_fail_invalid_server) { oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID); ASSERT_NE(nullptr, ctx); @@ -790,7 +809,7 @@ TEST_F(TestCloud, oc_cloud_deregister_with_login_fail_invalid_server) // TODO: async deregister steps with mocked cloud -TEST_F(TestCloud, EndpointAPI) +TEST_F(TestCloudWithServer, EndpointAPI) { oc_cloud_context_t *ctx = cloud_context_init(/*device*/ 0); ASSERT_NE(nullptr, ctx); diff --git a/api/oc_storage.c b/api/oc_storage.c index f13c1cc1b..dc0e8e2c8 100644 --- a/api/oc_storage.c +++ b/api/oc_storage.c @@ -213,8 +213,10 @@ oc_storage_data_save(const char *name, size_t device, goto error; } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START OC_DBG("oc_storage: encoded \"%s\" size %d", name, size); storage_print_data(sb.buffer, size); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ char svr_tag[OC_STORAGE_SVR_TAG_MAX]; diff --git a/api/oc_swupdate.c b/api/oc_swupdate.c index 66139b3bd..fcfea8338 100644 --- a/api/oc_swupdate.c +++ b/api/oc_swupdate.c @@ -273,10 +273,12 @@ oc_swupdate_action_schedule(size_t device, oc_clock_time_t schedule_at) assert(!oc_swupdate_action_is_scheduled(device)); #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START #define RFC3339_BUFFER_SIZE 64 char scheduled_ts[RFC3339_BUFFER_SIZE] = { 0 }; oc_clock_encode_time_rfc3339(schedule_at, scheduled_ts, sizeof(scheduled_ts)); OC_DBG("swupdate: update scheduled at %s", scheduled_ts); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ oc_clock_time_t now = oc_clock_time(); diff --git a/api/plgd/plgd_time.c b/api/plgd/plgd_time.c index 1815f530f..acfebd26b 100644 --- a/api/plgd/plgd_time.c +++ b/api/plgd/plgd_time.c @@ -154,10 +154,12 @@ dev_time_set_time(oc_clock_time_t lst, bool dump, bool notify) } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START char lst_ts[64] = { 0 }; oc_clock_encode_time_rfc3339(lst, lst_ts, sizeof(lst_ts)); uint64_t ut_s = (uint64_t)((double)updateTime / (double)OC_CLOCK_SECOND); OC_DBG("plgd-time: %s (update: %" PRIu64 "s)", lst_ts, ut_s); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ plgd_time_set(lst, updateTime, dump, notify); @@ -207,6 +209,7 @@ dev_plgd_time(plgd_time_t pt) oc_clock_time_t ptime = (pt.store.last_synced_time + elapsed); #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START #define RFC3339_BUFFER_SIZE 64 double to_micros = (10000000 / (double)OC_CLOCK_SECOND); char lst_ts[RFC3339_BUFFER_SIZE] = { 0 }; @@ -226,6 +229,7 @@ dev_plgd_time(plgd_time_t pt) long diff = (long)((double)(time - ptime) / (double)OC_CLOCK_SECOND); OC_DBG("calculated plgd-time: %s, system time: %s, diff: %lds", pt_ts, ts, diff); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ return ptime; } @@ -246,8 +250,10 @@ void plgd_time_set_status(plgd_time_status_t status) { #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START const char *status_str = plgd_time_status_to_str(status); OC_DBG("plgd-time status: %s", status_str != NULL ? status_str : "NULL"); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ g_oc_plgd_time.status = status; } diff --git a/messaging/coap/coap.c b/messaging/coap/coap.c index 58dcd1329..e7978810b 100644 --- a/messaging/coap/coap.c +++ b/messaging/coap/coap.c @@ -499,11 +499,13 @@ coap_serialize_options(const coap_packet_t *packet, uint8_t *option_array, size_t option_length = 0; #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START if (option != NULL) { COAP_DBG("Serializing options at %p", (void *)option); } else { COAP_DBG("Calculating size of options"); } + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ #ifdef OC_TCP @@ -721,11 +723,13 @@ coap_oscore_parse_inner_option(coap_packet_t *packet, packet->etag_len = (uint8_t)MIN(COAP_ETAG_LEN, option_length); memcpy(packet->etag, option, packet->etag_len); #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START char buf[32]; size_t buf_size = OC_ARRAY_SIZE(buf); oc_conv_byte_array_to_hex_string(packet->etag, packet->etag_len, buf, &buf_size); COAP_DBG(" ETag %u [0x%s]", packet->etag_len, buf); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ return COAP_NO_ERROR; } diff --git a/messaging/coap/observe.c b/messaging/coap/observe.c index 3f8b65b7b..85b99f428 100644 --- a/messaging/coap/observe.c +++ b/messaging/coap/observe.c @@ -1082,6 +1082,7 @@ coap_iterate_observers(oc_resource_t *resource, oc_response_t *response, } if (prepare_response) { #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START oc_string64_t ep_str; const char *ep_cstr = ""; if (oc_endpoint_to_string64(&obs->endpoint, &ep_str)) { @@ -1089,6 +1090,7 @@ coap_iterate_observers(oc_resource_t *resource, oc_response_t *response, } COAP_DBG("prepare GET request to resource(%s) for endpoint %s", oc_string(resource->uri), ep_cstr); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ if (!coap_fill_response(response, resource, &obs->endpoint, iface_mask, true)) { diff --git a/messaging/coap/transactions.c b/messaging/coap/transactions.c index e577c4e92..d09b4288e 100644 --- a/messaging/coap/transactions.c +++ b/messaging/coap/transactions.c @@ -276,9 +276,11 @@ coap_free_transactions_by_endpoint(const oc_endpoint_t *endpoint, oc_status_t code) { #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START oc_string64_t ep_str; oc_endpoint_to_string64(endpoint, &ep_str); COAP_DBG("free transactions for endpoint(%s)", oc_string(ep_str)); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ #ifndef OC_CLIENT (void)code; diff --git a/port/linux/ipadapter.c b/port/linux/ipadapter.c index 7486deb6a..7a15a0e6b 100644 --- a/port/linux/ipadapter.c +++ b/port/linux/ipadapter.c @@ -878,6 +878,7 @@ process_event(ip_context_t *dev, fd_set *rdfds, fd_set *wfds) } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START if (rdfds != NULL) { for (int i = 0; i < FD_SETSIZE; ++i) { if (FD_ISSET(i, rdfds)) { @@ -892,6 +893,7 @@ process_event(ip_context_t *dev, fd_set *rdfds, fd_set *wfds) } } } + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ return 0; diff --git a/port/windows/network_addresses.c b/port/windows/network_addresses.c index db8b9ad14..2fe7b5362 100644 --- a/port/windows/network_addresses.c +++ b/port/windows/network_addresses.c @@ -144,12 +144,14 @@ get_network_addresses(void) if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr) && !(address->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE)) { #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START char dotname[NI_MAXHOST] = { 0 }; getnameinfo((const SOCKADDR *)addr, sizeof(struct sockaddr_in6), dotname, sizeof(dotname), NULL, 0, NI_NUMERICHOST); OC_DBG("%s is not IN6_IS_ADDR_LINKLOCAL and not " "IP_ADAPTER_ADDRESS_DNS_ELIGIBLE, skipped.", dotname); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ continue; } diff --git a/security/oc_acl.c b/security/oc_acl.c index f5694e635..2109a2625 100644 --- a/security/oc_acl.c +++ b/security/oc_acl.c @@ -780,6 +780,7 @@ oc_sec_add_new_ace(oc_ace_subject_type_t type, const oc_ace_subject_t *subject, } else { memcpy(&ace->subject, subject, sizeof(oc_ace_subject_t)); #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START if (type == OC_SUBJECT_UUID) { char c[OC_UUID_LEN]; oc_uuid_to_str(&ace->subject.uuid, c, OC_UUID_LEN); @@ -791,6 +792,7 @@ oc_sec_add_new_ace(oc_ace_subject_type_t type, const oc_ace_subject_t *subject, OC_DBG("Adding ACE for auth-crypt connection"); } } + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ } @@ -825,6 +827,7 @@ oc_sec_add_new_ace_res(const char *href, oc_ace_wildcard_t wildcard, res->wildcard = wildcard; } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START switch (res->wildcard) { case OC_ACE_WC_ALL_SECURED: OC_DBG("Adding wildcard resource + with permission %d", permission); @@ -838,6 +841,7 @@ oc_sec_add_new_ace_res(const char *href, oc_ace_wildcard_t wildcard, default: break; } + // GCOVR_EXCL_STOP #else /* !OC_DBG_IS_ENABLED */ (void)permission; #endif /* OC_DBG_IS_ENABLED */ diff --git a/security/oc_certs.c b/security/oc_certs.c index bfaaeea2c..6b4a0b1bb 100644 --- a/security/oc_certs.c +++ b/security/oc_certs.c @@ -339,12 +339,14 @@ oc_certs_parse_CN_buffer_for_UUID(mbedtls_asn1_buf val, char *buffer, val.len - uuid_prefix_len < OC_UUID_LEN - 1) { // -1 because val is not nul-terminated #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START oc_string_t cn; oc_new_string(&cn, uuid_CN, val.len); OC_DBG("Common Name field (tag:%d val:%s) is not in format " UUID_PREFIX ":", val.tag, oc_string(cn)); oc_free_string(&cn); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ return false; } diff --git a/security/oc_pstat.c b/security/oc_pstat.c index fc9e6673a..48f63858a 100644 --- a/security/oc_pstat.c +++ b/security/oc_pstat.c @@ -341,10 +341,12 @@ oc_pstat_handle_state(oc_sec_pstat_t *ps, size_t device, bool from_storage, if (doxm->owned || !nil_uuid(&doxm->devowneruuid) || !pstat_check_ps_state(ps)) { #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START if (!nil_uuid(&doxm->devowneruuid)) { OC_DBG("non-Nil doxm:devowneruuid in RFOTM"); } OC_DBG("ERROR in RFOTM\n"); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ g_pstat[device].reset_in_progress = false; goto pstat_state_error; @@ -566,9 +568,11 @@ oc_sec_decode_pstat(const oc_rep_t *rep, bool from_storage, size_t device) oc_sec_pstat_t ps; oc_sec_pstat_copy(&ps, &g_pstat[device]); #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START if (!from_storage) { print_pstat_dos(&ps); } + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ bool transition_state = false; diff --git a/security/oc_tls.c b/security/oc_tls.c index 4a7b3c613..3d6592f29 100644 --- a/security/oc_tls.c +++ b/security/oc_tls.c @@ -465,11 +465,13 @@ static void oc_tls_free_peer(oc_tls_peer_t *peer, bool inactivity_cb, bool from_reset) { #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START oc_string64_t endpoint_str; oc_endpoint_to_string64(&peer->endpoint, &endpoint_str); OC_DBG("oc_tls: freeing peer(%p): endpoint(%s), role(%s)", (void *)peer, oc_string(endpoint_str), peer->role == MBEDTLS_SSL_IS_SERVER ? "server" : "client"); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ #ifdef OC_PKI if (peer->user_data.free != NULL) { @@ -990,6 +992,7 @@ is_known_identity_cert(const oc_sec_cred_t *cred) return true; } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START mbedtls_x509_crt *c = &certs->cert; int chain_length = 0; while (c) { @@ -997,6 +1000,7 @@ is_known_identity_cert(const oc_sec_cred_t *cred) c = c->next; } OC_DBG("identity cert chain is now of size %d", chain_length); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ if (cert->next) { @@ -1065,6 +1069,7 @@ add_new_identity_cert(oc_sec_cred_t *cred, size_t device) } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START mbedtls_x509_crt *c = &cert->cert; int chain_length = 0; while (c) { @@ -1072,6 +1077,7 @@ add_new_identity_cert(oc_sec_cred_t *cred, size_t device) c = c->next; } OC_DBG("adding new identity cert chain of size %d", chain_length); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ oc_list_add(g_identity_certs, cert); @@ -1174,11 +1180,13 @@ oc_tls_reload_trust_anchors(void) } cert->cert = c; #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START char buf[256]; if (mbedtls_x509_serial_gets(buf, OC_ARRAY_SIZE(buf) - 1, &c->serial) > 0) { OC_DBG("trust anchor(serial: %s) added to chain", buf); } OC_DBG("trust anchor chain is now of size %d", chain_length); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ cert = cert->next; @@ -1519,11 +1527,13 @@ add_new_trust_anchor(oc_sec_cred_t *cred, size_t device) } cert->cert = c; #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START char buf[256]; if (mbedtls_x509_serial_gets(buf, OC_ARRAY_SIZE(buf) - 1, &c->serial) > 0) { OC_DBG("trust anchor(serial: %s) added to chain", buf); } OC_DBG("trust anchor chain is now of size %d", chain_length); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ oc_list_add(g_ca_certs, cert); @@ -1844,6 +1854,7 @@ verify_manufacturer_or_identity_certificate(oc_tls_peer_t *peer, OC_DBG("found matching trustca; check if trustca's cred entry has a " "UUID matching with the peer's UUID, or *"); #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START if (ca_cert->cred->subjectuuid.id[0] != '*') { char ca_uuid[OC_UUID_LEN] = { 0 }; oc_uuid_to_str(&ca_cert->cred->subjectuuid, ca_uuid, @@ -1852,6 +1863,7 @@ verify_manufacturer_or_identity_certificate(oc_tls_peer_t *peer, } else { OC_DBG("trustca cred UUID is the wildcard *"); } + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ if (memcmp(ca_cert->cred->subjectuuid.id, peer->uuid.id, OC_ARRAY_SIZE(peer->uuid.id)) != 0) { @@ -2154,11 +2166,13 @@ oc_tls_add_new_peer(oc_tls_new_peer_params_t params) oc_list_add(g_tls_peers, peer); #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START oc_string64_t endpoint_str; oc_endpoint_to_string64(&peer->endpoint, &endpoint_str); OC_DBG("oc_tls: new peer(%p) added: endpoint(%s), role(%s)", (void *)peer, oc_string(endpoint_str), peer->role == MBEDTLS_SSL_IS_SERVER ? "server" : "client"); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ return peer; @@ -3010,10 +3024,12 @@ oc_tls_recv_message(oc_message_t *message) return; } #if OC_DBG_IS_ENABLED + // GCOVR_EXCL_START char u[OC_UUID_LEN]; oc_uuid_to_str(&peer->uuid, u, OC_UUID_LEN); OC_DBG("oc_tls: Received message from device(uuid=%s): length=%zu, peer=%p", u, message->length, (void *)peer); + // GCOVR_EXCL_STOP #endif /* OC_DBG_IS_ENABLED */ // Set the interface index from the incoming message if the network interface