// Path: fluency-fluentd/src/main/java/org/komamitsu/fluency/fluentd/ingester/sender/FluentdSender.java
// public abstract class FluentdSender
//         implements Closeable, Sender
// {
//     private static final Logger LOG = LoggerFactory.getLogger(FluentdSender.class);
//     private final Config config;
// 
//     protected FluentdSender(Config config)
//     {
//         this.config = config;
//     }
// 
//     protected FluentdSender()
//     {
//         this(new FluentdSender.Config());
//     }
// 
//     public synchronized void send(ByteBuffer buffer)
//             throws IOException
//     {
//         sendInternalWithRestoreBufferPositions(Arrays.asList(buffer), null);
//     }
// 
//     public synchronized void send(List<ByteBuffer> buffers)
//             throws IOException
//     {
//         sendInternalWithRestoreBufferPositions(buffers, null);
//     }
// 
//     public void sendWithAck(List<ByteBuffer> buffers, String ackToken)
//             throws IOException
//     {
//         sendInternalWithRestoreBufferPositions(buffers, ackToken);
//     }
// 
//     private void sendInternalWithRestoreBufferPositions(List<ByteBuffer> buffers, String ackToken)
//             throws IOException
//     {
//         List<Integer> positions = new ArrayList<>(buffers.size());
//         for (ByteBuffer data : buffers) {
//             positions.add(data.position());
//         }
// 
//         try {
//             sendInternal(buffers, ackToken);
//         }
//         catch (Exception e) {
//             for (int i = 0; i < buffers.size(); i++) {
//                 buffers.get(i).position(positions.get(i));
//             }
// 
//             ErrorHandler errorHandler = config.getErrorHandler();
//             if (errorHandler != null) {
//                 try {
//                     errorHandler.handle(e);
//                 }
//                 catch (Exception ex) {
//                     LOG.warn("Failed to handle an error in the error handler {}", errorHandler, ex);
//                 }
//             }
// 
//             if (e instanceof IOException) {
//                 throw (IOException) e;
//             }
//             else {
//                 throw new IOException(e);
//             }
//         }
//     }
// 
//     public abstract boolean isAvailable();
// 
//     abstract protected void sendInternal(List<ByteBuffer> buffers, String ackToken)
//             throws IOException;
// 
//     public static class Config
//             extends Sender.Config
//     {
//     }
// }
// 
// Path: fluency-core/src/main/java/org/komamitsu/fluency/ingester/Ingester.java
// public interface Ingester
//         extends Closeable
// {
//     void ingest(String tag, ByteBuffer dataBuffer)
//             throws IOException;
// 
//     Sender getSender();
// }


import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.komamitsu.fluency.fluentd.ingester.sender.FluentdSender;
import org.komamitsu.fluency.ingester.Ingester;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import org.msgpack.core.MessagePack;
import org.msgpack.core.MessageUnpacker;
import org.msgpack.value.ImmutableArrayValue;
import org.msgpack.value.Value;
import org.msgpack.value.ValueFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/*
 * Copyright 2019 Mitsunori Komatsu (komamitsu)
 *
 * Licensed 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.
 */

package org.komamitsu.fluency.fluentd.ingester;




class FluentdIngesterTest
{
    private static final String TAG = "foo.bar";
    private static final byte[] DATA = "hello, world".getBytes(StandardCharsets.UTF_8);
    @Captor
    public ArgumentCaptor<List<ByteBuffer>> byteBuffersArgumentCaptor;
    private FluentdSender fluentdSender;

    @BeforeEach
    void setUp()
            throws Exception
    {
        MockitoAnnotations.initMocks(this);
        fluentdSender = mock(FluentdSender.class);
    }

    private byte[] getIngestedData(List<ByteBuffer> byteBuffers)
            throws IOException
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        for (ByteBuffer byteBuffer : byteBuffers) {
            outputStream.write(byteBuffer.array());
        }
        return outputStream.toByteArray();
    }

    @Test
    void ingestWithoutAck()
            throws IOException
    {
// Path: fluency-fluentd/src/main/java/org/komamitsu/fluency/fluentd/ingester/sender/FluentdSender.java
// public abstract class FluentdSender
//         implements Closeable, Sender
// {
//     private static final Logger LOG = LoggerFactory.getLogger(FluentdSender.class);
//     private final Config config;
// 
//     protected FluentdSender(Config config)
//     {
//         this.config = config;
//     }
// 
//     protected FluentdSender()
//     {
//         this(new FluentdSender.Config());
//     }
// 
//     public synchronized void send(ByteBuffer buffer)
//             throws IOException
//     {
//         sendInternalWithRestoreBufferPositions(Arrays.asList(buffer), null);
//     }
// 
//     public synchronized void send(List<ByteBuffer> buffers)
//             throws IOException
//     {
//         sendInternalWithRestoreBufferPositions(buffers, null);
//     }
// 
//     public void sendWithAck(List<ByteBuffer> buffers, String ackToken)
//             throws IOException
//     {
//         sendInternalWithRestoreBufferPositions(buffers, ackToken);
//     }
// 
//     private void sendInternalWithRestoreBufferPositions(List<ByteBuffer> buffers, String ackToken)
//             throws IOException
//     {
//         List<Integer> positions = new ArrayList<>(buffers.size());
//         for (ByteBuffer data : buffers) {
//             positions.add(data.position());
//         }
// 
//         try {
//             sendInternal(buffers, ackToken);
//         }
//         catch (Exception e) {
//             for (int i = 0; i < buffers.size(); i++) {
//                 buffers.get(i).position(positions.get(i));
//             }
// 
//             ErrorHandler errorHandler = config.getErrorHandler();
//             if (errorHandler != null) {
//                 try {
//                     errorHandler.handle(e);
//                 }
//                 catch (Exception ex) {
//                     LOG.warn("Failed to handle an error in the error handler {}", errorHandler, ex);
//                 }
//             }
// 
//             if (e instanceof IOException) {
//                 throw (IOException) e;
//             }
//             else {
//                 throw new IOException(e);
//             }
//         }
//     }
// 
//     public abstract boolean isAvailable();
// 
//     abstract protected void sendInternal(List<ByteBuffer> buffers, String ackToken)
//             throws IOException;
// 
//     public static class Config
//             extends Sender.Config
//     {
//     }
// }
// 
// Path: fluency-core/src/main/java/org/komamitsu/fluency/ingester/Ingester.java
// public interface Ingester
//         extends Closeable
// {
//     void ingest(String tag, ByteBuffer dataBuffer)
//             throws IOException;
// 
//     Sender getSender();
// }


// Path: fluency-fluentd/src/test/java/org/komamitsu/fluency/fluentd/ingester/FluentdIngesterTest.java
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.komamitsu.fluency.fluentd.ingester.sender.FluentdSender;
import org.komamitsu.fluency.ingester.Ingester;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import org.msgpack.core.MessagePack;
import org.msgpack.core.MessageUnpacker;
import org.msgpack.value.ImmutableArrayValue;
import org.msgpack.value.Value;
import org.msgpack.value.ValueFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

/*
 * Copyright 2019 Mitsunori Komatsu (komamitsu)
 *
 * Licensed 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.
 */

package org.komamitsu.fluency.fluentd.ingester;




class FluentdIngesterTest
{
    private static final String TAG = "foo.bar";
    private static final byte[] DATA = "hello, world".getBytes(StandardCharsets.UTF_8);
    @Captor
    public ArgumentCaptor<List<ByteBuffer>> byteBuffersArgumentCaptor;
    private FluentdSender fluentdSender;

    @BeforeEach
    void setUp()
            throws Exception
    {
        MockitoAnnotations.initMocks(this);
        fluentdSender = mock(FluentdSender.class);
    }

    private byte[] getIngestedData(List<ByteBuffer> byteBuffers)
            throws IOException
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        for (ByteBuffer byteBuffer : byteBuffers) {
            outputStream.write(byteBuffer.array());
        }
        return outputStream.toByteArray();
    }

    @Test
    void ingestWithoutAck()
            throws IOException
    {
        Ingester ingester = new FluentdIngester(new FluentdIngester.Config(), fluentdSender);