gea-program 0.19.0__tar.gz → 0.20.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gea_program-0.19.0 → gea_program-0.20.0}/PKG-INFO +10 -2
- {gea_program-0.19.0 → gea_program-0.20.0}/README.md +9 -1
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/__init__.py +1 -1
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/__main__.py +22 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/acceptance_tests.py +111 -10
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/blind_harness.py +1 -1
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/client_reports.py +9 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/correlation.py +1 -1
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/TESTER_GUIDE.md +2 -2
- gea_program-0.20.0/gea/help/soak.md +11 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/helplib.py +1 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/service.py +5 -1
- gea_program-0.20.0/gea/soak.py +403 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/survey_cmd.py +12 -10
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/web/app.html +2 -2
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/wits0.py +45 -27
- {gea_program-0.19.0 → gea_program-0.20.0}/gea_program.egg-info/PKG-INFO +10 -2
- {gea_program-0.19.0 → gea_program-0.20.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/pyproject.toml +1 -1
- {gea_program-0.19.0 → gea_program-0.20.0}/LICENSE +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/backup.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/bench.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/certificates.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/cli.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/config_versioning.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/conformance.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/dashboard.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/deviation.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/doctor.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/earth_model.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/etp.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/example_register_map.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/fat_sat.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/files.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/follower.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/forward_model.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/gamma.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/geodesy.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/alarms.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/backup.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/conformance.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/data-in.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/doctor.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/drift.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/etp.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/files.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/instruments.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/month-end.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/notifications.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/osdu.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/patches.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/quality.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/seismic.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/site.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/sites.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/sra.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/start.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/transients.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/vibration.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/housekeeping.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/jobs.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/live_ports.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/loadtest.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/modbus.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/model_card.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/month_end.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/notify.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/opcua_port.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/operator_app.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/osdu.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/patches.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/permits.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/ports.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/ppdm.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/project.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/quakeml.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/reconciler.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/sample_record.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/sbom.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seedlink.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/segy.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_array.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_film.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_response.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_track.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/service_life.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/shell.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/shut_in.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/sla_report.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/sra.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/store_forward.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/strata_join.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/supervisor.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/survey_view.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/telemetry.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/tool_library.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/transient.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/vibration.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/well_assembler.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/witsml.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea/workspace.py +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/setup.cfg +0 -0
- {gea_program-0.19.0 → gea_program-0.20.0}/tests/test_acceptance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gea-program
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -125,7 +125,7 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
|
|
|
125
125
|
gea client-report --report accuracy --out client_report
|
|
126
126
|
gea model-cards --out model_cards
|
|
127
127
|
gea sbom --out sbom
|
|
128
|
-
gea accept # the product gate (
|
|
128
|
+
gea accept # the product gate (347 checks)
|
|
129
129
|
gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
|
|
130
130
|
gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
|
|
131
131
|
gea gui # the desktop window (pip install "gea-program[desktop]")
|
|
@@ -740,6 +740,14 @@ headers on every response, and `gea housekeeping --workspace C:\site --apply`
|
|
|
740
740
|
than truncating them and prunes finished job folders and old recordings. `gea
|
|
741
741
|
loadtest --patches 16 --seconds 60 --with-service` tells you whether the site
|
|
742
742
|
machine carries the patches it will be given, with the page still answering.
|
|
743
|
+
`gea soak --hours 72 --patches 4 --with-service --out C:\site\reports\soak`
|
|
744
|
+
runs the site's patch count, an ETP patch and a SeedLink station through
|
|
745
|
+
link relays that are cut on a schedule, and writes the Soak Report from the
|
|
746
|
+
supervisor's own numbers: seconds to reconnect per source after every
|
|
747
|
+
outage, what each protocol lost while the link was down (WITS0 has no
|
|
748
|
+
replay; SeedLink resumes by sequence number, so its gap count must be
|
|
749
|
+
zero), and the page's answer time through it; Verification runs a 15-minute
|
|
750
|
+
one from the page. `gea help soak`.
|
|
743
751
|
`gea backup --workspace C:\site --out D:\gea-backups --keep 14` copies the
|
|
744
752
|
whole site into one dated archive with a manifest of every file's hash, onto
|
|
745
753
|
another disk or a share; schedule it daily from Audit / Update, verify an
|
|
@@ -86,7 +86,7 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
|
|
|
86
86
|
gea client-report --report accuracy --out client_report
|
|
87
87
|
gea model-cards --out model_cards
|
|
88
88
|
gea sbom --out sbom
|
|
89
|
-
gea accept # the product gate (
|
|
89
|
+
gea accept # the product gate (347 checks)
|
|
90
90
|
gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
|
|
91
91
|
gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
|
|
92
92
|
gea gui # the desktop window (pip install "gea-program[desktop]")
|
|
@@ -701,6 +701,14 @@ headers on every response, and `gea housekeeping --workspace C:\site --apply`
|
|
|
701
701
|
than truncating them and prunes finished job folders and old recordings. `gea
|
|
702
702
|
loadtest --patches 16 --seconds 60 --with-service` tells you whether the site
|
|
703
703
|
machine carries the patches it will be given, with the page still answering.
|
|
704
|
+
`gea soak --hours 72 --patches 4 --with-service --out C:\site\reports\soak`
|
|
705
|
+
runs the site's patch count, an ETP patch and a SeedLink station through
|
|
706
|
+
link relays that are cut on a schedule, and writes the Soak Report from the
|
|
707
|
+
supervisor's own numbers: seconds to reconnect per source after every
|
|
708
|
+
outage, what each protocol lost while the link was down (WITS0 has no
|
|
709
|
+
replay; SeedLink resumes by sequence number, so its gap count must be
|
|
710
|
+
zero), and the page's answer time through it; Verification runs a 15-minute
|
|
711
|
+
one from the page. `gea help soak`.
|
|
704
712
|
`gea backup --workspace C:\site --out D:\gea-backups --keep 14` copies the
|
|
705
713
|
whole site into one dated archive with a manifest of every file's hash, onto
|
|
706
714
|
another disk or a share; schedule it daily from Audit / Update, verify an
|
|
@@ -392,6 +392,19 @@ def main(argv=None) -> int:
|
|
|
392
392
|
p_hk.add_argument("--actor", type=str, default="housekeeping")
|
|
393
393
|
p_hk.add_argument("--json", action="store_true")
|
|
394
394
|
|
|
395
|
+
p_sk = sub.add_parser("soak", help="the patches through link outages for hours, measured: N WITS0 patches, an ETP patch and a SeedLink station through relays that are cut on a schedule; the Soak Report")
|
|
396
|
+
p_sk.add_argument("--hours", type=float, default=None, help="how long (72 for the go-live soak); or --seconds")
|
|
397
|
+
p_sk.add_argument("--seconds", type=float, default=None)
|
|
398
|
+
p_sk.add_argument("--patches", type=int, default=2, help="WITS0 patches (the site's own count)")
|
|
399
|
+
p_sk.add_argument("--no-etp", action="store_true"); p_sk.add_argument("--no-seedlink", action="store_true")
|
|
400
|
+
p_sk.add_argument("--outage-every", type=float, default=600.0, help="seconds between link outages")
|
|
401
|
+
p_sk.add_argument("--outage-len", type=float, default=60.0, help="seconds each outage lasts")
|
|
402
|
+
p_sk.add_argument("--interval", type=float, default=1.0, help="simulator frame interval (s)")
|
|
403
|
+
p_sk.add_argument("--reconnect-budget", type=float, default=90.0, help="seconds a source may take to be back and receiving after the link returns")
|
|
404
|
+
p_sk.add_argument("--with-service", action="store_true", help="also serve the page and time its answers through the outages")
|
|
405
|
+
p_sk.add_argument("--out", type=str, default=None, help="where soak.json and the Soak Report go (default: the throw-away workspace's reports/soak)")
|
|
406
|
+
p_sk.add_argument("--keep", action="store_true", help="keep the throw-away workspace")
|
|
407
|
+
p_sk.add_argument("--json", action="store_true")
|
|
395
408
|
p_lt = sub.add_parser("loadtest", help="how many supervised patches this machine carries: N WITS0 simulators and patches for a while, with the service answering")
|
|
396
409
|
p_lt.add_argument("--patches", type=int, default=8)
|
|
397
410
|
p_lt.add_argument("--seconds", type=float, default=30.0)
|
|
@@ -915,6 +928,15 @@ def main(argv=None) -> int:
|
|
|
915
928
|
for x in r['records_removed'][:20]:
|
|
916
929
|
print(f" record {x['well_id']}/{x['file']} {x['age_days']} d")
|
|
917
930
|
return 0
|
|
931
|
+
elif a.cmd == "soak":
|
|
932
|
+
import json as _json
|
|
933
|
+
from .soak import run as _soak
|
|
934
|
+
secs = a.seconds if a.seconds is not None else (a.hours * 3600.0 if a.hours is not None else 600.0)
|
|
935
|
+
r = _soak(seconds=secs, patches=a.patches, etp=not a.no_etp, seedlink=not a.no_seedlink, outage_every_s=a.outage_every, outage_s=a.outage_len,
|
|
936
|
+
interval_s=a.interval, with_service=a.with_service, keep=a.keep, out_dir=a.out, reconnect_budget_s=a.reconnect_budget, verbose=not a.json)
|
|
937
|
+
if a.json:
|
|
938
|
+
print(_json.dumps({k: v for k, v in r.items() if k != "samples_timeline"}, indent=1, default=str))
|
|
939
|
+
return 0 if r["ok"] else 1
|
|
918
940
|
elif a.cmd == "loadtest":
|
|
919
941
|
import json as _json
|
|
920
942
|
from .loadtest import run as _lt
|
|
@@ -646,7 +646,7 @@ def section_s_correlation() -> None:
|
|
|
646
646
|
and all("continuity" in r["continuity_claim"].lower()
|
|
647
647
|
or r["continuity_claim"] == "TWIN_HOLE_ELIGIBLE"
|
|
648
648
|
for r in df["refused"] + df["ok"])
|
|
649
|
-
and "
|
|
649
|
+
and "census as it stands" in df["finding"],
|
|
650
650
|
"S2 correlation: every cross-site pair carries a continuity claim "
|
|
651
651
|
"bounded by distance, and thin pairs refuse with counts")
|
|
652
652
|
|
|
@@ -767,26 +767,27 @@ def section_y_survey() -> None:
|
|
|
767
767
|
"""Section Y - the one-command user path: gea survey."""
|
|
768
768
|
from .survey_cmd import run_survey
|
|
769
769
|
txt, d = run_survey(demo=True)
|
|
770
|
-
|
|
771
|
-
|
|
770
|
+
from .client_reports import forbidden_terms
|
|
771
|
+
ok('one answer with its provenance' in txt and d['n_stations'] == 65
|
|
772
|
+
and d['exclusions']['washout_or_null_stations'] == 46 and not forbidden_terms(txt),
|
|
772
773
|
"Y1 survey demo: end-to-end on the bundled KTB excerpt - 65 "
|
|
773
|
-
"stations, 46 exclusions DISCLOSED, one readable report")
|
|
774
|
+
"stations, 46 exclusions DISCLOSED, one readable report that passes the same internal-register guard every client report passes")
|
|
774
775
|
ok('vp_m_s' in d and abs(d.get('vp_cross_check_pct', 99)) < 5.0,
|
|
775
776
|
"Y2 survey self-grading: the file carries its own sonic and the "
|
|
776
777
|
"estimate lands within 5 pct of measured (demo: ~+0.7 pct) - the "
|
|
777
778
|
"tool grades itself when the data allows")
|
|
778
|
-
ok('ASSUMPTION' in txt and '
|
|
779
|
-
"Y3 survey
|
|
780
|
-
"it acts and the
|
|
779
|
+
ok('ASSUMPTION' in txt and 'does not call a measurement' in txt,
|
|
780
|
+
"Y3 survey: the prior-family assumption is printed where "
|
|
781
|
+
"it acts and the what-this-tool-does-not-call-a-measurement section is always present")
|
|
781
782
|
import tempfile, os as _os
|
|
782
783
|
with tempfile.TemporaryDirectory() as td:
|
|
783
784
|
f = _os.path.join(td, 'empty.las')
|
|
784
785
|
open(f, 'w').write('~Version\n VERS. 2.0:\n~Well\n~Curve\n'
|
|
785
786
|
'DEPT.M : depth\n~ASCII\n1.0\n2.0\n')
|
|
786
787
|
txt2, d2 = run_survey(path=f)
|
|
787
|
-
ok(d2['refusals'] and '
|
|
788
|
-
"Y4 survey
|
|
789
|
-
"
|
|
788
|
+
ok(d2['refusals'] and 'NOT ESTIMATED' in txt2 and not forbidden_terms(txt2),
|
|
789
|
+
"Y4 survey: a LAS with no density and no gravity gets "
|
|
790
|
+
"NOT ESTIMATED naming the unlocking channel, not an "
|
|
790
791
|
"invented answer")
|
|
791
792
|
|
|
792
793
|
|
|
@@ -5996,6 +5997,105 @@ def section_bm_month_end(tmp: str) -> None:
|
|
|
5996
5997
|
"says the index collects and does not recompute"
|
|
5997
5998
|
+ (f" [failed: {', '.join(failed2)}; cli={r_cli.stdout[-200:]!r} {r_cli.stderr[-200:]!r}]" if failed2 else ""))
|
|
5998
5999
|
|
|
6000
|
+
|
|
6001
|
+
def section_bn_soak(tmp: str) -> None:
|
|
6002
|
+
"""Section BN - the soak: the link relay cuts and restores a connection; the patches, the ETP store and the
|
|
6003
|
+
SeedLink station through relays under scheduled outages, every one back and receiving, SeedLink without a gap,
|
|
6004
|
+
the page answering; the Soak Report; the CLI, the page row, the guard on plain-text deliverables."""
|
|
6005
|
+
import socket as _socket
|
|
6006
|
+
import subprocess as _sp
|
|
6007
|
+
from . import soak as SK
|
|
6008
|
+
from . import helplib as H
|
|
6009
|
+
from .client_reports import forbidden_terms, guard_text
|
|
6010
|
+
pkg = Path(__file__).parent
|
|
6011
|
+
d = Path(tmp, "bn"); d.mkdir()
|
|
6012
|
+
|
|
6013
|
+
# -- the relay alone: bytes through, a cut severs, a restore accepts again on the same port -------------------------
|
|
6014
|
+
echo = _socket.socket(); echo.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1); echo.bind(("127.0.0.1", 0)); echo.listen(4); echo.settimeout(5)
|
|
6015
|
+
eport = echo.getsockname()[1]
|
|
6016
|
+
|
|
6017
|
+
def echo_once():
|
|
6018
|
+
try:
|
|
6019
|
+
c, _ = echo.accept(); c.settimeout(5)
|
|
6020
|
+
while True:
|
|
6021
|
+
b = c.recv(4096)
|
|
6022
|
+
if not b:
|
|
6023
|
+
break
|
|
6024
|
+
c.sendall(b.upper())
|
|
6025
|
+
except OSError:
|
|
6026
|
+
pass
|
|
6027
|
+
threading.Thread(target=echo_once, daemon=True).start()
|
|
6028
|
+
rl = SK.LinkRelay(("127.0.0.1", eport)); rl.start()
|
|
6029
|
+
cl = _socket.create_connection(("127.0.0.1", rl.port), timeout=5); cl.sendall(b"ping"); back = cl.recv(16)
|
|
6030
|
+
rl.cut()
|
|
6031
|
+
severed = False
|
|
6032
|
+
try:
|
|
6033
|
+
cl.settimeout(2); cl.sendall(b"x"); r_ = cl.recv(16); severed = r_ == b""
|
|
6034
|
+
except OSError:
|
|
6035
|
+
severed = True
|
|
6036
|
+
refused = False
|
|
6037
|
+
try:
|
|
6038
|
+
_socket.create_connection(("127.0.0.1", rl.port), timeout=1).close()
|
|
6039
|
+
except OSError:
|
|
6040
|
+
refused = True
|
|
6041
|
+
threading.Thread(target=echo_once, daemon=True).start()
|
|
6042
|
+
rl.restore(); time.sleep(0.3)
|
|
6043
|
+
cl2 = _socket.create_connection(("127.0.0.1", rl.port), timeout=5); cl2.sendall(b"again"); back2 = cl2.recv(16); cl2.close()
|
|
6044
|
+
rl.stop(); echo.close()
|
|
6045
|
+
ok(back == b"PING" and severed and refused and back2 == b"AGAIN" and rl.stats["cuts"] >= 1 and rl.stats["connections"] == 2 and rl.stats["bytes_to_target"] >= 9,
|
|
6046
|
+
"BN1 the link relay: bytes flow both ways to the target; a cut closes the listener and severs every carried connection (a client's next "
|
|
6047
|
+
"read sees the link gone and a new connection is refused); a restore listens again on the same port and carries a new connection")
|
|
6048
|
+
|
|
6049
|
+
# -- the soak itself, short: two WITS0 patches, the ETP store, the SeedLink station, two outages, the page ----------
|
|
6050
|
+
res = SK.run(seconds=75, patches=2, etp=True, seedlink=True, outage_every_s=22, outage_s=5, interval_s=0.5, with_service=True, out_dir=str(d / "out"),
|
|
6051
|
+
reconnect_budget_s=30, verbose=False)
|
|
6052
|
+
per = {p["protocol"]: p for p in res["per_source"]}
|
|
6053
|
+
rep_md = (d / "out" / "soak_report.md").read_text(encoding="utf-8") if (d / "out" / "soak_report.md").exists() else ""
|
|
6054
|
+
c = {
|
|
6055
|
+
"ran_two_outages": len(res["outages"]) >= 2 and all(o["connections_cut"] >= 4 for o in res["outages"]),
|
|
6056
|
+
"every_source_back": all(o["all_back"] for o in res["outages"]) and res["checks"]["every_outage_recovered"],
|
|
6057
|
+
"down_during": all(set(o["down_during"]) >= {"station"} or len(o["down_during"]) >= 1 for o in res["outages"]),
|
|
6058
|
+
"wits0_loss_counted": per["wits0"]["lost"] is not None and per["wits0"]["lost"] >= 1 and ("no replay" in per["wits0"]["resume"] or "gone" in per["wits0"]["resume"]),
|
|
6059
|
+
"etp_no_replay_named": per["etp"]["lost"] is None and "store" in per["etp"]["resume"] and per["etp"]["received"] > 0,
|
|
6060
|
+
"seedlink_resumed": per["seedlink"]["gaps"] == 0 and per["seedlink"]["lost"] == 0 and per["seedlink"]["reconnects"] >= 1 and "sequence" in per["seedlink"]["resume"],
|
|
6061
|
+
"all_connected_at_end": res["checks"]["all_connected_at_end"] and all(p["status"] == "CONNECTED" for p in res["per_source"]),
|
|
6062
|
+
"page_answered": res["service"]["probes_during_outage"] >= 2 and res["checks"]["page_answered_through_outages"],
|
|
6063
|
+
"verdict_ok": res["ok"] and "OK" in res["verdict"] and "no gap" in res["verdict"],
|
|
6064
|
+
"report_written": res.get("report") and os.path.isfile(res["report"]) and "Outages and recovery" in rep_md and "does not call a measurement" in rep_md
|
|
6065
|
+
and not forbidden_terms(rep_md) and os.path.isfile(d / "out" / "soak.json"),
|
|
6066
|
+
}
|
|
6067
|
+
failed = [k for k, v in c.items() if not v]
|
|
6068
|
+
ok(not failed,
|
|
6069
|
+
"BN2 the soak: two WITS0 patches, the ETP store and the SeedLink station through relays, the link cut twice on schedule - every source "
|
|
6070
|
+
"down during the cut and back, CONNECTED and receiving, within the budget after it; WITS0's loss counted as the protocol's own (no replay), "
|
|
6071
|
+
"the ETP store's new session named, SeedLink resumed by sequence number with no gap; the page answered through the outages; all connected "
|
|
6072
|
+
"at the end; the Soak Report written with the outage table and what it does not call a measurement, clean of internal-register terms"
|
|
6073
|
+
+ (f" [failed: {', '.join(failed)}; verdict={res['verdict']!r}; outages={json.dumps(res['outages'], default=str)[:600]}]" if failed else ""))
|
|
6074
|
+
|
|
6075
|
+
# -- the CLI, the page, the help, the guard on plain text -----------------------------------------------------------
|
|
6076
|
+
r_cli = _sp.run([sys.executable, "-m", "gea", "soak", "--seconds", "30", "--patches", "1", "--no-etp", "--no-seedlink", "--outage-every", "10", "--outage-len", "3", "--json"],
|
|
6077
|
+
capture_output=True, text=True)
|
|
6078
|
+
try:
|
|
6079
|
+
cli = json.loads(r_cli.stdout)
|
|
6080
|
+
except ValueError:
|
|
6081
|
+
cli = {}
|
|
6082
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
6083
|
+
help_md = (pkg / "help" / "soak.md").read_text(encoding="utf-8")
|
|
6084
|
+
guard_err = None
|
|
6085
|
+
try:
|
|
6086
|
+
guard_text("a line that calls itself honest", "a test text")
|
|
6087
|
+
except ValueError as e:
|
|
6088
|
+
guard_err = str(e)
|
|
6089
|
+
from .survey_cmd import run_survey
|
|
6090
|
+
txt, _ = run_survey(demo=True)
|
|
6091
|
+
ok(r_cli.returncode == 0 and cli.get("ok") is True and len(cli.get("outages", [])) >= 1 and cli["config"]["patches_wits0"] == 1 and cli["config"]["seedlink"] is False
|
|
6092
|
+
and "data-v=\"soak\"" in page_src and "Soak" in page_src and "172 checks" not in page_src
|
|
6093
|
+
and any(t["topic"] == "soak" for t in H.topics()) and not H.check("soak") and "declared, not observed" in help_md.split("will not call a measurement")[1]
|
|
6094
|
+
and guard_err and "internal-register" in guard_err and not forbidden_terms(txt) and "does not call a measurement" in txt,
|
|
6095
|
+
"BN3 `gea soak --json` runs the schedule and exits 0 on OK; the Verification page carries the soak row and button and no longer names a "
|
|
6096
|
+
"gate count typed by hand; `gea help soak`; `guard_text` is the client-report guard for plain text, and the strata survey's report passes it "
|
|
6097
|
+
"(its closing line and its NOT ESTIMATED section reworded)")
|
|
6098
|
+
|
|
5999
6099
|
def main() -> int:
|
|
6000
6100
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
6001
6101
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -6064,6 +6164,7 @@ def main() -> int:
|
|
|
6064
6164
|
section_bk_seedlink(tmp)
|
|
6065
6165
|
section_bl_backup(tmp)
|
|
6066
6166
|
section_bm_month_end(tmp)
|
|
6167
|
+
section_bn_soak(tmp)
|
|
6067
6168
|
if _FAILS:
|
|
6068
6169
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
6069
6170
|
for f in _FAILS:
|
|
@@ -103,6 +103,6 @@ def accuracy_report() -> Dict:
|
|
|
103
103
|
'worst_mae_pct': (ok[-1]['mae_pct'] if ok else None),
|
|
104
104
|
'median_coverage': (statistics.median(cov) if cov else None),
|
|
105
105
|
'method': ('leave-one-out over the same machinery clients get; '
|
|
106
|
-
'coverage targets ~0.68 (
|
|
106
|
+
'coverage targets ~0.68 (a true 1-sigma); refusals '
|
|
107
107
|
'listed, never hidden; regenerated live so the '
|
|
108
108
|
'accuracy table can never be a stale snapshot')}
|
|
@@ -1784,6 +1784,15 @@ def forbidden_terms(text: str) -> List[str]:
|
|
|
1784
1784
|
return [t for t in FORBIDDEN_TERMS if t in low]
|
|
1785
1785
|
|
|
1786
1786
|
|
|
1787
|
+
def guard_text(text: str, what: str = 'a client deliverable') -> str:
|
|
1788
|
+
"""The guard `write` applies to rendered reports, for any other text the program hands a client - a plain-text
|
|
1789
|
+
report, a printed summary: raise if an internal-register term is in it. Returns the text unchanged."""
|
|
1790
|
+
bad = forbidden_terms(text)
|
|
1791
|
+
if bad:
|
|
1792
|
+
raise ValueError(f'{what} contains internal-register terms: {sorted(set(bad))}')
|
|
1793
|
+
return text
|
|
1794
|
+
|
|
1795
|
+
|
|
1787
1796
|
def write(doc: Document, out_dir: str, basename: str = 'gauge_drift_report') -> dict:
|
|
1788
1797
|
"""Write markdown, HTML, the machine JSON, the records CSV and the tag
|
|
1789
1798
|
catalogue CSV. Returns the paths. Raises if the rendered report contains
|
|
@@ -151,5 +151,5 @@ def depth_frame_pairs(em: EarthModel = None, target_bins: int = TARGET_BINS,
|
|
|
151
151
|
'n_refused': len(refused),
|
|
152
152
|
'finding': ('the library currently supports %d cross-site '
|
|
153
153
|
'depth-frame correlations; %d candidate pairs '
|
|
154
|
-
'refused thin - the
|
|
154
|
+
'refused thin - the census as it stands, not a failure'
|
|
155
155
|
% (len(ok), len(refused)))}
|
|
@@ -57,7 +57,7 @@ BROWSER" below. `verify.cmd` runs the full test from the kit.
|
|
|
57
57
|
|
|
58
58
|
16. In a few seconds a report appears that starts with:
|
|
59
59
|
|
|
60
|
-
GEA SURVEY - one well, one
|
|
60
|
+
GEA SURVEY - one well, one answer with its provenance
|
|
61
61
|
|
|
62
62
|
## PART 5 — YOU'RE DONE. CHECK THESE THREE THINGS:
|
|
63
63
|
|
|
@@ -65,7 +65,7 @@ BROWSER" below. `verify.cmd` runs the full test from the kit.
|
|
|
65
65
|
scientific well, public archive).
|
|
66
66
|
18. Find the line starting with **CROSS-CHECK**. The program checks its own
|
|
67
67
|
answer against the well's real measurement — it should say about **+0.7%**.
|
|
68
|
-
19. Find the section **"what this tool
|
|
68
|
+
19. Find the section **"what this tool does not call a measurement."** That is on
|
|
69
69
|
purpose. This program tells you when it doesn't know something instead
|
|
70
70
|
of making it up.
|
|
71
71
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# The soak
|
|
2
|
+
|
|
3
|
+
> The load test says whether the machine carries the site's patches with the page still answering. The soak says what happens to those patches when the link goes down and comes back, again and again, over hours - how long each protocol takes to reconnect, what it loses while the link is down, whether the resume leaves a gap, whether the page keeps answering - with the supervisor's own numbers, not a model's.
|
|
4
|
+
|
|
5
|
+
**The command**: `gea soak --hours 72 --patches 4 --outage-every 600 --outage-len 60 --with-service --out C:\site\reports\soak` runs N WITS0 patches, an ETP patch and a SeedLink live station through link relays on this machine, cuts every relay for the declared seconds on the declared interval, and writes `soak.json` and the Soak Report into `--out`; `--patches` is the site's own patch count. On the dashboard, Verification -> Soak (15 min) runs a short one as a job at the site's patch count with outages of 20 s every 2 min; the 72-hour run is a command-line job for the machine that will serve the site. `gea help soak`.
|
|
6
|
+
|
|
7
|
+
**What it writes**: per outage - when the link was cut, for how long, how many connections it carried, which sources were down during it, and how many seconds after the link came back each source was CONNECTED and receiving again (or NOT BACK within the budget); per source - received, produced, lost (WITS0's frames sent while the link was down, which the protocol does not replay), gaps (SeedLink's, which must be zero: the resume by sequence number is the proof), reconnection attempts, latency p95, and how the protocol resumes; the page's answer time outside and during the outages when `--with-service`; the checks - all connected at the start and at the end, every outage recovered within the budget, no SeedLink gap, the page answering - and the verdict.
|
|
8
|
+
|
|
9
|
+
**The number to check**: `every source back within N s`, with N under the budget; `SeedLink resumed with no gap`; the page p95 during outages under a second; `OK`.
|
|
10
|
+
|
|
11
|
+
**What this page will not call a measurement**: the field link - these are relays on the loopback and the outage lengths were declared, not observed. A protocol's loss recovered - WITS0 and ETP frames sent while the link was down are gone by the protocol's nature; they are counted, never recovered, and the store-and-forward buffer the Data Resilience report models is the answer to that, not this soak. A soak shorter than asked - the summary says how long it ran. A site's real patch count - run it at the number the site will carry.
|
|
@@ -50,6 +50,7 @@ INDEX: List[tuple] = [
|
|
|
50
50
|
('backup', 'The backup', 'the site copied off the machine, verified, and restored once before it is trusted'),
|
|
51
51
|
('doctor', 'Which code is running', 'gea doctor and the serve start-up gate'),
|
|
52
52
|
('audit-update', 'Audit / Update', 'the whole audit log with filters, the program against PyPI, every report against its source'),
|
|
53
|
+
('soak', 'The soak', 'the patches through link outages for hours: reconnection, resume, loss by protocol, the page answering - measured, not modelled'),
|
|
53
54
|
('upkeep', 'Upkeep', 'housekeeping, sessions, the TLS proxy, the load test'),
|
|
54
55
|
]
|
|
55
56
|
# the four lines every page must carry, in this order
|
|
@@ -75,7 +75,7 @@ PBKDF2_ROUNDS = 200_000
|
|
|
75
75
|
# Commands the page may run as jobs. Anything else is refused (never `serve`, never a shell).
|
|
76
76
|
RUNNABLE = ('accept', 'fat-sat', 'sbom', 'permits', 'sla-report', 'model-cards', 'client-report', 'dashboard', 'workspace', 'drift-monitor',
|
|
77
77
|
'well-test', 'alarms', 'notify', 'swaps', 'certificates', 'transient', 'housekeeping', 'store-forward', 'config', 'reconcile', 'ingest', 'opcua', 'mqtt', 'report', 'gamma', 'bench',
|
|
78
|
-
'service-life', 'telemetry', 'run', 'wells', 'survey', 'wits0', 'witsml', 'wits0-sim', 'etp', 'etp-sim', 'files', 'doctor', 'update', 'backup')
|
|
78
|
+
'service-life', 'telemetry', 'run', 'wells', 'survey', 'wits0', 'witsml', 'wits0-sim', 'etp', 'etp-sim', 'files', 'doctor', 'update', 'backup', 'soak')
|
|
79
79
|
WEB_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'web')
|
|
80
80
|
|
|
81
81
|
|
|
@@ -1375,6 +1375,10 @@ class App:
|
|
|
1375
1375
|
return self._job(['fat-sat', '--kind', 'SAT', '--out', os.path.join(self.ws.reports_dir)], user, 'SAT protocol')
|
|
1376
1376
|
if what == 'sbom':
|
|
1377
1377
|
return self._job(['sbom', '--out', self.ws.reports_dir], user, 'SBOM')
|
|
1378
|
+
if what == 'soak':
|
|
1379
|
+
n = max(1, len(self.patches.store.list())) # the site's own patch count, never fewer than one
|
|
1380
|
+
return self._job(['soak', '--patches', str(n), '--seconds', '900', '--outage-every', '120', '--outage-len', '20', '--with-service',
|
|
1381
|
+
'--out', os.path.join(self.ws.reports_dir, 'soak')], user, f'soak: {n} patch(es) through link outages for 15 min')
|
|
1378
1382
|
if what == 'standalone':
|
|
1379
1383
|
tool = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'tools', 'standalone_check.py')
|
|
1380
1384
|
if not os.path.isfile(tool):
|