• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geo-engine / geoengine / 18554766227

16 Oct 2025 08:12AM UTC coverage: 88.843% (+0.3%) from 88.543%
18554766227

push

github

web-flow
build: update dependencies (#1081)

* update sqlfluff

* clippy autofix

* manual clippy fixes

* removal of unused code

* update deps

* upgrade packages

* enable cargo lints

* make sqlfluff happy

* fix chrono parsin error

* clippy

* byte_size

* fix image cmp with tiffs

* remove debug

177 of 205 new or added lines in 38 files covered. (86.34%)

41 existing lines in 20 files now uncovered.

106415 of 119779 relevant lines covered (88.84%)

84190.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.35
/operators/src/engine/execution_context.rs
1
use super::query::QueryAbortRegistration;
2
use super::{
3
    CreateSpan, InitializedPlotOperator, InitializedRasterOperator, InitializedVectorOperator,
4
    MockQueryContext,
5
};
6
use crate::engine::{
7
    ChunkByteSize, RasterResultDescriptor, ResultDescriptor, VectorResultDescriptor,
8
};
9
use crate::error::Error;
10
use crate::machine_learning::MlModelLoadingInfo;
11
use crate::meta::wrapper::InitializedOperatorWrapper;
12
use crate::mock::MockDatasetDataSourceLoadingInfo;
13
use crate::source::{GdalLoadingInfo, OgrSourceDataset};
14
use crate::util::{Result, create_rayon_thread_pool};
15
use async_trait::async_trait;
16
use geoengine_datatypes::dataset::{DataId, NamedData};
17
use geoengine_datatypes::machine_learning::MlModelName;
18
use geoengine_datatypes::primitives::{RasterQueryRectangle, VectorQueryRectangle};
19
use geoengine_datatypes::raster::TilingSpecification;
20
use geoengine_datatypes::util::test::TestDefault;
21
use rayon::ThreadPool;
22
use serde::{Deserialize, Serialize};
23
use std::any::Any;
24
use std::collections::HashMap;
25
use std::fmt::Debug;
26
use std::marker::PhantomData;
27
use std::sync::Arc;
28

29
/// A context that provides certain utility access during operator initialization
30
#[async_trait::async_trait]
31
pub trait ExecutionContext: Send
32
    + Sync
33
    + MetaDataProvider<MockDatasetDataSourceLoadingInfo, VectorResultDescriptor, VectorQueryRectangle>
34
    + MetaDataProvider<OgrSourceDataset, VectorResultDescriptor, VectorQueryRectangle>
35
    + MetaDataProvider<GdalLoadingInfo, RasterResultDescriptor, RasterQueryRectangle>
36
{
37
    fn thread_pool(&self) -> &Arc<ThreadPool>;
38
    fn tiling_specification(&self) -> TilingSpecification;
39

40
    fn wrap_initialized_raster_operator(
41
        &self,
42
        op: Box<dyn InitializedRasterOperator>,
43
        span: CreateSpan,
44
    ) -> Box<dyn InitializedRasterOperator>;
45

46
    fn wrap_initialized_vector_operator(
47
        &self,
48
        op: Box<dyn InitializedVectorOperator>,
49
        span: CreateSpan,
50
    ) -> Box<dyn InitializedVectorOperator>;
51

52
    fn wrap_initialized_plot_operator(
53
        &self,
54
        op: Box<dyn InitializedPlotOperator>,
55
        span: CreateSpan,
56
    ) -> Box<dyn InitializedPlotOperator>;
57

58
    async fn resolve_named_data(&self, data: &NamedData) -> Result<DataId>;
59

60
    async fn ml_model_loading_info(&self, name: &MlModelName) -> Result<MlModelLoadingInfo>;
61
}
62

63
#[async_trait]
64
pub trait MetaDataProvider<L, R, Q>
65
where
66
    R: ResultDescriptor,
67
{
68
    async fn meta_data(&self, id: &DataId) -> Result<Box<dyn MetaData<L, R, Q>>>;
69
}
70

71
#[async_trait]
72
pub trait MetaData<L, R, Q>: Debug + Send + Sync
73
where
74
    R: ResultDescriptor,
75
{
76
    async fn loading_info(&self, query: Q) -> Result<L>;
77
    async fn result_descriptor(&self) -> Result<R>;
78

79
    fn box_clone(&self) -> Box<dyn MetaData<L, R, Q>>;
80
}
81

82
impl<L, R, Q> Clone for Box<dyn MetaData<L, R, Q>>
83
where
84
    R: ResultDescriptor,
85
{
86
    fn clone(&self) -> Box<dyn MetaData<L, R, Q>> {
133✔
87
        self.box_clone()
133✔
88
    }
133✔
89
}
90

91
pub struct MockExecutionContext {
92
    pub thread_pool: Arc<ThreadPool>,
93
    pub meta_data: HashMap<DataId, Box<dyn Any + Send + Sync>>,
94
    pub named_data: HashMap<NamedData, DataId>,
95
    pub ml_models: HashMap<MlModelName, MlModelLoadingInfo>,
96
    pub tiling_specification: TilingSpecification,
97
}
98

99
impl TestDefault for MockExecutionContext {
100
    fn test_default() -> Self {
146✔
101
        Self {
146✔
102
            thread_pool: create_rayon_thread_pool(0),
146✔
103
            meta_data: HashMap::default(),
146✔
104
            named_data: HashMap::default(),
146✔
105
            ml_models: HashMap::default(),
146✔
106
            tiling_specification: TilingSpecification::test_default(),
146✔
107
        }
146✔
108
    }
146✔
109
}
110

111
impl MockExecutionContext {
112
    pub fn new_with_tiling_spec(tiling_specification: TilingSpecification) -> Self {
130✔
113
        Self {
130✔
114
            thread_pool: create_rayon_thread_pool(0),
130✔
115
            meta_data: HashMap::default(),
130✔
116
            named_data: HashMap::default(),
130✔
117
            ml_models: HashMap::default(),
130✔
118
            tiling_specification,
130✔
119
        }
130✔
120
    }
130✔
121

122
    pub fn new_with_tiling_spec_and_thread_count(
×
123
        tiling_specification: TilingSpecification,
×
124
        num_threads: usize,
×
125
    ) -> Self {
×
126
        Self {
×
127
            thread_pool: create_rayon_thread_pool(num_threads),
×
128
            meta_data: HashMap::default(),
×
129
            named_data: HashMap::default(),
×
130
            ml_models: HashMap::default(),
×
131
            tiling_specification,
×
132
        }
×
133
    }
×
134

135
    pub fn add_meta_data<L, R, Q>(
50✔
136
        &mut self,
50✔
137
        data: DataId,
50✔
138
        named_data: NamedData,
50✔
139
        meta_data: Box<dyn MetaData<L, R, Q>>,
50✔
140
    ) where
50✔
141
        L: Send + Sync + 'static,
50✔
142
        R: Send + Sync + 'static + ResultDescriptor,
50✔
143
        Q: Send + Sync + 'static,
50✔
144
    {
145
        self.meta_data.insert(
50✔
146
            data.clone(),
50✔
147
            Box::new(meta_data) as Box<dyn Any + Send + Sync>,
50✔
148
        );
149

150
        self.named_data.insert(named_data, data);
50✔
151
    }
50✔
152

153
    pub fn delete_meta_data(&mut self, named_data: &NamedData) {
2✔
154
        let data = self.named_data.remove(named_data);
2✔
155
        if let Some(data) = data {
2✔
156
            self.meta_data.remove(&data);
2✔
157
        }
2✔
158
    }
2✔
159

160
    pub fn mock_query_context(&self, chunk_byte_size: ChunkByteSize) -> MockQueryContext {
3✔
161
        let (abort_registration, abort_trigger) = QueryAbortRegistration::new();
3✔
162
        MockQueryContext {
3✔
163
            chunk_byte_size,
3✔
164
            thread_pool: self.thread_pool.clone(),
3✔
165
            cache: None,
3✔
166
            quota_checker: None,
3✔
167
            quota_tracking: None,
3✔
168
            abort_registration,
3✔
169
            abort_trigger: Some(abort_trigger),
3✔
170
        }
3✔
171
    }
3✔
172
}
173

174
#[async_trait::async_trait]
175
impl ExecutionContext for MockExecutionContext {
176
    fn thread_pool(&self) -> &Arc<ThreadPool> {
×
177
        &self.thread_pool
×
178
    }
×
179

180
    fn tiling_specification(&self) -> TilingSpecification {
254✔
181
        self.tiling_specification
254✔
182
    }
254✔
183

184
    fn wrap_initialized_raster_operator(
322✔
185
        &self,
322✔
186
        op: Box<dyn InitializedRasterOperator>,
322✔
187
        _span: CreateSpan,
322✔
188
    ) -> Box<dyn InitializedRasterOperator> {
322✔
189
        op
322✔
190
    }
322✔
191

192
    fn wrap_initialized_vector_operator(
168✔
193
        &self,
168✔
194
        op: Box<dyn InitializedVectorOperator>,
168✔
195
        _span: CreateSpan,
168✔
196
    ) -> Box<dyn InitializedVectorOperator> {
168✔
197
        op
168✔
198
    }
168✔
199

200
    fn wrap_initialized_plot_operator(
53✔
201
        &self,
53✔
202
        op: Box<dyn InitializedPlotOperator>,
53✔
203
        _span: CreateSpan,
53✔
204
    ) -> Box<dyn InitializedPlotOperator> {
53✔
205
        op
53✔
206
    }
53✔
207

208
    async fn resolve_named_data(&self, data: &NamedData) -> Result<DataId> {
54✔
209
        self.named_data
210
            .get(data)
211
            .cloned()
UNCOV
212
            .ok_or_else(|| Error::UnknownDatasetName { name: data.clone() })
×
213
    }
54✔
214

215
    async fn ml_model_loading_info(&self, name: &MlModelName) -> Result<MlModelLoadingInfo> {
3✔
216
        self.ml_models
217
            .get(name)
218
            .cloned()
UNCOV
219
            .ok_or_else(|| Error::UnknownMlModelName { name: name.clone() })
×
220
    }
3✔
221
}
222

223
#[async_trait]
224
impl<L, R, Q> MetaDataProvider<L, R, Q> for MockExecutionContext
225
where
226
    L: 'static,
227
    R: 'static + ResultDescriptor,
228
    Q: 'static,
229
{
230
    async fn meta_data(&self, id: &DataId) -> Result<Box<dyn MetaData<L, R, Q>>> {
54✔
231
        let meta_data = self
232
            .meta_data
233
            .get(id)
234
            .ok_or(Error::UnknownDataId)?
235
            .downcast_ref::<Box<dyn MetaData<L, R, Q>>>()
236
            .ok_or(Error::InvalidMetaDataType)?;
237

238
        Ok(meta_data.clone())
239
    }
54✔
240
}
241

242
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
243
#[serde(rename_all = "camelCase")]
244
pub struct StaticMetaData<L, R, Q>
245
where
246
    L: Debug + Clone + Send + Sync + 'static,
247
    R: Debug + Send + Sync + 'static + ResultDescriptor,
248
    Q: Debug + Clone + Send + Sync + 'static,
249
{
250
    pub loading_info: L,
251
    pub result_descriptor: R,
252
    #[serde(skip)]
253
    pub phantom: PhantomData<Q>,
254
}
255

256
#[async_trait]
257
impl<L, R, Q> MetaData<L, R, Q> for StaticMetaData<L, R, Q>
258
where
259
    L: Debug + Clone + Send + Sync + 'static,
260
    R: Debug + Send + Sync + 'static + ResultDescriptor,
261
    Q: Debug + Clone + Send + Sync + 'static,
262
{
263
    async fn loading_info(&self, _query: Q) -> Result<L> {
62✔
264
        Ok(self.loading_info.clone())
265
    }
62✔
266

267
    async fn result_descriptor(&self) -> Result<R> {
38✔
268
        Ok(self.result_descriptor.clone())
269
    }
38✔
270

271
    fn box_clone(&self) -> Box<dyn MetaData<L, R, Q>> {
49✔
272
        Box::new(self.clone())
49✔
273
    }
49✔
274
}
275

276
mod db_types {
277
    use geoengine_datatypes::delegate_from_to_sql;
278
    use postgres_types::{FromSql, ToSql};
279

280
    use super::*;
281

282
    pub type MockMetaData = StaticMetaData<
283
        MockDatasetDataSourceLoadingInfo,
284
        VectorResultDescriptor,
285
        VectorQueryRectangle,
286
    >;
287

288
    #[derive(Debug, ToSql, FromSql)]
×
289
    #[postgres(name = "MockMetaData")]
290
    pub struct MockMetaDataDbType {
291
        pub loading_info: MockDatasetDataSourceLoadingInfo,
292
        pub result_descriptor: VectorResultDescriptor,
293
    }
294

295
    impl From<&MockMetaData> for MockMetaDataDbType {
296
        fn from(other: &MockMetaData) -> Self {
×
297
            Self {
×
298
                loading_info: other.loading_info.clone(),
×
299
                result_descriptor: other.result_descriptor.clone(),
×
300
            }
×
301
        }
×
302
    }
303

304
    impl TryFrom<MockMetaDataDbType> for MockMetaData {
305
        type Error = Error;
306

307
        fn try_from(other: MockMetaDataDbType) -> Result<Self, Self::Error> {
×
308
            Ok(Self {
×
309
                loading_info: other.loading_info,
×
310
                result_descriptor: other.result_descriptor,
×
311
                phantom: PhantomData,
×
312
            })
×
313
        }
×
314
    }
315

316
    pub type OgrMetaData =
317
        StaticMetaData<OgrSourceDataset, VectorResultDescriptor, VectorQueryRectangle>;
318

319
    #[derive(Debug, ToSql, FromSql)]
×
320
    #[postgres(name = "OgrMetaData")]
321
    pub struct OgrMetaDataDbType {
322
        pub loading_info: OgrSourceDataset,
323
        pub result_descriptor: VectorResultDescriptor,
324
    }
325

326
    impl From<&StaticMetaData<OgrSourceDataset, VectorResultDescriptor, VectorQueryRectangle>>
327
        for OgrMetaDataDbType
328
    {
329
        fn from(other: &OgrMetaData) -> Self {
26✔
330
            Self {
26✔
331
                loading_info: other.loading_info.clone(),
26✔
332
                result_descriptor: other.result_descriptor.clone(),
26✔
333
            }
26✔
334
        }
26✔
335
    }
336

337
    impl TryFrom<OgrMetaDataDbType> for OgrMetaData {
338
        type Error = Error;
339

340
        fn try_from(other: OgrMetaDataDbType) -> Result<Self, Self::Error> {
12✔
341
            Ok(Self {
12✔
342
                loading_info: other.loading_info,
12✔
343
                result_descriptor: other.result_descriptor,
12✔
344
                phantom: PhantomData,
12✔
345
            })
12✔
346
        }
12✔
347
    }
348

349
    delegate_from_to_sql!(MockMetaData, MockMetaDataDbType);
350
    delegate_from_to_sql!(OgrMetaData, OgrMetaDataDbType);
351
}
352

353
/// A mock execution context that wraps all operators with a statistics operator.
354
pub struct StatisticsWrappingMockExecutionContext {
355
    pub inner: MockExecutionContext,
356
}
357

358
impl TestDefault for StatisticsWrappingMockExecutionContext {
359
    fn test_default() -> Self {
×
360
        Self {
×
361
            inner: MockExecutionContext::test_default(),
×
362
        }
×
363
    }
×
364
}
365

366
#[async_trait::async_trait]
367
impl ExecutionContext for StatisticsWrappingMockExecutionContext {
368
    fn thread_pool(&self) -> &Arc<ThreadPool> {
×
369
        &self.inner.thread_pool
×
370
    }
×
371

372
    fn tiling_specification(&self) -> TilingSpecification {
×
373
        self.inner.tiling_specification
×
374
    }
×
375

376
    fn wrap_initialized_raster_operator(
×
377
        &self,
×
378
        op: Box<dyn InitializedRasterOperator>,
×
379
        span: CreateSpan,
×
380
    ) -> Box<dyn InitializedRasterOperator> {
×
381
        InitializedOperatorWrapper::new(op, span).boxed()
×
382
    }
×
383

384
    fn wrap_initialized_vector_operator(
×
385
        &self,
×
386
        op: Box<dyn InitializedVectorOperator>,
×
387
        span: CreateSpan,
×
388
    ) -> Box<dyn InitializedVectorOperator> {
×
389
        InitializedOperatorWrapper::new(op, span).boxed()
×
390
    }
×
391

392
    fn wrap_initialized_plot_operator(
×
393
        &self,
×
394
        op: Box<dyn InitializedPlotOperator>,
×
395
        _span: CreateSpan,
×
396
    ) -> Box<dyn InitializedPlotOperator> {
×
397
        op
×
398
    }
×
399

400
    async fn resolve_named_data(&self, data: &NamedData) -> Result<DataId> {
×
401
        self.inner.resolve_named_data(data).await
402
    }
×
403

404
    async fn ml_model_loading_info(&self, name: &MlModelName) -> Result<MlModelLoadingInfo> {
×
405
        self.inner.ml_model_loading_info(name).await
406
    }
×
407
}
408

409
#[async_trait]
410
impl<L, R, Q> MetaDataProvider<L, R, Q> for StatisticsWrappingMockExecutionContext
411
where
412
    L: 'static,
413
    R: 'static + ResultDescriptor,
414
    Q: 'static,
415
{
416
    async fn meta_data(&self, id: &DataId) -> Result<Box<dyn MetaData<L, R, Q>>> {
×
417
        self.inner.meta_data(id).await
418
    }
×
419
}
420

421
#[cfg(test)]
422
mod tests {
423
    use super::*;
424
    use geoengine_datatypes::collections::VectorDataType;
425
    use geoengine_datatypes::spatial_reference::SpatialReferenceOption;
426

427
    #[tokio::test]
428
    async fn test() {
1✔
429
        let info = StaticMetaData {
1✔
430
            loading_info: 1_i32,
1✔
431
            result_descriptor: VectorResultDescriptor {
1✔
432
                data_type: VectorDataType::Data,
1✔
433
                spatial_reference: SpatialReferenceOption::Unreferenced,
1✔
434
                columns: Default::default(),
1✔
435
                time: None,
1✔
436
                bbox: None,
1✔
437
            },
1✔
438
            phantom: Default::default(),
1✔
439
        };
1✔
440

441
        let info: Box<dyn MetaData<i32, VectorResultDescriptor, VectorQueryRectangle>> =
1✔
442
            Box::new(info);
1✔
443

444
        let info2: Box<dyn Any + Send + Sync> = Box::new(info);
1✔
445

446
        let info3 = info2
1✔
447
            .downcast_ref::<Box<dyn MetaData<i32, VectorResultDescriptor, VectorQueryRectangle>>>()
1✔
448
            .unwrap();
1✔
449

450
        assert_eq!(
1✔
451
            info3.result_descriptor().await.unwrap(),
1✔
452
            VectorResultDescriptor {
1✔
453
                data_type: VectorDataType::Data,
1✔
454
                spatial_reference: SpatialReferenceOption::Unreferenced,
1✔
455
                columns: Default::default(),
1✔
456
                time: None,
1✔
457
                bbox: None,
1✔
458
            }
1✔
459
        );
1✔
460
    }
1✔
461
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc