test_rewind.cxx 4.29 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Unit tests for class RewindInputStream.
 */

#include "config.h"
#include "input/plugins/RewindInputPlugin.hxx"
#include "input/InputStream.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "util/Error.hxx"

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

#include <string>

#include <string.h>
20
#include <stdlib.h>
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

class StringInputStream final : public InputStream {
	const char *data;
	size_t remaining;

public:
	StringInputStream(const char *_uri,
			  Mutex &_mutex, Cond &_cond,
			  const char *_data)
		:InputStream(_uri, _mutex, _cond),
		 data(_data), remaining(strlen(data)) {
		SetReady();
	}

	/* virtual methods from InputStream */
	bool IsEOF() override {
		return remaining == 0;
	}

	size_t Read(void *ptr, size_t read_size,
		    gcc_unused Error &error) override {
		size_t nbytes = std::min(remaining, read_size);
		memcpy(ptr, data, nbytes);
		data += nbytes;
		remaining -= nbytes;
		offset += nbytes;
		return nbytes;
	}
};

class RewindTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(RewindTest);
	CPPUNIT_TEST(TestRewind);
	CPPUNIT_TEST_SUITE_END();

public:
	void TestRewind() {
		Mutex mutex;
		Cond cond;

		StringInputStream *sis =
			new StringInputStream("foo://", mutex, cond,
					      "foo bar");
		CPPUNIT_ASSERT(sis->IsReady());

		InputStream *ris = input_rewind_open(sis);
		CPPUNIT_ASSERT(ris != sis);
		CPPUNIT_ASSERT(ris != nullptr);

		const ScopeLock protect(mutex);

		ris->Update();
		CPPUNIT_ASSERT(ris->IsReady());
		CPPUNIT_ASSERT(!ris->KnownSize());
75
		CPPUNIT_ASSERT_EQUAL(offset_type(0), ris->GetOffset());
76 77 78 79 80 81 82

		Error error;
		char buffer[16];
		size_t nbytes = ris->Read(buffer, 2, error);
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('f', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
83
		CPPUNIT_ASSERT_EQUAL(offset_type(2), ris->GetOffset());
84 85 86 87 88 89
		CPPUNIT_ASSERT(!ris->IsEOF());

		nbytes = ris->Read(buffer, 2, error);
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('o', buffer[0]);
		CPPUNIT_ASSERT_EQUAL(' ', buffer[1]);
90
		CPPUNIT_ASSERT_EQUAL(offset_type(4), ris->GetOffset());
91 92
		CPPUNIT_ASSERT(!ris->IsEOF());

93
		CPPUNIT_ASSERT(ris->Seek(1, error));
94
		CPPUNIT_ASSERT_EQUAL(offset_type(1), ris->GetOffset());
95 96 97 98 99 100
		CPPUNIT_ASSERT(!ris->IsEOF());

		nbytes = ris->Read(buffer, 2, error);
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('o', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
101
		CPPUNIT_ASSERT_EQUAL(offset_type(3), ris->GetOffset());
102 103
		CPPUNIT_ASSERT(!ris->IsEOF());

104
		CPPUNIT_ASSERT(ris->Seek(0, error));
105
		CPPUNIT_ASSERT_EQUAL(offset_type(0), ris->GetOffset());
106 107 108 109 110 111
		CPPUNIT_ASSERT(!ris->IsEOF());

		nbytes = ris->Read(buffer, 2, error);
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('f', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
112
		CPPUNIT_ASSERT_EQUAL(offset_type(2), ris->GetOffset());
113 114 115 116 117 118
		CPPUNIT_ASSERT(!ris->IsEOF());

		nbytes = ris->Read(buffer, sizeof(buffer), error);
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('o', buffer[0]);
		CPPUNIT_ASSERT_EQUAL(' ', buffer[1]);
119
		CPPUNIT_ASSERT_EQUAL(offset_type(4), ris->GetOffset());
120 121 122 123 124 125 126
		CPPUNIT_ASSERT(!ris->IsEOF());

		nbytes = ris->Read(buffer, sizeof(buffer), error);
		CPPUNIT_ASSERT_EQUAL(size_t(3), nbytes);
		CPPUNIT_ASSERT_EQUAL('b', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('a', buffer[1]);
		CPPUNIT_ASSERT_EQUAL('r', buffer[2]);
127
		CPPUNIT_ASSERT_EQUAL(offset_type(7), ris->GetOffset());
128 129
		CPPUNIT_ASSERT(ris->IsEOF());

130
		CPPUNIT_ASSERT(ris->Seek(3, error));
131
		CPPUNIT_ASSERT_EQUAL(offset_type(3), ris->GetOffset());
132 133 134 135 136 137 138 139
		CPPUNIT_ASSERT(!ris->IsEOF());

		nbytes = ris->Read(buffer, sizeof(buffer), error);
		CPPUNIT_ASSERT_EQUAL(size_t(4), nbytes);
		CPPUNIT_ASSERT_EQUAL(' ', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('b', buffer[1]);
		CPPUNIT_ASSERT_EQUAL('a', buffer[2]);
		CPPUNIT_ASSERT_EQUAL('r', buffer[3]);
140
		CPPUNIT_ASSERT_EQUAL(offset_type(7), ris->GetOffset());
141 142 143 144 145 146 147 148 149 150 151 152 153 154
		CPPUNIT_ASSERT(ris->IsEOF());
	}
};

CPPUNIT_TEST_SUITE_REGISTRATION(RewindTest);

int
main(gcc_unused int argc, gcc_unused char **argv)
{
	CppUnit::TextUi::TestRunner runner;
	auto &registry = CppUnit::TestFactoryRegistry::getRegistry();
	runner.addTest(registry.makeTest());
	return runner.run() ? EXIT_SUCCESS : EXIT_FAILURE;
}