summaryrefslogtreecommitdiff
path: root/src/ipa/libipa
AgeCommit message (Expand)Author
2022-05-18ipa: libipa: Add frame context pointer in process()Umang Jain
2022-05-13libipa: camera_sensor_helper: Add OV5675 helperQuentin Schulz
2022-04-01libipa: camera_sensor_helper: Add OV5640 helperPaul Elder
2022-04-01libipa: camera_sensor_helper: Add IMX296 helperLaurent Pinchart
2022-04-01libipa: camera_sensor_helper: Add IMX290 helperLaurent Pinchart
2022-04-01libipa: camera_sensor_helper: Implement exponential gain modelLaurent Pinchart
2022-04-01libipa: camera_sensor_helper: Reorganize gain constantsLaurent Pinchart
2022-03-28ipa: libipa: Histogram: Constify the constructor spanJean-Michel Hautbois
2022-03-17libipa: Add CameraSensorHelper for OV2740Daniel Scally
2021-11-29ipa: libipa: Introduce Algorithm class templateJean-Michel Hautbois
2021-11-29libipa: Correct IMX219 in CameraSensorHelperJean-Michel Hautbois
2021-11-24ipa: libipa: Convert to pragma onceKieran Bingham
2021-08-31ipa: libipa: histogram: Fix typoLaurent Pinchart
2021-08-20ipa: move libipa::Algorithm to ipa/ipu3/algorithmsJean-Michel Hautbois
2021-08-09libcamera: Rename 'method' to 'function'Laurent Pinchart
2021-07-25libipa: Add CameraSensorHelper for ov8865Daniel Scally
2021-07-23libipa: Add CameraSensorHelper for IMX258Umang Jain
2021-07-15libipa: Correct OV5670 CameraSensorHelper gain valuesJean-Michel Hautbois
2021-07-15libipa: Add CameraSensorHelper for OV13858Jean-Michel Hautbois
2021-07-09ipa: libipa: Fixups in CameraSensorHelpersJean-Michel Hautbois
2021-06-28ipa: Create a camera sensor helper classJean-Michel Hautbois
2021-06-25libcamera/base: Validate internal headers as privateKieran Bingham
2021-06-25libcamera/base: Move span to base libraryKieran Bingham
2021-06-25libcamera/base: Move extended base functionalityKieran Bingham
2021-04-22ipa: ipu3: Add a histogram classJean-Michel Hautbois
2021-04-22ipa: Add a common interface for algorithm objectsJean-Michel Hautbois
2021-02-16libcamera: IPAInterface: Replace C API with the new C++-only APIPaul Elder
2020-12-08libcamera: ipa: Pass a set of controls and return results from ipa::start()Naushir Patuck
2020-07-17libcamera: ipa_interface: Add support for custom IPA data to configure()Laurent Pinchart
2020-05-16libcamera: Move IPA headers from include/ipa/ to include/libcamera/ipa/Laurent Pinchart
2020-05-16libcamera: Move internal headers to include/libcamera/internal/Laurent Pinchart
2020-05-13licenses: License all meson files under CC0-1.0Laurent Pinchart
2020-04-28libcamera: ipa: Add support for CameraSensorInfoJacopo Mondi
2020-04-28ipa: Pass IPA initialization settings to IPAInterface::init()Laurent Pinchart
2020-04-14ipa: Add start() and stop() operationsNiklas Söderlund
2020-01-14libcamera: Switch from utils::make_unique to std::make_uniqueLaurent Pinchart
2020-01-12ipa: Switch to FrameBuffer interfaceNiklas Söderlund
2019-11-20ipa: Allow short-circuiting the ipa_context_opsLaurent Pinchart
2019-11-20ipa: Switch to the plain C APIJacopo Mondi
href='#n339'>339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2020, Google Inc.
 *
 * file.cpp - File I/O operations tests
 */

#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include "libcamera/internal/file.h"

#include "test.h"

using namespace std;
using namespace libcamera;

class FileTest : public Test
{
protected:
	int init()
	{
		fileName_ = "/tmp/libcamera.test.XXXXXX";
		int fd = mkstemp(&fileName_.front());
		if (fd == -1)
			return TestFail;

		close(fd);
		unlink(fileName_.c_str());

		return TestPass;
	}

	int run()
	{
		/* Test static functions. */
		if (!File::exists("/dev/null")) {
			cerr << "Valid file not found" << endl;
			return TestFail;
		}

		if (File::exists("/dev/null/invalid")) {
			cerr << "Invalid file should not exist" << endl;
			return TestFail;
		}

		if (File::exists("/dev")) {
			cerr << "Directories should not be treated as files" << endl;
			return TestFail;
		}

		/* Test unnamed file. */
		File file;

		if (!file.fileName().empty()) {
			cerr << "Unnamed file has non-empty file name" << endl;
			return TestFail;
		}

		if (file.exists()) {
			cerr << "Unnamed file exists" << endl;
			return TestFail;
		}

		if (file.isOpen()) {
			cerr << "File is open after construction" << endl;
			return TestFail;
		}

		if (file.openMode() != File::NotOpen) {
			cerr << "File has invalid open mode after construction"
			     << endl;
			return TestFail;
		}

		if (file.size() >= 0) {
			cerr << "Unnamed file has a size" << endl;
			return TestFail;
		}

		if (file.open(File::ReadWrite)) {
			cerr << "Opening unnamed file succeeded" << endl;
			return TestFail;
		}

		if (file.error() == 0) {
			cerr << "Open failure didn't set error" << endl;
			return TestFail;
		}

		/* Test named file referring to an invalid file. */
		file.setFileName("/dev/null/invalid");

		if (file.fileName() != "/dev/null/invalid") {
			cerr << "File reports incorrect file name" << endl;
			return TestFail;
		}

		if (file.exists()) {
			cerr << "Invalid file exists" << endl;
			return TestFail;
		}

		if (file.isOpen()) {
			cerr << "Invalid file is open after construction" << endl;
			return TestFail;
		}

		if (file.openMode() != File::NotOpen) {
			cerr << "Invalid file has invalid open mode after construction"
			     << endl;
			return TestFail;
		}

		if (file.size() >= 0) {
			cerr << "Invalid file has a size" << endl;
			return TestFail;
		}

		if (file.open(File::ReadWrite)) {
			cerr << "Opening invalid file succeeded" << endl;
			return TestFail;
		}

		/* Test named file referring to a valid file. */
		file.setFileName("/dev/null");

		if (!file.exists()) {
			cerr << "Valid file does not exist" << endl;
			return TestFail;
		}

		if (file.isOpen()) {
			cerr << "Valid file is open after construction" << endl;
			return TestFail;
		}

		if (file.openMode() != File::NotOpen) {
			cerr << "Valid file has invalid open mode after construction"
			     << endl;
			return TestFail;
		}

		if (file.size() >= 0) {
			cerr << "Invalid file has a size" << endl;
			return TestFail;
		}

		/* Test open and close. */
		if (!file.open(File::ReadWrite)) {
			cerr << "Opening file failed" << endl;
			return TestFail;
		}

		if (!file.isOpen()) {
			cerr << "Open file reported as closed" << endl;
			return TestFail;
		}

		if (file.openMode() != File::ReadWrite) {
			cerr << "Open file has invalid open mode" << endl;
			return TestFail;
		}

		file.close();

		if (file.isOpen()) {
			cerr << "Closed file reported as open" << endl;
			return TestFail;
		}

		if (file.openMode() != File::NotOpen) {
			cerr << "Closed file has invalid open mode" << endl;
			return TestFail;
		}

		/* Test size(). */
		file.setFileName("/proc/self/exe");

		if (file.size() >= 0) {
			cerr << "File has valid size before open" << endl;
			return TestFail;
		}

		file.open(File::ReadOnly);

		ssize_t size = file.size();
		if (size <= 0) {
			cerr << "File has invalid size after open" << endl;
			return TestFail;
		}

		file.close();

		/* Test file creation. */
		file.setFileName(fileName_);

		if (file.exists()) {
			cerr << "Temporary file already exists" << endl;
			return TestFail;
		}

		if (file.open(File::ReadOnly)) {
			cerr << "Read-only open succeeded on nonexistent file" << endl;
			return TestFail;
		}

		if (!file.open(File::WriteOnly)) {
			cerr << "Write-only open failed on nonexistent file" << endl;
			return TestFail;
		}

		if (!file.exists()) {
			cerr << "Write-only open failed to create file" << endl;
			return TestFail;
		}

		file.close();

		/* Test read and write. */
		std::array<uint8_t, 256> buffer = { 0 };

		strncpy(reinterpret_cast<char *>(buffer.data()), "libcamera",
			buffer.size());

		if (file.read(buffer) >= 0) {
			cerr << "Read succeeded on closed file" << endl;
			return TestFail;
		}

		if (file.write(buffer) >= 0) {
			cerr << "Write succeeded on closed file" << endl;
			return TestFail;
		}

		file.open(File::ReadOnly);

		if (file.write(buffer) >= 0) {
			cerr << "Write succeeded on read-only file" << endl;
			return TestFail;
		}

		file.close();

		file.open(File::ReadWrite);

		if (file.write({ buffer.data(), 9 }) != 9) {
			cerr << "Write test failed" << endl;
			return TestFail;
		}

		if (file.read(buffer) != 0) {
			cerr << "Read at end of file test failed" << endl;
			return TestFail;
		}

		if (file.seek(0) != 0) {
			cerr << "Seek test failed" << endl;
			return TestFail;
		}

		if (file.read(buffer) != 9) {
			cerr << "Read test failed" << endl;
			return TestFail;
		}

		if (file.pos() != 9) {
			cerr << "Position test failed" << endl;
			return TestFail;
		}

		file.close();

		/* Test mapping and unmapping. */
		file.setFileName("/proc/self/exe");
		file.open(File::ReadOnly);

		Span<uint8_t> data = file.map();
		if (data.empty()) {
			cerr << "Mapping of complete file failed" << endl;
			return TestFail;
		}

		if (data.size() != static_cast<size_t>(size)) {
			cerr << "Mapping  of complete file has invalid size" << endl;
			return TestFail;
		}

		if (!file.unmap(data.data())) {
			cerr << "Unmapping of complete file failed" << endl;
			return TestFail;
		}

		data = file.map(4096, 8192);
		if (data.empty()) {
			cerr << "Mapping of file region failed" << endl;
			return TestFail;
		}

		if (data.size() != 8192) {
			cerr << "Mapping of file region has invalid size" << endl;
			return TestFail;
		}

		if (!file.unmap(data.data())) {
			cerr << "Unmapping of file region failed" << endl;
			return TestFail;
		}

		file.close();

		/* Test private mapping. */
		file.setFileName(fileName_);
		file.open(File::ReadWrite);

		data = file.map(0, -1, File::MapPrivate);
		if (data.empty()) {
			cerr << "Private mapping failed" << endl;
			return TestFail;
		}

		std::string str{ reinterpret_cast<char *>(data.data()), data.size() };
		if (str != "libcamera") {
			cerr << "Invalid contents of private mapping" << endl;
			return TestFail;
		}

		memcpy(data.data(), "LIBCAMERA", 9);

		if (!file.unmap(data.data())) {
			cerr << "Private unmapping failed" << endl;
			return TestFail;
		}

		data = file.map();

		str = { reinterpret_cast<char *>(data.data()), data.size() };
		if (str != "libcamera") {
			cerr << "Private mapping changed file contents" << endl;
			return TestFail;
		}

		/* Test shared mapping. */
		data = file.map();
		if (data.empty()) {
			cerr << "Shared mapping failed" << endl;
			return TestFail;
		}

		memcpy(data.data(), "LIBCAMERA", 9);

		if (!file.unmap(data.data())) {
			cerr << "Shared unmapping failed" << endl;
			return TestFail;
		}

		data = file.map();

		str = { reinterpret_cast<char *>(data.data()), data.size() };
		if (str != "LIBCAMERA") {
			cerr << "Shared mapping failed to change file contents"
			     << endl;
			return TestFail;
		}

		return TestPass;
	}

	void cleanup()
	{
		unlink(fileName_.c_str());
	}

private:
	std::string fileName_;
};

TEST_REGISTER(FileTest)