| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "boost/filesystem.hpp" |
| #include "Stream.hh" |
| #include "Exception.hh" |
| #include <boost/test/included/unit_test_framework.hpp> |
| #include <boost/test/parameterized_test.hpp> |
| |
| namespace avro { |
| namespace stream { |
| |
| struct CheckEmpty1 { |
| void operator()(InputStream& is) { |
| const uint8_t* d; |
| size_t n; |
| BOOST_CHECK(! is.next(&d, &n)); |
| } |
| }; |
| |
| struct CheckEmpty2 { |
| void operator()(InputStream& is) { |
| StreamReader r; |
| r.reset(is); |
| BOOST_CHECK_THROW(r.read(), Exception); |
| } |
| }; |
| |
| struct TestData { |
| size_t chunkSize; |
| size_t dataSize; |
| }; |
| |
| struct Fill1 { |
| void operator()(OutputStream& os, size_t len) { |
| StreamWriter w; |
| w.reset(os); |
| for (size_t i = 0; i < len; ++i) { |
| w.write(i % 10 + '0'); |
| } |
| w.flush(); |
| } |
| }; |
| |
| struct Fill2 { |
| void operator()(OutputStream& os, size_t len) { |
| for (size_t i = 0; i < len;) { |
| uint8_t *b; |
| size_t n; |
| os.next(&b, &n); |
| size_t j = 0; |
| for (; i < len && j < n; ++j, ++i, ++b) { |
| *b = i % 10 + '0'; |
| } |
| if (i == len) { |
| os.backup(n - j); |
| } |
| } |
| os.flush(); |
| } |
| }; |
| |
| struct Verify1 { |
| void operator()(InputStream& is, size_t dataSize) { |
| StreamReader r; |
| r.reset(is); |
| for (size_t i = 0; i < dataSize; ++i) { |
| BOOST_CHECK_EQUAL(i % 10 + '0', r.read()); |
| } |
| BOOST_CHECK_THROW(r.read(), Exception); |
| } |
| }; |
| |
| struct Verify2 { |
| void operator()(InputStream& is, size_t len) { |
| const uint8_t *b; |
| size_t n; |
| |
| for (size_t i = 0; i < len;) { |
| BOOST_REQUIRE(is.next(&b, &n)); |
| size_t j = 0; |
| for (; i < len && j < n; ++j, ++i, ++b) { |
| BOOST_CHECK_EQUAL(*b, i % 10 + '0'); |
| } |
| BOOST_CHECK_EQUAL(j, n); |
| } |
| BOOST_CHECK(! is.next(&b, &n)); |
| } |
| }; |
| |
| template <typename V> |
| void testEmpty_memoryStream() { |
| std::auto_ptr<OutputStream> os = memoryOutputStream(); |
| std::auto_ptr<InputStream> is = memoryInputStream(*os); |
| V()(*is); |
| } |
| |
| template <typename F, typename V> |
| void testNonEmpty_memoryStream(const TestData& td) |
| { |
| std::auto_ptr<OutputStream> os = memoryOutputStream(td.chunkSize); |
| F()(*os, td.dataSize); |
| |
| std::auto_ptr<InputStream> is = memoryInputStream(*os); |
| V()(*is, td.dataSize); |
| } |
| |
| void testNonEmpty2(const TestData& td) { |
| std::vector<uint8_t> v; |
| for (size_t i = 0; i < td.dataSize; ++i) { |
| v.push_back(i % 10 + '0'); |
| } |
| |
| std::auto_ptr<InputStream> is = memoryInputStream(&v[0], v.size()); |
| Verify1()(*is, td.dataSize); |
| } |
| |
| static const char filename[] = "test_str.bin"; |
| |
| struct FileRemover { |
| const boost::filesystem::path file; |
| FileRemover(const char* filename) : file(filename) { } |
| ~FileRemover() { boost::filesystem::remove(file); } |
| }; |
| |
| template <typename V> |
| void testEmpty_fileStream() { |
| FileRemover fr(filename); |
| { |
| std::auto_ptr<OutputStream> os = fileOutputStream(filename); |
| } |
| std::auto_ptr<InputStream> is = fileInputStream(filename); |
| V()(*is); |
| } |
| |
| template <typename F, typename V> |
| void testNonEmpty_fileStream(const TestData& td) |
| { |
| FileRemover fr(filename); |
| { |
| std::auto_ptr<OutputStream> os = fileOutputStream(filename, |
| td.chunkSize); |
| F()(*os, td.dataSize); |
| } |
| |
| std::auto_ptr<InputStream> is = fileInputStream(filename, td.chunkSize); |
| V()(*is, td.dataSize); |
| } |
| |
| TestData data[] = { |
| { 100, 0 }, |
| { 100, 1 }, |
| { 100, 10 }, |
| { 100, 100 }, |
| { 100, 101 }, |
| { 100, 1000 }, |
| { 100, 1024 } |
| }; |
| |
| } // namespace stream |
| |
| } // namespace |
| |
| boost::unit_test::test_suite* |
| init_unit_test_suite( int argc, char* argv[] ) |
| { |
| boost::unit_test::test_suite* ts = |
| BOOST_TEST_SUITE("Avro C++ unit test suite for streams"); |
| |
| ts->add(BOOST_TEST_CASE( |
| &avro::stream::testEmpty_memoryStream<avro::stream::CheckEmpty1>)); |
| ts->add(BOOST_TEST_CASE( |
| &avro::stream::testEmpty_memoryStream<avro::stream::CheckEmpty2>)); |
| |
| ts->add(BOOST_PARAM_TEST_CASE( |
| (&avro::stream::testNonEmpty_memoryStream<avro::stream::Fill1, |
| avro::stream::Verify1>), |
| avro::stream::data, |
| avro::stream::data + |
| sizeof(avro::stream::data) / sizeof(avro::stream::data[0]))); |
| ts->add(BOOST_PARAM_TEST_CASE( |
| (&avro::stream::testNonEmpty_memoryStream<avro::stream::Fill2, |
| avro::stream::Verify1>), |
| avro::stream::data, |
| avro::stream::data + |
| sizeof(avro::stream::data) / sizeof(avro::stream::data[0]))); |
| ts->add(BOOST_PARAM_TEST_CASE( |
| (&avro::stream::testNonEmpty_memoryStream<avro::stream::Fill2, |
| avro::stream::Verify2>), |
| avro::stream::data, |
| avro::stream::data + |
| sizeof(avro::stream::data) / sizeof(avro::stream::data[0]))); |
| |
| ts->add(BOOST_PARAM_TEST_CASE(&avro::stream::testNonEmpty2, |
| avro::stream::data, |
| avro::stream::data + |
| sizeof(avro::stream::data) / sizeof(avro::stream::data[0]))); |
| |
| ts->add(BOOST_TEST_CASE( |
| &avro::stream::testEmpty_fileStream<avro::stream::CheckEmpty1>)); |
| ts->add(BOOST_TEST_CASE( |
| &avro::stream::testEmpty_fileStream<avro::stream::CheckEmpty2>)); |
| |
| ts->add(BOOST_PARAM_TEST_CASE( |
| (&avro::stream::testNonEmpty_fileStream<avro::stream::Fill1, |
| avro::stream::Verify1>), |
| avro::stream::data, |
| avro::stream::data + |
| sizeof(avro::stream::data) / sizeof(avro::stream::data[0]))); |
| ts->add(BOOST_PARAM_TEST_CASE( |
| (&avro::stream::testNonEmpty_fileStream<avro::stream::Fill2, |
| avro::stream::Verify1>), |
| avro::stream::data, |
| avro::stream::data + |
| sizeof(avro::stream::data) / sizeof(avro::stream::data[0]))); |
| ts->add(BOOST_PARAM_TEST_CASE( |
| (&avro::stream::testNonEmpty_fileStream<avro::stream::Fill2, |
| avro::stream::Verify2>), |
| avro::stream::data, |
| avro::stream::data + |
| sizeof(avro::stream::data) / sizeof(avro::stream::data[0]))); |
| return ts; |
| } |