[libcamera-devel] [PATCH v2 4/4] test: MediaDevice: Add link exercise test

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Jan 8 19:22:15 CET 2019


Hi Jacopo,

Thank you for the patch.

On Tuesday, 8 January 2019 19:04:07 EET Jacopo Mondi wrote:
> Add test function to exercise the link handling abilities of the media
> device.
> 
> Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> ---
> v1->v2:
> - Make the link handling test work only on vimc as operating on a known
>   graph makes it possible to identify unexpected results.
> 
>  test/media_device/media_device_test.cpp | 147 +++++++++++++++++++++++-
>  1 file changed, 143 insertions(+), 4 deletions(-)
> 
> diff --git a/test/media_device/media_device_test.cpp
> b/test/media_device/media_device_test.cpp index c482b2e..2b2f5cd 100644
> --- a/test/media_device/media_device_test.cpp
> +++ b/test/media_device/media_device_test.cpp
> @@ -42,8 +42,145 @@ private:
>  	void printMediaGraph(const MediaDevice &media, ostream &os);
>  	void printLinkFlags(const MediaLink *link, ostream &os);
>  	void printNode(const MediaPad *pad, ostream &os);
> +
> +	int exerciseLinks(MediaDevice &media);

Especially given how we skip the test if we have a non-vimc device, I thnk 
this should really be part of a separate test class.

>  };
> 
> +/*
> + * Exercise the link handling interface.
> + *
> + * Try to get existing and non-existing links, and try to enable
> + * disable links.
> + *
> + * WARNING: this test only runs on VIMC, as a known media graph allows
> + * the test to exercise known links and verify the result of operations
> + * known to fail or succeed. If the 'vimc' driver is not loaded, the test
> is
> + * skipped.
> + */
> +int MediaDeviceTest::exerciseLinks(MediaDevice &media)
> +{
> +	if (media.driver() != "vimc")
> +		return TestSkip;

This check should be moved to the init() function of the test class.

> +	/* First of all reset all links in the media graph. */
> +	int ret = media.resetLinks();
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * Test if link can be consistently retrieved through the different
> +	 * methods the media device offers.
> +	 */
> +	MediaLink *link = media.link("Debayer A", 1, "Scaler", 0);
> +	if (!link) {
> +		cerr << "Unable to find link \"Debayer A\"[1] -> \"Scaler\"[0]"
> +		     << endl << "This link exists in VIMC media graph" << endl;
> +		return TestFail;
> +	}
> +
> +	MediaEntity *source = media.getEntityByName("Debayer A");
> +	if (!source) {
> +		cerr << "Unable to find entity \"Debayer A\"" << endl;
> +		return TestFail;
> +	}
> +
> +	MediaEntity *sink = media.getEntityByName("Scaler");
> +	if (!sink) {
> +		cerr << "Unable to find entity \"Scaler\"" << endl;
> +		return TestFail;
> +	}
> +
> +	MediaLink *link2 = media.link(source, 1, sink, 0);
> +	if (!link2) {
> +		cerr << "Unable to find link \"Debayer A\"[1] -> \"Scaler\"[0]"
> +		     << endl << "This link exists in VIMC media graph" << endl;
> +		return TestFail;
> +	}
> +
> +	if (link != link2) {
> +		cerr << "The returned link does not match what was expected"
> +		     << endl;
> +		return TestFail;
> +	}
> +
> +	link2 = media.link(source->getPadByIndex(1), sink->getPadByIndex(0));
> +	if (!link2) {
> +		cerr << "Unable to find link \"Debayer A\"[1] -> \"Scaler\"[0]"
> +		     << endl << "This link exists in VIMC media graph" << endl;
> +		return TestFail;
> +	}
> +
> +	if (link != link2) {
> +		cerr << "The returned link does not match what was expected"
> +		     << endl;
> +		return TestFail;
> +	}
> +
> +	/* After reset the link shall not be enabled. */
> +	if (link->flags() & MEDIA_LNK_FL_ENABLED) {
> +		cerr << "Link \"Debayer A\"[1] -> \"Scaler\"[0]"
> +		     << " should not be enabled after a media device reset"
> +		     << endl;
> +		return TestFail;
> +	}
> +
> +	/* Enable the link and test if enabling was successful. */
> +	ret = link->setEnable(true);
> +	if (ret)
> +		return TestFail;
> +
> +	if (!(link->flags() & MEDIA_LNK_FL_ENABLED)) {
> +		cerr << "Link \"Debayer A\"[1] -> \"Scaler\"[0]"
> +		     << " should now be enabled" << endl;
> +		return TestFail;
> +	}
> +
> +	/* Disable the link and test if disabling was successful. */
> +	ret = link->setEnable(false);
> +	if (ret)
> +		return TestFail;
> +
> +	if (link->flags() & MEDIA_LNK_FL_ENABLED) {
> +		cerr << "Link \"Debayer A\"[1] -> \"Scaler\"[0]"
> +		     << " should now be disabled" << endl;
> +		return TestFail;
> +	}
> +
> +	/* Try to get a non existing link. */
> +	link = media.link("Sensor A", 1, "Scaler", 0);
> +	if (link) {
> +		cerr << "Link \"Sensor A\"[1] -> \"Scaler\"[0]"
> +		     << " does not exist but something was returned"
> +		     << endl;
> +		return TestFail;
> +	}
> +
> +	/* Now get an immutable link and try to disable it. */
> +	link = media.link("Sensor A", 0, "Raw Capture 0", 0);
> +	if (!link) {
> +		cerr << "Unable to find link \"Sensor A\"[0] -> "
> +		     << "\"Raw Capture 0\"[0]"
> +		     << endl << "This link exists in VIMC media graph" << endl;
> +		return TestFail;
> +	}
> +
> +	if (!(link->flags() & MEDIA_LNK_FL_IMMUTABLE)) {
> +		cerr << "Link \"Sensor A\"[0] -> \"Raw Capture 0\"[0]"
> +		     << " should have been 'IMMUTABLE'" << endl;
> +		return TestFail;
> +	}
> +
> +	/* Disabling an immutable link shall fail. */
> +	ret = link->setEnable(false);
> +	if (!ret) {
> +		cerr << "Link \"Sensor A\"[0] -> \"Raw Capture 0\"[0]"
> +		     << " is 'IMMUTABLE', it shouldn't be disabled" << endl;
> +		return TestFail;
> +	}
> +
> +	return 0;
> +}
> +
>  void MediaDeviceTest::printNode(const MediaPad *pad, ostream &os)
>  {
>  	const MediaEntity *entity = pad->entity();
> @@ -136,11 +273,14 @@ int MediaDeviceTest::testMediaDevice(const string
> devnode)
> 
>  	/* Run tests in sequence. */
>  	printMediaGraph(dev, cerr);
> +
> +	ret = exerciseLinks(dev);
> +

You should iterate over all the media devices present in the system and pick 
the first vimc device, as it may not be /dev/media0. The device enumerator 
should provide you with the media devices (and this would also serve as a 
device enumerator test :-)).

>  	/* TODO: add more tests here. */
> 
>  	dev.close();
> 
> -	return 0;
> +	return ret;
>  }
> 
>  /* Run tests on all media devices. */
> @@ -149,7 +289,7 @@ int MediaDeviceTest::run()
>  {
>  	const string devnode("/dev/media");
>  	unsigned int i;
> -	int ret = 77; /* skip test exit code */
> +	int ret = TestSkip;
> 
>  	/*
>  	 * Run the test sequence on all media device found in the
> @@ -163,9 +303,8 @@ int MediaDeviceTest::run()
>  			continue;
> 
>  		ret = testMediaDevice(mediadev);
> -		if (ret)
> +		if (ret && ret != TestSkip)
>  			return ret;
> -
>  	}
> 
>  	return ret;

-- 
Regards,

Laurent Pinchart





More information about the libcamera-devel mailing list