blob: 594e686db7735d52920390b3c6511d5ebc10f81a [file] [log] [blame]
// 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 <string>
#include <gmock/gmock.h>
#include <mesos/type_utils.hpp>
#include <stout/gtest.hpp>
#include <stout/none.hpp>
#include <stout/os.hpp>
#include <stout/protobuf.hpp>
#include <stout/result.hpp>
#include <stout/tests/utils.hpp>
#include "messages/messages.hpp"
using std::string;
using google::protobuf::RepeatedPtrField;
namespace mesos {
namespace internal {
namespace tests {
class ProtobufIOTest : public TemporaryDirectoryTest {};
// TODO(bmahler): Move this file into stout.
TEST_F(ProtobufIOTest, Basic)
{
const string file = ".protobuf_io_test_basic";
Try<int_fd> result = os::open(
file,
O_CREAT | O_WRONLY | O_SYNC | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
ASSERT_SOME(result);
int_fd fdw = result.get();
result = os::open(
file,
O_CREAT | O_RDONLY | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
ASSERT_SOME(result);
int_fd fdr = result.get();
const size_t writes = 10;
for (size_t i = 0; i < writes; i++) {
FrameworkID frameworkId;
frameworkId.set_value(stringify(i));
Try<Nothing> result = ::protobuf::write(fdw, frameworkId);
ASSERT_SOME(result);
}
Result<FrameworkID> read = None();
size_t reads = 0;
while (true) {
read = ::protobuf::read<FrameworkID>(fdr);
if (!read.isSome()) {
break;
}
EXPECT_EQ(read->value(), stringify(reads++));
}
// Ensure we've hit the end of the file without reading a partial
// protobuf.
ASSERT_NONE(read);
ASSERT_EQ(writes, reads);
os::close(fdw);
os::close(fdr);
}
TEST_F(ProtobufIOTest, Append)
{
const string file = ".protobuf_io_test_append";
const size_t writes = 10;
for (size_t i = 0; i < writes; i++) {
FrameworkID frameworkId;
frameworkId.set_value(stringify(i));
Try<Nothing> result = ::protobuf::append(file, frameworkId);
ASSERT_SOME(result);
}
Try<int_fd> fd = os::open(
file,
O_CREAT | O_RDONLY | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
ASSERT_SOME(fd);
Result<FrameworkID> read = None();
size_t reads = 0;
while (true) {
read = ::protobuf::read<FrameworkID>(fd.get());
if (!read.isSome()) {
break;
}
EXPECT_EQ(read->value(), stringify(reads++));
}
// Ensure we've hit the end of the file without reading a partial
// protobuf.
ASSERT_NONE(read);
ASSERT_EQ(writes, reads);
os::close(fd.get());
}
TEST_F(ProtobufIOTest, RepeatedPtrField)
{
const string file = ".protobuf_io_test_repeated_ptr_field";
RepeatedPtrField<FrameworkID> expected;
// NOTE: This uses `int` instead of `size_t` because eventually the iterator
// is used in `Get(int)`, and converting from `size_t` generates a warning.
const int size = 10;
for (int i = 0; i < size; i++) {
FrameworkID frameworkId;
frameworkId.set_value(stringify(i));
expected.Add()->CopyFrom(frameworkId);
}
Try<Nothing> write = ::protobuf::write(file, expected);
ASSERT_SOME(write);
Result<RepeatedPtrField<FrameworkID>> actual =
::protobuf::read<RepeatedPtrField<FrameworkID>>(file);
ASSERT_SOME(actual);
ASSERT_EQ(expected.size(), actual->size());
for (int i = 0; i < size; i++) {
EXPECT_EQ(expected.Get(i), actual->Get(i));
}
}
} // namespace tests {
} // namespace internal {
} // namespace mesos {