Files
scylladb/tests/fstream_test.cc
Avi Kivity 439b9c848a tests: fix fstream_test misuse of shared_ptr
'static shared_ptr' causes the shared_ptr to be destroyed on a cpu other
than the one it was constructed on, which is illegal.
2015-06-20 12:02:00 +03:00

136 lines
5.1 KiB
C++

/*
* This file is open source software, licensed to you under the terms
* of the Apache License, Version 2.0 (the "License"). See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. 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.
*/
/*
* Copyright (C) 2015 Cloudius Systems, Ltd.
*/
#include <algorithm>
#include <iostream>
#include "core/reactor.hh"
#include "core/fstream.hh"
#include "core/shared_ptr.hh"
#include "core/app-template.hh"
#include "core/do_with.hh"
#include "test-utils.hh"
struct writer {
output_stream<char> out;
writer(file f) : out(make_file_output_stream(
make_lw_shared<file>(std::move(f)))) {}
};
struct reader {
input_stream<char> in;
reader(file f) : in(make_file_input_stream(
make_lw_shared<file>(std::move(f)))) {}
};
SEASTAR_TEST_CASE(test_fstream) {
auto sem = make_lw_shared<semaphore>(0);
engine().open_file_dma("testfile.tmp",
open_flags::rw | open_flags::create | open_flags::truncate).then([sem] (file f) {
auto w = make_shared<writer>(std::move(f));
auto buf = static_cast<char*>(::malloc(4096));
memset(buf, 0, 4096);
buf[0] = '[';
buf[1] = 'A';
buf[4095] = ']';
w->out.write(buf, 4096).then([buf, w] {
::free(buf);
return make_ready_future<>();
}).then([w] {
auto buf = static_cast<char*>(::malloc(8192));
memset(buf, 0, 8192);
buf[0] = '[';
buf[1] = 'B';
buf[8191] = ']';
return w->out.write(buf, 8192).then([buf, w] {
::free(buf);
return w->out.close().then([w] {});
});
}).then([] {
return engine().open_file_dma("testfile.tmp", open_flags::ro);
}).then([] (file f) {
/* file content after running the above:
* 00000000 5b 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |[A..............|
* 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
* *
* 00000ff0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5d |...............]|
* 00001000 5b 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |[B..............|
* 00001010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
* *
* 00002ff0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5d |...............]|
* 00003000
*/
auto r = make_shared<reader>(std::move(f));
return r->in.read_exactly(4096 + 8192).then([r] (temporary_buffer<char> buf) {
auto p = buf.get();
BOOST_REQUIRE(p[0] == '[' && p[1] == 'A' && p[4095] == ']');
BOOST_REQUIRE(p[4096] == '[' && p[4096 + 1] == 'B' && p[4096 + 8191] == ']');
return make_ready_future<>();
});
}).finally([sem] () {
sem->signal();
});
});
return sem->wait();
}
SEASTAR_TEST_CASE(test_fstream_unaligned) {
auto sem = make_lw_shared<semaphore>(0);
engine().open_file_dma("testfile.tmp",
open_flags::rw | open_flags::create | open_flags::truncate).then([sem] (file f) {
auto w = make_shared<writer>(std::move(f));
auto buf = static_cast<char*>(::malloc(40));
memset(buf, 0, 40);
buf[0] = '[';
buf[1] = 'A';
buf[39] = ']';
w->out.write(buf, 40).then([buf, w] {
::free(buf);
return w->out.close().then([w] {});
}).then([] {
return engine().open_file_dma("testfile.tmp", open_flags::ro);
}).then([] (file f) {
return do_with(std::move(f), [] (file& f) {
return f.size().then([] (size_t size) {
// assert that file was indeed truncated to the amount of bytes written.
BOOST_REQUIRE(size == 40);
return make_ready_future<>();
});
});
}).then([] {
return engine().open_file_dma("testfile.tmp", open_flags::ro);
}).then([] (file f) {
auto r = make_shared<reader>(std::move(f));
return r->in.read_exactly(40).then([r] (temporary_buffer<char> buf) {
auto p = buf.get();
BOOST_REQUIRE(p[0] == '[' && p[1] == 'A' && p[39] == ']');
return make_ready_future<>();
});
}).finally([sem] () {
sem->signal();
});
});
return sem->wait();
}