ss: Relax but enforce the character limit in HTInterval strings
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core.tests / src / org / eclipse / tracecompass / statesystem / core / tests / backend / historytree / HTIntervalStringReadWriteTest.java
1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9
10 package org.eclipse.tracecompass.statesystem.core.tests.backend.historytree;
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.fail;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.FileOutputStream;
18 import java.io.IOException;
19 import java.nio.ByteBuffer;
20 import java.nio.ByteOrder;
21 import java.nio.channels.FileChannel;
22 import java.nio.charset.Charset;
23 import java.util.List;
24 import java.util.Set;
25 import java.util.stream.Collectors;
26 import java.util.stream.IntStream;
27
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTInterval;
30 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.junit.runners.Parameterized;
34 import org.junit.runners.Parameterized.Parameters;
35
36 import com.google.common.collect.ImmutableList;
37 import com.google.common.collect.ImmutableSet;
38 import com.google.common.collect.Sets;
39
40 /**
41 * Test the reading/writing logic in {@link HTInterval}, particularly regarding
42 * the string length limitations.
43 *
44 * @author Alexandre Montplaisir
45 */
46 @RunWith(Parameterized.class)
47 @NonNullByDefault({})
48 public class HTIntervalStringReadWriteTest {
49
50 private static final Charset CHARSET = Charset.forName("UTF-8");
51
52 private int fNbChars;
53 private int fCharLength;
54 private char fChar;
55
56 /**
57 * Parameter generator.
58 *
59 * Generates a combination of all possible string lenghts and all possible
60 * character lengths.
61 *
62 * @return The test parameters
63 */
64 @Parameters(name = "nb of chars: {0}, char length: {1}")
65 public static Iterable<Object[]> getTestParams() {
66 Set<List<Integer>> set = Sets.cartesianProduct(ImmutableList.of(
67 ImmutableSet.of(
68 0,
69 10,
70 Byte.MAX_VALUE - 1,
71 (int) Byte.MAX_VALUE,
72 Byte.MAX_VALUE + 1,
73
74 Short.MAX_VALUE / 2 - 1,
75 Short.MAX_VALUE / 2,
76 Short.MAX_VALUE / 2 + 1,
77
78 Short.MAX_VALUE / 3 - 1,
79 Short.MAX_VALUE / 3,
80 Short.MAX_VALUE / 3 + 1,
81
82 Short.MAX_VALUE - 1,
83 (int) Short.MAX_VALUE,
84 Short.MAX_VALUE + 1),
85
86 ImmutableSet.of(1, 2, 3)
87 ));
88
89 return set.stream()
90 .map(List::toArray)
91 .collect(Collectors.toList());
92 }
93
94 /**
95 * Test constructor, take the generated parameters as parameters.
96 *
97 * @param nbChars
98 * The number of characters in the test string.
99 * @param charLength
100 * The length (in bytes) of the UTF-8-encoded form of the
101 * character being used.
102 */
103 public HTIntervalStringReadWriteTest(Integer nbChars, Integer charLength) {
104 fNbChars = nbChars.intValue();
105 fCharLength = charLength.intValue();
106 switch (charLength) {
107 case 1:
108 fChar = 'a';
109 break;
110 case 2:
111 fChar = 'é';
112 break;
113 case 3:
114 fChar = '长'; // "chang" means long / length in Chinese!
115 break;
116 default:
117 throw new IllegalArgumentException();
118 }
119 }
120
121 /**
122 * Test method
123 *
124 * @throws IOException
125 * Fails the test
126 */
127 @Test
128 public void testStringWithChars() throws IOException {
129 StringBuilder sb = new StringBuilder();
130 IntStream.range(0, fNbChars).forEach(i -> sb.append(fChar));
131 String str = sb.toString();
132 assertEquals(fNbChars, str.length());
133 assertEquals(fNbChars * fCharLength, str.getBytes(CHARSET).length);
134
135 TmfStateValue value = TmfStateValue.newValueString(str);
136 if (fNbChars * fCharLength > Short.MAX_VALUE) {
137 /* For sizes that are known to be too long, expect an exception */
138 try {
139 new HTInterval(0, 10, 1, value);
140 } catch (IllegalArgumentException e) {
141 return;
142 }
143 fail();
144 }
145 HTInterval interval = new HTInterval(0, 10, 1, value);
146 writeAndReadInterval(interval);
147 }
148
149 private static void writeAndReadInterval(HTInterval interval) throws IOException {
150 int sizeOnDisk = interval.getSizeOnDisk();
151
152 /* Write the interval to a file */
153 File tempFile = File.createTempFile("test-interval", ".interval");
154 try (FileOutputStream fos = new FileOutputStream(tempFile, false);
155 FileChannel fc = fos.getChannel();) {
156
157 ByteBuffer bb = ByteBuffer.allocate(sizeOnDisk);
158 bb.order(ByteOrder.LITTLE_ENDIAN);
159 bb.clear();
160
161 interval.writeInterval(bb);
162 bb.flip();
163 int written = fc.write(bb);
164 assertEquals(sizeOnDisk, written);
165 }
166
167 /* Read the interval from the file */
168 HTInterval readInterval;
169 try (FileInputStream fis = new FileInputStream(tempFile);
170 FileChannel fc = fis.getChannel();) {
171
172 ByteBuffer bb = ByteBuffer.allocate(sizeOnDisk);
173 bb.order(ByteOrder.LITTLE_ENDIAN);
174 bb.clear();
175
176 int read = fc.read(bb);
177 assertEquals(sizeOnDisk, read);
178 bb.flip();
179 readInterval = HTInterval.readFrom(bb);
180 }
181
182 assertEquals(interval, readInterval);
183 }
184 }
This page took 0.034951 seconds and 5 git commands to generate.