/* * 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.unit.core.message.impl; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import org.apache.activemq.artemis.api.core.ActiveMQBuffer; import org.apache.activemq.artemis.api.core.ICoreMessage; import org.apache.activemq.artemis.api.core.Message; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.client.impl.ClientMessageImpl; import org.apache.activemq.artemis.core.message.impl.CoreMessage; import org.apache.activemq.artemis.core.protocol.core.impl.wireformat.SessionSendMessage; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.activemq.artemis.utils.RandomUtil; import org.junit.Assert; import org.junit.Test; public class MessageImplTest extends ActiveMQTestBase { @Test public void getSetAttributes() { for (int j = 0; j < 10; j++) { byte[] bytes = new byte[1000]; for (int i = 0; i < bytes.length; i++) { bytes[i] = RandomUtil.randomByte(); } final byte type = RandomUtil.randomByte(); final boolean durable = RandomUtil.randomBoolean(); final long expiration = RandomUtil.randomLong(); final long timestamp = RandomUtil.randomLong(); final byte priority = RandomUtil.randomByte(); ICoreMessage message1 = new ClientMessageImpl(type, durable, expiration, timestamp, priority, 100); ICoreMessage message = message1; Assert.assertEquals(type, message.getType()); Assert.assertEquals(durable, message.isDurable()); Assert.assertEquals(expiration, message.getExpiration()); Assert.assertEquals(timestamp, message.getTimestamp()); Assert.assertEquals(priority, message.getPriority()); final SimpleString destination = new SimpleString(RandomUtil.randomString()); final boolean durable2 = RandomUtil.randomBoolean(); final long expiration2 = RandomUtil.randomLong(); final long timestamp2 = RandomUtil.randomLong(); final byte priority2 = RandomUtil.randomByte(); message.setAddress(destination); Assert.assertEquals(destination, message.getAddressSimpleString()); message.setDurable(durable2); Assert.assertEquals(durable2, message.isDurable()); message.setExpiration(expiration2); Assert.assertEquals(expiration2, message.getExpiration()); message.setTimestamp(timestamp2); Assert.assertEquals(timestamp2, message.getTimestamp()); message.setPriority(priority2); Assert.assertEquals(priority2, message.getPriority()); } } @Test public void testExpired() { Message message = new ClientMessageImpl(); Assert.assertEquals(0, message.getExpiration()); Assert.assertFalse(message.isExpired()); message.setExpiration(System.currentTimeMillis() + 1000); Assert.assertFalse(message.isExpired()); message.setExpiration(System.currentTimeMillis() - 1); Assert.assertTrue(message.isExpired()); message.setExpiration(System.currentTimeMillis() - 1000); Assert.assertTrue(message.isExpired()); message.setExpiration(0); Assert.assertFalse(message.isExpired()); } @Test public void testProperties() { for (int j = 0; j < 10; j++) { Message msg = new ClientMessageImpl(); SimpleString prop1 = new SimpleString("prop1"); boolean val1 = RandomUtil.randomBoolean(); msg.putBooleanProperty(prop1, val1); SimpleString prop2 = new SimpleString("prop2"); byte val2 = RandomUtil.randomByte(); msg.putByteProperty(prop2, val2); SimpleString prop3 = new SimpleString("prop3"); byte[] val3 = RandomUtil.randomBytes(); msg.putBytesProperty(prop3, val3); SimpleString prop4 = new SimpleString("prop4"); double val4 = RandomUtil.randomDouble(); msg.putDoubleProperty(prop4, val4); SimpleString prop5 = new SimpleString("prop5"); float val5 = RandomUtil.randomFloat(); msg.putFloatProperty(prop5, val5); SimpleString prop6 = new SimpleString("prop6"); int val6 = RandomUtil.randomInt(); msg.putIntProperty(prop6, val6); SimpleString prop7 = new SimpleString("prop7"); long val7 = RandomUtil.randomLong(); msg.putLongProperty(prop7, val7); SimpleString prop8 = new SimpleString("prop8"); short val8 = RandomUtil.randomShort(); msg.putShortProperty(prop8, val8); SimpleString prop9 = new SimpleString("prop9"); SimpleString val9 = new SimpleString(RandomUtil.randomString()); msg.putStringProperty(prop9, val9); Assert.assertEquals(9, msg.getPropertyNames().size()); Assert.assertTrue(msg.getPropertyNames().contains(prop1)); Assert.assertTrue(msg.getPropertyNames().contains(prop2)); Assert.assertTrue(msg.getPropertyNames().contains(prop3)); Assert.assertTrue(msg.getPropertyNames().contains(prop4)); Assert.assertTrue(msg.getPropertyNames().contains(prop5)); Assert.assertTrue(msg.getPropertyNames().contains(prop6)); Assert.assertTrue(msg.getPropertyNames().contains(prop7)); Assert.assertTrue(msg.getPropertyNames().contains(prop8)); Assert.assertTrue(msg.getPropertyNames().contains(prop9)); Assert.assertTrue(msg.containsProperty(prop1)); Assert.assertTrue(msg.containsProperty(prop2)); Assert.assertTrue(msg.containsProperty(prop3)); Assert.assertTrue(msg.containsProperty(prop4)); Assert.assertTrue(msg.containsProperty(prop5)); Assert.assertTrue(msg.containsProperty(prop6)); Assert.assertTrue(msg.containsProperty(prop7)); Assert.assertTrue(msg.containsProperty(prop8)); Assert.assertTrue(msg.containsProperty(prop9)); Assert.assertEquals(val1, msg.getObjectProperty(prop1)); Assert.assertEquals(val2, msg.getObjectProperty(prop2)); Assert.assertEquals(val3, msg.getObjectProperty(prop3)); Assert.assertEquals(val4, msg.getObjectProperty(prop4)); Assert.assertEquals(val5, msg.getObjectProperty(prop5)); Assert.assertEquals(val6, msg.getObjectProperty(prop6)); Assert.assertEquals(val7, msg.getObjectProperty(prop7)); Assert.assertEquals(val8, msg.getObjectProperty(prop8)); Assert.assertEquals(val9, msg.getObjectProperty(prop9)); SimpleString val10 = new SimpleString(RandomUtil.randomString()); // test overwrite msg.putStringProperty(prop9, val10); Assert.assertEquals(val10, msg.getObjectProperty(prop9)); int val11 = RandomUtil.randomInt(); msg.putIntProperty(prop9, val11); Assert.assertEquals(val11, msg.getObjectProperty(prop9)); msg.removeProperty(prop1); Assert.assertEquals(8, msg.getPropertyNames().size()); Assert.assertTrue(msg.getPropertyNames().contains(prop2)); Assert.assertTrue(msg.getPropertyNames().contains(prop3)); Assert.assertTrue(msg.getPropertyNames().contains(prop4)); Assert.assertTrue(msg.getPropertyNames().contains(prop5)); Assert.assertTrue(msg.getPropertyNames().contains(prop6)); Assert.assertTrue(msg.getPropertyNames().contains(prop7)); Assert.assertTrue(msg.getPropertyNames().contains(prop8)); Assert.assertTrue(msg.getPropertyNames().contains(prop9)); msg.removeProperty(prop2); Assert.assertEquals(7, msg.getPropertyNames().size()); Assert.assertTrue(msg.getPropertyNames().contains(prop3)); Assert.assertTrue(msg.getPropertyNames().contains(prop4)); Assert.assertTrue(msg.getPropertyNames().contains(prop5)); Assert.assertTrue(msg.getPropertyNames().contains(prop6)); Assert.assertTrue(msg.getPropertyNames().contains(prop7)); Assert.assertTrue(msg.getPropertyNames().contains(prop8)); Assert.assertTrue(msg.getPropertyNames().contains(prop9)); msg.removeProperty(prop9); Assert.assertEquals(6, msg.getPropertyNames().size()); Assert.assertTrue(msg.getPropertyNames().contains(prop3)); Assert.assertTrue(msg.getPropertyNames().contains(prop4)); Assert.assertTrue(msg.getPropertyNames().contains(prop5)); Assert.assertTrue(msg.getPropertyNames().contains(prop6)); Assert.assertTrue(msg.getPropertyNames().contains(prop7)); Assert.assertTrue(msg.getPropertyNames().contains(prop8)); msg.removeProperty(prop3); msg.removeProperty(prop4); msg.removeProperty(prop5); msg.removeProperty(prop6); msg.removeProperty(prop7); msg.removeProperty(prop8); Assert.assertEquals(0, msg.getPropertyNames().size()); } } @Test public void testMessageCopyIssue() throws Exception { for (long i = 0; i < 300; i++) { if (i % 10 == 0) System.out.println("#test " + i); internalMessageCopy(); } } private void internalMessageCopy() throws Exception { final long RUNS = 2; final CoreMessage msg = new CoreMessage(123, 18); msg.setMessageID(RandomUtil.randomLong()); msg.setAddress(new SimpleString("Batatantkashf aksjfh aksfjh askfdjh askjfh ")); final AtomicInteger errors = new AtomicInteger(0); int T1_number = 10; int T2_number = 10; final CountDownLatch latchAlign = new CountDownLatch(T1_number + T2_number); final CountDownLatch latchReady = new CountDownLatch(1); class T1 extends Thread { @Override public void run() { latchAlign.countDown(); try { latchReady.await(); } catch (Exception ignored) { } for (int i = 0; i < RUNS; i++) { try { Message newMsg = msg.copy(); } catch (Throwable e) { e.printStackTrace(); errors.incrementAndGet(); } } } } final String bigString; { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < 500; i++) { buffer.append(" "); } bigString = buffer.toString(); } class T2 extends Thread { @Override public void run() { latchAlign.countDown(); try { latchReady.await(); } catch (Exception ignored) { } for (int i = 0; i < RUNS; i++) { ActiveMQBuffer buf = null; try { SessionSendMessage ssm = new SessionSendMessage(msg); buf = ssm.encode(null); simulateRead(buf); } catch (Throwable e) { e.printStackTrace(); errors.incrementAndGet(); } finally { if ( buf != null ) { buf.release(); } } } } } ArrayList<Thread> threads = new ArrayList<>(); for (int i = 0; i < T1_number; i++) { T1 t = new T1(); threads.add(t); t.start(); } for (int i = 0; i < T2_number; i++) { T2 t2 = new T2(); threads.add(t2); t2.start(); } latchAlign.await(); latchReady.countDown(); for (Thread t : threads) { t.join(); } Assert.assertEquals(0, errors.get()); } private void simulateRead(ActiveMQBuffer buf) { buf.setIndex(buf.capacity() / 2, buf.capacity() / 2); // ok this is not actually happening during the read process, but changing this shouldn't affect the buffer on copy // this is to exaggerate the isolation on this test buf.writeBytes(new byte[1024]); } // Protected ------------------------------------------------------------------------------- // Private ---------------------------------------------------------------------------------- }