test_rewind.cxx 4.14 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

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;
	}

40
	size_t Read(void *ptr, size_t read_size) override {
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
		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());
74
		CPPUNIT_ASSERT_EQUAL(offset_type(0), ris->GetOffset());
75 76 77

		Error error;
		char buffer[16];
78
		size_t nbytes = ris->Read(buffer, 2);
79 80 81
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('f', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
82
		CPPUNIT_ASSERT_EQUAL(offset_type(2), ris->GetOffset());
83 84
		CPPUNIT_ASSERT(!ris->IsEOF());

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

92
		ris->Seek(1);
93
		CPPUNIT_ASSERT_EQUAL(offset_type(1), ris->GetOffset());
94 95
		CPPUNIT_ASSERT(!ris->IsEOF());

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

103
		ris->Seek(0);
104
		CPPUNIT_ASSERT_EQUAL(offset_type(0), ris->GetOffset());
105 106
		CPPUNIT_ASSERT(!ris->IsEOF());

107
		nbytes = ris->Read(buffer, 2);
108 109 110
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('f', buffer[0]);
		CPPUNIT_ASSERT_EQUAL('o', buffer[1]);
111
		CPPUNIT_ASSERT_EQUAL(offset_type(2), ris->GetOffset());
112 113
		CPPUNIT_ASSERT(!ris->IsEOF());

114
		nbytes = ris->Read(buffer, sizeof(buffer));
115 116 117
		CPPUNIT_ASSERT_EQUAL(size_t(2), nbytes);
		CPPUNIT_ASSERT_EQUAL('o', buffer[0]);
		CPPUNIT_ASSERT_EQUAL(' ', buffer[1]);
118
		CPPUNIT_ASSERT_EQUAL(offset_type(4), ris->GetOffset());
119 120
		CPPUNIT_ASSERT(!ris->IsEOF());

121
		nbytes = ris->Read(buffer, sizeof(buffer));
122 123 124 125
		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]);
126
		CPPUNIT_ASSERT_EQUAL(offset_type(7), ris->GetOffset());
127 128
		CPPUNIT_ASSERT(ris->IsEOF());

129
		ris->Seek(3);
130
		CPPUNIT_ASSERT_EQUAL(offset_type(3), ris->GetOffset());
131 132
		CPPUNIT_ASSERT(!ris->IsEOF());

133
		nbytes = ris->Read(buffer, sizeof(buffer));
134 135 136 137 138
		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]);
139
		CPPUNIT_ASSERT_EQUAL(offset_type(7), ris->GetOffset());
140 141 142 143 144 145 146 147 148 149 150 151 152 153
		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;
}