lib-x17-fintech 2.1.3__py3-none-any.whl
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.
- lib_x17_fintech-2.1.3.dist-info/METADATA +633 -0
- lib_x17_fintech-2.1.3.dist-info/RECORD +282 -0
- lib_x17_fintech-2.1.3.dist-info/WHEEL +5 -0
- lib_x17_fintech-2.1.3.dist-info/licenses/LICENSE +1 -0
- lib_x17_fintech-2.1.3.dist-info/top_level.txt +1 -0
- xfintech/__init__.py +0 -0
- xfintech/connect/__init__.py +18 -0
- xfintech/connect/artifact/__init__.py +5 -0
- xfintech/connect/artifact/artifact.py +168 -0
- xfintech/connect/artifact/tests/__init__.py +3 -0
- xfintech/connect/artifact/tests/test_class_artifact_all.py +564 -0
- xfintech/connect/common/__init__.py +12 -0
- xfintech/connect/common/connect.py +49 -0
- xfintech/connect/common/connectref.py +119 -0
- xfintech/connect/common/error.py +62 -0
- xfintech/connect/common/tests/__init__.py +1 -0
- xfintech/connect/common/tests/test_class_connectlike_all.py +544 -0
- xfintech/connect/common/tests/test_class_connectref_all.py +586 -0
- xfintech/connect/common/tests/test_class_errors_all.py +524 -0
- xfintech/connect/instance/__init__.py +7 -0
- xfintech/connect/instance/macos.py +121 -0
- xfintech/connect/instance/s3.py +176 -0
- xfintech/connect/instance/tests/__init__.py +1 -0
- xfintech/connect/instance/tests/test_class_macosconnect_all.py +692 -0
- xfintech/connect/instance/tests/test_class_s3connect_all.py +603 -0
- xfintech/data/__init__.py +20 -0
- xfintech/data/common/__init__.py +15 -0
- xfintech/data/common/cache.py +186 -0
- xfintech/data/common/coolant.py +171 -0
- xfintech/data/common/metric.py +138 -0
- xfintech/data/common/paginate.py +132 -0
- xfintech/data/common/params.py +162 -0
- xfintech/data/common/retry.py +201 -0
- xfintech/data/common/tests/__init__.py +1 -0
- xfintech/data/common/tests/test_class_cache_all.py +681 -0
- xfintech/data/common/tests/test_class_coolant_all.py +534 -0
- xfintech/data/common/tests/test_class_metric_all.py +705 -0
- xfintech/data/common/tests/test_class_paginate_all.py +508 -0
- xfintech/data/common/tests/test_class_params_all.py +891 -0
- xfintech/data/common/tests/test_class_retry_all.py +714 -0
- xfintech/data/job/__init__.py +17 -0
- xfintech/data/job/errors.py +112 -0
- xfintech/data/job/house.py +156 -0
- xfintech/data/job/job.py +247 -0
- xfintech/data/job/joblike.py +47 -0
- xfintech/data/job/tests/__init__.py +1 -0
- xfintech/data/job/tests/test_class_errors_all.py +275 -0
- xfintech/data/job/tests/test_class_house_all.py +801 -0
- xfintech/data/job/tests/test_class_job_all.py +684 -0
- xfintech/data/job/tests/test_class_joblike_all.py +482 -0
- xfintech/data/relay/__init__.py +7 -0
- xfintech/data/relay/client.py +114 -0
- xfintech/data/relay/clientlike.py +45 -0
- xfintech/data/relay/tests/test_class_relayclient_all.py +484 -0
- xfintech/data/relay/tests/test_class_relayclientlike_all.py +500 -0
- xfintech/data/source/__init__.py +7 -0
- xfintech/data/source/baostock/__init__.py +21 -0
- xfintech/data/source/baostock/job/__init__.py +5 -0
- xfintech/data/source/baostock/job/job.py +217 -0
- xfintech/data/source/baostock/job/tests/__init__.py +0 -0
- xfintech/data/source/baostock/job/tests/test_class_baostockjob_all.py +547 -0
- xfintech/data/source/baostock/session/__init__.py +8 -0
- xfintech/data/source/baostock/session/relay.py +223 -0
- xfintech/data/source/baostock/session/session.py +241 -0
- xfintech/data/source/baostock/session/tests/__init__.py +0 -0
- xfintech/data/source/baostock/session/tests/test_class_relay_all.py +694 -0
- xfintech/data/source/baostock/session/tests/test_class_session_all.py +505 -0
- xfintech/data/source/baostock/stock/__init__.py +0 -0
- xfintech/data/source/baostock/stock/hs300stock/__init__.py +3 -0
- xfintech/data/source/baostock/stock/hs300stock/constant.py +49 -0
- xfintech/data/source/baostock/stock/hs300stock/hs300stock.py +133 -0
- xfintech/data/source/baostock/stock/hs300stock/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/hs300stock/tests/test_class_hs300index_all.py +413 -0
- xfintech/data/source/baostock/stock/minuteline/__init__.py +19 -0
- xfintech/data/source/baostock/stock/minuteline/constant.py +89 -0
- xfintech/data/source/baostock/stock/minuteline/minuteline.py +163 -0
- xfintech/data/source/baostock/stock/minuteline/tests/__init__.py +0 -0
- xfintech/data/source/baostock/stock/minuteline/tests/test_class_minuteline_all.py +582 -0
- xfintech/data/source/baostock/stock/stock/__init__.py +19 -0
- xfintech/data/source/baostock/stock/stock/constant.py +55 -0
- xfintech/data/source/baostock/stock/stock/stock.py +149 -0
- xfintech/data/source/baostock/stock/stock/tests/__init__.py +0 -0
- xfintech/data/source/baostock/stock/stock/tests/test_class_stock_all.py +508 -0
- xfintech/data/source/baostock/stock/stockinfo/__init__.py +5 -0
- xfintech/data/source/baostock/stock/stockinfo/constant.py +66 -0
- xfintech/data/source/baostock/stock/stockinfo/stockinfo.py +176 -0
- xfintech/data/source/baostock/stock/stockinfo/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/stockinfo/tests/test_class_stockinfo_all.py +617 -0
- xfintech/data/source/baostock/stock/sz50stock/__init__.py +3 -0
- xfintech/data/source/baostock/stock/sz50stock/constant.py +49 -0
- xfintech/data/source/baostock/stock/sz50stock/sz50stock.py +133 -0
- xfintech/data/source/baostock/stock/sz50stock/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/sz50stock/tests/test_class_sz50stock_all.py +397 -0
- xfintech/data/source/baostock/stock/tradedate/__init__.py +19 -0
- xfintech/data/source/baostock/stock/tradedate/constant.py +72 -0
- xfintech/data/source/baostock/stock/tradedate/tests/__init__.py +0 -0
- xfintech/data/source/baostock/stock/tradedate/tests/test_class_tradedate_all.py +695 -0
- xfintech/data/source/baostock/stock/tradedate/tradedate.py +208 -0
- xfintech/data/source/baostock/stock/zz500stock/__init__.py +3 -0
- xfintech/data/source/baostock/stock/zz500stock/constant.py +55 -0
- xfintech/data/source/baostock/stock/zz500stock/tests/__init__.py +1 -0
- xfintech/data/source/baostock/stock/zz500stock/tests/test_class_zz500stock_all.py +421 -0
- xfintech/data/source/baostock/stock/zz500stock/zz500stock.py +133 -0
- xfintech/data/source/tushare/__init__.py +61 -0
- xfintech/data/source/tushare/job/__init__.py +5 -0
- xfintech/data/source/tushare/job/job.py +257 -0
- xfintech/data/source/tushare/job/tests/test_class_tusharejob_all.py +589 -0
- xfintech/data/source/tushare/session/__init__.py +5 -0
- xfintech/data/source/tushare/session/relay.py +231 -0
- xfintech/data/source/tushare/session/session.py +239 -0
- xfintech/data/source/tushare/session/tests/test_class_relay_all.py +719 -0
- xfintech/data/source/tushare/session/tests/test_class_session_all.py +705 -0
- xfintech/data/source/tushare/stock/__init__.py +55 -0
- xfintech/data/source/tushare/stock/adjfactor/__init__.py +19 -0
- xfintech/data/source/tushare/stock/adjfactor/adjfactor.py +150 -0
- xfintech/data/source/tushare/stock/adjfactor/constant.py +71 -0
- xfintech/data/source/tushare/stock/adjfactor/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/adjfactor/tests/test_class_adjfactor_all.py +372 -0
- xfintech/data/source/tushare/stock/capflow/__init__.py +19 -0
- xfintech/data/source/tushare/stock/capflow/capflow.py +171 -0
- xfintech/data/source/tushare/stock/capflow/constant.py +105 -0
- xfintech/data/source/tushare/stock/capflow/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/capflow/tests/test_class_capflow_all.py +589 -0
- xfintech/data/source/tushare/stock/capflowdc/__init__.py +19 -0
- xfintech/data/source/tushare/stock/capflowdc/capflowdc.py +167 -0
- xfintech/data/source/tushare/stock/capflowdc/constant.py +95 -0
- xfintech/data/source/tushare/stock/capflowdc/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/capflowdc/tests/test_class_capflowdc_all.py +814 -0
- xfintech/data/source/tushare/stock/capflowths/__init__.py +19 -0
- xfintech/data/source/tushare/stock/capflowths/capflowths.py +173 -0
- xfintech/data/source/tushare/stock/capflowths/constant.py +92 -0
- xfintech/data/source/tushare/stock/capflowths/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/capflowths/tests/test_class_capflowths_all.py +551 -0
- xfintech/data/source/tushare/stock/company/__init__.py +19 -0
- xfintech/data/source/tushare/stock/company/company.py +188 -0
- xfintech/data/source/tushare/stock/company/constant.py +92 -0
- xfintech/data/source/tushare/stock/company/tests/__init__.py +1 -0
- xfintech/data/source/tushare/stock/company/tests/test_class_company_all.py +829 -0
- xfintech/data/source/tushare/stock/companybusiness/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companybusiness/companybusiness.py +183 -0
- xfintech/data/source/tushare/stock/companybusiness/constant.py +91 -0
- xfintech/data/source/tushare/stock/companybusiness/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companybusiness/tests/test_class_companybusiness_all.py +633 -0
- xfintech/data/source/tushare/stock/companycashflow/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companycashflow/companycashflow.py +277 -0
- xfintech/data/source/tushare/stock/companycashflow/constant.py +293 -0
- xfintech/data/source/tushare/stock/companycashflow/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companycashflow/tests/test_class_companycashflow_all.py +619 -0
- xfintech/data/source/tushare/stock/companydebt/__init__.py +19 -0
- xfintech/data/source/tushare/stock/companydebt/companydebt.py +339 -0
- xfintech/data/source/tushare/stock/companydebt/constant.py +403 -0
- xfintech/data/source/tushare/stock/companydebt/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companydebt/tests/test_class_companydebt_all.py +655 -0
- xfintech/data/source/tushare/stock/companyoverview/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companyoverview/companyoverview.py +214 -0
- xfintech/data/source/tushare/stock/companyoverview/constant.py +152 -0
- xfintech/data/source/tushare/stock/companyoverview/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companyoverview/tests/test_class_companyoverview_all.py +647 -0
- xfintech/data/source/tushare/stock/companyprofit/__init__.py +21 -0
- xfintech/data/source/tushare/stock/companyprofit/companyprofit.py +272 -0
- xfintech/data/source/tushare/stock/companyprofit/constant.py +259 -0
- xfintech/data/source/tushare/stock/companyprofit/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/companyprofit/tests/test_class_companyprofit_all.py +635 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/__init__.py +21 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/conceptcapflowdc.py +175 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/constant.py +106 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/conceptcapflowdc/tests/test_class_conceptcapflowdc_all.py +568 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/__init__.py +21 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/conceptcapflowths.py +188 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/constant.py +89 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/conceptcapflowths/tests/test_class_conceptcapflowths_all.py +516 -0
- xfintech/data/source/tushare/stock/dayline/__init__.py +19 -0
- xfintech/data/source/tushare/stock/dayline/constant.py +87 -0
- xfintech/data/source/tushare/stock/dayline/dayline.py +177 -0
- xfintech/data/source/tushare/stock/dayline/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/dayline/tests/test_class_dayline_all.py +585 -0
- xfintech/data/source/tushare/stock/industrycapflowths/__init__.py +21 -0
- xfintech/data/source/tushare/stock/industrycapflowths/constant.py +89 -0
- xfintech/data/source/tushare/stock/industrycapflowths/industrycapflowths.py +192 -0
- xfintech/data/source/tushare/stock/industrycapflowths/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/industrycapflowths/tests/test_class_industrycapflowths_all.py +683 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/__init__.py +21 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/constant.py +90 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/marketindexcapflowdc.py +173 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/test_class_marketindexcapflowdc_all.py +793 -0
- xfintech/data/source/tushare/stock/monthline/__init__.py +19 -0
- xfintech/data/source/tushare/stock/monthline/constant.py +87 -0
- xfintech/data/source/tushare/stock/monthline/monthline.py +180 -0
- xfintech/data/source/tushare/stock/monthline/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/monthline/tests/test_class_monthline_all.py +574 -0
- xfintech/data/source/tushare/stock/stock/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stock/constant.py +105 -0
- xfintech/data/source/tushare/stock/stock/stock.py +193 -0
- xfintech/data/source/tushare/stock/stock/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stock/tests/test_class_stock_all.py +788 -0
- xfintech/data/source/tushare/stock/stockdividend/__init__.py +21 -0
- xfintech/data/source/tushare/stock/stockdividend/constant.py +111 -0
- xfintech/data/source/tushare/stock/stockdividend/stockdividend.py +180 -0
- xfintech/data/source/tushare/stock/stockdividend/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockdividend/tests/test_class_stockdividend_all.py +725 -0
- xfintech/data/source/tushare/stock/stockinfo/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockinfo/constant.py +104 -0
- xfintech/data/source/tushare/stock/stockinfo/stockinfo.py +208 -0
- xfintech/data/source/tushare/stock/stockinfo/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockinfo/tests/test_class_stockinfo_all.py +881 -0
- xfintech/data/source/tushare/stock/stockipo/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockipo/constant.py +90 -0
- xfintech/data/source/tushare/stock/stockipo/stockipo.py +234 -0
- xfintech/data/source/tushare/stock/stockipo/tests/__init__.py +1 -0
- xfintech/data/source/tushare/stock/stockipo/tests/test_class_stockipo_all.py +750 -0
- xfintech/data/source/tushare/stock/stockpledge/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockpledge/constant.py +72 -0
- xfintech/data/source/tushare/stock/stockpledge/stockpledge.py +158 -0
- xfintech/data/source/tushare/stock/stockpledge/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockpledge/tests/test_class_stockpledge_all.py +664 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/__init__.py +21 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/constant.py +85 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/stockpledgedetail.py +171 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockpledgedetail/tests/test_class_stockpledgedetail_all.py +112 -0
- xfintech/data/source/tushare/stock/stockst/__init__.py +19 -0
- xfintech/data/source/tushare/stock/stockst/constant.py +80 -0
- xfintech/data/source/tushare/stock/stockst/stockst.py +189 -0
- xfintech/data/source/tushare/stock/stockst/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stockst/tests/test_class_stockst_all.py +693 -0
- xfintech/data/source/tushare/stock/stocksuspend/__init__.py +21 -0
- xfintech/data/source/tushare/stock/stocksuspend/constant.py +75 -0
- xfintech/data/source/tushare/stock/stocksuspend/stocksuspend.py +151 -0
- xfintech/data/source/tushare/stock/stocksuspend/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/stocksuspend/tests/test_class_stocksuspend_all.py +626 -0
- xfintech/data/source/tushare/stock/techindex/__init__.py +19 -0
- xfintech/data/source/tushare/stock/techindex/constant.py +600 -0
- xfintech/data/source/tushare/stock/techindex/techindex.py +314 -0
- xfintech/data/source/tushare/stock/techindex/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/techindex/tests/test_class_techindex_all.py +576 -0
- xfintech/data/source/tushare/stock/tradedate/__init__.py +19 -0
- xfintech/data/source/tushare/stock/tradedate/constant.py +93 -0
- xfintech/data/source/tushare/stock/tradedate/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/tradedate/tests/test_class_tradedate_all.py +947 -0
- xfintech/data/source/tushare/stock/tradedate/tradedate.py +234 -0
- xfintech/data/source/tushare/stock/weekline/__init__.py +19 -0
- xfintech/data/source/tushare/stock/weekline/constant.py +87 -0
- xfintech/data/source/tushare/stock/weekline/tests/__init__.py +0 -0
- xfintech/data/source/tushare/stock/weekline/tests/test_class_weekline_all.py +575 -0
- xfintech/data/source/tushare/stock/weekline/weekline.py +182 -0
- xfintech/fabric/__init__.py +18 -0
- xfintech/fabric/column/__init__.py +7 -0
- xfintech/fabric/column/info.py +202 -0
- xfintech/fabric/column/kind.py +102 -0
- xfintech/fabric/column/tests/__init__.py +0 -0
- xfintech/fabric/column/tests/test_class_info_all.py +207 -0
- xfintech/fabric/column/tests/test_class_kind_all.py +80 -0
- xfintech/fabric/table/__init__.py +5 -0
- xfintech/fabric/table/info.py +263 -0
- xfintech/fabric/table/tests/__init__.py +0 -0
- xfintech/fabric/table/tests/test_class_info_all.py +547 -0
- xfintech/serde/__init__.py +35 -0
- xfintech/serde/common/__init__.py +9 -0
- xfintech/serde/common/dataformat.py +78 -0
- xfintech/serde/common/deserialiserlike.py +38 -0
- xfintech/serde/common/error.py +182 -0
- xfintech/serde/common/serialiserlike.py +38 -0
- xfintech/serde/common/tests/__init__.py +1 -0
- xfintech/serde/common/tests/test_class_dataformat_all.py +694 -0
- xfintech/serde/common/tests/test_class_deserialiserlike_all.py +500 -0
- xfintech/serde/common/tests/test_class_errors_all.py +518 -0
- xfintech/serde/common/tests/test_class_serialiserlike_all.py +401 -0
- xfintech/serde/deserialiser/__init__.py +7 -0
- xfintech/serde/deserialiser/pandas.py +113 -0
- xfintech/serde/deserialiser/python.py +68 -0
- xfintech/serde/deserialiser/tests/__init__.py +1 -0
- xfintech/serde/deserialiser/tests/test_class_pandasdeserialiser_all.py +503 -0
- xfintech/serde/deserialiser/tests/test_class_pythondeserialiser_all.py +570 -0
- xfintech/serde/serialiser/__init__.py +7 -0
- xfintech/serde/serialiser/pandas.py +116 -0
- xfintech/serde/serialiser/python.py +71 -0
- xfintech/serde/serialiser/tests/__init__.py +1 -0
- xfintech/serde/serialiser/tests/test_class_pandasserialiser_all.py +474 -0
- xfintech/serde/serialiser/tests/test_class_pythonserialiser_all.py +508 -0
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from unittest.mock import patch
|
|
3
|
+
|
|
4
|
+
from xfintech.data.common.coolant import Coolant
|
|
5
|
+
|
|
6
|
+
# ==================== Coolant Initialization Tests ====================
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_coolant_init_defaults():
|
|
10
|
+
"""Test Coolant initialization with default values"""
|
|
11
|
+
coolant = Coolant()
|
|
12
|
+
|
|
13
|
+
assert coolant.interval == 0
|
|
14
|
+
assert coolant.use_jitter is False
|
|
15
|
+
assert coolant.jitter_min == 0.0
|
|
16
|
+
assert coolant.jitter_max == 0.0
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_coolant_init_with_interval():
|
|
20
|
+
"""Test Coolant initialization with custom interval"""
|
|
21
|
+
coolant = Coolant(interval=5)
|
|
22
|
+
|
|
23
|
+
assert coolant.interval == 5
|
|
24
|
+
assert coolant.use_jitter is False
|
|
25
|
+
assert coolant.jitter_min == 0.0
|
|
26
|
+
assert coolant.jitter_max == 0.0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_coolant_init_with_jitter():
|
|
30
|
+
"""Test Coolant initialization with jitter enabled"""
|
|
31
|
+
coolant = Coolant(use_jitter=True)
|
|
32
|
+
|
|
33
|
+
assert coolant.interval == 0
|
|
34
|
+
assert coolant.use_jitter is True
|
|
35
|
+
assert coolant.jitter_min == 0.1
|
|
36
|
+
assert coolant.jitter_max == 3.0
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_coolant_init_custom_jitter_range():
|
|
40
|
+
"""Test Coolant initialization with custom jitter range"""
|
|
41
|
+
coolant = Coolant(use_jitter=True, jitter_min=0.5, jitter_max=2.5)
|
|
42
|
+
|
|
43
|
+
assert coolant.use_jitter is True
|
|
44
|
+
assert coolant.jitter_min == 0.5
|
|
45
|
+
assert coolant.jitter_max == 2.5
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_coolant_init_complete():
|
|
49
|
+
"""Test Coolant initialization with all parameters"""
|
|
50
|
+
coolant = Coolant(interval=3, use_jitter=True, jitter_min=0.2, jitter_max=1.5)
|
|
51
|
+
|
|
52
|
+
assert coolant.interval == 3
|
|
53
|
+
assert coolant.use_jitter is True
|
|
54
|
+
assert coolant.jitter_min == 0.2
|
|
55
|
+
assert coolant.jitter_max == 1.5
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_coolant_init_jitter_without_flag():
|
|
59
|
+
"""Test jitter params ignored when use_jitter is False"""
|
|
60
|
+
coolant = Coolant(use_jitter=False, jitter_min=1.0, jitter_max=2.0)
|
|
61
|
+
|
|
62
|
+
assert coolant.use_jitter is False
|
|
63
|
+
assert coolant.jitter_min == 0.0
|
|
64
|
+
assert coolant.jitter_max == 0.0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_coolant_init_interval_zero():
|
|
68
|
+
"""Test Coolant initialization with zero interval"""
|
|
69
|
+
coolant = Coolant(interval=0)
|
|
70
|
+
|
|
71
|
+
assert coolant.interval == 0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_coolant_init_interval_negative():
|
|
75
|
+
"""Test Coolant initialization with negative interval"""
|
|
76
|
+
coolant = Coolant(interval=-5)
|
|
77
|
+
|
|
78
|
+
assert coolant.interval == -5
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# ==================== Class Constants Tests ====================
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_coolant_default_constants():
|
|
85
|
+
"""Test class default constants are set correctly"""
|
|
86
|
+
assert Coolant.DEFAULT_INTERVAL == 0
|
|
87
|
+
assert Coolant.DEFAULT_JITTER_MIN == 0.1
|
|
88
|
+
assert Coolant.DEFAULT_JITTER_MAX == 3.0
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# ==================== Resolve Methods Tests ====================
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_coolant_resolve_interval_with_value():
|
|
95
|
+
"""Test _resolve_interval with explicit value"""
|
|
96
|
+
coolant = Coolant()
|
|
97
|
+
result = coolant._resolve_interval(10)
|
|
98
|
+
|
|
99
|
+
assert result == 10
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_coolant_resolve_interval_none():
|
|
103
|
+
"""Test _resolve_interval with None returns default"""
|
|
104
|
+
coolant = Coolant()
|
|
105
|
+
result = coolant._resolve_interval(None)
|
|
106
|
+
|
|
107
|
+
assert result == Coolant.DEFAULT_INTERVAL
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def test_coolant_resolve_jitter_min_with_jitter_enabled():
|
|
111
|
+
"""Test _resolve_jitter_min with jitter enabled"""
|
|
112
|
+
coolant = Coolant(use_jitter=True)
|
|
113
|
+
result = coolant._resolve_jitter_min(0.5)
|
|
114
|
+
|
|
115
|
+
assert result == 0.5
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_coolant_resolve_jitter_min_with_jitter_disabled():
|
|
119
|
+
"""Test _resolve_jitter_min with jitter disabled"""
|
|
120
|
+
coolant = Coolant(use_jitter=False)
|
|
121
|
+
result = coolant._resolve_jitter_min(0.5)
|
|
122
|
+
|
|
123
|
+
assert result == 0.0
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def test_coolant_resolve_jitter_min_none_with_jitter():
|
|
127
|
+
"""Test _resolve_jitter_min returns default when None and jitter enabled"""
|
|
128
|
+
coolant = Coolant(use_jitter=True)
|
|
129
|
+
result = coolant._resolve_jitter_min(None)
|
|
130
|
+
|
|
131
|
+
assert result == Coolant.DEFAULT_JITTER_MIN
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_coolant_resolve_jitter_max_with_jitter_enabled():
|
|
135
|
+
"""Test _resolve_jitter_max with jitter enabled"""
|
|
136
|
+
coolant = Coolant(use_jitter=True)
|
|
137
|
+
result = coolant._resolve_jitter_max(2.5)
|
|
138
|
+
|
|
139
|
+
assert result == 2.5
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_coolant_resolve_jitter_max_with_jitter_disabled():
|
|
143
|
+
"""Test _resolve_jitter_max with jitter disabled"""
|
|
144
|
+
coolant = Coolant(use_jitter=False)
|
|
145
|
+
result = coolant._resolve_jitter_max(2.5)
|
|
146
|
+
|
|
147
|
+
assert result == 0.0
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_coolant_resolve_jitter_max_none_with_jitter():
|
|
151
|
+
"""Test _resolve_jitter_max returns default when None and jitter enabled"""
|
|
152
|
+
coolant = Coolant(use_jitter=True)
|
|
153
|
+
result = coolant._resolve_jitter_max(None)
|
|
154
|
+
|
|
155
|
+
assert result == Coolant.DEFAULT_JITTER_MAX
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def test_coolant_resolve_jitter_min_int_conversion():
|
|
159
|
+
"""Test _resolve_jitter_min converts int to float"""
|
|
160
|
+
coolant = Coolant(use_jitter=True)
|
|
161
|
+
result = coolant._resolve_jitter_min(1)
|
|
162
|
+
|
|
163
|
+
assert result == 1.0
|
|
164
|
+
assert isinstance(result, float)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_coolant_resolve_jitter_max_int_conversion():
|
|
168
|
+
"""Test _resolve_jitter_max converts int to float"""
|
|
169
|
+
coolant = Coolant(use_jitter=True)
|
|
170
|
+
result = coolant._resolve_jitter_max(3)
|
|
171
|
+
|
|
172
|
+
assert result == 3.0
|
|
173
|
+
assert isinstance(result, float)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# ==================== Jitter Method Tests ====================
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@patch("time.sleep")
|
|
180
|
+
@patch("random.uniform")
|
|
181
|
+
def test_coolant_jitter_enabled(mock_uniform, mock_sleep):
|
|
182
|
+
"""Test jitter() with jitter enabled"""
|
|
183
|
+
mock_uniform.return_value = 1.5
|
|
184
|
+
coolant = Coolant(use_jitter=True, jitter_min=0.5, jitter_max=2.0)
|
|
185
|
+
|
|
186
|
+
coolant.jitter()
|
|
187
|
+
|
|
188
|
+
mock_uniform.assert_called_once_with(0.5, 2.0)
|
|
189
|
+
mock_sleep.assert_called_once_with(1.5)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@patch("time.sleep")
|
|
193
|
+
@patch("random.uniform")
|
|
194
|
+
def test_coolant_jitter_disabled(mock_uniform, mock_sleep):
|
|
195
|
+
"""Test jitter() with jitter disabled does nothing"""
|
|
196
|
+
coolant = Coolant(use_jitter=False)
|
|
197
|
+
|
|
198
|
+
coolant.jitter()
|
|
199
|
+
|
|
200
|
+
mock_uniform.assert_not_called()
|
|
201
|
+
mock_sleep.assert_not_called()
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@patch("time.sleep")
|
|
205
|
+
@patch("random.uniform")
|
|
206
|
+
def test_coolant_jitter_rounding(mock_uniform, mock_sleep):
|
|
207
|
+
"""Test jitter() rounds to 1 decimal place"""
|
|
208
|
+
mock_uniform.return_value = 1.567
|
|
209
|
+
coolant = Coolant(use_jitter=True)
|
|
210
|
+
|
|
211
|
+
coolant.jitter()
|
|
212
|
+
|
|
213
|
+
mock_sleep.assert_called_once_with(1.6)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@patch("time.sleep")
|
|
217
|
+
@patch("random.uniform")
|
|
218
|
+
def test_coolant_jitter_uses_configured_range(mock_uniform, mock_sleep):
|
|
219
|
+
"""Test jitter() uses configured min/max range"""
|
|
220
|
+
mock_uniform.return_value = 0.75
|
|
221
|
+
coolant = Coolant(use_jitter=True, jitter_min=0.3, jitter_max=0.8)
|
|
222
|
+
|
|
223
|
+
coolant.jitter()
|
|
224
|
+
|
|
225
|
+
mock_uniform.assert_called_once_with(0.3, 0.8)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@patch("time.sleep")
|
|
229
|
+
@patch("random.uniform")
|
|
230
|
+
def test_coolant_jitter_default_range(mock_uniform, mock_sleep):
|
|
231
|
+
"""Test jitter() uses default range when not specified"""
|
|
232
|
+
mock_uniform.return_value = 1.0
|
|
233
|
+
coolant = Coolant(use_jitter=True)
|
|
234
|
+
|
|
235
|
+
coolant.jitter()
|
|
236
|
+
|
|
237
|
+
mock_uniform.assert_called_once_with(0.1, 3.0)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
# ==================== Cool Method Tests ====================
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@patch("time.sleep")
|
|
244
|
+
def test_coolant_cool_zero_interval_no_jitter(mock_sleep):
|
|
245
|
+
"""Test cool() with zero interval and no jitter returns immediately"""
|
|
246
|
+
coolant = Coolant(interval=0, use_jitter=False)
|
|
247
|
+
|
|
248
|
+
coolant.cool()
|
|
249
|
+
|
|
250
|
+
mock_sleep.assert_not_called()
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
@patch("time.sleep")
|
|
254
|
+
@patch("random.uniform")
|
|
255
|
+
def test_coolant_cool_zero_interval_with_jitter(mock_uniform, mock_sleep):
|
|
256
|
+
"""Test cool() with zero interval but jitter enabled applies jitter"""
|
|
257
|
+
mock_uniform.return_value = 1.5
|
|
258
|
+
coolant = Coolant(interval=0, use_jitter=True)
|
|
259
|
+
|
|
260
|
+
coolant.cool()
|
|
261
|
+
|
|
262
|
+
# Should only call sleep once for jitter
|
|
263
|
+
assert mock_sleep.call_count == 1
|
|
264
|
+
mock_sleep.assert_called_with(1.5)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
@patch("time.sleep")
|
|
268
|
+
def test_coolant_cool_with_interval_no_jitter(mock_sleep):
|
|
269
|
+
"""Test cool() with interval but no jitter"""
|
|
270
|
+
coolant = Coolant(interval=3, use_jitter=False)
|
|
271
|
+
|
|
272
|
+
coolant.cool()
|
|
273
|
+
|
|
274
|
+
mock_sleep.assert_called_once_with(3)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@patch("time.sleep")
|
|
278
|
+
@patch("random.uniform")
|
|
279
|
+
def test_coolant_cool_with_interval_and_jitter(mock_uniform, mock_sleep):
|
|
280
|
+
"""Test cool() with both interval and jitter"""
|
|
281
|
+
mock_uniform.return_value = 0.5
|
|
282
|
+
coolant = Coolant(interval=2, use_jitter=True, jitter_min=0.1, jitter_max=1.0)
|
|
283
|
+
|
|
284
|
+
coolant.cool()
|
|
285
|
+
|
|
286
|
+
# Should call sleep twice: once for interval, once for jitter
|
|
287
|
+
assert mock_sleep.call_count == 2
|
|
288
|
+
calls = mock_sleep.call_args_list
|
|
289
|
+
assert calls[0][0][0] == 2 # interval
|
|
290
|
+
assert calls[1][0][0] == 0.5 # jitter
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@patch("time.sleep")
|
|
294
|
+
def test_coolant_cool_negative_interval(mock_sleep):
|
|
295
|
+
"""Test cool() with negative interval applies jitter if enabled"""
|
|
296
|
+
coolant = Coolant(interval=-1, use_jitter=False)
|
|
297
|
+
|
|
298
|
+
coolant.cool()
|
|
299
|
+
|
|
300
|
+
# Negative interval treated as <= 0, so should return early
|
|
301
|
+
mock_sleep.assert_not_called()
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@patch("time.sleep")
|
|
305
|
+
def test_coolant_cool_interval_rounding(mock_sleep):
|
|
306
|
+
"""Test cool() rounds interval to 1 decimal place"""
|
|
307
|
+
coolant = Coolant(interval=5, use_jitter=False)
|
|
308
|
+
|
|
309
|
+
coolant.cool()
|
|
310
|
+
|
|
311
|
+
mock_sleep.assert_called_once_with(5)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@patch("time.sleep")
|
|
315
|
+
@patch("random.uniform")
|
|
316
|
+
def test_coolant_cool_order_of_operations(mock_uniform, mock_sleep):
|
|
317
|
+
"""Test cool() applies interval before jitter"""
|
|
318
|
+
mock_uniform.return_value = 0.3
|
|
319
|
+
coolant = Coolant(interval=1, use_jitter=True)
|
|
320
|
+
|
|
321
|
+
coolant.cool()
|
|
322
|
+
|
|
323
|
+
# Verify order: interval sleep, then jitter sleep
|
|
324
|
+
calls = mock_sleep.call_args_list
|
|
325
|
+
assert len(calls) == 2
|
|
326
|
+
assert calls[0][0][0] == 1 # First call is interval
|
|
327
|
+
assert calls[1][0][0] == 0.3 # Second call is jitter
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
# ==================== Integration Tests ====================
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def test_coolant_cool_actual_timing_no_jitter():
|
|
334
|
+
"""Test cool() actually waits for the specified interval"""
|
|
335
|
+
coolant = Coolant(interval=0.1, use_jitter=False)
|
|
336
|
+
|
|
337
|
+
start = time.time()
|
|
338
|
+
coolant.cool()
|
|
339
|
+
elapsed = time.time() - start
|
|
340
|
+
|
|
341
|
+
assert 0.09 <= elapsed <= 0.2 # Allow some tolerance
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def test_coolant_cool_actual_timing_with_jitter():
|
|
345
|
+
"""Test cool() waits for interval plus jitter"""
|
|
346
|
+
coolant = Coolant(interval=0.1, use_jitter=True, jitter_min=0.1, jitter_max=0.2)
|
|
347
|
+
|
|
348
|
+
start = time.time()
|
|
349
|
+
coolant.cool()
|
|
350
|
+
elapsed = time.time() - start
|
|
351
|
+
|
|
352
|
+
# Should be at least interval + jitter_min
|
|
353
|
+
assert elapsed >= 0.19 # 0.1 interval + 0.1 jitter min (with tolerance)
|
|
354
|
+
# Should be at most interval + jitter_max (with some tolerance)
|
|
355
|
+
assert elapsed <= 0.4
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def test_coolant_cool_zero_interval_actual():
|
|
359
|
+
"""Test cool() with zero interval completes quickly"""
|
|
360
|
+
coolant = Coolant(interval=0, use_jitter=False)
|
|
361
|
+
|
|
362
|
+
start = time.time()
|
|
363
|
+
coolant.cool()
|
|
364
|
+
elapsed = time.time() - start
|
|
365
|
+
|
|
366
|
+
assert elapsed < 0.01 # Should be nearly instant
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def test_coolant_multiple_cool_calls():
|
|
370
|
+
"""Test multiple sequential cool() calls"""
|
|
371
|
+
coolant = Coolant(interval=0.05, use_jitter=False)
|
|
372
|
+
|
|
373
|
+
start = time.time()
|
|
374
|
+
coolant.cool()
|
|
375
|
+
coolant.cool()
|
|
376
|
+
coolant.cool()
|
|
377
|
+
elapsed = time.time() - start
|
|
378
|
+
|
|
379
|
+
# 0.05 rounds to 0.1, so 3 * 0.1 = 0.3 seconds
|
|
380
|
+
assert 0.28 <= elapsed <= 0.35
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def test_coolant_reuse():
|
|
384
|
+
"""Test Coolant instance can be reused"""
|
|
385
|
+
coolant = Coolant(interval=0.05, use_jitter=False)
|
|
386
|
+
|
|
387
|
+
# First use
|
|
388
|
+
start = time.time()
|
|
389
|
+
coolant.cool()
|
|
390
|
+
elapsed1 = time.time() - start
|
|
391
|
+
|
|
392
|
+
# Second use
|
|
393
|
+
start = time.time()
|
|
394
|
+
coolant.cool()
|
|
395
|
+
elapsed2 = time.time() - start
|
|
396
|
+
|
|
397
|
+
# 0.05 rounds to 0.1 when sleeping
|
|
398
|
+
assert 0.09 <= elapsed1 <= 0.15
|
|
399
|
+
assert 0.09 <= elapsed2 <= 0.15
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def test_coolant_different_instances():
|
|
403
|
+
"""Test different Coolant instances are independent"""
|
|
404
|
+
coolant1 = Coolant(interval=0.1, use_jitter=False)
|
|
405
|
+
coolant2 = Coolant(interval=0.2, use_jitter=False)
|
|
406
|
+
|
|
407
|
+
start = time.time()
|
|
408
|
+
coolant1.cool()
|
|
409
|
+
elapsed1 = time.time() - start
|
|
410
|
+
|
|
411
|
+
start = time.time()
|
|
412
|
+
coolant2.cool()
|
|
413
|
+
elapsed2 = time.time() - start
|
|
414
|
+
|
|
415
|
+
assert 0.09 <= elapsed1 <= 0.15
|
|
416
|
+
assert 0.19 <= elapsed2 <= 0.25
|
|
417
|
+
assert elapsed2 > elapsed1
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
# ==================== Edge Cases and Special Scenarios ====================
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def test_coolant_jitter_min_equals_max():
|
|
424
|
+
"""Test jitter with min equal to max"""
|
|
425
|
+
coolant = Coolant(use_jitter=True, jitter_min=1.0, jitter_max=1.0)
|
|
426
|
+
|
|
427
|
+
assert coolant.jitter_min == 1.0
|
|
428
|
+
assert coolant.jitter_max == 1.0
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
@patch("time.sleep")
|
|
432
|
+
@patch("random.uniform")
|
|
433
|
+
def test_coolant_jitter_min_equals_max_sleep(mock_uniform, mock_sleep):
|
|
434
|
+
"""Test jitter sleep when min equals max"""
|
|
435
|
+
mock_uniform.return_value = 1.0
|
|
436
|
+
coolant = Coolant(use_jitter=True, jitter_min=1.0, jitter_max=1.0)
|
|
437
|
+
|
|
438
|
+
coolant.jitter()
|
|
439
|
+
|
|
440
|
+
mock_uniform.assert_called_once_with(1.0, 1.0)
|
|
441
|
+
mock_sleep.assert_called_once_with(1.0)
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def test_coolant_very_small_interval():
|
|
445
|
+
"""Test coolant with very small interval"""
|
|
446
|
+
coolant = Coolant(interval=0.01, use_jitter=False)
|
|
447
|
+
|
|
448
|
+
start = time.time()
|
|
449
|
+
coolant.cool()
|
|
450
|
+
elapsed = time.time() - start
|
|
451
|
+
|
|
452
|
+
assert elapsed < 0.05
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def test_coolant_jitter_only():
|
|
456
|
+
"""Test coolant with only jitter, no base interval"""
|
|
457
|
+
coolant = Coolant(interval=0, use_jitter=True, jitter_min=0.05, jitter_max=0.1)
|
|
458
|
+
|
|
459
|
+
start = time.time()
|
|
460
|
+
coolant.cool()
|
|
461
|
+
elapsed = time.time() - start
|
|
462
|
+
|
|
463
|
+
# Should only apply jitter
|
|
464
|
+
assert 0.04 <= elapsed <= 0.15
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
@patch("time.sleep")
|
|
468
|
+
def test_coolant_cool_preserves_state(mock_sleep):
|
|
469
|
+
"""Test cool() doesn't modify instance state"""
|
|
470
|
+
coolant = Coolant(interval=2, use_jitter=True, jitter_min=0.5, jitter_max=1.5)
|
|
471
|
+
|
|
472
|
+
original_interval = coolant.interval
|
|
473
|
+
original_jitter = coolant.use_jitter
|
|
474
|
+
original_min = coolant.jitter_min
|
|
475
|
+
original_max = coolant.jitter_max
|
|
476
|
+
|
|
477
|
+
coolant.cool()
|
|
478
|
+
|
|
479
|
+
assert coolant.interval == original_interval
|
|
480
|
+
assert coolant.use_jitter == original_jitter
|
|
481
|
+
assert coolant.jitter_min == original_min
|
|
482
|
+
assert coolant.jitter_max == original_max
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def test_coolant_rate_limiting_scenario():
|
|
486
|
+
"""Test coolant for rate limiting scenario"""
|
|
487
|
+
coolant = Coolant(interval=0.05, use_jitter=False)
|
|
488
|
+
|
|
489
|
+
operations = []
|
|
490
|
+
start_time = time.time()
|
|
491
|
+
|
|
492
|
+
for i in range(3):
|
|
493
|
+
operations.append(time.time() - start_time)
|
|
494
|
+
if i < 2: # Don't cool after last operation
|
|
495
|
+
coolant.cool()
|
|
496
|
+
|
|
497
|
+
# Check spacing between operations
|
|
498
|
+
assert operations[1] - operations[0] >= 0.04
|
|
499
|
+
assert operations[2] - operations[1] >= 0.04
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def test_coolant_api_throttling_scenario():
|
|
503
|
+
"""Test coolant for API throttling with jitter"""
|
|
504
|
+
coolant = Coolant(interval=0.05, use_jitter=True, jitter_min=0.01, jitter_max=0.05)
|
|
505
|
+
|
|
506
|
+
call_times = []
|
|
507
|
+
start = time.time()
|
|
508
|
+
|
|
509
|
+
for i in range(3):
|
|
510
|
+
call_times.append(time.time() - start)
|
|
511
|
+
if i < 2:
|
|
512
|
+
coolant.cool()
|
|
513
|
+
|
|
514
|
+
# Each gap should be at least interval + jitter_min
|
|
515
|
+
for i in range(1, len(call_times)):
|
|
516
|
+
gap = call_times[i] - call_times[i - 1]
|
|
517
|
+
assert gap >= 0.05 # At least the interval
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
@patch("time.sleep")
|
|
521
|
+
@patch("random.uniform")
|
|
522
|
+
def test_coolant_configuration_independence(mock_uniform, mock_sleep):
|
|
523
|
+
"""Test coolant configuration doesn't affect other instances"""
|
|
524
|
+
mock_uniform.return_value = 0.5
|
|
525
|
+
|
|
526
|
+
coolant1 = Coolant(interval=1, use_jitter=True, jitter_min=0.1, jitter_max=0.5)
|
|
527
|
+
coolant2 = Coolant(interval=2, use_jitter=False)
|
|
528
|
+
|
|
529
|
+
coolant1.cool()
|
|
530
|
+
coolant2.cool()
|
|
531
|
+
|
|
532
|
+
# coolant1 should have interval + jitter
|
|
533
|
+
# coolant2 should only have interval
|
|
534
|
+
assert mock_sleep.call_count == 3 # 1 interval + 1 jitter + 1 interval
|