Unit test for the gossip intent store
This change also implements a unit test harness for the
EventuallyConsistentMap that is intended to be reusable
to test other stores.
Change-Id: I2257da9b19412b97a3aa0f127be7263a7732b852
diff --git a/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java b/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java
index 87052ba..b88b5ff 100644
--- a/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/cluster/ClusterServiceAdapter.java
@@ -18,19 +18,25 @@
import java.util.Set;
import org.joda.time.DateTime;
+import org.onlab.packet.IpAddress;
+
+import com.google.common.collect.ImmutableSet;
/**
* Test adapter for the cluster service.
*/
public class ClusterServiceAdapter implements ClusterService {
+ ControllerNode local = new DefaultControllerNode(new NodeId("local"),
+ IpAddress.valueOf("127.0.0.1"));
+
@Override
public ControllerNode getLocalNode() {
- return null;
+ return local;
}
@Override
public Set<ControllerNode> getNodes() {
- return null;
+ return ImmutableSet.of(local);
}
@Override
diff --git a/core/api/src/test/java/org/onosproject/net/intent/PartitionServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/intent/PartitionServiceAdapter.java
new file mode 100644
index 0000000..ffb2635
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/intent/PartitionServiceAdapter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.net.intent;
+
+import org.onosproject.cluster.NodeId;
+
+import static org.junit.Assert.*;
+
+/**
+ * Testing adapter for the partition service.
+ */
+public class PartitionServiceAdapter implements PartitionService {
+ @Override
+ public boolean isMine(Key intentKey) {
+ return true;
+ }
+
+ @Override
+ public NodeId getLeader(Key intentKey) {
+ return null;
+ }
+
+ @Override
+ public void addListener(PartitionEventListener listener) {
+
+ }
+
+ @Override
+ public void removeListener(PartitionEventListener listener) {
+
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/store/service/EventuallyConsistentMapAdapter.java b/core/api/src/test/java/org/onosproject/store/service/EventuallyConsistentMapAdapter.java
new file mode 100644
index 0000000..07f5fb4
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/store/service/EventuallyConsistentMapAdapter.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.store.service;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
+
+/**
+ * Testing adapter for EventuallyConsistentMap.
+ */
+public class EventuallyConsistentMapAdapter<K, V> implements EventuallyConsistentMap<K, V> {
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public boolean containsKey(K key) {
+ return false;
+ }
+
+ @Override
+ public boolean containsValue(V value) {
+ return false;
+ }
+
+ @Override
+ public V get(K key) {
+ return null;
+ }
+
+ @Override
+ public void put(K key, V value) {
+
+ }
+
+ @Override
+ public V remove(K key) {
+ return null;
+ }
+
+ @Override
+ public void remove(K key, V value) {
+
+ }
+
+ @Override
+ public V compute(K key, BiFunction<K, V, V> recomputeFunction) {
+ return null;
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> m) {
+
+ }
+
+ @Override
+ public void clear() {
+
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return null;
+ }
+
+ @Override
+ public Collection<V> values() {
+ return null;
+ }
+
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ return null;
+ }
+
+ @Override
+ public void addListener(EventuallyConsistentMapListener<K, V> listener) {
+
+ }
+
+ @Override
+ public void removeListener(EventuallyConsistentMapListener<K, V> listener) {
+
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/store/service/StorageServiceAdapter.java b/core/api/src/test/java/org/onosproject/store/service/StorageServiceAdapter.java
new file mode 100644
index 0000000..ec04e33
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/store/service/StorageServiceAdapter.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.store.service;
+
+/**
+ * Adapter for the storage service.
+ */
+public class StorageServiceAdapter implements StorageService {
+ @Override
+ public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <E> DistributedSetBuilder<E> setBuilder() {
+ return null;
+ }
+
+ @Override
+ public <E> DistributedQueueBuilder<E> queueBuilder() {
+ return null;
+ }
+
+ @Override
+ public AtomicCounterBuilder atomicCounterBuilder() {
+ return null;
+ }
+
+ @Override
+ public <V> AtomicValueBuilder<V> atomicValueBuilder() {
+ return null;
+ }
+
+ @Override
+ public TransactionContextBuilder transactionContextBuilder() {
+ return null;
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java b/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
new file mode 100644
index 0000000..5ee44c4
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.store.service;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiFunction;
+
+import org.onlab.util.KryoNamespace;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.store.Timestamp;
+
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.*;
+
+/**
+ * Testing version of an Eventually Consistent Map.
+ */
+
+public final class TestEventuallyConsistentMap<K, V> extends EventuallyConsistentMapAdapter<K, V> {
+
+ private final HashMap<K, V> map;
+ private final String mapName;
+ private final List<EventuallyConsistentMapListener<K, V>> listeners;
+ private final BiFunction<K, V, Collection<NodeId>> peerUpdateFunction;
+
+ private TestEventuallyConsistentMap(String mapName,
+ BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) {
+ map = new HashMap<>();
+ listeners = new LinkedList<>();
+ this.mapName = mapName;
+ this.peerUpdateFunction = peerUpdateFunction;
+ }
+
+ /**
+ * Notify all listeners of an event.
+ */
+ private void notifyListeners(EventuallyConsistentMapEvent<K, V> event) {
+ listeners.forEach(
+ listener -> listener.event(event)
+ );
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(K key) {
+ return map.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(V value) {
+ return map.containsValue(value);
+ }
+
+ @Override
+ public V get(K key) {
+ return map.get(key);
+ }
+
+ @Override
+ public void put(K key, V value) {
+ map.put(key, value);
+ EventuallyConsistentMapEvent<K, V> addEvent =
+ new EventuallyConsistentMapEvent<>(mapName, PUT, key, value);
+ notifyListeners(addEvent);
+ peerUpdateFunction.apply(key, value);
+ }
+
+ @Override
+ public V remove(K key) {
+ V result = map.remove(key);
+ if (result != null) {
+ EventuallyConsistentMapEvent<K, V> removeEvent =
+ new EventuallyConsistentMapEvent<>(mapName, REMOVE,
+ key, map.get(key));
+ notifyListeners(removeEvent);
+ }
+ return result;
+ }
+
+ @Override
+ public void remove(K key, V value) {
+ boolean removed = map.remove(key, value);
+ if (removed) {
+ EventuallyConsistentMapEvent<K, V> removeEvent =
+ new EventuallyConsistentMapEvent<>(mapName, REMOVE, key, value);
+ notifyListeners(removeEvent);
+ }
+ }
+
+ @Override
+ public V compute(K key, BiFunction<K, V, V> recomputeFunction) {
+ return map.compute(key, recomputeFunction);
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> m) {
+ map.putAll(m);
+ }
+
+ @Override
+ public void clear() {
+ map.clear();
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return map.keySet();
+ }
+
+ @Override
+ public Collection<V> values() {
+ return map.values();
+ }
+
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ return map.entrySet();
+ }
+
+ public static <K, V> Builder<K, V> builder() {
+ return new Builder<>();
+ }
+
+ @Override
+ public void addListener(EventuallyConsistentMapListener<K, V> listener) {
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeListener(EventuallyConsistentMapListener<K, V> listener) {
+ listeners.remove(listener);
+ }
+
+ public static class Builder<K, V> implements EventuallyConsistentMapBuilder<K, V> {
+ private String name;
+ private BiFunction<K, V, Collection<NodeId>> peerUpdateFunction;
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withSerializer(KryoNamespace.Builder serializerBuilder) {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V>
+ withTimestampProvider(BiFunction<K, V, Timestamp> timestampProvider) {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withEventExecutor(ExecutorService executor) {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withCommunicationExecutor(ExecutorService executor) {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withBackgroundExecutor(ScheduledExecutorService executor) {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V>
+ withPeerUpdateFunction(BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) {
+ this.peerUpdateFunction = peerUpdateFunction;
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withTombstonesDisabled() {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withAntiEntropyPeriod(long period, TimeUnit unit) {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withFasterConvergence() {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMapBuilder<K, V> withPersistence() {
+ return this;
+ }
+
+ @Override
+ public EventuallyConsistentMap<K, V> build() {
+ if (name == null) {
+ name = "test";
+ }
+ return new TestEventuallyConsistentMap<>(name, peerUpdateFunction);
+ }
+ }
+
+}
+
diff --git a/core/api/src/test/java/org/onosproject/store/service/TestStorageService.java b/core/api/src/test/java/org/onosproject/store/service/TestStorageService.java
new file mode 100644
index 0000000..d79796c
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/store/service/TestStorageService.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.store.service;
+
+public class TestStorageService extends StorageServiceAdapter {
+
+
+ @Override
+ public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() {
+ return TestEventuallyConsistentMap.builder();
+ }
+
+ @Override
+ public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
+ throw new UnsupportedOperationException("consistentMapBuilder");
+ }
+
+ @Override
+ public <E> DistributedSetBuilder<E> setBuilder() {
+ throw new UnsupportedOperationException("setBuilder");
+ }
+
+ @Override
+ public <E> DistributedQueueBuilder<E> queueBuilder() {
+ throw new UnsupportedOperationException("queueBuilder");
+ }
+
+ @Override
+ public AtomicCounterBuilder atomicCounterBuilder() {
+ throw new UnsupportedOperationException("atomicCounterBuilder");
+ }
+
+ @Override
+ public <V> AtomicValueBuilder<V> atomicValueBuilder() {
+ throw new UnsupportedOperationException("atomicValueBuilder");
+ }
+
+ @Override
+ public TransactionContextBuilder transactionContextBuilder() {
+ throw new UnsupportedOperationException("transactionContextBuilder");
+ }
+}
diff --git a/core/store/dist/src/test/java/org/onosproject/store/intent/impl/GossipIntentStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/GossipIntentStoreTest.java
new file mode 100644
index 0000000..a74c3a2
--- /dev/null
+++ b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/GossipIntentStoreTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.store.intent.impl;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.IntStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.intent.HostToHostIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentTestsMocks;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.intent.PartitionServiceAdapter;
+import org.onosproject.store.service.TestStorageService;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.net.NetTestTools.hid;
+
+/**
+ * Gossip Intent Store test using database adapter.
+ */
+public class GossipIntentStoreTest {
+
+ private GossipIntentStore intentStore;
+ private IdGenerator idGenerator;
+ private HostToHostIntent.Builder builder1;
+
+ @Before
+ public void setUp() {
+ intentStore = new GossipIntentStore();
+ intentStore.storageService = new TestStorageService();
+ intentStore.partitionService = new PartitionServiceAdapter();
+ intentStore.clusterService = new ClusterServiceAdapter();
+ idGenerator = new MockIdGenerator();
+ Intent.bindIdGenerator(idGenerator);
+ builder1 = HostToHostIntent
+ .builder()
+ .one(hid("12:34:56:78:91:ab/1"))
+ .two(hid("12:34:56:78:91:ac/1"))
+ .appId(APP_ID);
+ intentStore.activate();
+ }
+
+ @After
+ public void cleanUp() {
+ intentStore.deactivate();
+ Intent.unbindIdGenerator(idGenerator);
+ }
+
+ /**
+ * Generates a list of test intent data.
+ *
+ * @param count how many intent data objects are needed
+ * @return list of intent data
+ */
+ private List<IntentData> generateIntentList(int count) {
+ LinkedList<IntentData> intents = new LinkedList<>();
+ IntStream.rangeClosed(1, count)
+ .forEach(i ->
+ intents.add(
+ new IntentData(
+ builder1
+ .priority(i)
+ .build(),
+ IntentState.INSTALLED,
+ new IntentTestsMocks.MockTimestamp(12))));
+ return intents;
+ }
+
+ /**
+ * Tests the intent count APIs.
+ */
+ @Test
+ public void testGetIntentCount() {
+ assertThat(intentStore.getIntentCount(), is(0L));
+
+ generateIntentList(5).forEach(intentStore::write);
+
+ assertThat(intentStore.getIntentCount(), is(5L));
+ }
+
+ /**
+ * Tests the batch add API.
+ */
+ @Test
+ public void testBatchAdd() {
+ assertThat(intentStore.getIntentCount(), is(0L));
+
+ List<IntentData> intents = generateIntentList(5);
+
+ intentStore.batchWrite(intents);
+ assertThat(intentStore.getIntentCount(), is(5L));
+ }
+
+
+ /**
+ * Tests adding and withdrawing an Intent.
+ */
+ @Test
+ public void testAddAndWithdrawIntent() {
+ // build and install one intent
+ Intent intent = builder1.build();
+ IntentData installed = new IntentData(
+ intent,
+ IntentState.INSTALLED,
+ new IntentTestsMocks.MockTimestamp(12));
+ intentStore.write(installed);
+
+ // check that the intent count includes the new one
+ assertThat(intentStore.getIntentCount(), is(1L));
+
+ // check that the getIntents() API returns the new intent
+ intentStore.getIntents()
+ .forEach(item -> assertThat(item, is(intent)));
+
+ // check that the getInstallableIntents() API returns the new intent
+ intentStore.getInstallableIntents(intent.key())
+ .forEach(item -> assertThat(item, is(intent)));
+
+ // check that the getIntent() API can find the new intent
+ Intent queried = intentStore.getIntent(intent.key());
+ assertThat(queried, is(intent));
+
+ // check that the state of the new intent is correct
+ IntentState state = intentStore.getIntentState(intent.key());
+ assertThat(state, is(IntentState.INSTALLED));
+
+ // check that the getIntentData() API returns the proper value for the
+ // new intent
+ IntentData dataByQuery = intentStore.getIntentData(intent.key());
+ assertThat(dataByQuery, is(installed));
+
+ // check that the getIntentData() API returns the new intent when given
+ // a time stamp to look for
+ Iterable<IntentData> dataIteratorByTime = intentStore.getIntentData(true, 10L);
+ assertThat(dataIteratorByTime.iterator().hasNext(), is(true));
+ dataIteratorByTime.forEach(
+ data -> assertThat(data, is(installed))
+ );
+
+ // check that the getIntentData() API returns the new intent when asked to
+ // find all intents
+ Iterable<IntentData> dataIteratorAll = intentStore.getIntentData(false, 0L);
+ assertThat(dataIteratorAll.iterator().hasNext(), is(true));
+ dataIteratorAll.forEach(
+ data -> assertThat(data, is(installed))
+ );
+
+ // now purge the intent that was created
+ IntentData purge = new IntentData(
+ intent,
+ IntentState.PURGE_REQ,
+ new IntentTestsMocks.MockTimestamp(12));
+ intentStore.write(purge);
+
+ // check that no intents are left
+ assertThat(intentStore.getIntentCount(), is(0L));
+
+ // check that a getIntent() operation on the key of the purged intent
+ // returns null
+ Intent queriedAfterWithdrawal = intentStore.getIntent(intent.key());
+ assertThat(queriedAfterWithdrawal, nullValue());
+ }
+
+ /**
+ * Tests the operation of the APIs for the pending map.
+ */
+ @Test
+ public void testPending() {
+ // crete a new intent and add it as pending
+ Intent intent = builder1.build();
+ IntentData installed = new IntentData(
+ intent,
+ IntentState.INSTALLED,
+ new IntentTestsMocks.MockTimestamp(11));
+ intentStore.addPending(installed);
+
+ // check that the getPending() API returns the new pending intent
+ Iterable<Intent> pendingIntentIteratorAll = intentStore.getPending();
+ assertThat(pendingIntentIteratorAll.iterator().hasNext(), is(true));
+ pendingIntentIteratorAll.forEach(
+ data -> assertThat(data, is(intent))
+ );
+
+ // check that the getPendingData() API returns the IntentData for the
+ // new pending intent
+ Iterable<IntentData> pendingDataIteratorAll = intentStore.getPendingData();
+ assertThat(pendingDataIteratorAll.iterator().hasNext(), is(true));
+ pendingDataIteratorAll.forEach(
+ data -> assertThat(data, is(installed))
+ );
+
+ // check that the new pending intent is returned by the getPendingData()
+ // API when a time stamp is provided
+ Iterable<IntentData> pendingDataIteratorSelected =
+ intentStore.getPendingData(true, 10L);
+ assertThat(pendingDataIteratorSelected.iterator().hasNext(), is(true));
+ pendingDataIteratorSelected.forEach(
+ data -> assertThat(data, is(installed))
+ );
+
+ // check that the new pending intent is returned by the getPendingData()
+ // API when a time stamp is provided
+ Iterable<IntentData> pendingDataIteratorAllFromTimestamp =
+ intentStore.getPendingData(false, 0L);
+ assertThat(pendingDataIteratorAllFromTimestamp.iterator().hasNext(), is(true));
+ pendingDataIteratorSelected.forEach(
+ data -> assertThat(data, is(installed))
+ );
+ }
+}