Package com.netflix.suro.sink.localfile

Source Code of com.netflix.suro.sink.localfile.TestLocalFileSink

/*
* Copyright 2013 Netflix, Inc.
*
*    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 com.netflix.suro.sink.localfile;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.netflix.suro.connection.TestConnectionPool;
import com.netflix.suro.jackson.DefaultObjectMapper;
import com.netflix.suro.message.Message;
import com.netflix.suro.message.MessageSetReader;
import com.netflix.suro.message.StringMessage;
import com.netflix.suro.sink.Sink;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.*;
import java.util.HashSet;
import java.util.Set;

import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class TestLocalFileSink {
    @Rule
    public TemporaryFolder tempDir = new TemporaryFolder();

    private static Injector injector = Guice.createInjector(
        new SuroSinkPlugin(),
        new AbstractModule() {
            @Override
            protected void configure() {
                bind(ObjectMapper.class).to(DefaultObjectMapper.class);
            }
            }
    );

    @Test
    public void testDefaultParameters() throws IOException {
        String testdir = tempDir.newFolder().getAbsolutePath();

        final String localFileSinkSpec = "{\n" +
                "    \"type\": \"" + LocalFileSink.TYPE + "\",\n" +
                "    \"outputDir\": \"" + testdir + "\"\n" +
                "    }\n" +
                "}";

        ObjectMapper mapper = injector.getInstance(ObjectMapper.class);
        Sink sink = mapper.readValue(localFileSinkSpec, new TypeReference<Sink>(){});
        sink.open();

        assertNull(sink.recvNotice());

        for (Message m : new MessageSetReader(TestConnectionPool.createMessageSet(10000))) {
            sink.writeTo(new StringMessage(m));
        }

        sink.close();

        System.out.println(sink.getStat());

        int count = 0;
        File dir = new File(testdir);
        File[] files = dir.listFiles();
        for (File file : files) {
            assertTrue(file.getName().contains(".done"));
            if (!file.getName().contains("crc")) {
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line = br.readLine()) != null) {
                    assertTrue(line.contains("testMessage"));
                    ++count;
                }
                br.close();
            }
        }
        assertEquals(count, 10000);
    }

    @Test
    public void testWithPeriodRotation() throws IOException, InterruptedException {
        String testdir = tempDir.newFolder().getAbsolutePath();

        final String localFileSinkSpec = "{\n" +
                "    \"type\": \"" + LocalFileSink.TYPE + "\",\n" +
                "    \"outputDir\": \"" + testdir + "\",\n" +
                "    \"writer\": {\n" +
                "        \"type\": \"text\"\n" +
                "    },\n" +
                "    \"maxFileSize\": 100000000,\n" +
                "    \"minPercentFreeDisk\": 50,\n" +
                "    \"rotationPeriod\": \"PT5s\",\n" +
                "    \"notice\": {\n" +
                "        \"type\": \"queue\"\n" +
                "    }\n" +
                "}";

        ObjectMapper mapper = injector.getInstance(ObjectMapper.class);
        Sink sink = mapper.readValue(localFileSinkSpec, new TypeReference<Sink>(){});
        sink.open();
        assertNull(sink.recvNotice());

        for (Message m : new MessageSetReader(TestConnectionPool.createMessageSet(100))) {
            sink.writeTo(new StringMessage(m));
            Thread.sleep(100);
        }

        sink.close();

        int count = 0;
        int fileCount = 0;
        File dir = new File(testdir);
        File[] files = dir.listFiles();
        for (File file : files) {
            assertTrue(file.getName().contains(".done"));
            if (!file.getName().contains("crc")) {
                ++fileCount;
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line = br.readLine()) != null) {
                    assertTrue(line.contains("testMessage"));
                    ++count;
                }
                br.close();
            }
        }
        assertEquals(count, 100);
        assertTrue(fileCount > 1);
    }

    @Test
    public void testSpaceChecker() throws Exception {
        String testdir = tempDir.newFolder().getAbsolutePath();

        final String localFileSinkSpec = "{\n" +
                "    \"type\": \"" + LocalFileSink.TYPE + "\",\n" +
                "    \"outputDir\": \"" + testdir + "\",\n" +
                "    \"writer\": {\n" +
                "        \"type\": \"text\"\n" +
                "    },\n" +
                "    \"maxFileSize\": 10240,\n" +
                "    \"minPercentFreeDisk\": 50,\n" +
                "    \"rotationPeriod\": \"PT1m\",\n" +
                "    \"notice\": {\n" +
                "        \"type\": \"queue\"\n" +
                "    }\n" +
                "}";

        ObjectMapper mapper = injector.getInstance(ObjectMapper.class);

        final LocalFileSink.SpaceChecker spaceChecker = mock(LocalFileSink.SpaceChecker.class);
        when(spaceChecker.hasEnoughSpace()).thenReturn(false);

        Sink sink = mapper.readValue(localFileSinkSpec, new TypeReference<Sink>(){});
        sink.open();

        Thread.sleep(1000); // wait until thread starts

        assertNull(sink.recvNotice());

        when(spaceChecker.hasEnoughSpace()).thenReturn(true);

        for (Message m : new MessageSetReader(TestConnectionPool.createMessageSet(10000))) {
            sink.writeTo(new StringMessage(m));
        }

        sink.close();

        int count = 0;
        File dir = new File(testdir);
        File[] files = dir.listFiles();
        for (File file : files) {
            assertTrue(file.getName().contains(".done"));
            if (!file.getName().contains("crc")) {
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line = br.readLine()) != null) {
                    assertTrue(line.contains("testMessage"));
                    ++count;
                }
                br.close();
            }
        }
        assertEquals(count, 10000);
    }

    @Test
    public void testWithSizeRotation() throws IOException {
        String testdir = tempDir.newFolder().getAbsolutePath();

        final String localFileSinkSpec = "{\n" +
                "    \"type\": \"" + LocalFileSink.TYPE + "\",\n" +
                "    \"outputDir\": \"" + testdir + "\",\n" +
                "    \"writer\": {\n" +
                "        \"type\": \"text\"\n" +
                "    },\n" +
                "    \"maxFileSize\": 10240,\n" +
                "    \"minPercentFreeDisk\": 50,\n" +
                "    \"rotationPeriod\": \"PT10m\",\n" +
                "    \"batchSize\": 1,\n" +
                "    \"notice\": {\n" +
                "        \"type\": \"queue\"\n" +
                "    }\n" +
                "}";

        ObjectMapper mapper = injector.getInstance(ObjectMapper.class);
        Sink sink = mapper.readValue(localFileSinkSpec, new TypeReference<Sink>(){});
        sink.open();
        assertNull(sink.recvNotice());

        for (Message m : new MessageSetReader(TestConnectionPool.createMessageSet(10000))) {
            sink.writeTo(new StringMessage(m));
        }

        sink.close();

        int count = 0;
        int errorCount = 0;
        File dir = new File(testdir);
        File[] files = dir.listFiles();
        for (File file : files) {
            System.out.println(file.getName());
            assertTrue(file.getName().contains(".done"));
            if (!file.getName().contains("crc")) {
                if (file.length() > 12000) {
                    ++errorCount;
                    // last file can be bigger due to flushing
                }
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line = br.readLine()) != null) {
                    assertTrue(line.contains("testMessage"));
                    ++count;
                }
                br.close();
            }
        }
        assertEquals(count, 10000);
        assertTrue(errorCount <= 1);
    }

    @Test
    public void rotateEmptyFile() throws IOException, InterruptedException {
        String testdir = tempDir.newFolder().getAbsolutePath();

        final String localFileSinkSpec = "{\n" +
                "    \"type\": \"" + LocalFileSink.TYPE + "\",\n" +
                "    \"outputDir\": \"" + testdir + "\",\n" +
                "    \"writer\": {\n" +
                "        \"type\": \"text\"\n" +
                "    },\n" +
                "    \"maxFileSize\": 100000000,\n" +
                "    \"minPercentFreeDisk\": 50,\n" +
                "    \"rotationPeriod\": \"PT2s\",\n" +
                "    \"notice\": {\n" +
                "        \"type\": \"queue\"\n" +
                "    }\n" +
                "}";

        ObjectMapper mapper = injector.getInstance(ObjectMapper.class);
        Sink sink = mapper.readValue(localFileSinkSpec, new TypeReference<Sink>(){});
        sink.open();
        assertNull(sink.recvNotice());

        for (Message m : new MessageSetReader(TestConnectionPool.createMessageSet(100))) {
            sink.writeTo(new StringMessage(m));
            Thread.sleep(100);
        }

        Thread.sleep(3000);

        sink.close();

        int count = 0;
        int fileCount = 0;
        File dir = new File(testdir);
        File[] files = dir.listFiles();
        for (File file : files) {
            assertTrue(file.getName().contains(".done"));
            if (!file.getName().contains("crc")) {
                ++fileCount;
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                while ((line = br.readLine()) != null) {
                    assertTrue(line.contains("testMessage"));
                    ++count;
                }
                br.close();
                assertTrue(count > 0); // should not empty
            }
        }
        assertEquals(count, 100);
        assertTrue(fileCount > 1);
    }

    @Test
    public void testCleanUp() throws IOException, InterruptedException {
        String testdir = tempDir.newFolder().getAbsolutePath();

        // create files
        final int numFiles = 5;
        Set<String> filePathSet = new HashSet<String>();
        for (int i = 0; i < numFiles; ++i) {
            String fileName = "testFile" + i + (i == numFiles - 1 ? LocalFileSink.suffix : LocalFileSink.done);
            File f = new File(testdir, fileName);
            f.createNewFile();
            FileOutputStream o = new FileOutputStream(f);
            o.write(100 /*any data*/);
            o.close();
            if (i != numFiles - 1) {
                filePathSet.add(f.getAbsolutePath());
            }
        }

        final String localFileSinkSpec = "{\n" +
                "    \"type\": \"" + LocalFileSink.TYPE + "\",\n" +
                "    \"rotationPeriod\": \"PT1m\",\n" +
                "    \"outputDir\": \"" + testdir + "\"\n" +
                "    }\n" +
                "}";

        Thread.sleep(3000); // wait until .suro file is expired
        ObjectMapper mapper = injector.getInstance(ObjectMapper.class);
        LocalFileSink sink = (LocalFileSink)mapper.readValue(
                localFileSinkSpec,
                new TypeReference<Sink>(){});
        assertEquals(sink.cleanUp(testdir, false), numFiles -1); // due to empty file wouldn't be clean up

        Set<String> filePathSetResult = new HashSet<String>();
        for (int i = 0; i < numFiles - 1; ++i) {
            filePathSetResult.add(sink.recvNotice());
        }
        assertEquals(filePathSet, filePathSetResult);

        assertEquals(sink.cleanUp(testdir, true), numFiles);
    }

    @Test
    public void testGetFileExt() {
        assertEquals(LocalFileSink.getFileExt("abc.done"), ".done");
        assertNull(LocalFileSink.getFileExt("abcdone"));
        assertNull(LocalFileSink.getFileExt("abcdone."));
    }
}
TOP

Related Classes of com.netflix.suro.sink.localfile.TestLocalFileSink

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.