parent
7982417480
commit
08c8147f54
@ -63,6 +63,7 @@ set(
|
||||
inc/azure/core/internal/json/json.hpp
|
||||
inc/azure/core/internal/strings.hpp
|
||||
inc/azure/core/io/body_stream.hpp
|
||||
inc/azure/core/azure_assert.hpp
|
||||
inc/azure/core/base64.hpp
|
||||
inc/azure/core/case_insensitive_containers.hpp
|
||||
inc/azure/core/context.hpp
|
||||
@ -87,6 +88,7 @@ set(
|
||||
AZURE_CORE_SOURCE
|
||||
${CURL_TRANSPORT_ADAPTER_SRC}
|
||||
${WIN_TRANSPORT_ADAPTER_SRC}
|
||||
src/azure_assert.cpp
|
||||
src/cryptography/md5.cpp
|
||||
src/http/bearer_token_authentication_policy.cpp
|
||||
src/http/http.cpp
|
||||
|
||||
56
sdk/core/azure-core/inc/azure/core/azure_assert.hpp
Normal file
56
sdk/core/azure-core/inc/azure/core/azure_assert.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Provide assert macros to use with pre-conditions.
|
||||
*
|
||||
* @remark Asserts are turned ON when `NDEBUG` is NOT defined (for Debug build). For Release build,
|
||||
* `std::abort()` is directly called if the condition is false, without calling assert().
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#if defined(NDEBUG)
|
||||
|
||||
/*
|
||||
* NDEBUG = defined = Build is on Release
|
||||
* Define AZURE_ASSERT to call abort directly on exp == false
|
||||
*/
|
||||
|
||||
#define AZURE_ASSERT(exp) \
|
||||
do \
|
||||
{ \
|
||||
if (!(exp)) \
|
||||
{ \
|
||||
std::abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define AZURE_ASSERT_MSG(exp, msg) AZURE_ASSERT(exp)
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* NDEBUG = NOT defined = Build is on Debug
|
||||
* Define AZURE_ASSERT to call assert to provide better debug experience.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#define AZURE_ASSERT(exp) assert((exp))
|
||||
#define AZURE_ASSERT_MSG(exp, msg) assert(((void)msg, (exp)))
|
||||
|
||||
#endif
|
||||
|
||||
[[noreturn]] void AzureNoReturnPath(std::string const& msg);
|
||||
|
||||
#define AZURE_ASSERT_FALSE(exp) AZURE_ASSERT(!(exp))
|
||||
#define AZURE_UNREACHABLE_CODE AzureNoReturnPath("unreachable code!")
|
||||
#define AZURE_NOT_IMPLEMENTED AzureNoReturnPath("not implemented code!")
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "azure/core/azure_assert.hpp"
|
||||
#include "azure/core/datetime.hpp"
|
||||
#include "azure/core/dll_import_export.hpp"
|
||||
|
||||
@ -175,11 +176,9 @@ namespace Azure { namespace Core {
|
||||
{
|
||||
if (ptr->Key == key)
|
||||
{
|
||||
if (typeid(T) != ptr->ValueType)
|
||||
{
|
||||
// type mismatch
|
||||
std::abort();
|
||||
}
|
||||
AZURE_ASSERT_MSG(
|
||||
typeid(T) == ptr->ValueType, "Type mismatch for Context::TryGetValue().");
|
||||
|
||||
outputValue = *reinterpret_cast<const T*>(ptr->Value.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "azure/core/azure_assert.hpp"
|
||||
#include "azure/core/nullable.hpp"
|
||||
|
||||
#include <string>
|
||||
@ -111,7 +112,7 @@ public:
|
||||
break;
|
||||
}
|
||||
// Unknown comparison
|
||||
abort();
|
||||
AZURE_UNREACHABLE_CODE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,10 +138,8 @@ public:
|
||||
*/
|
||||
const std::string& ToString() const
|
||||
{
|
||||
if (!m_value.HasValue())
|
||||
{
|
||||
abort();
|
||||
}
|
||||
AZURE_ASSERT_MSG(m_value.HasValue(), "Empty ETag, check HasValue() before calling ToString().");
|
||||
|
||||
return m_value.Value();
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib> // for abort
|
||||
#include <azure/core/azure_assert.hpp>
|
||||
|
||||
#include <new> // for placement new
|
||||
#include <type_traits>
|
||||
#include <utility> // for swap and move
|
||||
@ -220,12 +221,7 @@ public:
|
||||
*/
|
||||
const T& Value() const& noexcept
|
||||
{
|
||||
if (!m_hasValue)
|
||||
{
|
||||
// throwing here prohibited by our guidelines
|
||||
// https://azure.github.io/azure-sdk/cpp_design.html#pre-conditions
|
||||
std::abort();
|
||||
}
|
||||
AZURE_ASSERT_MSG(m_hasValue, "Empty Nullable, check HasValue() first.");
|
||||
|
||||
return m_value;
|
||||
}
|
||||
@ -235,12 +231,7 @@ public:
|
||||
*/
|
||||
T& Value() & noexcept
|
||||
{
|
||||
if (!m_hasValue)
|
||||
{
|
||||
// throwing here prohibited by our guidelines
|
||||
// https://azure.github.io/azure-sdk/cpp_design.html#pre-conditions
|
||||
std::abort();
|
||||
}
|
||||
AZURE_ASSERT_MSG(m_hasValue, "Empty Nullable, check HasValue() first.");
|
||||
|
||||
return m_value;
|
||||
}
|
||||
@ -250,12 +241,7 @@ public:
|
||||
*/
|
||||
T&& Value() && noexcept
|
||||
{
|
||||
if (!m_hasValue)
|
||||
{
|
||||
// throwing here prohibited by our guidelines
|
||||
// https://azure.github.io/azure-sdk/cpp_design.html#pre-conditions
|
||||
std::abort();
|
||||
}
|
||||
AZURE_ASSERT_MSG(m_hasValue, "Empty Nullable, check HasValue() first.");
|
||||
|
||||
return std::move(m_value);
|
||||
}
|
||||
|
||||
12
sdk/core/azure-core/src/azure_assert.cpp
Normal file
12
sdk/core/azure-core/src/azure_assert.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "azure/core/azure_assert.hpp"
|
||||
|
||||
[[noreturn]] void AzureNoReturnPath(std::string const& msg)
|
||||
{
|
||||
// void msg for Release build where Assert is ignored
|
||||
(void)msg;
|
||||
AZURE_ASSERT_MSG(false, msg);
|
||||
std::abort();
|
||||
}
|
||||
@ -436,3 +436,23 @@ TEST(Context, Deadline)
|
||||
EXPECT_EQ(childCtx.GetDeadline(), Azure::DateTime::min());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Context, PreCondition)
|
||||
{
|
||||
// Get a mismatch type from the context
|
||||
std::string s("Test String");
|
||||
|
||||
Context context;
|
||||
Context::Key const key;
|
||||
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue(key, s);
|
||||
int value;
|
||||
|
||||
#if defined(NDEBUG)
|
||||
// Release build won't provide assert msg
|
||||
ASSERT_DEATH(c2.TryGetValue<int>(key, value), "");
|
||||
#else
|
||||
ASSERT_DEATH(c2.TryGetValue<int>(key, value), "Type mismatch for Context::TryGetValue");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -232,3 +232,15 @@ TEST(ETag, EqualsWeak)
|
||||
EXPECT_FALSE(ETag::Equals(weakTagTwo, weakTagtwo, ETag::ETagComparison::Weak));
|
||||
EXPECT_FALSE(ETag::Equals(weakTagtwo, weakTagTwo, ETag::ETagComparison::Weak));
|
||||
}
|
||||
|
||||
TEST(ETag, PreCondition)
|
||||
{
|
||||
ETag emptyTag;
|
||||
|
||||
#if defined(NDEBUG)
|
||||
// Release build won't provide assert msg
|
||||
ASSERT_DEATH(emptyTag.ToString(), "");
|
||||
#else
|
||||
ASSERT_DEATH(emptyTag.ToString(), "Empty ETag");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -171,3 +171,39 @@ TEST(Nullable, ValueOr)
|
||||
// Ensure val2 is still disengaged after call to ValueOr
|
||||
EXPECT_FALSE(val2);
|
||||
}
|
||||
|
||||
void Foo(int&& rValue) { (void)rValue; }
|
||||
|
||||
TEST(Nullable, PreCondition)
|
||||
{
|
||||
Nullable<int> emptyNullable;
|
||||
|
||||
#if defined(NDEBUG)
|
||||
// Release build won't provide assert msg
|
||||
ASSERT_DEATH(auto a = emptyNullable.Value(); (void)a;, "");
|
||||
#else
|
||||
ASSERT_DEATH(auto a = emptyNullable.Value(); (void)a;, "Empty Nullable");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Nullable, PreCondition2)
|
||||
{
|
||||
Nullable<int> emptyNullable;
|
||||
|
||||
#if defined(NDEBUG)
|
||||
// Release build won't provide assert msg
|
||||
ASSERT_DEATH(auto& a = emptyNullable.Value(); (void)a;, "");
|
||||
#else
|
||||
ASSERT_DEATH(auto& a = emptyNullable.Value(); (void)a;, "Empty Nullable");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Nullable, PreCondition3)
|
||||
{
|
||||
#if defined(NDEBUG)
|
||||
// Release build won't provide assert msg
|
||||
ASSERT_DEATH(Foo(Nullable<int>().Value());, "");
|
||||
#else
|
||||
ASSERT_DEATH(Foo(Nullable<int>().Value());, "Empty Nullable");
|
||||
#endif
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user