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