Improve segmented journal actor metrics
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / test / java / org / opendaylight / controller / cluster / io / FileBackedOutputStreamTest.java
1 /*
2  * Copyright (c) 2017 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.io;
9
10 import static org.junit.Assert.assertArrayEquals;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
16
17 import com.google.common.base.Stopwatch;
18 import com.google.common.util.concurrent.Uninterruptibles;
19 import java.io.File;
20 import java.io.IOException;
21 import java.util.Arrays;
22 import java.util.concurrent.TimeUnit;
23 import org.junit.After;
24 import org.junit.AfterClass;
25 import org.junit.Before;
26 import org.junit.BeforeClass;
27 import org.junit.Test;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Unit tests for FileBackedOutputStream.
33  *
34  * @author Thomas Pantelis
35  */
36 public class FileBackedOutputStreamTest {
37     private static final Logger LOG = LoggerFactory.getLogger(FileBackedOutputStreamTest.class);
38     private static final String TEMP_DIR = "target/FileBackedOutputStreamTest";
39
40     @BeforeClass
41     public static void staticSetup() {
42         createDir(TEMP_DIR);
43     }
44
45     @AfterClass
46     public static void staticCleanup() {
47         deleteTempFiles(TEMP_DIR);
48         deleteFile(TEMP_DIR);
49     }
50
51     @Before
52     public void setup() {
53         deleteTempFiles(TEMP_DIR);
54     }
55
56     @After
57     public void cleanup() {
58         deleteTempFiles(TEMP_DIR);
59     }
60
61     @Test
62     public void testFileThresholdNotReached() throws IOException {
63         LOG.info("testFileThresholdNotReached starting");
64         try (FileBackedOutputStream fbos = new FileBackedOutputStream(10, TEMP_DIR)) {
65             byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
66             fbos.write(bytes[0]);
67             fbos.write(bytes, 1, bytes.length - 1);
68
69             assertEquals("getCount", bytes.length, fbos.getCount());
70             assertNull("Found unexpected temp file", findTempFileName(TEMP_DIR));
71             assertEquals("Size", bytes.length, fbos.asByteSource().size());
72
73             // Read bytes twice.
74             assertArrayEquals("Read bytes", bytes, fbos.asByteSource().read());
75             assertArrayEquals("Read bytes", bytes, fbos.asByteSource().read());
76
77             fbos.cleanup();
78         }
79
80         LOG.info("testFileThresholdNotReached ending");
81     }
82
83     @Test
84     public void testFileThresholdReachedWithWriteBytes() throws IOException {
85         LOG.info("testFileThresholdReachedWithWriteBytes starting");
86         try (FileBackedOutputStream fbos = new FileBackedOutputStream(10, TEMP_DIR)) {
87             byte[] bytes = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
88             fbos.write(bytes[0]);
89             fbos.write(bytes, 1, 11);
90
91             String tempFileName = findTempFileName(TEMP_DIR);
92             assertNotNull("Expected temp file created", tempFileName);
93
94             fbos.write(bytes[12]);
95             fbos.write(bytes, 13, bytes.length - 13);
96
97             assertEquals("Temp file", tempFileName, findTempFileName(TEMP_DIR));
98             assertEquals("Size", bytes.length, fbos.asByteSource().size());
99
100             try (var inputStream = fbos.asByteSource().openStream()) {
101                 assertArrayEquals("Read bytes", bytes, fbos.asByteSource().read());
102
103                 byte[] inBytes = new byte[bytes.length];
104                 assertEquals("# bytes read", bytes.length, inputStream.read(inBytes));
105                 assertArrayEquals("Read InputStream", bytes, inBytes);
106                 assertEquals("End of stream", -1, inputStream.read());
107             }
108
109             fbos.cleanup();
110
111             assertNull("Found unexpected temp file", findTempFileName(TEMP_DIR));
112         }
113
114         LOG.info("testFileThresholdReachedWithWriteBytes ending");
115     }
116
117     @Test
118     public void testFileThresholdReachedWithWriteByte() throws IOException {
119         LOG.info("testFileThresholdReachedWithWriteByte starting");
120         try (FileBackedOutputStream fbos = new FileBackedOutputStream(2, TEMP_DIR)) {
121             byte[] bytes = new byte[]{0, 1, 2};
122             fbos.write(bytes[0]);
123             fbos.write(bytes[1]);
124
125             assertNull("Found unexpected temp file", findTempFileName(TEMP_DIR));
126
127             fbos.write(bytes[2]);
128             fbos.flush();
129
130             assertNotNull("Expected temp file created", findTempFileName(TEMP_DIR));
131
132             assertEquals("Size", bytes.length, fbos.asByteSource().size());
133             assertArrayEquals("Read bytes", bytes, fbos.asByteSource().read());
134         }
135
136         LOG.info("testFileThresholdReachedWithWriteByte ending");
137     }
138
139     @Test(expected = IOException.class)
140     public void testWriteAfterAsByteSource() throws IOException {
141         LOG.info("testWriteAfterAsByteSource starting");
142         try (FileBackedOutputStream fbos = new FileBackedOutputStream(3, TEMP_DIR)) {
143             byte[] bytes = new byte[]{0, 1, 2};
144             fbos.write(bytes);
145
146             assertNull("Found unexpected temp file", findTempFileName(TEMP_DIR));
147             assertEquals("Size", bytes.length, fbos.asByteSource().size());
148
149             // Should throw IOException after call to asByteSource.
150             fbos.write(1);
151         }
152     }
153
154     @Test
155     public void testTempFileDeletedOnGC() throws IOException {
156         LOG.info("testTempFileDeletedOnGC starting");
157
158         FileBackedOutputStream fbos = null;
159         try {
160             fbos = new FileBackedOutputStream(1, TEMP_DIR);
161             fbos.write(new byte[] {0, 1});
162             assertNotNull("Expected temp file created", findTempFileName(TEMP_DIR));
163         } finally {
164             if (fbos != null) {
165                 fbos.close();
166             }
167             fbos = null;
168         }
169
170         Stopwatch sw = Stopwatch.createStarted();
171         while (sw.elapsed(TimeUnit.SECONDS) <= 20) {
172             System.gc();
173             if (findTempFileName(TEMP_DIR) == null) {
174                 return;
175             }
176             Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
177         }
178
179         fail("Temp file was not deleted");
180     }
181
182     static String findTempFileName(final String dirPath) {
183         String[] files = new File(dirPath).list();
184         assertNotNull(files);
185         assertTrue("Found more than one temp file: " + Arrays.toString(files), files.length < 2);
186         return files.length == 1 ? files[0] : null;
187     }
188
189     static boolean deleteFile(final String file) {
190         return new File(file).delete();
191     }
192
193     static void deleteTempFiles(final String path) {
194         String[] files = new File(path).list();
195         if (files != null) {
196             for (String file : files) {
197                 deleteFile(path + File.separator + file);
198             }
199         }
200     }
201
202     static void createDir(final String path) {
203         File dir = new File(path);
204         if (!dir.exists() && !dir.mkdirs()) {
205             throw new RuntimeException("Failed to create temp dir " + path);
206         }
207     }
208 }