diff --git a/autotest/ogr/ogr_plscenes.py b/autotest/ogr/ogr_plscenes.py index 6432df14dfea..f98edefb87cf 100755 --- a/autotest/ogr/ogr_plscenes.py +++ b/autotest/ogr/ogr_plscenes.py @@ -45,17 +45,23 @@ def module_disable_exceptions(): yield +@pytest.fixture() +def pl_url(server): + return f"http://localhost:{server.port}" + + ############################################################################### # Test Data V1 API catalog listing with a single catalog -def test_ogr_plscenes_data_v1_catalog_no_paging(): +def test_ogr_plscenes_data_v1_catalog_no_paging(pl_url, handle_get): - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types?fortest=true", + handle_get( + "/data_v1/item-types/", '{ "item_types": [ { "id": "PSScene3Band" } ] }', ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds = gdal.OpenEx( "PLScenes:", gdal.OF_VECTOR, open_options=["VERSION=data_v1", "API_KEY=foo"] ) @@ -67,24 +73,24 @@ def test_ogr_plscenes_data_v1_catalog_no_paging(): with gdal.quiet_errors(): assert ds.GetLayerByName("non_existing") is None - gdal.Unlink("/vsimem/data_v1/item-types?fortest=true") - ############################################################################### # Test Data V1 API catalog listing with catalog paging -def test_ogr_plscenes_data_v1_catalog_paging(): +def test_ogr_plscenes_data_v1_catalog_paging(pl_url, handle_get): - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types?fortest=true", - '{"_links": { "_next" : "/vsimem/data_v1/item-types/page_2"}, "item_types": [ { "id": "PSScene3Band" } ] }', + handle_get( + "/data_v1/item-types/", + '{"_links": { "_next" : "PL_URL/data_v1/item-types/page_2"}, "item_types": [ { "id": "PSScene3Band" } ] }'.replace( + "PL_URL", pl_url + ), ) - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/page_2?fortest=true", + handle_get( + "/data_v1/item-types/page_2", '{ "item_types": [ { "id": "PSScene4Band" } ] }', ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds = gdal.OpenEx( "PLScenes:", gdal.OF_VECTOR, open_options=["VERSION=data_v1", "API_KEY=foo"] ) @@ -92,8 +98,8 @@ def test_ogr_plscenes_data_v1_catalog_paging(): with gdal.quiet_errors(): assert ds.GetLayerByName("non_existing") is None assert ds.GetLayerByName("PSScene3Band") is not None - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSScene4Band?fortest=true", + handle_get( + "/data_v1/item-types/PSScene4Band", '{ "id": "PSScene4Band"} }', ) assert ds.GetLayerByName("PSScene4Band") is not None @@ -102,32 +108,28 @@ def test_ogr_plscenes_data_v1_catalog_paging(): with gdal.quiet_errors(): assert ds.GetLayerByName("non_existing") is None - gdal.Unlink("/vsimem/data_v1/item-types?fortest=true") - gdal.Unlink("/vsimem/data_v1/item-types/page_2") - gdal.Unlink("/vsimem/data_v1/item-types/PSScene4Band") - ############################################################################### # Test Data V1 API -def test_ogr_plscenes_data_v1_nominal(): +def test_ogr_plscenes_data_v1_nominal_vector(pl_url, handle_get, handle_post): - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types?fortest=true", + handle_get( + "/data_v1/item-types/", """{ "item_types": [ {"display_description" : "display_description", "display_name" : "display_name", "id": "PSOrthoTile"} ]}""", ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds = gdal.OpenEx( "PLScenes:", gdal.OF_VECTOR, open_options=["VERSION=data_v1", "API_KEY=foo"] ) assert ds is not None - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds = gdal.OpenEx( "PLScenes:version=data_v1,api_key=foo,FOLLOW_LINKS=YES", gdal.OF_VECTOR ) @@ -141,17 +143,20 @@ def test_ogr_plscenes_data_v1_nominal(): and lyr.TestCapability(ogr.OLCRandomRead) == 0 ) # Different serialization depending on libjson versions - gdal.FileFromMemBuffer( - """/vsimem/data_v1/stats&POSTFIELDS={"interval":"year","item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"cloud_cover","config":{"gte":0.000000}}]}}""", - """{ "buckets": [ { "count": 1 }, { "count": 1} ] }""", + handle_post( + "/data_v1/stats", + post_body="""{"interval":"year","item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"cloud_cover","config":{"gte":0.000000}}]}}""", + contents="""{ "buckets": [ { "count": 1 }, { "count": 1} ] }""", ) - gdal.FileFromMemBuffer( - """/vsimem/data_v1/stats&POSTFIELDS={"interval":"year","item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"cloud_cover","config":{"gte":0}}]}}""", - """{ "buckets": [ { "count": 1 }, { "count": 1} ] }""", + handle_post( + "/data_v1/stats", + post_body="""{"interval":"year","item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"cloud_cover","config":{"gte":0}}]}}""", + contents="""{ "buckets": [ { "count": 1 }, { "count": 1} ] }""", ) - gdal.FileFromMemBuffer( - """/vsimem/data_v1/stats&POSTFIELDS={"interval":"year","item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"cloud_cover","config":{"gte":0.0}}]}}""", - """{ "buckets": [ { "count": 1 }, { "count": 1} ] }""", + handle_post( + "/data_v1/stats", + post_body="""{"interval":"year","item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"cloud_cover","config":{"gte":0.0}}]}}""", + contents="""{ "buckets": [ { "count": 1 }, { "count": 1} ] }""", ) assert lyr.GetFeatureCount() == 2 assert lyr.GetGeomType() == ogr.wkbMultiPolygon @@ -162,19 +167,20 @@ def test_ogr_plscenes_data_v1_nominal(): assert field_count == 106 # Regular /items/ fetching - gdal.FileFromMemBuffer( - """/vsimem/data_v1/quick-search?_page_size=250&POSTFIELDS={"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[]}}""", - """{ + handle_post( + """/data_v1/quick-search?_page_size=1""", + post_body="""{"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[]}}""", + contents="""{ "_links": { - "_next": "/vsimem/data_v1/quick-search?page=2" + "_next": "PL_URL/data_v1/quick-search?page=2" }, "features" : [ { "id": "id", "_links" : { "_self" : "self", - "assets" : "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets" + "assets" : "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets" }, "_permissions" : [ "download" ], "properties": { @@ -191,26 +197,32 @@ def test_ogr_plscenes_data_v1_nominal(): } } ] -}""", +}""".replace( + "PL_URL", pl_url + ), ) - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets?fortest=true", + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets", """{ "analytic" : { "_permissions": ["download"], "_links": { "_self": "analytic_links_self", - "activate": "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", + "activate": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", }, - "location": "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", + "location": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", "status": "active", "expires_at": "2016-02-11T12:34:56.789" } -}""", +}""".replace( + "PL_URL", pl_url + ), ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_options( + {"PL_URL": f"{pl_url}/data_v1/", "PLSCENES_PAGE_SIZE": "1"} + ): ds = gdal.OpenEx( "PLScenes:", gdal.OF_VECTOR, @@ -219,29 +231,34 @@ def test_ogr_plscenes_data_v1_nominal(): lyr = ds.GetLayer(0) f = lyr.GetNextFeature() - if ( - f.GetFID() != 1 - or f["id"] != "id" - or f["self_link"] != "self" - or f["assets_link"] != "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets" - or f["acquired"] != "2016/02/11 12:34:56.789+00" - or f["anomalous_pixels"] != 1.23 - or f["item_type"] != "foo" - or f["columns"] != 1 - or not f["ground_control"] - or f["asset_analytic_self_link"] != "analytic_links_self" - or f["asset_analytic_activate_link"] - != "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate" - or f["asset_analytic_permissions"] != ["download"] - or f["asset_analytic_expires_at"] != "2016/02/11 12:34:56.789" - or f["asset_analytic_location"] - != "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff" - or f["asset_analytic_status"] != "active" - or f.GetGeometryRef().ExportToWkt() - != "MULTIPOLYGON (((2 49,2.0 49.1,2.1 49.1,2.1 49.0,2 49)))" - ): - f.DumpReadable() - pytest.fail() + + assert f.GetFID() == 1 + assert f["id"] == "id" + assert f["self_link"] == "self" + assert ( + f["assets_link"] == f"{pl_url}/data_v1/item-types/PSOrthoTile/items/id/assets" + ) + assert f["acquired"] == "2016/02/11 12:34:56.789+00" + assert f["anomalous_pixels"] == 1.23 + assert f["item_type"] == "foo" + assert f["columns"] == 1 + assert f["ground_control"] + assert f["asset_analytic_self_link"] == "analytic_links_self" + assert ( + f["asset_analytic_activate_link"] + == f"{pl_url}/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate" + ) + assert f["asset_analytic_permissions"] == ["download"] + assert f["asset_analytic_expires_at"] == "2016/02/11 12:34:56.789" + assert ( + f["asset_analytic_location"] + == f"{pl_url}/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff" + ) + assert f["asset_analytic_status"] == "active" + assert ( + f.GetGeometryRef().ExportToWkt() + == "MULTIPOLYGON (((2 49,2.0 49.1,2.1 49.1,2.1 49.0,2 49)))" + ) lyr.ResetReading() f = lyr.GetNextFeature() @@ -249,8 +266,8 @@ def test_ogr_plscenes_data_v1_nominal(): f.DumpReadable() pytest.fail() - gdal.FileFromMemBuffer( - "/vsimem/data_v1/quick-search?page=2", + handle_get( + "/data_v1/quick-search?page=2", """{ "features" : [ { @@ -261,20 +278,15 @@ def test_ogr_plscenes_data_v1_nominal(): ) f = lyr.GetNextFeature() - if f.GetFID() != 2 or f["id"] != "id2": - f.DumpReadable() - pytest.fail() + assert f.GetFID() == 2 + assert f["id"] == "id2" lyr.ResetReading() f = lyr.GetNextFeature() - if f.GetFID() != 1: - f.DumpReadable() - pytest.fail() + assert f.GetFID() == 1 f = lyr.GetNextFeature() - if f.GetFID() != 2: - f.DumpReadable() - pytest.fail() + assert f.GetFID() == 2 f = lyr.GetNextFeature() assert f is None @@ -282,17 +294,16 @@ def test_ogr_plscenes_data_v1_nominal(): f = lyr.GetNextFeature() assert f is None - gdal.FileFromMemBuffer( - """/vsimem/data_v1/quick-search?_page_size=250&POSTFIELDS={"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"GeometryFilter","field_name":"geometry","config":{"type":"Point","coordinates":[2.0,49.0]}}]}}""", - """{"features" : [ { "id": "id3", "geometry": { "type": "Point", "coordinates": [2,49]} } ] }""", + handle_post( + """/data_v1/quick-search?_page_size=1""", + post_body="""{"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"GeometryFilter","field_name":"geometry","config":{"type":"Point","coordinates":[2.0,49.0]}}]}}""", + contents="""{"features" : [ { "id": "id3", "geometry": { "type": "Point", "coordinates": [2,49]} } ] }""", ) # POINT spatial filter lyr.SetSpatialFilterRect(2, 49, 2, 49) f = lyr.GetNextFeature() - if f["id"] != "id3": - f.DumpReadable() - pytest.fail() + assert f["id"] == "id3" # Cannot find /vsimem/data_v1/stats&POSTFIELDS={"interval":"year","item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"GeometryFilter","field_name":"geometry","config":{"type":"Point","coordinates":[2.0,49.0]}}]}} with gdal.quiet_errors(): @@ -301,24 +312,21 @@ def test_ogr_plscenes_data_v1_nominal(): # Reset spatial filter lyr.SetSpatialFilter(0, None) f = lyr.GetNextFeature() - if f["id"] != "id": - f.DumpReadable() - pytest.fail() + assert f["id"] == "id" # Test attribute filter on id lyr.SetAttributeFilter("id = 'filtered_id'") - gdal.FileFromMemBuffer( - """/vsimem/data_v1/quick-search?_page_size=250&POSTFIELDS={"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_id"]}]}}""", - """{ + handle_post( + """/data_v1/quick-search?_page_size=1""", + post_body="""{"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_id"]}]}}""", + contents="""{ "id": "filtered_id", "properties": {} }""", ) f = lyr.GetNextFeature() - if f["id"] != "filtered_id": - f.DumpReadable() - pytest.fail() + assert f["id"] == "filtered_id" # Test attribute filter fully evaluated on server side. lyr.SetAttributeFilter( @@ -330,7 +338,7 @@ def test_ogr_plscenes_data_v1_nominal(): "id": "filtered_2", "_links" : { "_self" : "self", - "assets" : "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets" + "assets" : "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets" }, "_permissions" : [ "download" ], "properties": { @@ -346,25 +354,28 @@ def test_ogr_plscenes_data_v1_nominal(): } } ] -}""" - gdal.FileFromMemBuffer( - """/vsimem/data_v1/quick-search?_page_size=250&POSTFIELDS={"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["a"]}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gte":"2016-02-11T00:00:00Z"}}]},{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lte":"2016-02-12T00:00:00Z"}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gt":"1970-01-01T01:23:45Z"}}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lt":"2100-01-01T01:23:45Z"}},{"type":"RangeFilter","field_name":"anomalous_pixels","config":{"gte":1.234567,"lte":1.234567}}]},{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["b"]}},{"type":"RangeFilter","field_name":"columns","config":{"gt":0}}]}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"columns","config":{"lt":2}},{"type":"NumberInFilter","field_name":"columns","config":[1]}]},{"type":"AndFilter","config":[{"type":"NumberInFilter","field_name":"columns","config":[1,2]},{"type":"OrFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_2"]},{"type":"StringInFilter","field_name":"id","config":["foo"]}]}]}]},{"type":"AndFilter","config":[{"type":"PermissionFilter","config":["download"]},{"type":"PermissionFilter","config":["download"]}]}]}]}]}}""", - content, +}""".replace( + "PL_URL", pl_url ) - gdal.FileFromMemBuffer( - """/vsimem/data_v1/quick-search?_page_size=250&POSTFIELDS={"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["a"]}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gte":"2016-02-11T00:00:00Z"}}]},{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lte":"2016-02-12T00:00:00Z"}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gt":"1970-01-01T01:23:45Z"}}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lt":"2100-01-01T01:23:45Z"}},{"type":"RangeFilter","field_name":"anomalous_pixels","config":{"gte":1.23456699,"lte":1.2345670099999999}}]},{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["b"]}},{"type":"RangeFilter","field_name":"columns","config":{"gt":0}}]}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"columns","config":{"lt":2}},{"type":"NumberInFilter","field_name":"columns","config":[1]}]},{"type":"AndFilter","config":[{"type":"NumberInFilter","field_name":"columns","config":[1,2]},{"type":"OrFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_2"]},{"type":"StringInFilter","field_name":"id","config":["foo"]}]}]}]},{"type":"AndFilter","config":[{"type":"PermissionFilter","config":["download"]},{"type":"PermissionFilter","config":["download"]}]}]}]}]}}""", - content, + handle_post( + """/data_v1/quick-search?_page_size=1""", + post_body="""{"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["a"]}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gte":"2016-02-11T00:00:00Z"}}]},{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lte":"2016-02-12T00:00:00Z"}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gt":"1970-01-01T01:23:45Z"}}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lt":"2100-01-01T01:23:45Z"}},{"type":"RangeFilter","field_name":"anomalous_pixels","config":{"gte":1.234567,"lte":1.234567}}]},{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["b"]}},{"type":"RangeFilter","field_name":"columns","config":{"gt":0}}]}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"columns","config":{"lt":2}},{"type":"NumberInFilter","field_name":"columns","config":[1]}]},{"type":"AndFilter","config":[{"type":"NumberInFilter","field_name":"columns","config":[1,2]},{"type":"OrFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_2"]},{"type":"StringInFilter","field_name":"id","config":["foo"]}]}]}]},{"type":"AndFilter","config":[{"type":"PermissionFilter","config":["download"]},{"type":"PermissionFilter","config":["download"]}]}]}]}]}}""", + contents=content, + ) + handle_post( + """/data_v1/quick-search?_page_size=1""", + post_body="""{"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["a"]}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gte":"2016-02-11T00:00:00Z"}}]},{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lte":"2016-02-12T00:00:00Z"}},{"type":"DateRangeFilter","field_name":"acquired","config":{"gt":"1970-01-01T01:23:45Z"}}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"DateRangeFilter","field_name":"acquired","config":{"lt":"2100-01-01T01:23:45Z"}},{"type":"RangeFilter","field_name":"anomalous_pixels","config":{"gte":1.23456699,"lte":1.2345670099999999}}]},{"type":"AndFilter","config":[{"type":"NotFilter","config":{"type":"StringInFilter","field_name":"id","config":["b"]}},{"type":"RangeFilter","field_name":"columns","config":{"gt":0}}]}]}]},{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"AndFilter","config":[{"type":"RangeFilter","field_name":"columns","config":{"lt":2}},{"type":"NumberInFilter","field_name":"columns","config":[1]}]},{"type":"AndFilter","config":[{"type":"NumberInFilter","field_name":"columns","config":[1,2]},{"type":"OrFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_2"]},{"type":"StringInFilter","field_name":"id","config":["foo"]}]}]}]},{"type":"AndFilter","config":[{"type":"PermissionFilter","config":["download"]},{"type":"PermissionFilter","config":["download"]}]}]}]}]}}""", + contents=content, ) f = lyr.GetNextFeature() - if f["id"] != "filtered_2": - f.DumpReadable() - pytest.fail() + assert f["id"] == "filtered_2" # Partly server / partly client lyr.SetAttributeFilter("id = 'filtered_3' AND id > 'a'") - gdal.FileFromMemBuffer( - """/vsimem/data_v1/quick-search?_page_size=250&POSTFIELDS={"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_3"]}]}}""", - """{ + handle_post( + """/data_v1/quick-search?_page_size=1""", + post_body="""{"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"StringInFilter","field_name":"id","config":["filtered_3"]}]}}""", + contents="""{ "features" : [ { "id": "filtered_3", @@ -375,51 +386,46 @@ def test_ogr_plscenes_data_v1_nominal(): }""", ) f = lyr.GetNextFeature() - if f["id"] != "filtered_3": - f.DumpReadable() - pytest.fail() + assert f["id"] == "filtered_3" lyr.SetAttributeFilter("id > 'a' AND id = 'filtered_3'") f = lyr.GetNextFeature() - if f["id"] != "filtered_3": - f.DumpReadable() - pytest.fail() + assert f["id"] == "filtered_3" # Completely client side lyr.SetAttributeFilter("id > 'a' OR id = 'id'") f = lyr.GetNextFeature() - if f["id"] != "id": - f.DumpReadable() - pytest.fail() + assert f["id"] == "id" # Completely client side lyr.SetAttributeFilter("NOT id > 'z'") f = lyr.GetNextFeature() - if f["id"] != "id": - f.DumpReadable() - pytest.fail() + assert f["id"] == "id" # Reset attribute filter lyr.SetAttributeFilter(None) f = lyr.GetNextFeature() - if f["id"] != "id": - f.DumpReadable() - pytest.fail() + assert f["id"] == "id" + - # Try raster access +def test_ogr_plscenes_data_v1_nominal_raster_1(pl_url, handle_get, handle_post): # Missing catalog - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): with gdal.quiet_errors(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, open_options=["VERSION=data_v1", "API_KEY=foo", "SCENE=id"], ) - assert ds_raster is None and gdal.GetLastErrorMsg().find("Missing catalog") >= 0 + assert ds_raster is None + assert "Missing catalog" in gdal.GetLastErrorMsg() + + +def test_ogr_plscenes_data_v1_nominal_raster_2(pl_url, handle_get, handle_post): # Invalid catalog - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdal.quiet_errors(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -430,13 +436,18 @@ def test_ogr_plscenes_data_v1_nominal(): "SCENE=id", ], ) + assert ds_raster is None + assert "404" in gdal.GetLastErrorMsg() + + +def test_ogr_plscenes_data_v1_nominal_raster_3(pl_url, handle_get, handle_post): # visual not an object - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets?fortest=true", + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/", """{ "visual": false }""", ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdal.quiet_errors(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -448,22 +459,27 @@ def test_ogr_plscenes_data_v1_nominal(): ], ) assert ds_raster is None + assert "Cannot find link" in gdal.GetLastErrorMsg() + +def test_ogr_plscenes_data_v1_nominal_raster_4(pl_url, handle_get, handle_post): # Inactive file, and activation link not working - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets?fortest=true", + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/", """{ "analytic" : { "_links": { "_self": "analytic_links_self", - "activate": "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", + "activate": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", }, "_permissions": ["download"], "status": "inactive", } -}""", +}""".replace( + "PL_URL", pl_url + ), ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdal.quiet_errors(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -477,22 +493,26 @@ def test_ogr_plscenes_data_v1_nominal(): ], ) assert ds_raster is None + assert "Activation timeout reached" in gdal.GetLastErrorMsg() + + +def test_ogr_plscenes_data_v1_nominal_raster_5(pl_url, handle_get, handle_post): # File in activation - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets?fortest=true", + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/", """{ "analytic" : { "_links": { "_self": "analytic_links_self", - "activate": "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", + "activate": "/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", }, "_permissions": ["download"], "status": "activating", } }""", ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdal.quiet_errors(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -506,17 +526,21 @@ def test_ogr_plscenes_data_v1_nominal(): ], ) assert ds_raster is None + assert "Activation timeout reached" in gdal.GetLastErrorMsg() - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets?fortest=true", + +def test_ogr_plscenes_data_v1_nominal_raster_6(pl_url, handle_get, handle_post): + + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/", """{ "analytic" : { "_permissions": ["download"], "_links": { "_self": "analytic_links_self", - "activate": "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", + "activate": "/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", }, - "location": "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", + "location": "/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", "status": "active", "expires_at": "2016-02-11T12:34:56.789" } @@ -524,7 +548,7 @@ def test_ogr_plscenes_data_v1_nominal(): ) # Missing /vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdaltest.error_handler(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -538,13 +562,36 @@ def test_ogr_plscenes_data_v1_nominal(): ], ) assert ds_raster is None + assert "generation of the product is in progress" in gdal.GetLastErrorMsg() + + +def test_ogr_plscenes_data_v1_nominal_raster_7(pl_url, handle_get, handle_post): + + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/", + """{ + "analytic" : { + "_permissions": ["download"], + "_links": { + "_self": "analytic_links_self", + "activate": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", + }, + "location": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my7.tiff", + "status": "active", + "expires_at": "2016-02-11T12:34:56.789" + } +}""".replace( + "PL_URL", pl_url + ), + ) # JSon content for /vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my7.tiff", """{}""", ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdaltest.error_handler(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -558,13 +605,36 @@ def test_ogr_plscenes_data_v1_nominal(): ], ) assert ds_raster is None + assert "generation of the product is in progress" in gdal.GetLastErrorMsg() + + +def test_ogr_plscenes_data_v1_nominal_raster_8(pl_url, handle_get, handle_post): + + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/", + """{ + "analytic" : { + "_permissions": ["download"], + "_links": { + "_self": "analytic_links_self", + "activate": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", + }, + "location": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", + "status": "active", + "expires_at": "2016-02-11T12:34:56.789" + } +}""".replace( + "PL_URL", pl_url + ), + ) # Missing metadata - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", open("../gcore/data/byte.tif", "rb").read(), ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdaltest.error_handler(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -578,14 +648,40 @@ def test_ogr_plscenes_data_v1_nominal(): ], ) assert ds_raster is not None - ds_raster = None + + +def test_ogr_plscenes_data_v1_nominal_raster_9(pl_url, handle_get, handle_post): + + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/", + """{ + "analytic" : { + "_permissions": ["download"], + "_links": { + "_self": "analytic_links_self", + "activate": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/activate", + }, + "location": "PL_URL/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", + "status": "active", + "expires_at": "2016-02-11T12:34:56.789" + } +}""".replace( + "PL_URL", pl_url + ), + ) # Failed filter by scene id - gdal.FileFromMemBuffer( - "/vsimem/data_v1/item-types/PSOrthoTile?fortest=true", + handle_get( + "/data_v1/item-types/PSOrthoTile", """{"id": "PSOrthoTile"}""", ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + + handle_get( + "/data_v1/item-types/PSOrthoTile/items/id/assets/analytic/my.tiff", + open("../gcore/data/byte.tif", "rb").read(), + ) + + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -599,19 +695,19 @@ def test_ogr_plscenes_data_v1_nominal(): ], ) assert ds_raster is not None - ds_raster = None # Test metadata items attached to dataset - gdal.FileFromMemBuffer( - """/vsimem/data_v1/quick-search?_page_size=250&POSTFIELDS={"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"StringInFilter","field_name":"id","config":["id"]}]}}""", - """{ + handle_post( + """/data_v1/quick-search?_page_size=250""", + post_body="""{"item_types":["PSOrthoTile"],"filter":{"type":"AndFilter","config":[{"type":"StringInFilter","field_name":"id","config":["id"]}]}}""", + contents="""{ "id": "id", "properties": { "anomalous_pixels": 1.23 }, }""", ) - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -629,7 +725,7 @@ def test_ogr_plscenes_data_v1_nominal(): ds_raster = None # Test invalid ASSET - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdaltest.error_handler(): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -645,7 +741,7 @@ def test_ogr_plscenes_data_v1_nominal(): assert ds_raster is None # Test subdatasets - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds_raster = gdal.OpenEx( "PLScenes:", gdal.OF_RASTER, @@ -661,7 +757,7 @@ def test_ogr_plscenes_data_v1_nominal(): ds_raster = None # Unsupported option - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdaltest.error_handler(): ds_raster = gdal.OpenEx( "PLScenes:unsupported=yes", gdal.OF_RASTER, @@ -674,8 +770,25 @@ def test_ogr_plscenes_data_v1_nominal(): ) assert ds_raster is None + +def test_ogr_plscenes_data_v1_nominal_raster_10(pl_url, handle_get, handle_post): + + handle_get( + "/data_v1/item-types/", + """{ "item_types": [ + {"display_description" : "display_description", + "display_name" : "display_name", + "id": "PSOrthoTile"} +]}""", + ) + + handle_get( + "/data_v1/item-types/PSOrthoTile", + """{"id": "PSOrthoTile"}""", + ) + # Test catalog with vector access - with gdal.config_option("PL_URL", "/vsimem/data_v1/"): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"): ds2 = gdal.OpenEx( "PLScenes:", gdal.OF_VECTOR, @@ -683,7 +796,7 @@ def test_ogr_plscenes_data_v1_nominal(): ) assert ds2 is not None and ds2.GetLayerCount() == 1 - with gdal.config_option("PL_URL", "/vsimem/data_v1/"), gdaltest.error_handler(): + with gdal.config_option("PL_URL", f"{pl_url}/data_v1/"), gdaltest.error_handler(): ds2 = gdal.OpenEx( "PLScenes:", gdal.OF_VECTOR, @@ -691,10 +804,6 @@ def test_ogr_plscenes_data_v1_nominal(): ) assert ds2 is None - fl = gdal.ReadDir("/vsimem/data_v1") - for filename in fl: - gdal.Unlink(filename) - ############################################################################### # Test robustness to errors in Data V1 API diff --git a/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1layer.cpp b/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1layer.cpp index f63b9fceacda..e2a5e2b9951c 100644 --- a/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1layer.cpp +++ b/ogr/ogrsf_frmts/plscenes/ogrplscenesdatav1layer.cpp @@ -975,11 +975,6 @@ OGRFeature *OGRPLScenesDataV1Layer::GetNextRawFeature() if (m_nFeatureIdx == static_cast(json_object_array_length(m_poFeatures))) { - if (m_nFeatureIdx < m_nPageSize && - m_poDS->GetBaseURL().find("/vsimem/") != 0) - { - return nullptr; - } m_osRequestURL = m_osNextURL; m_bStillInFirstPage = false; if (!GetNextPage())