summaryrefslogtreecommitdiff
path: root/test/v4l2_compat
AgeCommit message (Expand)Author
2022-12-24test: v4l2_compat: Enable test with ASanLaurent Pinchart
2022-12-24test: v4l2_compat: Reduce indentationLaurent Pinchart
2022-01-17test: v4l2_compat: Add --verbose argumentLaurent Pinchart
2021-09-23test: v4l2_compat: Skip vimc as a test candidatePaul Elder
2021-09-19test: v4l2_compat: Report test as skipped if no compatible driver foundLaurent Pinchart
2021-09-10test: v4l2_compat_test: Fix v4l2-compliance version parsingPaul Elder
2021-09-01test: v4l2_compat: Disable test when ASan is enabledLaurent Pinchart
2020-07-17tests: v4l2_compat: Fix v4l2-compliance and v4l2-ctl version parsingPaul Elder
2020-07-13tests: v4l2_compat: Check v4l2-compliance and v4l2-ctl versionsPaul Elder
2020-07-13tests: v4l2_compat: Prettify failure outputPaul Elder
2020-07-10tests: v4l2_compat: Add test for v4l2_compatPaul Elder
1 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2018, Google Inc.
 *
 * byte_stream_buffer.cpp - ByteStreamBuffer tests
 */

#include <array>
#include <iostream>

#include "libcamera/internal/byte_stream_buffer.h"

#include "test.h"

using namespace std;
using namespace libcamera;

class ByteStreamBufferTest : public Test
{
protected:
	int run()
	{
		/*
		 * gcc 11.1.0 incorrectly raises a maybe-uninitialized warning
		 * when calling data.size() below (if the address sanitizer is
		 * disabled). Silence it by initializing the array.
		 */
		std::array<uint8_t, 100> data = {};
		unsigned int i;
		uint32_t value;
		int ret;

		/*
		 * Write mode.
		 */
		ByteStreamBuffer wbuf(data.data(), data.size());

		if (wbuf.base() != data.data() || wbuf.size() != data.size() ||
		    wbuf.offset() != 0 || wbuf.overflow()) {
			cerr << "Write buffer incorrectly constructed" << endl;
			return TestFail;
		}

		/* Test write. */
		value = 0x12345678;
		ret = wbuf.write(&value);
		if (ret || wbuf.offset() != 4 || wbuf.overflow() ||
		    *reinterpret_cast<uint32_t *>(data.data()) != 0x12345678) {
			cerr << "Write failed on write buffer" << endl;
			return TestFail;
		}

		/* Test write carve out. */
		ByteStreamBuffer wco = wbuf.carveOut(10);
		if (wco.base() != wbuf.base() + 4 || wco.size() != 10 ||
		    wco.offset() != 0 || wco.overflow() || wbuf.offset() != 14 ||
		    wbuf.overflow()) {
			cerr << "Carving out write buffer failed" << endl;
			return TestFail;
		}

		/* Test write on the carved out buffer. */
		value = 0x87654321;
		ret = wco.write(&value);
		if (ret || wco.offset() != 4 || wco.overflow() ||
		    *reinterpret_cast<uint32_t *>(data.data() + 4) != 0x87654321) {
			cerr << "Write failed on carve out buffer" << endl;
			return TestFail;
		}

		if (wbuf.offset() != 14 || wbuf.overflow()) {
			cerr << "Write on carve out buffer modified write buffer" << endl;
			return TestFail;
		}

		/* Test read, this should fail. */
		ret = wbuf.read(&value);
		if (!ret || wbuf.overflow()) {
			cerr << "Read should fail on write buffer" << endl;
			return TestFail;
		}

		/* Test overflow on carved out buffer. */
		for (i = 0; i < 2; ++i) {
			ret = wco.write(&value);
			if (ret < 0)
				break;
		}

		if (i != 1 || !wco.overflow() || !wbuf.overflow()) {
			cerr << "Write on carve out buffer failed to overflow" << endl;
			return TestFail;
		}

		/* Test reinitialization of the buffer. */
		wbuf = ByteStreamBuffer(data.data(), data.size());
		if (wbuf.overflow() || wbuf.base() != data.data() ||
		    wbuf.offset() != 0) {
			cerr << "Write buffer reinitialization failed" << endl;
			return TestFail;
		}

		/*
		 * Read mode.
		 */
		ByteStreamBuffer rbuf(const_cast<const uint8_t *>(data.data()),
				      data.size());

		if (rbuf.base() != data.data() || rbuf.size() != data.size() ||
		    rbuf.offset() != 0 || rbuf.overflow()) {
			cerr << "Read buffer incorrectly constructed" << endl;
			return TestFail;
		}

		/* Test read. */
		value = 0;
		ret = rbuf.read(&value);
		if (ret || rbuf.offset() != 4 || rbuf.overflow() ||
		    value != 0x12345678) {
			cerr << "Write failed on write buffer" << endl;
			return TestFail;
		}

		/* Test read carve out. */
		ByteStreamBuffer rco = rbuf.carveOut(10);
		if (rco.base() != rbuf.base() + 4 || rco.size() != 10 ||
		    rco.offset() != 0 || rco.overflow() || rbuf.offset() != 14 ||
		    rbuf.overflow()) {
			cerr << "Carving out read buffer failed" << endl;
			return TestFail;
		}

		/* Test read on the carved out buffer. */
		value = 0;
		ret = rco.read(&value);
		if (ret || rco.offset() != 4 || rco.overflow() || value != 0x87654321) {
			cerr << "Read failed on carve out buffer" << endl;
			return TestFail;
		}

		if (rbuf.offset() != 14 || rbuf.overflow()) {
			cerr << "Read on carve out buffer modified read buffer" << endl;
			return TestFail;
		}

		/* Test write, this should fail. */
		ret = rbuf.write(&value);
		if (!ret || rbuf.overflow()) {
			cerr << "Write should fail on read buffer" << endl;
			return TestFail;
		}

		/* Test overflow on carved out buffer. */
		for (i = 0; i < 2; ++i) {
			ret = rco.read(&value);
			if (ret < 0)
				break;
		}

		if (i != 1 || !rco.overflow() || !rbuf.overflow()) {
			cerr << "Read on carve out buffer failed to overflow" << endl;
			return TestFail;
		}

		/* Test reinitialization of the buffer. */
		rbuf = ByteStreamBuffer(const_cast<const uint8_t *>(data.data()),
					data.size());
		if (rbuf.overflow() || rbuf.base() != data.data() ||
		    rbuf.offset() != 0) {
			cerr << "Read buffer reinitialization failed" << endl;
			return TestFail;
		}

		return TestPass;
	}
};

TEST_REGISTER(ByteStreamBufferTest)