mirror of https://github.com/apache/jclouds.git
Issue 158: implemented listImages and listHardwareProfiles in SoftLayerComputeServiceAdapter. Tidied ProductItemsToHardware and tests
This commit is contained in:
parent
afda717d2f
commit
2f73dbc539
|
@ -20,22 +20,24 @@ package org.jclouds.softlayer.compute.config;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
||||||
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
||||||
import org.jclouds.softlayer.SoftLayerClient;
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
import org.jclouds.softlayer.compute.functions.DatacenterToLocation;
|
import org.jclouds.softlayer.compute.functions.DatacenterToLocation;
|
||||||
import org.jclouds.softlayer.compute.functions.ProductItemsToHardware;
|
|
||||||
import org.jclouds.softlayer.compute.functions.ProductItemToImage;
|
import org.jclouds.softlayer.compute.functions.ProductItemToImage;
|
||||||
|
import org.jclouds.softlayer.compute.functions.ProductItemsToHardware;
|
||||||
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata;
|
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata;
|
||||||
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
||||||
import org.jclouds.softlayer.domain.Datacenter;
|
import org.jclouds.softlayer.domain.Datacenter;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -67,4 +69,12 @@ public class SoftLayerComputeServiceContextModule extends
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {})
|
bind(new TypeLiteral<Supplier<Location>>() {})
|
||||||
.to(OnlyLocationOrFirstZone.class);
|
.to(OnlyLocationOrFirstZone.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
|
return template.osFamily(OsFamily.UBUNTU)
|
||||||
|
.osVersionMatches("1[10].[10][04]")
|
||||||
|
.os64Bit(true)
|
||||||
|
.osDescriptionMatches(".*Minimal Install.*")
|
||||||
|
.minCores(2);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -20,25 +20,22 @@ package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.HardwareBuilder;
|
import org.jclouds.compute.domain.HardwareBuilder;
|
||||||
import org.jclouds.compute.domain.Processor;
|
import org.jclouds.compute.domain.Processor;
|
||||||
import org.jclouds.compute.domain.Volume;
|
import org.jclouds.compute.domain.Volume;
|
||||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||||
|
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a set of ProductItems to Hardware.
|
* Converts a set of ProductItems to Hardware.
|
||||||
|
@ -52,18 +49,17 @@ import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
||||||
public class ProductItemsToHardware implements Function<Set<ProductItem>, Hardware> {
|
public class ProductItemsToHardware implements Function<Set<ProductItem>, Hardware> {
|
||||||
|
|
||||||
private static final double CORE_SPEED = 2.0;
|
private static final double CORE_SPEED = 2.0;
|
||||||
private static final Pattern SAN_REGEX = Pattern.compile(".*GB \\(SAN\\).*");
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Hardware apply(Set<ProductItem> from) {
|
public Hardware apply(Set<ProductItem> items) {
|
||||||
|
|
||||||
ProductItem coresItem = getCoresItem(from);
|
ProductItem coresItem = getOnlyElement(filter(items, units("PRIVATE_CORE")));
|
||||||
ProductItem ramItem = getRamItem(from);
|
ProductItem ramItem = getOnlyElement(filter(items, categoryCode("ram")));
|
||||||
ProductItem volumeItem = bootVolume().apply(from);
|
ProductItem volumeItem = getOnlyElement(filter(items, matches(SoftLayerComputeServiceAdapter.SAN_DESCRIPTION_REGEX)));
|
||||||
|
|
||||||
final String hardwareId = hardwareId().apply(ImmutableList.of(coresItem, ramItem, volumeItem));
|
final String hardwareId = hardwareId().apply(ImmutableList.of(coresItem, ramItem, volumeItem));
|
||||||
final double cores = getCores(coresItem);
|
final double cores = ProductItems.capacity().apply(coresItem).doubleValue();
|
||||||
final int ram = getRam(ramItem);
|
final int ram = ProductItems.capacity().apply(ramItem).intValue();
|
||||||
final float volumeSize = ProductItems.capacity().apply(volumeItem);
|
final float volumeSize = ProductItems.capacity().apply(volumeItem);
|
||||||
|
|
||||||
return new HardwareBuilder()
|
return new HardwareBuilder()
|
||||||
|
@ -92,48 +88,4 @@ public class ProductItemsToHardware implements Function<Set<ProductItem>, Hardwa
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds an item that is usable as the hardware volume (is a SAN)
|
|
||||||
* @return The product item
|
|
||||||
* @throws java.util.NoSuchElementException if the item cannot be found
|
|
||||||
*/
|
|
||||||
public static Function<Set<ProductItem>,ProductItem> bootVolume() {
|
|
||||||
return new Function<Set<ProductItem>,ProductItem>() {
|
|
||||||
@Override
|
|
||||||
public ProductItem apply(Set<ProductItem> productItems) {
|
|
||||||
for(ProductItem item: productItems) {
|
|
||||||
String description = item.getDescription();
|
|
||||||
if (SAN_REGEX.matcher(description).matches()) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchElementException("cannot find suitable boot volume item");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProductItem getCoresItem(Set<ProductItem> from) {
|
|
||||||
Iterable<ProductItem> cpuItems = Iterables.filter(from, units("PRIVATE_CORE"));
|
|
||||||
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
|
||||||
assert coresToProductItem.size() == 1 : "Must have 1 cpu product item:"+coresToProductItem;
|
|
||||||
|
|
||||||
return coresToProductItem.entrySet().iterator().next().getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private double getCores(ProductItem from) {
|
|
||||||
return ProductItems.capacity().apply(from).doubleValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProductItem getRamItem(Set<ProductItem> from) {
|
|
||||||
Iterable<ProductItem> ramItems = Iterables.filter(from,categoryCode("ram"));
|
|
||||||
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
|
||||||
assert ramToProductItem.size() == 1 : "Must have 1 ram product item:"+ramToProductItem;
|
|
||||||
|
|
||||||
return ramToProductItem.entrySet().iterator().next().getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getRam(ProductItem from) {
|
|
||||||
return ProductItems.capacity().apply(from).intValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,23 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.strategy;
|
package org.jclouds.softlayer.compute.strategy;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import org.jclouds.compute.ComputeService;
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.softlayer.SoftLayerClient;
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
|
import org.jclouds.softlayer.compute.functions.ProductItems;
|
||||||
import org.jclouds.softlayer.domain.Datacenter;
|
import org.jclouds.softlayer.domain.Datacenter;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.ProductPackage;
|
import org.jclouds.softlayer.domain.ProductPackage;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
import org.jclouds.softlayer.predicates.ProductPackagePredicates;
|
import org.jclouds.softlayer.features.AccountClient;
|
||||||
|
import org.jclouds.softlayer.features.ProductPackageClient;
|
||||||
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -39,6 +44,8 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
||||||
|
@ -47,7 +54,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SoftLayerComputeServiceAdapter implements
|
public class SoftLayerComputeServiceAdapter implements
|
||||||
ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
||||||
|
|
||||||
|
public static final String SAN_DESCRIPTION_REGEX=".*GB \\(SAN\\).*";
|
||||||
|
//TODO: Better to pass this in as a property like virtualGuestPackageName?
|
||||||
|
private static final Float BOOT_VOLUME_CAPACITY = 100F;
|
||||||
|
|
||||||
private final SoftLayerClient client;
|
private final SoftLayerClient client;
|
||||||
private final String virtualGuestPackageName;
|
private final String virtualGuestPackageName;
|
||||||
|
|
||||||
|
@ -75,14 +87,36 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Set<ProductItem>> listHardwareProfiles() {
|
public Iterable<Set<ProductItem>> listHardwareProfiles() {
|
||||||
// TODO: get the set of product item prices corresponding to the hardware profiles
|
ProductPackage productPackage = getProductPackage();
|
||||||
return ImmutableSet.of();
|
Set<ProductItem> items = productPackage.getItems();
|
||||||
|
|
||||||
|
Iterable<ProductItem> cpuItems = Iterables.filter(items, units("PRIVATE_CORE"));
|
||||||
|
Iterable<ProductItem> ramItems = Iterables.filter(items,categoryCode("ram"));
|
||||||
|
Iterable<ProductItem> sanItems = Iterables.filter(items, Predicates.and(matches(SAN_DESCRIPTION_REGEX),categoryCode("one_time_charge")));
|
||||||
|
|
||||||
|
Map<Float, ProductItem> cpuMap = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
||||||
|
Map<Float, ProductItem> ramMap = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
||||||
|
Map<Float, ProductItem> sanMap = Maps.uniqueIndex(sanItems, ProductItems.capacity());
|
||||||
|
|
||||||
|
final ProductItem bootVolume = sanMap.get(BOOT_VOLUME_CAPACITY);
|
||||||
|
assert bootVolume!=null : "Boot volume capacity not found:"+BOOT_VOLUME_CAPACITY+", available:"+sanItems;
|
||||||
|
|
||||||
|
Set<Set<ProductItem>> result = Sets.newLinkedHashSet();
|
||||||
|
for(Map.Entry<Float, ProductItem> coresEntry : cpuMap.entrySet()) {
|
||||||
|
Float cores = coresEntry.getKey();
|
||||||
|
ProductItem ramItem = ramMap.get(cores);
|
||||||
|
//Amount of RAM and number of cores must match.
|
||||||
|
if(ramItem==null) continue;
|
||||||
|
|
||||||
|
result.add(ImmutableSet.of(coresEntry.getValue(),ramItem,bootVolume));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ProductItem> listImages() {
|
public Iterable<ProductItem> listImages() {
|
||||||
// TODO: get the list of product item prices corresponding to images
|
return Iterables.filter(getProductPackage().getItems(), categoryCode("os"));
|
||||||
return ImmutableSet.of();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,10 +126,15 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Datacenter> listLocations() {
|
public Iterable<Datacenter> listLocations() {
|
||||||
// TODO we should be able to specify a filter that gets the datacenters here.
|
return getProductPackage().getDatacenters();
|
||||||
ProductPackage virtualGuestPackage = Iterables.find(client.getAccountClient().getActivePackages(),
|
}
|
||||||
ProductPackagePredicates.named(virtualGuestPackageName));
|
|
||||||
return client.getProductPackageClient().getProductPackage(virtualGuestPackage.getId()).getDatacenters();
|
private ProductPackage getProductPackage() {
|
||||||
|
AccountClient accountClient = client.getAccountClient();
|
||||||
|
ProductPackageClient productPackageClient = client.getProductPackageClient();
|
||||||
|
|
||||||
|
ProductPackage p = Iterables.find(accountClient.getActivePackages(),named(virtualGuestPackageName));
|
||||||
|
return productPackageClient.getProductPackage(p.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,8 @@ import com.google.common.base.Predicate;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.ProductItemCategory;
|
import org.jclouds.softlayer.domain.ProductItemCategory;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class ProductItemPredicates {
|
public class ProductItemPredicates {
|
||||||
|
@ -73,9 +75,8 @@ public class ProductItemPredicates {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the ProductItem has the required units.
|
* Tests if the ProductItem has the required units.
|
||||||
* TODO Write test method
|
|
||||||
* @param units
|
* @param units
|
||||||
* @return true if it does, otherwise false.
|
* @return true if it does, otherwise false.
|
||||||
*/
|
*/
|
||||||
|
@ -94,4 +95,28 @@ public class ProductItemPredicates {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the ProductItem's description matches the supplied regular expression.
|
||||||
|
* @param regex a regular expression to match against.
|
||||||
|
* @return true if it does, otherwise false.
|
||||||
|
* @throws java.util.regex.PatternSyntaxException if the regex is invalid
|
||||||
|
*/
|
||||||
|
public static Predicate<ProductItem> matches(final String regex) {
|
||||||
|
checkNotNull(regex, "regex cannot be null");
|
||||||
|
final Pattern PATTERN = Pattern.compile(regex);
|
||||||
|
|
||||||
|
return new Predicate<ProductItem>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem, "productItem cannot ne null");
|
||||||
|
return PATTERN.matcher(productItem.getDescription()).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "regex("+regex+")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,7 @@ import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
|
|
||||||
import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.bootVolume;
|
|
||||||
import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.hardwareId;
|
import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.hardwareId;
|
||||||
import static org.testng.AssertJUnit.assertEquals;
|
import static org.testng.AssertJUnit.assertEquals;
|
||||||
|
|
||||||
|
@ -53,21 +51,6 @@ public class ProductItemsToHardwareTest {
|
||||||
assertEquals("123,456,789",id);
|
assertEquals("123,456,789",id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBootVolume() {
|
|
||||||
ProductItem item1 = ProductItem.builder().id(1).description("Not a SAN").build();
|
|
||||||
ProductItem item2 = ProductItem.builder().id(2).description("100 GB (SAN)").build();
|
|
||||||
|
|
||||||
ProductItem found = bootVolume().apply(ImmutableSet.of(item1,item2));
|
|
||||||
assertEquals(item2,found);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = NoSuchElementException.class)
|
|
||||||
public void testBootVolumeMissing() {
|
|
||||||
ProductItem item1 = ProductItem.builder().id(1).description("Not a SAN").build();
|
|
||||||
bootVolume().apply(ImmutableSet.of(item1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHardware() {
|
public void testHardware() {
|
||||||
ProductItem cpuItem = ProductItem.builder()
|
ProductItem cpuItem = ProductItem.builder()
|
||||||
|
|
|
@ -38,6 +38,7 @@ public class ProductItemPredicatesTest {
|
||||||
ramCategory = ProductItemCategory.builder().id(1).categoryCode("ram").build();
|
ramCategory = ProductItemCategory.builder().id(1).categoryCode("ram").build();
|
||||||
|
|
||||||
item = ProductItem.builder().id(1)
|
item = ProductItem.builder().id(1)
|
||||||
|
.description("a test item")
|
||||||
.categories(ImmutableSet.of(ramCategory))
|
.categories(ImmutableSet.of(ramCategory))
|
||||||
.capacity(2.0f)
|
.capacity(2.0f)
|
||||||
.units("GB")
|
.units("GB")
|
||||||
|
@ -88,4 +89,14 @@ public class ProductItemPredicatesTest {
|
||||||
public void testUnitsMissing() {
|
public void testUnitsMissing() {
|
||||||
assertFalse(ProductItemPredicates.units("Kg").apply(item));
|
assertFalse(ProductItemPredicates.units("Kg").apply(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchesRegex() {
|
||||||
|
assert ProductItemPredicates.matches(".*test.*").apply(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoMatchRegex() {
|
||||||
|
assertFalse(ProductItemPredicates.matches("no match").apply(item));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue