source/tests/test.unit/omni.log/TestILogDocs.cpp

// Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#include "../common/TestHelpers.h"
#include "../omni.core/ScopedTypeFactory.h"

#include <omni/log/ILog.h>

#include <carb/dictionary/ISerializer.h>

// clang-format off, example-begin log-macros
#include <omni/log/ILog.h>

void logAtEachLevel()
{
    OMNI_LOG_VERBOSE("This is verbose");
    OMNI_LOG_INFO("Þetta eru upplýsingar");
    OMNI_LOG_WARN("Սա նախազգուշացում է");
    OMNI_LOG_ERROR("这是一个错误");
    OMNI_LOG_FATAL("This is %s", "fatal");
}
// example-end log-macros, clang-format on

// example-begin add-channel
OMNI_LOG_ADD_CHANNEL(kMp3EncodeChannel, "audio.vorbis.encode", "Vorbis audio encoding.")
OMNI_LOG_ADD_CHANNEL(kMp3DecodeChannel, "audio.vorbis.decode", "Vorbis audio decoding.")
OMNI_LOG_ADD_CHANNEL(kSpatialChannel, "audio.spatial", "Spatial (3D) audio.")
// example-end add-channel

void logToChannelExample()
{
    const char* filename = "rickroll.ogg";
    float distance = 3.0f;

    // example-begin log-to-channel
    OMNI_LOG_ERROR(kMp3DecodeChannel, "failed to load '%s'", filename);

    // ...

    OMNI_LOG_VERBOSE(kSpatialChannel, "sound source is %f meters from listener", distance);

    // example-end log-to-channel
}

// example-begin declare-channel
OMNI_LOG_DECLARE_CHANNEL(kMp3EncodeChannel)
// example-end declare-channel

void showMessageConsumer()
{
    omniGetLogWithoutAcquire()->setEnabled(true);

    // example-begin on-message-consumer
    auto log = omniGetLogWithoutAcquire();

    bool sawFatalMessage = false;
    auto consumer = log->addMessageConsumer(
        [&sawFatalMessage](const char* channel, omni::log::Level level, const char* moduleName, const char* fileName,
                           const char* functionName, uint32_t lineNumber, const char* msg, uint32_t pid, uint32_t tid,
                           uint64_t timestamp) noexcept {
            if (omni::log::Level::eFatal == level)
            {
                sawFatalMessage = true;
            }
        });

    OMNI_LOG_FATAL("this is a fatal message");

    log->removeMessageConsumer(consumer);

    REQUIRE(sawFatalMessage);
    // example-end on-message-consumer

    log->setEnabled(false);
}

void showChannelUpdateConsumer()
{
    omniGetLogWithoutAcquire()->setEnabled(true);

    // the output below should be:
    /* example-begin on-channel-updated-consumer-output
    <global>: enabled is now 1
    <global>: level is now -1
    audio.opus.encode channel added
    audio.opus.encode: enabled is now 1[override]
    audio.opus.encode: level is now -1[inherit]
    audio.opus.encode: description is now OPUS audio codec encoding.
    example-end on-channel-updated-consumer-output */

    // example-begin on-channel-updated-consumer-code
    auto log = omniGetLogWithoutAcquire();

    log->setEnabled(false);
    log->setLevel(omni::log::Level::eVerbose);

    auto consumer = log->addChannelUpdateConsumer([](omni::log::ILog* log, omni::str::IReadOnlyCString* channel,
                                                     omni::log::ChannelUpdateReason reason) {
        switch (reason)
        {
            case omni::log::ChannelUpdateReason::eChannelAdded:
                OMNI_LOG_INFO("%s channel added", channel->getBuffer());
                break;
            case omni::log::ChannelUpdateReason::eChannelRemoved:
                OMNI_LOG_INFO("%s channel removed", channel->getBuffer());
                break;
            case omni::log::ChannelUpdateReason::eLevelUpdated:
            {
                omni::log::Level level;
                omni::log::SettingBehavior behavior;
                if (channel)
                {
                    if (OMNI_SUCCEEDED(log->getChannelLevel(channel->getBuffer(), &level, &behavior)))
                    {
                        OMNI_LOG_INFO("%s: level is now %d[%s]", channel->getBuffer(), int(level),
                                      ((omni::log::SettingBehavior::eInherit == behavior) ? "inherit" : "override"));
                    }
                }
                else
                {
                    OMNI_LOG_INFO("<global>: level is now %d", int32_t(log->getLevel()));
                }
                break;
            }
            case omni::log::ChannelUpdateReason::eEnabledUpdated:
            {
                bool enabled;
                omni::log::SettingBehavior behavior;
                if (channel)
                {
                    if (OMNI_SUCCEEDED(log->getChannelEnabled(channel->getBuffer(), &enabled, &behavior)))
                    {
                        OMNI_LOG_INFO("%s: enabled is now %d[%s]", channel->getBuffer(), int(enabled),
                                      ((omni::log::SettingBehavior::eInherit == behavior) ? "inherit" : "override"));
                    }
                }
                else
                {
                    OMNI_LOG_VERBOSE("<global>: enabled is now %d", int(log->isEnabled()));
                }
                break;
            }
            case omni::log::ChannelUpdateReason::eDescriptionUpdated:
            {
                omni::core::ObjectPtr<omni::str::IReadOnlyCString> descObj;
                if (OMNI_SUCCEEDED(log->getChannelDescription(channel->getBuffer(), descObj.put())))
                {
                    const char* desc = "(null)";
                    if (descObj)
                    {
                        desc = descObj->getBuffer();
                    }
                    OMNI_LOG_INFO("%s: description is now %s", channel->getBuffer(), desc);
                }
                break;
            }
            default:
                break;
        }
    });

    log->setEnabled(true);

    log->setLevel(omni::log::Level::eInfo);

    // this first call will produce an eChannelAdded event since the channel has never been seen
    log->setChannelEnabled("audio.opus.encode", false, omni::log::SettingBehavior::eInherit);

    log->setChannelEnabled("audio.opus.encode", true, omni::log::SettingBehavior::eOverride);
    log->setChannelLevel("audio.opus.encode", omni::log::Level::eInfo, omni::log::SettingBehavior::eInherit);

    log->setChannelDescription("audio.opus.encode", "OPUS audio codec encoding.");

    log->removeChannelUpdateConsumer(consumer);
    // example-end on-channel-updated-consumer-code

    log->setChannelEnabled("audio.opus.encode", false, omni::log::SettingBehavior::eInherit);
    log->setChannelLevel("audio.opus.encode", omni::log::Level::eWarn, omni::log::SettingBehavior::eInherit);

    log->setLevel(omni::log::Level::eWarn);
    log->setEnabled(false);
}

TEST_CASE("tests for omni::log documentation", "ncournia", "[omni::log::ILog]")
{
    test::ScopedTypeFactory scopedFactory;

    auto log = omniGetLogWithoutAcquire();
    REQUIRE(log);

    log->setEnabled(false);

    log->setChannelLevel(kDefaultChannel, omni::log::Level::eVerbose, omni::log::SettingBehavior::eInherit);
    log->setChannelEnabled(kDefaultChannel, false, omni::log::SettingBehavior::eInherit);

    logAtEachLevel();
    logToChannelExample();
    showMessageConsumer();
    showChannelUpdateConsumer();

    log->setEnabled(true);
}