/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.activemq.artemis.tests.util;
import java.util.concurrent.CountDownLatch;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.utils.DataConstants;
import org.apache.activemq.artemis.utils.RandomUtil;
import org.junit.Assert;
import org.junit.Test;
public class SimpleStringTest extends Assert {
/**
* Converting back and forth between char and byte requires care as char is unsigned.
*
* @see SimpleString#getChars(int, int, char[], int)
* @see SimpleString#charAt(int)
* @see SimpleString#split(char)
* @see SimpleString#concat(char)
*/
@Test
public void testGetChar() {
SimpleString p1 = new SimpleString("foo");
SimpleString p2 = new SimpleString("bar");
for (int i = 0; i < 1 << 16; i++) {
String msg = "expecting " + i;
char c = (char) i;
SimpleString s = new SimpleString(String.valueOf(c));
// test getChars(...)
char[] c1 = new char[1];
s.getChars(0, 1, c1, 0);
assertEquals(msg, c, c1[0]);
// test charAt(int)
assertEquals(msg, c, s.charAt(0));
// test concat(char)
SimpleString s2 = s.concat(c);
assertEquals(msg, c, s2.charAt(1));
// test splitting with chars
SimpleString sSplit = new SimpleString("foo" + String.valueOf(c) + "bar");
SimpleString[] chunks = sSplit.split(c);
SimpleString[] split1 = p1.split(c);
SimpleString[] split2 = p2.split(c);
assertEquals(split1.length + split2.length, chunks.length);
int j = 0;
for (SimpleString iS : split1) {
assertEquals(iS.toString(), iS, chunks[j++]);
}
for (SimpleString iS : split2) {
assertEquals(iS.toString(), iS, chunks[j++]);
}
}
}
@Test
public void testString() throws Exception {
final String str = "hello123ABC__524`16254`6125!%^$!%$!%$!%$!%!$%!$$!\uA324";
SimpleString s = new SimpleString(str);
Assert.assertEquals(str, s.toString());
Assert.assertEquals(2 * str.length(), s.getData().length);
byte[] data = s.getData();
SimpleString s2 = new SimpleString(data);
Assert.assertEquals(str, s2.toString());
}
@Test
public void testStartsWith() throws Exception {
SimpleString s1 = new SimpleString("abcdefghi");
Assert.assertTrue(s1.startsWith(new SimpleString("abc")));
Assert.assertTrue(s1.startsWith(new SimpleString("abcdef")));
Assert.assertTrue(s1.startsWith(new SimpleString("abcdefghi")));
Assert.assertFalse(s1.startsWith(new SimpleString("abcdefghijklmn")));
Assert.assertFalse(s1.startsWith(new SimpleString("aardvark")));
Assert.assertFalse(s1.startsWith(new SimpleString("z")));
}
@Test
public void testCharSequence() throws Exception {
String s = "abcdefghijkl";
SimpleString s1 = new SimpleString(s);
Assert.assertEquals('a', s1.charAt(0));
Assert.assertEquals('b', s1.charAt(1));
Assert.assertEquals('c', s1.charAt(2));
Assert.assertEquals('k', s1.charAt(10));
Assert.assertEquals('l', s1.charAt(11));
try {
s1.charAt(-1);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
s1.charAt(-2);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
s1.charAt(s.length());
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
s1.charAt(s.length() + 1);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
Assert.assertEquals(s.length(), s1.length());
CharSequence ss = s1.subSequence(0, s1.length());
Assert.assertEquals(ss, s1);
ss = s1.subSequence(1, 4);
Assert.assertEquals(ss, new SimpleString("bcd"));
ss = s1.subSequence(5, 10);
Assert.assertEquals(ss, new SimpleString("fghij"));
ss = s1.subSequence(5, 12);
Assert.assertEquals(ss, new SimpleString("fghijkl"));
try {
s1.subSequence(-1, 2);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
s1.subSequence(-4, -2);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
s1.subSequence(0, s1.length() + 1);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
s1.subSequence(0, s1.length() + 2);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
try {
s1.subSequence(5, 1);
Assert.fail("Should throw exception");
} catch (IndexOutOfBoundsException e) {
// OK
}
}
@Test
public void testEquals() throws Exception {
Assert.assertFalse(new SimpleString("abcdef").equals(new Object()));
Assert.assertFalse(new SimpleString("abcef").equals(null));
Assert.assertEquals(new SimpleString("abcdef"), new SimpleString("abcdef"));
Assert.assertFalse(new SimpleString("abcdef").equals(new SimpleString("abggcdef")));
Assert.assertFalse(new SimpleString("abcdef").equals(new SimpleString("ghijkl")));
}
@Test
public void testHashcode() throws Exception {
SimpleString str = new SimpleString("abcdef");
SimpleString sameStr = new SimpleString("abcdef");
SimpleString differentStr = new SimpleString("ghijk");
Assert.assertTrue(str.hashCode() == sameStr.hashCode());
Assert.assertFalse(str.hashCode() == differentStr.hashCode());
}
@Test
public void testUnicode() throws Exception {
String myString = "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5";
SimpleString s = new SimpleString(myString);
byte[] data = s.getData();
s = new SimpleString(data);
Assert.assertEquals(myString, s.toString());
}
@Test
public void testUnicodeWithSurrogates() throws Exception {
String myString = "abcdef&^*&!^ghijkl\uD900\uDD00";
SimpleString s = new SimpleString(myString);
byte[] data = s.getData();
s = new SimpleString(data);
Assert.assertEquals(myString, s.toString());
}
@Test
public void testSizeofString() throws Exception {
Assert.assertEquals(DataConstants.SIZE_INT, SimpleString.sizeofString(new SimpleString("")));
SimpleString str = new SimpleString(RandomUtil.randomString());
Assert.assertEquals(DataConstants.SIZE_INT + str.getData().length, SimpleString.sizeofString(str));
}
@Test
public void testSizeofNullableString() throws Exception {
Assert.assertEquals(1, SimpleString.sizeofNullableString(null));
Assert.assertEquals(1 + DataConstants.SIZE_INT, SimpleString.sizeofNullableString(new SimpleString("")));
SimpleString str = new SimpleString(RandomUtil.randomString());
Assert.assertEquals(1 + DataConstants.SIZE_INT + str.getData().length, SimpleString.sizeofNullableString(str));
}
@Test
public void testSplitNoDelimeter() throws Exception {
SimpleString s = new SimpleString("abcdefghi");
SimpleString[] strings = s.split('.');
Assert.assertNotNull(strings);
Assert.assertEquals(strings.length, 1);
Assert.assertEquals(strings[0], s);
}
@Test
public void testSplit1Delimeter() throws Exception {
SimpleString s = new SimpleString("abcd.efghi");
SimpleString[] strings = s.split('.');
Assert.assertNotNull(strings);
Assert.assertEquals(strings.length, 2);
Assert.assertEquals(strings[0], new SimpleString("abcd"));
Assert.assertEquals(strings[1], new SimpleString("efghi"));
}
@Test
public void testSplitmanyDelimeters() throws Exception {
SimpleString s = new SimpleString("abcd.efghi.jklmn.opqrs.tuvw.xyz");
SimpleString[] strings = s.split('.');
Assert.assertNotNull(strings);
Assert.assertEquals(strings.length, 6);
Assert.assertEquals(strings[0], new SimpleString("abcd"));
Assert.assertEquals(strings[1], new SimpleString("efghi"));
Assert.assertEquals(strings[2], new SimpleString("jklmn"));
Assert.assertEquals(strings[3], new SimpleString("opqrs"));
Assert.assertEquals(strings[4], new SimpleString("tuvw"));
Assert.assertEquals(strings[5], new SimpleString("xyz"));
}
@Test
public void testContains() {
SimpleString simpleString = new SimpleString("abcdefghijklmnopqrst");
Assert.assertFalse(simpleString.contains('.'));
Assert.assertFalse(simpleString.contains('%'));
Assert.assertFalse(simpleString.contains('8'));
Assert.assertFalse(simpleString.contains('.'));
Assert.assertTrue(simpleString.contains('a'));
Assert.assertTrue(simpleString.contains('b'));
Assert.assertTrue(simpleString.contains('c'));
Assert.assertTrue(simpleString.contains('d'));
Assert.assertTrue(simpleString.contains('e'));
Assert.assertTrue(simpleString.contains('f'));
Assert.assertTrue(simpleString.contains('g'));
Assert.assertTrue(simpleString.contains('h'));
Assert.assertTrue(simpleString.contains('i'));
Assert.assertTrue(simpleString.contains('j'));
Assert.assertTrue(simpleString.contains('k'));
Assert.assertTrue(simpleString.contains('l'));
Assert.assertTrue(simpleString.contains('m'));
Assert.assertTrue(simpleString.contains('n'));
Assert.assertTrue(simpleString.contains('o'));
Assert.assertTrue(simpleString.contains('p'));
Assert.assertTrue(simpleString.contains('q'));
Assert.assertTrue(simpleString.contains('r'));
Assert.assertTrue(simpleString.contains('s'));
Assert.assertTrue(simpleString.contains('t'));
}
@Test
public void testConcat() {
SimpleString start = new SimpleString("abcdefg");
SimpleString middle = new SimpleString("hijklmnop");
SimpleString end = new SimpleString("qrstuvwxyz");
Assert.assertEquals(start.concat(middle).concat(end), new SimpleString("abcdefghijklmnopqrstuvwxyz"));
Assert.assertEquals(start.concat('.').concat(end), new SimpleString("abcdefg.qrstuvwxyz"));
// Testing concat of SimpleString with String
for (int i = 0; i < 10; i++) {
Assert.assertEquals(new SimpleString("abcdefg-" + i), start.concat("-" + Integer.toString(i)));
}
}
@Test
public void testMultithreadHashCode() throws Exception {
for (int repeat = 0; repeat < 10; repeat++) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 100; i++) {
buffer.append("Some Big String " + i);
}
String strvalue = buffer.toString();
final int initialhash = new SimpleString(strvalue).hashCode();
final SimpleString value = new SimpleString(strvalue);
int nThreads = 100;
final CountDownLatch latch = new CountDownLatch(nThreads);
final CountDownLatch start = new CountDownLatch(1);
class T extends Thread {
boolean failed = false;
@Override
public void run() {
try {
latch.countDown();
start.await();
int newhash = value.hashCode();
if (newhash != initialhash) {
failed = true;
}
} catch (Exception e) {
e.printStackTrace();
failed = true;
}
}
}
T[] x = new T[nThreads];
for (int i = 0; i < nThreads; i++) {
x[i] = new T();
x[i].start();
}
ActiveMQTestBase.waitForLatch(latch);
start.countDown();
for (T t : x) {
t.join();
}
for (T t : x) {
Assert.assertFalse(t.failed);
}
}
}
}