def feature(self, node="clickhouse1"): """Check show create role query syntax. ```sql SHOW CREATE ROLE name ``` """ node = self.context.cluster.node(node) @contextmanager def setup(role): try: with Given("I have a role"): node.query(f"CREATE ROLE OR REPLACE {role}") yield finally: with Finally("I drop the role"): node.query(f"DROP ROLE IF EXISTS {role}") with Scenario("I show create role", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_ShowCreate("1.0")]): with setup("role0"): with When("I run show create role command"): node.query("SHOW CREATE ROLE role0") with Scenario("I show create role, role doesn't exist, exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_ShowCreate("1.0")]): with When("I run show create role to catch an exception"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("SHOW CREATE ROLE role0", exitcode=exitcode, message=message)
def feature(self, node="clickhouse1"): """Check alter user query syntax. ```sql ALTER USER [IF EXISTS] name [ON CLUSTER cluster_name] [RENAME TO new_name] [IDENTIFIED [WITH {PLAINTEXT_PASSWORD|SHA256_PASSWORD|DOUBLE_SHA1_PASSWORD}] BY {'password'|'hash'}] [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE] [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ] [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...] ``` """ node = self.context.cluster.node(node) @contextmanager def setup(user): try: with Given("I have a user"): node.query(f"CREATE USER OR REPLACE {user}") yield finally: with Finally("I drop the user", flags=TE): node.query(f"DROP USER IF EXISTS {user}") with Scenario("I alter user, base command", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter("1.0")]): with setup("user0"): with When("I alter user"): node.query("ALTER USER user0") with Scenario( "I alter user that does not exist without if exists, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter("1.0")]): with When("I run alter user command, expecting error 192"): exitcode, message = errors.user_not_found_in_disk(name="user0") node.query(f"ALTER USER user0", exitcode=exitcode, message=message) with Scenario("I alter user with if exists", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_IfExists("1.0")]): with setup("user0"): with When(f"I alter user with if exists"): node.query(f"ALTER USER IF EXISTS user0") with Scenario("I alter user that does not exist with if exists", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_IfExists("1.0")]): user = "******" with Given("I don't have a user"): node.query(f"DROP USER IF EXISTS {user}") with When(f"I alter user {user} with if exists"): node.query(f"ALTER USER IF EXISTS {user}") del user with Scenario("I alter user on a cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Cluster("1.0")]): with Given("I have a user on a cluster"): node.query( "CREATE USER OR REPLACE user0 ON CLUSTER sharded_cluster") with When("I alter user on a cluster"): node.query("ALTER USER user0 ON CLUSTER sharded_cluster") with Finally("I drop user from cluster"): node.query("DROP USER IF EXISTS user0 ON CLUSTER sharded_cluster") with Scenario("I alter user on a fake cluster, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Cluster("1.0")]): with When("I alter user on a fake cluster"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("ALTER USER user0 ON CLUSTER fake_cluster", exitcode=exitcode, message=message) with Scenario("I alter user to rename, target available", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Rename("1.0")]): with setup("user15"): with When("I alter user name"): node.query("ALTER USER user15 RENAME TO user15") with Scenario("I alter user to rename, target unavailable", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Rename("1.0")]): with setup("user15"): new_user = "******" try: with Given(f"Ensure target name {new_user} is NOT available"): node.query(f"CREATE USER IF NOT EXISTS {new_user}") with When(f"I try to rename to {new_user}"): exitcode, message = errors.cannot_rename_user( name="user15", name_new=new_user) node.query(f"ALTER USER user15 RENAME TO {new_user}", exitcode=exitcode, message=message) finally: with Finally(f"I cleanup target name {new_user}"): node.query(f"DROP USER IF EXISTS {new_user}") del new_user with Scenario("I alter user password plaintext password", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_Password_PlainText("1.0") ]): with setup("user1"): with When("I alter user with plaintext password"): node.query( "ALTER USER user1 IDENTIFIED WITH PLAINTEXT_PASSWORD BY 'mypassword'", step=When) with Scenario("I alter user password to sha256", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_Password_Sha256Password("1.0") ]): with setup("user2"): with When("I alter user with sha256_password"): password = hashlib.sha256( "mypassword".encode("utf-8")).hexdigest() node.query( f"ALTER USER user2 IDENTIFIED WITH SHA256_PASSWORD BY '{password}'", step=When) with Scenario( "I alter user password to double_sha1_password", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_Password_DoubleSha1Password("1.0") ]): with setup("user3"): with When("I alter user with double_sha1_password"): def hash(password): return hashlib.sha1(password.encode("utf-8")).hexdigest() password = hash(hash("mypassword")) node.query( f"ALTER USER user3 IDENTIFIED WITH DOUBLE_SHA1_PASSWORD BY '{password}'", step=When) with Scenario("I alter user host local", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Local("1.0")]): with setup("user4"): with When("I alter user with host local"): node.query("ALTER USER user4 HOST LOCAL") with Scenario("I alter user host name", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Name("1.0")]): with setup("user5"): with When("I alter user with host name"): node.query( "ALTER USER user5 HOST NAME 'localhost', NAME 'clickhouse.com'" ) with Scenario("I alter user host regexp", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Regexp("1.0") ]): with setup("user6"): with When("I alter user with host regexp"): node.query( "ALTER USER user6 HOST REGEXP 'lo..*host', 'lo*host'") with Scenario("I alter user host ip", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_IP("1.0")]): with setup("user7"): with When("I alter user with host ip"): node.query( "ALTER USER user7 HOST IP '127.0.0.1', IP '127.0.0.2'") with Scenario("I alter user host like", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Like("1.0")]): with setup("user8"): with When("I alter user with host like"): node.query("ALTER USER user8 HOST LIKE '%.clickhouse.com'") with Scenario("I alter user host any", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Any("1.0")]): with setup("user9"): with When("I alter user with host any"): node.query("ALTER USER user9 HOST ANY") with Scenario("I alter user host many hosts", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Like("1.0")]): with setup("user11"): with When("I alter user with multiple hosts"): node.query("ALTER USER user11 HOST LIKE '%.clickhouse.com', \ IP '127.0.0.2', NAME 'localhost', REGEXP 'lo*host'") with Scenario("I alter user default role set to none", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_None("1.0")]): with setup("user12"): with When("I alter user with default role none"): node.query("ALTER USER user12 DEFAULT ROLE NONE") with Scenario( "I alter user default role set to all", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole_All("1.0")]): with setup("user13"): with When("I alter user with all roles set to default"): node.query("ALTER USER user13 DEFAULT ROLE ALL") @contextmanager def setup_role(role): try: with Given(f"I have a role {role}"): node.query(f"CREATE ROLE OR REPLACE {role}") yield finally: with Finally(f"I drop the role {role}", flags=TE): node.query(f"DROP ROLE IF EXISTS {role}") with Scenario("I alter user default role", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0") ]): with setup("user14"), setup_role("role2"): with Given("I have a user with a role"): node.query("GRANT role2 TO user14") with When("I alter user default role"): node.query("ALTER USER user14 DEFAULT ROLE role2") with Scenario("I alter user default role, setting default role", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0") ]): with setup("user14a"), setup_role("default"): with Given("I grant default role to the user"): node.query("GRANT default TO user14a") with When("I alter user default role"): node.query("ALTER USER user14a DEFAULT ROLE default") with Scenario( "I alter user default role, role doesn't exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]): with setup("user12"): role = "role0" with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with When(f"I alter user with default role {role}"): exitcode, message = errors.role_not_found_in_disk(role) node.query(f"ALTER USER user12 DEFAULT ROLE {role}", exitcode=exitcode, message=message) del role with Scenario( "I alter user default role, all except role doesn't exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]): with setup("user12"): role = "role0" with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with When(f"I alter user with default role {role}"): exitcode, message = errors.role_not_found_in_disk(role) node.query(f"ALTER USER user12 DEFAULT ROLE ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario("I alter user default role multiple", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0") ]): with setup("user15"), setup_role("second"), setup_role("third"): with Given("I have a user with multiple roles"): node.query("GRANT second,third TO user15") with When("I alter user default role to second, third"): node.query("ALTER USER user15 DEFAULT ROLE second, third") with Scenario("I alter user default role set to all except", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_DefaultRole_AllExcept("1.0") ]): with setup("user16"), setup_role("second"): with Given("I have a user with a role"): node.query("GRANT second TO user16") with When("I alter user default role"): node.query("ALTER USER user16 DEFAULT ROLE ALL EXCEPT second") with Scenario("I alter user default role multiple all except", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_DefaultRole_AllExcept("1.0") ]): with setup("user17"), setup_role("second"), setup_role("third"): with Given("I have a user with multiple roles"): node.query("GRANT second,third TO user17") with When("I alter user default role to all except second"): node.query("ALTER USER user17 DEFAULT ROLE ALL EXCEPT second") with Scenario("I alter user settings profile", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_Settings("1.0"), \ RQ_SRS_006_RBAC_User_Alter_Settings_Profile("1.0")]): with setup("user18"): try: with Given("I have a profile"): node.query(f"CREATE SETTINGS PROFILE profile10") with When( "I alter user with settings and set profile to profile1" ): node.query( "ALTER USER user18 SETTINGS PROFILE profile10, max_memory_usage = 100 MIN 0 MAX 1000 READONLY" ) finally: with Finally("I drop the profile"): node.query(f"DROP SETTINGS PROFILE profile10") with Scenario( "I alter user settings profile, fake profile, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_Settings("1.0"), RQ_SRS_006_RBAC_User_Alter_Settings_Profile("1.0") ]): with setup("user18a"): profile = "profile0" with Given(f"I ensure that profile {profile} does not exist"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") with When( f"I alter user with Settings and set profile to fake profile {profile}" ): exitcode, message = errors.settings_profile_not_found_in_disk( profile) node.query("ALTER USER user18a SETTINGS PROFILE profile0", exitcode=exitcode, message=message) del profile with Scenario( "I alter user settings with a fake setting, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Settings("1.0")]): with setup("user18b"): with When( "I alter settings profile using settings and nonexistent value" ): exitcode, message = errors.unknown_setting("fake_setting") node.query( "ALTER USER user18b SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message) with Scenario("I alter user settings without profile (no equals)", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_Settings("1.0"), RQ_SRS_006_RBAC_User_Alter_Settings_Min("1.0"), RQ_SRS_006_RBAC_User_Alter_Settings_Max("1.0") ]): with setup("user19"): with When( "I alter user with settings without profile using no equals" ): node.query( "ALTER USER user19 SETTINGS max_memory_usage=10000000 MIN 100000 MAX 1000000000 READONLY" ) #equals sign (=) syntax verify with Scenario("I alter user settings without profile (yes equals)", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Alter_Settings("1.0"), RQ_SRS_006_RBAC_User_Alter_Settings_Min("1.0"), RQ_SRS_006_RBAC_User_Alter_Settings_Max("1.0") ]): with setup("user20"): with When( "I alter user with settings without profile using equals"): node.query( "ALTER USER user20 SETTINGS max_memory_usage=10000000 MIN=100000 MAX=1000000000 READONLY" ) #Add requirement to host: add/drop with Scenario( "I alter user to add host", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_AddDrop("1.0")]): with setup("user21"): with When("I alter user by adding local host"): node.query("ALTER USER user21 ADD HOST LOCAL") with And("I alter user by adding no host"): node.query("ALTER USER user21 ADD HOST NONE") with And("I alter user by adding host like"): node.query("ALTER USER user21 ADD HOST LIKE 'local%'") with And("I alter user by adding host ip"): node.query("ALTER USER user21 ADD HOST IP '127.0.0.1'") with And("I alter user by adding host name"): node.query("ALTER USER user21 ADD HOST NAME 'localhost'") with Scenario( "I alter user to remove host", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Alter_Host_AddDrop("1.0")]): with setup("user22"): with When("I alter user by removing local host"): node.query("ALTER USER user22 DROP HOST LOCAL") with And("I alter user by removing no host"): node.query("ALTER USER user22 DROP HOST NONE") with And("I alter user by removing like host"): node.query("ALTER USER user22 DROP HOST LIKE 'local%'") with And("I alter user by removing host ip"): node.query("ALTER USER user22 DROP HOST IP '127.0.0.1'") with And("I alter user by removing host name"): node.query("ALTER USER user22 DROP HOST NAME 'localhost'")
def feature(self, node="clickhouse1"): """Check create quota query syntax. ```sql CREATE QUOTA [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name] [KEYED BY {'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address'}] [FOR [RANDOMIZED] INTERVAL number {SECOND | MINUTE | HOUR | DAY} {MAX { {QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME} = number } [,...] | NO LIMITS | TRACKING ONLY} [,...]] [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] ``` """ node = self.context.cluster.node(node) @contextmanager def cleanup(quota): try: with Given("I ensure the quota does not already exist"): node.query(f"DROP QUOTA IF EXISTS {quota}") yield finally: with Finally("I drop the quota"): node.query(f"DROP QUOTA IF EXISTS {quota}") def create_quota(quota): with And(f"I ensure I do have quota {quota}"): node.query(f"CREATE QUOTA OR REPLACE {quota}") try: with Given("I have a user and a role"): node.query(f"CREATE USER user0") node.query(f"CREATE ROLE role0") with Scenario("I create quota with no options", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create("1.0")]): with cleanup("quota0"): with When("I create a quota with no options"): node.query("CREATE QUOTA quota0") with Scenario("I create quota that already exists, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create("1.0")]): quota = "quota0" with cleanup(quota): create_quota(quota) with When( f"I create a quota {quota} that already exists without IF EXISTS, throws exception" ): exitcode, message = errors.cannot_insert_quota(name=quota) node.query(f"CREATE QUOTA {quota}", exitcode=exitcode, message=message) del quota with Scenario("I create quota if not exists, quota does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_IfNotExists("1.0") ]): quota = "quota1" with cleanup(quota): with When(f"I create a quota {quota} with if not exists"): node.query(f"CREATE QUOTA IF NOT EXISTS {quota}") del quota with Scenario("I create quota if not exists, quota does exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_IfNotExists("1.0") ]): quota = "quota1" with cleanup(quota): create_quota(quota) with When(f"I create a quota {quota} with if not exists"): node.query(f"CREATE QUOTA IF NOT EXISTS {quota}") del quota with Scenario( "I create quota or replace, quota does not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Replace("1.0")]): quota = "quota2" with cleanup(quota): with When(f"I create a quota {quota} with or replace"): node.query(f"CREATE QUOTA OR REPLACE {quota}") del quota with Scenario( "I create quota or replace, quota does exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Replace("1.0")]): quota = "quota2" with cleanup(quota): create_quota(quota) with When(f"I create a quota {quota} with or replace"): node.query(f"CREATE QUOTA OR REPLACE {quota}") del quota keys = [ 'none', 'user name', 'ip address', 'client key', 'client key or user name', 'client key or ip address' ] for i, key in enumerate(keys): with Scenario( f"I create quota keyed by {key}", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_KeyedBy("1.0"), RQ_SRS_006_RBAC_Quota_Create_KeyedByOptions("1.0") ]): name = f'quota{3 + i}' with cleanup(name): with When(f"I create a quota with {key}"): node.query(f"CREATE QUOTA {name} KEYED BY '{key}'") with Scenario( "I create quota for randomized interval", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Interval_Randomized("1.0") ]): with cleanup("quota9"): with When("I create a quota for randomized interval"): node.query( "CREATE QUOTA quota9 FOR RANDOMIZED INTERVAL 1 DAY NO LIMITS" ) intervals = ['SECOND', 'MINUTE', 'HOUR', 'DAY', 'MONTH'] for i, interval in enumerate(intervals): with Scenario(f"I create quota for interval {interval}", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Interval("1.0") ]): name = f'quota{10 + i}' with cleanup(name): with When(f"I create a quota for {interval} interval"): node.query( f"CREATE QUOTA {name} FOR INTERVAL 1 {interval} NO LIMITS" ) constraints = [ 'MAX QUERIES', 'MAX ERRORS', 'MAX RESULT ROWS', 'MAX RESULT BYTES', 'MAX READ ROWS', 'MAX READ BYTES', 'MAX EXECUTION TIME', 'NO LIMITS', 'TRACKING ONLY' ] for i, constraint in enumerate(constraints): with Scenario( f"I create quota for {constraint.lower()}", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Queries("1.0"), RQ_SRS_006_RBAC_Quota_Create_Errors("1.0"), RQ_SRS_006_RBAC_Quota_Create_ResultRows("1.0"), RQ_SRS_006_RBAC_Quota_Create_ResultBytes("1.0"), RQ_SRS_006_RBAC_Quota_Create_ReadRows("1.0"), RQ_SRS_006_RBAC_Quota_Create_ReadBytes("1.0"), RQ_SRS_006_RBAC_Quota_Create_ExecutionTime("1.0"), RQ_SRS_006_RBAC_Quota_Create_NoLimits("1.0"), RQ_SRS_006_RBAC_Quota_Create_TrackingOnly("1.0") ]): name = f'quota{15 + i}' with cleanup(name): with When(f"I create quota for {constraint.lower()}"): node.query( f"CREATE QUOTA {name} FOR INTERVAL 1 DAY {constraint}{' 1024' if constraint.startswith('MAX') else ''}" ) with Scenario("I create quota for multiple constraints", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Interval("1.0"), RQ_SRS_006_RBAC_Quota_Create_Queries("1.0") ]): with cleanup("quota23"): with When(f"I create quota for multiple constraints"): node.query('CREATE QUOTA quota23 \ FOR INTERVAL 1 DAY NO LIMITS, \ FOR INTERVAL 2 DAY MAX QUERIES 124, \ FOR INTERVAL 1 HOUR TRACKING ONLY') with Scenario( "I create quota assigned to one role", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]): with cleanup("quota24"): with When("I create quota for role"): node.query("CREATE QUOTA quota24 TO role0") with Scenario( "I create quota to assign to role that does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I create a quota, assign to role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"CREATE QUOTA quota0 TO {role}", exitcode=exitcode, message=message) del role with Scenario( "I create quota to assign to all except role that does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I create a quota, assign to all except role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"CREATE QUOTA quota0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario("I create quota assigned to no role", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Assignment_None("1.0") ]): with When("I create quota for no role"): node.query("CREATE QUOTA quota24 TO NONE") with Scenario( "I create quota assigned to multiple roles", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]): with cleanup("quota25"): with When("I create quota for multiple roles"): node.query("CREATE QUOTA quota25 TO role0, user0") with Scenario("I create quota assigned to all", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Assignment_All("1.0") ]): with cleanup("quota26"): with When("I create quota for all"): node.query("CREATE QUOTA quota26 TO ALL") with Scenario("I create quota assigned to all except one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Assignment_Except("1.0") ]): with cleanup("quota27"): with When("I create quota for all except one role"): node.query("CREATE QUOTA quota27 TO ALL EXCEPT role0") with Scenario("I create quota assigned to all except multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Create_Assignment_Except("1.0") ]): with cleanup("quota28"): with When("I create quota for all except multiple roles"): node.query( "CREATE QUOTA quota28 TO ALL EXCEPT role0, user0") with Scenario( "I create quota on cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Cluster("1.0")]): try: with When("I run create quota command on cluster"): node.query( "CREATE QUOTA quota29 ON CLUSTER sharded_cluster") with When("I run create quota command on cluster, keyed"): node.query( "CREATE QUOTA OR REPLACE quota29 ON CLUSTER sharded_cluster KEYED BY 'none'" ) with When("I run create quota command on cluster, interval"): node.query( "CREATE QUOTA OR REPLACE quota29 ON CLUSTER sharded_cluster FOR INTERVAL 1 DAY TRACKING ONLY" ) with When("I run create quota command on cluster, assign"): node.query( "CREATE QUOTA OR REPLACE quota29 ON CLUSTER sharded_cluster TO ALL" ) finally: with Finally("I drop the quota from cluster"): node.query( "DROP QUOTA IF EXISTS quota29 ON CLUSTER sharded_cluster" ) with Scenario( "I create quota on nonexistent cluster, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Create_Cluster("1.0")]): with When("I run create quota on a cluster"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("CREATE QUOTA quota0 ON CLUSTER fake_cluster", exitcode=exitcode, message=message) finally: with Finally("I drop all the users and roles"): node.query(f"DROP USER IF EXISTS user0") node.query(f"DROP ROLE IF EXISTS role0")
def feature(self, node="clickhouse1"): """Check grant query syntax. ```sql GRANT ON CLUSTER [cluster_name] role [,...] TO {user | another_role | CURRENT_USER} [,...] [WITH ADMIN OPTION] ``` """ node = self.context.cluster.node(node) @contextmanager def setup(users=0, roles=0): try: with Given("I have some users and roles"): for i in range(users): node.query(f"CREATE USER OR REPLACE user{i}") for j in range(roles): node.query(f"CREATE ROLE OR REPLACE role{j}") yield finally: with Finally("I drop the users and roles"): for i in range(users): node.query(f"DROP USER IF EXISTS user{i}") for j in range(roles): node.query(f"DROP ROLE IF EXISTS role{j}") with Scenario("I grant a role to a user", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")]): with setup(1, 1): with When("I grant a role"): node.query("GRANT role0 TO user0") with Scenario("I grant a nonexistent role to user", requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")]): with setup(1, 0): with When("I grant nonexistent role to a user"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("GRANT role0 TO user0", exitcode=exitcode, message=message) # with nonexistent object name, GRANT assumes type role (treats user0 as role) with Scenario("I grant a role to a nonexistent user", requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")]): with setup(0, 1): with When("I grant role to a nonexistent user"): exitcode, message = errors.role_not_found_in_disk(name="user0") node.query("GRANT role0 TO user0", exitcode=exitcode, message=message) with Scenario("I grant a nonexistent role to a nonexistent user", requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")]): with setup(0, 0): with When("I grant nonexistent role to a nonexistent user"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("GRANT role0 TO user0", exitcode=exitcode, message=message) with Scenario("I grant a role to multiple users", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")]): with setup(2, 1): with When("I grant role to a multiple users"): node.query("GRANT role0 TO user0, user1") with Scenario("I grant multiple roles to multiple users", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")]): with setup(2, 2): with When("I grant multiple roles to multiple users"): node.query("GRANT role0, role1 TO user0, user1") with Scenario("I grant role to current user", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role_CurrentUser("1.0") ]): with setup(1, 1): with Given("I have a user with access management privilege"): node.query("GRANT ACCESS MANAGEMENT ON *.* TO user0") with When("I grant role to current user"): node.query("GRANT role0 TO CURRENT_USER", settings=[("user", "user0")]) with Scenario("I grant role to default user, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role_CurrentUser("1.0") ]): with setup(1, 1): with When("I grant role to default user"): exitcode, message = errors.cannot_update_default() node.query("GRANT role0 TO CURRENT_USER", exitcode=exitcode, message=message) with Scenario("I grant role to user with admin option", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role_AdminOption("1.0") ]): with setup(1, 1): with When("I grant role to a user with admin option"): node.query("GRANT role0 TO user0 WITH ADMIN OPTION") with Scenario("I grant role to user on cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role_OnCluster("1.0")]): try: with Given("I have a user and a role on a cluster"): node.query("CREATE USER user0 ON CLUSTER sharded_cluster") node.query("CREATE ROLE role0 ON CLUSTER sharded_cluster") with When("I grant the role to the user"): node.query("GRANT ON CLUSTER sharded_cluster role0 TO user0") finally: with Finally("I drop the user and role"): node.query("DROP USER user0 ON CLUSTER sharded_cluster") node.query("DROP ROLE role0 ON CLUSTER sharded_cluster") with Scenario("I grant role to user on fake cluster, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Grant_Role_OnCluster("1.0")]): with setup(1, 1): with When("I grant the role to the user"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("GRANT ON CLUSTER fake_cluster role0 TO user0", exitcode=exitcode, message=message)
def feature(self, node="clickhouse1"): """Check create user query syntax. ```sql CREATE USER [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name] [IDENTIFIED [WITH {NO_PASSWORD|PLAINTEXT_PASSWORD|SHA256_PASSWORD|SHA256_HASH|DOUBLE_SHA1_PASSWORD|DOUBLE_SHA1_HASH}] BY {'password'|'hash'}] [HOST {LOCAL | NAME 'name' | NAME REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE] [DEFAULT ROLE role [,...]] [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...] ``` """ node = self.context.cluster.node(node) @contextmanager def cleanup(user): try: with Given("I ensure the user does not already exist", flags=TE): node.query(f"DROP USER IF EXISTS {user}") yield finally: with Finally("I drop the user", flags=TE): node.query(f"DROP USER IF EXISTS {user}") def create_user(user): with Given(f"I ensure I do have user {user}"): node.query(f"CREATE USER OR REPLACE {user}") with Scenario("I create user with no options", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create("1.0"), RQ_SRS_006_RBAC_User_Create_Host_Default("1.0") ]): with cleanup("user0"): with When("I create a user with no options"): node.query("CREATE USER user0") with Scenario("I create user that already exists, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create("1.0"), RQ_SRS_006_RBAC_User_Create_Host_Default("1.0") ]): user = "******" with cleanup(user): create_user(user) with When( f"I create a user {user} that already exists without IF EXISTS, throws exception" ): exitcode, message = errors.cannot_insert_user(name=user) node.query(f"CREATE USER {user}", exitcode=exitcode, message=message) del user with Scenario( "I create user with if not exists, user does not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_IfNotExists("1.0")]): user = "******" with cleanup(user): with When(f"I create a user {user} with if not exists"): node.query(f"CREATE USER IF NOT EXISTS {user}") del user #Bug exists, mark as xfail with Scenario( "I create user with if not exists, user does exist", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_IfNotExists("1.0")]): user = "******" with cleanup(user): create_user(user) with When(f"I create a user {user} with if not exists"): node.query(f"CREATE USER IF NOT EXISTS {user}") del user with Scenario("I create user or replace, user does not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Replace("1.0")]): user = "******" with cleanup(user): with When(f"I create a user {user} with or replace"): node.query(f"CREATE USER OR REPLACE {user}") del user with Scenario("I create user or replace, user does exist", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Replace("1.0")]): user = "******" with cleanup(user): create_user(user) with When(f"I create a user {user} with or replace"): node.query(f"CREATE USER OR REPLACE {user}") del user with Scenario("I create user with no password", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_Password_NoPassword("1.0") ]): with cleanup("user1"): with When("I create a user with no password"): node.query("CREATE USER user1 IDENTIFIED WITH NO_PASSWORD") with Scenario("I create user with plaintext password", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_Password_PlainText("1.0") ]): with cleanup("user1"): with When("I create a user with plaintext password"): node.query( "CREATE USER user1 IDENTIFIED WITH PLAINTEXT_PASSWORD BY 'mypassword'" ) with Scenario( "I create user with sha256 password", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_Password_Sha256Password("1.0") ]): with cleanup("user2"): with When("I create a user with sha256 password"): password = hashlib.sha256( "mypassword".encode("utf-8")).hexdigest() node.query( f"CREATE USER user2 IDENTIFIED WITH SHA256_PASSWORD BY '{password}'" ) with Scenario( "I create user with sha256 password using IDENTIFIED BY", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_Password_Sha256Password("1.0") ]): with cleanup("user2"): with When("I create a user with sha256 password using short form"): password = hashlib.sha256( "mypassword".encode("utf-8")).hexdigest() node.query(f"CREATE USER user2 IDENTIFIED BY '{password}'") with Scenario("I create user with sha256_hash password", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_Password_Sha256Hash("1.0") ]): with cleanup("user3"): with When("I create a user with sha256_hash"): def hash(password): return hashlib.sha256(password.encode("utf-8")).hexdigest() password = hash(hash("mypassword")) node.query( f"CREATE USER user3 IDENTIFIED WITH SHA256_HASH BY '{password}'" ) with Scenario( "I create user with double sha1 password", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_Password_DoubleSha1Password("1.0") ]): with cleanup("user3"): with When("I create a user with double_sha1_password"): node.query( f"CREATE USER user3 IDENTIFIED WITH DOUBLE_SHA1_PASSWORD BY 'mypassword'" ) with Scenario( "I create user with double sha1 hash", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_Password_DoubleSha1Hash("1.0") ]): with cleanup("user3"): with When("I create a user with double_sha1_hash"): def hash(password): return hashlib.sha1(password.encode("utf-8")).hexdigest() password = hash(hash("mypassword")) node.query( f"CREATE USER user3 IDENTIFIED WITH DOUBLE_SHA1_HASH BY '{password}'" ) with Scenario("I create user with host name", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Host_Name("1.0")]): with cleanup("user4"): with When("I create a user with host name"): node.query( "CREATE USER user4 HOST NAME 'localhost', NAME 'clickhouse.com'" ) with Scenario( "I create user with host regexp", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Host_Regexp("1.0")]): with cleanup("user5"): with When("I create a user with host regexp"): node.query( "CREATE USER user5 HOST REGEXP 'lo.?*host', REGEXP 'lo*host'" ) with Scenario("I create user with host ip", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Host_IP("1.0")]): with cleanup("user6"): with When("I create a user with host ip"): node.query( "CREATE USER user6 HOST IP '127.0.0.1', IP '127.0.0.2'") with Scenario("I create user with host like", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Host_Like("1.0")]): with cleanup("user7"): with When("I create a user with host like"): node.query("CREATE USER user7 HOST LIKE 'local%'") with Scenario("I create user with host none", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Host_None("1.0")]): with cleanup("user7"): with When("I create a user with host none"): node.query("CREATE USER user7 HOST NONE") with Scenario("I create user with host local", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Host_Local("1.0") ]): with cleanup("user7"): with When("I create a user with host local"): node.query("CREATE USER user7 HOST LOCAL") with Scenario("I create user with host any", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Host_Any("1.0")]): with cleanup("user7"): with When("I create a user with host any"): node.query("CREATE USER user7 HOST ANY") with Scenario("I create user with default role set to none", flags=TE, requirements=[ RQ_SRS_006_RBAC_User_Create_DefaultRole_None("1.0") ]): with cleanup("user8"): with When("I create a user with no default role"): node.query("CREATE USER user8 DEFAULT ROLE NONE") with Scenario( "I create user with default role", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]): with Given("I have a role"): node.query("CREATE ROLE default") with cleanup("user9"): with When("I create a user with a default role"): node.query("CREATE USER user9 DEFAULT ROLE default") with Finally("I drop the role"): node.query("DROP ROLE default") with Scenario( "I create user default role, role doesn't exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]): with cleanup("user12"): role = "role0" with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with When(f"I create user with default role {role}"): exitcode, message = errors.role_not_found_in_disk(role) node.query(f"CREATE USER user12 DEFAULT ROLE {role}", exitcode=exitcode, message=message) del role with Scenario( "I create user default role, all except role doesn't exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]): with cleanup("user12"): role = "role0" with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with When(f"I create user with default role {role}"): exitcode, message = errors.role_not_found_in_disk(role) node.query( f"CREATE USER user12 DEFAULT ROLE ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario( "I create user with all roles set to default", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole_All("1.0")]): with cleanup("user10"): with When("I create a user with all roles as default"): node.query("CREATE USER user10 DEFAULT ROLE ALL") with Scenario("I create user with settings profile", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]): with cleanup("user11"): with When("I create a user with a settings profile"): node.query( "CREATE USER user11 SETTINGS PROFILE default, max_memory_usage=10000000 READONLY" ) with Scenario( "I create user settings profile, fake profile, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]): with cleanup("user18a"): profile = "profile0" with Given(f"I ensure that profile {profile} does not exist"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") with When( f"I create user with Settings and set profile to fake profile {profile}" ): exitcode, message = errors.settings_profile_not_found_in_disk( profile) node.query("CREATE USER user18a SETTINGS PROFILE profile0", exitcode=exitcode, message=message) del profile with Scenario( "I create user settings with a fake setting, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]): with cleanup("user18b"): with When( "I create settings profile using settings and nonexistent value" ): exitcode, message = errors.unknown_setting("fake_setting") node.query( "CREATE USER user18b SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message) with Scenario("I create user with settings without profile", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]): with cleanup("user12"): with When("I create a user with settings and no profile"): node.query( "CREATE USER user12 SETTINGS max_memory_usage=10000000 READONLY" ) with Scenario("I create user on cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_OnCluster("1.0")]): try: with When("I create user on cluster"): node.query("CREATE USER user13 ON CLUSTER sharded_cluster") finally: with Finally("I drop the user"): node.query("DROP USER user13 ON CLUSTER sharded_cluster") with Scenario("I create user on fake cluster, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_User_Create_OnCluster("1.0")]): with When("I create user on fake cluster"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("CREATE USER user14 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)
def feature(self, node="clickhouse1"): """Check alter row policy query syntax. ```sql ALTER [ROW] POLICY [IF EXISTS] name [ON CLUSTER cluster_name] ON [database.]table [RENAME TO new_name] [AS {PERMISSIVE | RESTRICTIVE}] [FOR SELECT] [USING {condition | NONE}][,...] [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] ``` """ node = self.context.cluster.node(node) @contextmanager def cleanup(policy): try: with Given("I have a row policy"): node.query(f"CREATE ROW POLICY {policy} ON default.foo") yield finally: with Finally("I drop the row policy"): node.query( f"DROP ROW POLICY IF EXISTS {policy} ON default.foo") def cleanup_policy(policy): with Given(f"I ensure that policy {policy} does not exist"): node.query(f"DROP ROW POLICY IF EXISTS {policy} ON default.foo") try: with Given("I have a table and some roles"): node.query( f"CREATE TABLE default.foo (x UInt64, y String) Engine=Memory") node.query(f"CREATE ROLE role0") node.query(f"CREATE ROLE role1") with Scenario("I alter row policy with no options", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy0"): with When("I alter row policy"): node.query("ALTER ROW POLICY policy0 ON default.foo") with Scenario("I alter row policy using short syntax with no options", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy1"): with When("I alter row policy short form"): node.query("ALTER POLICY policy1 ON default.foo") with Scenario("I alter row policy, does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): policy = "policy2" cleanup_policy(policy) with When(f"I alter row policy {policy} that doesn't exist"): exitcode, message = errors.row_policy_not_found_in_disk( name=f"{policy} ON default.foo") node.query(f"ALTER ROW POLICY {policy} ON default.foo", exitcode=exitcode, message=message) del policy with Scenario("I alter row policy if exists", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_IfExists("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy2"): with When("I alter row policy using if exists"): node.query( "ALTER ROW POLICY IF EXISTS policy2 ON default.foo") with Scenario("I alter row policy if exists, policy does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_IfExists("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): policy = "policy2" cleanup_policy(policy) with When(f"I alter row policy {policy} that doesn't exist"): node.query( f"ALTER ROW POLICY IF EXISTS {policy} ON default.foo") del policy with Scenario("I alter row policy to rename, target available", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Rename("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy3"): with When("I alter row policy with rename"): node.query( "ALTER ROW POLICY policy3 ON default.foo RENAME TO policy3" ) with Scenario("I alter row policy to rename, target unavailable", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Rename("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy3"): new_policy = "policy4" try: with Given( f"Ensure target name {new_policy} is NOT available" ): node.query( f"CREATE ROW POLICY IF NOT EXISTS {new_policy} ON default.foo" ) with When(f"I try to rename to {new_policy}"): exitcode, message = errors.cannot_rename_row_policy( name="policy3 ON default.foo", name_new=f"{new_policy} ON default.foo") node.query( f"ALTER ROW POLICY policy3 ON default.foo RENAME TO {new_policy}", exitcode=exitcode, message=message) finally: with Finally(f"I cleanup target name {new_policy}"): node.query( f"DROP ROW POLICY IF EXISTS {new_policy} ON default.foo" ) del new_policy with Scenario( "I alter row policy to permissive", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Access_Permissive("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy4"): with When("I alter row policy as permissive"): node.query( "ALTER ROW POLICY policy4 ON default.foo AS PERMISSIVE" ) with Scenario( "I alter row policy to restrictive", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Access_Restrictive("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy5"): with When("I alter row policy as restrictive"): node.query( "ALTER ROW POLICY policy5 ON default.foo AS RESTRICTIVE" ) with Scenario("I alter row policy for select", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_ForSelect("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy6"): with When("I alter row policy using for select"): node.query( "ALTER ROW POLICY policy6 ON default.foo FOR SELECT USING x > 10" ) with Scenario("I alter row policy using condition", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Condition("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy6"): with When("I alter row policy wtih condition"): node.query( "ALTER ROW POLICY policy6 ON default.foo USING x > 10") with Scenario( "I alter row policy using condition none", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Condition_None("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy7"): with When("I alter row policy using no condition"): node.query( "ALTER ROW POLICY policy7 ON default.foo USING NONE") with Scenario("I alter row policy to one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy8"): with When("I alter row policy to a role"): node.query( "ALTER ROW POLICY policy8 ON default.foo TO role0") with Scenario( "I alter row policy to assign to role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0") ]): role = "role2" with cleanup("policy8a"): with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I alter a row policy, assign to role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk( name=role) node.query( f"ALTER ROW POLICY policy8a ON default.foo TO {role}", exitcode=exitcode, message=message) del role with Scenario( "I alter row policy to assign to all excpet role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0") ]): role = "role2" with cleanup("policy8a"): with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I alter a row policy, assign to all except role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk( name=role) node.query( f"ALTER ROW POLICY policy8a ON default.foo TO ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario("I alter row policy assigned to multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy9"): with When("I alter row policy to multiple roles"): node.query( "ALTER ROW POLICY policy9 ON default.foo TO role0, role1" ) with Scenario( "I alter row policy assigned to all", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_All("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy10"): with When("I alter row policy to all"): node.query( "ALTER ROW POLICY policy10 ON default.foo TO ALL") with Scenario("I alter row policy assigned to all except one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_AllExcept( "1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy11"): with When("I alter row policy to all except"): node.query( "ALTER ROW POLICY policy11 ON default.foo TO ALL EXCEPT role0" ) with Scenario( "I alter row policy assigned to all except multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_AllExcept( "1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy12"): with When("I alter row policy to all except multiple roles"): node.query( "ALTER ROW POLICY policy12 ON default.foo TO ALL EXCEPT role0, role1" ) with Scenario( "I alter row policy assigned to none", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_None("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with cleanup("policy12"): with When("I alter row policy to no assignment"): node.query( "ALTER ROW POLICY policy12 ON default.foo TO NONE") # Official syntax: ON CLUSTER cluster_name ON database.table # Working syntax: both orderings of ON CLUSTER and TABLE clauses work with Scenario("I alter row policy on cluster", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): try: with Given("I have a row policy"): node.query( "CREATE ROW POLICY policy13 ON CLUSTER sharded_cluster ON default.foo" ) with When("I run alter row policy command"): node.query( "ALTER ROW POLICY policy13 ON CLUSTER sharded_cluster ON default.foo" ) finally: with Finally("I drop the row policy"): node.query( "DROP ROW POLICY IF EXISTS policy13 ON CLUSTER sharded_cluster ON default.foo" ) with Scenario("I alter row policy on fake cluster, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): with When("I run alter row policy command"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query( "ALTER ROW POLICY policy13 ON CLUSTER fake_cluster ON default.foo", exitcode=exitcode, message=message) with Scenario("I alter row policy on cluster after table", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"), RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0") ]): try: with Given("I have a row policy"): node.query( "CREATE ROW POLICY policy14 ON default.foo ON CLUSTER sharded_cluster" ) with When("I run create row policy command"): node.query( "ALTER ROW POLICY policy14 ON default.foo ON CLUSTER sharded_cluster" ) finally: with Finally("I drop the row policy"): node.query( "DROP ROW POLICY IF EXISTS policy14 ON default.foo ON CLUSTER sharded_cluster" ) finally: with Finally("I drop the table and the roles"): node.query(f"DROP TABLE IF EXISTS default.foo") node.query(f"DROP ROLE IF EXISTS role0, role1")
def feature(self, node="clickhouse1"): """Check create settings profile query syntax. ```sql CREATE [SETTINGS] PROFILE [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name] [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY] | [INHERIT|PROFILE 'profile_name']] [,...] [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] ``` """ node = self.context.cluster.node(node) @contextmanager def cleanup(profile): try: with Given(f"I ensure the profile {profile} does not exist"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") yield finally: with Finally("I drop the profile"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") def create_profile(profile): with Given(f"I ensure I do have profile {profile}"): node.query(f"CREATE SETTINGS PROFILE OR REPLACE {profile}") try: with Given("I have a user and a role"): node.query(f"CREATE USER user0") node.query(f"CREATE ROLE role0") with Scenario("I create settings profile with no options", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]): with cleanup("profile0"): with When("I create settings profile"): node.query("CREATE SETTINGS PROFILE profile0") with Scenario("I create settings profile that already exists, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]): profile = "profile0" with cleanup(profile): create_profile(profile) with When(f"I create settings profile {profile} that already exists"): exitcode, message = errors.cannot_insert_settings_profile(name=profile) node.query(f"CREATE SETTINGS PROFILE {profile}", exitcode=exitcode, message=message) del profile with Scenario("I create settings profile if not exists, profile does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_IfNotExists("1.0")]): with cleanup("profile1"): with When("I create settings profile with if not exists"): node.query("CREATE SETTINGS PROFILE IF NOT EXISTS profile1") with Scenario("I create settings profile if not exists, profile does exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_IfNotExists("1.0")]): profile = "profile1" with cleanup(profile): create_profile(profile) with When(f"I create settings profile {profile} with if not exists"): node.query(f"CREATE SETTINGS PROFILE IF NOT EXISTS {profile}") del profile with Scenario("I create settings profile or replace, profile does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Replace("1.0")]): with cleanup("profile2"): with When("I create settings policy with or replace"): node.query("CREATE SETTINGS PROFILE OR REPLACE profile2") with Scenario("I create settings profile or replace, profile does exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Replace("1.0")]): with cleanup("profile2"): create_profile("profile2") with When("I create settings policy with or replace"): node.query("CREATE SETTINGS PROFILE OR REPLACE profile2") with Scenario("I create settings profile short form", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]): with cleanup("profile3"): with When("I create settings profile short form"): node.query("CREATE PROFILE profile3") with Scenario("I create settings profile with a setting value", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables("1.0"), RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Value("1.0")]): with cleanup("profile4"): with When("I create settings profile with settings"): node.query("CREATE SETTINGS PROFILE profile4 SETTINGS max_memory_usage = 100000001") with Scenario("I create settings profile with a setting value, does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables("1.0"), RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Value("1.0")]): with When("I create settings profile using settings and nonexistent value"): exitcode, message = errors.unknown_setting("fake_setting") node.query("CREATE SETTINGS PROFILE profile0 SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message) with Scenario("I create settings profile with a min setting value", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]): with cleanup("profile5"), cleanup("profile6"): with When("I create settings profile with min setting with and without equals"): node.query("CREATE SETTINGS PROFILE profile5 SETTINGS max_memory_usage MIN 100000001") node.query("CREATE SETTINGS PROFILE profile6 SETTINGS max_memory_usage MIN = 100000001") with Scenario("I create settings profile with a max setting value", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]): with cleanup("profile7"), cleanup("profile8"): with When("I create settings profile with max setting with and without equals"): node.query("CREATE SETTINGS PROFILE profile7 SETTINGS max_memory_usage MAX 100000001") node.query("CREATE SETTINGS PROFILE profile8 SETTINGS max_memory_usage MAX = 100000001") with Scenario("I create settings profile with min and max setting values", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]): with cleanup("profile9"): with When("I create settings profile with min and max setting"): node.query("CREATE SETTINGS PROFILE profile9 SETTINGS max_memory_usage MIN 100000001 MAX 200000001") with Scenario("I create settings profile with a readonly setting", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]): with cleanup("profile10"): with When("I create settings profile with readonly"): node.query("CREATE SETTINGS PROFILE profile10 SETTINGS max_memory_usage READONLY") with Scenario("I create settings profile with a writable setting", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]): with cleanup("profile21"): with When("I create settings profile with writable"): node.query("CREATE SETTINGS PROFILE profile21 SETTINGS max_memory_usage WRITABLE") with Scenario("I create settings profile with inherited settings", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")]): with cleanup("profile11"): with When("I create settings profile with inherit"): node.query("CREATE SETTINGS PROFILE profile11 SETTINGS INHERIT 'default'") with Scenario("I create settings profile with inherit/from profile, fake profile, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")]): profile = "profile3" with Given(f"I ensure that profile {profile} does not exist"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") sources = {"INHERIT","PROFILE"} for source in sources: with When(f"I create settings profile {source} from nonexistant parent"): exitcode, message = errors.settings_profile_not_found_in_disk(profile) node.query(f"CREATE PROFILE profile0 SETTINGS {source} {profile}", exitcode=exitcode, message=message) del profile with Scenario("I create settings profile with inherited settings other form", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")]): with cleanup("profile12"): with When("I create settings profile with inherit short form"): node.query("CREATE PROFILE profile12 SETTINGS PROFILE 'default'") with Scenario("I create settings profile with multiple settings", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]): with cleanup("profile13"): with When("I create settings profile with multiple settings"): node.query("CREATE SETTINGS PROFILE profile13" " SETTINGS max_memory_usage = 100000001" " SETTINGS max_memory_usage_for_user = 100000001") with Scenario("I create settings profile with multiple settings short form", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints("1.0")]): with cleanup("profile14"): with When("I create settings profile with multiple settings short form"): node.query("CREATE SETTINGS PROFILE profile14" " SETTINGS max_memory_usage = 100000001," " max_memory_usage_for_user = 100000001") with Scenario("I create settings profile assigned to one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]): with cleanup("profile15"): with When("I create settings profile for a role"): node.query("CREATE SETTINGS PROFILE profile15 TO role0") with Scenario("I create settings profile to assign to role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then(f"I create a settings profile, assign to role {role}, which does not exist"): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"CREATE SETTINGS PROFILE profile0 TO {role}", exitcode=exitcode, message=message) del role with Scenario("I create settings profile to assign to all except role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then(f"I create a settings profile, assign to all except role {role}, which does not exist"): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"CREATE SETTINGS PROFILE profile0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario("I create settings profile assigned to multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")]): with cleanup("profile16"): with When("I create settings profile for multiple roles"): node.query("CREATE SETTINGS PROFILE profile16 TO role0, user0") with Scenario("I create settings profile assigned to all", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_All("1.0")]): with cleanup("profile17"): with When("I create settings profile for all"): node.query("CREATE SETTINGS PROFILE profile17 TO ALL") with Scenario("I create settings profile assigned to all except one role", flags=TE,requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_AllExcept("1.0")]): with cleanup("profile18"): with When("I create settings profile for all except one role"): node.query("CREATE SETTINGS PROFILE profile18 TO ALL EXCEPT role0") with Scenario("I create settings profile assigned to all except multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_AllExcept("1.0")]): with cleanup("profile19"): with When("I create settings profile for all except multiple roles"): node.query("CREATE SETTINGS PROFILE profile19 TO ALL EXCEPT role0, user0") with Scenario("I create settings profile assigned to none", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_None("1.0")]): with cleanup("profile22"): with When("I create settings profile for none"): node.query("CREATE SETTINGS PROFILE profile22 TO NONE") with Scenario("I create settings profile on cluster", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_OnCluster("1.0")]): try: with When("I run create settings profile command"): node.query("CREATE SETTINGS PROFILE profile20 ON CLUSTER sharded_cluster") node.query("CREATE SETTINGS PROFILE OR REPLACE profile20 ON CLUSTER sharded_cluster SETTINGS max_memory_usage = 100000001") node.query("CREATE SETTINGS PROFILE OR REPLACE profile20 ON CLUSTER sharded_cluster SETTINGS INHERIT 'default'") node.query("CREATE SETTINGS PROFILE OR REPLACE profile20 ON CLUSTER sharded_cluster TO ALL") finally: with Finally("I drop the settings profile"): node.query("DROP SETTINGS PROFILE IF EXISTS profile20 ON CLUSTER sharded_cluster") with Scenario("I create settings profile on fake cluster, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Create_OnCluster("1.0")]): with When("I run create settings profile command"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("CREATE SETTINGS PROFILE profile1 ON CLUSTER fake_cluster", exitcode=exitcode, message=message) finally: with Finally("I drop all the users and roles"): node.query(f"DROP USER IF EXISTS user0") node.query(f"DROP ROLE IF EXISTS role0")
def feature(self, node="clickhouse1"): """Check create row policy query syntax. ```sql CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] policy_name [ON CLUSTER cluster_name] ON [db.]table [AS {PERMISSIVE | RESTRICTIVE}] [FOR SELECT] [USING condition] [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] ``` """ node = self.context.cluster.node(node) @contextmanager def cleanup(policy, on="default.foo"): try: with Given( f"I ensure the row policy does not already exist on {on}"): node.query(f"DROP ROW POLICY IF EXISTS {policy} ON {on}") yield finally: with Finally(f"I drop the row policy on {on}"): node.query(f"DROP ROW POLICY IF EXISTS {policy} ON {on}") def create_policy(policy, on="default.foo"): with Given(f"I ensure I do have policy {policy} on {on}"): node.query(f"CREATE ROW POLICY OR REPLACE {policy} ON {on}") try: with Given("I have a table and some roles"): node.query( f"CREATE TABLE default.foo (x UInt64, y String) Engine=Memory") node.query(f"CREATE ROLE role0") node.query(f"CREATE ROLE role1") with Scenario("I create row policy with no options", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy0"): with When("I create row policy"): node.query("CREATE ROW POLICY policy0 ON default.foo") with Scenario("I create row policy using short syntax with no options", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy1"): with When("I create row policy short form"): node.query("CREATE POLICY policy1 ON default.foo") with Scenario( "I create row policy that already exists, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): policy = "policy0" with cleanup(policy): create_policy(policy) with When(f"I create row policy {policy}"): exitcode, message = errors.cannot_insert_row_policy( name=f"{policy} ON default.foo") node.query(f"CREATE ROW POLICY {policy} ON default.foo", exitcode=exitcode, message=message) del policy with Scenario( "I create row policy if not exists, policy does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_IfNotExists("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy2"): with When("I create row policy with if not exists"): node.query( "CREATE ROW POLICY IF NOT EXISTS policy2 ON default.foo" ) with Scenario("I create row policy if not exists, policy does exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_IfNotExists("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): policy = "policy2" with cleanup(policy): create_policy(policy) with When(f"I create row policy {policy} with if not exists"): node.query( f"CREATE ROW POLICY IF NOT EXISTS {policy} ON default.foo" ) del policy with Scenario("I create row policy or replace, policy does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Replace("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy3"): with When("I create row policy with or replace"): node.query( "CREATE ROW POLICY OR REPLACE policy3 ON default.foo") with Scenario("I create row policy or replace, policy does exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Replace("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): policy = "policy3" with cleanup(policy): create_policy(policy) with When(f"I create row policy {policy} with or replace"): node.query( f"CREATE ROW POLICY OR REPLACE {policy} ON default.foo" ) del policy with Scenario( "I create row policy as permissive", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Access_Permissive("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy4"): with When("I create row policy as permissive"): node.query( "CREATE ROW POLICY policy4 ON default.foo AS PERMISSIVE" ) with Scenario( "I create row policy as restrictive", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Access_Restrictive("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy5"): with When("I create row policy as restrictive"): node.query( "CREATE ROW POLICY policy5 ON default.foo AS RESTRICTIVE" ) with Scenario("I create row policy for select", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_ForSelect("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_Condition("1.0") ]): with cleanup("policy6"): with When("I create row policy with for select"): node.query( "CREATE ROW POLICY policy6 ON default.foo FOR SELECT USING x > 10" ) with Scenario("I create row policy using condition", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Condition("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy6"): with When("I create row policy with condition"): node.query( "CREATE ROW POLICY policy6 ON default.foo USING x > 10" ) with Scenario("I create row policy assigned to one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy7"): with When("I create row policy for one role"): node.query( "CREATE ROW POLICY policy7 ON default.foo TO role0") with Scenario( "I create row policy to assign to role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0") ]): role = "role2" with cleanup("policy8a"): with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I create a row policy, assign to role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk( name=role) node.query( f"CREATE ROW POLICY policy8a ON default.foo TO {role}", exitcode=exitcode, message=message) del role with Scenario( "I create row policy to assign to all excpet role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0") ]): role = "role2" with cleanup("policy8a"): with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I create a row policy, assign to all except role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk( name=role) node.query( f"CREATE ROW POLICY policy8a ON default.foo TO ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario("I create row policy assigned to multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy8b"): with When("I create row policy for multiple roles"): node.query( "CREATE ROW POLICY policy8b ON default.foo TO role0, role1" ) with Scenario( "I create row policy assigned to all", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_All("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy9"): with When("I create row policy for all"): node.query( "CREATE ROW POLICY policy9 ON default.foo TO ALL") with Scenario( "I create row policy assigned to all except one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_AllExcept( "1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy10"): with When("I create row policy for all except one"): node.query( "CREATE ROW POLICY policy10 ON default.foo TO ALL EXCEPT role0" ) with Scenario( "I create row policy assigned to all except multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_AllExcept( "1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy11"): with When("I create row policy for all except multiple roles"): node.query( "CREATE ROW POLICY policy11 ON default.foo TO ALL EXCEPT role0, role1" ) with Scenario( "I create row policy assigned to none", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_None("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with cleanup("policy11"): with When("I create row policy for none"): node.query( "CREATE ROW POLICY policy11 ON default.foo TO NONE") with Scenario("I create row policy on cluster", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): try: with When("I run create row policy command on cluster"): node.query( "CREATE ROW POLICY policy12 ON CLUSTER sharded_cluster ON default.foo" ) finally: with Finally("I drop the row policy from cluster"): node.query( "DROP ROW POLICY IF EXISTS policy12 ON default.foo ON CLUSTER sharded_cluster" ) with Scenario("I create row policy on fake cluster, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): with When("I run create row policy command"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query( "CREATE ROW POLICY policy13 ON CLUSTER fake_cluster ON default.foo", exitcode=exitcode, message=message) with Scenario("I create row policy on cluster after table", flags=TE, requirements=[ RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"), RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0") ]): try: with When("I run create row policy command on cluster"): node.query( "CREATE ROW POLICY policy12 ON default.foo ON CLUSTER sharded_cluster" ) finally: with Finally("I drop the row policy from cluster"): node.query( "DROP ROW POLICY IF EXISTS policy12 ON default.foo ON CLUSTER sharded_cluster" ) finally: with Finally("I drop the table and the roles"): node.query(f"DROP TABLE IF EXISTS default.foo") node.query(f"DROP ROLE IF EXISTS role0, role1")
def feature(self, node="clickhouse1"): """Check revoke query syntax. ```sql REVOKE [ON CLUSTER cluster_name] [ADMIN OPTION FOR] role [,...] FROM {user | role | CURRENT_USER} [,...] | ALL | ALL EXCEPT {user_name | role_name | CURRENT_USER} [,...] ``` """ node = self.context.cluster.node(node) @contextmanager def setup(users=2, roles=2): try: with Given("I have some users"): for i in range(users): node.query(f"CREATE USER OR REPLACE user{i}") with And("I have some roles"): for i in range(roles): node.query(f"CREATE ROLE OR REPLACE role{i}") yield finally: with Finally("I drop the users"): for i in range(users): node.query(f"DROP USER IF EXISTS user{i}") with And("I drop the roles"): for i in range(roles): node.query(f"DROP ROLE IF EXISTS role{i}") with Scenario("I revoke a role from a user", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(): with When("I revoke a role"): node.query("REVOKE role0 FROM user0") with Scenario("I revoke a nonexistent role from user", requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(1, 0): with When("I revoke nonexistent role from a user"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("REVOKE role0 FROM user0", exitcode=exitcode, message=message) # with nonexistent object name, REVOKE assumes type role (treats user0 as role) with Scenario("I revoke a role from a nonexistent user", requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(0, 1): with When("I revoke role from a nonexistent user"): exitcode, message = errors.role_not_found_in_disk(name="user0") node.query("REVOKE role0 FROM user0", exitcode=exitcode, message=message) # with nonexistent object name, REVOKE assumes type role (treats user0 as role) with Scenario("I revoke a role from ALL EXCEPT nonexistent user", requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(0, 1): with When("I revoke role from a nonexistent user"): exitcode, message = errors.role_not_found_in_disk(name="user0") node.query("REVOKE role0 FROM ALL EXCEPT user0", exitcode=exitcode, message=message) with Scenario("I revoke a nonexistent role from a nonexistent user", requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(0, 0): with When("I revoke nonexistent role from a nonexistent user"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("REVOKE role0 FROM user0", exitcode=exitcode, message=message) with Scenario("I revoke a role from multiple users", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(): with When("I revoke a role from multiple users"): node.query("REVOKE role0 FROM user0, user1") with Scenario("I revoke multiple roles from multiple users", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(): node.query("REVOKE role0, role1 FROM user0, user1") #user is default, expect exception with Scenario("I revoke a role from default user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0") ]): with setup(): with When("I revoke a role from default user"): exitcode, message = errors.cannot_update_default() node.query("REVOKE role0 FROM CURRENT_USER", exitcode=exitcode, message=message) #user is user0 with Scenario("I revoke a role from current user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0") ]): with setup(): with When("I revoke a role from current user"): node.query("REVOKE role0 FROM CURRENT_USER", settings=[("user", "user0")]) #user is default, expect exception with Scenario("I revoke a role from all", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0") ]): with setup(): with When("I revoke a role from all"): exitcode, message = errors.cannot_update_default() node.query("REVOKE role0 FROM ALL", exitcode=exitcode, message=message) #user is default, expect exception with Scenario("I revoke multiple roles from all", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0") ]): with setup(): with When("I revoke multiple roles from all"): exitcode, message = errors.cannot_update_default() node.query("REVOKE role0, role1 FROM ALL", exitcode=exitcode, message=message) with Scenario("I revoke a role from all but current user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0") ]): with setup(): with When("I revoke a role from all except current"): node.query("REVOKE role0 FROM ALL EXCEPT CURRENT_USER") with Scenario("I revoke a role from all but default user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0") ]): with setup(): with When("I revoke a role from all except default"): node.query("REVOKE role0 FROM ALL EXCEPT default", settings=[("user", "user0")]) with Scenario("I revoke multiple roles from all but default user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0") ]): with setup(): with When("I revoke multiple roles from all except default"): node.query("REVOKE role0, role1 FROM ALL EXCEPT default", settings=[("user", "user0")]) with Scenario("I revoke a role from a role", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(): with When("I revoke a role from a role"): node.query("REVOKE role0 FROM role1") with Scenario("I revoke a role from a role and a user", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]): with setup(): with When("I revoke a role from multiple roles"): node.query("REVOKE role0 FROM role1, user0") with Scenario("I revoke a role from a user on cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_Role_Cluster("1.0")]): with Given("I have a role and a user on a cluster"): node.query( "CREATE USER OR REPLACE user0 ON CLUSTER sharded_cluster") node.query( "CREATE ROLE OR REPLACE role0 ON CLUSTER sharded_cluster") with When("I revoke a role from user on a cluster"): node.query("REVOKE ON CLUSTER sharded_cluster role0 FROM user0") with Finally("I drop the user and role"): node.query("DROP USER IF EXISTS user0 ON CLUSTER sharded_cluster") node.query("DROP ROLE IF EXISTS role0 ON CLUSTER sharded_cluster") with Scenario("I revoke a role on fake cluster, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_Role_Cluster("1.0")]): with When("I revoke a role from user on a cluster"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("REVOKE ON CLUSTER fake_cluster role0 FROM user0", exitcode=exitcode, message=message) with Scenario("I revoke multiple roles from multiple users on cluster", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_Role_Cluster("1.0") ]): with Given("I have multiple roles and multiple users on a cluster"): for i in range(2): node.query( f"CREATE USER OR REPLACE user{i} ON CLUSTER sharded_cluster" ) node.query( f"CREATE ROLE OR REPLACE role{i} ON CLUSTER sharded_cluster" ) with When("I revoke multiple roles from multiple users on cluster"): node.query( "REVOKE ON CLUSTER sharded_cluster role0, role1 FROM user0, user1" ) with Finally("I drop the roles and users"): for i in range(2): node.query( f"DROP USER IF EXISTS user{i} ON CLUSTER sharded_cluster") node.query( f"DROP ROLE IF EXISTS role{i} ON CLUSTER sharded_cluster") with Scenario("I revoke admin option for role from a user", flags=TE, requirements=[RQ_SRS_006_RBAC_Revoke_AdminOption("1.0")]): with setup(): with When("I revoke admin option for role from a user"): node.query("REVOKE ADMIN OPTION FOR role0 FROM user0") with Scenario( "I revoke admin option for multiple roles from multiple users", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Role("1.0"), RQ_SRS_006_RBAC_Revoke_AdminOption("1.0") ]): with setup(): with When( "I revoke admin option for multiple roles from multiple users" ): node.query( "REVOKE ADMIN OPTION FOR role0, role1 FROM user0, user1")
def feature(self, node="clickhouse1"): """Check set default role query syntax. ```sql SET DEFAULT ROLE {NONE | role [,...] | ALL | ALL EXCEPT role [,...]} TO {user|CURRENT_USER} [,...] ``` """ node = self.context.cluster.node(node) @contextmanager def setup(users=2,roles=2): try: with Given("I have some users"): for i in range(users): node.query(f"CREATE USER OR REPLACE user{i}") with And("I have some roles"): for i in range(roles): node.query(f"CREATE ROLE OR REPLACE role{i}") yield finally: with Finally("I drop the users"): for i in range(users): node.query(f"DROP USER IF EXISTS user{i}") with And("I drop the roles"): for i in range(roles): node.query(f"DROP ROLE IF EXISTS role{i}") with Scenario("I set default a nonexistent role to user", requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with setup(1,0): with When("I set default nonexistent role to a user"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("SET DEFAULT ROLE role0 TO user0", exitcode=exitcode, message=message) with Scenario("I set default ALL EXCEPT a nonexistent role to user", requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with setup(1,0): with When("I set default nonexistent role to a user"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("SET DEFAULT ROLE ALL EXCEPT role0 TO user0", exitcode=exitcode, message=message) with Scenario("I set default a role to a nonexistent user", requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with setup(0,1): with When("I set default role to a nonexistent user"): exitcode, message = errors.user_not_found_in_disk(name="user0") node.query("SET DEFAULT ROLE role0 TO user0", exitcode=exitcode, message=message) # In SET DEFAULT ROLE, the nonexistent user is noticed first and becomes the thrown exception with Scenario("I set default a nonexistent role to a nonexistent user", requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with setup(0,0): with When("I set default nonexistent role to a nonexistent user"): exitcode, message = errors.user_not_found_in_disk(name="user0") node.query("SET DEFAULT ROLE role0 TO user0", exitcode=exitcode, message=message) try: with Given("I have some roles and some users"): for i in range(2): node.query(f"CREATE ROLE role{i}") node.query(f"CREATE USER user{i}") node.query(f"GRANT role0, role1 TO user0, user1") with Scenario("I set default role for a user to none", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole_None("1.0")]): with When("I set no roles default for user"): node.query("SET DEFAULT ROLE NONE TO user0") with Scenario("I set one default role for a user", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with When("I set a default role for user "): node.query("SET DEFAULT ROLE role0 TO user0") with Scenario("I set one default role for user default, throws exception", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with When("I set a default role for default"): exitcode, message = errors.cannot_update_default() node.query("SET DEFAULT ROLE role0 TO default", exitcode=exitcode, message=message) with Scenario("I set multiple default roles for a user", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with When("I set multiple default roles to user"): node.query("SET DEFAULT ROLE role0, role1 TO user0") with Scenario("I set multiple default roles for multiple users", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole("1.0")]): with When("I set multiple default roles to multiple users"): node.query("SET DEFAULT ROLE role0, role1 TO user0, user1") with Scenario("I set all roles as default for a user", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole_All("1.0")]): with When("I set all roles default to user"): node.query("SET DEFAULT ROLE ALL TO user0") with Scenario("I set all roles except one for a user", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole_AllExcept("1.0")]): with When("I set all except one role default to user"): node.query("SET DEFAULT ROLE ALL EXCEPT role0 TO user0") with Scenario("I set default role for current user", flags = TE, requirements=[ RQ_SRS_006_RBAC_SetDefaultRole_CurrentUser("1.0")]): with When("I set default role to current user"): node.query("GRANT ACCESS MANAGEMENT ON *.* TO user0") node.query("SET DEFAULT ROLE role0 TO CURRENT_USER", settings = [("user","user0")]) finally: with Finally("I drop the roles and users"): for i in range(2): node.query(f"DROP ROLE IF EXISTS role{i}") node.query(f"DROP USER IF EXISTS user{i}")
def feature(self, node="clickhouse1"): """Check set role query syntax. ``` SET ROLE {DEFAULT | NONE | role [,...] | ALL | ALL EXCEPT role [,...]} ``` """ node = self.context.cluster.node(node) @contextmanager def setup(roles=0): try: with Given("I have some roles"): for i in range(roles): node.query(f"CREATE ROLE role{i}") yield finally: with Finally("I drop the roles"): for i in range(roles): node.query(f"DROP ROLE IF EXISTS role{i}") with Scenario("I set default role for current user", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole_Default("1.0")]): with When("I set default role for current user"): node.query("SET ROLE DEFAULT") with Scenario("I set no role for current user", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole_None("1.0")]): with When("I set no role for current user"): node.query("SET ROLE NONE") with Scenario("I set nonexistent role, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole_None("1.0")]): with Given("I ensure that role role5 does not exist"): node.query("DROP ROLE IF EXISTS role5") with When("I set nonexistent role for current user"): exitcode, message = errors.role_not_found_in_disk("role5") node.query("SET ROLE role5", exitcode=exitcode, message=message) with Scenario("I set nonexistent role, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole_None("1.0")]): with Given("I ensure that role role5 does not exist"): node.query("DROP ROLE IF EXISTS role5") with When("I set nonexistent role for current user"): exitcode, message = errors.role_not_found_in_disk("role5") node.query("SET ROLE ALL EXCEPT role5", exitcode=exitcode, message=message) with Scenario("I set one role for current user", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole("1.0")]): with setup(1): with Given("I have a user"): node.query("CREATE USER OR REPLACE user0") with And("I grant user a role"): node.query("GRANT role0 TO user0") with When("I set role for the user"): node.query("SET ROLE role0", settings=[("user", "user0")]) with Finally("I drop the user"): node.query("DROP USER user0") with Scenario("I set multiple roles for current user", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole("1.0")]): with setup(2): with Given("I have a user"): node.query("CREATE USER OR REPLACE user0") with And("I grant user a role"): node.query("GRANT role0, role1 TO user0") with When("I set roles for the user"): node.query("SET ROLE role0, role1", settings=[("user", "user0")]) with Finally("I drop the user"): node.query("DROP USER user0") with Scenario("I set all roles for current user", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole_All("1.0")]): with When("I set all roles for current user"): node.query("SET ROLE ALL") with Scenario("I set all roles except one for current user", flags=TE, requirements=[RQ_SRS_006_RBAC_SetRole_AllExcept("1.0")]): with setup(1): with When("I run set role command"): node.query("SET ROLE ALL EXCEPT role0")
def feature(self, node="clickhouse1"): """Check grant privilege syntax. ```sql GRANT [ON CLUSTER cluster_name] privilege {SELECT | SELECT(columns) | INSERT | ALTER | CREATE | DROP | TRUNCATE | OPTIMIZE | SHOW | KILL QUERY | ACCESS MANAGEMENT | SYSTEM | INTROSPECTION | SOURCES | dictGet | NONE |ALL [PRIVILEGES]} [, ...] ON {*.* | database.* | database.table | * | table} TO {user | role | CURRENT_USER} [,...] [WITH GRANT OPTION] ``` """ node = self.context.cluster.node(node) Scenario(run=grant_privileges) # with nonexistant object name, GRANT assumes type role with Scenario("I grant privilege to role that does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]): with Given("I ensure that role does not exist"): node.query("DROP ROLE IF EXISTS role0") with When("I grant privilege ON CLUSTER"): exitcode, message = errors.role_not_found_in_disk(name="role0") node.query("GRANT NONE TO role0", exitcode=exitcode, message=message) with Scenario("I grant privilege ON CLUSTER", flags=TE, requirements=[ RQ_SRS_006_RBAC_Grant_Privilege_OnCluster("1.0"), RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]): with setup(node): with When("I grant privilege ON CLUSTER"): node.query("GRANT ON CLUSTER sharded_cluster NONE TO user0") with Scenario("I grant privilege on fake cluster, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_Grant_Privilege_OnCluster("1.0")]): with setup(node): with When("I grant privilege ON CLUSTER"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("GRANT ON CLUSTER fake_cluster NONE TO user0", exitcode=exitcode, message=message) with Scenario("I grant privilege to multiple users and roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_Grant_Privilege_To("1.0"), RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]): with setup(node): with When("I grant privilege to several users"): node.query("GRANT NONE TO user0, user1, role1") with Scenario("I grant privilege to current user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Grant_Privilege_ToCurrentUser("1.0"), RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]): with setup(node): with When("I grant privilege to current user"): node.query("GRANT NONE TO CURRENT_USER", settings = [("user","user0")]) with Scenario("I grant privilege NONE to default user, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_Grant_Privilege_ToCurrentUser("1.0"), RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]): with setup(node): with When("I grant privilege to current user"): exitcode, message = errors.cannot_update_default() node.query("GRANT NONE TO CURRENT_USER", exitcode=exitcode, message=message) with Scenario("I grant privilege with grant option", flags=TE, requirements=[ RQ_SRS_006_RBAC_Grant_Privilege_GrantOption("1.0"), RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]): with setup(node): with When("I grant privilege with grant option"): node.query("GRANT NONE ON *.* TO user0 WITH GRANT OPTION")
def feature(self, node="clickhouse1"): """Check alter settings profile query syntax. ```sql ALTER SETTINGS PROFILE [IF EXISTS] name [ON CLUSTER cluster_name] [RENAME TO new_name] [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...] [TO {user_or_role [,...] | NONE | ALL | ALL EXCEPT user_or_role [,...]]} ``` """ node = self.context.cluster.node(node) def cleanup_profile(profile): with Given(f"I ensure that profile {profile} does not exist"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") try: with Given("I have a profile and some users and roles"): node.query(f"CREATE SETTINGS PROFILE profile0") node.query(f"CREATE USER user0") node.query(f"CREATE ROLE role0") with Scenario( "I alter settings profile with no options", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]): with When("I alter settings profile"): node.query("ALTER SETTINGS PROFILE profile0") with Scenario( "I alter settings profile short form", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]): with When("I short form alter settings profile"): node.query("ALTER PROFILE profile0") with Scenario( "I alter settings profile that does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]): profile = "profile1" cleanup_profile(profile) with When( f"I alter settings profile {profile} that doesn't exist"): exitcode, message = errors.settings_profile_not_found_in_disk( name=profile) node.query(f"ALTER SETTINGS PROFILE {profile}", exitcode=exitcode, message=message) del profile with Scenario("I alter settings profile if exists", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0") ]): with When("I alter settings profile using if exists"): node.query("ALTER SETTINGS PROFILE IF EXISTS profile0") with Scenario( "I alter settings profile if exists, profile does not exist", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0") ]): profile = "profile1" cleanup_profile(profile) with When(f"I alter settings profile {profile} using if exists"): node.query(f"ALTER SETTINGS PROFILE IF EXISTS {profile}") del profile with Scenario("I alter settings profile to rename, target available", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0") ]): with When("I alter settings profile by renaming it"): node.query( "ALTER SETTINGS PROFILE profile0 RENAME TO profile0") with Scenario("I alter settings profile to rename, target unavailable", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0") ]): new_profile = "profile1" try: with Given( f"Ensure target name {new_profile} is NOT available"): node.query( f"CREATE SETTINGS PROFILE IF NOT EXISTS {new_profile}") with When(f"I try to rename to {new_profile}"): exitcode, message = errors.cannot_rename_settings_profile( name="profile0", name_new=new_profile) node.query( f"ALTER SETTINGS PROFILE profile0 RENAME TO {new_profile}", exitcode=exitcode, message=message) finally: with Finally(f"I cleanup target name {new_profile}"): node.query( f"DROP SETTINGS PROFILE IF EXISTS {new_profile}") del new_profile with Scenario( "I alter settings profile with a setting value", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"), RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value( "1.0") ]): with When("I alter settings profile using settings"): node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage = 100000001" ) with Scenario( "I alter settings profile with a setting value, does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"), RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value( "1.0") ]): with When( "I alter settings profile using settings and nonexistent value" ): exitcode, message = errors.unknown_setting("fake_setting") node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message) with Scenario( "I alter settings profile with a min setting value", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints( "1.0") ]): with When("I alter settings profile using 2 minimum formats"): node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN 100000001" ) node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN = 100000001" ) with Scenario( "I alter settings profile with a max setting value", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints( "1.0") ]): with When("I alter settings profile using 2 maximum formats"): node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MAX 100000001" ) node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MAX = 100000001" ) with Scenario( "I alter settings profile with min and max setting values", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints( "1.0") ]): with When("I alter settings profile with both min and max"): node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN 100000001 MAX 200000001" ) with Scenario( "I alter settings profile with a readonly setting", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints( "1.0") ]): with When("I alter settings profile with with readonly"): node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage READONLY" ) with Scenario( "I alter settings profile with a writable setting", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints( "1.0") ]): with When("I alter settings profile with writable"): node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage WRITABLE" ) with Scenario( "I alter settings profile with inherited settings", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_Inherit( "1.0") ]): with When("I alter settings profile with inherit"): node.query( "ALTER SETTINGS PROFILE profile0 SETTINGS INHERIT 'default'" ) with Scenario( "I alter settings profile with inherit, parent profile does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_Inherit( "1.0") ]): profile = "profile3" with Given(f"I ensure that profile {profile} does not exist"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") with When( "I alter settings profile inherit from nonexistant parent" ): exitcode, message = errors.settings_profile_not_found_in_disk( profile) node.query( f"ALTER PROFILE profile0 SETTINGS INHERIT {profile}", exitcode=exitcode, message=message) del profile with Scenario( "I alter settings profile with multiple settings", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"), RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value( "1.0") ]): with When("I alter settings profile with multiple settings"): node.query("ALTER SETTINGS PROFILE profile0" " SETTINGS max_memory_usage = 100000001" " SETTINGS max_memory_usage_for_user = 100000001") with Scenario( "I alter settings profile with multiple settings short form", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"), RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value( "1.0") ]): with When( "I alter settings profile with short form multiple settings" ): node.query("ALTER SETTINGS PROFILE profile0" " SETTINGS max_memory_usage = 100000001," " max_memory_usage_for_user = 100000001") with Scenario( "I alter settings profile assigned to one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0") ]): with When("I alter settings profile with assignment to role"): node.query("ALTER SETTINGS PROFILE profile0 TO role0") with Scenario( "I alter settings profile to assign to role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0") ]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I alter a settings profile, assign to role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"ALTER SETTINGS PROFILE profile0 TO {role}", exitcode=exitcode, message=message) del role with Scenario( "I alter settings profile to assign to all except role that does not exist, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0") ]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I alter a settings profile, assign to all except role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk(name=role) node.query( f"ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario( "I alter settings profile assigned to multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0") ]): with When( "I alter settings profile with assignment to multiple roles" ): node.query("ALTER SETTINGS PROFILE profile0 TO role0, user0") with Scenario( "I alter settings profile assigned to all", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_All("1.0") ]): with When("I alter settings profile with assignment to all"): node.query("ALTER SETTINGS PROFILE profile0 TO ALL") with Scenario( "I alter settings profile assigned to all except one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_AllExcept( "1.0") ]): with When( "I alter settings profile with assignment to all except a role" ): node.query( "ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT role0") with Scenario( "I alter settings profile assigned to all except multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_AllExcept( "1.0") ]): with When( "I alter settings profile with assignmentto all except multiple roles" ): node.query( "ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT role0, user0" ) with Scenario( "I alter settings profile assigned to none", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_None( "1.0") ]): with When("I alter settings profile with assignment to none"): node.query("ALTER SETTINGS PROFILE profile0 TO NONE") with Scenario( "I alter settings profile on cluster", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_OnCluster( "1.0") ]): try: with Given("I have a settings profile on cluster"): node.query( "CREATE SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster" ) with When("I run alter settings profile command"): node.query( "ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster" ) with And("I alter settings profile with settings"): node.query( "ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster SETTINGS max_memory_usage = 100000001" ) with And("I alter settings profile with inherit"): node.query( "ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster SETTINGS INHERIT 'default'" ) with And("I alter settings profile to all"): node.query( "ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster TO ALL" ) finally: with Finally("I drop the settings profile"): node.query( "DROP SETTINGS PROFILE IF EXISTS profile1 ON CLUSTER sharded_cluster" ) with Scenario( "I alter settings profile on fake cluster, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_OnCluster( "1.0") ]): with When("I run alter settings profile command"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query( "ALTER SETTINGS PROFILE profile1 ON CLUSTER fake_cluster", exitcode=exitcode, message=message) finally: with Finally("I drop the profile and all the users and roles"): node.query(f"DROP SETTINGS PROFILE IF EXISTS profile0") node.query(f"DROP USER IF EXISTS user0") node.query(f"DROP ROLE IF EXISTS role0")
def feature(self, node="clickhouse1"): """Check revoke privilege syntax. ```sql REVOKE [ON CLUSTER cluster_name] privilege [(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} FROM {user | CURRENT_USER} [,...] | ALL | ALL EXCEPT {user | CURRENT_USER} [,...] ``` """ node = self.context.cluster.node(node) Scenario(run=revoke_privileges) with Scenario("I revoke privilege ON CLUSTER", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_Cluster("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege ON CLUSTER"): node.query("REVOKE ON CLUSTER sharded_cluster NONE FROM user0") with Scenario("I revoke privilege ON fake CLUSTER, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_Cluster("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege ON CLUSTER"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("REVOKE ON CLUSTER fake_cluster NONE FROM user0", exitcode=exitcode, message=message) with Scenario("I revoke privilege from multiple users and roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege from multiple users"): node.query("REVOKE NONE FROM user0, user1, role1") with Scenario("I revoke privilege from current user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege from current user"): node.query("REVOKE NONE FROM CURRENT_USER", settings = [("user","user0")]) with Scenario("I revoke privilege from all users", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege from all users"): exitcode, message = errors.cannot_update_default() node.query("REVOKE NONE FROM ALL", exitcode=exitcode,message=message) with Scenario("I revoke privilege from default user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege from default user"): exitcode, message = errors.cannot_update_default() node.query("REVOKE NONE FROM default", exitcode=exitcode,message=message) #By default, ClickHouse treats unnamed object as role with Scenario("I revoke privilege from nonexistent role, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): role = "role5" with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with When(f"I revoke privilege from nonexistent role {role}"): exitcode, message = errors.role_not_found_in_disk(role) node.query(f"REVOKE NONE FROM {role}", exitcode=exitcode,message=message) with Scenario("I revoke privilege from ALL EXCEPT nonexistent role, throws exception", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): role = "role5" with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with When(f"I revoke privilege from nonexistent role {role}"): exitcode, message = errors.role_not_found_in_disk(role) node.query(f"REVOKE NONE FROM ALL EXCEPT {role}", exitcode=exitcode,message=message) with Scenario("I revoke privilege from all except some users and roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege all except some users"): node.query("REVOKE NONE FROM ALL EXCEPT default, user0, role1") with Scenario("I revoke privilege from all except current user", flags=TE, requirements=[ RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"), RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]): with setup(node): with When("I revoke privilege from all except current user"): node.query("REVOKE NONE FROM ALL EXCEPT CURRENT_USER")
def feature(self, node="clickhouse1"): """Check drop role query syntax. ```sql DROP ROLE [IF EXISTS] name [,...] [ON CLUSTER cluster_name] ``` """ node = self.context.cluster.node(node) @contextmanager def setup(role): try: with Given("I have a role"): node.query(f"CREATE ROLE OR REPLACE {role}") yield finally: with Finally("I confirm the role is dropped"): node.query(f"DROP ROLE IF EXISTS {role}") def cleanup_role(role): with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with Scenario("I drop role with no options", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop("1.0")]): with setup("role0"): with When("I drop role"): node.query("DROP ROLE role0") with Scenario("I drop role that doesn't exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop("1.0")]): role = "role0" cleanup_role(role) with When(f"I drop role {role}"): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"DROP ROLE {role}", exitcode=exitcode, message=message) del role with Scenario("I drop multiple roles", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop("1.0")]): with setup("role1"), setup("role2"): with When("I drop multiple roles"): node.query("DROP ROLE role1, role2") with Scenario("I drop role that does not exist, using if exists", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]): with When("I drop role if exists"): node.query("DROP ROLE IF EXISTS role3") with Scenario("I drop multiple roles where one does not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]): with setup("role5"): with When("I drop multiple roles where one doesnt exist"): node.query("DROP ROLE IF EXISTS role3, role5") with Scenario("I drop multiple roles where both do not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]): with Given("I ensure role does not exist"): node.query("DROP ROLE IF EXISTS role6") with When("I drop the nonexistant roles"): node.query("DROP USER IF EXISTS role5, role6") with Scenario("I drop role on cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop_Cluster("1.0")]): with Given("I have a role on cluster"): node.query("CREATE ROLE role0 ON CLUSTER sharded_cluster") with When("I drop the role from the cluster"): node.query("DROP ROLE role0 ON CLUSTER sharded_cluster") with Scenario("I drop role on fake cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Drop_Cluster("1.0")]): with When("I run drop role command"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("DROP ROLE role2 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)
def feature(self, node="clickhouse1"): """Check alter quota query syntax. ```sql ALTER QUOTA [IF EXISTS] name [ON CLUSTER cluster_name] [RENAME TO new_name] [KEYED BY {'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address'}] [FOR [RANDOMIZED] INTERVAL number {SECOND | MINUTE | HOUR | DAY | MONTH} {MAX { {QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME} = number } [,...] | NO LIMITS | TRACKING ONLY} [,...]] [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] ``` """ node = self.context.cluster.node(node) def cleanup_quota(quota): with Given(f"I ensure that quota {quota} does not exist"): node.query(f"DROP QUOTA IF EXISTS {quota}") try: with Given("I have a quota, a user, and a role"): node.query(f"CREATE QUOTA quota0") node.query(f"CREATE USER user0") node.query(f"CREATE ROLE role0") with Scenario("I alter quota with no options", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter("1.0")]): with When("I alter quota"): node.query("ALTER QUOTA quota0") with Scenario("I alter quota that does not exist, throws an exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter("1.0")]): quota = "quota1" cleanup_quota(quota) with When(f"I alter quota {quota}, which does not exist"): exitcode, message = errors.quota_not_found_in_disk(name=quota) node.query(f"ALTER QUOTA {quota}", exitcode=exitcode, message=message) del quota with Scenario( "I alter quota with if exists, quota does exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_IfExists("1.0")]): node.query("ALTER QUOTA IF EXISTS quota0") with Scenario( "I alter quota with if exists, quota does not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_IfExists("1.0")]): quota = "quota1" cleanup_quota(quota) with When( f"I alter quota {quota}, which does not exist, with IF EXISTS" ): node.query(f"ALTER QUOTA IF EXISTS {quota}") del quota with Scenario("I alter quota using rename, target available", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Rename("1.0") ]): node.query("ALTER QUOTA quota0 RENAME TO quota0") with Scenario("I alter quota using rename, target unavailable", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Rename("1.0") ]): new_quota = "quota1" try: with Given(f"Ensure target name {new_quota} is NOT available"): node.query(f"CREATE QUOTA IF NOT EXISTS {new_quota}") with When(f"I try to rename to {new_quota}"): exitcode, message = errors.cannot_rename_quota( name="quota0", name_new=new_quota) node.query(f"ALTER QUOTA quota0 RENAME TO {new_quota}", exitcode=exitcode, message=message) finally: with Finally(f"I cleanup target name {new_quota}"): node.query(f"DROP QUOTA IF EXISTS {new_quota}") del new_quota keys = [ 'none', 'user name', 'ip address', 'client key', 'client key or user name', 'client key or ip address' ] for key in keys: with Scenario(f"I alter quota keyed by {key}", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_KeyedBy("1.0"), RQ_SRS_006_RBAC_Quota_Alter_KeyedByOptions("1.0") ]): with When("I alter quota with a key"): node.query(f"ALTER QUOTA quota0 KEYED BY '{key}'") with Scenario( "I alter quota for randomized interval", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Interval_Randomized("1.0") ]): with When("I alter quota on a randomized interval"): node.query( "ALTER QUOTA quota0 FOR RANDOMIZED INTERVAL 1 DAY NO LIMITS" ) intervals = ['SECOND', 'MINUTE', 'HOUR', 'DAY', 'MONTH'] for i, interval in enumerate(intervals): with Scenario(f"I alter quota for interval {interval}", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Interval("1.0") ]): with When(f"I alter quota for {interval}"): node.query( f"ALTER QUOTA quota0 FOR INTERVAL 1 {interval} NO LIMITS" ) constraints = [ 'MAX QUERIES', 'MAX ERRORS', 'MAX RESULT ROWS', 'MAX RESULT BYTES', 'MAX READ ROWS', 'MAX READ BYTES', 'MAX EXECUTION TIME', 'NO LIMITS', 'TRACKING ONLY' ] for i, constraint in enumerate(constraints): with Scenario(f"I alter quota for {constraint.lower()}", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Queries("1.0"), RQ_SRS_006_RBAC_Quota_Alter_Errors("1.0"), RQ_SRS_006_RBAC_Quota_Alter_ResultRows("1.0"), RQ_SRS_006_RBAC_Quota_Alter_ReadRows("1.0"), RQ_SRS_006_RBAC_Quota_ALter_ResultBytes("1.0"), RQ_SRS_006_RBAC_Quota_Alter_ReadBytes("1.0"), RQ_SRS_006_RBAC_Quota_Alter_ExecutionTime("1.0"), RQ_SRS_006_RBAC_Quota_Alter_NoLimits("1.0"), RQ_SRS_006_RBAC_Quota_Alter_TrackingOnly("1.0") ]): with When("I alter quota for a constraint"): node.query( f"ALTER QUOTA quota0 FOR INTERVAL 1 DAY {constraint}{' 1024' if constraint.startswith('MAX') else ''}" ) with Scenario("I create quota for multiple constraints", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Interval("1.0"), RQ_SRS_006_RBAC_Quota_Alter_Queries("1.0") ]): node.query("ALTER QUOTA quota0 \ FOR INTERVAL 1 DAY NO LIMITS, \ FOR INTERVAL 2 DAY MAX QUERIES 124, \ FOR INTERVAL 1 MONTH TRACKING ONLY") with Scenario( "I alter quota to assign to one role", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]): with When("I alter quota to a role"): node.query("ALTER QUOTA quota0 TO role0") with Scenario( "I alter quota to assign to role that does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I alter a quota, assign to role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"ALTER QUOTA quota0 TO {role}", exitcode=exitcode, message=message) del role with Scenario( "I alter quota to assign to all except role that does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]): role = "role1" with Given(f"I drop {role} if it exists"): node.query(f"DROP ROLE IF EXISTS {role}") with Then( f"I alter a quota, assign to all except role {role}, which does not exist" ): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"ALTER QUOTA quota0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message) del role with Scenario( "I alter quota to assign to one role and one user", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")]): with When("I alter quota to a role and a user"): node.query("ALTER QUOTA quota0 TO role0, user0") with Scenario("I alter quota assigned to none", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Assignment_None("1.0") ]): with When("I alter quota to none"): node.query("ALTER QUOTA quota0 TO NONE") with Scenario("I alter quota to assign to all", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Assignment_All("1.0") ]): with When("I alter quota to all"): node.query("ALTER QUOTA quota0 TO ALL") with Scenario("I alter quota to assign to all except one role", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Assignment_Except("1.0") ]): with When("I alter quota to all except one role"): node.query("ALTER QUOTA quota0 TO ALL EXCEPT role0") with Scenario("I alter quota to assign to all except multiple roles", flags=TE, requirements=[ RQ_SRS_006_RBAC_Quota_Alter_Assignment_Except("1.0") ]): with When("I alter quota to all except one multiple roles"): node.query("ALTER QUOTA quota0 TO ALL EXCEPT role0, user0") with Scenario( "I alter quota on cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Cluster("1.0")]): try: with Given("I have a quota on a cluster"): node.query( "CREATE QUOTA quota1 ON CLUSTER sharded_cluster") with When("I run alter quota command on a cluster"): node.query("ALTER QUOTA quota1 ON CLUSTER sharded_cluster") with And("I run alter quota command on a cluster with a key"): node.query( "ALTER QUOTA quota1 ON CLUSTER sharded_cluster KEYED BY 'none'" ) with And( "I run alter quota command on a cluster with an interval" ): node.query( "ALTER QUOTA quota1 ON CLUSTER sharded_cluster FOR INTERVAL 1 DAY TRACKING ONLY" ) with And("I run alter quota command on a cluster for all"): node.query( "ALTER QUOTA quota1 ON CLUSTER sharded_cluster TO ALL") finally: with Finally("I drop the quota"): node.query( "DROP QUOTA IF EXISTS quota1 ON CLUSTER sharded_cluster" ) with Scenario( "I alter quota on nonexistent cluster, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Quota_Alter_Cluster("1.0")]): with When("I run alter quota on a cluster"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("ALTER QUOTA quota0 ON CLUSTER fake_cluster", exitcode=exitcode, message=message) finally: with Finally("I drop the quota and all the users and roles"): node.query(f"DROP QUOTA IF EXISTS quota0") node.query(f"DROP USER IF EXISTS user0") node.query(f"DROP ROLE IF EXISTS role0")
def feature(self, node="clickhouse1"): """Check alter role query syntax. ```sql ALTER ROLE [IF EXISTS] name [ON CLUSTER cluster_name] [RENAME TO new_name] [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...] ``` """ node = self.context.cluster.node(node) @contextmanager def setup(role, profile=None): try: with Given("I have a role"): node.query(f"CREATE ROLE OR REPLACE {role}") if profile != None: #create profile when name is given with Given("And I have a profile"): node.query(f"CREATE SETTINGS PROFILE OR REPLACE {profile}") yield finally: with Finally("I drop the role"): node.query(f"DROP ROLE IF EXISTS {role}") if profile != "": with Finally("I drop the profile"): node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}") def cleanup_role(role): with Given(f"I ensure that role {role} does not exist"): node.query(f"DROP ROLE IF EXISTS {role}") with Scenario("I alter role with no options", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter("1.0")]): with setup("role0"): with When("I alter role"): node.query("ALTER ROLE role0") with Scenario("I alter role that does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter("1.0")]): role = "role0" cleanup_role(role) with When(f"I alter role {role} that does not exist"): exitcode, message = errors.role_not_found_in_disk(name=role) node.query(f"ALTER ROLE {role}", exitcode=exitcode, message=message) del role with Scenario("I alter role if exists, role does exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_IfExists("1.0")]): with setup("role1"): with When("I alter role with if exists"): node.query("ALTER ROLE IF EXISTS role1") with Scenario("I alter role if exists, role does not exist", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_IfExists("1.0")]): role = "role0" cleanup_role(role) with When(f"I alter role {role} that does not exist"): node.query(f"ALTER ROLE IF EXISTS {role}") del role with Scenario("I alter role on cluster", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Cluster("1.0")]): try: with Given("I have a role on a cluster"): node.query("CREATE ROLE role1 ON CLUSTER sharded_cluster") with When("I run alter role on a cluster"): node.query("ALTER ROLE role1 ON CLUSTER sharded_cluster") with And("I rename role on a cluster"): node.query( "ALTER ROLE role1 ON CLUSTER sharded_cluster RENAME TO role2" ) with And("I alter role with settings on a cluster"): node.query( "ALTER ROLE role2 ON CLUSTER sharded_cluster SETTINGS max_memory_usage=10000000 READONLY" ) finally: with Finally("I drop the role"): node.query( "DROP ROLE IF EXISTS role1,role2 ON CLUSTER sharded_cluster" ) with Scenario("I alter role on nonexistent cluster, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Cluster("1.0")]): with When("I run alter role on a cluster"): exitcode, message = errors.cluster_not_found("fake_cluster") node.query("ALTER ROLE role1 ON CLUSTER fake_cluster", exitcode=exitcode, message=message) with Scenario("I alter role to rename, new name is available", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Rename("1.0")]): with setup("role2"): new_role = "role3" try: with Given(f"Ensure target name {new_role} is available"): node.query(f"DROP ROLE IF EXISTS {new_role}") with When(f"I try to rename to {new_role}"): node.query(f"ALTER ROLE role2 RENAME TO {new_role}") finally: with Finally(f"I cleanup new name {new_role}"): node.query(f"DROP ROLE IF EXISTS {new_role}") del new_role with Scenario( "I alter role to rename, new name is not available, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Rename("1.0")]): with setup("role2a"): new_role = "role3a" try: with Given(f"Ensure target name {new_role} is NOT available"): node.query(f"CREATE ROLE IF NOT EXISTS {new_role}") with When(f"I try to rename to {new_role}"): exitcode, message = errors.cannot_rename_role( name="role2a", name_new=new_role) node.query(f"ALTER ROLE role2a RENAME TO {new_role}", exitcode=exitcode, message=message) finally: with Finally(f"I cleanup target name {new_role}"): node.query(f"DROP ROLE IF EXISTS {new_role}") del new_role with Scenario("I alter role settings profile", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role4"): with When("I alter role with settings profile"): node.query( "ALTER ROLE role4 SETTINGS PROFILE default, max_memory_usage=10000000 READONLY" ) with Scenario( "I alter role settings profile, profile does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role4a"): with Given("I ensure profile profile0 does not exist"): node.query("DROP SETTINGS PROFILE IF EXISTS profile0") with When( "I alter role with settings profile that does not exist"): exitcode, message = errors.settings_profile_not_found_in_disk( "profile0") node.query("ALTER ROLE role4a SETTINGS PROFILE profile0", exitcode=exitcode, message=message) with Scenario("I alter role settings profile multiple", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role4b", profile="profile0"): with When("I alter role with multiple profiles"): node.query( "ALTER ROLE role4b SETTINGS PROFILE default, PROFILE profile0, \ max_memory_usage=10000000 READONLY") with Scenario("I alter role settings without profile", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role5"): with When("I alter role with settings and no profile"): node.query( "ALTER ROLE role5 SETTINGS max_memory_usage=10000000 READONLY" ) with Scenario( "I alter role settings, variable does not exist, throws exception", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role5a"): with When("I alter role using settings and nonexistent value"): exitcode, message = errors.unknown_setting("fake_setting") node.query( "ALTER ROLE role5a SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message) with Scenario("I alter role settings without profile multiple", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role6"): with When("I alter role with multiple settings and no profile"): node.query( "ALTER ROLE role6 SETTINGS max_memory_usage=10000000 READONLY, \ max_rows_to_read MIN 20 MAX 25") with Scenario( "I alter role settings with multiple profiles multiple variables", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role7", profile="profile1"): with When("I alter role with multiple settings and profiles"): node.query( "ALTER ROLE role7 SETTINGS PROFILE default, PROFILE profile1, \ max_memory_usage=10000000 READONLY, max_rows_to_read MIN 20 MAX 25" ) with Scenario("I alter role settings readonly", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role8"): with When("I alter role with readonly"): node.query( "ALTER ROLE role8 SETTINGS max_memory_usage READONLY") with Scenario("I alter role settings writable", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role9"): with When("I alter role with writable"): node.query( "ALTER ROLE role9 SETTINGS max_memory_usage WRITABLE") with Scenario("I alter role settings min, with and without = sign", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role10"): with When("I set min, no equals"): node.query( "ALTER ROLE role10 SETTINGS max_memory_usage MIN 200") with When("I set min, yes equals"): node.query( "ALTER ROLE role10 SETTINGS max_memory_usage MIN = 200") with Scenario("I alter role settings max, with and without = sign", flags=TE, requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")]): with setup("role11"): with When("I set max, no equals"): node.query( "ALTER ROLE role11 SETTINGS max_memory_usage MAX 2000") with When("I set max, yes equals"): node.query( "ALTER ROLE role11 SETTINGS max_memory_usage MAX = 200")