text: // 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.get().value(), stringify(reads++));
    }
  
    // Ensure we've hit the end of the file without reading a partial
    // protobuf.
    ASSERT_TRUE(read.isNone());
    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.get().value(), stringify(reads++));
    }
  
    // Ensure we've hit the end of the file without reading a partial
    // protobuf.
    ASSERT_TRUE(read.isNone());
    ASSERT_EQ(writes, reads);
  
    os::close(fd.get());
  }
  
  TEST_F(ProtobufIOTest, RepeatedPtrField)
  {
    const string file = ".protobuf_io_test_repeated_ptr_field";
  
    RepeatedPtrField<FrameworkID> expected;
  
    const size_t size = 10;
    for (size_t 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>> read =
      ::protobuf::read<RepeatedPtrField<FrameworkID>>(file);
    ASSERT_SOME(read);
  
    RepeatedPtrField<FrameworkID> actual = read.get();
  
    ASSERT_EQ(expected.size(), actual.size());
    for (size_t i = 0; i < size; i++) {
      EXPECT_EQ(expected.Get(i), actual.Get(i));
    }
  }
  
  } // namespace tests {
  } // namespace internal {
  } // namespace mesos {
  