Add checks for the expected sizes of all public classes

This ensures that d-pointers exist where they're expected, and that
classes are virtual that we expect to be virtual, as well as ensuring
that we get a failure if the class size changes when it shouldn't.

This also fixes the issues that were discovered by adding these tests.
This commit is contained in:
Scott Wheeler 2023-07-30 06:31:48 +02:00
parent a1bdb0171d
commit f903e1ad71
13 changed files with 335 additions and 28 deletions

View File

@ -110,6 +110,9 @@ namespace TagLib {
bool readAudioProperties = true,
AudioProperties::ReadStyle
audioPropertiesStyle = AudioProperties::Average) const = 0;
private:
class FileTypeResolverPrivate;
FileTypeResolverPrivate *d;
};
class TAGLIB_EXPORT StreamTypeResolver : public FileTypeResolver
@ -124,6 +127,9 @@ namespace TagLib {
bool readAudioProperties = true,
AudioProperties::ReadStyle
audioPropertiesStyle = AudioProperties::Average) const = 0;
private:
class StreamTypeResolverPrivate;
StreamTypeResolverPrivate *d;
};
/*!

View File

@ -55,6 +55,9 @@ namespace TagLib {
bool readU32L(unsigned long &number);
bool readU16B(unsigned short &number);
bool readU32B(unsigned long &number);
private:
class FileBasePrivate;
FileBasePrivate *d;
};
} // namespace Mod
} // namespace TagLib

View File

@ -48,7 +48,7 @@ namespace TagLib {
};
CoverArt(Format format, const ByteVector &data);
~CoverArt();
virtual ~CoverArt();
CoverArt(const CoverArt &item);

View File

@ -52,7 +52,7 @@ namespace TagLib {
*/
void swap(Item &item);
~Item();
virtual ~Item();
Item(int value);
Item(unsigned char value);

View File

@ -80,6 +80,10 @@ namespace TagLib {
* ISO-8859-1.
*/
virtual ByteVector render(const String &s) const;
private:
class StringHandlerPrivate;
StringHandlerPrivate *d;
};
//! The main class in the ID3v1 implementation

View File

@ -77,6 +77,10 @@ namespace TagLib {
* \a data is an ISO-8859-1 (Latin1) character array.
*/
virtual String parse(const ByteVector &data) const;
private:
class Latin1StringHandlerPrivate;
Latin1StringHandlerPrivate *d;
};
//! The main class in the ID3v2 implementation

View File

@ -61,7 +61,7 @@ namespace TagLib {
{
public:
StringHandler();
~StringHandler();
virtual ~StringHandler();
/*!
* Decode a string from \a data. The default implementation assumes that
@ -74,6 +74,10 @@ namespace TagLib {
* assumes that \a s is an UTF-8 string.
*/
virtual ByteVector render(const String &s) const;
private:
class StringHandlerPrivate;
StringHandlerPrivate *d;
};
//! The main class in the ID3v2 implementation

View File

@ -56,6 +56,9 @@ namespace TagLib
// Noncopyable
DebugListener(const DebugListener &) = delete;
DebugListener &operator=(const DebugListener &) = delete;
class DebugListenerPrivate;
DebugListenerPrivate *d;
};
/*!

View File

@ -160,6 +160,9 @@ namespace TagLib {
private:
IOStream(const IOStream &) = delete;
IOStream &operator=(const IOStream &) = delete;
class IOStreamPrivate;
IOStreamPrivate *d;
};
} // namespace TagLib

View File

@ -27,22 +27,40 @@
using namespace TagLib;
PropertyMap::PropertyMap() = default;
PropertyMap::PropertyMap(const PropertyMap &m) = default;
PropertyMap::PropertyMap(const SimplePropertyMap &m)
class PropertyMap::PropertyMapPrivate
{
for(auto it = m.begin(); it != m.end(); ++it){
String key = it->first.upper();
public:
StringList unsupported;
};
PropertyMap::PropertyMap() :
d(new PropertyMapPrivate)
{
}
PropertyMap::PropertyMap(const PropertyMap &m) :
SimplePropertyMap(m),
d(new PropertyMapPrivate)
{
*d = *m.d;
}
PropertyMap::PropertyMap(const SimplePropertyMap &m) :
d(new PropertyMapPrivate)
{
for(auto [key, value] : m) {
if(!key.isEmpty())
insert(it->first, it->second);
insert(key.upper(), value);
else
unsupported.append(it->first);
d->unsupported.append(key.upper());
}
}
PropertyMap::~PropertyMap() = default;
PropertyMap::~PropertyMap()
{
delete d;
}
bool PropertyMap::insert(const String &key, const StringList &values)
{
@ -106,7 +124,7 @@ PropertyMap &PropertyMap::merge(const PropertyMap &other)
{
for(auto it = other.begin(); it != other.end(); ++it)
insert(it->first, it->second);
unsupported.append(other.unsupported);
d->unsupported.append(other.d->unsupported);
return *this;
}
@ -138,7 +156,7 @@ bool PropertyMap::operator==(const PropertyMap &other) const
if( otherFind == other.end() || (otherFind->second != it->second) )
return false;
}
return unsupported == other.unsupported;
return d->unsupported == other.d->unsupported;
}
bool PropertyMap::operator!=(const PropertyMap &other) const
@ -152,8 +170,8 @@ String PropertyMap::toString() const
for(auto it = begin(); it != end(); ++it)
ret += it->first+"="+it->second.toString(", ") + "\n";
if(!unsupported.isEmpty())
ret += "Unsupported Data: " + unsupported.toString(", ") + "\n";
if(!d->unsupported.isEmpty())
ret += "Unsupported Data: " + d->unsupported.toString(", ") + "\n";
return ret;
}
@ -169,12 +187,14 @@ void PropertyMap::removeEmpty()
StringList &PropertyMap::unsupportedData()
{
return unsupported;
return d->unsupported;
}
const StringList &PropertyMap::unsupportedData() const
PropertyMap &PropertyMap::operator=(const PropertyMap &other)
{
return unsupported;
SimplePropertyMap::operator=(other);
*d = *other.d;
return *this;
}
#ifdef _MSC_VER

View File

@ -23,8 +23,8 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_PROPERTYMAP_H_
#define TAGLIB_PROPERTYMAP_H_
#ifndef TAGLIB_PROPERTYMAP_H
#define TAGLIB_PROPERTYMAP_H
#include "tmap.h"
#include "tstringlist.h"
@ -198,7 +198,7 @@ namespace TagLib {
* If no defaultValue is specified, it returns an empty string list.
*/
StringList value(const String &key,
const StringList &defaultValue = StringList()) const;
const StringList &defaultValue = StringList()) const;
/*!
* Returns a reference to the value associated with \a key.
@ -235,9 +235,11 @@ namespace TagLib {
* You can remove items from the returned list, which tells TagLib to remove
* those unsupported elements if you call File::setProperties() with the
* same PropertyMap as argument.
*
* \deprecated
*/
// TODO: Returning mutable references to internal data structures is a bad idea.
StringList &unsupportedData();
const StringList &unsupportedData() const;
/*!
* Removes all entries which have an empty value list.
@ -246,11 +248,12 @@ namespace TagLib {
String toString() const;
PropertyMap &operator=(const PropertyMap &other);
private:
StringList unsupported;
class PropertyMapPrivate;
PropertyMapPrivate *d;
};
} // namespace TagLib
#endif /* TAGLIB_PROPERTYMAP_H_ */
#endif /* TAGLIB_PROPERTYMAP_H */

View File

@ -66,6 +66,7 @@ SET(test_runner_SRCS
test_mpc.cpp
test_opus.cpp
test_speex.cpp
test_sizes.cpp
)
INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIR})

256
tests/test_sizes.cpp Normal file
View File

@ -0,0 +1,256 @@
/***************************************************************************
copyright : (C) 2023 Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include "aifffile.h"
#include "aiffproperties.h"
#include "apefile.h"
#include "apefooter.h"
#include "apeitem.h"
#include "apeproperties.h"
#include "apetag.h"
#include "asfattribute.h"
#include "asffile.h"
#include "asfpicture.h"
#include "asfproperties.h"
#include "asftag.h"
#include "attachedpictureframe.h"
#include "audioproperties.h"
#include "chapterframe.h"
#include "commentsframe.h"
#include "eventtimingcodesframe.h"
#include "fileref.h"
#include "flacfile.h"
#include "flacmetadatablock.h"
#include "flacunknownmetadatablock.h"
#include "flacpicture.h"
#include "flacproperties.h"
#include "generalencapsulatedobjectframe.h"
#include "id3v1genres.h"
#include "id3v1tag.h"
#include "id3v2.h"
#include "id3v2extendedheader.h"
#include "id3v2footer.h"
#include "id3v2frame.h"
#include "id3v2framefactory.h"
#include "id3v2header.h"
#include "id3v2synchdata.h"
#include "id3v2tag.h"
#include "infotag.h"
#include "itfile.h"
#include "itproperties.h"
#include "modfile.h"
#include "modfilebase.h"
#include "modproperties.h"
#include "modtag.h"
#include "mp4atom.h"
#include "mp4coverart.h"
#include "mp4file.h"
#include "mp4item.h"
#include "mp4properties.h"
#include "mp4tag.h"
#include "mpcfile.h"
#include "mpcproperties.h"
#include "mpegfile.h"
#include "mpegheader.h"
#include "mpegproperties.h"
#include "oggfile.h"
#include "oggflacfile.h"
#include "oggpage.h"
#include "oggpageheader.h"
#include "opusfile.h"
#include "opusproperties.h"
#include "ownershipframe.h"
#include "podcastframe.h"
#include "popularimeterframe.h"
#include "privateframe.h"
#include "relativevolumeframe.h"
#include "rifffile.h"
#include "s3mfile.h"
#include "s3mproperties.h"
#include "speexfile.h"
#include "speexproperties.h"
#include "synchronizedlyricsframe.h"
#include "tableofcontentsframe.h"
#include "tag.h"
#include "tbytevector.h"
#include "tbytevectorlist.h"
#include "tbytevectorstream.h"
#include "tdebuglistener.h"
#include "textidentificationframe.h"
#include "tfile.h"
#include "tfilestream.h"
#include "tiostream.h"
#include "tlist.h"
#include "tmap.h"
#include "tpropertymap.h"
#include "trefcounter.h"
#include "trueaudiofile.h"
#include "trueaudioproperties.h"
#include "tstring.h"
#include "tstringlist.h"
#include "uniquefileidentifierframe.h"
#include "unknownframe.h"
#include "unsynchronizedlyricsframe.h"
#include "urllinkframe.h"
#include "vorbisfile.h"
#include "vorbisproperties.h"
#include "wavfile.h"
#include "wavpackfile.h"
#include "wavpackproperties.h"
#include "wavproperties.h"
#include "xingheader.h"
#include "xiphcomment.h"
#include "xmfile.h"
#include "xmproperties.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
using namespace std;
using namespace TagLib;
class TestSizes : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestSizes);
CPPUNIT_TEST(testSizes);
CPPUNIT_TEST_SUITE_END();
public:
void testSizes()
{
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::File));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::APE::Footer));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::APE::Item));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ASF::Attribute));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::File));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ASF::Picture));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::AudioProperties));
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::ByteVector));
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::ByteVectorList));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ByteVectorStream));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::DebugListener));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::File));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::FLAC::MetadataBlock));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::Picture));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::UnknownMetadataBlock));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::File));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::FileRef));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::FileRef::FileTypeResolver));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FileRef::StreamTypeResolver));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FileStream));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ID3v1::StringHandler));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v1::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::AttachedPictureFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::AttachedPictureFrameV22));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::ChapterFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::CommentsFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::EventTimingCodesFrame));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ID3v2::ExtendedHeader));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ID3v2::Footer));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ID3v2::Frame));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ID3v2::FrameFactory));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::GeneralEncapsulatedObjectFrame));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ID3v2::Header));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::ID3v2::Latin1StringHandler));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::OwnershipFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::PodcastFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::PopularimeterFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::PrivateFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::RelativeVolumeFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::SynchronizedLyricsFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::TableOfContentsFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::TextIdentificationFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::UniqueFileIdentifierFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::UnknownFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::UnsynchronizedLyricsFrame));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ID3v2::UrlLinkFrame));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::ID3v2::UserTextIdentificationFrame));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::ID3v2::UserUrlLinkFrame));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::IOStream));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::IT::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::IT::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::List<int>));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::MP4::CoverArt));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::File));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::MP4::Item));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPC::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPC::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPEG::File));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::MPEG::Header));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPEG::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::MPEG::XingHeader));
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::Map<int, int>));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Mod::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::FileBase));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Ogg::FLAC::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::File));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Ogg::Opus::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::Opus::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::Ogg::Page));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::Ogg::PageHeader));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Ogg::Speex::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::Speex::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Ogg::Vorbis::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::Vorbis::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::XiphComment));
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::PropertyMap));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::RIFF::AIFF::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::AIFF::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::File));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::RIFF::Info::StringHandler));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::Info::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::RIFF::WAV::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::WAV::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::S3M::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::S3M::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::String));
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::StringList));
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::Tag));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::TrueAudio::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::TrueAudio::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::WavPack::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::WavPack::Properties));
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::XM::File));
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::XM::Properties));
}
private:
constexpr size_t classSize(int baseClasses, bool isVirtual)
{
return sizeof(void *) * (baseClasses + static_cast<int>(isVirtual) + 1);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestSizes);