package org.geoserver.wcs2_0.eo;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.util.Collections;
import org.apache.commons.io.FileUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.CoverageView;
import org.geoserver.catalog.DimensionPresentation;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MetadataMap;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.CoverageView.CompositionType;
import org.geoserver.catalog.CoverageView.CoverageBand;
import org.geoserver.catalog.CoverageView.InputCoverageBand;
import org.geoserver.catalog.PublishedType;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.data.test.TestData;
import org.geoserver.data.test.SystemTestData.LayerProperty;
import org.geoserver.wcs.WCSInfo;
import org.geotools.feature.NameImpl;
import org.junit.Test;
import org.w3c.dom.Document;
import org.springframework.mock.web.MockHttpServletResponse;
public class DescribeOECoverageSetTest extends WCSEOTestSupport {
@Override
protected void setUpTestData(SystemTestData testData) throws Exception {
super.setUpTestData(testData);
testData.setUpDefaultRasterLayers();
testData.setUpRasterLayer(WATTEMP, "watertemp.zip", null, null, TestData.class);
}
@Test
public void testBasic() throws Exception {
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__timeranges_dss");
// print(dom);
// main structure is there
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcs:CoverageDescriptions)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcseo:DatasetSeriesDescriptions)", dom));
// expected granules are there
assertEquals("12", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberMatched", dom));
assertEquals("12", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberReturned", dom));
assertEquals("12", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
// check one granule
String base = "//wcs:CoverageDescriptions/wcs:CoverageDescription[@gml:id='sf__timeranges_granule_time_domainsRanges.4']";
assertEquals("1", xpath.evaluate("count(" + base + ")", dom));
// ... the time has been sliced to this single granule
assertEquals("2008-10-31T00:00:00.000Z", xpath.evaluate(base + "/gml:boundedBy/gml:EnvelopeWithTimePeriod/gml:beginPosition", dom));
assertEquals("2008-11-03T00:00:00.000Z", xpath.evaluate(base + "/gml:boundedBy/gml:EnvelopeWithTimePeriod/gml:endPosition", dom));
assertEquals("2008-10-31T00:00:00.000Z", xpath.evaluate(base + "/gmlcov:metadata/gmlcov:Extension/wcseo:EOMetadata" +
"/eop:EarthObservation/om:phenomenonTime/gml:TimePeriod/gml:beginPosition", dom));
// check the DatasetSeriesDescriptions
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcseo:DatasetSeriesDescriptions/wcseo:DatasetSeriesDescription)", dom));
assertEquals("1", xpath.evaluate("count(//wcseo:DatasetSeriesDescription/gml:boundedBy/gml:Envelope)", dom));
assertEquals("sf__timeranges_dss", xpath.evaluate("//wcseo:DatasetSeriesDescription/wcseo:DatasetSeriesId", dom));
assertEquals("2008-10-31T00:00:00.000Z", xpath.evaluate("//wcseo:DatasetSeriesDescription/gml:TimePeriod/gml:beginPosition", dom));
assertEquals("2008-11-07T00:00:00.000Z", xpath.evaluate("//wcseo:DatasetSeriesDescription/gml:TimePeriod/gml:endPosition", dom));
}
@Test
public void testBasicNoMaxCount() throws Exception {
// remove the max count config
WCSInfo wcs = getGeoServer().getService(WCSInfo.class);
wcs.getMetadata().remove(WCSEOMetadata.COUNT_DEFAULT.key);
getGeoServer().save(wcs);
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__timeranges_dss");
// print(dom);
// main structure is there
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcs:CoverageDescriptions)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcseo:DatasetSeriesDescriptions)", dom));
// expected granules are there
assertEquals("12", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberMatched", dom));
assertEquals("12", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberReturned", dom));
assertEquals("12", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testSectionsAll() throws Exception {
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__watertemp_dss§ions=All");
// everything
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcs:CoverageDescriptions)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcseo:DatasetSeriesDescriptions)", dom));
}
@Test
public void testSectionsCoverageDescriptions() throws Exception {
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__watertemp_dss§ions=CoverageDescriptions");
// only descriptions
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcs:CoverageDescriptions)", dom));
assertEquals("0", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcseo:DatasetSeriesDescriptions)", dom));
}
@Test
public void testSectionsDatasetSeries() throws Exception {
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__watertemp_dss§ions=DatasetSeriesDescriptions");
// only descriptions
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription)", dom));
assertEquals("0", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcs:CoverageDescriptions)", dom));
assertEquals("1", xpath.evaluate("count(/wcseo:EOCoverageSetDescription/wcseo:DatasetSeriesDescriptions)", dom));
}
@Test
public void testSectionsInvalid() throws Exception {
// invalid request
MockHttpServletResponse response = getAsServletResponse("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__watertemp_dss§ions=sectionNotThere");
checkOws20Exception(response, 400, "InvalidParameterValue", "sections");
}
@Test
public void testCountLessThanMatched() throws Exception {
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__watertemp_dss&count=2");
// print(dom);
// expected granules are there
assertEquals("4", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberMatched", dom));
assertEquals("2", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberReturned", dom));
assertEquals("2", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testDefaultCount() throws Exception {
// set the default count to 1
WCSInfo wcs = getGeoServer().getService(WCSInfo.class);
wcs.getMetadata().put(WCSEOMetadata.COUNT_DEFAULT.key, 1);
getGeoServer().save(wcs);
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__watertemp_dss");
// print(dom);
// expected granules are there
assertEquals("4", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberMatched", dom));
assertEquals("1", xpath.evaluate("/wcseo:EOCoverageSetDescription/@numberReturned", dom));
assertEquals("1", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testSpatioTemporalDataset() throws Exception {
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss");
// print(dom);
// this one has 16 granules
assertEquals("16", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
// four of which start at one of these corners (2 times) (check the bbox is actually the one of the granule, that is)
String envelopeBase = "//wcs:CoverageDescriptions/wcs:CoverageDescription/gml:boundedBy/gml:EnvelopeWithTimePeriod";
assertEquals("2", xpath.evaluate("count(" + envelopeBase + "[gml:lowerCorner='42.000641593750004 0.23722100000000002 0.0'])", dom));
assertEquals("2", xpath.evaluate("count(" + envelopeBase + "[gml:lowerCorner='42.000641593750004 9.424764334960939 0.0'])", dom));
assertEquals("2", xpath.evaluate("count(" + envelopeBase + "[gml:lowerCorner='40.56208080273438 9.424764334960939 0.0'])", dom));
assertEquals("2", xpath.evaluate("count(" + envelopeBase + "[gml:lowerCorner='40.56208080273438 0.23722100000000002 0.0'])", dom));
// check also by time, they should be 8 and 8
assertEquals("8", xpath.evaluate("count(" + envelopeBase + "[gml:beginPosition='2008-10-31T00:00:00.000Z' and gml:endPosition='2008-10-31T00:00:00.000Z'])", dom));
assertEquals("8", xpath.evaluate("count(" + envelopeBase + "[gml:beginPosition='2008-11-01T00:00:00.000Z' and gml:endPosition='2008-11-01T00:00:00.000Z'])", dom));
}
@Test
public void testMultiDimensional() throws Exception {
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__multidim_dss");
// print(dom);
// this one has 12 granules
assertEquals("12", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
// check a specific granule
String base = "//wcs:CoverageDescriptions/wcs:CoverageDescription[@gml:id='sf__multidim_granule_multidim.1']";
// ... the bbox is the expected one (it's lat/lon/elev/time
assertEquals("40.562080748421806 0.23722068851276978 20.0", xpath.evaluate(base + "/gml:boundedBy/gml:EnvelopeWithTimePeriod/gml:lowerCorner", dom));
assertEquals("44.55808294568743 14.592757149389236 99.0", xpath.evaluate(base + "/gml:boundedBy/gml:EnvelopeWithTimePeriod/gml:upperCorner", dom));
assertEquals("2008-10-31T00:00:00.000Z", xpath.evaluate(base + "/gml:boundedBy/gml:EnvelopeWithTimePeriod/gml:beginPosition", dom));
assertEquals("2008-11-03T00:00:00.000Z", xpath.evaluate(base + "/gml:boundedBy/gml:EnvelopeWithTimePeriod/gml:endPosition", dom));
// check the custom dimensions support
String extBase = base + "/gmlcov:metadata/gmlcov:Extension";
assertEquals("2008-10-31T00:00:00.000Z", xpath.evaluate(extBase + "/wcsgs:TimeDomain/gml:TimePeriod/gml:beginPosition", dom));
assertEquals("2008-11-03T00:00:00.000Z", xpath.evaluate(extBase + "/wcsgs:TimeDomain/gml:TimePeriod/gml:endPosition", dom));
assertEquals("20.0", xpath.evaluate(extBase + "/wcsgs:ElevationDomain/wcsgs:Range/wcsgs:start", dom));
assertEquals("99.0", xpath.evaluate(extBase + "/wcsgs:ElevationDomain/wcsgs:Range/wcsgs:end", dom));
assertEquals("12.0", xpath.evaluate(extBase + "/wcsgs:DimensionDomain[@name='WAVELENGTH']/wcsgs:Range/wcsgs:start", dom));
assertEquals("24.0", xpath.evaluate(extBase + "/wcsgs:DimensionDomain[@name='WAVELENGTH']/wcsgs:Range/wcsgs:end", dom));
// check the EO metadata times too
assertEquals("2008-10-31T00:00:00.000Z", xpath.evaluate(extBase + "/wcseo:EOMetadata/eop:EarthObservation/om:phenomenonTime/gml:TimePeriod/gml:beginPosition", dom));
assertEquals("2008-11-03T00:00:00.000Z", xpath.evaluate(extBase + "/wcseo:EOMetadata/eop:EarthObservation/om:phenomenonTime/gml:TimePeriod/gml:endPosition", dom));
}
@Test
public void testInvalidSubset() throws Exception {
MockHttpServletResponse response = getAsServletResponse("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=abc(1,5)");
checkOws20Exception(response, 400, "InvalidParameterValue", "subset");
}
@Test
public void testLonTrimOverlap() throws Exception {
// only the first part
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Long(1,5)");
assertEquals("8", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
// overlaps with all
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Long(5,12)");
assertEquals("16", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testLonTrimContains() throws Exception {
// overlaps but not contains
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Long(1,5)&containment=contains");
assertEquals("0", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("0", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// overlaps with all, contains none
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Long(5,12)&containment=contains");
assertEquals("0", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("0", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// contains only half
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Long(0,10)&containment=contains");
assertEquals("8", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testLatTrimOverlap() throws Exception {
// only the first part
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Lat(40,41)");
assertEquals("8", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
// overlaps with all
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Lat(41,43)");
assertEquals("16", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testLatTrimContains() throws Exception {
// overlaps but not contains
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Lat(40,41)&containment=contains");
assertEquals("0", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("0", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// overlaps with all, contains none
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Lat(41,43)&containment=contains");
assertEquals("0", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("0", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// contains only half
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss&subset=Lat(39,43)&containment=contains");
assertEquals("8", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("1", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
}
@Test
public void testTimeTrimOverlaps() throws Exception {
// overlaps with first half
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss" +
"&subset=phenomenonTime(\"2008-10-31T00:00:00.000Z\",\"2008-10-31T23:59:00.000Z\")");
assertEquals("8", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("1", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// overlaps with second half
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss" +
"&subset=phenomenonTime(\"2008-11-01T00:00:00.000Z\",\"2008-11-01T01:00:00.000Z\")");
assertEquals("8", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("1", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// overlaps with none
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss" +
"&subset=phenomenonTime(\"2008-11-02T01:00:00.000Z\",\"2008-11-02T02:00:00.000Z\")");
assertEquals("0", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("0", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
}
@Test
public void testTimeIntervalTrimContains() throws Exception {
// overlaps with some, contains none
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__timeranges_dss" +
"&subset=phenomenonTime(\"2008-10-31T00:00:00.000Z\",\"2008-10-31T23:59:00.000Z\")&containment=contains");
assertEquals("0", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("0", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// contains a bunch
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__timeranges_dss" +
"&subset=phenomenonTime(\"2008-10-30T00:00:00.000Z\",\"2008-11-03T00:00:00.000Z\")&containment=contains");
// print(dom);
assertEquals("4", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("1", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
}
@Test
public void testTimeIntervalTrimContainsLenient() throws Exception {
// overlaps with some, contains none (dates are incomplete, we use the lenient parameter)
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__timeranges_dss" +
"&subset=phenomenonTime(\"2008-10-31T00:00Z\",\"2008-10-31T23:59Z\")&containment=contains");
assertEquals("0", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("0", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
// contains a bunch
dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__timeranges_dss" +
"&subset=phenomenonTime(\"2008-10-30T00:00Z\",\"2008-11-03T00:00Z\")&containment=contains");
// print(dom);
assertEquals("4", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
assertEquals("1", xpath.evaluate("count(//wcseo:DatasetSeriesDescriptions)", dom));
}
@Test
public void testMixedTrim() throws Exception {
//
Document dom = getAsDOM("wcs?request=DescribeEOCoverageSet&version=2.0.1&service=WCS&eoid=sf__spatio-temporal_dss" +
"&subset=Long(1,5)&subset=Lat(40,41)&subset=phenomenonTime(\"2008-10-31T00:00:00.000Z\",\"2008-10-31T23:59:00.000Z\")");
// print(dom);
assertEquals("2", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testMixedTrimPost() throws Exception {
final File xml= new File("./src/test/resources/describeEOCoverageSetTrims.xml");
final String request= FileUtils.readFileToString(xml);
Document dom = postAsDOM("wcs?", request);
print(dom);
assertEquals("2", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
@Test
public void testCoverageView() throws Exception {
// Creating the coverageView
final Catalog catalog = getCatalog();
final CoverageStoreInfo storeInfo = catalog.getCoverageStoreByName("watertemp");
final InputCoverageBand band = new InputCoverageBand("watertemp", "0");
final CoverageBand outputBand = new CoverageBand(Collections.singletonList(band), "watertemp@0",
0, CompositionType.BAND_SELECT);
final CoverageView coverageView = new CoverageView("waterView",
Collections.singletonList(outputBand));
final CatalogBuilder builder = new CatalogBuilder(catalog);
builder.setStore(storeInfo);
// Adding the coverageView to the catalog
final String layerName = "waterview";
final CoverageInfo coverageInfo = coverageView.createCoverageInfo(layerName, storeInfo, builder);
coverageInfo.getParameters().put("USE_JAI_IMAGEREAD","false");
coverageInfo.getMetadata().put(WCSEOMetadata.DATASET.key, true);
catalog.add(coverageInfo);
// Adding the layer
LayerInfo layer = catalog.getLayerByName(layerName);
if (layer == null) {
layer = catalog.getFactory().createLayer();
}
layer.setResource(coverageInfo);
setupRasterDimension(layerName, ResourceInfo.TIME, DimensionPresentation.LIST, null);
enableEODataset(layerName);
layer.setType(PublishedType.RASTER);
layer.setEnabled(true);
if (layer.getId() == null) {
catalog.add(layer);
} else {
catalog.save(layer);
}
Document dom = getAsDOM("wcs?service=WCS&version=2.0.1&request=DescribeEOCoverageSet&eoId=sf__waterview_dss");
assertEquals("4", xpath.evaluate("count(//wcs:CoverageDescriptions/wcs:CoverageDescription)", dom));
}
}