From 443f61d496cf112be3d21faf1918a751eced0ee0 Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Fri, 15 Apr 2022 11:37:24 -0400 Subject: [PATCH 1/7] Replace pytest-aiohttp dependency with pytest-asyncio. --- api/Pipfile | 2 +- api/Pipfile.lock | 440 ++++++++--------------------------------------- 2 files changed, 71 insertions(+), 371 deletions(-) diff --git a/api/Pipfile b/api/Pipfile index bcd6efb7cb5..5afcd36027e 100755 --- a/api/Pipfile +++ b/api/Pipfile @@ -13,7 +13,7 @@ coverage = "==5.1" mypy = "==0.910" numpydoc = "==0.9.1" pytest = "==7.0.1" -pytest-aiohttp = "==0.3.0" +pytest-asyncio = "~=0.18" pytest-cov = "==2.10.1" pytest-lazy-fixture = "==0.6.3" pytest-xdist = "~=2.2.1" diff --git a/api/Pipfile.lock b/api/Pipfile.lock index 3b8fc6b433f..dc2d98f5be7 100644 --- a/api/Pipfile.lock +++ b/api/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "38c2ad464885d93f11a04e036599733fccf09f9035b6cb54ce06173cce79001a" + "sha256": "8e2f73e3017d5fa3148522a7515a13cc54df65fb85469ba584966a065e363563" }, "pipfile-spec": 6, "requires": {}, @@ -17,89 +17,11 @@ "develop": { "aenum": { "hashes": [ - "sha256:07ea89f43d78b3d5997b32b8d5b0ec3e5be17b3e05b7bac0154b8c484a4aeff5", - "sha256:859fe994719e6b5e39f15f73acd84e08b4e57dc642373b177a5fa6646798706a", - "sha256:8dbe15f446eb8264b788dfeca163fb0a043d408d212152397dc11377b851e4ae" - ], - "version": "==3.1.8" - }, - "aiohttp": { - "hashes": [ - "sha256:01d7bdb774a9acc838e6b8f1d114f45303841b89b95984cbb7d80ea41172a9e3", - "sha256:03a6d5349c9ee8f79ab3ff3694d6ce1cfc3ced1c9d36200cb8f08ba06bd3b782", - "sha256:04d48b8ce6ab3cf2097b1855e1505181bdd05586ca275f2505514a6e274e8e75", - "sha256:0770e2806a30e744b4e21c9d73b7bee18a1cfa3c47991ee2e5a65b887c49d5cf", - "sha256:07b05cd3305e8a73112103c834e91cd27ce5b4bd07850c4b4dbd1877d3f45be7", - "sha256:086f92daf51a032d062ec5f58af5ca6a44d082c35299c96376a41cbb33034675", - "sha256:099ebd2c37ac74cce10a3527d2b49af80243e2a4fa39e7bce41617fbc35fa3c1", - "sha256:0c7ebbbde809ff4e970824b2b6cb7e4222be6b95a296e46c03cf050878fc1785", - "sha256:102e487eeb82afac440581e5d7f8f44560b36cf0bdd11abc51a46c1cd88914d4", - "sha256:11691cf4dc5b94236ccc609b70fec991234e7ef8d4c02dd0c9668d1e486f5abf", - "sha256:11a67c0d562e07067c4e86bffc1553f2cf5b664d6111c894671b2b8712f3aba5", - "sha256:12de6add4038df8f72fac606dff775791a60f113a725c960f2bab01d8b8e6b15", - "sha256:13487abd2f761d4be7c8ff9080de2671e53fff69711d46de703c310c4c9317ca", - "sha256:15b09b06dae900777833fe7fc4b4aa426556ce95847a3e8d7548e2d19e34edb8", - "sha256:1c182cb873bc91b411e184dab7a2b664d4fea2743df0e4d57402f7f3fa644bac", - "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8", - "sha256:28d490af82bc6b7ce53ff31337a18a10498303fe66f701ab65ef27e143c3b0ef", - "sha256:2e5d962cf7e1d426aa0e528a7e198658cdc8aa4fe87f781d039ad75dcd52c516", - "sha256:2ed076098b171573161eb146afcb9129b5ff63308960aeca4b676d9d3c35e700", - "sha256:2f2f69dca064926e79997f45b2f34e202b320fd3782f17a91941f7eb85502ee2", - "sha256:31560d268ff62143e92423ef183680b9829b1b482c011713ae941997921eebc8", - "sha256:31d1e1c0dbf19ebccbfd62eff461518dcb1e307b195e93bba60c965a4dcf1ba0", - "sha256:37951ad2f4a6df6506750a23f7cbabad24c73c65f23f72e95897bb2cecbae676", - "sha256:3af642b43ce56c24d063325dd2cf20ee012d2b9ba4c3c008755a301aaea720ad", - "sha256:44db35a9e15d6fe5c40d74952e803b1d96e964f683b5a78c3cc64eb177878155", - "sha256:473d93d4450880fe278696549f2e7aed8cd23708c3c1997981464475f32137db", - "sha256:477c3ea0ba410b2b56b7efb072c36fa91b1e6fc331761798fa3f28bb224830dd", - "sha256:4a4a4e30bf1edcad13fb0804300557aedd07a92cabc74382fdd0ba6ca2661091", - "sha256:4aed991a28ea3ce320dc8ce655875e1e00a11bdd29fe9444dd4f88c30d558602", - "sha256:51467000f3647d519272392f484126aa716f747859794ac9924a7aafa86cd411", - "sha256:55c3d1072704d27401c92339144d199d9de7b52627f724a949fc7d5fc56d8b93", - "sha256:589c72667a5febd36f1315aa6e5f56dd4aa4862df295cb51c769d16142ddd7cd", - "sha256:5bfde62d1d2641a1f5173b8c8c2d96ceb4854f54a44c23102e2ccc7e02f003ec", - "sha256:5c23b1ad869653bc818e972b7a3a79852d0e494e9ab7e1a701a3decc49c20d51", - "sha256:61bfc23df345d8c9716d03717c2ed5e27374e0fe6f659ea64edcd27b4b044cf7", - "sha256:6ae828d3a003f03ae31915c31fa684b9890ea44c9c989056fea96e3d12a9fa17", - "sha256:6c7cefb4b0640703eb1069835c02486669312bf2f12b48a748e0a7756d0de33d", - "sha256:6d69f36d445c45cda7b3b26afef2fc34ef5ac0cdc75584a87ef307ee3c8c6d00", - "sha256:6f0d5f33feb5f69ddd57a4a4bd3d56c719a141080b445cbf18f238973c5c9923", - "sha256:6f8b01295e26c68b3a1b90efb7a89029110d3a4139270b24fda961893216c440", - "sha256:713ac174a629d39b7c6a3aa757b337599798da4c1157114a314e4e391cd28e32", - "sha256:718626a174e7e467f0558954f94af117b7d4695d48eb980146016afa4b580b2e", - "sha256:7187a76598bdb895af0adbd2fb7474d7f6025d170bc0a1130242da817ce9e7d1", - "sha256:71927042ed6365a09a98a6377501af5c9f0a4d38083652bcd2281a06a5976724", - "sha256:7d08744e9bae2ca9c382581f7dce1273fe3c9bae94ff572c3626e8da5b193c6a", - "sha256:7dadf3c307b31e0e61689cbf9e06be7a867c563d5a63ce9dca578f956609abf8", - "sha256:81e3d8c34c623ca4e36c46524a3530e99c0bc95ed068fd6e9b55cb721d408fb2", - "sha256:844a9b460871ee0a0b0b68a64890dae9c415e513db0f4a7e3cab41a0f2fedf33", - "sha256:8b7ef7cbd4fec9a1e811a5de813311ed4f7ac7d93e0fda233c9b3e1428f7dd7b", - "sha256:97ef77eb6b044134c0b3a96e16abcb05ecce892965a2124c566af0fd60f717e2", - "sha256:99b5eeae8e019e7aad8af8bb314fb908dd2e028b3cdaad87ec05095394cce632", - "sha256:a25fa703a527158aaf10dafd956f7d42ac6d30ec80e9a70846253dd13e2f067b", - "sha256:a2f635ce61a89c5732537a7896b6319a8fcfa23ba09bec36e1b1ac0ab31270d2", - "sha256:a79004bb58748f31ae1cbe9fa891054baaa46fb106c2dc7af9f8e3304dc30316", - "sha256:a996d01ca39b8dfe77440f3cd600825d05841088fd6bc0144cc6c2ec14cc5f74", - "sha256:b0e20cddbd676ab8a64c774fefa0ad787cc506afd844de95da56060348021e96", - "sha256:b6613280ccedf24354406caf785db748bebbddcf31408b20c0b48cb86af76866", - "sha256:b9d00268fcb9f66fbcc7cd9fe423741d90c75ee029a1d15c09b22d23253c0a44", - "sha256:bb01ba6b0d3f6c68b89fce7305080145d4877ad3acaed424bae4d4ee75faa950", - "sha256:c2aef4703f1f2ddc6df17519885dbfa3514929149d3ff900b73f45998f2532fa", - "sha256:c34dc4958b232ef6188c4318cb7b2c2d80521c9a56c52449f8f93ab7bc2a8a1c", - "sha256:c3630c3ef435c0a7c549ba170a0633a56e92629aeed0e707fec832dee313fb7a", - "sha256:c3d6a4d0619e09dcd61021debf7059955c2004fa29f48788a3dfaf9c9901a7cd", - "sha256:d15367ce87c8e9e09b0f989bfd72dc641bcd04ba091c68cd305312d00962addd", - "sha256:d2f9b69293c33aaa53d923032fe227feac867f81682f002ce33ffae978f0a9a9", - "sha256:e999f2d0e12eea01caeecb17b653f3713d758f6dcc770417cf29ef08d3931421", - "sha256:ea302f34477fda3f85560a06d9ebdc7fa41e82420e892fc50b577e35fc6a50b2", - "sha256:eaba923151d9deea315be1f3e2b31cc39a6d1d2f682f942905951f4e40200922", - "sha256:ef9612483cb35171d51d9173647eed5d0069eaa2ee812793a75373447d487aa4", - "sha256:f5315a2eb0239185af1bddb1abf472d877fede3cc8d143c6cddad37678293237", - "sha256:fa0ffcace9b3aa34d205d8130f7873fcfefcb6a4dd3dd705b0dab69af6712642", - "sha256:fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578" + "sha256:3044126aa854afc5fb04ee4a6740b6b7506db01004fea0e39e09ac8508d81503", + "sha256:e47aa190d7ac36dfc39b05b4b15b3275937d068d3a6cef2accabd831f6dde8f7", + "sha256:f46db857e334b6ad26567db23c2173ce184d64cd208226c4c0289faefa3219cc" ], - "markers": "python_version >= '3.6'", - "version": "==3.8.1" + "version": "==3.1.9" }, "aionotify": { "hashes": [ @@ -108,14 +30,6 @@ ], "version": "==0.2.0" }, - "aiosignal": { - "hashes": [ - "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a", - "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2" - ], - "markers": "python_version >= '3.6'", - "version": "==1.2.0" - }, "alabaster": { "hashes": [ "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", @@ -131,22 +45,6 @@ "markers": "python_full_version >= '3.6.2'", "version": "==3.3.0" }, - "async-timeout": { - "hashes": [ - "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", - "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" - ], - "markers": "python_version >= '3.6'", - "version": "==4.0.2" - }, - "asynctest": { - "hashes": [ - "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676", - "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac" - ], - "markers": "python_version < '3.8'", - "version": "==0.13.0" - }, "atomicwrites": { "hashes": [ "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197", @@ -202,11 +100,11 @@ }, "bleach": { "hashes": [ - "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da", - "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994" + "sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1", + "sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565" ], - "markers": "python_version >= '3.6'", - "version": "==4.1.0" + "markers": "python_version >= '3.7'", + "version": "==5.0.0" }, "certifi": { "hashes": [ @@ -225,11 +123,11 @@ }, "click": { "hashes": [ - "sha256:19a4baa64da924c5e0cd889aba8e947f280309f1a2ce0947a3e3a7bcb7cc72d6", - "sha256:977c213473c7665d3aa092b41ff12063227751c41d7b17165013e10069cc5cd2" + "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e", + "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72" ], "markers": "python_version >= '3.7'", - "version": "==8.1.0" + "version": "==8.1.2" }, "colorama": { "hashes": [ @@ -331,77 +229,12 @@ "index": "pypi", "version": "==1.2.1" }, - "frozenlist": { - "hashes": [ - "sha256:006d3595e7d4108a12025ddf415ae0f6c9e736e726a5db0183326fd191b14c5e", - "sha256:01a73627448b1f2145bddb6e6c2259988bb8aee0fb361776ff8604b99616cd08", - "sha256:03a7dd1bfce30216a3f51a84e6dd0e4a573d23ca50f0346634916ff105ba6e6b", - "sha256:0437fe763fb5d4adad1756050cbf855bbb2bf0d9385c7bb13d7a10b0dd550486", - "sha256:04cb491c4b1c051734d41ea2552fde292f5f3a9c911363f74f39c23659c4af78", - "sha256:0c36e78b9509e97042ef869c0e1e6ef6429e55817c12d78245eb915e1cca7468", - "sha256:25af28b560e0c76fa41f550eacb389905633e7ac02d6eb3c09017fa1c8cdfde1", - "sha256:2fdc3cd845e5a1f71a0c3518528bfdbfe2efaf9886d6f49eacc5ee4fd9a10953", - "sha256:30530930410855c451bea83f7b272fb1c495ed9d5cc72895ac29e91279401db3", - "sha256:31977f84828b5bb856ca1eb07bf7e3a34f33a5cddce981d880240ba06639b94d", - "sha256:3c62964192a1c0c30b49f403495911298810bada64e4f03249ca35a33ca0417a", - "sha256:3f7c935c7b58b0d78c0beea0c7358e165f95f1fd8a7e98baa40d22a05b4a8141", - "sha256:40dff8962b8eba91fd3848d857203f0bd704b5f1fa2b3fc9af64901a190bba08", - "sha256:40ec383bc194accba825fbb7d0ef3dda5736ceab2375462f1d8672d9f6b68d07", - "sha256:436496321dad302b8b27ca955364a439ed1f0999311c393dccb243e451ff66aa", - "sha256:4406cfabef8f07b3b3af0f50f70938ec06d9f0fc26cbdeaab431cbc3ca3caeaa", - "sha256:45334234ec30fc4ea677f43171b18a27505bfb2dba9aca4398a62692c0ea8868", - "sha256:47be22dc27ed933d55ee55845d34a3e4e9f6fee93039e7f8ebadb0c2f60d403f", - "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b", - "sha256:4eda49bea3602812518765810af732229b4291d2695ed24a0a20e098c45a707b", - "sha256:57f4d3f03a18facacb2a6bcd21bccd011e3b75d463dc49f838fd699d074fabd1", - "sha256:603b9091bd70fae7be28bdb8aa5c9990f4241aa33abb673390a7f7329296695f", - "sha256:65bc6e2fece04e2145ab6e3c47428d1bbc05aede61ae365b2c1bddd94906e478", - "sha256:691ddf6dc50480ce49f68441f1d16a4c3325887453837036e0fb94736eae1e58", - "sha256:6983a31698490825171be44ffbafeaa930ddf590d3f051e397143a5045513b01", - "sha256:6a202458d1298ced3768f5a7d44301e7c86defac162ace0ab7434c2e961166e8", - "sha256:6eb275c6385dd72594758cbe96c07cdb9bd6becf84235f4a594bdf21e3596c9d", - "sha256:754728d65f1acc61e0f4df784456106e35afb7bf39cfe37227ab00436fb38676", - "sha256:768efd082074bb203c934e83a61654ed4931ef02412c2fbdecea0cff7ecd0274", - "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab", - "sha256:871d42623ae15eb0b0e9df65baeee6976b2e161d0ba93155411d58ff27483ad8", - "sha256:88aafd445a233dbbf8a65a62bc3249a0acd0d81ab18f6feb461cc5a938610d24", - "sha256:8c905a5186d77111f02144fab5b849ab524f1e876a1e75205cd1386a9be4b00a", - "sha256:8cf829bd2e2956066dd4de43fd8ec881d87842a06708c035b37ef632930505a2", - "sha256:92e650bd09b5dda929523b9f8e7f99b24deac61240ecc1a32aeba487afcd970f", - "sha256:93641a51f89473837333b2f8100f3f89795295b858cd4c7d4a1f18e299dc0a4f", - "sha256:94c7a8a9fc9383b52c410a2ec952521906d355d18fccc927fca52ab575ee8b93", - "sha256:9f892d6a94ec5c7b785e548e42722e6f3a52f5f32a8461e82ac3e67a3bd073f1", - "sha256:acb267b09a509c1df5a4ca04140da96016f40d2ed183cdc356d237286c971b51", - "sha256:adac9700675cf99e3615eb6a0eb5e9f5a4143c7d42c05cea2e7f71c27a3d0846", - "sha256:aff388be97ef2677ae185e72dc500d19ecaf31b698986800d3fc4f399a5e30a5", - "sha256:b5009062d78a8c6890d50b4e53b0ddda31841b3935c1937e2ed8c1bda1c7fb9d", - "sha256:b684c68077b84522b5c7eafc1dc735bfa5b341fb011d5552ebe0968e22ed641c", - "sha256:b9e3e9e365991f8cc5f5edc1fd65b58b41d0514a6a7ad95ef5c7f34eb49b3d3e", - "sha256:bd89acd1b8bb4f31b47072615d72e7f53a948d302b7c1d1455e42622de180eae", - "sha256:bde99812f237f79eaf3f04ebffd74f6718bbd216101b35ac7955c2d47c17da02", - "sha256:c6c321dd013e8fc20735b92cb4892c115f5cdb82c817b1e5b07f6b95d952b2f0", - "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b", - "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3", - "sha256:d26b650b71fdc88065b7a21f8ace70175bcf3b5bdba5ea22df4bfd893e795a3b", - "sha256:d6d32ff213aef0fd0bcf803bffe15cfa2d4fde237d1d4838e62aec242a8362fa", - "sha256:e1e26ac0a253a2907d654a37e390904426d5ae5483150ce3adedb35c8c06614a", - "sha256:e30b2f9683812eb30cf3f0a8e9f79f8d590a7999f731cf39f9105a7c4a39489d", - "sha256:e84cb61b0ac40a0c3e0e8b79c575161c5300d1d89e13c0e02f76193982f066ed", - "sha256:e982878792c971cbd60ee510c4ee5bf089a8246226dea1f2138aa0bb67aff148", - "sha256:f20baa05eaa2bcd5404c445ec51aed1c268d62600362dc6cfe04fae34a424bd9", - "sha256:f7353ba3367473d1d616ee727945f439e027f0bb16ac1a750219a8344d1d5d3c", - "sha256:f96293d6f982c58ebebb428c50163d010c2f05de0cde99fd681bfdc18d4b2dc2", - "sha256:ff9310f05b9d9c5c4dd472983dc956901ee6cb2c3ec1ab116ecdde25f3ce4951" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.0" - }, "idna": { "hashes": [ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_version >= '3'", + "markers": "python_version >= '3.5'", "version": "==3.3" }, "imagesize": { @@ -503,71 +336,6 @@ "index": "pypi", "version": "==4.0.3" }, - "multidict": { - "hashes": [ - "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60", - "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c", - "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672", - "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51", - "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032", - "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2", - "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b", - "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80", - "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88", - "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a", - "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d", - "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389", - "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c", - "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9", - "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c", - "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516", - "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b", - "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43", - "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee", - "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227", - "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d", - "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae", - "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7", - "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4", - "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9", - "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f", - "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013", - "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9", - "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e", - "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693", - "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a", - "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15", - "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb", - "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96", - "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87", - "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376", - "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658", - "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0", - "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071", - "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360", - "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc", - "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3", - "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba", - "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8", - "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9", - "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2", - "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3", - "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68", - "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8", - "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d", - "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49", - "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608", - "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57", - "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86", - "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20", - "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293", - "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849", - "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937", - "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d" - ], - "markers": "python_version >= '3.7'", - "version": "==6.0.2" - }, "mypy": { "hashes": [ "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9", @@ -606,39 +374,40 @@ }, "numpy": { "hashes": [ - "sha256:00c9fa73a6989895b8815d98300a20ac993c49ac36c8277e8ffeaa3631c0dbbb", - "sha256:025b497014bc33fc23897859350f284323f32a2fff7654697f5a5fc2a19e9939", - "sha256:08de8472d9f7571f9d51b27b75e827f5296295fa78817032e84464be8bb905bc", - "sha256:1964db2d4a00348b7a60ee9d013c8cb0c566644a589eaa80995126eac3b99ced", - "sha256:2a9add27d7fc0fdb572abc3b2486eb3b1395da71e0254c5552b2aad2a18b5441", - "sha256:2d8adfca843bc46ac199a4645233f13abf2011a0b2f4affc5c37cd552626f27b", - "sha256:301e408a052fdcda5cdcf03021ebafc3c6ea093021bf9d1aa47c54d48bdad166", - "sha256:311283acf880cfcc20369201bd75da907909afc4666966c7895cbed6f9d2c640", - "sha256:341dddcfe3b7b6427a28a27baa59af5ad51baa59bfec3264f1ab287aa3b30b13", - "sha256:3a5098df115340fb17fc93867317a947e1dcd978c3888c5ddb118366095851f8", - "sha256:3c978544be9e04ed12016dd295a74283773149b48f507d69b36f91aa90a643e5", - "sha256:3d893b0871322eaa2f8c7072cdb552d8e2b27645b7875a70833c31e9274d4611", - "sha256:4fe6a006557b87b352c04596a6e3f12a57d6e5f401d804947bd3188e6b0e0e76", - "sha256:507c05c7a37b3683eb08a3ff993bd1ee1e6c752f77c2f275260533b265ecdb6c", - "sha256:58ca1d7c8aef6e996112d0ce873ac9dfa1eaf4a1196b4ff7ff73880a09923ba7", - "sha256:61bada43d494515d5b122f4532af226fdb5ee08fe5b5918b111279843dc6836a", - "sha256:69a5a8d71c308d7ef33ef72371c2388a90e3495dbb7993430e674006f94797d5", - "sha256:6a5928bc6241264dce5ed509e66f33676fc97f464e7a919edc672fb5532221ee", - "sha256:7b9d6b14fc9a4864b08d1ba57d732b248f0e482c7b2ff55c313137e3ed4d8449", - "sha256:a7c4b701ca418cd39e28ec3b496e6388fe06de83f5f0cb74794fa31cfa384c02", - "sha256:a7e8f6216f180f3fd4efb73de5d1eaefb5f5a1ee5b645c67333033e39440e63a", - "sha256:b545ebadaa2b878c8630e5bcdb97fc4096e779f335fc0f943547c1c91540c815", - "sha256:c293d3c0321996cd8ffe84215ffe5d269fd9d1d12c6f4ffe2b597a7c30d3e593", - "sha256:c5562bcc1a9b61960fc8950ade44d00e3de28f891af0acc96307c73613d18f6e", - "sha256:ca9c23848292c6fe0a19d212790e62f398fd9609aaa838859be8459bfbe558aa", - "sha256:cc1b30205d138d1005adb52087ff45708febbef0e420386f58664f984ef56954", - "sha256:dbce7adeb66b895c6aaa1fad796aaefc299ced597f6fbd9ceddb0dd735245354", - "sha256:dc4b2fb01f1b4ddbe2453468ea0719f4dbb1f5caa712c8b21bb3dd1480cd30d9", - "sha256:eed2afaa97ec33b4411995be12f8bdb95c87984eaa28d76cf628970c8a2d689a", - "sha256:fc7a7d7b0ed72589fd8b8486b9b42a564f10b8762be8bd4d9df94b807af4a089" + "sha256:1dbe1c91269f880e364526649a52eff93ac30035507ae980d2fed33aaee633ac", + "sha256:357768c2e4451ac241465157a3e929b265dfac85d9214074985b1786244f2ef3", + "sha256:3820724272f9913b597ccd13a467cc492a0da6b05df26ea09e78b171a0bb9da6", + "sha256:4391bd07606be175aafd267ef9bea87cf1b8210c787666ce82073b05f202add1", + "sha256:4aa48afdce4660b0076a00d80afa54e8a97cd49f457d68a4342d188a09451c1a", + "sha256:58459d3bad03343ac4b1b42ed14d571b8743dc80ccbf27444f266729df1d6f5b", + "sha256:5c3c8def4230e1b959671eb959083661b4a0d2e9af93ee339c7dada6759a9470", + "sha256:5f30427731561ce75d7048ac254dbe47a2ba576229250fb60f0fb74db96501a1", + "sha256:643843bcc1c50526b3a71cd2ee561cf0d8773f062c8cbaf9ffac9fdf573f83ab", + "sha256:67c261d6c0a9981820c3a149d255a76918278a6b03b6a036800359aba1256d46", + "sha256:67f21981ba2f9d7ba9ade60c9e8cbaa8cf8e9ae51673934480e45cf55e953673", + "sha256:6aaf96c7f8cebc220cdfc03f1d5a31952f027dda050e5a703a0d1c396075e3e7", + "sha256:7c4068a8c44014b2d55f3c3f574c376b2494ca9cc73d2f1bd692382b6dffe3db", + "sha256:7c7e5fa88d9ff656e067876e4736379cc962d185d5cd808014a8a928d529ef4e", + "sha256:7f5ae4f304257569ef3b948810816bc87c9146e8c446053539947eedeaa32786", + "sha256:82691fda7c3f77c90e62da69ae60b5ac08e87e775b09813559f8901a88266552", + "sha256:8737609c3bbdd48e380d463134a35ffad3b22dc56295eff6f79fd85bd0eeeb25", + "sha256:9f411b2c3f3d76bba0865b35a425157c5dcf54937f82bbeb3d3c180789dd66a6", + "sha256:a6be4cb0ef3b8c9250c19cc122267263093eee7edd4e3fa75395dfda8c17a8e2", + "sha256:bcb238c9c96c00d3085b264e5c1a1207672577b93fa666c3b14a45240b14123a", + "sha256:bf2ec4b75d0e9356edea834d1de42b31fe11f726a81dfb2c2112bc1eaa508fcf", + "sha256:d136337ae3cc69aa5e447e78d8e1514be8c3ec9b54264e680cf0b4bd9011574f", + "sha256:d4bf4d43077db55589ffc9009c0ba0a94fa4908b9586d6ccce2e0b164c86303c", + "sha256:d6a96eef20f639e6a97d23e57dd0c1b1069a7b4fd7027482a4c5c451cd7732f4", + "sha256:d9caa9d5e682102453d96a0ee10c7241b72859b01a941a397fd965f23b3e016b", + "sha256:dd1c8f6bd65d07d3810b90d02eba7997e32abbdf1277a481d698969e921a3be0", + "sha256:e31f0bb5928b793169b87e3d1e070f2342b22d5245c755e2b81caa29756246c3", + "sha256:ecb55251139706669fdec2ff073c98ef8e9a84473e51e716211b41aa0f18e656", + "sha256:ee5ec40fdd06d62fe5d4084bef4fd50fd4bb6bfd2bf519365f569dc470163ab0", + "sha256:f17e562de9edf691a42ddb1eb4a5541c20dd3f9e65b09ded2beb0799c0cf29bb", + "sha256:fdffbfb6832cd0b300995a2b08b8f6fa9f6e856d562800fea9182316d99c4e8e" ], "markers": "python_version < '3.11' and python_version >= '3.7'", - "version": "==1.21.5" + "version": "==1.21.6" }, "numpydoc": { "hashes": [ @@ -767,11 +536,11 @@ }, "pyparsing": { "hashes": [ - "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea", - "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484" + "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954", + "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06" ], - "markers": "python_version >= '3.6'", - "version": "==3.0.7" + "markers": "python_full_version >= '3.6.8'", + "version": "==3.0.8" }, "pyrsistent": { "hashes": [ @@ -815,13 +584,14 @@ "index": "pypi", "version": "==7.0.1" }, - "pytest-aiohttp": { + "pytest-asyncio": { "hashes": [ - "sha256:0b9b660b146a65e1313e2083d0d2e1f63047797354af9a28d6b7c9f0726fa33d", - "sha256:c929854339637977375838703b62fef63528598bc0a9d451639eba95f4aaa44f" + "sha256:16cf40bdf2b4fb7fc8e4b82bd05ce3fbcd454cbf7b92afc445fe299dabb88213", + "sha256:7659bdb0a9eb9c6e3ef992eef11a2b3e69697800ad02fb06374a210d85b29f91", + "sha256:8fafa6c52161addfd41ee7ab35f11836c5a16ec208f93ee388f752bea3493a84" ], "index": "pypi", - "version": "==0.3.0" + "version": "==0.18.3" }, "pytest-cov": { "hashes": [ @@ -892,6 +662,14 @@ ], "version": "==0.9.1" }, + "setuptools": { + "hashes": [ + "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8", + "sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592" + ], + "markers": "python_version >= '3.7'", + "version": "==62.1.0" + }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -1003,11 +781,11 @@ }, "tqdm": { "hashes": [ - "sha256:4230a49119a416c88cc47d0d2d32d5d90f1a282d5e497d49801950704e49863d", - "sha256:6461b009d6792008d0000e1b0c7ca50195ec78c0e808a3a6b668a56a3236c3a5" + "sha256:40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d", + "sha256:74a2cdefe14d11442cedf3ba4e21a3b84ff9a2dbdc6cfae2c34addb2a14a5ea6" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.63.1" + "version": "==4.64.0" }, "twine": { "hashes": [ @@ -1050,7 +828,7 @@ "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f", "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65" ], - "markers": "python_version < '3.8' and implementation_name == 'cpython'", + "markers": "python_version < '3.8'", "version": "==1.4.3" }, "typeguard": { @@ -1090,7 +868,7 @@ "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4.0'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==1.26.9" }, "webencodings": { @@ -1178,91 +956,13 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.14.0" }, - "yarl": { - "hashes": [ - "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac", - "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8", - "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e", - "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746", - "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98", - "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125", - "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d", - "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d", - "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986", - "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d", - "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec", - "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8", - "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee", - "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3", - "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1", - "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd", - "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b", - "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de", - "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0", - "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8", - "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6", - "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245", - "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23", - "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332", - "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1", - "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c", - "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4", - "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0", - "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8", - "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832", - "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58", - "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6", - "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1", - "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52", - "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92", - "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185", - "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d", - "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d", - "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b", - "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739", - "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05", - "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63", - "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d", - "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa", - "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913", - "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe", - "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b", - "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b", - "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656", - "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1", - "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4", - "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e", - "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63", - "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271", - "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed", - "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d", - "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda", - "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265", - "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f", - "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c", - "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba", - "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c", - "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b", - "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523", - "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a", - "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef", - "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95", - "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72", - "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794", - "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41", - "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576", - "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59" - ], - "markers": "python_version >= '3.6'", - "version": "==1.7.2" - }, "zipp": { "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad", + "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099" ], "markers": "python_version >= '3.7'", - "version": "==3.7.0" + "version": "==3.8.0" } } } From 8ec1607d6636f02c0f3a186e3df51c2f7f110a47 Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Fri, 15 Apr 2022 22:19:08 -0400 Subject: [PATCH 2/7] Configure pytest-aiohttp for auto mode. --- api/pytest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/api/pytest.ini b/api/pytest.ini index fe04656523e..3655ca7f3c7 100644 --- a/api/pytest.ini +++ b/api/pytest.ini @@ -9,3 +9,4 @@ markers = ot2_only: Test only functions using the OT2 hardware ot3_only: Test only functions the OT3 hardware addopts = --color=yes +asyncio_mode = auto From 37402dbe1f194ce7dd4816924af88114c0010a6f Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Fri, 15 Apr 2022 23:58:20 -0400 Subject: [PATCH 3/7] Delete `asyncio_loop_exception_handler` fixture. --- api/tests/opentrons/conftest.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/api/tests/opentrons/conftest.py b/api/tests/opentrons/conftest.py index 6c0c1bebb3c..bd0368df8fa 100755 --- a/api/tests/opentrons/conftest.py +++ b/api/tests/opentrons/conftest.py @@ -36,16 +36,6 @@ Protocol = namedtuple("Protocol", ["text", "filename", "filelike"]) -@pytest.fixture(autouse=True) -def asyncio_loop_exception_handler(loop): - def exception_handler(loop, context): - pytest.fail(str(context)) - - loop.set_exception_handler(exception_handler) - yield - loop.set_exception_handler(None) - - @pytest.fixture def ot_config_tempdir(tmp_path: pathlib.Path) -> Generator[pathlib.Path, None, None]: os.environ["OT_API_CONFIG_DIR"] = str(tmp_path) From 985ba5580ea288571d447104f6dc74420f6fd2a8 Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Fri, 15 Apr 2022 23:52:51 -0400 Subject: [PATCH 4/7] Remove `loop` arguments and replace with `get_running_loop()` as necessary. --- .../config/test_advanced_settings.py | 10 +-- api/tests/opentrons/conftest.py | 17 ++-- .../communication/test_async_serial.py | 4 +- .../hardware_control/emulation/test_proxy.py | 3 +- .../integration/test_controller.py | 1 - .../integration/test_magdeck.py | 3 +- .../integration/test_tempdeck.py | 3 +- .../integration/test_thermocycler.py | 3 +- .../modules/test_hc_heatershaker.py | 5 +- .../modules/test_hc_magdeck.py | 20 ++--- .../modules/test_hc_tempdeck.py | 27 +++---- .../modules/test_hc_thermocycler.py | 28 +++---- .../test_execution_manager.py | 6 +- .../opentrons/hardware_control/test_gpio.py | 2 +- .../hardware_control/test_instruments.py | 77 ++++++++++--------- .../hardware_control/test_modules.py | 4 +- .../opentrons/hardware_control/test_moves.py | 5 +- .../hardware_control/test_simulator_setup.py | 6 +- .../opentrons/protocol_api/test_context.py | 33 ++++---- .../clients/test_child_thread_transport.py | 13 ++-- .../test_python_context_creator.py | 3 +- .../advanced_control/test_transfers.py | 9 ++- api/tests/opentrons/system/test_nmcli.py | 2 +- api/tests/opentrons/system/test_wifi.py | 4 +- 24 files changed, 147 insertions(+), 141 deletions(-) diff --git a/api/tests/opentrons/config/test_advanced_settings.py b/api/tests/opentrons/config/test_advanced_settings.py index 476b08b4ca7..a03fd777fa6 100644 --- a/api/tests/opentrons/config/test_advanced_settings.py +++ b/api/tests/opentrons/config/test_advanced_settings.py @@ -76,7 +76,6 @@ def test_get_all_adv_settings_empty(clear_cache, mock_read_settings_file): async def test_set_adv_setting( - loop, mock_read_settings_file, mock_settings_values, mock_write_settings_file, @@ -95,7 +94,7 @@ async def test_set_adv_setting( async def test_set_adv_setting_unknown( - loop, mock_read_settings_file, mock_write_settings_file + mock_read_settings_file, mock_write_settings_file ): mock_read_settings_file.return_value = advanced_settings.SettingsData({}, 1) with pytest.raises(ValueError, match="is not recognized"): @@ -103,7 +102,7 @@ async def test_set_adv_setting_unknown( async def test_get_all_adv_settings_lru_cache( - loop, clear_cache, mock_read_settings_file, mock_write_settings_file + clear_cache, mock_read_settings_file, mock_write_settings_file ): # Cache should not be used. advanced_settings.get_all_adv_settings() @@ -126,7 +125,6 @@ async def test_get_all_adv_settings_lru_cache( async def test_restart_required( - loop, restore_restart_required, mock_read_settings_file, mock_write_settings_file, @@ -161,7 +159,7 @@ async def test_restart_required( [False, "info"], ], ) -async def test_disable_log_integration_side_effect(loop, v, expected_level): +async def test_disable_log_integration_side_effect(v, expected_level): with patch("opentrons.config.advanced_settings.log_control") as mock_log_control: async def set_syslog_level(level): @@ -177,7 +175,7 @@ async def set_syslog_level(level): mock_log_control.set_syslog_level.assert_called_once_with(expected_level) -async def test_disable_log_integration_side_effect_error(loop): +async def test_disable_log_integration_side_effect_error(): with patch("opentrons.config.advanced_settings.log_control") as mock_log_control: async def set_syslog_level(level): diff --git a/api/tests/opentrons/conftest.py b/api/tests/opentrons/conftest.py index bd0368df8fa..02670969fc4 100755 --- a/api/tests/opentrons/conftest.py +++ b/api/tests/opentrons/conftest.py @@ -13,6 +13,7 @@ import aionotify # type: ignore[import] except (OSError, ModuleNotFoundError): aionotify = None +import asyncio import os import io import json @@ -143,7 +144,7 @@ def virtual_smoothie_env(monkeypatch): @pytest.fixture( params=["ot2", "ot3"], ) -async def machine_variant_ffs(request, loop): +async def machine_variant_ffs(request): if request.node.get_closest_marker("ot3_only") and request.param == "ot2": pytest.skip() if request.node.get_closest_marker("ot2_only") and request.param == "ot3": @@ -174,7 +175,7 @@ async def _build_ot2_hw() -> AsyncIterator[ThreadManager[HardwareControlAPI]]: @pytest.fixture -async def ot2_hardware(request, loop, virtual_smoothie_env): +async def ot2_hardware(request, virtual_smoothie_env): async for hw in _build_ot2_hw(): yield hw @@ -193,7 +194,7 @@ async def _build_ot3_hw() -> AsyncIterator[ThreadManager[HardwareControlAPI]]: @pytest.fixture -async def ot3_hardware(request, loop, enable_ot3_hardware_controller): +async def ot3_hardware(request, enable_ot3_hardware_controller): # this is from the command line parameters added in root conftest if request.config.getoption("--ot2-only"): pytest.skip("testing only ot2") @@ -207,7 +208,7 @@ async def ot3_hardware(request, loop, enable_ot3_hardware_controller): params=[lambda: _build_ot2_hw, lambda: _build_ot3_hw], ids=["ot2", "ot3"], ) -async def hardware(request, loop, virtual_smoothie_env): +async def hardware(request, virtual_smoothie_env): if request.node.get_closest_marker("ot2_only") and request.param() == _build_ot3_hw: pytest.skip() if request.node.get_closest_marker("ot3_only") and request.param() == _build_ot2_hw: @@ -230,10 +231,10 @@ async def hardware(request, loop, virtual_smoothie_env): @pytest.fixture -async def ctx(loop, hardware) -> ProtocolContext: +async def ctx(hardware) -> ProtocolContext: return ProtocolContext( implementation=ProtocolContextImplementation(sync_hardware=hardware.sync), - loop=loop, + loop=asyncio.get_running_loop(), ) @@ -288,8 +289,8 @@ async def mock_connect(obj, port=None): @pytest.fixture -async def hardware_api(loop, is_robot): - hw_api = await API.build_hardware_simulator(loop=loop) +async def hardware_api(is_robot): + hw_api = await API.build_hardware_simulator(loop=asyncio.get_running_loop()) return hw_api diff --git a/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py b/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py index 8e4a5a921c6..1fd6b627e08 100644 --- a/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py +++ b/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py @@ -31,13 +31,13 @@ def mock_serial( @pytest.fixture async def subject( - loop: asyncio.AbstractEventLoop, mock_serial: MagicMock + mock_serial: MagicMock ) -> AsyncSerial: """The test subject.""" return AsyncSerial( serial=mock_serial, executor=ThreadPoolExecutor(), - loop=loop, + loop=asyncio.get_running_loop(), reset_buffer_before_write=False, ) diff --git a/api/tests/opentrons/hardware_control/emulation/test_proxy.py b/api/tests/opentrons/hardware_control/emulation/test_proxy.py index 549b246f8a5..b7d6d718cd2 100644 --- a/api/tests/opentrons/hardware_control/emulation/test_proxy.py +++ b/api/tests/opentrons/hardware_control/emulation/test_proxy.py @@ -42,13 +42,12 @@ def proxy_listener() -> SimpleProxyListener: @pytest.fixture async def subject( - loop: asyncio.AbstractEventLoop, setting: ProxySettings, proxy_listener: SimpleProxyListener, ) -> AsyncIterator[Proxy]: """Test subject.""" p = Proxy("proxy", proxy_listener, setting) - task = loop.create_task(p.run()) + task = asyncio.get_running_loop().create_task(p.run()) yield p task.cancel() try: diff --git a/api/tests/opentrons/hardware_control/integration/test_controller.py b/api/tests/opentrons/hardware_control/integration/test_controller.py index 0a012eff30f..564fd9c222d 100644 --- a/api/tests/opentrons/hardware_control/integration/test_controller.py +++ b/api/tests/opentrons/hardware_control/integration/test_controller.py @@ -11,7 +11,6 @@ @pytest.fixture async def subject( - loop: asyncio.BaseEventLoop, emulation_app: Iterator[None], emulator_settings: Settings, ) -> Controller: diff --git a/api/tests/opentrons/hardware_control/integration/test_magdeck.py b/api/tests/opentrons/hardware_control/integration/test_magdeck.py index 683edce81a9..1888bdc48e2 100644 --- a/api/tests/opentrons/hardware_control/integration/test_magdeck.py +++ b/api/tests/opentrons/hardware_control/integration/test_magdeck.py @@ -10,7 +10,6 @@ @pytest.fixture async def magdeck( - loop: asyncio.BaseEventLoop, emulation_app: Iterator[None], emulator_settings: Settings, ) -> AsyncIterator[MagDeck]: @@ -18,7 +17,7 @@ async def magdeck( port=f"socket://127.0.0.1:{emulator_settings.magdeck_proxy.driver_port}", execution_manager=AsyncMock(), usb_port=USBPort(name="", port_number=1, device_path="", hub=1), - loop=loop, + loop=asyncio.get_running_loop(), ) yield module await module.cleanup() diff --git a/api/tests/opentrons/hardware_control/integration/test_tempdeck.py b/api/tests/opentrons/hardware_control/integration/test_tempdeck.py index 92b6cb3875f..4968975ce25 100644 --- a/api/tests/opentrons/hardware_control/integration/test_tempdeck.py +++ b/api/tests/opentrons/hardware_control/integration/test_tempdeck.py @@ -10,7 +10,6 @@ @pytest.fixture async def tempdeck( - loop: asyncio.BaseEventLoop, emulator_settings: Settings, emulation_app: Iterator[None], ) -> TempDeck: @@ -19,7 +18,7 @@ async def tempdeck( port=f"socket://127.0.0.1:{emulator_settings.temperature_proxy.driver_port}", execution_manager=execution_manager, usb_port=USBPort(name="", port_number=1, device_path="", hub=1), - loop=loop, + loop=asyncio.get_running_loop(), polling_frequency=0.01, ) yield module diff --git a/api/tests/opentrons/hardware_control/integration/test_thermocycler.py b/api/tests/opentrons/hardware_control/integration/test_thermocycler.py index f6d03356425..93497a47d0f 100644 --- a/api/tests/opentrons/hardware_control/integration/test_thermocycler.py +++ b/api/tests/opentrons/hardware_control/integration/test_thermocycler.py @@ -9,7 +9,6 @@ @pytest.fixture async def thermocycler( - loop: asyncio.BaseEventLoop, emulation_app: Iterator[None], emulator_settings: Settings, ) -> Thermocycler: @@ -19,7 +18,7 @@ async def thermocycler( port=f"socket://127.0.0.1:{emulator_settings.thermocycler_proxy.driver_port}", execution_manager=execution_manager, usb_port=USBPort(name="", port_number=1, device_path="", hub=1), - loop=loop, + loop=asyncio.get_running_loop(), polling_frequency=0.01, ) yield module diff --git a/api/tests/opentrons/hardware_control/modules/test_hc_heatershaker.py b/api/tests/opentrons/hardware_control/modules/test_hc_heatershaker.py index 66738cb1613..09bee9fb383 100644 --- a/api/tests/opentrons/hardware_control/modules/test_hc_heatershaker.py +++ b/api/tests/opentrons/hardware_control/modules/test_hc_heatershaker.py @@ -1,3 +1,4 @@ +import asyncio import pytest from opentrons.hardware_control import modules, ExecutionManager from opentrons.hardware_control.modules.types import ( @@ -20,13 +21,13 @@ def usb_port(): @pytest.fixture -async def simulating_module(usb_port, loop): +async def simulating_module(usb_port): module = await modules.build( port=usb_port.device_path, usb_port=usb_port, which="heatershaker", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) assert isinstance(module, modules.AbstractModule) diff --git a/api/tests/opentrons/hardware_control/modules/test_hc_magdeck.py b/api/tests/opentrons/hardware_control/modules/test_hc_magdeck.py index 5a8e752fc55..3dc2355f3d1 100644 --- a/api/tests/opentrons/hardware_control/modules/test_hc_magdeck.py +++ b/api/tests/opentrons/hardware_control/modules/test_hc_magdeck.py @@ -1,6 +1,8 @@ +import asyncio + import pytest -from opentrons.hardware_control import modules, ExecutionManager +from opentrons.hardware_control import modules, ExecutionManager from opentrons.drivers.rpi_drivers.types import USBPort @@ -14,25 +16,25 @@ def usb_port(): ) -async def test_sim_initialization(loop, usb_port): +async def test_sim_initialization(usb_port): mag = await modules.build( port="/dev/ot_module_sim_magdeck0", usb_port=usb_port, which="magdeck", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) assert isinstance(mag, modules.AbstractModule) -async def test_sim_data(loop, usb_port): +async def test_sim_data(usb_port): mag = await modules.build( port="/dev/ot_module_sim_magdeck0", usb_port=usb_port, which="magdeck", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) assert mag.status == "disengaged" @@ -44,13 +46,13 @@ async def test_sim_data(loop, usb_port): assert "data" in mag.live_data -async def test_sim_state_update(loop, usb_port): +async def test_sim_state_update(usb_port): mag = await modules.build( port="/dev/ot_module_sim_magdeck0", usb_port=usb_port, which="magdeck", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) await mag.calibrate() @@ -61,13 +63,13 @@ async def test_sim_state_update(loop, usb_port): assert mag.status == "disengaged" -async def test_revision_model_parsing(loop, usb_port): +async def test_revision_model_parsing(usb_port): mag = await modules.build( "", "magdeck", True, usb_port, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) mag._device_info["model"] = "mag_deck_v1.1" diff --git a/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py b/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py index 1bc5407eaaa..c8eb805cbae 100644 --- a/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py +++ b/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py @@ -1,10 +1,11 @@ -import pytest +import asyncio from mock import AsyncMock -from opentrons.drivers.temp_deck import AbstractTempDeckDriver -from opentrons.hardware_control import modules, ExecutionManager +import pytest from opentrons.drivers.rpi_drivers.types import USBPort +from opentrons.drivers.temp_deck import AbstractTempDeckDriver +from opentrons.hardware_control import modules, ExecutionManager @pytest.fixture @@ -17,25 +18,25 @@ def usb_port(): ) -async def test_sim_initialization(loop, usb_port): +async def test_sim_initialization(usb_port): temp = await modules.build( port="/dev/ot_module_sim_tempdeck0", usb_port=usb_port, which="tempdeck", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) assert isinstance(temp, modules.AbstractModule) -async def test_sim_state(loop, usb_port): +async def test_sim_state(usb_port): temp = await modules.TempDeck.build( port="/dev/ot_module_sim_tempdeck0", usb_port=usb_port, simulating=True, interrupt_callback=lambda x: None, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) await temp.wait_next_poll() @@ -52,13 +53,13 @@ async def test_sim_state(loop, usb_port): assert status["version"] == "dummyVersionTD" -async def test_sim_update(loop, usb_port): +async def test_sim_update(usb_port): temp = await modules.TempDeck.build( port="/dev/ot_module_sim_tempdeck0", usb_port=usb_port, simulating=True, interrupt_callback=lambda x: None, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), polling_frequency=0, ) @@ -73,13 +74,13 @@ async def test_sim_update(loop, usb_port): assert temp.status == "idle" -async def test_revision_model_parsing(loop, usb_port): +async def test_revision_model_parsing(usb_port): mag = await modules.TempDeck.build( port="", simulating=True, usb_port=usb_port, interrupt_callback=lambda x: None, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), polling_frequency=0, ) @@ -93,7 +94,7 @@ async def test_revision_model_parsing(loop, usb_port): assert mag.model() == "temperatureModuleV1" -async def test_poll_error(loop, usb_port) -> None: +async def test_poll_error(usb_port) -> None: mock_driver = AsyncMock(spec=AbstractTempDeckDriver) mock_driver.get_temperature.side_effect = ValueError("hello!") @@ -103,7 +104,7 @@ async def test_poll_error(loop, usb_port) -> None: execution_manager=AsyncMock(spec=ExecutionManager), driver=mock_driver, device_info={}, - loop=loop, + loop=asyncio.get_running_loop(), polling_frequency=1, ) with pytest.raises(ValueError, match="hello!"): diff --git a/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py b/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py index d593afd6d5d..090d2a1d194 100644 --- a/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py +++ b/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py @@ -1,9 +1,11 @@ -import pytest +import asyncio import mock -from opentrons.drivers.thermocycler import SimulatingDriver -from opentrons.hardware_control import modules, ExecutionManager + +import pytest from opentrons.drivers.rpi_drivers.types import USBPort +from opentrons.drivers.thermocycler import SimulatingDriver +from opentrons.hardware_control import modules, ExecutionManager @pytest.fixture @@ -16,26 +18,26 @@ def usb_port() -> USBPort: ) -async def test_sim_initialization(loop, usb_port): +async def test_sim_initialization(usb_port): therm = await modules.build( port="/dev/ot_module_sim_thermocycler0", usb_port=usb_port, which="thermocycler", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) assert isinstance(therm, modules.AbstractModule) -async def test_lid(loop, usb_port): +async def test_lid(usb_port): therm = await modules.build( port="/dev/ot_module_sim_thermocycler0", usb_port=usb_port, which="thermocycler", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) @@ -56,13 +58,13 @@ async def test_lid(loop, usb_port): assert therm.lid_status == "open" -async def test_sim_state(loop, usb_port): +async def test_sim_state(usb_port): therm = await modules.build( port="/dev/ot_module_sim_thermocycler0", usb_port=usb_port, which="thermocycler", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) @@ -78,13 +80,13 @@ async def test_sim_state(loop, usb_port): assert status["version"] == "dummyVersionTC" -async def test_sim_update(loop, usb_port): +async def test_sim_update(usb_port): therm = await modules.build( port="/dev/ot_module_sim_thermocycler0", usb_port=usb_port, which="thermocycler", simulating=True, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) @@ -147,13 +149,13 @@ def simulator_set_plate_spy( @pytest.fixture async def set_temperature_subject( - loop, usb_port: USBPort, simulator_set_plate_spy: SimulatingDriver + usb_port: USBPort, simulator_set_plate_spy: SimulatingDriver ) -> modules.Thermocycler: """Fixture that spys on set_plate_temperature""" hw_tc = modules.Thermocycler( port="/dev/ot_module_sim_thermocycler0", usb_port=usb_port, - loop=loop, + loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), driver=simulator_set_plate_spy, device_info={}, diff --git a/api/tests/opentrons/hardware_control/test_execution_manager.py b/api/tests/opentrons/hardware_control/test_execution_manager.py index 7943d75a3a6..4ad3c4475e0 100644 --- a/api/tests/opentrons/hardware_control/test_execution_manager.py +++ b/api/tests/opentrons/hardware_control/test_execution_manager.py @@ -7,7 +7,7 @@ ) -async def test_state_machine(loop): +async def test_state_machine(): """ Test that an execution manager's state is RUNNING on init and PAUSE when it when pause is called, unless CANCELLED @@ -43,7 +43,7 @@ async def test_state_machine(loop): assert await exec_mgr.get_state() == ExecutionState.RUNNING -async def test_cancel_tasks(loop): +async def test_cancel_tasks(): """ Test that an execution manager cancels all un-protected running asyncio Tasks when cancel is called @@ -55,6 +55,8 @@ async def fake_task(): exec_mgr = ExecutionManager() + loop = asyncio.get_running_loop() + cancellable_task = loop.create_task(fake_task()) await exec_mgr.register_cancellable_task(cancellable_task) diff --git a/api/tests/opentrons/hardware_control/test_gpio.py b/api/tests/opentrons/hardware_control/test_gpio.py index aa491ed8dc4..6e8ff4f4912 100644 --- a/api/tests/opentrons/hardware_control/test_gpio.py +++ b/api/tests/opentrons/hardware_control/test_gpio.py @@ -5,7 +5,7 @@ from opentrons.drivers.rpi_drivers.gpio_simulator import SimulatingGPIOCharDev -async def test_gpio_setup(loop, monkeypatch): +async def test_gpio_setup(monkeypatch): # Test without DTOVERLAY path # Board revision should be defaulted to 2.1 backend = await hc.Controller.build(config=None) diff --git a/api/tests/opentrons/hardware_control/test_instruments.py b/api/tests/opentrons/hardware_control/test_instruments.py index edced4aed03..16e87f25a3d 100644 --- a/api/tests/opentrons/hardware_control/test_instruments.py +++ b/api/tests/opentrons/hardware_control/test_instruments.py @@ -1,11 +1,15 @@ +import asyncio import mock + import pytest try: import aionotify except (OSError, ModuleNotFoundError): aionotify = None # type: ignore + import typeguard + from opentrons import types from opentrons.hardware_control import API from opentrons.hardware_control.types import Axis @@ -118,17 +122,17 @@ def get_plunger_speed(api): return api._instrument_handler.plunger_speed -async def test_cache_instruments(loop, sim_and_instr): +async def test_cache_instruments(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) await hw_api.cache_instruments() attached = hw_api.attached_instruments typeguard.check_type("left mount dict", attached[types.Mount.LEFT], PipetteDict) -async def test_mismatch_fails(loop, sim_and_instr): +async def test_mismatch_fails(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) requested_instr = { types.Mount.LEFT: "p20_single_gen2", types.Mount.RIGHT: "p300_single", @@ -138,11 +142,11 @@ async def test_mismatch_fails(loop, sim_and_instr): async def test_backwards_compatibility( - dummy_backwards_compatibility, loop, sim_and_instr + dummy_backwards_compatibility, sim_and_instr ): sim_builder, _ = sim_and_instr hw_api = await sim_builder( - attached_instruments=dummy_backwards_compatibility, loop=loop + attached_instruments=dummy_backwards_compatibility, loop=asyncio.get_running_loop() ) requested_instr = {types.Mount.LEFT: "p10_single", types.Mount.RIGHT: "p300_single"} volumes = { @@ -165,9 +169,8 @@ async def test_cache_instruments_hc( hardware_controller_lockfile, running_on_pi, cntrlr_mock_connect, - loop, ): - hw_api_cntrlr = await API.build_hardware_controller(loop=loop) + hw_api_cntrlr = await API.build_hardware_controller(loop=asyncio.get_running_loop()) async def mock_driver_model(mount): attached_pipette = {"left": LEFT_PIPETTE_MODEL, "right": None} @@ -203,7 +206,7 @@ async def mock_driver_id(mount): @pytest.mark.ot2_only -async def test_cache_instruments_sim(loop, sim_and_instr): +async def test_cache_instruments_sim(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr def fake_func1(value): @@ -212,7 +215,7 @@ def fake_func1(value): def fake_func2(mount, value): return mount, value - sim = await sim_builder(loop=loop) + sim = await sim_builder(loop=asyncio.get_running_loop()) # With nothing specified at init or expected, we should have nothing # afterwards and nothing should have been reconfigured sim._backend._smoothie_driver.update_steps_per_mm = mock.AsyncMock(fake_func1) @@ -279,7 +282,7 @@ def fake_func2(mount, value): # correspondence between expectations and preconfiguration sim = await sim_builder( attached_instruments=dummy_instruments, - loop=loop, + loop=asyncio.get_running_loop(), strict_attached_instruments=False, ) await sim.cache_instruments({types.Mount.LEFT: "p300_multi"}) @@ -290,9 +293,9 @@ def fake_func2(mount, value): await sim.cache_instruments({types.Mount.LEFT: "p10_sing"}) -async def test_prep_aspirate(loop, sim_and_instr): +async def test_prep_aspirate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) await hw_api.home() await hw_api.cache_instruments() @@ -309,9 +312,9 @@ async def test_prep_aspirate(loop, sim_and_instr): await hw_api.aspirate(mount, 1) -async def test_aspirate_new(dummy_instruments, loop): +async def test_aspirate_new(dummy_instruments): hw_api = await API.build_hardware_simulator( - attached_instruments=dummy_instruments, loop=loop + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() ) await hw_api.home() await hw_api.cache_instruments() @@ -328,9 +331,9 @@ async def test_aspirate_new(dummy_instruments, loop): assert pos[Axis.B] == new_plunger_pos -async def test_aspirate_old(dummy_instruments, loop, old_aspiration): +async def test_aspirate_old(dummy_instruments, old_aspiration): hw_api = await API.build_hardware_simulator( - attached_instruments=dummy_instruments, loop=loop + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() ) await hw_api.home() await hw_api.cache_instruments() @@ -347,8 +350,8 @@ async def test_aspirate_old(dummy_instruments, loop, old_aspiration): assert pos[Axis.B] == new_plunger_pos -async def test_aspirate_ot3(dummy_instruments_ot3, ot3_api_obj, loop): - hw_api = await ot3_api_obj(attached_instruments=dummy_instruments_ot3, loop=loop) +async def test_aspirate_ot3(dummy_instruments_ot3, ot3_api_obj): + hw_api = await ot3_api_obj(attached_instruments=dummy_instruments_ot3, loop=asyncio.get_running_loop()) await hw_api.home() await hw_api.cache_instruments() @@ -364,9 +367,9 @@ async def test_aspirate_ot3(dummy_instruments_ot3, ot3_api_obj, loop): assert pos[Axis.B] == new_plunger_pos -async def test_dispense_ot2(dummy_instruments, loop): +async def test_dispense_ot2(dummy_instruments): hw_api = await API.build_hardware_simulator( - attached_instruments=dummy_instruments, loop=loop + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() ) await hw_api.home() @@ -390,8 +393,8 @@ async def test_dispense_ot2(dummy_instruments, loop): assert (await hw_api.current_position(mount))[Axis.B] == plunger_pos_2 -async def test_dispense_ot3(dummy_instruments_ot3, ot3_api_obj, loop): - hw_api = await ot3_api_obj(attached_instruments=dummy_instruments_ot3, loop=loop) +async def test_dispense_ot3(dummy_instruments_ot3, ot3_api_obj): + hw_api = await ot3_api_obj(attached_instruments=dummy_instruments_ot3, loop=asyncio.get_running_loop()) await hw_api.home() await hw_api.cache_instruments() @@ -414,9 +417,9 @@ async def test_dispense_ot3(dummy_instruments_ot3, ot3_api_obj, loop): assert (await hw_api.current_position(mount))[Axis.B] == plunger_pos_2 -async def test_no_pipette(loop, sim_and_instr): +async def test_no_pipette(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) await hw_api.cache_instruments() aspirate_ul = 3.0 aspirate_rate = 2 @@ -425,9 +428,9 @@ async def test_no_pipette(loop, sim_and_instr): assert not hw_api._current_volume[types.Mount.RIGHT] -async def test_pick_up_tip(loop, is_robot, sim_and_instr): +async def test_pick_up_tip(is_robot, sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -443,9 +446,9 @@ async def test_pick_up_tip(loop, is_robot, sim_and_instr): assert hw_api.hardware_instruments[mount].current_volume == 0 -async def test_pick_up_tip_pos_ot2(loop, is_robot, dummy_instruments): +async def test_pick_up_tip_pos_ot2(is_robot, dummy_instruments): hw_api = await API.build_hardware_simulator( - attached_instruments=dummy_instruments, loop=loop + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() ) mount = types.Mount.LEFT await hw_api.home() @@ -481,9 +484,9 @@ def assert_move_called(mock_move, speed, lock=None): ) -async def test_aspirate_flow_rate(loop, sim_and_instr): +async def test_aspirate_flow_rate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -538,9 +541,9 @@ async def test_aspirate_flow_rate(loop, sim_and_instr): assert_move_called(mock_move, 5) -async def test_dispense_flow_rate(loop, sim_and_instr): +async def test_dispense_flow_rate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -593,9 +596,9 @@ async def test_dispense_flow_rate(loop, sim_and_instr): assert_move_called(mock_move, 5) -async def test_blowout_flow_rate(loop, sim_and_instr): +async def test_blowout_flow_rate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -631,9 +634,9 @@ async def test_blowout_flow_rate(loop, sim_and_instr): assert_move_called(mock_move, 15) -async def test_reset_instruments(loop, monkeypatch, sim_and_instr): +async def test_reset_instruments(monkeypatch, sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=loop) + hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) hw_api.set_flow_rate(types.Mount.LEFT, 20) # gut check assert hw_api.attached_instruments[types.Mount.LEFT]["aspirate_flow_rate"] == 20 diff --git a/api/tests/opentrons/hardware_control/test_modules.py b/api/tests/opentrons/hardware_control/test_modules.py index bf9cedba8f8..e2863d2823f 100644 --- a/api/tests/opentrons/hardware_control/test_modules.py +++ b/api/tests/opentrons/hardware_control/test_modules.py @@ -85,9 +85,11 @@ async def test_filtering_modules(): assert filtered_modules == api.attached_modules[2:4] -async def test_module_update_integration(monkeypatch, loop): +async def test_module_update_integration(monkeypatch): from opentrons.hardware_control import modules + loop = asyncio.get_running_loop() + def async_return(result): f = asyncio.Future() f.set_result(result) diff --git a/api/tests/opentrons/hardware_control/test_moves.py b/api/tests/opentrons/hardware_control/test_moves.py index 631e214e645..4d7cebcea0a 100644 --- a/api/tests/opentrons/hardware_control/test_moves.py +++ b/api/tests/opentrons/hardware_control/test_moves.py @@ -1,3 +1,4 @@ +import asyncio import mock import pytest from opentrons import types @@ -310,7 +311,7 @@ async def test_new_critical_point_applied(hardware_api): assert await hardware_api.current_position(types.Mount.RIGHT) == target -async def test_attitude_deck_cal_applied(monkeypatch, loop): +async def test_attitude_deck_cal_applied(monkeypatch): new_gantry_cal = [[1.0047, -0.0046, 0.0], [0.0011, 1.0038, 0.0], [0.0, 0.0, 1.0]] called_with = None @@ -320,7 +321,7 @@ async def mock_move( nonlocal called_with called_with = position - hardware_api = await hc.API.build_hardware_simulator(loop=loop) + hardware_api = await hc.API.build_hardware_simulator(loop=asyncio.get_running_loop()) monkeypatch.setattr(hardware_api._backend, "move", mock_move) deck_cal = RobotCalibration( deck_calibration=DeckCalibration( diff --git a/api/tests/opentrons/hardware_control/test_simulator_setup.py b/api/tests/opentrons/hardware_control/test_simulator_setup.py index d1d8d7c8982..0f0b01a0749 100644 --- a/api/tests/opentrons/hardware_control/test_simulator_setup.py +++ b/api/tests/opentrons/hardware_control/test_simulator_setup.py @@ -6,7 +6,7 @@ from opentrons.types import Mount -async def test_with_magdeck(loop): +async def test_with_magdeck(): setup = simulator_setup.SimulatorSetup( attached_modules={ "magdeck": [simulator_setup.ModuleCall("engage", kwargs={"height": 3})] @@ -21,7 +21,7 @@ async def test_with_magdeck(loop): } -async def test_with_thermocycler(loop): +async def test_with_thermocycler(): setup = simulator_setup.SimulatorSetup( attached_modules={ "thermocycler": [ @@ -58,7 +58,7 @@ async def test_with_thermocycler(loop): } -async def test_with_tempdeck(loop): +async def test_with_tempdeck(): setup = simulator_setup.SimulatorSetup( attached_modules={ "tempdeck": [ diff --git a/api/tests/opentrons/protocol_api/test_context.py b/api/tests/opentrons/protocol_api/test_context.py index 9b847056547..c6b8b3444b9 100644 --- a/api/tests/opentrons/protocol_api/test_context.py +++ b/api/tests/opentrons/protocol_api/test_context.py @@ -1,5 +1,6 @@ """ Test the functions and classes in the protocol context """ +import asyncio import json from unittest import mock from typing import Any, Dict @@ -259,7 +260,7 @@ def test_pick_up_and_drop_tip(ctx, get_labware_def): assert pipette.critical_point() == nozzle_offset -def test_return_tip_old_version(loop, hardware, get_labware_def): +async def test_return_tip_old_version(hardware, get_labware_def): # API version 2.2, a returned tip would be picked up by the # next pick up tip call api_version = APIVersion(2, 1) @@ -268,7 +269,7 @@ def test_return_tip_old_version(loop, hardware, get_labware_def): api_version=api_version, sync_hardware=hardware.sync, ), - loop=loop, + loop=asyncio.get_running_loop(), api_version=api_version, ) ctx.home() @@ -622,14 +623,14 @@ def fake_dispense(vol=None, loc=None, rate=None): assert mix_steps == expected_mix_steps -def test_touch_tip_default_args(loop, monkeypatch, hardware): +async def test_touch_tip_default_args(monkeypatch, hardware): api_version = APIVersion(2, 3) ctx = papi.ProtocolContext( implementation=ProtocolContextImplementation( api_version=api_version, sync_hardware=hardware.sync, ), - loop=loop, + loop=asyncio.get_running_loop(), api_version=api_version, ) ctx.home() @@ -922,7 +923,7 @@ def test_loaded_modules(ctx, monkeypatch): assert ctx.loaded_modules[4] == temp2 -def test_order_of_module_load(loop): +async def test_order_of_module_load(): import opentrons.hardware_control as hardware_control import opentrons.protocol_api as protocol_api @@ -938,7 +939,7 @@ def test_order_of_module_load(loop): ctx1 = protocol_api.ProtocolContext( implementation=ProtocolContextImplementation(sync_hardware=fake_hardware), - loop=loop, + loop=asyncio.get_running_loop(), ) temp1 = ctx1.load_module("tempdeck", 4) @@ -955,7 +956,7 @@ def test_order_of_module_load(loop): # was loaded into ctx2 = protocol_api.ProtocolContext( implementation=ProtocolContextImplementation(sync_hardware=fake_hardware), - loop=loop, + loop=asyncio.get_running_loop(), ) ctx2.load_module("thermocycler") @@ -1014,7 +1015,7 @@ def test_tip_length_for_load_caldata(ctx): delete.clear_tip_length_calibration() -def test_bundled_labware(loop, get_labware_fixture, hardware): +def test_bundled_labware(get_labware_fixture, hardware): fixture_96_plate = get_labware_fixture("fixture_96_plate") bundled_labware = {"fixture/fixture_96_plate/1": fixture_96_plate} @@ -1022,7 +1023,7 @@ def test_bundled_labware(loop, get_labware_fixture, hardware): implementation=ProtocolContextImplementation( sync_hardware=hardware.sync, bundled_labware=bundled_labware ), - loop=loop, + loop=asyncio.get_running_loop(), ) lw1 = ctx.load_labware("fixture_96_plate", 3, namespace="fixture") @@ -1030,7 +1031,7 @@ def test_bundled_labware(loop, get_labware_fixture, hardware): assert ctx.loaded_labwares[3]._implementation.get_definition() == fixture_96_plate -def test_bundled_labware_missing(loop, get_labware_fixture, hardware): +def test_bundled_labware_missing(get_labware_fixture, hardware): bundled_labware: Dict[str, Any] = {} with pytest.raises( RuntimeError, match="No labware found in bundle with load name fixture_96_plate" @@ -1039,7 +1040,7 @@ def test_bundled_labware_missing(loop, get_labware_fixture, hardware): implementation=ProtocolContextImplementation( bundled_labware=bundled_labware, sync_hardware=hardware.sync ), - loop=loop, + loop=asyncio.get_running_loop(), ) ctx.load_labware("fixture_96_plate", 3, namespace="fixture") @@ -1054,30 +1055,30 @@ def test_bundled_labware_missing(loop, get_labware_fixture, hardware): extra_labware=bundled_labware, sync_hardware=hardware.sync, ), - loop=loop, + loop=asyncio.get_running_loop(), ) ctx.load_labware("fixture_96_plate", 3, namespace="fixture") -def test_bundled_data(loop, hardware): +def test_bundled_data(hardware): bundled_data = {"foo": b"1,2,3"} ctx = papi.ProtocolContext( implementation=ProtocolContextImplementation( bundled_data=bundled_data, sync_hardware=hardware.sync ), - loop=loop, + loop=asyncio.get_running_loop(), ) assert ctx.bundled_data == bundled_data -def test_extra_labware(loop, get_labware_fixture, hardware): +def test_extra_labware(get_labware_fixture, hardware): fixture_96_plate = get_labware_fixture("fixture_96_plate") bundled_labware = {"fixture/fixture_96_plate/1": fixture_96_plate} ctx = papi.ProtocolContext( implementation=ProtocolContextImplementation( extra_labware=bundled_labware, sync_hardware=hardware.sync ), - loop=loop, + loop=asyncio.get_running_loop(), ) ls1 = ctx.load_labware("fixture_96_plate", 3, namespace="fixture") diff --git a/api/tests/opentrons/protocol_engine/clients/test_child_thread_transport.py b/api/tests/opentrons/protocol_engine/clients/test_child_thread_transport.py index 223cbfdb5ee..b8b44263e2b 100644 --- a/api/tests/opentrons/protocol_engine/clients/test_child_thread_transport.py +++ b/api/tests/opentrons/protocol_engine/clients/test_child_thread_transport.py @@ -1,7 +1,7 @@ """Tests for am ChildThreadTransport.""" import pytest -from asyncio import AbstractEventLoop +from asyncio import get_running_loop from datetime import datetime from decoy import Decoy from functools import partial @@ -19,17 +19,15 @@ async def engine(decoy: Decoy) -> ProtocolEngine: @pytest.fixture -def subject( +async def subject( engine: ProtocolEngine, - loop: AbstractEventLoop, ) -> ChildThreadTransport: """Get a ChildThreadTransport test subject.""" - return ChildThreadTransport(engine=engine, loop=loop) + return ChildThreadTransport(engine=engine, loop=get_running_loop()) async def test_execute_command( decoy: Decoy, - loop: AbstractEventLoop, engine: ProtocolEngine, subject: ChildThreadTransport, ) -> None: @@ -54,14 +52,13 @@ async def test_execute_command( ) task = partial(subject.execute_command, request=cmd_request) - result = await loop.run_in_executor(None, task) + result = await get_running_loop().run_in_executor(None, task) assert result == cmd_result async def test_execute_command_failure( decoy: Decoy, - loop: AbstractEventLoop, engine: ProtocolEngine, subject: ChildThreadTransport, ) -> None: @@ -93,4 +90,4 @@ async def test_execute_command_failure( task = partial(subject.execute_command, request=cmd_request) with pytest.raises(ProtocolEngineError, match="Things are not looking good"): - await loop.run_in_executor(None, task) + await get_running_loop().run_in_executor(None, task) diff --git a/api/tests/opentrons/protocol_runner/smoke_tests/test_python_context_creator.py b/api/tests/opentrons/protocol_runner/smoke_tests/test_python_context_creator.py index 2d308d37837..acb02fdd06c 100644 --- a/api/tests/opentrons/protocol_runner/smoke_tests/test_python_context_creator.py +++ b/api/tests/opentrons/protocol_runner/smoke_tests/test_python_context_creator.py @@ -32,7 +32,6 @@ async def test_creates_protocol_context(protocol_engine: ProtocolEngine) -> None async def test_wires_protocol_context_to_engine( - loop: asyncio.AbstractEventLoop, protocol_engine: ProtocolEngine, ) -> None: """Smoke test the returned ProtocolContext by running a command.""" @@ -41,7 +40,7 @@ async def test_wires_protocol_context_to_engine( # run a ProtocolContext command in a ThreadPoolExecutor to validate # commands are going to the engine across the thread boundary - result = await loop.run_in_executor( + result = await asyncio.get_running_loop().run_in_executor( executor=None, func=partial( context.load_labware, diff --git a/api/tests/opentrons/protocols/advanced_control/test_transfers.py b/api/tests/opentrons/protocols/advanced_control/test_transfers.py index 349be7a837b..d184606472d 100644 --- a/api/tests/opentrons/protocols/advanced_control/test_transfers.py +++ b/api/tests/opentrons/protocols/advanced_control/test_transfers.py @@ -1,4 +1,5 @@ """ Test the Transfer class and its functions """ +import asyncio import pytest import opentrons.protocol_api as papi from opentrons.protocols.context.protocol_api.protocol_context import ( @@ -1045,12 +1046,12 @@ def test_oversized_transfer(_instr_labware): assert xfer_plan_list == exp1 -def test_multichannel_transfer_old_version(loop, hardware): +async def test_multichannel_transfer_old_version(hardware): # for API version below 2.2, multichannel pipette can only # reach row A of 384-well plates ctx = papi.ProtocolContext( implementation=ProtocolContextImplementation(sync_hardware=hardware.sync), - loop=loop, + loop=asyncio.get_running_loop(), api_version=APIVersion(2, 1), ) lw1 = ctx.load_labware("biorad_96_wellplate_200ul_pcr", 1) @@ -1107,13 +1108,13 @@ def test_multichannel_transfer_old_version(loop, hardware): xfer_plan_list.append(step) -def test_multichannel_transfer_locs(loop, hardware): +def test_multichannel_transfer_locs(hardware): api_version = APIVersion(2, 2) ctx = papi.ProtocolContext( implementation=ProtocolContextImplementation( api_version=api_version, sync_hardware=hardware.sync ), - loop=loop, + loop=asyncio.get_running_loop(), api_version=api_version, ) lw1 = ctx.load_labware("biorad_96_wellplate_200ul_pcr", 1) diff --git a/api/tests/opentrons/system/test_nmcli.py b/api/tests/opentrons/system/test_nmcli.py index 00a824a41dd..d587dcdbd2d 100644 --- a/api/tests/opentrons/system/test_nmcli.py +++ b/api/tests/opentrons/system/test_nmcli.py @@ -137,7 +137,7 @@ async def mock_call(cmd, suppress_err=False): assert result == expected -async def test_networking_status(loop, monkeypatch): +async def test_networking_status(monkeypatch): async def mock_call(cmd): # Command: `nmcli networking connectivity` if "connectivity" in cmd: diff --git a/api/tests/opentrons/system/test_wifi.py b/api/tests/opentrons/system/test_wifi.py index a63c477164d..5c205a3a5c8 100644 --- a/api/tests/opentrons/system/test_wifi.py +++ b/api/tests/opentrons/system/test_wifi.py @@ -147,7 +147,7 @@ def test_eap_check_option(): ) -async def test_list_keys(loop, wifi_keys_tempdir): +async def test_list_keys(wifi_keys_tempdir): dummy_names = ["ad12d1df199bc912", "cbdda8124128cf", "812410990c5412"] for dn in dummy_names: os.mkdir(os.path.join(wifi_keys_tempdir, dn)) @@ -165,7 +165,7 @@ async def test_list_keys(loop, wifi_keys_tempdir): raise KeyError(dn) -async def test_key_lifecycle(loop, wifi_keys_tempdir): +async def test_key_lifecycle(wifi_keys_tempdir): with tempfile.TemporaryDirectory() as source_td: keys = list(wifi.list_keys()) assert keys == [] From 2a9efefb87fb0a00c02547a6a3f11a78f90ee1f2 Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Fri, 15 Apr 2022 15:14:55 -0400 Subject: [PATCH 5/7] Make additional stuff async to ensure it gets run in an event loop. --- api/tests/opentrons/conftest.py | 2 ++ .../asyncio/communication/test_serial_connection.py | 4 +++- .../drivers/smoothie_drivers/test_connection.py | 4 +++- api/tests/opentrons/protocol_api/test_context.py | 12 ++++++------ .../opentrons/protocol_api/test_module_context.py | 12 +++++++++--- .../protocols/advanced_control/test_transfers.py | 2 +- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/api/tests/opentrons/conftest.py b/api/tests/opentrons/conftest.py index 02670969fc4..0f0a4047c3e 100755 --- a/api/tests/opentrons/conftest.py +++ b/api/tests/opentrons/conftest.py @@ -230,6 +230,8 @@ async def hardware(request, virtual_smoothie_env): ) +# Async because ProtocolContext.__init__() needs an event loop, +# so this fixture needs to run in an event loop. @pytest.fixture async def ctx(hardware) -> ProtocolContext: return ProtocolContext( diff --git a/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py b/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py index 541990d1c39..9f8741e2eff 100644 --- a/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py +++ b/api/tests/opentrons/drivers/asyncio/communication/test_serial_connection.py @@ -22,8 +22,10 @@ def ack() -> str: return "ack" +# Async because SerialConnection.__init__() needs an event loop, +# so this fixture needs to run in an event loop. @pytest.fixture -def subject(mock_serial_port: AsyncMock, ack: str) -> SerialConnection: +async def subject(mock_serial_port: AsyncMock, ack: str) -> SerialConnection: """Create the test subject.""" SerialConnection.RETRY_WAIT_TIME = 0 # type: ignore[attr-defined] return SerialConnection( diff --git a/api/tests/opentrons/drivers/smoothie_drivers/test_connection.py b/api/tests/opentrons/drivers/smoothie_drivers/test_connection.py index 49f5d9d3206..b0fd200c300 100644 --- a/api/tests/opentrons/drivers/smoothie_drivers/test_connection.py +++ b/api/tests/opentrons/drivers/smoothie_drivers/test_connection.py @@ -12,8 +12,10 @@ def mock_serial_connection() -> AsyncMock: return AsyncMock(spec=AsyncSerial) +# Async because SmoothieConnection.__init__() needs an event loop, +# so this fixture needs to run in an event loop. @pytest.fixture -def subject(mock_serial_connection: AsyncMock) -> SmoothieConnection: +async def subject(mock_serial_connection: AsyncMock) -> SmoothieConnection: """The test subject.""" return SmoothieConnection( serial=mock_serial_connection, diff --git a/api/tests/opentrons/protocol_api/test_context.py b/api/tests/opentrons/protocol_api/test_context.py index c6b8b3444b9..18e9b90f4ed 100644 --- a/api/tests/opentrons/protocol_api/test_context.py +++ b/api/tests/opentrons/protocol_api/test_context.py @@ -1015,7 +1015,7 @@ def test_tip_length_for_load_caldata(ctx): delete.clear_tip_length_calibration() -def test_bundled_labware(get_labware_fixture, hardware): +async def test_bundled_labware(get_labware_fixture, hardware): fixture_96_plate = get_labware_fixture("fixture_96_plate") bundled_labware = {"fixture/fixture_96_plate/1": fixture_96_plate} @@ -1031,7 +1031,7 @@ def test_bundled_labware(get_labware_fixture, hardware): assert ctx.loaded_labwares[3]._implementation.get_definition() == fixture_96_plate -def test_bundled_labware_missing(get_labware_fixture, hardware): +async def test_bundled_labware_missing(get_labware_fixture, hardware): bundled_labware: Dict[str, Any] = {} with pytest.raises( RuntimeError, match="No labware found in bundle with load name fixture_96_plate" @@ -1060,7 +1060,7 @@ def test_bundled_labware_missing(get_labware_fixture, hardware): ctx.load_labware("fixture_96_plate", 3, namespace="fixture") -def test_bundled_data(hardware): +async def test_bundled_data(hardware): bundled_data = {"foo": b"1,2,3"} ctx = papi.ProtocolContext( implementation=ProtocolContextImplementation( @@ -1071,7 +1071,7 @@ def test_bundled_data(hardware): assert ctx.bundled_data == bundled_data -def test_extra_labware(get_labware_fixture, hardware): +async def test_extra_labware(get_labware_fixture, hardware): fixture_96_plate = get_labware_fixture("fixture_96_plate") bundled_labware = {"fixture/fixture_96_plate/1": fixture_96_plate} ctx = papi.ProtocolContext( @@ -1086,7 +1086,7 @@ def test_extra_labware(get_labware_fixture, hardware): assert ctx.loaded_labwares[3]._implementation.get_definition() == fixture_96_plate -def test_api_version_checking(hardware): +async def test_api_version_checking(hardware): minor_over = APIVersion( papi.MAX_SUPPORTED_VERSION.major, papi.MAX_SUPPORTED_VERSION.minor + 1, @@ -1108,7 +1108,7 @@ def test_api_version_checking(hardware): ) -def test_api_per_call_checking(monkeypatch, hardware): +async def test_api_per_call_checking(monkeypatch, hardware): implementation = ProtocolContextImplementation(sync_hardware=hardware.sync) ctx = papi.ProtocolContext( diff --git a/api/tests/opentrons/protocol_api/test_module_context.py b/api/tests/opentrons/protocol_api/test_module_context.py index ae46aa64d7d..671f324045e 100644 --- a/api/tests/opentrons/protocol_api/test_module_context.py +++ b/api/tests/opentrons/protocol_api/test_module_context.py @@ -30,8 +30,10 @@ def mock_module_controller() -> mock.MagicMock: return mock.MagicMock() +# Async because ProtocolContext.__init__() needs an event loop, +# so this fixture needs to run in an event loop. @pytest.fixture -def ctx_with_tempdeck( +async def ctx_with_tempdeck( mock_hardware: mock.MagicMock, mock_module_controller: mock.MagicMock ) -> ProtocolContext: """Context fixture with a mock temp deck.""" @@ -51,8 +53,10 @@ def find_modules(resolved_model: ModuleModel, resolved_type: ModuleType): ) +# Async because ProtocolContext.__init__() needs an event loop, +# so this fixture needs to run in an event loop. @pytest.fixture -def ctx_with_magdeck( +async def ctx_with_magdeck( mock_hardware: mock.AsyncMock, mock_module_controller: mock.MagicMock ) -> ProtocolContext: """Context fixture with a mock mag deck.""" @@ -72,8 +76,10 @@ def find_modules(resolved_model: ModuleModel, resolved_type: ModuleType): ) +# Async because ProtocolContext.__init__() needs an event loop, +# so this fixture needs to run in an event loop. @pytest.fixture -def ctx_with_thermocycler( +async def ctx_with_thermocycler( mock_hardware: mock.AsyncMock, mock_module_controller: mock.MagicMock ) -> ProtocolContext: """Context fixture with a mock thermocycler.""" diff --git a/api/tests/opentrons/protocols/advanced_control/test_transfers.py b/api/tests/opentrons/protocols/advanced_control/test_transfers.py index d184606472d..9bec4665f7a 100644 --- a/api/tests/opentrons/protocols/advanced_control/test_transfers.py +++ b/api/tests/opentrons/protocols/advanced_control/test_transfers.py @@ -1108,7 +1108,7 @@ async def test_multichannel_transfer_old_version(hardware): xfer_plan_list.append(step) -def test_multichannel_transfer_locs(hardware): +async def test_multichannel_transfer_locs(hardware): api_version = APIVersion(2, 2) ctx = papi.ProtocolContext( implementation=ProtocolContextImplementation( From fa4de8ebf7c0228cdc9b0e828da9930226e84f0a Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Fri, 15 Apr 2022 23:56:52 -0400 Subject: [PATCH 6/7] Format and lint. --- .../communication/test_async_serial.py | 4 +- .../integration/test_controller.py | 1 - .../hardware_control/test_instruments.py | 51 +++++++++++++------ .../opentrons/hardware_control/test_moves.py | 4 +- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py b/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py index 1fd6b627e08..7b160ef5c03 100644 --- a/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py +++ b/api/tests/opentrons/drivers/asyncio/communication/test_async_serial.py @@ -30,9 +30,7 @@ def mock_serial( @pytest.fixture -async def subject( - mock_serial: MagicMock -) -> AsyncSerial: +async def subject(mock_serial: MagicMock) -> AsyncSerial: """The test subject.""" return AsyncSerial( serial=mock_serial, diff --git a/api/tests/opentrons/hardware_control/integration/test_controller.py b/api/tests/opentrons/hardware_control/integration/test_controller.py index 564fd9c222d..2015817c5dc 100644 --- a/api/tests/opentrons/hardware_control/integration/test_controller.py +++ b/api/tests/opentrons/hardware_control/integration/test_controller.py @@ -1,4 +1,3 @@ -import asyncio from typing import Iterator import pytest diff --git a/api/tests/opentrons/hardware_control/test_instruments.py b/api/tests/opentrons/hardware_control/test_instruments.py index 16e87f25a3d..ae801ad1e0c 100644 --- a/api/tests/opentrons/hardware_control/test_instruments.py +++ b/api/tests/opentrons/hardware_control/test_instruments.py @@ -124,7 +124,9 @@ def get_plunger_speed(api): async def test_cache_instruments(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) await hw_api.cache_instruments() attached = hw_api.attached_instruments typeguard.check_type("left mount dict", attached[types.Mount.LEFT], PipetteDict) @@ -132,7 +134,9 @@ async def test_cache_instruments(sim_and_instr): async def test_mismatch_fails(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) requested_instr = { types.Mount.LEFT: "p20_single_gen2", types.Mount.RIGHT: "p300_single", @@ -141,12 +145,11 @@ async def test_mismatch_fails(sim_and_instr): await hw_api.cache_instruments(requested_instr) -async def test_backwards_compatibility( - dummy_backwards_compatibility, sim_and_instr -): +async def test_backwards_compatibility(dummy_backwards_compatibility, sim_and_instr): sim_builder, _ = sim_and_instr hw_api = await sim_builder( - attached_instruments=dummy_backwards_compatibility, loop=asyncio.get_running_loop() + attached_instruments=dummy_backwards_compatibility, + loop=asyncio.get_running_loop(), ) requested_instr = {types.Mount.LEFT: "p10_single", types.Mount.RIGHT: "p300_single"} volumes = { @@ -295,7 +298,9 @@ def fake_func2(mount, value): async def test_prep_aspirate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) await hw_api.home() await hw_api.cache_instruments() @@ -351,7 +356,9 @@ async def test_aspirate_old(dummy_instruments, old_aspiration): async def test_aspirate_ot3(dummy_instruments_ot3, ot3_api_obj): - hw_api = await ot3_api_obj(attached_instruments=dummy_instruments_ot3, loop=asyncio.get_running_loop()) + hw_api = await ot3_api_obj( + attached_instruments=dummy_instruments_ot3, loop=asyncio.get_running_loop() + ) await hw_api.home() await hw_api.cache_instruments() @@ -394,7 +401,9 @@ async def test_dispense_ot2(dummy_instruments): async def test_dispense_ot3(dummy_instruments_ot3, ot3_api_obj): - hw_api = await ot3_api_obj(attached_instruments=dummy_instruments_ot3, loop=asyncio.get_running_loop()) + hw_api = await ot3_api_obj( + attached_instruments=dummy_instruments_ot3, loop=asyncio.get_running_loop() + ) await hw_api.home() await hw_api.cache_instruments() @@ -419,7 +428,9 @@ async def test_dispense_ot3(dummy_instruments_ot3, ot3_api_obj): async def test_no_pipette(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) await hw_api.cache_instruments() aspirate_ul = 3.0 aspirate_rate = 2 @@ -430,7 +441,9 @@ async def test_no_pipette(sim_and_instr): async def test_pick_up_tip(is_robot, sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -486,7 +499,9 @@ def assert_move_called(mock_move, speed, lock=None): async def test_aspirate_flow_rate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -543,7 +558,9 @@ async def test_aspirate_flow_rate(sim_and_instr): async def test_dispense_flow_rate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -598,7 +615,9 @@ async def test_dispense_flow_rate(sim_and_instr): async def test_blowout_flow_rate(sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) mount = types.Mount.LEFT await hw_api.home() await hw_api.cache_instruments() @@ -636,7 +655,9 @@ async def test_blowout_flow_rate(sim_and_instr): async def test_reset_instruments(monkeypatch, sim_and_instr): sim_builder, dummy_instruments = sim_and_instr - hw_api = await sim_builder(attached_instruments=dummy_instruments, loop=asyncio.get_running_loop()) + hw_api = await sim_builder( + attached_instruments=dummy_instruments, loop=asyncio.get_running_loop() + ) hw_api.set_flow_rate(types.Mount.LEFT, 20) # gut check assert hw_api.attached_instruments[types.Mount.LEFT]["aspirate_flow_rate"] == 20 diff --git a/api/tests/opentrons/hardware_control/test_moves.py b/api/tests/opentrons/hardware_control/test_moves.py index 4d7cebcea0a..159f8f8d163 100644 --- a/api/tests/opentrons/hardware_control/test_moves.py +++ b/api/tests/opentrons/hardware_control/test_moves.py @@ -321,7 +321,9 @@ async def mock_move( nonlocal called_with called_with = position - hardware_api = await hc.API.build_hardware_simulator(loop=asyncio.get_running_loop()) + hardware_api = await hc.API.build_hardware_simulator( + loop=asyncio.get_running_loop() + ) monkeypatch.setattr(hardware_api._backend, "move", mock_move) deck_cal = RobotCalibration( deck_calibration=DeckCalibration( From ac53e0d2c9d6b378c5a2b8e674c4700081d0de78 Mon Sep 17 00:00:00 2001 From: amitlissack Date: Tue, 19 Apr 2022 11:41:28 -0400 Subject: [PATCH 7/7] fix(api): Less magical async tests fix (#9990) * module instances clean themselves up --- api/tests/opentrons/conftest.py | 12 +- .../modules/test_hc_tempdeck.py | 105 +++++------- .../modules/test_hc_thermocycler.py | 150 ++++++++---------- .../test_execution_manager.py | 2 + .../hardware_control/test_modules.py | 116 ++++++++++---- 5 files changed, 203 insertions(+), 182 deletions(-) diff --git a/api/tests/opentrons/conftest.py b/api/tests/opentrons/conftest.py index 0f0a4047c3e..f5d32781b05 100755 --- a/api/tests/opentrons/conftest.py +++ b/api/tests/opentrons/conftest.py @@ -170,6 +170,8 @@ async def _build_ot2_hw() -> AsyncIterator[ThreadManager[HardwareControlAPI]]: yield hw_sim finally: config.robot_configs.clear() + for m in hw_sim.attached_modules: + await m.cleanup() hw_sim.set_config(old_config) hw_sim.clean_up() @@ -189,6 +191,8 @@ async def _build_ot3_hw() -> AsyncIterator[ThreadManager[HardwareControlAPI]]: yield hw_sim finally: config.robot_configs.clear() + for m in hw_sim.attached_modules: + await m.cleanup() hw_sim.set_config(old_config) hw_sim.clean_up() @@ -233,11 +237,15 @@ async def hardware(request, virtual_smoothie_env): # Async because ProtocolContext.__init__() needs an event loop, # so this fixture needs to run in an event loop. @pytest.fixture -async def ctx(hardware) -> ProtocolContext: - return ProtocolContext( +async def ctx(hardware) -> AsyncIterator[ProtocolContext]: + c = ProtocolContext( implementation=ProtocolContextImplementation(sync_hardware=hardware.sync), loop=asyncio.get_running_loop(), ) + yield c + # Manually clean up all the modules. + for m in c.loaded_modules.items(): + m[1]._module.cleanup() @pytest.fixture diff --git a/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py b/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py index c8eb805cbae..ae80a173ad7 100644 --- a/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py +++ b/api/tests/opentrons/hardware_control/modules/test_hc_tempdeck.py @@ -18,7 +18,9 @@ def usb_port(): ) -async def test_sim_initialization(usb_port): +@pytest.fixture +async def subject(usb_port: USBPort) -> modules.AbstractModule: + """Test subject""" temp = await modules.build( port="/dev/ot_module_sim_tempdeck0", usb_port=usb_port, @@ -27,78 +29,57 @@ async def test_sim_initialization(usb_port): loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) - assert isinstance(temp, modules.AbstractModule) + yield temp + await temp.cleanup() -async def test_sim_state(usb_port): - temp = await modules.TempDeck.build( - port="/dev/ot_module_sim_tempdeck0", - usb_port=usb_port, - simulating=True, - interrupt_callback=lambda x: None, - loop=asyncio.get_running_loop(), - execution_manager=ExecutionManager(), - ) - await temp.wait_next_poll() - assert temp.temperature == 0 - assert temp.target is None - assert temp.status == "idle" - assert temp.live_data["status"] == temp.status - assert temp.live_data["data"]["currentTemp"] == temp.temperature - assert temp.live_data["data"]["targetTemp"] == temp.target - status = temp.device_info +async def test_sim_initialization(subject: modules.AbstractModule): + assert isinstance(subject, modules.AbstractModule) + + +async def test_sim_state(subject: modules.AbstractModule): + await subject.wait_next_poll() + assert subject.temperature == 0 + assert subject.target is None + assert subject.status == "idle" + assert subject.live_data["status"] == subject.status + assert subject.live_data["data"]["currentTemp"] == subject.temperature + assert subject.live_data["data"]["targetTemp"] == subject.target + status = subject.device_info assert status["serial"] == "dummySerialTD" # return v1 if sim_model is not passed assert status["model"] == "temp_deck_v1.1" assert status["version"] == "dummyVersionTD" -async def test_sim_update(usb_port): - temp = await modules.TempDeck.build( - port="/dev/ot_module_sim_tempdeck0", - usb_port=usb_port, - simulating=True, - interrupt_callback=lambda x: None, - loop=asyncio.get_running_loop(), - execution_manager=ExecutionManager(), - polling_frequency=0, - ) - await temp.set_temperature(10) - assert temp.temperature == 10 - assert temp.target == 10 - assert temp.status == "holding at target" - await temp.deactivate() - await temp.wait_next_poll() - assert temp.temperature == 23 - assert temp.target is None - assert temp.status == "idle" - - -async def test_revision_model_parsing(usb_port): - mag = await modules.TempDeck.build( - port="", - simulating=True, - usb_port=usb_port, - interrupt_callback=lambda x: None, - loop=asyncio.get_running_loop(), - execution_manager=ExecutionManager(), - polling_frequency=0, - ) - mag._device_info["model"] = "temp_deck_v20" - assert mag.model() == "temperatureModuleV2" - mag._device_info["model"] = "temp_deck_v4.0" - assert mag.model() == "temperatureModuleV1" - del mag._device_info["model"] - assert mag.model() == "temperatureModuleV1" - mag._device_info["model"] = "temp_deck_v1.1" - assert mag.model() == "temperatureModuleV1" +async def test_sim_update(subject: modules.AbstractModule): + await subject.set_temperature(10) + assert subject.temperature == 10 + assert subject.target == 10 + assert subject.status == "holding at target" + await subject.deactivate() + await subject.wait_next_poll() + assert subject.temperature == 23 + assert subject.target is None + assert subject.status == "idle" -async def test_poll_error(usb_port) -> None: +async def test_revision_model_parsing(subject: modules.AbstractModule): + subject._device_info["model"] = "temp_deck_v20" + assert subject.model() == "temperatureModuleV2" + subject._device_info["model"] = "temp_deck_v4.0" + assert subject.model() == "temperatureModuleV1" + del subject._device_info["model"] + assert subject.model() == "temperatureModuleV1" + subject._device_info["model"] = "temp_deck_v1.1" + assert subject.model() == "temperatureModuleV1" + + +async def test_poll_error(usb_port: USBPort) -> None: mock_driver = AsyncMock(spec=AbstractTempDeckDriver) mock_driver.get_temperature.side_effect = ValueError("hello!") - magdeck = modules.TempDeck( + tempdeck = modules.TempDeck( port="", usb_port=usb_port, execution_manager=AsyncMock(spec=ExecutionManager), @@ -108,4 +89,6 @@ async def test_poll_error(usb_port) -> None: polling_frequency=1, ) with pytest.raises(ValueError, match="hello!"): - await magdeck.wait_next_poll() + await tempdeck.wait_next_poll() + + await tempdeck.cleanup() diff --git a/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py b/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py index 090d2a1d194..c7b31d5f286 100644 --- a/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py +++ b/api/tests/opentrons/hardware_control/modules/test_hc_thermocycler.py @@ -18,7 +18,9 @@ def usb_port() -> USBPort: ) -async def test_sim_initialization(usb_port): +@pytest.fixture +async def subject(usb_port: USBPort) -> modules.Thermocycler: + """Test subject""" therm = await modules.build( port="/dev/ot_module_sim_thermocycler0", usb_port=usb_port, @@ -27,105 +29,82 @@ async def test_sim_initialization(usb_port): loop=asyncio.get_running_loop(), execution_manager=ExecutionManager(), ) + yield therm + await therm.cleanup() - assert isinstance(therm, modules.AbstractModule) +async def test_sim_initialization(subject: modules.Thermocycler): + assert isinstance(subject, modules.AbstractModule) -async def test_lid(usb_port): - therm = await modules.build( - port="/dev/ot_module_sim_thermocycler0", - usb_port=usb_port, - which="thermocycler", - simulating=True, - loop=asyncio.get_running_loop(), - execution_manager=ExecutionManager(), - ) - await therm.open() - await therm.wait_next_poll() - assert therm.lid_status == "open" +async def test_lid(subject: modules.Thermocycler): + await subject.open() + await subject.wait_next_poll() + assert subject.lid_status == "open" - await therm.close() - await therm.wait_next_poll() - assert therm.lid_status == "closed" + await subject.close() + await subject.wait_next_poll() + assert subject.lid_status == "closed" - await therm.close() - await therm.wait_next_poll() - assert therm.lid_status == "closed" + await subject.close() + await subject.wait_next_poll() + assert subject.lid_status == "closed" - await therm.open() - await therm.wait_next_poll() - assert therm.lid_status == "open" + await subject.open() + await subject.wait_next_poll() + assert subject.lid_status == "open" -async def test_sim_state(usb_port): - therm = await modules.build( - port="/dev/ot_module_sim_thermocycler0", - usb_port=usb_port, - which="thermocycler", - simulating=True, - loop=asyncio.get_running_loop(), - execution_manager=ExecutionManager(), - ) - - assert therm.temperature is None - assert therm.target is None - assert therm.status == "error" - assert therm.live_data["status"] == therm.status - assert therm.live_data["data"]["currentTemp"] == therm.temperature - assert therm.live_data["data"]["targetTemp"] == therm.target - status = therm.device_info +async def test_sim_state(subject: modules.Thermocycler): + assert subject.temperature == 23 + assert subject.target is None + assert subject.status == "idle" + assert subject.live_data["status"] == subject.status + assert subject.live_data["data"]["currentTemp"] == subject.temperature + assert subject.live_data["data"]["targetTemp"] == subject.target + status = subject.device_info assert status["serial"] == "dummySerialTC" assert status["model"] == "dummyModelTC" assert status["version"] == "dummyVersionTC" -async def test_sim_update(usb_port): - therm = await modules.build( - port="/dev/ot_module_sim_thermocycler0", - usb_port=usb_port, - which="thermocycler", - simulating=True, - loop=asyncio.get_running_loop(), - execution_manager=ExecutionManager(), - ) - - await therm.set_temperature( +async def test_sim_update(subject: modules.Thermocycler): + await subject.set_temperature( temperature=10, hold_time_seconds=None, hold_time_minutes=None, volume=50 ) - await therm.wait_next_poll() - assert therm.temperature == 10 - assert therm.target == 10 - assert therm.status == "holding at target" - # await asyncio.wait_for(therm.wait_for_temp(), timeout=0.2) - await therm.deactivate_block() - await therm.wait_next_poll() - assert therm.temperature == 23 - assert therm.target is None - assert therm.status == "idle" - - await therm.set_lid_temperature(temperature=80) - assert therm.lid_temp == 80 - assert therm.lid_target == 80 - - await therm.deactivate_lid() - await therm.wait_next_poll() - assert therm.lid_temp == 23 - assert therm.lid_target is None - - await therm.set_temperature(temperature=10, volume=60, hold_time_seconds=2) - await therm.set_lid_temperature(temperature=70) - assert therm.temperature == 10 - assert therm.target == 10 - assert therm.lid_temp == 70 - assert therm.lid_target == 70 - await therm.deactivate() - await therm.wait_next_poll() - assert therm.temperature == 23 - assert therm.target is None - assert therm.status == "idle" - assert therm.lid_temp == 23 - assert therm.lid_target is None + await subject.wait_next_poll() + assert subject.temperature == 10 + assert subject.target == 10 + assert subject.status == "holding at target" + + await subject.deactivate_block() + await subject.wait_next_poll() + assert subject.temperature == 23 + assert subject.target is None + assert subject.status == "idle" + + await subject.set_lid_temperature(temperature=80) + assert subject.lid_temp == 80 + assert subject.lid_target == 80 + + await subject.deactivate_lid() + await subject.wait_next_poll() + assert subject.lid_temp == 23 + assert subject.lid_target is None + + await subject.set_temperature(temperature=10, volume=60, hold_time_seconds=2) + await subject.set_lid_temperature(temperature=70) + assert subject.temperature == 10 + assert subject.target == 10 + assert subject.lid_temp == 70 + assert subject.lid_target == 70 + await subject.deactivate() + await subject.wait_next_poll() + assert subject.temperature == 23 + assert subject.target is None + assert subject.status == "idle" + assert subject.lid_temp == 23 + assert subject.lid_target is None @pytest.fixture @@ -161,7 +140,8 @@ async def set_temperature_subject( device_info={}, polling_interval_sec=0.001, ) - return hw_tc + yield hw_tc + await hw_tc.cleanup() async def test_set_temperature_with_volume( diff --git a/api/tests/opentrons/hardware_control/test_execution_manager.py b/api/tests/opentrons/hardware_control/test_execution_manager.py index 4ad3c4475e0..0b3b0f6b2f8 100644 --- a/api/tests/opentrons/hardware_control/test_execution_manager.py +++ b/api/tests/opentrons/hardware_control/test_execution_manager.py @@ -73,3 +73,5 @@ async def fake_task(): assert len(all_tasks) == 2 # current and other assert other_task in all_tasks assert cancellable_task not in all_tasks + + other_task.cancel() diff --git a/api/tests/opentrons/hardware_control/test_modules.py b/api/tests/opentrons/hardware_control/test_modules.py index e2863d2823f..f9cbce26ba7 100644 --- a/api/tests/opentrons/hardware_control/test_modules.py +++ b/api/tests/opentrons/hardware_control/test_modules.py @@ -21,6 +21,8 @@ async def test_get_modules_simulating(): await asyncio.sleep(0.05) from_api = api.attached_modules assert sorted([mod.name() for mod in from_api]) == sorted(mods) + for m in api.attached_modules: + await m.cleanup() async def test_module_caching(): @@ -84,24 +86,16 @@ async def test_filtering_modules(): assert len(filtered_modules) == 2 assert filtered_modules == api.attached_modules[2:4] + for m in api.attached_modules: + await m.cleanup() -async def test_module_update_integration(monkeypatch): + +@pytest.fixture +async def mod_tempdeck(): from opentrons.hardware_control import modules loop = asyncio.get_running_loop() - def async_return(result): - f = asyncio.Future() - f.set_result(result) - return f - - bootloader_kwargs = { - "stdout": asyncio.subprocess.PIPE, - "stderr": asyncio.subprocess.PIPE, - "loop": loop, - } - - # test temperature module update with avrdude bootloader usb_port = USBPort( name="", hub=None, @@ -118,26 +112,22 @@ def async_return(result): execution_manager=ExecutionManager(), sim_model="temperatureModuleV2", ) + yield tempdeck + await tempdeck.cleanup() - upload_via_avrdude_mock = mock.Mock( - return_value=(async_return((True, "avrdude bootloader worked"))) - ) - monkeypatch.setattr(modules.update, "upload_via_avrdude", upload_via_avrdude_mock) - async def mock_find_avrdude_bootloader_port(): - return "ot_module_avrdude_bootloader1" +@pytest.fixture +async def mod_magdeck(): + from opentrons.hardware_control import modules - monkeypatch.setattr( - modules.update, "find_bootloader_port", mock_find_avrdude_bootloader_port - ) + loop = asyncio.get_running_loop() - await modules.update_firmware(tempdeck, "fake_fw_file_path", loop) - upload_via_avrdude_mock.assert_called_once_with( - "ot_module_avrdude_bootloader1", "fake_fw_file_path", bootloader_kwargs + usb_port = USBPort( + name="", + hub=None, + port_number=0, + device_path="/dev/ot_module_sim_magdeck0", ) - upload_via_avrdude_mock.reset_mock() - - # test magnetic module update with avrdude bootloader magdeck = await modules.build( port="/dev/ot_module_sim_magdeck0", @@ -147,13 +137,22 @@ async def mock_find_avrdude_bootloader_port(): loop=loop, execution_manager=ExecutionManager(), ) + yield magdeck + await magdeck.cleanup() - await modules.update_firmware(magdeck, "fake_fw_file_path", loop) - upload_via_avrdude_mock.assert_called_once_with( - "ot_module_avrdude_bootloader1", "fake_fw_file_path", bootloader_kwargs - ) - # test thermocycler module update with bossa bootloader +@pytest.fixture +async def mod_thermocycler(): + from opentrons.hardware_control import modules + + loop = asyncio.get_running_loop() + + usb_port = USBPort( + name="", + hub=None, + port_number=0, + device_path="/dev/ot_module_sim_thermocycler0", + ) thermocycler = await modules.build( port="/dev/ot_module_sim_thermocycler0", @@ -163,7 +162,54 @@ async def mock_find_avrdude_bootloader_port(): loop=loop, execution_manager=ExecutionManager(), ) + yield thermocycler + await thermocycler.cleanup() + + +async def test_module_update_integration( + monkeypatch, mod_tempdeck, mod_magdeck, mod_thermocycler +): + from opentrons.hardware_control import modules + + loop = asyncio.get_running_loop() + + def async_return(result): + f = asyncio.Future() + f.set_result(result) + return f + bootloader_kwargs = { + "stdout": asyncio.subprocess.PIPE, + "stderr": asyncio.subprocess.PIPE, + "loop": loop, + } + + upload_via_avrdude_mock = mock.Mock( + return_value=(async_return((True, "avrdude bootloader worked"))) + ) + monkeypatch.setattr(modules.update, "upload_via_avrdude", upload_via_avrdude_mock) + + async def mock_find_avrdude_bootloader_port(): + return "ot_module_avrdude_bootloader1" + + monkeypatch.setattr( + modules.update, "find_bootloader_port", mock_find_avrdude_bootloader_port + ) + + # test temperature module update with avrdude bootloader + await modules.update_firmware(mod_tempdeck, "fake_fw_file_path", loop) + upload_via_avrdude_mock.assert_called_once_with( + "ot_module_avrdude_bootloader1", "fake_fw_file_path", bootloader_kwargs + ) + upload_via_avrdude_mock.reset_mock() + + # test magnetic module update with avrdude bootloader + await modules.update_firmware(mod_magdeck, "fake_fw_file_path", loop) + upload_via_avrdude_mock.assert_called_once_with( + "ot_module_avrdude_bootloader1", "fake_fw_file_path", bootloader_kwargs + ) + + # test thermocycler module update with bossa bootloader upload_via_bossa_mock = mock.Mock( return_value=(async_return((True, "bossa bootloader worked"))) ) @@ -176,7 +222,7 @@ async def mock_find_bossa_bootloader_port(): modules.update, "find_bootloader_port", mock_find_bossa_bootloader_port ) - await modules.update_firmware(thermocycler, "fake_fw_file_path", loop) + await modules.update_firmware(mod_thermocycler, "fake_fw_file_path", loop) upload_via_bossa_mock.assert_called_once_with( "ot_module_bossa_bootloader1", "fake_fw_file_path", bootloader_kwargs ) @@ -215,6 +261,8 @@ async def test_get_bundled_fw(monkeypatch, tmpdir): assert api.attached_modules[2].bundled_fw == BundledFirmware( version="0.1.2", path=dummy_tc_file ) + for m in api.attached_modules: + await m.cleanup() @pytest.mark.parametrize(