aletrn commited on
Commit
7a8b84d
·
1 Parent(s): 84a883f

[test] add test cases for download_extent

Browse files
src/utilities/utilities.py CHANGED
@@ -1,4 +1,6 @@
1
  """Various utilities (logger, time benchmark, args dump, numerical and stats info)"""
 
 
2
 
3
 
4
  def _prepare_base64_input(sb):
@@ -52,3 +54,38 @@ def base64_encode(sb: str or bytes) -> bytes:
52
 
53
  sb_bytes = _prepare_base64_input(sb)
54
  return base64.b64encode(sb_bytes)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """Various utilities (logger, time benchmark, args dump, numerical and stats info)"""
2
+ from src import app_logger
3
+ from src.utilities.serialize import serialize
4
 
5
 
6
  def _prepare_base64_input(sb):
 
54
 
55
  sb_bytes = _prepare_base64_input(sb)
56
  return base64.b64encode(sb_bytes)
57
+
58
+
59
+ def hash_calculate(arr: any) -> str or bytes:
60
+ """
61
+ Return computed hash from input variable (typically a numpy array).
62
+
63
+ Args:
64
+ arr: input variable
65
+
66
+ Returns:
67
+ str or bytes: computed hash from input variable
68
+ """
69
+ import hashlib
70
+ import numpy as np
71
+ from base64 import b64encode
72
+
73
+ if isinstance(arr, np.ndarray):
74
+ hash_fn = hashlib.sha256(arr.data)
75
+ elif isinstance(arr, dict):
76
+ import json
77
+
78
+ serialized = serialize(arr)
79
+ variable_to_hash = json.dumps(serialized, sort_keys=True).encode('utf-8')
80
+ hash_fn = hashlib.sha256(variable_to_hash)
81
+ elif isinstance(arr, str):
82
+ try:
83
+ hash_fn = hashlib.sha256(arr)
84
+ except TypeError:
85
+ app_logger.warning(f"TypeError, re-try encoding arg:{arr},type:{type(arr)}.")
86
+ hash_fn = hashlib.sha256(arr.encode('utf-8'))
87
+ elif isinstance(arr, bytes):
88
+ hash_fn = hashlib.sha256(arr)
89
+ else:
90
+ raise ValueError(f"variable 'arr':{arr} not yet handled.")
91
+ return b64encode(hash_fn.digest())
tests/events/geotiff/10/553/394.tif ADDED
tests/events/geotiff/10/553/395.tif ADDED
tests/events/geotiff/10/553/396.tif ADDED
tests/events/geotiff/10/554/394.tif ADDED
tests/events/geotiff/10/554/395.tif ADDED
tests/events/geotiff/10/554/396.tif ADDED
tests/events/geotiff/10/555/394.tif ADDED
tests/events/geotiff/10/555/395.tif ADDED
tests/events/geotiff/10/555/396.tif ADDED
tests/io/test_tms2geotiff.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import unittest
2
+
3
+ import numpy as np
4
+
5
+ from src import app_logger
6
+ from src.io.tms2geotiff import download_extent
7
+ from src.utilities.utilities import hash_calculate
8
+ from tests import TEST_EVENTS_FOLDER
9
+
10
+
11
+ tile_source_url = "http://localhost:8000/geotiff/{z}/{x}/{y}.tif"
12
+ input_bbox = [[38.03932961278458, 15.36808069832851], [37.455509218936974, 14.632807441554068]]
13
+
14
+
15
+ class TestTms2geotiff(unittest.TestCase):
16
+ from contextlib import contextmanager
17
+
18
+ @staticmethod
19
+ @contextmanager
20
+ def http_server(host: str, port: int, directory: str):
21
+ """Function http_server defined within this test class to avoid pytest error "fixture 'host' not found"."""
22
+ from functools import partial
23
+ from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
24
+ from threading import Thread
25
+
26
+ server = ThreadingHTTPServer(
27
+ (host, port), partial(SimpleHTTPRequestHandler, directory=directory)
28
+ )
29
+ server_thread = Thread(target=server.serve_forever, name="http_server")
30
+ server_thread.start()
31
+ print(f"listen:: host {host}, port {port}.")
32
+
33
+ try:
34
+ yield
35
+ finally:
36
+ server.shutdown()
37
+ server_thread.join()
38
+
39
+ def test_download_extent(self):
40
+ listen_port = 8000
41
+
42
+ with self.http_server("localhost", listen_port, directory=TEST_EVENTS_FOLDER):
43
+ pt0, pt1 = input_bbox
44
+ zoom = 10
45
+ img, matrix = download_extent(
46
+ source=tile_source_url, lat0=pt0[0], lon0=pt0[1], lat1=pt1[0], lon1=pt1[1], zoom=zoom
47
+ )
48
+ app_logger.info("# DOWNLOAD ENDED! #")
49
+ np_img = np.array(img)
50
+ output_hash = hash_calculate(np_img)
51
+ assert output_hash == b'LJNhEuMMp2nRclFJfF6oM3iMVbnZnWDmZqWzrs3T4Hs='
52
+
53
+ def test_download_extent_io_error1(self):
54
+
55
+ with self.assertRaises(IOError):
56
+ try:
57
+ pt0, pt1 = input_bbox
58
+ zoom = 10
59
+ download_extent(
60
+ source=tile_source_url, lat0=pt0[0], lon0=pt0[1], lat1=pt1[0], lon1=pt1[1], zoom=zoom
61
+ )
62
+ except IOError as ioe1:
63
+ app_logger.error(f"ioe1:{ioe1}.")
64
+ msg0 = "HTTPConnectionPool(host='localhost', port=8000): Max retries exceeded with url: /geotiff/"
65
+ msg1 = "Caused by NewConnectionError"
66
+ msg2 = ": Failed to establish a new connection: [Errno 61] Connection refused'))"
67
+ assert msg0 in str(ioe1)
68
+ assert msg1 in str(ioe1)
69
+ assert msg2 in str(ioe1)
70
+ raise ioe1
71
+
72
+ def test_download_extent_io_error2(self):
73
+ listen_port = 8000
74
+ with self.http_server("localhost", listen_port, directory=TEST_EVENTS_FOLDER):
75
+ pt0, pt1 = input_bbox
76
+ zoom = 10
77
+
78
+ with self.assertRaises(AttributeError):
79
+ try:
80
+ download_extent(
81
+ source=tile_source_url + "_not_found_raster!",
82
+ lat0=pt0[0], lon0=pt0[1], lat1=pt1[0], lon1=pt1[1], zoom=zoom
83
+ )
84
+ except AttributeError as ae:
85
+ app_logger.error(f"ae:{ae}.")
86
+ assert str(ae) == "'NoneType' object has no attribute 'crop'"
87
+ raise ae
88
+
89
+
90
+ if __name__ == '__main__':
91
+ from tests import TEST_ROOT_FOLDER
92
+
93
+ main_listen_port = 8000
94
+ print("http_basedir_serve:", TEST_ROOT_FOLDER, "#")
95
+ with TestTms2geotiff.http_server("127.0.0.1", main_listen_port, directory=TEST_ROOT_FOLDER):
96
+ pass
97
+ # import time
98
+ # time.sleep(10)
99
+ print("Http server stopped.")