|
1 /* |
|
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 import java.io.ByteArrayInputStream; |
|
24 import java.io.ByteArrayOutputStream; |
|
25 import java.io.IOException; |
|
26 import java.io.ObjectInputStream; |
|
27 import java.io.ObjectOutputStream; |
|
28 import java.time.Instant; |
|
29 import java.util.Objects; |
|
30 import java.util.logging.Level; |
|
31 import java.util.logging.LogRecord; |
|
32 import java.util.logging.SimpleFormatter; |
|
33 |
|
34 /** |
|
35 * @test |
|
36 * @bug 8072645 |
|
37 * @summary tests the new methods added to LogRecord. |
|
38 * @run main LogRecordWithNanosAPI |
|
39 * @author danielfuchs |
|
40 */ |
|
41 public class LogRecordWithNanosAPI { |
|
42 |
|
43 static final int MILLIS_IN_SECOND = 1000; |
|
44 static final int NANOS_IN_MILLI = 1000_000; |
|
45 static final int NANOS_IN_SECOND = 1000_000_000; |
|
46 |
|
47 static final boolean verbose = true; |
|
48 |
|
49 static final class TestAssertException extends RuntimeException { |
|
50 TestAssertException(String msg) { super(msg); } |
|
51 } |
|
52 |
|
53 private static void assertEquals(long expected, long received, String msg) { |
|
54 if (expected != received) { |
|
55 throw new TestAssertException("Unexpected result for " + msg |
|
56 + ".\n\texpected: " + expected |
|
57 + "\n\tactual: " + received); |
|
58 } else if (verbose) { |
|
59 System.out.println("Got expected " + msg + ": " + received); |
|
60 } |
|
61 } |
|
62 |
|
63 private static void assertEquals(Object expected, Object received, String msg) { |
|
64 if (!Objects.equals(expected, received)) { |
|
65 throw new TestAssertException("Unexpected result for " + msg |
|
66 + ".\n\texpected: " + expected |
|
67 + "\n\tactual: " + received); |
|
68 } else if (verbose) { |
|
69 System.out.println("Got expected " + msg + ": " + received); |
|
70 } |
|
71 } |
|
72 |
|
73 // The nano second fractional part of a second, contained in a time expressed |
|
74 // as a number of millisecond from the epoch. |
|
75 private static long nanoInSecondFromEpochMilli(long millis) { |
|
76 return (((millis%MILLIS_IN_SECOND) + MILLIS_IN_SECOND)%MILLIS_IN_SECOND)*NANOS_IN_MILLI; |
|
77 } |
|
78 |
|
79 /** |
|
80 * Serializes a log record, then deserializes it and check that both |
|
81 * records match. |
|
82 * @param record the log record to serialize & deserialize. |
|
83 * @param hasExceedingNanos whether the record has a nano adjustment whose |
|
84 * value exceeds 1ms. |
|
85 * @throws IOException Unexpected. |
|
86 * @throws ClassNotFoundException Unexpected. |
|
87 */ |
|
88 public static void test(LogRecord record, boolean hasExceedingNanos) |
|
89 throws IOException, ClassNotFoundException { |
|
90 |
|
91 // Format the given logRecord using the SimpleFormatter |
|
92 SimpleFormatter formatter = new SimpleFormatter(); |
|
93 String str = formatter.format(record); |
|
94 |
|
95 // Serialize the given LogRecord |
|
96 final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
|
97 final ObjectOutputStream oos = new ObjectOutputStream(baos); |
|
98 oos.writeObject(record); |
|
99 oos.flush(); |
|
100 oos.close(); |
|
101 |
|
102 // First checks that the log record can be deserialized |
|
103 final ByteArrayInputStream bais = |
|
104 new ByteArrayInputStream(baos.toByteArray()); |
|
105 final ObjectInputStream ois = new ObjectInputStream(bais); |
|
106 final LogRecord record2 = (LogRecord)ois.readObject(); |
|
107 |
|
108 assertEquals(record.getMillis(), record2.getMillis(), "getMillis()"); |
|
109 assertEquals(record.getInstant().getEpochSecond(), |
|
110 record2.getInstant().getEpochSecond(), |
|
111 "getInstant().getEpochSecond()"); |
|
112 assertEquals(record.getInstant().getNano(), |
|
113 record2.getInstant().getNano(), |
|
114 "getInstant().getNano()"); |
|
115 assertEquals(record.getInstant().toEpochMilli(), |
|
116 record2.getInstant().toEpochMilli(), |
|
117 "getInstant().toEpochMilli()"); |
|
118 long millis = record.getMillis(); |
|
119 millis = hasExceedingNanos |
|
120 ? Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
121 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI |
|
122 + record.getInstant().getNano() % NANOS_IN_MILLI).toEpochMilli() |
|
123 : millis; |
|
124 assertEquals(millis, record.getInstant().toEpochMilli(), |
|
125 "getMillis()/getInstant().toEpochMilli()"); |
|
126 millis = record2.getMillis(); |
|
127 millis = hasExceedingNanos |
|
128 ? Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
129 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI |
|
130 + record2.getInstant().getNano() % NANOS_IN_MILLI).toEpochMilli() |
|
131 : millis; |
|
132 assertEquals(millis, record2.getInstant().toEpochMilli(), |
|
133 "getMillis()/getInstant().toEpochMilli()"); |
|
134 long nanos = nanoInSecondFromEpochMilli(record.getMillis()) |
|
135 + record.getInstant().getNano() % NANOS_IN_MILLI; |
|
136 assertEquals(nanos, record.getInstant().getNano(), |
|
137 "nanoInSecondFromEpochMilli(record.getMillis())" |
|
138 + " + record.getInstant().getNano() % NANOS_IN_MILLI /getInstant().getNano()"); |
|
139 nanos = nanoInSecondFromEpochMilli(record2.getMillis()) |
|
140 + record2.getInstant().getNano() % NANOS_IN_MILLI; |
|
141 assertEquals(nanos, record2.getInstant().getNano(), |
|
142 "nanoInSecondFromEpochMilli(record2.getMillis())" |
|
143 + " + record2.getInstant().getNano() % NANOS_IN_MILLI /getInstant().getNano()"); |
|
144 |
|
145 // Format the deserialized LogRecord using the SimpleFormatter, and |
|
146 // check that the string representation obtained matches the string |
|
147 // representation of the original LogRecord |
|
148 String str2 = formatter.format(record2); |
|
149 if (!str.equals(str2)) |
|
150 throw new RuntimeException("Unexpected values in deserialized object:" |
|
151 + "\n\tExpected: " + str |
|
152 + "\n\tRetrieved: "+str); |
|
153 |
|
154 } |
|
155 |
|
156 |
|
157 public static void main(String[] args) throws Exception { |
|
158 int count=0; |
|
159 LogRecord record = new LogRecord(Level.INFO, "Java Version: {0}"); |
|
160 record.setLoggerName("test"); |
|
161 record.setParameters(new Object[] {System.getProperty("java.version")}); |
|
162 final int nanos = record.getInstant().getNano() % NANOS_IN_MILLI; |
|
163 final long millis = record.getMillis(); |
|
164 final Instant instant = record.getInstant(); |
|
165 if (millis != instant.toEpochMilli()) { |
|
166 throw new RuntimeException("Unexpected millis: " |
|
167 + record.getMillis()); |
|
168 } |
|
169 test(record, false); |
|
170 |
|
171 // nano adjustment < 1ms (canonical case) |
|
172 int newNanos = (nanos + 111111) % NANOS_IN_MILLI; |
|
173 record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
174 (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newNanos)); |
|
175 assertEquals(newNanos, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
176 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
177 assertEquals(millis, record.getMillis(), "record.getMillis()"); |
|
178 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
179 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newNanos), |
|
180 record.getInstant(), "record.getInstant()"); |
|
181 test(record, false); |
|
182 assertEquals(newNanos, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
183 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
184 assertEquals(millis, record.getMillis(), "record.getMillis()"); |
|
185 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
186 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newNanos), |
|
187 record.getInstant(), "record.getInstant()"); |
|
188 |
|
189 // nano adjustment > 1ms - non canonical - should still work |
|
190 int newExceedingNanos = 2111_111; |
|
191 record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
192 (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); |
|
193 assertEquals(newExceedingNanos % NANOS_IN_MILLI, |
|
194 record.getInstant().getNano() % NANOS_IN_MILLI, |
|
195 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
196 assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, |
|
197 record.getMillis(), "record.getMillis()"); |
|
198 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
199 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), |
|
200 record.getInstant(), "record.getInstant()"); |
|
201 test(record, true); |
|
202 assertEquals(newExceedingNanos % NANOS_IN_MILLI, |
|
203 record.getInstant().getNano() % NANOS_IN_MILLI, |
|
204 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
205 assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, |
|
206 record.getMillis(), "record.getMillis()"); |
|
207 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
208 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), |
|
209 record.getInstant(), "record.getInstant()"); |
|
210 |
|
211 // nano adjustement > 1s - non canonical - should still work |
|
212 newExceedingNanos = 1111_111_111; |
|
213 record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
214 (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); |
|
215 assertEquals(newExceedingNanos % NANOS_IN_MILLI, |
|
216 record.getInstant().getNano() % NANOS_IN_MILLI, |
|
217 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
218 assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, |
|
219 record.getMillis(), "record.getMillis()"); |
|
220 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
221 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), |
|
222 record.getInstant(), "record.getInstant()"); |
|
223 test(record, true); |
|
224 assertEquals(newExceedingNanos % NANOS_IN_MILLI, |
|
225 record.getInstant().getNano() % NANOS_IN_MILLI, |
|
226 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
227 assertEquals(millis + newExceedingNanos / NANOS_IN_MILLI, |
|
228 record.getMillis(), "record.getMillis()"); |
|
229 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
230 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), |
|
231 record.getInstant(), "record.getInstant()"); |
|
232 |
|
233 // nano adjustement < 0 - non canonical - should still work |
|
234 newExceedingNanos = -1; |
|
235 record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
236 (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); |
|
237 assertEquals(newExceedingNanos + NANOS_IN_MILLI, |
|
238 record.getInstant().getNano() % NANOS_IN_MILLI, |
|
239 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
240 assertEquals(millis -1, record.getMillis(), "record.getMillis()"); |
|
241 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
242 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), |
|
243 record.getInstant(), "record.getInstant()"); |
|
244 test(record, true); |
|
245 record.setInstant(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
246 (millis % MILLIS_IN_SECOND) * NANOS_IN_MILLI + newExceedingNanos)); |
|
247 assertEquals(millis -1, record.getMillis(), "record.getMillis()"); |
|
248 assertEquals(Instant.ofEpochSecond(millis/MILLIS_IN_SECOND, |
|
249 (millis%MILLIS_IN_SECOND)*NANOS_IN_MILLI + newExceedingNanos), |
|
250 record.getInstant(), "record.getInstant()"); |
|
251 |
|
252 // setMillis |
|
253 record.setMillis(millis-1); |
|
254 assertEquals(millis-1, record.getInstant().toEpochMilli(), |
|
255 "record.getInstant().toEpochMilli()"); |
|
256 assertEquals(millis-1, record.getMillis(), |
|
257 "record.getMillis()"); |
|
258 assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
259 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
260 test(record, false); |
|
261 assertEquals(millis-1, record.getInstant().toEpochMilli(), |
|
262 "record.getInstant().toEpochMilli()"); |
|
263 assertEquals(millis-1, record.getMillis(), |
|
264 "record.getMillis()"); |
|
265 assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
266 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
267 |
|
268 // setMillis to 0 |
|
269 record.setMillis(0); |
|
270 assertEquals(0, record.getInstant().toEpochMilli(), |
|
271 "record.getInstant().toEpochMilli()"); |
|
272 assertEquals(0, record.getMillis(), |
|
273 "record.getMillis()"); |
|
274 assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
275 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
276 test(record, false); |
|
277 assertEquals(0, record.getInstant().toEpochMilli(), |
|
278 "record.getInstant().toEpochMilli()"); |
|
279 assertEquals(0, record.getMillis(), |
|
280 "record.getMillis()"); |
|
281 assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
282 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
283 |
|
284 // setMillis to -1 |
|
285 record.setMillis(-1); |
|
286 assertEquals(-1, record.getInstant().toEpochMilli(), |
|
287 "record.getInstant().toEpochMilli()"); |
|
288 assertEquals(-1, record.getMillis(), |
|
289 "record.getMillis()"); |
|
290 assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
291 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
292 test(record, false); |
|
293 assertEquals(-1, record.getInstant().toEpochMilli(), |
|
294 "record.getInstant().toEpochMilli()"); |
|
295 assertEquals(-1, record.getMillis(), |
|
296 "record.getMillis()"); |
|
297 assertEquals(0, record.getInstant().getNano() % NANOS_IN_MILLI, |
|
298 "record.getInstant().getNano() % NANOS_IN_MILLI"); |
|
299 |
|
300 try { |
|
301 record.setInstant(null); |
|
302 } catch (NullPointerException x) { |
|
303 System.out.println("Got expected NPE when trying to call record.setInstant(null): " + x); |
|
304 } |
|
305 |
|
306 } |
|
307 |
|
308 } |