[libcamera-devel] [PATCH v2 2/5] test: Add tests for the Flags class

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Jul 27 05:02:02 CEST 2021


Hi Jacopo,

On Mon, Jul 26, 2021 at 11:46:44AM +0200, Jacopo Mondi wrote:
> On Sun, Jul 25, 2021 at 08:18:24PM +0300, Laurent Pinchart wrote:
> > Add tests that exercise the whole API of the Flags class.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> > ---
> > Changes since v1:
> >
> > - Fix enumerator Beta
> > - Typo fix
> > ---
> >  test/flags.cpp   | 204 +++++++++++++++++++++++++++++++++++++++++++++++
> >  test/meson.build |   1 +
> >  2 files changed, 205 insertions(+)
> >  create mode 100644 test/flags.cpp
> >
> > diff --git a/test/flags.cpp b/test/flags.cpp
> > new file mode 100644
> > index 000000000000..5a684e6ee11f
> > --- /dev/null
> > +++ b/test/flags.cpp
> > @@ -0,0 +1,204 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Copyright (C) 2020, Google Inc.
> > + *
> > + * flags.cpp - Flags tests
> > + */
> > +
> > +#include <iostream>
> > +
> > +#include <libcamera/base/flags.h>
> > +
> > +#include "test.h"
> > +
> > +using namespace libcamera;
> > +using namespace std;
> > +
> > +class FlagsTest : public Test
> > +{
> > +protected:
> > +	enum class Option {
> > +		First = (1 << 0),
> > +		Second = (1 << 1),
> > +		Third = (1 << 2),
> > +	};
> > +
> > +	using Options = Flags<Option>;
> > +
> > +	enum class Mode {
> > +		Alpha = (1 << 0),
> > +		Beta = (1 << 1),
> > +		Gamma = (1 << 2),
> > +	};
> > +
> > +	using Modes = Flags<Mode>;
> > +
> > +	int run() override;
> > +};
> > +
> > +namespace libcamera {
> > +
> > +LIBCAMERA_FLAGS_ENABLE_OPERATORS(FlagsTest::Option)
> > +
> > +} /* namespace libcamera */
> > +
> > +int FlagsTest::run()
> > +{
> > +	/* Commented-out constructs are expected not to compile. */
> > +
> > +	/* Flags<int> f; */
> 
> Leftovers then ?

Not really, they're meant to show invalid usage, we have similar
constructs in the Span tests. I have yet to find a way to create tests
where compilation failures are considered a success :-)

> > +
> > +	/*
> > +	 * Unary operators with enum argument.
> > +	 */
> > +
> > +	Options options;
> > +
> > +	if (options) {
> > +		cerr << "Default-constructed Flags<> is not zero" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options |= Option::First;
> > +
> > +	if (!options || options != Option::First) {
> > +		cerr << "Unary bitwise OR with enum failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	/* options &= Mode::Alpha; */
> > +	/* options |= Mode::Beta;  */
> > +	/* options ^= Mode::Gamma; */
> > +
> > +	options &= ~Option::First;
> > +
> 
> Do you need these empy lines ?

I'll drop them.

> > +	if (options) {
> > +		cerr << "Unary bitwise AND with enum failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options ^= Option::Second;
> > +
> > +	if (options != Option::Second) {
> > +		cerr << "Unary bitwise XOR with enum failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options = Options();
> > +
> > +	/*
> > +	 * Unary operators with Flags argument.
> > +	 */
> > +
> > +	options |= Options(Option::First);
> > +
> > +	if (options != Option::First) {
> > +		cerr << "Unary bitwise OR with Flags<> failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	/* options &= Options(Mode::Alpha); */
> > +	/* options |= Options(Mode::Beta);  */
> > +	/* options ^= Options(Mode::Gamma); */
> > +
> > +	options &= ~Options(Option::First);
> > +
> > +	if (options) {
> > +		cerr << "Unary bitwise AND with Flags<> failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options ^= Options(Option::Second);
> > +
> > +	if (options != Option::Second) {
> > +		cerr << "Unary bitwise XOR with Flags<> failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options = Options();
> > +
> > +	/*
> > +	 * Binary operators with enum argument.
> > +	 */
> > +
> > +	options = options | Option::First;
> > +
> > +	if (!(options & Option::First)) {
> > +		cerr << "Binary bitwise OR with enum failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	/* options = options & Mode::Alpha; */
> > +	/* options = options | Mode::Beta;  */
> > +	/* options = options ^ Mode::Gamma; */
> > +
> > +	options = options & ~Option::First;
> > +
> > +	if (options != (Option::First & Option::Second)) {
> > +		cerr << "Binary bitwise AND with enum failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options = options ^ (Option::First ^ Option::Second);
> > +
> > +	if (options != (Option::First | Option::Second)) {
> > +		cerr << "Binary bitwise XOR with enum failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options = Options();
> > +
> > +	/*
> > +	 * Binary operators with Flags argument.
> > +	 */
> > +
> > +	options |= Options(Option::First);
> > +
> > +	if (!(options & Option::First)) {
> > +		cerr << "Binary bitwise OR with Flags<> failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	/* options = options & Options(Mode::Alpha); */
> > +	/* options = options | Options(Mode::Beta);  */
> > +	/* options = options ^ Options(Mode::Gamma); */
> 
> So Mode is not actually used ?

Correct.

> > +
> > +	options = options & ~Options(Option::First);
> > +
> > +	if (options) {
> > +		cerr << "Binary bitwise AND with Flags<> failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options = options ^ Options(Option::Second);
> > +
> > +	if (options != Option::Second) {
> > +		cerr << "Binary bitwise XOR with Flags<> failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	options = Options();
> > +
> > +	/*
> > +	 * Conversion operators.
> > +	 */
> 
> Don't these comments fits on one line ?

I thought they were more effective at creating sections to improve
readability when using multiple lines, but if it bothers you I can
change that.

> > +	options |= Option::First | Option::Second | Option::Third;
> > +	if (static_cast<Options::Type>(options) != 7) {
> > +		cerr << "Cast to underlying type failed" << endl;
> > +		return TestFail;
> > +	}
> > +
> > +	/*
> > +	 * Conversion of the result of ninary operators on the underlying enum.
> > +	 */
> > +
> > +	/* unsigned int val1 = Option::First; */
> > +	/* unsigned int val2 = ~Option::First; */
> > +	/* unsigned int val3 = Option::First | Option::Second; */
> > +	/* Option val4 = ~Option::First; */
> > +	/* Option val5 = Option::First | Option::Second; */
> > +
> > +	return TestPass;
> > +}
> > +
> > +TEST_REGISTER(FlagsTest)
> > diff --git a/test/meson.build b/test/meson.build
> > index 2c3e76546fbc..3bceb5df586f 100644
> > --- a/test/meson.build
> > +++ b/test/meson.build
> > @@ -40,6 +40,7 @@ internal_tests = [
> >      ['event-thread',                    'event-thread.cpp'],
> >      ['file',                            'file.cpp'],
> >      ['file-descriptor',                 'file-descriptor.cpp'],
> > +    ['flags',                           'flags.cpp'],
> >      ['hotplug-cameras',                 'hotplug-cameras.cpp'],
> >      ['mapped-buffer',                   'mapped-buffer.cpp'],
> >      ['message',                         'message.cpp'],

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list