class TestGetAllBucketsAPI(object): """ Test Suite for testing of REST API endpoint to get all of the buckets - Removes all of the created by the tests buckets, orgs - Creates 26 buckets (single upper case letters) per each of the 5 orgs (5 lower case letters each) """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def test_get_all_buckets_count(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests that the count of the created buckets equals to expected """ test_name = 'test_get_all_buckets_count ' expected_buckets_count = 130 self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get count of all buckets') actual_count = buckets_util.get_count_of_buckets( self, self.get_all_setup_buckets) self.mylog.info(test_name + 'Actual count of created buckets is ' + str(actual_count)) self.mylog.info(test_name + 'Assert expected_count ' + str(expected_buckets_count) + ' equals to actual count ' + str(actual_count)) self.footer(test_name) _assert(self, actual_count, expected_buckets_count, 'buckets count') def test_verify_created_buckets(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests that created bucket can be found in the list of all buckets returned by the 'get all buckets' endpoint """ test_name = 'test_verify_created_buckets ' self.header(test_name) self.mylog.info(test_name + 'STEP 1: find bucket per org') for org_name in org_names: for bucket_name in ascii_uppercase: success = buckets_util.find_bucket_by_name( self, self.get_all_setup_buckets, bucket_name, org_name) self.mylog.info( test_name + 'Assert actual bucket \'%s\' could be found in \'%s\'' % (bucket_name, org_name)) _assert(self, success, True, 'find bucket per org') self.footer(test_name)
class TestGetAllOrganizationsAPI(object): """ Test Suite for testing of REST API endpoint to get all of the orgs - Removes all of the created by the tests orgs - Creates 5 test organizations """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def test_get_all_orgs_count(self): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests that the count of the created orgs equals to expected """ test_name = 'test_get_all_orgs_count ' expected_orgs_count = 5 self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get count of all organizations') actual_count = org_util.get_count_of_orgs(self, self.get_all_setup_orgs) self.mylog.info(test_name + 'Actual count of created organizations is ' + str(actual_count)) self.mylog.info(test_name + 'Assert expected_count ' + str(expected_orgs_count) + ' equals to actual count ' + str(actual_count)) _assert(self, actual_count, expected_orgs_count, 'orgs count') self.footer(test_name) def test_verify_created_orgs(self): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests that created org can be found in the list of all orgs returned by the 'get all orgs' endpoint """ test_name = 'test_verify_created_orgs ' self.header(test_name) self.mylog.info(test_name + 'STEP 1: find organization by name') for name in org_names: org_name, org_id = org_util.find_org_by_name( self, name, self.get_all_setup_orgs) self.mylog.info(test_name + 'Assert expected name ' + str(name) + ' equals to actual name ' + str(org_name)) _assert(self, org_name, name, 'org name') self.footer(test_name)
class TestGetAllUsersAPI(object): """ Test Suite for testing of REST API endpoint to get all of the users - Removes all of the created by the tests users - Creates N test users """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def test_get_all_users_count(self): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests that the count of the created users equals to expected """ test_name = 'test_get_all_users_count ' expected_users_count = 10 self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get count of all users') actual_count = gateway_util.get_count_of_users( self, self.get_all_setup_users) self.mylog.info(test_name + 'Actual count of created users is ' + str(actual_count)) self.mylog.info( test_name + 'Assert actual user_count \'%s\' equals to expected user_count \'%s\'' % (actual_count, expected_users_count)) _assert(self, actual_count, expected_users_count, 'user count') self.footer(test_name) def test_verify_created_users(self): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests that created user can be found in the list of all users returned by the 'get all users' endpoint """ test_name = 'test_verify_created_users ' self.header(test_name) self.mylog.info(test_name + 'STEP 1: find users by name') for name in user_names: success = gateway_util.find_user_by_name(self, name, self.get_all_setup_users) _assert(self, success, True, 'find user by name') self.footer(test_name)
class TestCreateTasks(object): """ Test Suite for testing REST API endpoint for creating tasks where: - org_name is the same as task_name - flux The existing tasks would be removed before running tests """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('')
class TestUpdateBucketsNameAPI(object): """ Test suite to test rest api endpoint for updating Bucket's Name removes created by tests organizations and buckets """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, org_name, bucket_name, retention_period, new_bucket_name=None, new_retention=None): """ :param name_of_the_test_to_run: test to be run :param org_name: name of the organization to be created :param bucket_name: name of the bucket to be created :param retention_period: retention period for the bucket :param new_bucket_name: name of the bucket to update to :param new_retention: retention period to update to :return: pass/fail """ test_name = name_of_the_test_to_run + org_name + ' ' new_bucket_name_to_assert = '' if org_name == 'DoubleQuotes\\"': new_bucket_name_to_assert = 'DoubleQuotes"_updated' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization \'%s\'' % org_name) create_org_result = org_util.create_organization( self, self.gateway, org_name) status = create_org_result['status'] created_org_id = create_org_result['org_id'] created_org_name = create_org_result['org_name'] if org_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif org_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, '') self.mylog.info( test_name + 'STEP 2: Verify org data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='', get_index_values=True, id_by_index_name=created_org_id, error_by_index_name='') self.mylog.info(test_name + 'STEP 3: Create Bucket "%s"' % bucket_name) create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, retention_period, created_org_id) status = create_bucket_result['status'] created_bucket_id = create_bucket_result['bucket_id'] created_bucket_name = create_bucket_result['bucket_name'] created_retention = create_bucket_result['every_seconds'] created_organization_id = create_bucket_result['org_id'] if bucket_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif bucket_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info( test_name + 'STEP 4: Verify bucket data was persisted in the etcd store') verify_bucket_etcd_entries(self, test_name, created_bucket_id, created_bucket_name, expected_error='', expected_retention_period=3600000000000) # Neither bucket name, nor the retention period are being updated. if new_bucket_name is None and new_retention is None: self.mylog.info(test_name + 'STEP 5: Bucket info is not getting updated') update_bucket_result = \ buckets_util.update_bucket(self, self.gateway, created_bucket_id, created_bucket_name, created_retention, new_bucket_name=None, new_retention=None) updated_bucket_name = update_bucket_result['bucket_name'] retention = update_bucket_result['every_seconds'] status = update_bucket_result['status'] bucket_id = update_bucket_result['bucket_id'] organization_id = update_bucket_result['org_id'] self.mylog.info( test_name + 'Assert updated bucket name \'%s\' equals to expected bucket name \'%s\'' % (updated_bucket_name, created_bucket_name)) _assert(self, updated_bucket_name, created_bucket_name, 'bucket name') self.mylog.info( test_name + 'Assert actual retention \'%s\' equals to expected \'%s\' retention' % (retention, created_retention)) _assert(self, retention, created_retention, 'retention period') # only bucket name is being updated elif new_bucket_name is not None and new_retention is None: self.mylog.info(test_name + 'STEP 5: Update created bucket with \'%s\' name' % new_bucket_name) update_bucket_result = \ buckets_util.update_bucket(self, self.gateway, created_bucket_id, created_bucket_name, created_retention, new_bucket_name, new_retention=None) updated_bucket_name = update_bucket_result['bucket_name'] retention = update_bucket_result['every_seconds'] status = update_bucket_result['status'] bucket_id = update_bucket_result['bucket_id'] organization_id = update_bucket_result['org_id'] if org_name == 'DoubleQuotes\\"': self.mylog.info( test_name + 'Assert updated bucket_name \'%s\' equals to expected bucket_name \'%s\'' % (updated_bucket_name, new_bucket_name_to_assert)) _assert(self, updated_bucket_name, new_bucket_name_to_assert, 'bucket name') else: self.mylog.info( test_name + 'Assert updated bucket_name \'%s\' equals to expected bucket_name \'%s\'' % (updated_bucket_name, new_bucket_name)) _assert(self, updated_bucket_name, new_bucket_name, '') self.mylog.info( test_name + 'Assert updated retention \'%s\' equals to expected retention \'%s\'' % (retention, created_retention)) _assert(self, retention, created_retention, 'retention period') # only retention is being updated elif new_bucket_name is None and new_retention is not None: self.mylog.info( test_name + 'STEP 5: Update created bucket with \'%d\' retention name' % new_retention) update_bucket_result = \ buckets_util.update_bucket(self, self.gateway, created_bucket_id, created_bucket_name, created_retention, new_bucket_name=None, new_retention=new_retention) updated_bucket_name = update_bucket_result['bucket_name'] retention = update_bucket_result['every_seconds'] status = update_bucket_result['status'] bucket_id = update_bucket_result['bucket_id'] organization_id = update_bucket_result['org_id'] self.mylog.info( test_name + 'Assert updated bucket_name \'%s\' equals to expected bucket_name \'%s\'' % (updated_bucket_name, created_bucket_name)) _assert(self, updated_bucket_name, created_bucket_name, 'bucket name') self.mylog.info( test_name + 'Assert updated retention \'%s\' equals to expected retention \'%s\'' % (retention, new_retention)) _assert(self, retention, new_retention, 'retention period') # bucket name and retention period are being updated else: self.mylog.info( test_name + 'STEP 5: Update created bucket with \'%s\' bucket name and \'%d\' retention' % (new_bucket_name, new_retention)) update_bucket_result = \ buckets_util.update_bucket(self, self.gateway, created_bucket_id, created_bucket_name, created_retention, new_bucket_name, new_retention) retention = update_bucket_result['every_seconds'] updated_bucket_name = update_bucket_result['bucket_name'] status = update_bucket_result['status'] bucket_id = update_bucket_result['bucket_id'] organization_id = update_bucket_result['org_id'] self.mylog.info( test_name + 'Assert updated retention \'%s\' equals to expected retention \'%s\'' % (retention, new_retention)) _assert(self, retention, new_retention, 'retention period') if org_name == 'DoubleQuotes\\"': self.mylog.info( test_name + 'Assert updated bucket_name \'%s\' equals to expected bucket_name \'%s\'' % (updated_bucket_name, new_bucket_name_to_assert)) _assert(self, updated_bucket_name, new_bucket_name_to_assert, 'bucket name') else: self.mylog.info( test_name + 'Assert updated bucket_name \'%s\' equals to expected bucket_name \'%s\'' % (updated_bucket_name, new_bucket_name)) _assert(self, updated_bucket_name, new_bucket_name, '') self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, 200)) _assert(self, status, 200, 'status code') self.mylog.info( test_name + 'Assert actual bucket_id \'%s\' equals to expected bucket_id \'%s\'' % (bucket_id, created_bucket_id)) _assert(self, bucket_id, created_bucket_id, 'bucket id') self.mylog.info( test_name + 'Assert actual org_id \'%s\' equals to expected org_id \'%s\'' % (organization_id, created_organization_id)) _assert(self, organization_id, created_organization_id, 'organization id') self.mylog.info('') self.mylog.info( test_name + 'STEP 6: Verify updated bucket info was persisted in the etcd store' ) verify_bucket_etcd_entries(self, test_name, bucket_id, updated_bucket_name, expected_error='', expected_retention_period=3600000000000) self.footer(test_name) ############################################### # Lower Case Character Bucket Names # ############################################### @pytest.mark.parametrize('one_char', ascii_lowercase) def test_update_buckets_name_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing single character lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_single_char_lower_case ', one_char, one_char, 3600, one_char + '_updated', None) @pytest.mark.parametrize('ten_char_lc', ten_char_lc) def test_update_buckets_name_10_char_lower_case(self, ten_char_lc): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing random 10 lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_10_char_lower_case ', ten_char_lc, ten_char_lc, 3600, ten_char_lc + '_updated', None) @pytest.mark.parametrize('twenty_char_lc', twenty_char_lc) def test_update_buckets_name_20_char_lower_case(self, twenty_char_lc): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing random 20 lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_20_char_lower_case ', twenty_char_lc, twenty_char_lc, 3600, twenty_char_lc + '_updated', None) ###################################################### # Upper Case Character Bucket Names # ###################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_update_buckets_name_single_char_upper_case(self, one_char): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing single upper case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_single_char_upper_case ', one_char, one_char, 3600, one_char + '_updated', None) @pytest.mark.parametrize('ten_char_uc', ten_char_uc) def test_update_buckets_name_10_char_upper_case(self, ten_char_uc): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing random 10 upper case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_10_char_upper_case ', ten_char_uc, ten_char_uc, 3600, ten_char_uc + '_updated', None) @pytest.mark.parametrize('twenty_char_uc', twenty_char_uc) def test_update_buckets_name_20_char_upper_case(self, twenty_char_uc): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests buckets name containing random 20 upper case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_20_char_upper_case ', twenty_char_uc, twenty_char_uc, 3600, twenty_char_uc + '_updated', None) ############################################################# # Non-alphanumeric Character Buckets Names # ############################################################# @pytest.mark.parametrize('one_char', nonalphanumeric) def test_update_buckets_name_single_char_nonalphanumeric_case( self, one_char): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing single non-alphanumeric character can be updated and persisted in the etcd store. """ self.run_tests( 'test_update_buckets_name_single_char_nonalphanumeric_case ', one_char, one_char, 3600, one_char + '_updated', None) @pytest.mark.parametrize('ten_char_nonalphanumeric', ten_char_nonalphanumeric) def test_update_buckets_name_10_char_nonalphanumeric_case( self, ten_char_nonalphanumeric): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing random 10 non-alphanumeric characters can be updated and persisted in the etcd store. """ self.run_tests( 'test_update_buckets_name_10_char_nonalphanumeric_case ', ten_char_nonalphanumeric, ten_char_nonalphanumeric, 3600, ten_char_nonalphanumeric + '_updated', None) @pytest.mark.parametrize('twenty_char_nonalphanumeric', twenty_char_nonalphanumeric) def test_update_buckets_name_20_char_nonalphanumeric_case( self, twenty_char_nonalphanumeric): """ TEST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing random 20 non-alphanumeric characters can be updated and persisted in the etcd store. """ self.run_tests( 'test_update_buckets_name_20_char_nonalphanumeric_case ', twenty_char_nonalphanumeric, twenty_char_nonalphanumeric, 3600, twenty_char_nonalphanumeric + '_updated', None) #################################################### # Number Characters bucket Names # #################################################### @pytest.mark.parametrize('one_char', digits) def test_update_buckets_name_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing single digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_single_char_numbers ', one_char, one_char, 3600, one_char + '_updated', None) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_update_buckets_name_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing random 10 digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_10_char_numbers ', ten_char_numbers, ten_char_numbers, 3600, ten_char_numbers + '_updated', None) @pytest.mark.parametrize('five_char_numbers', five_char_numbers) def test_update_buckets_name_5_char_numbers(self, five_char_numbers): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing random 5 digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_5_char_numbers ', five_char_numbers, five_char_numbers, 3600, five_char_numbers + '_updated', None) ####################################### # Mix Characters bucket Names # ####################################### @pytest.mark.parametrize('twenty_char_names', twenty_char_names_list) def test_update_buckets_name_20_char_mix(self, twenty_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing 20 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_20_char_mix ', twenty_char_names, twenty_char_names, 3600, twenty_char_names + '_updated', None) @pytest.mark.parametrize('forty_char_names', forty_char_names_list) def test_update_buckets_name_40_char_mix(self, forty_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing 40 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_40_char_mix ', forty_char_names, forty_char_names, 3600, forty_char_names + '_updated', None) @pytest.mark.parametrize('two_hundred_char_name', two_hundred_char_name_list) def test_update_buckets_name_200_char_mix(self, two_hundred_char_name): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing 200 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_200_char_mix ', two_hundred_char_name, two_hundred_char_name, 3600, two_hundred_char_name + '_updated', None) @pytest.mark.parametrize('four_hundred_char_name', four_hundred_char_name_list) def test_update_buckets_name_400_char_mix(self, four_hundred_char_name): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name containing 400 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_400_char_mix ', four_hundred_char_name, four_hundred_char_name, 3600, four_hundred_char_name + '_updated', None) @pytest.mark.onetest @pytest.mark.parametrize('special_char', special_char) def test_update_buckets_name_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests buckets name containing special characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_buckets_name_special_chars ', special_char, special_char, 3600, special_char + '_updated', None) def test_update_buckets_name_already_exist(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests buckets name can be updated and persisted in the etcd store if name already exists. """ org_name = 'test_org_name_already_exists' bucket_name = 'test_bucket_name_already_exists' self.run_tests('test_update_buckets_name_already_exist', org_name, bucket_name, 3600, bucket_name, None) def test_update_buckets_to_empty_name(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: PATCH tests bucket name can not be updated and persisted in the etcd store if name is empty """ org_name = 'test_org_name_empty_name' bucket_name = 'test_bucket_name' self.run_tests('test_update_buckets_to_empty_name', org_name, bucket_name, 3600, '', None)
class TestKapacitorRegressions(object): ''' kapacitor fixture returns the URL of kapacitor, such as http://<ip>:<port> (currently only supports http protoco) data_nodes_ips fixture returns the list of ip addresses of the data nodes delete_created_db fixture - deletes all of the databases with the exception of _internal and telegraf delete_kapacitor_tasks fixture- delete all of the existing kapacitor's tasks ''' mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = chronograf_rest_lib.RestLib(mylog) krl = kapacitor_rest_lib.KapacitorRestLib(mylog) irl = influxdb_rest_lib.InfluxDBInfluxDBRestLib(mylog) # need to move this method into library eventually def show_subscripitons(self, data_url, db_name, auth=None): subscriptions = False time_end = time.time() + 15 while time.time() < time_end: (success, subscription_d, error) = self.irl.show_subscriptions(data_url, auth=auth) assert success, self.mylog.info( 'test_del_db_sending_data_to_kapacitor : Assertion Error ' + str(error)) if db_name in subscription_d.keys(): subscriptions = True self.mylog.info( 'test_del_db_sending_data_to_kapacitor : FOUND SUBSCRIPITON' ) break else: self.mylog.info( 'test_del_db_sending_data_to_kapacitor : SLEEPING FOR 1 SEC' ) time.sleep(1) continue return subscriptions def header(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s START --------------->' % test_name) self.mylog.info( '#######################################################') def footer(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s END --------------->' % test_name) self.mylog.info( '#######################################################') self.mylog.info('') ########################################################## def test_del_db_sending_data_to_kapacitor(self): """ 1. Update config file to set subscription-sync-interval to 5 seconds 2. Create a task 3. Create database using python client APIs """ test_name = 'test_del_db_sending_data_to_kapacitor' data_node_to_connect = choice(self.data_nodes_ips) db_name = 'tddsdtk_db' task_name = 'tddsdtk' field_value_1 = 'This is a first data to write' field_value_final = 'This is a final data to write' # eventually move 'set' to the the set_value method in kapacitor rest lib #data_to_set={'set':{'subscriptions-sync-interval':'5s'}} data_to_set = {'subscriptions-sync-interval': '5s'} task_to_create = { 'id': task_name, 'type': 'stream', 'dbrps': [{ 'db': 'tddsdtk_db', 'rp': 'autogen' }], 'script': 'stream\n |from()\n .measurement(\'test\')\n |httpOut(\'test\')\n', 'status': 'enabled' } first_data_to_write = [{ 'measurement': 'test', 'tags': { 'host': 'server01', 'region': 'us-west' }, 'fields': { 'f1': field_value_1, } }] final_data_to_write = [{ 'measurement': 'test', 'tags': { 'host': 'server01', 'region': 'us-west' }, 'fields': { 'f1': field_value_final, } }] if self.http_auth: username = self.admin_user password = self.admin_pass auth = (username, password) else: username = '' password = '' auth = None client = influxDBClient(data_node_to_connect, 8086, username=username, password=password) self.mylog.info( test_name + ' : STEP 1 - update subscription-sync-interval in kapacitor config ' 'file to be 5second instead of 1 min') self.krl.set_value(self.kapacitor, 'influxdb', data_to_set) self.krl.verify_set_value(self.kapacitor, 'influxdb', json=data_to_set) # create a task that will print a received point from a test database self.mylog.info(test_name + ' : STEP 2 Creating Task') self.krl.create_task(self.kapacitor, json=task_to_create) # create a database with RP=autogen self.mylog.info(test_name + ' : STEP 3 Creating Database') du.create_database(self, client, db_name) # wait for up to 10 seconds and check if subscription to the database was created self.mylog.info( test_name + ' : STEP 4 Verifying Kapacitor created a subscription to a DB') subscriptions = self.show_subscripitons('http://' + data_node_to_connect + ':8086', db_name, auth=auth) assert subscriptions, self.mylog.info( test_name + ' Did not find any subscriptions') self.mylog.info(test_name + ' : STEP 5 Send Test Data') assert du.write_points(self, client, points=first_data_to_write, database=db_name) self.mylog.info(test_name + ' : STEP 6 Verify Kapacitor receieved the data') path_to_hhtpout = self.krl.KAPACITOR_TASKS + '/' + task_name + '/test' result = self.rl.get(self.kapacitor, path_to_hhtpout) assert result.status_code == 200, \ self.mylog.info(test_name + ' Assertion Failure status code=' + str(result.status_code)) value = result.json()['series'] # getting the field value of first_data_to_wrtie self.mylog.info(test_name + ' - data recieved by kapacitor :' + str(value)) assert field_value_1 in value[0]['values'][0], \ self.mylog.info('Assertion Failure field_value_1 ' + field_value_1 + ' cannot be found in the last record written : ' + str(value[0]['values'])) self.mylog.info( test_name + ' : STEP 7 Drop Database %s that is sending data to kapacitor ' % db_name) client.drop_database(db_name) self.mylog.info(test_name + ' : STEP 8 SHOW SUBSCRIPTIONS') subscriptions = self.show_subscripitons('http://' + data_node_to_connect + ':8086', db_name, auth=auth) assert subscriptions == False, self.mylog.info(test_name + ' Found a subscription') self.mylog.info(test_name + ' : STEP 9 Recreating Database') du.create_database(self, client, db_name) # wait for up to 10 seconds and check if subscription to the database was created self.mylog.info( test_name + ' : STEP 10 Verifying Kapacitor created a subscription to a DB') subscriptions = self.show_subscripitons('http://' + data_node_to_connect + ':8086', db_name, auth=auth) assert subscriptions, \ self.mylog.info(test_name + ' Did not find any subscriptions') self.mylog.info(test_name + ' : STEP 11 Send Test Data') assert du.write_points(self, client, points=final_data_to_write, database=db_name) self.mylog.info(test_name + ' : STEP 12 Verify Kapacitor receieved the data') path_to_hhtpout = self.krl.KAPACITOR_TASKS + '/' + task_name + '/test' result = self.rl.get(self.kapacitor, path_to_hhtpout) assert result.status_code == 200, \ self.mylog.info('Assertion Failure status code=' + str(result.status_code)) value = result.json()['series'] # getting the field value of first_data_to_wrtie self.mylog.info(test_name + ' - data recieved by kapacitor :' + str(value)) assert field_value_final in value[0]['values'][0], \ self.mylog.info('Assertion Failure field_value_final ' + field_value_final + ' cannot be found in the last record written : ' + str(value[0]['values']))
class TestCreateUsersAPI(object): """ Test Suite for testing REST API endpoint for creating users The existing users would be removed before running tests """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, user_name): """ :param name_of_the_test_to_run: test name :param user_name: name of the user to be created :return: pass/fail """ test_name = name_of_the_test_to_run + user_name + ' ' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Create a user \'%s\'' % user_name) status, created_user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) if user_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif user_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, created_user_id, created_user_name, expected_error='') self.footer(test_name) # ================== LOWER CASE CHARACTERS ======================== @pytest.mark.parametrize('one_char', ascii_lowercase) def test_create_users_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing single character lower case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_single_char_lower_case ', one_char) @pytest.mark.parametrize('ten_char', ten_char_lc) def test_create_users_10_char_lower_case(self, ten_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 10 random lower case characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_10_char_lower_case ', ten_char) @pytest.mark.parametrize('twenty_char', twenty_char_lc) def test_create_users_20_char_lower_case(self, twenty_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 20 random lower case characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_20_char_lower_case ', twenty_char) # =================== UPPER CASE CHARACTERS ========================== @pytest.mark.parametrize('one_char', ascii_uppercase) def test_create_users_single_char_upper_case(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing single character upper case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_single_char_upper_case ', one_char) @pytest.mark.parametrize('ten_char', ten_char_uc) def test_create_users_10_char_upper_case(self, ten_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 10 random upper case characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_10_char_upper_case ', ten_char) @pytest.mark.parametrize('twenty_char', twenty_char_uc) def test_create_users_20_char_upper_case(self, twenty_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 20 random lower case characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_20_char_upper_case ', twenty_char) # ========================== DIGITS =================================== @pytest.mark.parametrize('one_char', digits) def test_create_users_single_digit(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing single digit can be created and persisted in the etcd store. """ self.run_tests('test_create_users_single_digit ', one_char) @pytest.mark.parametrize('ten_char', ten_char_numbers) def test_create_users_10_digits(self, ten_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 10 random digits can be created and persisted in the etcd store. """ self.run_tests('test_create_users_10_digits ', ten_char) @pytest.mark.parametrize('five_char', five_char_numbers) def test_create_users_5_digits(self, five_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 5 random digits can be created and persisted in the etcd store. """ self.run_tests('test_create_users_5_digits ', five_char) # ============================ NON-ALPHANUMERIC ============================= @pytest.mark.parametrize('one_char', nonalphanumeric) def test_create_users_single_nonalphanumeric_char(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 1 non-alphanumeric character can be created and persisted in the etcd store. """ self.run_tests('test_create_users_single_nonalphanumeric_char ', one_char) @pytest.mark.parametrize('ten_char', ten_char_nonalphanumeric) def test_create_users_10_nonalphanumeric_char(self, ten_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 10 random non-alphanumeric character can be created and persisted in the etcd store. """ self.run_tests('test_create_users_10_nonalphanumeric_char ', ten_char) @pytest.mark.parametrize('twenty_char', twenty_char_nonalphanumeric) def test_create_users_20_nonalphanumeric_char(self, twenty_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing random 20 non-alphanumeric characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_20_nonalphanumeric_char ', twenty_char) # ============================ MIX CHARACTERS ================================ @pytest.mark.parametrize('twenty_char_names', twenty_char_names_list) def test_create_users_20_char_mix(self, twenty_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 20 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_20_char_mix ', twenty_char_names) @pytest.mark.parametrize('forty_char_names', forty_char_names_list) def test_create_users_40_char_mix(self, forty_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 40 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_40_char_mix ', forty_char_names) @pytest.mark.parametrize('two_hundred_char_names', two_hundred_char_name_list) def test_create_users_200_char_mix(self, two_hundred_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 200 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_200_char_mix ', two_hundred_char_names) @pytest.mark.parametrize('four_hundred_char_names', four_hundred_char_name_list) def test_create_users_400_char_mix(self, four_hundred_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing 400 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_400_char_mix ', four_hundred_char_names) @pytest.mark.parametrize('special_char', special_char) def test_create_users_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests user name containing special characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_special_chars ', special_char) def test_create_users_duplicate_names(self): """ REST API: http://<gateway>/api/v2/users METHOD: POST tests cannot create user with already existing name. """ test_name = 'test_create_users_duplicate_names ' user_name = 'duplicate_name' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Create a user \'%s\'' % user_name) status, created_user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) self.mylog.info( test_name + 'Assert actual status code \'%s\' equals to expected status code \'%s\'' % (status, 201)) _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, created_user_id, created_user_name, expected_error='') self.mylog.info(test_name + 'STEP 3: Try creating user with the same name') status, created_user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) _assert(self, status, 404, 'status code', xfail=True, reason='status code is \'%s\'' % status) self.footer(test_name)
class TestDefaultDatabases(object): ''' delete_created_databases - deletes all of the databases created by tests delete_created_rp - removes all of the created, non-default retention policies delete_created_sources - deletes all of the non-default data sources default_sources - gets all of the default sources chronograf - returns chronograf URL data_nodes - returns the list of data nodes URLS get_source_path - returns path to a 'source' URL ''' mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = chronograf_rest_lib.RestLib(mylog) create_rp_name = 'test_create_rp' alter_rp_name = 'test_alter_rp' delete_rp_name = 'test_delete_rp' database_name_rp = '_internal' # Cannot use setup_class with fixtures since it si being called before fixtures. # Have to move clean up using InfluxDBClient into conftest with params, where # parameters are created names of the retention policies. def header(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s START --------------->' % test_name) self.mylog.info( '#######################################################') def footer(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s END --------------->' % test_name) self.mylog.info( '#######################################################') self.mylog.info('') ########################################################## def test_default_databases(self): ''' 1. Get default databases (_internal and telegraf) 2. For every default database verify retention policy duration, retention policy shard group duration, if retention policy is default one and default policy replication ''' # Default sources cannot be used to get databases internal_expected = { 'rp_duration': '168h0m0s', 'rp_replication': 1, 'rp_default': True, 'rp_shard_duration': '24h0m0s', 'rp_name': 'monitor' } telegraf_expected = { 'rp_duration': '0s', 'rp_replication': 2, 'rp_default': True, 'rp_shard_duration': '168h0m0s', 'rp_name': 'autogen' } self.header('test_default_databases') self.mylog.info('test_default_databases - STEP 1: GET DBS LINKS') # in a 2 data nodes set ups we will end up with 2 default data sources = 2 dbs links # dbs_links = [u'/chronograf/v1/sources/1/dbs', u'/chronograf/v1/sources/2/dbs'] dbs_links = du.get_default_databases_links( self, default_sources=self.default_sources) for link in dbs_links: self.mylog.info( 'test_default_databases - STEP 2: GET ALL OF THE DATABASES') # get all of the databases per dbs link dictionary_of_dbs = self.rl.get_databases(self.chronograf, link) # iterate over database names for a specific source for db_name in dictionary_of_dbs.keys(): if db_name == '_internal': retention_policies = du.get_retention_policies( self, dictionary_of_dbs, db_name) # assert retention policy duration assert internal_expected['rp_duration'] == \ du.get_rp_duration(self, retention_policies, internal_expected['rp_name']) # assert retention policy replication assert internal_expected['rp_replication'] == \ du.get_rp_replication(self, retention_policies, internal_expected['rp_name']) # assert shard duration assert internal_expected['rp_shard_duration'] == \ du.get_rp_shardduration(self, retention_policies, internal_expected['rp_name']) # if policy is default #assert internal_expected['rp_default'] == \ # du.get_rp_default(self, retention_policies, internal_expected['rp_name']) if db_name == 'telegraf': retention_policies = du.get_retention_policies( self, dictionary_of_dbs, db_name) # assert retention policy duration assert telegraf_expected['rp_duration'] == \ du.get_rp_duration(self, retention_policies, telegraf_expected['rp_name']) # assert retention policy replication assert telegraf_expected['rp_replication'] == \ du.get_rp_replication(self, retention_policies, telegraf_expected['rp_name']) # assert shard duration assert telegraf_expected['rp_shard_duration'] == \ du.get_rp_shardduration(self, retention_policies, telegraf_expected['rp_name']) self.footer('test_default_databases') def test_create_database_default_values(self): ''' 1. Get default Sources from the all_sources fixture 2. Randomly choose one of the sources to create a database ''' test_name = 'test_create_database_default_values ' database_name = 'test create database default values' # database will be created with all default params data = {'name': database_name} self.header(test_name) self.mylog.info(test_name + ' - STEP 1: CHOOSE A SOURCE') if (len(self.default_sources) == 0): # we do not have any sources # create one data_node = choice(self.data_nodes) (status, body, source_id) = self.rl.create_source(self.chronograf, self.get_source_path, {'url': data_node}) assert source_id is not None else: source_id = choice(self.default_sources.keys()) self.mylog.info(test_name + ' - STEP 2: GET DBS URL FOR SOURCE ID=' + str(source_id)) dbs_url = self.default_sources[source_id].get('DBS') self.mylog.info(test_name + str(dbs_url)) self.mylog.info(test_name + 'STEP 3: CREATE DATABASE ' + database_name) response = self.rl.create_database(self.chronograf, dbs_url, json=data) assert response.status_code == 201, \ self.mylog.info(test_name + ' Assertion Error' + str(response.text)) self.mylog.info(test_name + str(response.json())) assert response.json().get('name') == database_name assert response.json().get('retentionPolicies')[0].get( 'name') == 'autogen' assert response.json().get('retentionPolicies')[0].get( 'replication') == 2 assert response.json().get('retentionPolicies')[0].get( 'duration') == '0s' assert response.json().get('retentionPolicies')[0].get( 'shardDuration') == '168h0m0s' self.footer(test_name) def test_delete_database_default_values(self): ''' 1. Choose a source from available default sources, otherwise create a new data source 2. Get a DB link for a chosen source 3. Create a database using just a database name as a param 4. Delete created database ''' test_name = 'test_delete_database_default_values ' database_name = 'test delete database default values' # database will be created with all default params data = {'name': database_name} self.header(test_name) self.mylog.info(test_name + 'STEP 1: CHOOSE A SOURCE') if (len(self.default_sources) == 0): # we do not have any sources # create one data_node = choice(self.data_nodes) (status, body, source_id) = self.rl.create_source(self.chronograf, self.get_source_path, {'url': data_node}) assert source_id is not None else: source_id = choice(self.default_sources.keys()) self.mylog.info(test_name + ' - STEP 2: GET DBS URL FOR SOURCE ID=' + str(source_id)) dbs_url = self.all_sources[source_id].get('DBS') self.mylog.info(test_name + ' dbs_url=' + str(dbs_url)) self.mylog.info(test_name + 'STEP 3: CREATE DATABASE ' + database_name) response = self.rl.create_database(self.chronograf, dbs_url, json=data) assert response.status_code == 201, \ self.mylog.info(test_name + ' Assertion Error' + str(response.text)) db_name = response.json().get('name') self.mylog.info(test_name + 'STEP 4: DELETING DATABASE ' + str(db_name)) response = self.rl.delete_database(self.chronograf, dbs_url, db_name) assert response.status_code == 204, \ self.mylog.info(test_name + ' Assertion Error' + str(response.text)) self.footer(test_name) def test_create_rp(self): ''' 1. Choose a source id from available default sources 2. Get a Db url for a chosen source 3. Get a data for an _internal database 4. Get a link to RP URL 5. Create a RP and assert the results ''' test_name = 'test_create_rp ' self.header(test_name) data = { 'name': self.create_rp_name, 'duration': '1d', 'replication': 2, 'shardDuration': '2h', 'isDefault': False } # need to get a source to be able to get a link to a database # (allows us to get a rp link to create a rp) self.mylog.info(test_name + ' - STEP 1: CHOOSE SOURCE_ID') source_id = choice(self.default_sources.keys()) assert source_id is not None # just a precaution self.mylog.info(test_name + '- STEP 2 : GET THE DATABASE URL FOR A SOURCE_ID ' + str(source_id)) dbs_url = self.default_sources[source_id].get("DBS") self.mylog.info(test_name + ' - STEP 3: get database info') result = self.rl.get_database(self.chronograf, dbs_url, self.database_name_rp) self.mylog.info(test_name + 'STEP 3 result = ' + str(result)) self.mylog.info(test_name + ' - STEP4: GET RETENTION POLICY LINK') rp_link = result.get('POLICY_LINKS') assert rp_link is not None # just a precaution self.mylog.info('test_create_rp - STEP 5: CREATE A RETENTION POLICY') response = self.rl.create_retention_policy_for_database( self.chronograf, rp_link, json=data) assert response.status_code == 201, \ self.mylog.info(test_name + ' Assertion Error' + str(response.text)) assert response.json()['name'] == self.create_rp_name assert response.json()['duration'] == '24h0m0s' assert response.json()['replication'] == 2 assert response.json()['shardDuration'] == '2h0m0s' assert response.json()['isDefault'] is False def test_alter_rp(self): ''' 1. Choose a source from available default sources 2. Get DB URL for a chosen source 3. Get DB info for _internal DB 4. Get a link to a RP URL 5. Create RP 6. Alter created RP ''' test_name = 'test_alter_rp' self.header(test_name) data = { 'name': self.alter_rp_name, 'duration': '2d', 'replication': 1, 'shardDuration': '1h', 'isDefault': False } updated_data = { 'name': self.alter_rp_name, 'duration': '3d', 'replication': 2, 'shardDuration': '2h', 'isDefault': False } self.mylog.info(test_name + '- STEP 1: CHOOSE SOURCE_ID') source_id = choice(self.default_sources.keys()) assert source_id is not None # just a precaution self.mylog.info(test_name + ' - STEP 2 : GET THE DATABASE URL FOR A SOURCE_ID ' + str(source_id)) dbs_url = self.default_sources[source_id].get("DBS") self.mylog.info(test_name + '- STEP 3: get database info') result = self.rl.get_database(self.chronograf, dbs_url, self.database_name_rp) self.mylog.info(test_name + 'STEP 3 result = ' + str(result)) self.mylog.info(test_name + '- STEP4: GET RETENTION POLICY LINK') rp_link = result.get('POLICY_LINKS') assert rp_link is not None # just a precaution self.mylog.info(test_name + '- STEP 5: CREATE A RETENTION POLICY') self.rl.create_retention_policy_for_database(self.chronograf, rp_link, json=data) self.mylog.info(test_name + '- STEP 6: ALTER RETENTION POLICY') response_alter = self.rl.patch_retention_policy_for_database( self.chronograf, rp_link, self.alter_rp_name, json=updated_data) assert response_alter.status_code == 201, \ self.mylog.info(test_name + ' Assertion Error' + str(response_alter.text)) assert response_alter.json()['name'] == self.alter_rp_name assert response_alter.json()['duration'] == '72h0m0s' assert response_alter.json()['replication'] == 2 assert response_alter.json()['shardDuration'] == '2h0m0s' assert response_alter.json()['isDefault'] is False def test_delete_rp(self): ''' 1. Choose a source from available default sources 2. Get a DB URL for a chosen source 3. Get info for a _internal DB 4. Get a link to a RP 5. Create a RP 6. Delete created RP ''' test_name = 'test_delete_rp ' self.header(test_name) data = { 'name': self.delete_rp_name, 'duration': '4d', 'replication': 2, 'shardDuration': '2h', 'isDefault': False } self.mylog.info(test_name + ' - STEP 1: RANDOMLY CHOOSE SOURCE_ID') source_id = choice(self.default_sources.keys()) assert source_id is not None # just a precaution self.mylog.info(test_name + ' - STEP 2 : GET THE DATABASE URL FOR A SOURCE_ID ' + str(source_id)) dbs_url = self.default_sources[source_id].get("DBS") self.mylog.info(test_name + ' - STEP 3: get database info') result = self.rl.get_database(self.chronograf, dbs_url, self.database_name_rp) self.mylog.info(test_name + 'STEP 3 result = ' + str(result)) self.mylog.info(test_name + ' - STEP4: GET RETENTION POLICY LINK') rp_link = result.get('POLICY_LINKS') assert rp_link is not None # just a precaution self.mylog.info(test_name + '- STEP 5: CREATE A RETENTION POLICY') self.rl.create_retention_policy_for_database(self.chronograf, rp_link, json=data) self.mylog.info(test_name + '- STEP 6: DELETE RETENTION POLICY') response = self.rl.delete_retention_policy_for_database( self.chronograf, rp_link, self.delete_rp_name) assert response.status_code == 204, \ self.mylog.info(test_name + ' Assertion Error' + str(response.text)) self.footer(test_name)
class TestUpdateUsersAPI(object): """ Test suite to test rest api endpoint for updating users removes created by tests users """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, user_name): """ :param name_of_the_test_to_run: name of the test to be run :param user_name: name of user under the test :return: pass/fail """ test_name = name_of_the_test_to_run + user_name + ' ' new_name_to_assert = '' if user_name == 'DoubleQuotes\\"': new_name_to_assert = 'DoubleQuotes"_updated_name' new_name = user_name + '_updated_name' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create User \'%s\'' % user_name) status, created_user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) if user_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif user_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, created_user_id, created_user_name, expected_error='') self.mylog.info(test_name + ' STEP 3: Update created user with the \'%s\' name' % new_name) status, new_user_id, updated_user_name, error_message = \ gateway_util.update_user(self, self.gateway, created_user_id, new_name) self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, 200)) _assert(self, status, 200, 'status code') self.mylog.info( test_name + 'Assert updated user_id \'%s\' equals to expected user_id \'%s\'' % (new_user_id, created_user_id)) _assert(self, new_user_id, created_user_id, 'user id') if user_name == 'DoubleQuotes\\"': self.mylog.info( test_name + 'Assert updated user_name \'%s\' equals to expected user_name \'%s\'' % (updated_user_name, new_name_to_assert)) _assert(self, updated_user_name, new_name_to_assert, 'user name') else: self.mylog.info( test_name + 'Assert updated user_name \'%s\' equals to expected user_name \'%s\'' % (updated_user_name, new_name)) _assert(self, updated_user_name, new_name, 'user name') self.mylog.info( test_name + 'STEP 4: Verify updated name was persisted in the etcd store') verify_user_etcd_entries(self, test_name, new_user_id, updated_user_name, expected_error='') self.footer(test_name) ############################################ # Lower Case Character User Names # ############################################ @pytest.mark.parametrize('one_char', ascii_lowercase) def test_update_users_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing single character lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_single_char_lower_case_', one_char) @pytest.mark.parametrize('ten_char', ten_char_lc) def test_update_users_10_char_lower_case(self, ten_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 10 random characters lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_10_char_lower_case_', ten_char) @pytest.mark.parametrize('twenty_char', twenty_char_lc) def test_update_users_20_char_lower_case(self, twenty_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 20 random characters lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_20_char_lower_case_', twenty_char) ################################################### # Upper Case Character User Names # ################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_update_users_single_char_upper_case(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing single upper case character letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_single_char_upper_case_', one_char) @pytest.mark.parametrize('ten_char', ten_char_uc) def test_update_users_10_char_upper_case(self, ten_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 10 random upper case character letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_10_char_upper_case_', ten_char) @pytest.mark.parametrize('twenty_char', twenty_char_uc) def test_update_users_20_char_upper_case(self, twenty_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 20 random upper case character letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_20_char_upper_case_', twenty_char) ######################################################### # Non-alphanumeric Character User Names # ######################################################### @pytest.mark.parametrize('one_char', nonalphanumeric) def test_update_users_single_char_nonalphanumeric(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing non-alphanumeric character letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_single_char_nonalphanumeric_', one_char) @pytest.mark.parametrize('ten_char_nonalphanumeric', ten_char_nonalphanumeric) def test_update_users_10_char_nonalphanumeric(self, ten_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 10 random non-alphanumeric character letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_10_char_nonalphanumeric_', ten_char_nonalphanumeric) @pytest.mark.parametrize('twenty_char_nonalphanumeric', twenty_char_nonalphanumeric) def test_update_orgs_20_char_nonalphanumeric_case( self, twenty_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 20 random non-alphanumeric character letters can be updated and persisted in the etcd store. """ self.run_tests('twenty_char_nonalphanumeric_', twenty_char_nonalphanumeric) ################################################# # Number Characters User Names # ################################################# @pytest.mark.parametrize('one_char', digits) def test_update_users_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing single digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_single_char_numbers_', one_char) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_update_users_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 10 random digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_10_char_numbers_', ten_char_numbers) @pytest.mark.parametrize('five_numbers', five_char_numbers) def test_update_users_5_char_numbers(self, five_numbers): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 5 random digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_5_char_numbers_', five_numbers) #################################### # Mix Characters User Names # #################################### @pytest.mark.parametrize('twenty_char_names', twenty_char_names_list) def test_update_users_20_char_mix(self, twenty_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 20 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_20_char_mix_', twenty_char_names) @pytest.mark.parametrize('forty_char_names', forty_char_names_list) def test_update_users_40_char_mix(self, forty_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 40 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_40_char_mix_', forty_char_names) @pytest.mark.parametrize('two_hundred_char_names', two_hundred_char_name_list) def test_update_users_200_char_mix(self, two_hundred_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 200 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_200_char_mix_', two_hundred_char_names) @pytest.mark.parametrize('four_hundred_char_names', four_hundred_char_name_list) def test_update_users_400_char_mix(self, four_hundred_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing 400 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_400_char_mix_', four_hundred_char_names) @pytest.mark.parametrize('special_char', special_char) def test_update_users_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name containing special characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_users_special_chars_', special_char) def test_update_users_already_exist(self): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name can be updated and persisted in the etcd store if name already exists. """ test_name = 'test_update_users_already_exist' user_name = 'existing_user' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create User') status, created_user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, 201)) _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, created_user_id, created_user_name, expected_error='') self.mylog.info(test_name + ' STEP 3: Update created user with the \'%s\' name' % user_name) status, updated_user_id, updated_user_name, error_message = \ gateway_util.update_user(self, self.gateway, created_user_id, user_name) self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, 200)) _assert(self, status, 200, 'status code') self.mylog.info( test_name + 'Assert updated user_id \'%s\' equals to expected user_id \'%s\'' % (updated_user_id, created_user_id)) _assert(self, updated_user_id, created_user_id, 'user id') self.mylog.info( test_name + 'Assert updated user_name \'%s\' equals to expected user_name \'%s\'' % (updated_user_name, user_name)) _assert(self, updated_user_name, user_name, 'user name') self.mylog.info(test_name + 'STEP 4: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, updated_user_id, updated_user_name, expected_error='') self.footer(test_name) def test_update_users_empty_name(self): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests user name can be updated and persisted in the etcd store if name is empty """ test_name = 'test_update_users_empy_name' user_name = 'user_to_be_updated' user_name_to_update = '' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create User \'%s\'' % user_name) status, created_user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, 201)) _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, created_user_id, created_user_name, expected_error='') self.mylog.info(test_name + ' STEP 3: Update created user with the \'%s\' name' % user_name_to_update) status, updated_user_id, updated_user_name, error_message = \ gateway_util.update_user(self, self.gateway, created_user_id, user_name_to_update) self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, 200)) _assert(self, status, 200, 'status code') self.mylog.info( test_name + 'Assert updated user_id \'%s\' equals to expected user_id \'%s\'' % (updated_user_id, created_user_id)) _assert(self, updated_user_id, created_user_id, 'user id') self.mylog.info( test_name + 'Assert updated user_name \'%s\' equals to expected user_name \'%s\'' % (updated_user_name, user_name_to_update)) _assert(self, updated_user_name, user_name_to_update, 'user name') self.mylog.info(test_name + 'STEP 4: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, updated_user_id, updated_user_name, expected_error='') self.footer(test_name)
class TestUpdateOrganizationsAPI(object): """ Test suite to test rest api endpoint for updating organizations removes created by tests organizations """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, org_name): """ :param name_of_the_test_to_run: test to run :param org_name: :return: pass/fail """ test_name = name_of_the_test_to_run + org_name + ' ' org_name_to_assert = '' if org_name == 'DoubleQuotes\\"': org_name_to_assert = 'DoubleQuotes"_updated_name' new_org_name = org_name + '_updated_name' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization') create_result = org_util.create_organization(self, self.gateway, org_name) status = create_result['status'] created_org_id = create_result['org_id'] if org_name == '': _assert(self, status, 201, 'status_code', xfail=True, reason='https://github.com/influxdata/platform/issues/188') elif org_name == 'BackSlash\\': _assert(self, status, 201, 'status_code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status_code') self.mylog.info(test_name + ' STEP 2: Update created org with the \'%s\' name' % new_org_name) update_result = org_util.update_organization(self, self.gateway, created_org_id, new_org_name) status = update_result['status'] new_org_id = update_result['updated_org_id'] updated_org_name = update_result['updated_org_name'] self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status 200' % status) _assert(self, status, 200, 'status_code') self.mylog.info( test_name + 'Assert actual org_id \'%s\' equals to expected org_id \'%s\'' % (new_org_id, created_org_id)) _assert(self, new_org_id, created_org_id, 'org_id') if org_name == 'DoubleQuotes\\"': self.mylog.info( test_name + 'Assert actual org_name \'%s\' equals to expected org_name \'%s\'' % (updated_org_name, org_name_to_assert)) _assert(self, updated_org_name, org_name_to_assert, 'org_name') else: self.mylog.info( test_name + 'Assert actual org_name \'%s\' equals to expected org_name \'%s\'' % (updated_org_name, new_org_name)) _assert(self, updated_org_name, new_org_name, 'org_name') self.mylog.info( test_name + 'STEP 3: Verify updated name was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id=new_org_id, created_org_name=updated_org_name, error='') self.footer(test_name) ############################################ # Lower Case Character Org Names # ############################################ @pytest.mark.parametrize('one_char', ascii_lowercase) def test_update_orgs_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing single character lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_single_char_lower_case ', one_char) @pytest.mark.parametrize('ten_char_lc', ten_char_lc) def test_update_orgs_10_char_lower_case(self, ten_char_lc): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 10 lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_10_char_lower_case ', ten_char_lc) @pytest.mark.parametrize('twenty_char_lc', twenty_char_lc) def test_update_orgs_20_char_lower_case(self, twenty_char_lc): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 20 lower case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_20_char_lower_case ', twenty_char_lc) ################################################### # Upper Case Character Org Names # ################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_update_orgs_single_char_upper_case(self, one_char): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing single upper case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_single_char_upper_case ', one_char) @pytest.mark.parametrize('ten_char_uc', ten_char_uc) def test_update_orgs_10_char_upper_case(self, ten_char_uc): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 10 upper case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_10_char_upper_case ', ten_char_uc) @pytest.mark.parametrize('twenty_char_uc', twenty_char_uc) def test_update_orgs_20_char_upper_case(self, twenty_char_uc): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 20 upper case letters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_20_char_upper_case ', twenty_char_uc) ######################################################### # Non-alphanumeric Character Org Names # ######################################################### @pytest.mark.parametrize('one_char', nonalphanumeric) def test_update_orgs_single_char_nonalphanumeric_case(self, one_char): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing single non-alphanumeric character can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_single_char_nonalphanumeric_case ', one_char) @pytest.mark.parametrize('ten_char_nonalphanumeric', ten_char_nonalphanumeric) def test_update_orgs_10_char_nonalphanumeric_case( self, ten_char_nonalphanumeric): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 10 non-alphanumeric characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_10_char_nonalphanumeric_case ', ten_char_nonalphanumeric) @pytest.mark.parametrize('twenty_char_nonalphanumeric', twenty_char_nonalphanumeric) def test_update_orgs_20_char_nonalphanumeric_case( self, twenty_char_nonalphanumeric): """ TEST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 20 non-alphanumeric characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_20_char_nonalphanumeric_case ', twenty_char_nonalphanumeric) ################################################# # Number Characters Org Names # ################################################# @pytest.mark.parametrize('one_char', digits) def test_update_orgs_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing single digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_single_char_numbers ', one_char) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_update_orgs_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 10 digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_10_char_numbers ', ten_char_numbers) @pytest.mark.parametrize('five_char_numbers', five_char_numbers) def test_update_orgs_5_char_numbers(self, five_char_numbers): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing random 5 digits can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_5_char_numbers ', five_char_numbers) #################################### # Mix Characters Org Names # #################################### @pytest.mark.parametrize('twenty_char_names', twenty_char_names_list) def test_update_orgs_20_char_mix(self, twenty_char_names): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing 20 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_20_char_mix ', twenty_char_names) @pytest.mark.parametrize('forty_char_names', forty_char_names_list) def test_update_orgs_40_char_mix(self, forty_char_names): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing 40 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_40_char_mix ', forty_char_names) @pytest.mark.parametrize('two_hundred_char_name', two_hundred_char_name_list) def test_update_orgs_200_char_mix(self, two_hundred_char_name): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing 200 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_200_char_mix ', two_hundred_char_name) @pytest.mark.parametrize('four_hundred_char_name', four_hundred_char_name_list) def test_update_orgs_400_char_mix(self, four_hundred_char_name): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name containing 400 mix characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_400_char_mix ', four_hundred_char_name) @pytest.mark.parametrize('special_char', special_char) def test_update_orgs_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests orgs name containing special characters can be updated and persisted in the etcd store. """ self.run_tests('test_update_orgs_special_chars ', special_char) def test_update_orgs_already_exist(self): """ REST API: http://<gateway>/api/v2/users METHOD: PATCH tests org name can be updated and persisted in the etcd store if name already exists. """ test_name = 'test_update_org`_already_exist' org_name = 'existing_org' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization') create_result = org_util.create_organization(self, self.gateway, org_name) status = create_result['status'] created_org_id = create_result['org_id'] self.mylog.info( test_name + 'Assert actual status code \'%s\' equals to expected status code 201' % status) _assert(self, status, 201, 'status_code') self.mylog.info(test_name + ' STEP 2: Update created org with the \'%s\' name' % org_name) update_result = org_util.update_organization(self, self.gateway, created_org_id, org_name) status = update_result['status'] updated_org_id = update_result['updated_org_id'] updated_org_name = update_result['updated_org_name'] self.mylog.info( test_name + 'Assert actual status code \'%s\' equals to expected status code 201' % status) _assert(self, status, 200, 'status_code') self.mylog.info( test_name + 'Assert updated org_id \'%s\' equals to expected org_id \'%s\'' % (updated_org_id, created_org_id)) _assert(self, updated_org_id, created_org_id, 'org_id') self.mylog.info( test_name + 'Assert updated org_name \'%s\' equals to expected org_name \'%s\'' % (updated_org_name, org_name)) _assert(self, updated_org_name, org_name, 'org_name') self.mylog.info( test_name + 'STEP 3: Verify created user was persisted in the etcd store') verify_org_etcd_entries(self, test_name, updated_org_id, updated_org_name, '') self.footer(test_name) def test_update_orgs_empty_name(self): """ REST API: http://<gateway>/api/v2/orgs METHOD: PATCH tests org name can be updated and persisted in the etcd store if name is empty """ test_name = 'test_update_orgs_empty_name' org_name = 'org_to_be_updated' org_name_to_update = '' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization') create_result = org_util.create_organization(self, self.gateway, org_name) status = create_result['status'] created_org_id = create_result['org_id'] created_org_name = create_result['org_name'] self.mylog.info( test_name + 'Assert actual status code \'%s\' equals to expected status code 201' % status) _assert(self, status, 201, 'status_code') self.mylog.info( test_name + 'STEP 2: Verify created organization was persisted in the etcd store' ) verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='') self.mylog.info(test_name + ' STEP 3: Update created org with the \'%s\' name' % org_name_to_update) update_result = org_util.update_organization(self, self.gateway, created_org_id, org_name_to_update) status = update_result['status'] updated_org_id = update_result['updated_org_id'] updated_org_name = update_result['updated_org_name'] self.mylog.info( test_name + 'Assert actual status code \'%s\' equals to expected status code 200' % status) _assert(self, status, 200, 'status_code') self.mylog.info( test_name + 'Assert updated org_id \'%s\' equals to expected org_id \'%s\'' % (updated_org_id, created_org_id)) _assert(self, updated_org_id, created_org_id, 'org_id') self.mylog.info( test_name + 'Assert updated org_name \'%s\' equals to expected org_name \'%s\'' % (updated_org_name, '')) _assert(self, updated_org_name, '', 'org_name') self.footer(test_name)
class TestSources(): ''' chronograf fixture - to get the chronograf URL data_nodes - to get the list of data nodes URLs meta_nodes - to get the list of meta nodes URLs delete_created_source - to delete sources that were created by test(s) suites get_source_path - to get chronograf's source path, e.g./chronograf/v1/sources http_auth - where basic password authentication is available or not admin_user - admin user username admin_pass - admin user password ''' mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = chronograf_rest_lib.RestLib(mylog) CUSTOM_NAME = 'Test Create Source User Options' UPDATE_NAME = 'Test Update Source Name' UPDATED_NAME = 'Updated Name Of The Source' DELETE_NAME = 'Delete source name' ########################################################## def verify_source(self, expected, source_id, source): ''' :param expected_data: dictionary of expected values :param source_id: ID of the created source :param source: dictionaly of actual values :return: does not return anything ''' username = su.get_source_username(self, source_id, source) self.mylog.info('ASSERT ACTUAL username='******' EQUALS '\ 'EXPECTED username='******'USERNAME'])) su.verify_data(self, expected['USERNAME'], username) insecure = su.get_source_insecureskipverify(self, source_id, source) self.mylog.info('ASSERT ACTUAL insecure=' + str(insecure) + ' EQUALS '\ 'EXPECTED insecure=' + str(expected['INSECURE_SKIP_VERIFY'])) su.verify_data(self, expected['INSECURE_SKIP_VERIFY'], insecure) url = su.get_source_url(self, source_id, source) self.mylog.info('ASSERT ACTUAL url=' + str(url) + ' EQUALS EXPECTED '\ 'url=' + str(expected['DATA_URL'])) su.verify_data(self, expected['DATA_URL'], url) name = su.get_source_name(self, source_id, source) self.mylog.info('ASSERT ACTUAL name=' + str(name) + ' EQUALS EXPECTED '\ 'name' + str(expected['NAME'])) su.verify_data(self, expected['NAME'], name) roles = su.get_source_roles_link(self, source_id, source) self.mylog.info('ASSERT ACTUAL roles=' + str(roles) + ' EQUALS '\ 'EXPECTED roles=' + str(expected['ROLES'])) su.verify_data(self, expected['ROLES'], roles) default = su.get_source_default(self, source_id, source) self.mylog.info('ASSERT ACTUAL default=' + str(default) + ' EQUALS '\ 'EXPECTED default=' + str(expected['DEFAULT'])) su.verify_data(self, expected['DEFAULT'], default) telegrafdb = su.get_source_telegraf(self, source_id, source) self.mylog.info('ASSERT ACTUAL telegrafdb=' + str(telegrafdb) + ' EQUALS '\ 'EXPECTED telegrafdb=' + str(expected['TELEGRAF_DB'])) su.verify_data(self, expected['TELEGRAF_DB'], telegrafdb) shared_secret = su.get_source_sharedsecret(self, source_id, source) self.mylog.info('ASSERT ACTUAL shared_secret=' + str(shared_secret) + ' EQUALS '\ 'EXPECTED shared_secret=' + str(expected['SHARED_SECRET'])) su.verify_data(self, expected['SHARED_SECRET'], shared_secret) meta_url = su.get_source_metaurl(self, source_id, source) self.mylog.info('ASSERT ACTUAL meta_url=' + str(meta_url) + ' EQUALS '\ 'EXPECTED meta_url=' + str(expected['META_URL'])) su.verify_data(self, expected['META_URL'], meta_url) kapacitor = su.get_source_kapacitors_link(self, source_id, source) self.mylog.info('ASSERT ACTUAL kapacitor=' + str(kapacitor) + ' EQUALS '\ 'EXPECTED kapacitor=' + str(expected['KAPACITOR'])) su.verify_data(self, expected['KAPACITOR'], kapacitor) write = su.get_source_write_link(self, source_id, source) self.mylog.info('ASSERT ACTUAL write=' + str(write) + ' EQUALS '\ 'EXPECTED write=' + str(expected['WRITE'])) su.verify_data(self, expected['WRITE'], write) proxy = su.get_source_proxy_link(self, source_id, source) self.mylog.info('ASSERT ACTUAL proxy=' + str(proxy) + ' EQUALS '\ 'EXPECTED proxy=' + str(expected['PROXY'])) su.verify_data(self, expected['PROXY'], proxy) permissions = su.get_source_permissions_link(self, source_id, source) self.mylog.info('ASSERT ACTUAL permissions=' + str(permissions) + ' EQUALS '\ 'EXPECTED permissions=' + str(expected['PERMISSIONS'])) su.verify_data(self, expected['PERMISSIONS'], permissions) query = su.get_source_queries_link(self, source_id, source) self.mylog.info('ASSERT ACTUAL query=' + str(query) + ' EQUALS '\ 'EXPECTED query=' + str(expected['QUERY'])) su.verify_data(self, expected['QUERY'], query) type = su.get_source_type(self, source_id, source) self.mylog.info('ASSERT ACTUAL type=' + str(type) + ' EQUALS '\ 'EXPECTED type=' + str(expected['TYPE'])) su.verify_data(self, expected['TYPE'], type) users = su.get_source_users_link(self, source_id, source) self.mylog.info('ASSERT ACTUAL users=' + str(users) + ' EQUALS EXPECTED '\ 'users=' + str(expected['USERS'])) su.verify_data(self, expected['USERS'], users) ########################################################## def header(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s START --------------->' % test_name) self.mylog.info( '#######################################################') def footer(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s END --------------->' % test_name) self.mylog.info( '#######################################################') self.mylog.info('') ########################################################## def test_get_default_sources_count(self): ''' 1. Get all of the default data sources 2. Verify the number of data sources equals the number of data nodes. ''' self.header('test_get_default_sources_count') self.mylog.info( 'test_get_default_sources_count - STEP 1: Get all default sources') sources = self.rl.get_sources(self.chronograf, self.get_source_path) # by default pcl will create data sources one per data node assert len(sources) == len(self.data_nodes), \ self.mylog.info('test_get_default_sources_count() ASSERTION ' 'FAILURE expected ' + str(len(sources)) + ', actual ' + str(len(self.data_nodes))) self.footer('test_get_default_sources_count') def test_create_source_url_only(self): ''' 1. Creates source by using only one required param in request body - url of the data node. 2. Asserts that ID of the source is not None 3. Get data for the created source 4. Verify expected response data equals actula response data from get source request. ''' # choose a data node from a list of existing data nodes. For now use the first one source_url = self.get_source_path DATA_URL = choice(self.data_nodes) if self.http_auth: JSON_URL_ONLY = { 'url': DATA_URL, 'username': self.admin_user, 'password': self.admin_pass } USERNAME = self.admin_user else: JSON_URL_ONLY = {'url': DATA_URL} USERNAME = '' self.header('test_create_source_url_only') self.mylog.info( 'test_create_source_url_only - STEP 1: CALL RestLib.create_source()' ) (status, message, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_URL_ONLY) assert source_id is not None, self.mylog.info( 'test_create_source_url_only : ASSERTION FAILED, source_id is None' ) self.mylog.info( 'test_create_source_url_only - STEP 1: DONE SOURCE_ID=' + str(source_id)) # Expected dictionary expected = { 'NAME': '', 'INSECURE_SKIP_VERIFY': False, 'DATA_URL': DATA_URL, 'USERNAME': USERNAME, 'ROLES': '', 'DEFAULT': 0, 'TELEGRAF_DB': 'telegraf', 'SHARED_SECRET': '', 'META_URL': '', 'KAPACITOR': '/chronograf/v1/sources/%s/kapacitors' % source_id, 'WRITE': '/chronograf/v1/sources/%s/write' % source_id, 'PROXY': '/chronograf/v1/sources/%s/proxy' % source_id, 'PERMISSIONS': '/chronograf/v1/sources/%s/permissions' % source_id, 'QUERY': '/chronograf/v1/sources/%s/queries' % source_id, 'TYPE': 'influx-enterprise', 'USERS': '/chronograf/v1/sources/%s/users' % source_id } self.mylog.info( 'test_create_source_url_only - STEP 2: CALL RestLib.get_source()') source = self.rl.get_source(self.chronograf, source_url, source_id) self.mylog.info('test_create_source_url_only - STEP 2: DONE') self.verify_source(expected, source_id, source) self.footer('test_create_source_url_only') def test_create_source_incorrect_url(self): ''' 1. Tries to create a source using incorrect url for data node 2. Asserts request status is 400 and error message is 'Error contacting source' NOTE: UI does not return any errors at all. Would be nice to let users know why they cannot create a source ''' JSON_BAD_URL = {'url': 'http://255.0.0.0:8087'} error_message = 'Error contacting source' source_url = self.get_source_path self.header('test_create_source_incorrect_url') self.mylog.info( 'test_create_source_incorrect_url - STEP 1: CALL RestLib.create_source()' ) (status, message, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_BAD_URL) self.mylog.info('test_create_source_incorrecturl - STEP 1: DONE') self.mylog.info( 'test_create_source_incorrect_url : ASSERT 400 equals ' + str(status)) assert 400 == status, self.mylog.info( 'test_create_source_incorrect_url - ASSERTION ERROR, ' 'status=' + str(status)) self.mylog.info('test_create_source_incorrect_url : ASSERT ' + str(error_message)\ + ' equals to ' + str(message)) assert error_message == message, self.mylog.info('message=' + str(message)) def test_create_source_user_options(self): ''' 1. Create source using data that user would be able to enter via UI, i.e: URL of data node, Name of the source, metaURL and telegraf database (All values are correct) Username and Password won't be used (requires different cluster configuration) 2. Assert that ID of the source is not None 3. Verify expected response data equals actual data from get source request ''' # Choose meta and data node from the list of existing nodes. For now use the first one in the list source_url = self.get_source_path DATA_URL = choice(self.data_nodes) META_URL = choice(self.meta_nodes) if self.http_auth: JSON_USER_OPTIONS = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.CUSTOM_NAME, 'telegraf': 'telegraf', 'default': True, 'username': self.admin_user, 'password': self.admin_pass } USERNAME = self.admin_user else: JSON_USER_OPTIONS = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.CUSTOM_NAME, 'telegraf': 'telegraf', 'default': True } USERNAME = '' self.header('test_create_source_user_options') self.mylog.info( 'test_create_user_options - STEP 1: CALL RestLib.create_source()') (status, message, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_USER_OPTIONS) assert source_id is not None, self.mylog.info( 'test_create_source_user_options : ASSERTION FAILED, source_id is None' ) self.mylog.info('test_create_user_options - STEP 1: DONE SOURCE_ID=' + str(source_id)) # Expected dictionary expected = { 'USERNAME': USERNAME, 'INSECURE_SKIP_VERIFY': False, 'DATA_URL': DATA_URL, 'NAME': self.CUSTOM_NAME, 'ROLES': '/chronograf/v1/sources/%s/roles' % source_id, 'DEFAULT': True, 'TELEGRAF_DB': 'telegraf', 'SHARED_SECRET': '', 'META_URL': META_URL, 'KAPACITOR': '/chronograf/v1/sources/%s/kapacitors' % source_id, 'WRITE': '/chronograf/v1/sources/%s/write' % source_id, 'PROXY': '/chronograf/v1/sources/%s/proxy' % source_id, 'PERMISSIONS': '/chronograf/v1/sources/%s/permissions' % source_id, 'QUERY': '/chronograf/v1/sources/%s/queries' % source_id, 'TYPE': 'influx-enterprise', 'USERS': '/chronograf/v1/sources/%s/users' % source_id } self.mylog.info( 'test_create_source_user_options - STEP 2: CALL RestLib.get_source()' ) source = self.rl.get_source(self.chronograf, source_url, source_id) self.mylog.info('test_create_source_user_options - STEP 2: DONE') self.verify_source(expected, source_id, source) self.footer('test_create_source_user_options') def test_update_source_name_field(self): ''' Create source using data that user would be able to enter via UI, i.e: URL of data node, Name of the source, metaURL and telegraf database (All values are correct) Username and Password won't be used (requires different cluster configuration) 2. Assert that ID of the source is not None 3. Verify expected response data equals actual data from get source request ''' source_url = self.get_source_path DATA_URL = choice(self.data_nodes) META_URL = choice(self.meta_nodes) if self.http_auth: JSON_UPDATE_NAME = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.UPDATE_NAME, 'telegraf': 'telegraf', 'default': True, 'username': self.admin_user, 'password': self.admin_pass } JSON_UPDATED_NAME = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.UPDATED_NAME, 'telegraf': 'telegraf', 'default': True, 'username': self.admin_user, 'password': self.admin_pass } USERNAME = self.admin_user else: JSON_UPDATE_NAME = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.UPDATE_NAME, 'telegraf': 'telegraf', 'default': True } JSON_UPDATED_NAME = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.UPDATED_NAME, 'telegraf': 'telegraf', 'default': True } USERNAME = '' self.header('test_update_source_name_field') self.mylog.info( 'test_update_source_name_field - STEP 1: CALL RestLib.create_source()' ) (status, message, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_UPDATE_NAME) assert source_id is not None, self.mylog.info( 'test_update_source_name_field : ASSERTION FAILED, source_id is None' ) self.mylog.info( 'test_update_source_name_field - STEP 1: DONE SOURCE_ID=' + str(source_id)) # Expected dictionary expected = { 'USERNAME': USERNAME, 'INSECURE_SKIP_VERIFY': False, 'DATA_URL': DATA_URL, 'NAME': self.UPDATE_NAME, 'ROLES': '/chronograf/v1/sources/%s/roles' % source_id, 'DEFAULT': 1, 'TELEGRAF_DB': 'telegraf', 'SHARED_SECRET': '', 'META_URL': META_URL, 'KAPACITOR': '/chronograf/v1/sources/%s/kapacitors' % source_id, 'WRITE': '/chronograf/v1/sources/%s/write' % source_id, 'PROXY': '/chronograf/v1/sources/%s/proxy' % source_id, 'PERMISSIONS': '/chronograf/v1/sources/%s/permissions' % source_id, 'QUERY': '/chronograf/v1/sources/%s/queries' % source_id, 'TYPE': 'influx-enterprise', 'USERS': '/chronograf/v1/sources/%s/users' % source_id } expected_updated = { 'USERNAME': USERNAME, 'INSECURE_SKIP_VERIFY': False, 'DATA_URL': DATA_URL, 'NAME': self.UPDATED_NAME, 'ROLES': '/chronograf/v1/sources/%s/roles' % source_id, 'DEFAULT': 1, 'TELEGRAF_DB': 'telegraf', 'SHARED_SECRET': '', 'META_URL': META_URL, 'KAPACITOR': '/chronograf/v1/sources/%s/kapacitors' % source_id, 'WRITE': '/chronograf/v1/sources/%s/write' % source_id, 'PROXY': '/chronograf/v1/sources/%s/proxy' % source_id, 'PERMISSIONS': '/chronograf/v1/sources/%s/permissions' % source_id, 'QUERY': '/chronograf/v1/sources/%s/queries' % source_id, 'TYPE': 'influx-enterprise', 'USERS': '/chronograf/v1/sources/%s/users' % source_id } self.mylog.info( 'test_update_source_name_field - STEP 2: CALL RestLib.get_source()' ) source = self.rl.get_source(self.chronograf, source_url, source_id) self.mylog.info('test_update_source_name_field - STEP 2: DONE') self.verify_source(expected, source_id, source) self.mylog.info( 'test_update_source_name_field - STEP 3: CALL RestLib.patch_source()' ) response = self.rl.patch_source(self.chronograf, source_url, JSON_UPDATED_NAME, source_id) assert response.status_code == 200, \ self.mylog.info('test_update_source_name_field -Assertion Error ' + str(response.text)) self.mylog.info('test_update_source_name_field - STEP 3: DONE') self.mylog.info( 'test_update_source_name_field - STEP 4: CALL RestLib.get_source()' ) source = self.rl.get_source(self.chronograf, source_url, source_id) self.mylog.info('test_update_source_name_field - STEP 4: DONE') self.verify_source(expected_updated, source_id, source) self.footer('test_update_source_name_field') def test_delete_source(self): ''' 1. Create source using data that user would be able to enter via UI, i.e: URL of data node, Name of the source, metaURL and telegraf database (All values are correct) Username and Password won't be used (requires different cluster configuration) 2. Assert that ID of the source is not None 3. Delete Created Source ''' source_url = self.get_source_path DATA_URL = choice(self.data_nodes) META_URL = choice(self.meta_nodes) if self.http_auth: JSON_USER_OPTIONS = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.DELETE_NAME, 'telegraf': 'telegraf', 'default': True, 'username': self.admin_user, 'password': self.admin_pass } else: JSON_USER_OPTIONS = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': self.DELETE_NAME, 'telegraf': 'telegraf', 'default': True } self.header('test_delete_source') self.mylog.info( 'test_delete_source - STEP 1: CALL RestLib.create_source()') (status, message, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_USER_OPTIONS) assert source_id is not None, self.mylog.info( 'test_create_source_user_options : ASSERTION FAILED, source_id is None' ) self.mylog.info('test_create_user_options - STEP 1: DONE SOURCE_ID=' + str(source_id)) self.mylog.info( 'test_delete_source - STEP 2 : DELETING SOURCE FOR source_id=' + str(source_id)) response = self.rl.delete_source(self.chronograf, source_url, source_id) assert response.status_code == 204, \ self.mylog.info('test_update_source_name_field -Assertion Error ' + str(response.text))
class TestSmoke(object): """ TODO """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def test_e2e_smoke(self): """ 1. Create an organization. Verify organization was created successfully. 2. Create a bucket for the organization created in step 1. Verify org was created successfully. 3. Create a user. Verify user was created successfully. 4. Give user permissions to write data to buckets and read data from the same buckets. Verify authentication is successful. 5. Write data points 5.1. Verify data got to kafka. 6. Query data using using queryd. (gateway:9999/api/v2/querysvc) 7. Query data using gateway. (gateway:9999/api/v2/query) """ test_name = 'test_e2e_smoke ' org_name = 'test_e2e_smoke_org' bucket_name = 'test_e2e_smoke_bucket' user_name = 'test_e2e_smoke_user' measurement = 'test_m' tag = 'hello world' tag_storage = 'hello\ world' value = '1234' query = 'from(bucket:"%s") |> range(start:-5m)' % bucket_name err = '' # intial error message is am empty string. data = [ ] # to store the data that made it to kafka, initial value is empty list. final_kafka_points = '' # if kafka has a data we are looking for, added to a final_point str. final_storage_points = '' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Create Organization') self.mylog.info(test_name + '\n') create_org_result = org_util.create_organization( self, self.gateway, org_name) status_code = create_org_result.get('status') org_id = create_org_result.get('org_id') org_name = create_org_result.get('org_name') _assert(self, status_code, 201, 'Create Organization Status Code') verify_org_etcd_entries(self, test_name, org_id, org_name, error='') self.mylog.info(test_name + 'STEP 2: Create Bucket') self.mylog.info(test_name + '\n') create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, organization_id=org_id) status_code = create_bucket_result['status'] created_bucket_id = create_bucket_result.get('bucket_id') created_bucket_name = create_bucket_result.get('bucket_name') _assert(self, status_code, 201, 'Create Bucket Status Code') verify_bucket_etcd_entries(self, test_name, created_bucket_id, created_bucket_name, 0, expected_error='') self.mylog.info(test_name + 'STEP 3: Create User') self.mylog.info(test_name + '\n') status_code, user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) _assert(self, status_code, 201, 'Create User Status Code') permissions = [{ "action": "read", "resource": "bucket/%s" % created_bucket_id }, { "action": "write", "resource": "bucket/%s" % created_bucket_id }] self.mylog.info( test_name + 'STEP 4: Create Authorization Token for \'%s\' to be able to read/write \'%s\' bucket' % (user_name, bucket_name)) self.mylog.info(test_name + '\n') create_auth_result = gateway_util.create_authorization( self, self.gateway, user_name, user_id, json.dumps(permissions)) token = create_auth_result.get('token') _assert(self, create_auth_result.get('status'), 201, 'Create Authorization Status') _assert(self, create_auth_result.get('error'), None, 'Create Authorization Error') self.mylog.info(test_name + 'STEP 5: Write point to a bucket') self.mylog.info(test_name + '\n') write_result = gateway_util.write_points( self, self.gateway, token, org_name, bucket_name, data='%s,t=%s f=%s' % (measurement, tag_storage, value)) _assert(self, write_result.get('status'), 204, 'Write Data Point To A Bucket') _assert(self, write_result.get('error'), '', 'Write Data Error Message') self.mylog.info(test_name + 'STEP 6: Verify Data Was Written To Kafka') self.mylog.info(test_name + '\n') # just if there is a latency on writing data to kafka, give it some time end_time = time.time() + 10 while time.time() <= end_time: topics, data, err = gateway_util.kafka_find_data_by_tag( self, self.kubeconf, self.kubecluster, self.namespace, tag, 'kafka-0') if len(data) == 0: self.mylog.info( test_name + 'KAFKA DOES NOT HAVE THE DATA YET. SLEEPING 1 SECOND.') time.sleep(1) continue else: for point in data: if tag in point: final_kafka_points += point self.mylog.info(test_name + 'KAFKA DOES HAVE THE DATA:' + str(point)) break else: self.mylog.info(test_name + 'KAFKA DOES NOT HAVE THE DATA YET') continue break _assert(self, err, '', 'ERROR GETTING DATA FROM KAFKA') _assert(self, len(data) > 0, True, 'KAFKA DOES NOT HAVE THE DATA') _assert(self, tag in final_kafka_points, True, 'KAFKA DOES NOT HAVE THE DATA') # storage is pulling every 10 seconds from kafka self.mylog.info(test_name + 'STEP 7: Verify Data Was Written To Storage') self.mylog.info(test_name + '\n') end_time = time.time() + 20 while time.time() <= end_time: engine, data, err = gateway_util.storage_find_data( self, self.kubeconf, self.kubecluster, self.namespace, tag, 'storage-0') if len(data) == 0: self.mylog.info( test_name + 'STORAGE DOES NOT HAVE THE DATA YET. SLEEPING FOR 1 SECOND.' ) time.sleep(1) continue else: for point in data: if tag_storage in point: final_storage_points += point self.mylog.info(test_name + 'STORAGE DOES HAVE THE DATA: ' + str(point)) break else: # storage has some data, but data we are looking for is not there yet. self.mylog.info('STORAGE DOES NOT HAVE THE DATA YET') continue break _assert(self, err, '', 'ERROR GETTING DATA FROM STORAGE') _assert(self, len(data) > 0, True, 'STORAGE DOES NOT HAVE THE DATA') _assert(self, tag_storage in final_storage_points, True, 'STORAGE DOES NOT HAVE THE DATA') self.mylog.info(test_name + 'STEP 8: Query Data using Queryd') self.mylog.info(test_name + '\n') # need to give it up to 30 sec to get the results back end_time = time.time() + 30 result_queryd = None while time.time() <= end_time: result_queryd = gateway_util.queryd_query_data(self, query, self.flux, org_id, timeout=5, responsenone=False) if result_queryd.get('status') == 200 and len( result_queryd.get('result')) == 1: break else: self.mylog.info( test_name + 'WAITING FOR QUERY RESULTS. SLEEPING FOR 1 SECOND.') time.sleep(1) _assert(self, result_queryd.get('status'), 200, ' STATUS CODE') _assert(self, len(result_queryd.get('result')), 1, ' NUMBER OF RECORDS') _assert(self, result_queryd.get('result')[0].get('_measurement'), measurement, 'Measurement') _assert(self, result_queryd.get('result')[0].get('_value'), value, 'Field Value') _assert(self, result_queryd.get('result')[0].get('t'), tag, 'Tag Value') self.mylog.info('') self.mylog.info(test_name + 'STEP 9: Query Data using Gateway') self.mylog.info(test_name + '\n') # need to give it up to 30 sec to get the results back end_time = time.time() + 30 result_gateway = None while time.time() <= end_time: result_gateway = gateway_util.gateway_query_data( self, query, self.gateway, token, org_name) if result_gateway.get('status') == 200 and len( result_gateway.get('result')) == 1: break else: self.mylog.info( test_name + 'WAITING FOR QUERY RESULTS. SLEEPING FOR 1 SECONDS.') time.sleep(1) _assert(self, result_gateway.get('status'), 200, ' STATUS CODE') _assert(self, len(result_gateway.get('result')), 1, ' NUMBER OF RECORDS') _assert(self, result_gateway.get('result')[0].get('_measurement'), measurement, 'Measurement') _assert(self, result_gateway.get('result')[0].get('_value'), value, 'Field Value') _assert(self, result_gateway.get('result')[0].get('t'), tag, 'Tag Value') def test_tasks_smoke(self): """ 1. Create organization and verify it was created successfully. 2. Create bucket (source bucket) to read data from and verify it was created successfully. 3. Create bucket (destination bucket) to write data to and verify it was created successfully. 4. Create user. 5. Create an authorization token. 6. Create task. 7. Verify created task. 8. Write a point to a bucket the data is read from. 9. Verify data was written to kafka. 10. Verify data was written to storage. 11. Query written data using gateway endpoint. 12. Wait for task to be executed. 13. Verify data was written to kafka. 14. Verify data was written to a bucket we wrote a data to. 15. Query the data from a bucket the data was written to. """ test_name = 'test_tasks_smoke ' org_name = 'test_tasks_smoke_org' bucket_name_destination = 'test_tasks_smoke_bucket_dest' bucket_name_source = 'test_tasks_smoke_bucket_source' user_name = 'test_tasks_smoke_user' task_description = 'task_description' task_status = 'active' task_name = 'test_task_smoke_name' task_duration = '30s' data = [ ] # to store the data that made it to kafka, initial value is empty list err = '' # initially there is no error task_tag = 'taskcreation' measurement = 'task_m' value = '1234' tag = 'qa_great' result_gateway = {} final_kafka_points = '' final_storage_points = '' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Create Organization') self.mylog.info(test_name + '\n') create_org = org_util.create_organization(self, self.gateway, org_name) status = create_org.get('status') _assert(self, status, 201, 'RESPONSE STATUS') org_id = create_org.get('org_id') org_name = create_org.get('org_name') verify_org_etcd_entries(self, test_name, org_id, org_name, error='') # create bucket to read data from - source bucket self.mylog.info(test_name + 'STEP 2: Create Bucket To Read Data From') self.mylog.info(test_name + '\n') create_bucket_source = buckets_util.create_bucket( self, self.gateway, bucket_name_source, organization_id=org_id) status = create_bucket_source.get('status') _assert(self, status, 201, 'RESPONSE STATUS') bucket_id_created_source = create_bucket_source.get('bucket_id') bucket_name_created_source = create_bucket_source.get('bucket_name') verify_bucket_etcd_entries(self, test_name, bucket_id_created_source, bucket_name_created_source, 0, expected_error='') # create bucket to write data to self.mylog.info(test_name + 'STEP 3: Create Bucket To Write Data To') self.mylog.info(test_name + '\n') create_bucket_dest = buckets_util.create_bucket( self, self.gateway, bucket_name_destination, organization_id=org_id) status = create_bucket_dest.get('status') _assert(self, status, 201, 'RESPONSE STATUS') bucket_id_created_dest = create_bucket_dest.get('bucket_id') bucket_name_created_dest = create_bucket_dest.get('bucket_name') verify_bucket_etcd_entries(self, test_name, bucket_id_created_dest, bucket_name_created_dest, 0, expected_error='') # create user self.mylog.info(test_name + 'STEP 4: Create User') self.mylog.info(test_name + '\n') create_user = gateway_util.create_user(self, self.gateway, user_name) status = create_user[0] _assert(self, status, 201, 'RESPONSE STATUS') user_id = create_user[1] user_name = create_user[2] verify_user_etcd_entries(self, test_name, user_id, user_name, expected_error='') # give user permissions self.mylog.info( test_name + 'STEP 5: Create Authorization Token For Tasks/Write And Read Operations' ) self.mylog.info(test_name + '\n') tasks_permissions = [{ "action": "create", "resource": "org/%s/task" % org_id }, { "action": "read", "resource": "bucket/%s" % bucket_id_created_source }, { "action": "write", "resource": "bucket/%s" % bucket_id_created_dest }] write_permissions = [{ "action": "write", "resource": "bucket/%s" % bucket_id_created_source }] read_permissions = [{ "action": "write", "resource": "bucket/%s" % bucket_id_created_dest }, { "action": "read", "resource": "bucket/%s" % bucket_id_created_source }] create_tasks_permissions = \ gateway_util.create_authorization(self, self.gateway, user_name, user_id, json.dumps(tasks_permissions)) status = create_tasks_permissions.get('status') _assert(self, status, 201, 'RESPONSE STATUS') tasks_token = create_tasks_permissions.get('token') create_write_permissions = \ gateway_util.create_authorization(self, self.gateway, user_name, user_id, json.dumps(write_permissions)) status = create_write_permissions.get('status') _assert(self, status, 201, 'RESPONSE STATUS') write_token = create_write_permissions.get('token') create_read_permissions = \ gateway_util.create_authorization(self, self.gateway, user_name, user_id, json.dumps(read_permissions)) status = create_read_permissions.get('status') _assert(self, status, 201, 'RESPONSE STATUS') read_token = create_read_permissions.get('token') self.mylog.info(test_name + 'STEP 6: Create Task') self.mylog.info(test_name + '\n') flux_script = 'option task = {name:"%s", every:%s} from(bucket:"%s") |> range(start: -1h) ' \ '|> map(fn: (r) => ({_time: r._time, _value:r._value, t : "%s"}))' \ '|> to(bucket:"%s", orgID:"%s")' % \ (task_name, task_duration, bucket_name_source, task_tag, bucket_name_destination, org_id) create_task = tasks_util.create_task(self, self.gateway, org_id, task_description, tasks_token, task_status, flux=flux_script) time_task_created = time.time() self.mylog.info(test_name + 'TASK WAS CREATED AT : ' + str(datetime.now())) status = create_task.get('status') _assert(self, status, 201, 'RESPONSE STATUS') task_id = create_task.get('task_id') # query etcd-tasks etcd_tasks = gateway_util.get_tasks_etcd(self, self.etcd_tasks, task_id) self.mylog.info(test_name + 'ETCD TASKS RESULT : ' + str(etcd_tasks)) self.mylog.info(test_name + 'STEP 7: Verify Created Task') self.mylog.info(test_name + '\n') _assert(self, etcd_tasks.get('flux_script'), flux_script, 'FLUX SCRIPT') _assert(self, etcd_tasks.get('task_name'), task_name, 'TASK_NAME') _assert(self, etcd_tasks.get('org_id'), org_id, 'ORG ID') _assert(self, etcd_tasks.get('user_id'), user_id, 'USER ID') _assert(self, etcd_tasks.get('status'), task_status, 'TASK STATUS') _assert(self, etcd_tasks.get('schedule'), 'every %s' % task_duration, 'TASK SCHEDULE') # write a point self.mylog.info(test_name + 'STEP 8: Write a point') self.mylog.info(test_name + '\n') write_result = gateway_util.write_points(self, self.gateway, write_token, org_name, bucket_name_source, data='%s,t=%s f=%s' % (measurement, tag, value)) _assert(self, write_result.get('status'), 204, 'Write Data Point To A Bucket') _assert(self, write_result.get('error'), '', 'Write Data Error Message') self.mylog.info(test_name + 'STEP 9: Verify Data Was Written To Kafka') self.mylog.info(test_name + '\n') end_time = time.time( ) + 10 # data should be written to kafka right away, but give it up to 10 sec while time.time() <= end_time: topics, data, err = gateway_util.kafka_find_data_by_tag( self, self.kubeconf, self.kubecluster, self.namespace, tag, 'kafka-0') if len( data ) == 0: # kafka does not have any data, usually new deployments self.mylog.info( test_name + 'KAFKA DOES NOT HAVE THE DATA YET. SLEEPING FOR 1 SECOND') time.sleep(1) continue else: for point in data: if tag in point: final_kafka_points += point self.mylog.info(test_name + 'KAFKA DOES HAVE THE DATA: ' + str(point)) break else: # there is already data in kafka, but the data we are looking for is not there yet. self.mylog.info('KAFKA DOES NOT HAVE THE DATA YET') continue break _assert(self, err, '', 'ERROR GETTING DATA FROM KAFKA') _assert(self, len(data) > 0, True, 'KAFKA DOES NOT HAVE THE DATA') _assert(self, tag in final_kafka_points, True, 'KAFKA DOES NOT HAVE THE DATA') # storage is pulling every 10 seconds from kafka self.mylog.info(test_name + 'STEP 10: Verify Data Was Written To Storage') end_time = time.time() + 20 while time.time() <= end_time: engine, data, err = gateway_util.storage_find_data( self, self.kubeconf, self.kubecluster, self.namespace, tag, 'storage-0') if len( data ) == 0: # storage does not have any data yet, new deployments self.mylog.info( test_name + 'STORAGE DOES NOT HAVE THE DATA YET. SLEEPING FOR 1 SECOND' ) time.sleep(1) continue else: for point in data: if tag in point: final_storage_points += point self.mylog.info(test_name + 'STORAGE DOES HAVE THE DATA: ' + str(point)) break else: # storage has some data, but data we are looking for is not there yet. self.mylog.info('STORAGE DOES NOT HAVE THE DATA YET') continue break _assert(self, err, '', 'ERROR GETTING DATA FROM STORAGE') _assert(self, len(data) > 0, True, 'STORAGE DOES NOT HAVE THE DATA') _assert(self, tag in final_storage_points, True, 'STORAGE DOES NOT HAVE THE DATA') # query the data from a bucket self.mylog.info(test_name + 'STEP 11: Query Data using Gateway') self.mylog.info(test_name + '\n') query_out = 'from(bucket:"%s") |> range(start:-5m)' % bucket_name_source end_time = time.time( ) + 15 # should happen right away, since data is already in storage while time.time() <= end_time: result_gateway = gateway_util.gateway_query_data( self, query_out, self.gateway, read_token, org_name) if result_gateway.get('status') == 200 and len( result_gateway.get('result')) == 1: break else: self.mylog.info(test_name + 'WAITING FOR QUERY RESULTS. SLEEPING 1 SECOND') time.sleep(1) _assert(self, result_gateway.get('status'), 200, ' STATUS CODE') _assert(self, len(result_gateway.get('result')), 1, ' NUMBER OF RECORDS') _assert(self, result_gateway.get('result')[0].get('_measurement'), measurement, 'Measurement') _assert(self, result_gateway.get('result')[0].get('_value'), value, 'Field Value') _assert(self, result_gateway.get('result')[0].get('t'), tag, 'Tag Value') # Wait for task service to execute the flux query query_in = 'from(bucket:"%s") |> range(start:-5m)' % bucket_name_destination # task wil start running at the end of the 'end_time', which is time task was created + 40 sec, since task will # start running for the first time after its scheduled time passes, that is 30sec. self.mylog.info(test_name + 'STEP 12: Wait For Task To Be Executed') self.mylog.info(test_name + '\n') end_time = time_task_created + 40 while time.time() < end_time: time.sleep(1) self.mylog.info(test_name + 'STEP 13: Verify Data Was Written To Kafka') self.mylog.info(test_name + '\n') final_kafka_points = '' end_time = time.time() + 10 while time.time() <= end_time: topics, data, err = gateway_util.kafka_find_data_by_tag( self, self.kubeconf, self.kubecluster, self.namespace, task_tag, 'kafka-0') if len(data) == 0: self.mylog.info( test_name + 'KAFKA DOES NOT HAVE THE DATA YET. SLEEPING 1 SECOND.') time.sleep(1) continue else: for point in data: if task_tag in point and not 'task-system' in point: final_kafka_points += point self.mylog.info(test_name + 'KAFKA DOES HAVE THE DATA:' + str(point)) break else: self.mylog.info(test_name + 'KAFKA DOES NOT HAVE THE DATA YET') continue break _assert(self, err, '', 'ERROR GETTING DATA FROM KAFKA') _assert(self, len(data) > 0, True, 'KAFKA DOES NOT HAVE THE DATA') _assert(self, task_tag in final_kafka_points, True, 'KAFKA DOES NOT HAVE THE DATA') # storage is pulling every 10 seconds from kafka self.mylog.info(test_name + 'STEP 14: Verify Data Was Written To Storage') self.mylog.info(test_name + '\n') final_storage_points = '' end_time = time.time() + 20 while time.time() <= end_time: engine, data, err = gateway_util.storage_find_data( self, self.kubeconf, self.kubecluster, self.namespace, task_tag, 'storage-0') if len(data) == 0: self.mylog.info( test_name + 'STORAGE DOES NOT HAVE THE DATA YET. SLEEPING 1 SECOND') time.sleep(1) continue else: for point in data: if task_tag in point and not 'task-system' in point: final_storage_points += point self.mylog.info(test_name + 'STORAGE DOES HAVE THE DATA:' + str(point)) break else: self.mylog.info(test_name + 'STORAGE DOES NOT HAVE THE DATA YET') continue break _assert(self, err, '', 'ERROR GETTING DATA FROM STORAGE') _assert(self, len(data) > 0, True, 'STORAGE DOES NOT HAVE THE DATA') _assert(self, task_tag in final_storage_points, True, 'STORAGE DOES NOT HAVE THE DATA') self.mylog.info(test_name + 'STEP 15: Query Data Using Gateway') self.mylog.info(test_name + '\n') end_time = time.time() + 30 while time.time() <= end_time: result_gateway = gateway_util.gateway_query_data( self, query_in, self.gateway, read_token, org_name) if result_gateway.get('status') == 200 and len( result_gateway.get('result')) == 1: break else: self.mylog.info(test_name + 'WAITING FOR QUERY RESULTS. SLEEPING 2 SECOND') time.sleep(2) _assert(self, result_gateway.get('status'), 200, ' STATUS CODE') _assert(self, len(result_gateway.get('result')), 1, ' NUMBER OF RECORDS') _assert(self, result_gateway.get('result')[0].get('_measurement'), measurement, 'Measurement') _assert(self, result_gateway.get('result')[0].get('_value'), value, 'Field Value') _assert(self, result_gateway.get('result')[0].get('t'), task_tag, 'Tag Value')
class TestCreateOrganizationsAPI(object): """ Test Suite for testing REST API endpoint for creating organizations The existing orgs would be removed before running tests """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): """ :param test_name: :return: """ self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): """ :param test_name: :return: """ self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, org_name): """ :param name_of_the_test_to_run: test to be run :param org_name: name of the organization to be created :return: pass/fail """ test_name = name_of_the_test_to_run + org_name + ' ' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization "%s"' % org_name) create_result = org_util.create_organization(self, self.gateway, org_name) status = create_result['status'] created_org_id = create_result['org_id'] created_org_name = create_result['org_name'] if org_name == '': # TODO: According to @goller organization with empty name can be created. Currently there is a bug. # TODO: Create a bug (@gshif) _assert(self, status, 201, 'status code', xfail=True, reason='Should be able to create an org with empty name') elif org_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='') self.footer(test_name) ############################################ # Lower Case Character Org Names # ############################################ @pytest.mark.parametrize('one_char', ascii_lowercase) def test_create_orgs_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing single character lower case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_single_char_lower_case ', one_char) @pytest.mark.parametrize('ten_char_lc', ten_char_lc) def test_create_orgs_10_char_lower_case(self, ten_char_lc): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing random 10 lower case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_10_char_lower_case ', ten_char_lc) @pytest.mark.parametrize('twenty_char_lc', twenty_char_lc) def test_create_orgs_20_char_lower_case(self, twenty_char_lc): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing random 20 lower case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_20_char_lower_case ', twenty_char_lc) ################################################### # Upper Case Character Org Names # ################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_create_orgs_single_char_upper_case(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing single character upper case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_single_char_upper_case ', one_char) @pytest.mark.parametrize('ten_char_uc', ten_char_uc) def test_create_orgs_10_char_upper_case(self, ten_char_uc): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing random 10 upper case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_10_char_upper_case ', ten_char_uc) @pytest.mark.parametrize('twenty_char_uc', twenty_char_uc) def test_create_orgs_20_char_upper_case(self, twenty_char_uc): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing random 20 upper case letters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_20_char_upper_case ', twenty_char_uc) ######################################################### # Non-alphanumeric Character Org Names # ######################################################### @pytest.mark.parametrize('one_char', nonalphanumeric) def test_create_orgs_single_char_nonalphanumeric_case(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing single non-alphanumeric characters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_single_char_nonalphanumeric_case ', one_char) @pytest.mark.parametrize('ten_char_nonalphanumeric', ten_char_nonalphanumeric) def test_create_orgs_10_char_nonalphanumeric_case( self, ten_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 10 random non-alphanumeric characters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_10_char_nonalphanumeric_case ', ten_char_nonalphanumeric) @pytest.mark.parametrize('twenty_char_nonalphanumeric', twenty_char_nonalphanumeric) def test_create_orgs_20_char_nonalphanumeric_case( self, twenty_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 20 random non-alphanumeric characters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_20_char_nonalphanumeric_case ', twenty_char_nonalphanumeric) ################################################# # Number Characters Org Names # ################################################# @pytest.mark.parametrize('one_char', digits) def test_create_orgs_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing single digits can be created and persisted in the etcd store """ self.run_tests('test_create_orgs_single_char_numbers ', one_char) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_create_orgs_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 10 random digits can be created and persisted in the etcd store """ self.run_tests('test_create_orgs_10_char_numbers', ten_char_numbers) @pytest.mark.parametrize('five_chars', five_char_numbers) def test_create_orgs_5_char_numbers(self, five_chars): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 5 random digits can be created and persisted in the etcd store """ self.run_tests('test_create_orgs_5_char_numbers', five_chars) #################################### # Mix Characters Org Names # #################################### @pytest.mark.parametrize('twenty_char_names', twenty_char_names_list) def test_create_orgs_20_char_mix(self, twenty_char_names): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 20 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_20_char_mix ', twenty_char_names) @pytest.mark.parametrize('forty_char_names', forty_char_names_list) def test_create_orgs_40_char_mix(self, forty_char_names): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 40 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_40_char_mix ', forty_char_names) @pytest.mark.parametrize('special_char', special_char) def test_create_orgs_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing special characters can be created and persisted in the etcd store. """ self.run_tests('test_create_users_special_chars ', special_char) # TODO modify test: should be able to create duplicate org def test_create_duplicate_org(self): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests cannot create org with already existing name. """ test_name = 'test_create_duplicate_org ' org_name = 'duporgname' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization %s' % org_name) create_result = org_util.create_organization(self, self.gateway, org_name) status = create_result['status'] created_org_id = create_result['org_id'] created_org_name = create_result['org_name'] _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, '') self.mylog.info(test_name + 'STEP 3: Creating org with the same name') # TODO: According to @goller multiple organizations with the same name could be created, # TODO: but with different ids, but currently it does not work # TODO: filed a bug(gshif) create_result = org_util.create_organization(self, self.gateway, org_name) status = create_result['status'] _assert(self, status, 201, 'status code', xfail=True, reason='cannot create org with the same name') self.footer(test_name) @pytest.mark.parametrize('two_hundred_char_names', two_hundred_char_name_list) def test_create_orgs_200_char_mix(self, two_hundred_char_names): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 200 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_200_char_mix ', two_hundred_char_names) @pytest.mark.parametrize('four_hundred_char_names', four_hundred_char_name_list) def test_create_orgs_400_char_mix(self, four_hundred_char_names): """ REST API: http://<gateway>/api/v2/orgs METHOD: POST tests org name containing 400 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_orgs_400_char_mix ', four_hundred_char_names)
class TestCreateBucketsAPI(object): """ Test Suite for testing REST API endpoint for creating buckets The existing buckets and organizations would be removed before running tests """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, org_name, bucket_name, retention_period): """ :param name_of_the_test_to_run: test to be run :param org_name: name of the org to be created :param bucket_name: name of the bucket to be created :param retention_period: retention period of the bucket. how long keep the data for. Default is 0s (forever) :return: pass/fail """ test_name = name_of_the_test_to_run + org_name + ' ' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization \'%s\'' % org_name) self.mylog.info('') create_org_result = org_util.create_organization(self, self.gateway, org_name) status = create_org_result['status'] created_org_id = create_org_result['org_id'] created_org_name = create_org_result['org_name'] if org_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif org_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, '') self.mylog.info(test_name + 'STEP 2: Verify org data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='', get_index_values=True, id_by_index_name=created_org_id, error_by_index_name='') self.mylog.info(test_name + 'STEP 3: Create Bucket "%s"' % bucket_name) create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, retention_period, created_org_id) status = create_bucket_result['status'] created_bucket_id = create_bucket_result['bucket_id'] created_bucket_name = create_bucket_result['bucket_name'] if bucket_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif bucket_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 4: Verify bucket data was persisted in the etcd store') # since RP is stored in nanoseconds, need to convert PR that is passed to method (1h, 1m, 1s, etc) into int by # removing the last character that indicates the duration in our case - h (hour) # exp_retention_period = int(retention_period[:-1]) * 3600000000000 verify_bucket_etcd_entries(self, test_name, created_bucket_id, created_bucket_name, expected_error='', expected_retention_period=3600000000000) self.footer(test_name) ############################################ # Lower Case Character Bucket Names # ############################################ @pytest.mark.parametrize('one_char', ascii_lowercase) def test_create_buckets_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing single character lower case letters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing a single lower case ascii character [abcdefghijklmnopqrstuvwxyz] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same lower case ascii character as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_single_char_lower_case ', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_lc', ten_char_lc) def test_create_buckets_10_char_lower_case(self, ten_char_lc): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing random 10 lower case letters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing 10 random lower case ascii characters from the [abcdefghijklmnopqrstuvwxyz] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same lower case ascii characters as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_10_char_lower_case ', ten_char_lc, ten_char_lc, 3600) @pytest.mark.parametrize('twenty_char_lc', twenty_char_lc) def test_create_buckets_20_char_lower_case(self, twenty_char_lc): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing random 20 lower case letters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing 20 random lower case ascii characters from the [abcdefghijklmnopqrstuvwxyz] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same lower case ascii characters as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_20_char_lower_case ', twenty_char_lc, twenty_char_lc, 3600) ###################################################### # Upper Case Character Bucket Names # ###################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_create_buckets_single_char_upper_case(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing single character upper case letters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing a single upper case ascii character [ABCDEFGHIJKLMNOPQRSTUVWXYZ] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same upper case ascii character as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_single_char_upper_case ', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_uc', ten_char_uc) def test_create_buckets_10_char_upper_case(self, ten_char_uc): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing random 10 upper case letters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing 10 random upper case ascii characters from the [ABCDEFGHIJKLMNOPQRSTUVWXYZ] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same upper case ascii characters as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_10_char_upper_case ', ten_char_uc, ten_char_uc, 3600) @pytest.mark.parametrize('twenty_char_uc', twenty_char_uc) def test_create_buckets_20_char_upper_case(self, twenty_char_uc): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing random 20 upper case letters can be created and persisted in the etcd store. Test Steps: 3600. Create an org with the name containing 20 random upper case ascii characters from the [ABCDEFGHIJKLMNOPQRSTUVWXYZ] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same upper case ascii characters as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_20_char_upper_case ', twenty_char_uc, twenty_char_uc, 3600) ############################################################ # Non-alphanumeric Character Bucket Names # ############################################################ @pytest.mark.parametrize('one_char', nonalphanumeric) def test_create_buckets_single_char_nonalphanumeric_case(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing single non-alphanumeric characters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing single non-alphanumeric character from the [!@#$%^*><&()_+{}[]|,.~/`?] list. (",\ and ' is a separate test case) 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same non-alphanumeric character as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_single_char_nonalphanumeric_case ', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_nonalphanumeric', ten_char_nonalphanumeric) def test_create_buckets_10_char_nonalphanumeric_case(self, ten_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 10 random non-alphanumeric characters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing 10 random non-alphanumeric characters from the [!@#$%^*><&()_+{}[]|,.~/`?] list. (",\ and ' is a separate test case) 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same non-alphanumeric characters as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_10_char_nonalphanumeric_case ', ten_char_nonalphanumeric, ten_char_nonalphanumeric, 3600) @pytest.mark.parametrize('twenty_char_nonalphanumeric', twenty_char_nonalphanumeric) def test_create_buckets_20_char_nonalphanumeric_case(self, twenty_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 20 random non-alphanumeric characters can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing 20 random non-alphanumeric characters from the [!@#$%^*><&()_+{}[]|,.~/`?] list. (",\ and ' is a separate test case) 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same non-alphanumeric characters as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_20_char_nonalphanumeric_case ', twenty_char_nonalphanumeric, twenty_char_nonalphanumeric, 3600) #################################################### # Number Characters Bucket Names # #################################################### @pytest.mark.parametrize('one_char', digits) def test_create_buckets_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing single digits can be created and persisted in the etcd store Test Steps: 1. Create an org with the name containing single digit from the [0123456789] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same single digit as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_single_char_numbers ', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_create_buckets_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 10 random digits can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing 10 random digits from the [0123456789] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same 10 random digits as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_10_char_numbers', ten_char_numbers, ten_char_numbers, 3600) @pytest.mark.parametrize('five_chars', five_char_numbers) def test_create_buckets_5_char_numbers(self, five_chars): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 5 random digits can be created and persisted in the etcd store. Test Steps: 1. Create an org with the name containing 20 random digits from the [0123456789] list. 2. Verify org name and org id persisted in the etcd store. 3. Create a bucket with the name containing the same 20 random digits as the organization name. 4. Verify bucket name and bucket id persisted in the etcd store. """ self.run_tests('test_create_buckets_5_char_numbers', five_chars, five_chars, 3600) ####################################### # Mix Characters Bucket Names # ####################################### @pytest.mark.parametrize('twenty_char_names', twenty_char_names_list) def test_create_buckets_20_char_mix(self, twenty_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 20 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_buckets_20_char_mix ', twenty_char_names, twenty_char_names, 3600) @pytest.mark.parametrize('forty_char_names', forty_char_names_list) def test_create_buckets_40_char_mix(self, forty_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 40 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_buckets_40_char_mix ', forty_char_names, forty_char_names, 3600) @pytest.mark.parametrize('special_char', special_char) def test_create_buckets_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing special characters can be created and persisted in the etcd store. """ self.run_tests('test_create_buckets_special_chars ', special_char, special_char, 3600) @pytest.mark.parametrize('two_hundred_char_names', two_hundred_char_name_list) def test_create_buckets_200_char_mix(self, two_hundred_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 200 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_buckets_200_char_mix ', two_hundred_char_names, two_hundred_char_names, 3600) @pytest.mark.parametrize('four_hundred_char_names', four_hundred_char_name_list) def test_create_buckets_400_char_mix(self, four_hundred_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket name containing 400 mix characters can be created and persisted in the etcd store. """ self.run_tests('test_create_buckets_400_char_mix ', four_hundred_char_names, four_hundred_char_names, 3600) def test_create_many_buckets_same_org(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests many buckets with different names can be created for the same organization. """ org_name = 'one_for_all' test_name = 'test_create_many_buckets_same_org ' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Create Organization \'%s\'' % org_name) create_org_result = org_util.create_organization(self, self.gateway, org_name) status = create_org_result['status'] created_org_id = create_org_result['org_id'] created_org_name = create_org_result['org_name'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, '') self.mylog.info(test_name + 'STEP 2: Verify org data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='', get_index_values=True, id_by_index_name=created_org_id, error_by_index_name='') self.mylog.info(test_name + 'STEP 3: Create Multiple Buckets for "%s" name' % org_name) for bucket_name in ascii_lowercase: self.mylog.info(test_name + 'Creating bucket \'%s\' name' % bucket_name) create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, 3600, created_org_id) status = create_bucket_result['status'] created_bucket_id = create_bucket_result['bucket_id'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, '') self.mylog.info(test_name + 'Verify bucket data was persisted in the etcd store') verify_bucket_etcd_entries(self, test_name, created_bucket_id, bucket_name, expected_error='', expected_retention_period=3600000000000) self.footer(test_name) def test_create_same_bucket_different_orgs(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket with the same name can be created for different organizations """ bucket_name = 'one_for_all' test_name = 'test_create_same_bucket_different_orgs ' self.header(test_name) for org_name in ascii_lowercase: org_name = org_name + '_same_bucket_name' self.mylog.info(test_name + 'STEP 1: Create Organization \'%s\'' % org_name) create_org_result = org_util.create_organization(self, self.gateway, org_name) status = create_org_result['status'] created_org_id = create_org_result['org_id'] created_org_name = create_org_result['org_name'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, '') self.mylog.info(test_name + 'STEP2: Verify org data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='', get_index_values=True, id_by_index_name=created_org_id, error_by_index_name='') self.mylog.info(test_name + 'STEP 3: Create Bucket \'%s\' name for org \'%s\' name' % (bucket_name, org_name)) create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, 3600, created_org_id) status = create_bucket_result['status'] created_bucket_id = create_bucket_result['bucket_id'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, '') self.mylog.info(test_name + 'STEP 4: Verify bucket data was persisted in the etcd store') verify_bucket_etcd_entries(self, test_name, created_bucket_id, bucket_name, expected_error='', expected_retention_period=3600000000000) self.footer(test_name) def test_create_duplicate_bucket(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests cannot create bucket with already existing name with the same org. """ test_name = 'test_create_duplicate_bucket ' org_name = 'orgname' bucket_name = 'dupbucketname' expected_error_message = 'bucket with name dupbucketname already exists' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization \'%s\'' % org_name) create_org_result = org_util.create_organization(self, self.gateway, org_name) status = create_org_result['status'] created_org_id = create_org_result['org_id'] created_org_name = create_org_result['org_name'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, '') self.mylog.info(test_name + 'STEP 2: Verify org data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='', get_index_values=True, id_by_index_name=created_org_id, error_by_index_name='') self.mylog.info(test_name + 'STEP 3: Create Bucket \'%s\'' % bucket_name) create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, 3600, created_org_id) status = create_bucket_result['status'] created_bucket_id = create_bucket_result['bucket_id'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 4: Verify bucket data was persisted in the etcd store') verify_bucket_etcd_entries(self, test_name, created_bucket_id, bucket_name, expected_error='', expected_retention_period=3600000000000) self.mylog.info(test_name + 'STEP 5: Create Bucket with already existing name for the same org') create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, 3600, created_org_id) error_message = create_bucket_result['error_message'] _assert(self, error_message, expected_error_message, 'error message') self.footer(test_name) def test_create_bucket_no_org_id(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests cannot create bucket if organization id is not provided """ test_name = 'test_create_bucket_no_org_id' bucket_name = 'bucket_no_org_id' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Create Bucket \'%s\' without ORG ID' % bucket_name) create_bucket_result = buckets_util.create_bucket(self, self.gateway, bucket_name, 3600) status = create_bucket_result['status'] _assert(self, status, 404, 'status code', xfail=True, reason='status=%s' % status) def test_create_bucket_default_rp(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: POST tests bucket cannot be created if retention policy is not provided, (was before: default RP is used: 0s)) """ test_name = 'test_create_bucket_default_rp' org_name = 'org_default_rp' bucket_name = 'bucket_default_rp' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization "%s"' % org_name) create_org_result = org_util.create_organization(self, self.gateway, org_name) status = create_org_result['status'] created_org_id = create_org_result['org_id'] created_org_name = create_org_result['org_name'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify org data was persisted in the etcd store') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='', get_index_values=True, id_by_index_name=created_org_id, error_by_index_name='') self.mylog.info(test_name + 'STEP 3: Create Bucket \'%s\'' % bucket_name) create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, retention_rules=None, organization_id=created_org_id) status = create_bucket_result['status'] created_bucket_id = create_bucket_result['bucket_id'] retention_period = create_bucket_result['every_seconds'] self.mylog.info(test_name + 'Assert actual status \'%s\' equals to expected status 201' % status) _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'Assert actual RP \'%s\' equals to expected RP \'%s\'' % (retention_period, 0)) _assert(self, retention_period, 0, 'retention policy') self.mylog.info(test_name + 'STEP 4: Verify bucket data was persisted in the etcd store') verify_bucket_etcd_entries(self, test_name, created_bucket_id, bucket_name, expected_error='', expected_retention_period=0) self.footer(test_name)
class TestAEService(object): ''' ''' mylog = lu.log(lu.get_log_path(), 'w', __name__) irl = influxdb_rest_lib.InfluxDBInfluxDBRestLib(mylog) #################################################################################################################### def header(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s START --------------->' % test_name) self.mylog.info( '#######################################################') def footer(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s END --------------->' % test_name) self.mylog.info( '#######################################################') self.mylog.info('') #################################################################################################################### @pytest.mark.parametrize('drop_database', ['test_tsm_db'], ids=[''], indirect=True) @pytest.mark.usefixtures('drop_database') def test_tsm_diffs(self): ''' ''' time_minus_3_days_ms = int(10800000) test_name = 'test_tsm_diffs ' database_name = 'test_tsm_db' rp = 'tsm_diff' user = self.clusteros host = (self.meta_leader).split('//')[1][:-5] privatekey = self.privatekey data_node = choice(self.data_nodes_ips) username, password = '', '' current_time_sec = int((datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1)).total_seconds()) point_time_sec = current_time_sec - 10800 - 1 current_time_ms = current_time_sec * 1000 point_time = current_time_ms - time_minus_3_days_ms if self.http_auth: # it is not supported by the writenode tool username = self.admin_user password = self.admin_pass point = [{ 'measurement': 'test_tsm', 'time': point_time, 'fields': { 'value': 1 }, 'tags': { 't': 1 } }] cmd_chmod='ssh -i %s -o StrictHostKeyChecking=no %s@%s \'cd /tmp; sudo chmod +x writenode_lin\'' \ % (privatekey, user, host) shard_id = None self.header(test_name) self.mylog.info(test_name + 'STEP 1: Create InfluxDBClient') client = InfluxDBClient(data_node, username=username, password=password) self.mylog.info(test_name + 'STEP 2: Create database') (success, error) = du.create_database(self, client, database_name) assert success, self.mylog.info(test_name + 'Failure to create database :' + str(error)) self.mylog.info( test_name + 'STEP 3: Create retention policy with Replicaiton Factor 2') (success, error) = du.create_retention_policy(self, client, rp_name=rp, duration='36h', replication='2', database=database_name, default=True) assert success, self.mylog.info( test_name + 'Failure to create retention policy :' + str(error)) # every 5 seconds if there are no writes the data from WAL will be written to TSM file # (INFLUXDB_DATA_CACHE_SNAPSHOT_WRITE_COLD_DURATION="5s" - setting in data section, provided through installer self.mylog.info(test_name + 'STEP 4: Write a point into %s database' % database_name) self.mylog.info(test_name + 'POINT_TIME_SEC=' + str(point_time_sec)) result = du.write_points(self, client, points=point, time_precision='ms', database=database_name) assert result, self.mylog.info(test_name + 'Failure to write a point first time') self.mylog.info( test_name + 'STEP 5: Wait for 7sec(CACHE_SNAPSHOT_WRITE_COLD_DURATION=5sec) before writing ' 'a second point to create a second tsm file') time.sleep(7) # at this time we should have one tsm file (the same shard group) on two of the data nodes self.mylog.info( test_name + 'STEP 6: Load extra data into randomly chosen data node to cause entropy' ) status, result, error = self.irl._show_cluster(self.meta_leader) assert status, self.mylog.info(test_name + 'Failed to show cluster info :' + str(error)) data_node_id = choice(iu.show_cluster_data_nodes(self, result).keys()) self.mylog.info(test_name + 'Write extra data to \'%s\' node' % str(data_node_id)) status, result, error = self.irl._show_shards(self.meta_leader) assert status, self.mylog.info(test_name + 'Failed to show shards info :' + str(error)) shards = iu.show_shards(self, result) # get the shard id the extra data should be written to for key, value in shards.items(): if value['database'] == database_name: shard_id = key self.mylog.info(test_name + 'SHARD_ID=' + str(shard_id)) break assert 0 == litmus_utils.execCmd(self, cmd_chmod), \ self.mylog.info(test_name + 'Failied to execute \'%s\'' % cmd_chmod) cmd='ssh -i %s -o StrictHostKeyChecking=no %s@%s \'cd /tmp; ./writenode_lin -node %d -points 100 -shards %s' \ ' -starttime %d\'' % (privatekey, user, host, data_node_id, shard_id, point_time_sec) assert 0 == litmus_utils.execCmd(self, cmd), \ self.mylog.info(test_name + 'Failied to execute \'%s\'' % cmd) self.mylog.info( test_name + 'Wait for 10 sec (INFLUXDB_DATA_COMPACT_FULL_WRITE_COLD_DURATION=10s) ' 'for compaction to complete') time.sleep(15) self.mylog.info(test_name + 'GET SHARD STRUCTURE OF DATANODES') for datanode in self.data_nodes_ips: litmus_utils.shard_layout(self, privatekey, '/var/lib/influxdb/data', database_name, rp, shard_id, user, datanode) self.mylog.info(test_name + 'STEP 7: Verify entropy was detected') success, result, message = self.irl._show_entropy( choice(self.data_nodes)) assert success, self.mylog.info(test_name + 'Failure to run \'show entropy\' :' + str(error)) entropy_shard = iu.show_entropy_shards(self, result) self.mylog.info(test_name + 'Assert expected status=diff equals to ' + entropy_shard[shard_id].get('status')) assert entropy_shard[shard_id].get( 'status') == 'diff', self.mylog.info('Assertion Error') # TODO: add retentin policy and database assertions. self.mylog.info(test_name + 'STEP 8: Fix entropy') (success, message) = self.irl.shard_repair(choice(self.data_nodes), shard_id) assert success, self.mylog.info( test_name + 'Failed to repair shard %s, message=%s' % (shard_id, message)) self.mylog.info(test_name + 'GET SHARD STRUCTURE OF DATANODES AFTER SHARD REPAIR') for datanode in self.data_nodes_ips: litmus_utils.shard_layout(self, privatekey, '/var/lib/influxdb/data', database_name, rp, shard_id, user, datanode) time.sleep(10) success, result, message = self.irl._show_entropy( choice(self.data_nodes)) assert success, self.mylog.info(test_name + 'Failure to run \'show entropy\' :' + str(error)) entropy_shard = iu.show_entropy_shards(self, result) assert entropy_shard == {} self.footer(test_name)
class TestKapacitor(): ''' kapacitor fixture - to get kapacitor URL chronograf fixture - to get chronograf URL data_node and meta_nodes fixtures - to get lists of meta and data nodes delete_created_sources - to delete sources created by kapacitor tests http_auth fixture - whether basic authentication is enabled admin_user and admin_pass fixtures - to get the username and password of the admin user. ''' mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = chronograf_rest_lib.RestLib(mylog) #################################################################################################################### def header(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s START --------------->' % test_name) self.mylog.info( '#######################################################') def footer(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s END --------------->' % test_name) self.mylog.info( '#######################################################') self.mylog.info('') def test_create_kapacitor(self): ''' 1. Create source and verify source_id is not None 2. Get Kapacitor URL - /chronograf/v1/sources/<source_id>/kapacitors 3. Create Kapacitor and verify kapacitor_id is not None 4. Get kapacitor data for the above created kapacitor instance 5. Assert Kapacitor is ping-able ''' self.header('test_create_kapacitor') source_url = self.get_source_path DATA_URL = choice(self.data_nodes) META_URL = choice(self.meta_nodes) SOURCE_NAME = 'CREATE KAPACITOR' KAPACITOR_NAME = 'KAPACITOR 1' if self.http_auth: JSON_SOURCE = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': SOURCE_NAME, 'telegraf': 'telegraf', 'default': True, 'username': self.admin_user, 'password': self.admin_pass } else: JSON_SOURCE = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': SOURCE_NAME, 'telegraf': 'telegraf', 'default': True } JSON_KAPACITOR = {'url': self.kapacitor, 'name': KAPACITOR_NAME} self.mylog.info( 'test_create_kapacitor - STEP 1: CREATE SOURCE (RestLib.create_source())' ) (status, message, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_SOURCE) assert source_id is not None, self.mylog.info( 'test_create_kapacitor : ASSERTION FAILED, source_id is None') self.mylog.info('test_create_kapacitor - STEP 2: GET KAPACITOR URL') source = self.rl.get_source(self.chronograf, source_url, source_id) kapacitor_url = su.get_source_kapacitors_link(self, source_id, source) self.mylog.info( 'test_create_kapacitor - STEP 3: CREATE KAPACITOR (RestLib.create_kapacitor)' ) (status, message, kapacitor_id) = self.rl.create_kapacitor(self.chronograf, kapacitor_url, JSON_KAPACITOR) assert kapacitor_id is not None, self.mylog.info( 'test_create_kapacitor : ASSERTION FAILED, kapacitor_id is None') self.mylog.info( 'test_create_kapacitor - STEP 4: GET KAPACITOR DATA(RestLib.get_kapacitor)' ) kapacitor_dictionary = self.rl.get_kapacitor(self.chronograf, kapacitor_url, kapacitor_id) self.mylog.info( 'test_create_kapacitor - STEP 4: GET KAPACITOR PING LINK(util.kpacitor_util.get_kapacitor_ping)' ) ping_link = ku.get_kapacitor_ping(self, kapacitor_id, kapacitor_dictionary) self.mylog.info('test_create_kapacitor ping url =' + str(ping_link)) self.mylog.info( 'test_create_kapacitor - STEP 5: PING KAPACITOR URL USING=' + str(ping_link)) response = self.rl.get(self.chronograf, ping_link) assert response.status_code == 204, self.mylog.info( 'test_create_kapacitor ASSERTION ERROR status_code=' + str(response.status_code)) self.footer('test_ create_kapacitor') def test_update_kapacitor_name(self): ''' 1. Create source and verify source_id is not None 2. Get Kapacitor URL - /chronograf/v1/sources/<source_id>/kapacitors 3. Create Kapacitor and verify kapacitor_id is not None 4. Get kapacitor data for the above created kapacitor instance 5. Assert Kapacitor is ping-able 6. Update Kapacitor's name 7. Get updated Kapacitor's name and assert it has been changed ''' self.header('test_update_kapacitor_name') source_url = self.get_source_path DATA_URL = choice(self.data_nodes) META_URL = choice(self.meta_nodes) SOURCE_NAME = 'CREATE KAPACITOR 2' KAPACITOR_NAME = 'KAPACITOR 2' KAPACITOR_UPDATED_NAME = 'KAPACITOR NEW NAME' if self.http_auth: JSON_SOURCE = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': SOURCE_NAME, 'telegraf': 'telegraf', 'default': True, 'username': self.admin_user, 'password': self.admin_pass } else: JSON_SOURCE = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': SOURCE_NAME, 'telegraf': 'telegraf', 'default': True } JSON_KAPACITOR = {'url': self.kapacitor, 'name': KAPACITOR_NAME} JSON_UPDATE_KAPACITOR = { 'url': self.kapacitor, 'name': KAPACITOR_UPDATED_NAME } self.mylog.info( 'test_update_kapacitor_name - STEP 1: CREATE SOURCE (RestLib.create_source())' ) (status, message, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_SOURCE) assert source_id is not None, self.mylog.info( 'test_create_kapacitor_name : ASSERTION FAILED, source_id is None') self.mylog.info( 'test_update_kapacitor_name - STEP 2: GET KAPACITOR URL') source = self.rl.get_source(self.chronograf, source_url, source_id) kapacitor_url = su.get_source_kapacitors_link(self, source_id, source) self.mylog.info( 'test_update_kapacitor_name - STEP 3: CREATE KAPACITOR (RestLib.create_kapacitor)' ) (status, message, kapacitor_id) = self.rl.create_kapacitor(self.chronograf, kapacitor_url, JSON_KAPACITOR) assert kapacitor_id is not None, self.mylog.info( 'test_update_kapacitor : ASSERTION FAILED, kapacitor_id is None') self.mylog.info( 'test_update_kapacitor_name - STEP 4: GET KAPACITOR DATA(RestLib.get_kapacitor)' ) kapacitor_dictionary = self.rl.get_kapacitor(self.chronograf, kapacitor_url, kapacitor_id) self.mylog.info( 'test_update_kapacitor_name - STEP 4: GET KAPACITOR PING LINK(util.kpacitor_util.get_kapacitor_ping)' ) ping_link = ku.get_kapacitor_ping(self, kapacitor_id, kapacitor_dictionary) self.mylog.info('test_update_kapacitor_name ping url =' + str(ping_link)) self.mylog.info( 'test_update_kapacitor_name - STEP 5: PING KAPACITOR URL USING=' + str(ping_link)) response = self.rl.get(self.chronograf, ping_link) assert response.status_code == 204, \ self.mylog.info('test_update_kapacitor_name ASSERTION ERROR' ' status_code=' + str(response.status_code)) self.mylog.info( 'test_update_kapacitor_name - STEP 6: UPDATE KAPACITOR NAME RestLib.patch_kapacitor)' ) response = self.rl.patch_kapacitor(self.chronograf, kapacitor_url, kapacitor_id, JSON_UPDATE_KAPACITOR) assert response.status_code == 200, \ self.mylog.info('test_update_kapacitor_name ASSERTION ERROR status_code=' + str(response.status_code)) kapacitor_dictionary = self.rl.get_kapacitor(self.chronograf, kapacitor_url, kapacitor_id) self.mylog.info( 'test_update_kapacitor_name - STEP 7: GET UPDATED KAPACITOR NAME') new_name = ku.get_kapacitor_name(self, kapacitor_id, kapacitor_dictionary) assert new_name == KAPACITOR_UPDATED_NAME, self.mylog.info( 'test_update_kapacitor_name updated name=' + str(new_name) + ', but expected ' + KAPACITOR_UPDATED_NAME) self.footer('test_update_kapacitor_name') def test_delete_kapacitor(self): ''' 1. Create source and verify source_id is not None 2. Get Kapacitor URL - /chronograf/v1/sources/<source_id>/kapacitors 3. Create Kapacitor and verify kapacitor_id is not None 4. Get kapacitor data for the above created kapacitor instance 5. Assert Kapacitor is ping-able 6. Delete created kapacitor ''' self.header('test_delete_kapacitor') source_url = self.get_source_path DATA_URL = choice(self.data_nodes) META_URL = choice(self.meta_nodes) SOURCE_NAME = 'CREATE KAPACITOR 3' KAPACITOR_NAME = 'KAPACITOR 3' if self.http_auth: JSON_SOURCE = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': SOURCE_NAME, 'telegraf': 'telegraf', 'default': True, 'username': self.admin_user, 'password': self.admin_pass } else: JSON_SOURCE = { 'url': DATA_URL, 'metaUrl': META_URL, 'name': SOURCE_NAME, 'telegraf': 'telegraf', 'default': True } JSON_KAPACITOR = {'url': self.kapacitor, 'name': KAPACITOR_NAME} self.mylog.info( 'test_delete_kapacitor - STEP 1: CREATE SOURCE (RestLib.create_source())' ) (status, source_body, source_id) = self.rl.create_source(self.chronograf, source_url, JSON_SOURCE) assert source_id is not None, self.mylog.info( 'test_delete_kapacitor : ASSERTION FAILED, source_id is None') self.mylog.info('test_delete_kapacitor - STEP 2: GET KAPACITOR URL') source = self.rl.get_source(self.chronograf, source_url, source_id) kapacitor_url = su.get_source_kapacitors_link(self, source_id, source) self.mylog.info( 'test_delete_kapacitor - STEP 3: CREATE KAPACITOR (RestLib.create_kapacitor)' ) (status, kap_body, kapacitor_id) = self.rl.create_kapacitor(self.chronograf, kapacitor_url, JSON_KAPACITOR) assert kapacitor_id is not None, self.mylog.info( 'test_delete_kapacitor : ASSERTION FAILED, kapacitor_id is None') self.mylog.info( 'test_delete_kapacitor - STEP 4: GET KAPACITOR DATA(RestLib.get_kapacitor)' ) kapacitor_dictionary = self.rl.get_kapacitor(self.chronograf, kapacitor_url, kapacitor_id) self.mylog.info( 'test_delete_kapacitor - STEP 4: GET KAPACITOR PING LINK(util.kpacitor_util.get_kapacitor_ping)' ) ping_link = ku.get_kapacitor_ping(self, kapacitor_id, kapacitor_dictionary) self.mylog.info('test_delete_kapacitor ping url =' + str(ping_link)) self.mylog.info( 'test_delete_kapacitor - STEP 5: PING KAPACITOR URL USING=' + str(ping_link)) response = self.rl.get(self.chronograf, ping_link) assert response.status_code == 204, self.mylog.info( 'test_delete_kapacitor ASSERTION ERROR status_code=' + str(response.status_code)) self.mylog.info( 'test_delete_kapacitor - STEP 7: DELETE KAPACITOR ID=' + str(kapacitor_id)) response = self.rl.delete_kapacitor(self.chronograf, kapacitor_url, kapacitor_id) assert response.status_code == 204, \ self.mylog.info('test_delete_kapacitor ASSERTION ERROR status_code=' + str(response.status_code)) self.footer('test_delete_kapacitor')
class TestGetUsersAPI(object): """ Test Suite for testing REST API endpoint for getting single user by id removes created by tests users """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test, user_name): """ :param name_of_the_test: name of the test to run :param user_name: user name to get :return: pass/fail """ test_name = name_of_the_test + user_name + ' ' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create User \'%s\'' % user_name) status, created_user_id, created_user_name, error_message = \ gateway_util.create_user(self, self.gateway, user_name) if user_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif user_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info(test_name + 'STEP 2: Verify data was persisted in the etcd store') verify_user_etcd_entries(self, test_name, created_user_id, created_user_name, expected_error='') self.mylog.info(test_name + ' STEP 3: Get Created User') status, actual_user_id, actual_user_name, error_message = \ gateway_util.get_user_by_id(self, self.gateway, created_user_id) self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, 200)) _assert(self, status, 200, 'status code') self.mylog.info( test_name + 'Assert actual user_id \'%s\' equals expected user_id \'%s\'' % (actual_user_id, created_user_id)) _assert(self, actual_user_id, created_user_id, 'user id') self.mylog.info( test_name + 'Assert actual user_name \'%s\' equals expected user_name \'%s\'' % (actual_user_name, created_user_name)) _assert(self, actual_user_name, created_user_name, 'user name') self.footer(test_name) ############################################ # Lower Case Character Get User Name # ############################################ @pytest.mark.parametrize('one_char', ascii_lowercase) def test_get_users_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using single lower case characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_single_char_lower_case_', one_char) @pytest.mark.parametrize('ten_char_lc', ten_char_lc) def test_get_users_10_char_lower_case(self, ten_char_lc): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 10 random lower case characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_10_char_lower_case_', ten_char_lc) @pytest.mark.parametrize('twenty_char_lc', twenty_char_lc) def test_get_users_20_char_lower_case(self, twenty_char_lc): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 20 random lower case characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_20_char_lower_case_', twenty_char_lc) ################################################### # Upper Case Character Get User Name # ################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_get_users_single_char_upper_case(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using single upper case characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_single_char_upper_case_', one_char) @pytest.mark.parametrize('ten_char_uc', ten_char_uc) def test_get_users_10_char_upper_case(self, ten_char_uc): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 10 random upper case characters can be returned by using get user by id endpoint. """ self.run_tests('est_get_users_10_char_upper_case_', ten_char_uc) @pytest.mark.parametrize('twenty_char_uc', twenty_char_uc) def test_get_users_20_char_upper_case(self, twenty_char_uc): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 20 random upper case characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_orgs_20_char_upper_case_', twenty_char_uc) ######################################################### # Non-alphanumeric Character Get User Name # ######################################################### @pytest.mark.parametrize('one_char', nonalphanumeric) def test_get_users_single_char_nonalphanumeric(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using single non-alphanumeric characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_single_char_nonalphanumeric_', one_char) @pytest.mark.parametrize('ten_char_alphanumeric', ten_char_nonalphanumeric) def test_get_users_10_char_nonalphanumeric(self, ten_char_alphanumeric): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 10 random non-alphanumeric characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_orgs_10_char_nonalphanumeric_', ten_char_alphanumeric) @pytest.mark.parametrize('twenty_char_alphanumeric', twenty_char_nonalphanumeric) def test_get_users_20_char_nonalphanumeric(self, twenty_char_alphanumeric): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 20 random non-alphanumeric characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_orgs_20_char_nonalphanumeric_', twenty_char_alphanumeric) ################################################# # Number Characters Get User Name # ################################################# @pytest.mark.parametrize('one_char', digits) def test_get_users_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using single digits can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_single_char_numbers_', one_char) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_get_users_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 10 random digits can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_10_char_numbers_', ten_char_numbers) @pytest.mark.parametrize('five_char_numbers', five_char_numbers) def test_get_users_5_char_numbers(self, five_char_numbers): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 5 random digits can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_5_char_numbers_', five_char_numbers) #################################### # Mix Characters Get User Name # #################################### @pytest.mark.parametrize('twenty_char', twenty_char_names_list) def test_get_users_20_char_name_mix(self, twenty_char): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 20 mix characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_20_char_name_mix_', twenty_char) @pytest.mark.parametrize('forty_char', forty_char_names_list) def test_get_users_40_char_name_mix(self, forty_char): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 40 mix characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_40_char_name_mix_', forty_char) @pytest.mark.parametrize('two_hundred_char_names', two_hundred_char_name_list) def test_get_users_200_char_mix(self, two_hundred_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 200 mix characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_200_char_name_mix_', two_hundred_char_names) @pytest.mark.parametrize('four_hundred_char_names', four_hundred_char_name_list) def test_get_users_400_char_mix(self, four_hundred_char_names): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using 400 mix characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_400_char_name_mix_', four_hundred_char_names) @pytest.mark.parametrize('special_char', special_char) def test_get_users_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests created user using special characters can be returned by using get user by id endpoint. """ self.run_tests('test_get_users_special_chars_', special_char) def test_get_non_existent_user_id(self): """ REST API: http://<gateway>/api/v2/users METHOD: GET tests getting non-existent user returns an error. """ test_name = 'test_get_non_existent_user_id ' user_id = 'doesnotexist' expected_status = 404 expected_error_message = 'user not found' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get non-existent user id') status, actual_user_id, actual_user_name, error_message = \ gateway_util.get_user_by_id(self, self.gateway, user_id) self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, expected_status)) _assert(self, status, expected_status, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') self.mylog.info( test_name + 'Assert actual error message \'%s\' equals to expected error message \'%s\'' % (error_message, expected_error_message)) _assert(self, error_message, expected_error_message, 'error message')
class TestGetBucketsAPI(object): """ Test Suite for testing REST API endpoint for getting single bucket by id removes created by tests buckets and organizations """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, org_name, bucket_name, retention_period): """ :param name_of_the_test_to_run: test to be run :param org_name: name of the organization to be created :param bucket_name: name of the bucket to be created :param retention_period: retention period of the bucket :return: pass/fail """ test_name = name_of_the_test_to_run + org_name + ' ' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization "%s"' % org_name) self.mylog.info(test_name + '') create_org_result = org_util.create_organization( self, self.gateway, org_name) status = create_org_result['status'] created_org_name = create_org_result['org_name'] created_org_id = create_org_result['org_id'] if org_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif org_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, '') self.mylog.info( test_name + 'STEP 2: Verify org data was persisted in the etcd store') self.mylog.info(test_name + '') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='', get_index_values=True, id_by_index_name=created_org_id, error_by_index_name='') self.mylog.info(test_name + 'STEP 3: Create Bucket "%s"' % bucket_name) self.mylog.info(test_name + '') create_bucket_result = \ buckets_util.create_bucket(self, self.gateway, bucket_name, retention_period, created_org_id) status = create_bucket_result['status'] created_bucket_id = create_bucket_result['bucket_id'] created_bucket_name = create_bucket_result['bucket_name'] if bucket_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/162') elif bucket_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info( test_name + 'STEP 4: Verify bucket data was persisted in the etcd store') self.mylog.info(test_name + '') # since RP is stored in nanoseconds, need to convert PR that is passed to method in seconds. exp_retention_period = int(retention_period) * 1000000000 verify_bucket_etcd_entries( self, test_name, created_bucket_id, created_bucket_name, expected_error='', expected_retention_period=exp_retention_period) self.mylog.info(test_name + ' STEP 5: Get Created Bucket') self.mylog.info(test_name + '') get_buckets_result = buckets_util.get_bucket_by_id( self, self.gateway, created_bucket_id) status = get_buckets_result['status'] actual_bucket_name = get_buckets_result['bucket_name'] actual_bucket_id = get_buckets_result['bucket_id'] self.mylog.info( test_name + 'Assert actual status \'%s\'equals to expected status \'%s\'' % (status, 200)) _assert(self, status, 200, '') self.mylog.info( test_name + 'Assert actual bucket_id \'%s\' equals to expected bucket id \'%s\'' % (actual_bucket_name, created_bucket_id)) _assert(self, actual_bucket_id, created_bucket_id, '') self.mylog.info( test_name + 'Assert actual bucket_name \'%s\' equals to expected bucket_name \'%s\'' % (actual_bucket_name, created_bucket_name)) _assert(self, actual_bucket_name, created_bucket_name, '') self.footer(test_name) ############################################## # Lower Case Character Get bucket Name # ############################################## @pytest.mark.parametrize('one_char', ascii_lowercase) def test_get_buckets_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using single lower case characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_single_char_lower_case_', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_lc', ten_char_lc) def test_get_buckets_10_char_lower_case(self, ten_char_lc): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 10 random lower case characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_10_char_lower_case_', ten_char_lc, ten_char_lc, 3600) @pytest.mark.parametrize('twenty_char_lc', twenty_char_lc) def test_get_buckets_20_char_lower_case(self, twenty_char_lc): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 20 random lower case characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_20_char_lower_case_', twenty_char_lc, twenty_char_lc, 3600) ##################################################### # Upper Case Character Get bucket Name # ##################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_get_buckets_single_char_upper_case(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using single upper case characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_single_char_upper_case_', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_uc', ten_char_uc) def test_get_buckets_10_char_upper_case(self, ten_char_uc): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 10 random upper case characters can be returned by using get bucket by id endpoint. """ self.run_tests('est_get_buckets_10_char_upper_case_', ten_char_uc, ten_char_uc, 3600) @pytest.mark.parametrize('twenty_char_uc', twenty_char_uc) def test_get_orgs_20_char_upper_case(self, twenty_char_uc): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 20 random upper case characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_orgs_20_char_upper_case_', twenty_char_uc, twenty_char_uc, 3600) ########################################################### # Non-alphanumeric Character Get bucket Name # ########################################################### @pytest.mark.parametrize('one_char', nonalphanumeric) def test_get_buckets_single_char_nonalphanumeric(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using single non-alphanumeric characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_single_char_nonalphanumeric_', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_nonalphanumeric', ten_char_nonalphanumeric) def test_get_buckets_10_char_nonalphanumeric(self, ten_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 10 random non-alphanumeric characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_orgs_10_char_nonalphanumeric_', ten_char_nonalphanumeric, ten_char_nonalphanumeric, 3600) @pytest.mark.parametrize('twenty_char_nonalphanumeric', twenty_char_nonalphanumeric) def test_get_buckets_20_char_nonalphanumeric(self, twenty_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 20 random non-alphanumeric characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_orgs_20_char_nonalphanumeric_', twenty_char_nonalphanumeric, twenty_char_nonalphanumeric, 3600) ################################################### # Number Characters Get bucket Name # ################################################### @pytest.mark.parametrize('one_char', digits) def test_get_buckets_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using single digits can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_single_char_numbers_', one_char, one_char, 3600) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_get_buckets_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 10 random digits can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_10_char_numbers_', ten_char_numbers, ten_char_numbers, 3600) @pytest.mark.parametrize('five_char_numbers', five_char_numbers) def test_get_buckets_5_char_numbers(self, five_char_numbers): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 5 random digits can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_5_char_numbers_', five_char_numbers, five_char_numbers, 3600) ###################################### # Mix Characters Get bucket Name # ###################################### @pytest.mark.parametrize('twenty_char', twenty_char_names_list) def test_get_buckets_20_char_name_mix(self, twenty_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 20 mix characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_20_char_name_mix_', twenty_char, twenty_char, 3600) @pytest.mark.parametrize('forty_char', forty_char_names_list) def test_get_buckets_40_char_name_mix(self, forty_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 40 mix characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_40_char_name_mix_', forty_char, forty_char, 3600) @pytest.mark.parametrize('two_hundred_char_names', two_hundred_char_name_list) def test_get_buckets_200_char_mix(self, two_hundred_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 200 mix characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_200_char_name_mix_', two_hundred_char_names, two_hundred_char_names, 3600) @pytest.mark.parametrize('four_hundred_char_names', four_hundred_char_name_list) def test_get_buckets_400_char_mix(self, four_hundred_char_names): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using 400 mix characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_400_char_name_mix_', four_hundred_char_names, four_hundred_char_names, 3600) @pytest.mark.parametrize('special_char', special_char) def test_get_buckets_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests created bucket using special characters can be returned by using get bucket by id endpoint. """ self.run_tests('test_get_buckets_special_chars_', special_char, special_char, 3600) def test_get_non_existent_bucket_id(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests getting non-existent bucket returns an error. """ test_name = 'test_get_non_existent_bucket_id ' bucket_id = 'doesnotexist' expected_status = 500 expected_error_message = 'id must have a length of 16 bytes' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get non-existent bucket id') get_bucket_result = buckets_util.get_bucket_by_id( self, self.gateway, bucket_id) status = get_bucket_result['status'] error_message = get_bucket_result['error_message'] self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, expected_status)) _assert(self, status, expected_status, 'status code', xfail=True, reason='status code is \'%s\'' % status) self.mylog.info( test_name + 'Assert actual error message \'%s\' equals to expected error message \'%s\'' % (error_message, expected_error_message)) _assert(self, error_message, expected_error_message, '') def test_get_non_existent_bucket_id_16_bytes(self): """ REST API: http://<gateway>/api/v2/buckets METHOD: GET tests getting non-existent bucket returns an error. """ test_name = 'test_get_non_existent_bucket_id ' bucket_id = '9999999999999999' expected_status = 500 expected_error_message = 'bucket not found' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get non-existent bucket id') get_bucket_result = buckets_util.get_bucket_by_id( self, self.gateway, bucket_id) status = get_bucket_result['status'] error_message = get_bucket_result['error_message'] self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, expected_status)) _assert(self, status, expected_status, 'status code', xfail=True, reason='status code is \'%s\'' % status) self.mylog.info( test_name + 'Assert actual error message \'%s\' equals to expected error message \'%s\'' % (error_message, expected_error_message)) _assert(self, error_message, expected_error_message, '')
class TestGetOrganizationsAPI(object): """ Test Suite for testing REST API endpoint for getting single organization Removes created by tests organizations before running tests """ mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = crl.RestLib(mylog) def header(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 17)) self.mylog.info('<--------- %s START --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 17)) def footer(self, test_name): self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('<--------- %s END --------->' % test_name) self.mylog.info('#' * (11 + len(test_name) + 15)) self.mylog.info('') def run_tests(self, name_of_the_test_to_run, org_name): """ :param name_of_the_test_to_run: test name to run :param org_name: name of the organization :return: pass/fail """ test_name = name_of_the_test_to_run + org_name + ' ' self.header(test_name) self.mylog.info(test_name + ' STEP 1: Create Organization "%s"' % org_name) create_result = org_util.create_organization(self, self.gateway, org_name) status = create_result['status'] created_org_id = create_result['org_id'] created_org_name = create_result['org_name'] if org_name == '': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/188') elif org_name == 'BackSlash\\': _assert(self, status, 201, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') else: _assert(self, status, 201, 'status code') self.mylog.info( test_name + ' STEP 2: Check the organization data was persisted in etcd') verify_org_etcd_entries(self, test_name, created_org_id, created_org_name, error='') self.mylog.info(test_name + ' STEP 3: Get Created Organization') get_result = org_util.get_organization_by_id(self, self.gateway, created_org_id) status = get_result['status'] actual_org_id = get_result['requested_org_id'] actual_org_name = get_result['requested_org_name'] self.mylog.info( test_name + 'Assert actual status code \'%s\' equals expected status code 200') _assert(self, status, 200, 'status code') self.mylog.info( test_name + 'Assert actual org_id \'%s\' equals to expected org_id \'%s\'' % (actual_org_id, created_org_id)) _assert(self, actual_org_id, created_org_id, 'org id') self.mylog.info( test_name + 'Assert actual org_name \'%s\' equals expected org_name \'%s\'' % (actual_org_name, created_org_name)) _assert(self, actual_org_name, created_org_name, 'org name') self.footer(test_name) ############################################ # Lower Case Character Org Names # ############################################ @pytest.mark.parametrize('one_char', ascii_lowercase) def test_get_orgs_single_char_lower_case(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created user using single lower case characters can be returned by using "get org by id endpoint". """ self.run_tests('test_get_orgs_single_char_lower_case ', one_char) @pytest.mark.parametrize('ten_char_lc', ten_char_lc) def test_get_orgs_10_char_lower_case(self, ten_char_lc): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 10 random lower case characters can be returned by using "get org by id" endpoint. """ self.run_tests('test_get_orgs_10_char_lower_case ', ten_char_lc) @pytest.mark.parametrize('twenty_char_lc', twenty_char_lc) def test_get_orgs_20_char_lower_case(self, twenty_char_lc): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 20 random lower case characters can be returned by using "get org by id" endpoint. """ self.run_tests('test_get_orgs_20_char_lower_case ', twenty_char_lc) ################################################### # Upper Case Character Org Names # ################################################### @pytest.mark.parametrize('one_char', ascii_uppercase) def test_get_orgs_single_char_upper_case(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using single UPPER case characters can be returned by using "get org by id endpoint". """ self.run_tests('test_get_orgs_single_char_upper_case ', one_char) @pytest.mark.parametrize('ten_char_uc', ten_char_uc) def test_get_orgs_10_char_upper_case(self, ten_char_uc): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 10 random UPPER case characters can be returned by using "get org by id endpoint". """ self.run_tests('test_get_orgs_10_char_upper_case ', ten_char_uc) @pytest.mark.parametrize('twenty_char_uc', twenty_char_uc) def test_get_orgs_20_char_upper_case(self, twenty_char_uc): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 20 random UPPER case characters can be returned by using "get org by id endpoint". """ self.run_tests('test_get_orgs_20_char_upper_case ', twenty_char_uc) ######################################################### # Non-alphanumeric Character Org Names # ######################################################### @pytest.mark.parametrize('one_char', nonalphanumeric) def test_get_orgs_single_char_nonalphanumeric(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using non-alphanumeric characters can be returned by using "get org by id endpoint". """ self.run_tests('test_get_orgs_single_char_nonalphanumeric ', one_char) @pytest.mark.parametrize('ten_char_nonalphanumeric', ten_char_nonalphanumeric) def test_get_orgs_10_char_nonalphanumeric(self, ten_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 10 random non-alphanumeric characters can be returned by using "get org by id endpoint". """ self.run_tests('test_get_orgs_10_char_nonalphanumeric ', ten_char_nonalphanumeric) @pytest.mark.parametrize('twenty_char_nonalphanumeric', twenty_char_nonalphanumeric) def test_get_orgs_20_char_nonalphanumeric(self, twenty_char_nonalphanumeric): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 20 random non-alphanumeric characters can be returned by using "get org by id endpoint". """ self.run_tests('test_get_orgs_20_char_nonalphanumeric', twenty_char_nonalphanumeric) ################################################# # Number Characters Org Names # ################################################# @pytest.mark.parametrize('one_char', digits) def test_get_orgs_single_char_numbers(self, one_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using single digits can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_single_char_numbers', one_char) @pytest.mark.parametrize('ten_char_numbers', ten_char_numbers) def test_get_orgs_10_char_numbers(self, ten_char_numbers): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 10 random digits can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_10_char_numbers ', ten_char_numbers) @pytest.mark.parametrize('five_char_numbers', five_char_numbers) def test_get_orgs_5_char_numbers(self, five_char_numbers): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 5 random digits can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_5_char_numbers ', five_char_numbers) #################################### # Mix Characters Org Names # #################################### @pytest.mark.parametrize('twenty_char', twenty_char_names_list) def test_get_orgs_20_char_name_mix(self, twenty_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 20 mixed characters can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_20_char_name_mix ', twenty_char) @pytest.mark.parametrize('forty_char', forty_char_names_list) def test_get_orgs_40_char_name_mix(self, forty_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 40 mixed characters can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_40_char_name_mix ', forty_char) @pytest.mark.parametrize('two_hundred_char_name', two_hundred_char_name_list) def test_get_orgs_200_char_mix(self, two_hundred_char_name): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 200 mixed characters can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_200_char_mix ', two_hundred_char_name) @pytest.mark.parametrize('four_hundred_char_name', four_hundred_char_name_list) def test_get_orgs_400_char_mix(self, four_hundred_char_name): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using 400 mixed characters can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_400_char_mix ', four_hundred_char_name) @pytest.mark.parametrize('special_char', special_char) def test_get_orgs_special_chars(self, special_char): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests created org using special characters can be returned by using "get org by id endpoint" """ self.run_tests('test_get_orgs_special_chars ', special_char) def test_get_non_existent_org_id(self): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests getting non-existent org returns an error. """ test_name = 'test_get_non_existent_org_id ' org_id = 'doesnotexist' expected_status = 500 expected_error_message = 'id must have a length of 16 bytes' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get non-existent org id') result = org_util.get_organization_by_id(self, self.gateway, org_id) status = result['status'] error_message = result['error_message'] self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, expected_status)) _assert(self, status, expected_status, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') self.mylog.info( test_name + 'Assert actual error message \'%s\' equals to expected error message \'%s\'' % (error_message, expected_error_message)) _assert(self, error_message, expected_error_message, 'error message') def test_get_non_existent_org_id_16_bytes(self): """ REST API: http://<gateway>/api/v2/orgs METHOD: GET tests getting non-existent org returns an error. """ test_name = 'test_get_non_existent_org_id ' org_id = '9999999999999999' expected_status = 500 expected_error_message = 'organization not found' self.header(test_name) self.mylog.info(test_name + 'STEP 1: Get non-existent org id') result = org_util.get_organization_by_id(self, self.gateway, org_id) status = result['status'] error_message = result['error_message'] self.mylog.info( test_name + 'Assert actual status \'%s\' equals to expected status \'%s\'' % (status, expected_status)) _assert(self, status, expected_status, 'status code', xfail=True, reason='https://github.com/influxdata/platform/issues/163') self.mylog.info( test_name + 'Assert actual error message \'%s\' equals to expected error message \'%s\'' % (error_message, expected_error_message)) _assert(self, error_message, expected_error_message, 'error message')
class TestUserPermissions(object): ''' delete_created_sources - delete all of the sources created by the tests, with the exception of ones created by pcl installer create_source - to create a source for admin_user cleanup_users - delete created for the test(s) users setup_users - create test users data_node_ips - to be used in InfluxDBCLient ''' mylog = lu.log(lu.get_log_path(), 'w', __name__) rl = chronograf_rest_lib.RestLib(mylog) users = [ 'user_ViewAdmin', 'user_ViewChronograf', 'user_CreateDatabase', 'user_CreateUserAndRole', 'user_AddRemoveNode', 'user_DropDatabase', 'user_DropData', 'user_ReadData', 'user_WriteData', 'user_Rebalance', 'user_ManageShard', 'user_ManageContinuousQuery', 'user_ManageQuery', 'user_ManageSubscription', 'user_Monitor', 'user_CopyShard', 'user_KapacitorAPI', 'user_KapacitorConfigAPI' ] ################## Helper methods ######################## def source_url(self, permission, Key): source_name = permission source_url = self.create_sources_for_test_users[source_name].get(Key) return (source_name, source_url) ########################################################## def header(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s START --------------->' % test_name) self.mylog.info( '#######################################################') def footer(self, test_name): self.mylog.info( '#######################################################') self.mylog.info('<--------------- %s END --------------->' % test_name) self.mylog.info( '#######################################################') self.mylog.info('') ########################################################## # user with CreateDatabase permission should be able to create database: # https://github.com/influxdata/influxdb/issues/9727 @pytest.mark.parametrize('user', users) def test_user_create_database(self, user): ''' :param user: :return: ''' # create source with a specific user test_name = 'test_user_create_database_' + user self.header(test_name) (name, source_db_url) = self.source_url(user, 'DB') self.mylog.info(test_name + ' name=%s, source_db_url=%s' % (name, source_db_url)) response = self.rl.create_database(self.chronograf, source_db_url, {'name': name}) if user == 'user_CreateDatabase': assert response.status_code == 201, \ pytest.xfail(reason='https://github.com/influxdata/influxdb/issues/9727') #self.mylog.info(test_name + ' Error Message' + response.json().get('message') ) else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer('test_user_create_database') # user with DropDatabase permission should be able to drop database @pytest.mark.parametrize('user', users) def test_user_drop_database(self, user): ''' :param user: :return: ''' test_name = 'test_user_drop_database_' + user self.header(test_name) (name, source_db_url) = self.source_url(user, 'DB') self.mylog.info(test_name + ' name=%s, source_db_url=%s' % (name, source_db_url)) # drop_test_db is not existing database, but deleting non-exisitng database does not return an error # this just tests correct authorization(s) response = self.rl.delete_database(self.chronograf, source_db_url, 'drop_test_db') if user == 'user_DropDatabase': assert response.status_code == 204, \ self.mylog.info(test_name + ' Error message ' + response.json().get('message')) else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer(test_name) # user with CreateDatabase permission should be able to create RP # https://github.com/influxdata/influxdb/issues/9727 @pytest.mark.parametrize('user', users) def test_user_create_rp(self, user): ''' :param user: :return: ''' test_name = 'test_user_create_rp_' + user self.header(test_name) data = { 'name': test_name, 'duration': '3d', 'replication': 2, 'shardDuration': '2h', 'isDefault': False } (name, source_db_url) = self.source_url(user, 'DB') self.mylog.info(test_name + ' name=%s, source_db_url=%s' % (name, source_db_url)) source_rp_url = source_db_url + '/_internal/rps' response = self.rl.create_retention_policy_for_database( self.chronograf, source_rp_url, data) if user == 'user_CreateDatabase': assert response.status_code == 201, \ pytest.xfail(reason='https://github.com/influxdata/influxdb/issues/9727') #self.mylog.info(test_name + ' Error Message' + response.json().get('message') ) else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer(test_name) # user with ReadData and CreateDatabase should be able to view RP # https://github.com/influxdata/influxdb/issues/9727 @pytest.mark.parametrize('user', users) def test_user_show_rp(self, user): ''' :param user: :return: ''' test_name = 'test_user_show_rp_' + user self.header(test_name) (name, source_db_url) = self.source_url(user, 'DB') self.mylog.info(test_name + ' name=%s, source_db_url=%s' % (name, source_db_url)) source_rp_url = source_db_url + '/_internal/rps' response = self.rl.get_retention_policies_for_database( self.chronograf, source_rp_url) if user == 'user_CreateDatabase' or user == 'user_ReadData': assert response.status_code == 200, \ pytest.xfail(reason='https://github.com/influxdata/influxdb/issues/9727') else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer(test_name) # user with CreateDatabase permission should be able to alter RP # https://github.com/influxdata/influxdb/issues/9727 @pytest.mark.parametrize('user', users) def test_user_alter_rp(self, user): ''' :param user: :return: ''' data_node = choice(self.data_nodes_ips) rp_to_create = 'ALTER_RP' duration = '3d' default = False replication = '2' database = '_internal' rp_to_update = 'ALTER_RP' data = { 'name': rp_to_update, 'duration': '4d', 'replication': 2, 'shardDuration': '1h', 'isDefault': False } test_name = 'test_user_alter_rp_' + user self.header(test_name) username, password = '', '' if self.http_auth: username = self.admin_user password = self.admin_pass client = InfluxDBClient(host=data_node, username=username, password=password) success = du.create_retention_policy(self, client, rp_to_create, duration, replication, database, default) assert success, self.mylog.info( test_name + ' Assertion Error, was not able to create RP') (name, source_db_url) = self.source_url(user, 'DB') self.mylog.info(test_name + ' name=%s, source_db_url=%s' % (name, source_db_url)) source_rp_url = source_db_url + '/_internal/rps' response = self.rl.patch_retention_policy_for_database( self.chronograf, source_rp_url, rp_to_update, data) if user == 'user_CreateDatabase': assert response.status_code == 201, \ pytest.xfail(reason='https://github.com/influxdata/influxdb/issues/9727') #self.mylog.info(test_name + ' Error Message' + response.json().get('message') ) else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer(test_name) # user with DropDatabase permission should be able to drop RP @pytest.mark.parametrize('user', users) def test_user_delete_rp(self, user): ''' :param user: :return: ''' test_name = 'test_user_delete_rp_' + user # creating the same RP multiple time won't create multiple RP or ERROR's out rp_to_create = 'DELETE_RP' duration = '3d' default = False replication = '2' database = '_internal' data_node = choice(self.data_nodes_ips) self.header(test_name) # need to create retention policy as admin_user, admin_pass if auth is enabled username, password = '', '' if self.http_auth: username = self.admin_user password = self.admin_pass client = InfluxDBClient(host=data_node, username=username, password=password) success = du.create_retention_policy(self, client, rp_to_create, duration, replication, database, default) assert success, self.mylog.info( test_name + ' Assertion Error, was not able to create RP') (name, source_db_url) = self.source_url(user, 'DB') self.mylog.info(test_name + ' name=%s, source_db_url=%s' % (name, source_db_url)) source_rp_url = source_db_url + '/_internal/rps' response = self.rl.delete_retention_policy_for_database( self.chronograf, source_rp_url, rp_to_create) if user == 'user_DropDatabase': assert response.status_code == 204, \ self.mylog.info(test_name + ' Error message ' + response.json().get('message')) # make sure that retention policy was actually dropped. ret_policies = client.get_list_retention_policies(database) assert rp_to_create not in [item['name'] for item in ret_policies], \ self.mylog.info(test_name + ' Retention Policy was not dropped') else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer(test_name) @pytest.mark.parametrize('user', users) def test_user_createuser(self, user): ''' :param user: :return: ''' test_name = 'test_user_createuser_' + user self.header(test_name) (name, source_users_url) = self.source_url(user, 'USERS') self.mylog.info(test_name + ' name=%s, source_users_url=%s' % (name, source_users_url)) data = {'name': name + '_createuser', 'password': name + '_createuser'} response = self.rl.create_user(self.chronograf, source_users_url, data) if user == 'user_CreateUserAndRole': assert response.status_code == 201, \ self.mylog.info(test_name + ' Error message ' + response.json().get('message')) else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer(test_name) @pytest.mark.parametrize('user', users) def test_user_deleteuser(self, user): ''' :param user: :return: ''' test_name = 'test_user_deleteuser_' + user data_node = choice(self.data_nodes_ips) self.header(test_name) user_name, user_password = user + '_deleteuser', user + '_deleteuser' username, password = '', '' if self.http_auth: username = self.admin_user password = self.admin_pass client = InfluxDBClient(host=data_node, username=username, password=password) (name, source_users_url) = self.source_url(user, 'USERS') (success, message) = uu.create_user(self, client, user_name, user_password, False) assert success, self.mylog.info(test_name + ' : Assertion Error') response = self.rl.delete_user(self.chronograf, source_users_url, user_name) if user == 'user_CreateUserAndRole': assert response.status_code == 204, \ self.mylog.info(test_name + ' Error message ' + response.json().get('message')) # TODO add verification that user indeed was deleted else: self.mylog.info(test_name + ' Error message: ' + response.json().get('message')) assert response.json().get('code') == 400 self.footer(test_name)