From dbe3c163bdd1e7bb7e5ef95d7d887729022deb93 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sun, 13 Dec 2020 13:28:42 +0100 Subject: [PATCH] run spec tests in parallel reduces time to run postgrest-test-spec-all by 20-25% --- test/Feature/InsertSpec.hs | 23 ++++++++------- test/Feature/RollbackSpec.hs | 18 ++++++------ test/Feature/UpdateSpec.hs | 22 ++------------ test/Main.hs | 56 ++++++++++++++++++++---------------- test/fixtures/privileges.sql | 3 ++ test/fixtures/schema.sql | 4 +++ 6 files changed, 61 insertions(+), 65 deletions(-) diff --git a/test/Feature/InsertSpec.hs b/test/Feature/InsertSpec.hs index 956e3d971..93312d5c4 100644 --- a/test/Feature/InsertSpec.hs +++ b/test/Feature/InsertSpec.hs @@ -293,29 +293,30 @@ spec actualPgVersion = do -- reset pk sequence first to make test repeatable request methodPost "/rpc/reset_sequence" [("Prefer", "tx=commit")] - [json|{"name": "items_id_seq", "value": 20}|] + [json|{"name": "items2_id_seq", "value": 20}|] `shouldRespondWith` [json|""|] - request methodPost "/items" [("Prefer", "return=representation")] "{}" - `shouldRespondWith` [json|[{ id: 20 }]|] - { matchStatus = 201, - matchHeaders = [] - } + request methodPost "/items2" + [("Prefer", "return=representation")] + [json|{}|] + `shouldRespondWith` + [json|[{ id: 20 }]|] + { matchStatus = 201 } it "successfully inserts a row with all-default columns with prefer=rep and &select=" $ do -- reset pk sequence first to make test repeatable request methodPost "/rpc/reset_sequence" [("Prefer", "tx=commit")] - [json|{"name": "items_id_seq", "value": 20}|] + [json|{"name": "items3_id_seq", "value": 20}|] `shouldRespondWith` [json|""|] - request methodPost "/items?select=id" [("Prefer", "return=representation")] "{}" + request methodPost "/items3?select=id" + [("Prefer", "return=representation")] + [json|{}|] `shouldRespondWith` [json|[{ id: 20 }]|] - { matchStatus = 201, - matchHeaders = [] - } + { matchStatus = 201 } context "POST with ?columns parameter" $ do it "ignores json keys not included in ?columns" $ do diff --git a/test/Feature/RollbackSpec.hs b/test/Feature/RollbackSpec.hs index 227c36447..db18f8b98 100644 --- a/test/Feature/RollbackSpec.hs +++ b/test/Feature/RollbackSpec.hs @@ -80,7 +80,7 @@ shouldPersistMutations reqHeaders respHeaders = do [json|[{"id":0}]|] { matchStatus = 201 , matchHeaders = respHeaders } - get "items?id=eq.0" + get "/items?id=eq.0" `shouldRespondWith` [json|[{"id":0}]|] deleteItems @@ -92,7 +92,7 @@ shouldPersistMutations reqHeaders respHeaders = do `shouldRespondWith` [json|[{"id":0}]|] { matchHeaders = respHeaders } - get "items?id=eq.0" + get "/items?id=eq.0" `shouldRespondWith` [json|[{"id":0}]|] deleteItems @@ -105,10 +105,10 @@ shouldPersistMutations reqHeaders respHeaders = do `shouldRespondWith` [json|[{"id":-1}]|] { matchHeaders = respHeaders } - get "items?id=eq.0" + get "/items?id=eq.0" `shouldRespondWith` [json|[]|] - get "items?id=eq.-1" + get "/items?id=eq.-1" `shouldRespondWith` [json|[{"id":-1}]|] deleteItems @@ -121,7 +121,7 @@ shouldPersistMutations reqHeaders respHeaders = do `shouldRespondWith` [json|[{"id":0}]|] { matchHeaders = respHeaders } - get "items?id=eq.0" + get "/items?id=eq.0" `shouldRespondWith` [json|[]|] @@ -134,7 +134,7 @@ shouldNotPersistMutations reqHeaders respHeaders = do [json|[{"id":0}]|] { matchStatus = 201 , matchHeaders = respHeaders } - get "items?id=eq.0" + get "/items?id=eq.0" `shouldRespondWith` [json|[]|] @@ -145,7 +145,7 @@ shouldNotPersistMutations reqHeaders respHeaders = do `shouldRespondWith` [json|[{"id":0}]|] { matchHeaders = respHeaders } - get "items?id=eq.0" + get "/items?id=eq.0" `shouldRespondWith` [json|[]|] @@ -156,7 +156,7 @@ shouldNotPersistMutations reqHeaders respHeaders = do `shouldRespondWith` [json|[{"id":0}]|] { matchHeaders = respHeaders } - get "items?id=eq.0" + get "/items?id=eq.0" `shouldRespondWith` [json|[]|] get "items?id=eq.1" @@ -170,7 +170,7 @@ shouldNotPersistMutations reqHeaders respHeaders = do `shouldRespondWith` [json|[{"id":1}]|] { matchHeaders = respHeaders } - get "items?id=eq.1" + get "/items?id=eq.1" `shouldRespondWith` [json|[{"id":1}]|] diff --git a/test/Feature/UpdateSpec.hs b/test/Feature/UpdateSpec.hs index 60888eef0..11dc721b4 100644 --- a/test/Feature/UpdateSpec.hs +++ b/test/Feature/UpdateSpec.hs @@ -51,32 +51,14 @@ spec = do context "in a nonempty table" $ do it "can update a single item" $ do - get "/items?id=eq.42" - `shouldRespondWith` - [json|[]|] - - request methodPatch "/items?id=eq.2" - [("Prefer", "tx=commit")] + patch "/items?id=eq.2" [json| { "id":42 } |] `shouldRespondWith` "" { matchStatus = 204 - , matchHeaders = ["Content-Range" <:> "0-0/*" - , "Preference-Applied" <:> "tx=commit" ] + , matchHeaders = ["Content-Range" <:> "0-0/*"] } - -- check it really got updated - get "/items?id=eq.42" - `shouldRespondWith` - [json|[ { "id": 42 } ]|] - - -- put value back for other tests - request methodPatch "/items?id=eq.42" - [("Prefer", "tx=commit")] - [json| { "id":2 } |] - `shouldRespondWith` - 204 - it "returns empty array when no rows updated and return=rep" $ request methodPatch "/items?id=eq.999999" [("Prefer", "return=representation")] [json| { "id":999999 } |] diff --git a/test/Main.hs b/test/Main.hs index 53bffa3e1..895e6af73 100644 --- a/test/Main.hs +++ b/test/Main.hs @@ -114,7 +114,6 @@ main = do , ("Feature.OptionsSpec" , Feature.OptionsSpec.spec) , ("Feature.QuerySpec" , Feature.QuerySpec.spec actualPgVersion) , ("Feature.RawOutputTypesSpec" , Feature.RawOutputTypesSpec.spec) - , ("Feature.RollbackAllowedSpec" , Feature.RollbackSpec.allowed) , ("Feature.RpcSpec" , Feature.RpcSpec.spec actualPgVersion) , ("Feature.SingularSpec" , Feature.SingularSpec.spec) , ("Feature.UpdateSpec" , Feature.UpdateSpec.spec) @@ -122,56 +121,74 @@ main = do ] hspec $ do - mapM_ (before withApp) specs + mapM_ (parallel . before withApp) specs -- we analyze to get accurate results from EXPLAIN - beforeAll_ analyze . before withApp $ + parallel $ beforeAll_ analyze . before withApp $ describe "Feature.RangeSpec" Feature.RangeSpec.spec -- this test runs with a raw-output-media-types set to text/html - before htmlRawOutputApp $ + parallel $ before htmlRawOutputApp $ describe "Feature.HtmlRawOutputSpec" Feature.HtmlRawOutputSpec.spec -- this test runs with a different server flag - before maxRowsApp $ + parallel $ before maxRowsApp $ describe "Feature.QueryLimitedSpec" Feature.QueryLimitedSpec.spec -- this test runs with a different schema - before unicodeApp $ + parallel $ before unicodeApp $ describe "Feature.UnicodeSpec" Feature.UnicodeSpec.spec -- this test runs with a proxy - before proxyApp $ + parallel $ before proxyApp $ describe "Feature.ProxySpec" Feature.ProxySpec.spec -- this test runs without a JWT secret - before noJwtApp $ + parallel $ before noJwtApp $ describe "Feature.NoJwtSpec" Feature.NoJwtSpec.spec -- this test runs with a binary JWT secret - before binaryJwtApp $ + parallel $ before binaryJwtApp $ describe "Feature.BinaryJwtSecretSpec" Feature.BinaryJwtSecretSpec.spec -- this test runs with a binary JWT secret and an audience claim - before audJwtApp $ + parallel $ before audJwtApp $ describe "Feature.AudienceJwtSecretSpec" Feature.AudienceJwtSecretSpec.spec -- this test runs with asymmetric JWK - before asymJwkApp $ + parallel $ before asymJwkApp $ describe "Feature.AsymmetricJwtSpec" Feature.AsymmetricJwtSpec.spec -- this test runs with asymmetric JWKSet - before asymJwkSetApp $ + parallel $ before asymJwkSetApp $ describe "Feature.AsymmetricJwtSpec" Feature.AsymmetricJwtSpec.spec -- this test runs with a nonexistent db-schema - before nonexistentSchemaApp $ + parallel $ before nonexistentSchemaApp $ describe "Feature.NonexistentSchemaSpec" Feature.NonexistentSchemaSpec.spec -- this test runs with an extra search path - before extraSearchPathApp $ + parallel $ before extraSearchPathApp $ describe "Feature.ExtraSearchPathSpec" Feature.ExtraSearchPathSpec.spec + when (actualPgVersion >= pgVersion96) $ do + -- this test runs with a root spec function override + parallel $ before rootSpecApp $ + describe "Feature.RootSpec" Feature.RootSpec.spec + parallel $ before responseHeadersApp $ + describe "Feature.RpcPreRequestGucsSpec" Feature.RpcPreRequestGucsSpec.spec + + -- this test runs with multiple schemas + parallel $ before multipleSchemaApp $ + describe "Feature.MultipleSchemaSpec" $ Feature.MultipleSchemaSpec.spec actualPgVersion + + -- Note: the rollback tests can not run in parallel, because they test persistance and + -- this results in race conditions + + -- this test runs with tx-rollback-all = true and tx-allow-override = true + before withApp $ + describe"Feature.RollbackAllowedSpec" Feature.RollbackSpec.allowed + -- this test runs with tx-rollback-all = false and tx-allow-override = false before disallowRollbackApp $ describe "Feature.RollbackDisallowedSpec" Feature.RollbackSpec.disallowed @@ -180,17 +197,6 @@ main = do before forceRollbackApp $ describe "Feature.RollbackForcedSpec" Feature.RollbackSpec.forced - when (actualPgVersion >= pgVersion96) $ do - -- this test runs with a root spec function override - before rootSpecApp $ - describe "Feature.RootSpec" Feature.RootSpec.spec - before responseHeadersApp $ - describe "Feature.RpcPreRequestGucsSpec" Feature.RpcPreRequestGucsSpec.spec - - -- this test runs with multiple schemas - before multipleSchemaApp $ - describe "Feature.MultipleSchemaSpec" $ Feature.MultipleSchemaSpec.spec actualPgVersion - where setupDbStructure pool schemas extraSearchPath ver = either (panic.show) id <$> P.use pool (HT.transaction HT.ReadCommitted HT.Read $ getDbStructure (toList schemas) extraSearchPath ver True) diff --git a/test/fixtures/privileges.sql b/test/fixtures/privileges.sql index c31a0497a..a41da7990 100644 --- a/test/fixtures/privileges.sql +++ b/test/fixtures/privileges.sql @@ -16,6 +16,7 @@ SET search_path = test, "تست", pg_catalog; GRANT ALL ON TABLE items , items2 + , items3 , "articleStars" , articles , auto_incrementing_pk @@ -143,6 +144,8 @@ GRANT INSERT ON TABLE insertonly TO postgrest_test_anonymous; GRANT USAGE ON SEQUENCE auto_incrementing_pk_id_seq , items_id_seq + , items2_id_seq + , items3_id_seq , callcounter_count , leak_id_seq TO postgrest_test_anonymous; diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index f4c613113..1f218b6cd 100644 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -113,6 +113,10 @@ CREATE TABLE items2 ( id bigserial primary key ); +CREATE TABLE items3 ( + id bigserial primary key +); + CREATE FUNCTION search(id BIGINT) RETURNS SETOF items LANGUAGE plpgsql AS $$BEGIN