/* * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others. * * Licensed 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. * * Contributors: * Florent Guillaume */ package org.nuxeo.ecm.core.pubsub; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.io.output.ByteArrayOutputStream; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.nuxeo.runtime.mockito.MockitoFeature; import org.nuxeo.runtime.mockito.RuntimeService; import org.nuxeo.runtime.test.runner.Features; import org.nuxeo.runtime.test.runner.FeaturesRunner; import org.nuxeo.runtime.test.runner.RuntimeFeature; @RunWith(FeaturesRunner.class) @Features({ RuntimeFeature.class, MockitoFeature.class }) public class TestAbstractPubSubInvalidator { @Mock @RuntimeService protected PubSubService pubSubService; @Before public void doBefore() throws Exception { doNothing().when(pubSubService).registerSubscriber(anyString(), any()); } public static class DummyInvalidations implements SerializableInvalidations { private static final long serialVersionUID = 1L; protected boolean inval; public void inval() { inval = true; } @Override public void add(SerializableInvalidations o) { DummyInvalidations other = (DummyInvalidations) o; inval = inval || other.inval; } @Override public boolean isEmpty() { return !inval; } @Override public void serialize(OutputStream out) throws IOException { if (inval) { out.write('Y'); } } public static DummyInvalidations deserialize(InputStream in) throws IOException { DummyInvalidations invals = new DummyInvalidations(); if (in.read() != -1) { invals.inval(); } return invals; } } public static class DummyInvalidator extends AbstractPubSubInvalidator<DummyInvalidations> { @Override public DummyInvalidations newInvalidations() { return new DummyInvalidations(); } @Override public DummyInvalidations deserialize(InputStream in) throws IOException { return DummyInvalidations.deserialize(in); } } @Test public void testDummyInvalidations() throws IOException { DummyInvalidations invals = new DummyInvalidations(); DummyInvalidations invals2 = new DummyInvalidations(); assertTrue(invals.isEmpty()); assertTrue(roundTrip(invals).isEmpty()); invals2.add(invals); assertTrue(invals2.isEmpty()); invals.inval(); assertFalse(invals.isEmpty()); assertFalse(roundTrip(invals).isEmpty()); invals2.add(invals); assertFalse(invals2.isEmpty()); } protected DummyInvalidations roundTrip(DummyInvalidations invalidations) throws IOException { DummyInvalidator invalidator = new DummyInvalidator(); try (ByteArrayOutputStream baout = new ByteArrayOutputStream()) { invalidations.serialize(baout); try (ByteArrayInputStream bain = new ByteArrayInputStream(baout.toByteArray())) { return invalidator.deserialize(bain); } } } @Test public void testScanDiscriminator() throws Exception { DummyInvalidator invalidator = new DummyInvalidator(); invalidator.initialize("topic", "di"); assertEquals(-1, invalidator.scanDiscriminator(null)); assertEquals(-1, invalidator.scanDiscriminator("".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("d".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("di".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("dis".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("x".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("xy".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("xyz".getBytes())); assertEquals(1, invalidator.scanDiscriminator(":foo".getBytes())); assertEquals(1, invalidator.scanDiscriminator(":".getBytes())); assertEquals(2, invalidator.scanDiscriminator("x:foo".getBytes())); assertEquals(2, invalidator.scanDiscriminator("x:".getBytes())); assertEquals(3, invalidator.scanDiscriminator("xy:foo".getBytes())); assertEquals(3, invalidator.scanDiscriminator("xy:".getBytes())); assertEquals(4, invalidator.scanDiscriminator("xyz:foo".getBytes())); assertEquals(4, invalidator.scanDiscriminator("xyz:".getBytes())); assertEquals(2, invalidator.scanDiscriminator("d:foo".getBytes())); assertEquals(2, invalidator.scanDiscriminator("d:".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("di:foo".getBytes())); assertEquals(-1, invalidator.scanDiscriminator("di:".getBytes())); assertEquals(4, invalidator.scanDiscriminator("dis:foo".getBytes())); assertEquals(4, invalidator.scanDiscriminator("dis:".getBytes())); } @Test public void testSubscriberDiscriminatorComparison() throws Exception { DummyInvalidator invalidator = new DummyInvalidator(); invalidator.initialize("topic", "d"); DummyInvalidations invals; // use different discriminator invalidator.subscriber("topic", "z:foo".getBytes()); invals = invalidator.receiveInvalidations(); assertFalse(invals.isEmpty()); // use same discriminator invalidator.subscriber("topic", "d:foo".getBytes()); invals = invalidator.receiveInvalidations(); assertTrue(invals.isEmpty()); } }