Esempio n. 1
0
File: test.py Progetto: masaar/limp
	def process_obj(
		cls,
		results: Dict[str, Any],
		obj: Union[Dict[str, Any], List[Any]],
		call_results: 'DictObj' = None,
	) -> Union[Dict[str, Any], List[Any]]:
		logger.debug(f'Attempting to process object: {obj}')
		from utils import extract_attr, generate_attr

		if type(obj) == dict:
			obj_iter = obj.keys()
		elif type(obj) == list:
			obj_iter = range(len(obj))

		for j in obj_iter:
			if type(obj[j]) == ATTR:
				obj[j] = generate_attr(attr_type=obj[j])
			elif type(obj[j]) in [CALC, CAST, JOIN]:
				obj[j] = obj[j].execute(scope=results)
			elif type(obj[j]) == dict:
				obj[j] = cls.process_obj(
					results=results, obj=obj[j], call_results=call_results
				)
			elif type(obj[j]) == list:
				if (
					len(obj[j])
					and type(obj[j][0]) == dict
					and '__attr' in obj[j][0].keys()
				):
					if 'count' not in obj[j][0].keys():
						obj[j][0]['count'] = 1
					obj[j] = [
						generate_attr(attr_type=obj[j][0]['__attr'], **obj[j][0])
						for ii in range(obj[j][0]['count'])
					]
				else:
					obj[j] = cls.process_obj(
						results=results, obj=obj[j], call_results=call_results
					)
			elif type(obj[j]) == str and obj[j].startswith('$__'):
				if obj[j] == '$__session':
					obj[j] = cls.session
				elif obj[j].startswith('$__session.'):
					obj[j] = extract_attr(scope=cls.session, attr_path=obj[j].replace('session.', ''))
				else:
					obj[j] = extract_attr(scope=results, attr_path=obj[j])
			elif callable(obj[j]):
				obj[j] = obj[j](results=results, call_results=call_results)

		logger.debug(f'Processed object: {obj}')
		return obj
Esempio n. 2
0
File: test.py Progetto: masaar/limp
	def execute(self, *, scope: Dict[str, Any]):
		for i in range(len(self._attrs)):
			# [DOC] Attempt to extract attr, execute oper
			if type(self._attrs[i]) == str and self._attrs[i].startswith('$__'):
				self._attrs[i] = extract_attr(scope=scope, attr_path=self._attrs[i])
			elif type(self._attrs[i]) in [CALC, CAST, JOIN]:
				self._attrs[i] = self._attrs[i].execute(scope=scope)
		# [DOC] Join using _separator
		return self._separator.join(self._attrs)
Esempio n. 3
0
File: test.py Progetto: masaar/limp
	def execute(self, *, scope: Dict[str, Any]):
		# [DOC] Attempt to extract attr, execute oper
		if type(self._attr) == str and self._attr.startswith('$__'):
			self._attr = extract_attr(scope=scope, attr_path=self._attr)
		elif type(self._attr) in [CALC, CAST, JOIN]:
			self._attr = self._attr.execute(scope=scope)
		# [DOC] Casr per _type
		if self._type == 'int':
			return int(self._attr)
		elif self._type == 'float':
			return float(self._attr)
		elif self._type == 'str':
			return str(self._attr)
Esempio n. 4
0
File: test.py Progetto: masaar/limp
	def execute(self, *, scope: Dict[str, Any]):
		results = None
		for i in range(len(self._attrs)):
			# [DOC] Attempt to extract attr, execute oper
			if type(self._attrs[i]) == str and self._attrs[i].startswith('$__'):
				self._attrs[i] = extract_attr(scope=scope, attr_path=self._attrs[i])
			elif type(self._attrs[i]) in [CALC, CAST, JOIN]:
				self._attrs[i] = self._attrs[i].execute(scope=scope)
			# [DOC] Calculate results per _oper
			if i == 0:
				results = self._attrs[i]
			else:
				results = getattr((results if results else 0), self._opers[self._oper])(
					self._attrs[i]
				)
		return results
Esempio n. 5
0
File: test.py Progetto: masaar/limp
	async def run_call(
		cls,
		results: Dict[str, Any],
		module: str,
		method: str,
		skip_events: List[Event],
		query: List[Any],
		doc: LIMP_DOC,
		acceptance: Dict[str, Any],
	):
		from config import Config

		call_results = {
			'step': 'call',
			'module': module,
			'method': method,
			'query': query,
			'doc': doc,
			'status': True,
		}
		query = Query(cls.process_obj(results=results, obj=query))
		doc = cls.process_obj(results=results, obj=doc)
		try:
			call_results['results'] = await Config.modules[module].methods[method](
				skip_events=skip_events,
				env={**cls.env, 'session': cls.session},
				query=query,
				doc=doc,
				call_id='__TEST__',
			)
			call_results['acceptance'] = cls.process_obj(
				results=results,
				obj=copy.deepcopy(acceptance),
				call_results=call_results,
			)
			for measure in acceptance.keys():
				if measure.startswith('session.'):
					results_measure = extract_attr(
						scope=cls.session, attr_path=f'$__{measure.replace("session.", "")}'
					)
				else:
					results_measure = extract_attr(
						scope=call_results['results'], attr_path=f'$__{measure}'
					)
				if results_measure != call_results['acceptance'][measure]:
					call_results['status'] = False
					cls.break_debugger(locals(), call_results)
					break
			if call_results['status'] == False:
				logger.debug(
					f'Test step \'call\' failed at measure \'{measure}\'. Required value is \'{call_results["acceptance"][measure]}\', but test results is \'{results_measure}\''
				)
				call_results['measure'] = measure
		except Exception as e:
			tb = traceback.format_exc()
			logger.error(f'Exception occured: {tb}')
			cls.break_debugger(locals(), call_results)
			call_results.update(
				{
					'measure': measure,
					'results': {
						'status': 500,
						'msg': str(e),
						'args': {'tb': tb, 'code': 'SERVER_ERROR'},
					},
				}
			)
			call_results['status'] = False
			call_results['measure'] = measure
		if call_results['status'] == True and 'session' in call_results['results'].args:
			call_results['session'] = call_results['results'].args.session
		return call_results
Esempio n. 6
0
File: test.py Progetto: masaar/limp
	async def run_test(
		cls, test_name: str, steps: List[STEP] = None
	) -> Union[None, Dict[str, Any]]:
		from config import Config
		from utils import DictObj

		if test_name not in Config.tests.keys():
			logger.error('Specified test is not defined in loaded config.')
			logger.debug(f'Loaded tests: {list(Config.tests.keys())}')
			exit()
		test: List[STEP] = Config.tests[test_name]
		results = {
			'test': Config.tests[test_name],
			'status': 'PASSED',
			'success_rate': 100,
			'stats': {'passed': 0, 'failed': 0, 'skipped': 0, 'total': 0},
			'steps': [],
		}

		step_failed = False
		for i in range(len(test)):
			results['stats']['total'] += 1
			step = copy.deepcopy(test[i])

			if steps and i not in steps:
				results['stats']['total'] -= 1
				results['stats']['skipped'] += 1
				continue

			if step_failed and not Config.test_force:
				results['stats']['skipped'] += 1
				continue

			if step._step == 'AUTH':
				try:
					STEP.validate_step(step=step)
					step = STEP.CALL(
						module='session',
						method='auth',
						doc={
							step._args['var']: step._args['val'],
							'hash': step._args['hash'],
						},
					)
				except InvalidTestStepException as e:
					logger.error(
						f'Can\'t process test step \'AUTH\' with error: {e} Exiting.'
					)
					exit()
			elif step._step == 'SIGNOUT':
				step = STEP.CALL(
					module='session', method='signout', query=[{'_id': '$__session'}]
				)
			else:
				try:
					STEP.validate_step(step=step)
				except InvalidTestStepException as e:
					logger.error(f'{e} Exiting.')
					exit()

			if step._step == 'CALL':
				call_results = await cls.run_call(results=results, **step._args)
				if 'session' in call_results.keys():
					logger.debug(
						'Updating session after detecting \'session\' in call results.'
					)
					if str(call_results['session']._id) == 'f00000000000000000000012':
						cls.session = DictObj(
							{
								**Config.compile_anon_session(),
								'user': DictObj(Config.compile_anon_user()),
							}
						)
					else:
						cls.session = call_results['session']
				results['steps'].append(call_results)

			elif step._step == 'TEST':
				test_results = await cls.run_test(
					test_name=step._args['test'], steps=step._args['steps']
				)
				if test_results['status'] == 'PASSED':
					test_results['status'] = True
				else:
					test_results['status'] = False
				results['steps'].append(test_results)

			elif step._step == 'SET_REALM':
				try:
					if step._args['realm'].startswith('$__'):
						step._args['realm'] = extract_attr(
							scope=results, attr_path=step._args['realm']
						)
					logger.debug(f'Updating realm to \'{step._args["realm"]}\'.')
					cls.env['realm'] = step._args['realm']
					results['steps'].append(
						{
							'step': 'set_realm',
							'realm': step._args['realm'],
							'status': True,
						}
					)
				except Exception as e:
					logger.error(e)
					results['steps'].append(
						{
							'step': 'set_realm',
							'realm': step._args['realm'],
							'status': False,
						}
					)

			if not results['steps'][-1]['status']:
				results['stats']['failed'] += 1
				if not Config.test_force:
					step_failed = True
			else:
				results['stats']['passed'] += 1

		if len(results['steps']) == 0:
			logger.error('No steps tested. Exiting.')
			exit()

		results['success_rate'] = int(
			(results['stats']['passed'] / results['stats']['total']) * 100
		)
		if results['success_rate'] == 0:
			results['status'] = 'FAILED'
		elif results['success_rate'] == 100:
			results['status'] = 'PASSED'
		else:
			results['status'] = 'PARTIAL'

		if test_name == Config.test:
			logger.debug(
				'Finished testing %s steps [Passed: %s, Failed: %s, Skipped: %s] with success rate of: %s%%',
				results['stats']['total'],
				results['stats']['passed'],
				results['stats']['failed'],
				results['stats']['skipped'],
				results['success_rate'],
			)
			tests_log = os.path.join(
				Config._limp_location,
				'tests',
				f'LIMP-TEST_{test_name}_{datetime.datetime.utcnow().strftime("%d-%b-%Y")}',
			)
			if os.path.exists(f'{tests_log}.json'):
				i = 1
				while True:
					if os.path.exists(f'{tests_log}.{i}.json'):
						i += 1
					else:
						tests_log = f'{tests_log}.{i}'
						break
			tests_log += '.json'
			with open(tests_log, 'w') as f:
				f.write(json.dumps(json.loads(JSONEncoder().encode(results)), indent=4))
				logger.debug(f'Full tests log available at: {tests_log}')
		else:
			return results
Esempio n. 7
0
File: data.py Progetto: masaar/limp
 async def _extend_doc(
     cls,
     *,
     env: Dict[str, Any],
     doc: LIMP_DOC,
     attr: Union[None, LIMP_DOC],
     extn_id: ObjectId,
     extn: EXTN,
     extn_models: Dict[str, BaseModel] = {},
 ) -> BaseModel:
     # [DOC] Check if extn module is dynamic value
     if extn.module.startswith('$__'):
         extn_module = Config.modules[extract_attr(scope={
             'doc': doc,
             'attr': attr
         },
                                                   attr_path=extn.module)]
     else:
         extn_module = Config.modules[extn.module]
     # [DOC] Check if extn attr set to fetch all or specific attrs
     if type(extn.attrs) == str and extn.attrs.startswith('$__'):
         extn_attrs = extract_attr(scope={
             'doc': doc,
             'attr': attr
         },
                                   attr_path=extn.attrs)
         if extn_attrs[0] == '*':
             extn_attrs = {
                 attr: extn_module.attrs[attr]
                 for attr in extn_module.attrs.keys()
             }
     elif extn.attrs[0] == '*':
         extn_attrs = {
             attr: extn_module.attrs[attr]
             for attr in extn_module.attrs.keys()
         }
     else:
         extn_attrs = {attr: extn_module.attrs[attr] for attr in extn.attrs}
     # [DOC] Implicitly add _id key to extn attrs so that we don't delete it in process
     extn_attrs['_id'] = 'id'
     # [DOC] Set skip events
     skip_events = [Event.PERM]
     # [DOC] Check if extn instruction is explicitly requires second-dimension extn.
     if extn.force == False:
         skip_events.append(Event.EXTN)
     elif type(extn.force) == str and extn.force.startswith('$__'):
         if not extract_attr(scope={
                 'doc': doc,
                 'attr': attr
         },
                             attr_path=extn.attrs):
             skip_events.append(Event.EXTN)
     # [DOC] Read doc if not in extn_models
     if str(extn_id) not in extn_models.keys():
         extn_results = await extn_module.methods['read'](
             skip_events=skip_events, env=env, query=[{
                 '_id': extn_id
             }])
         if extn_results['args']['count']:
             extn_models[str(extn_id)] = extn_results['args']['docs'][0]
         else:
             extn_models[str(extn_id)] = None
     # [DOC] Set attr to extn_models doc
     extn_doc = copy.deepcopy(extn_models[str(extn_id)])
     # [DOC] delete all unneeded keys from the resulted doc
     if extn_doc:
         extn_doc = BaseModel({
             attr: extn_doc[attr]
             for attr in extn_attrs.keys() if attr in extn_doc
         })
     return extn_doc
Esempio n. 8
0
    def _parse_permission_args(
        self,
        skip_events: List[str],
        env: Dict[str, Any],
        query: Union[LIMP_QUERY, Query],
        doc: LIMP_DOC,
        permission_args: Any,
    ):
        user = env['session'].user

        if type(permission_args) == list:
            args_iter = range(len(permission_args))
        elif type(permission_args) == dict:
            args_iter = list(permission_args.keys())

        for j in args_iter:
            if type(permission_args[j]) == ATTR_MOD:
                # [DOC] If attr is of type ATTR_MOD, call condition callable
                if permission_args[j].condition(skip_events=skip_events,
                                                env=env,
                                                query=query,
                                                doc=doc):
                    # [DOC] If condition return is True, update attr value
                    if callable(permission_args[j].default):
                        permission_args[j] = permission_args[j].default(
                            skip_events=skip_events,
                            env=env,
                            query=query,
                            doc=doc)
                        if type(permission_args[j]) == Exception:
                            raise permission_args[j]
                    else:
                        permission_args[j] = permission_args[j].default
            elif type(permission_args[j]) == dict:
                # [DOC] Check opers
                for oper in [
                        '$gt',
                        '$lt',
                        '$gte',
                        '$lte',
                        '$bet',
                        '$ne',
                        '$regex',
                        '$all',
                        '$in',
                ]:
                    if oper in permission_args[j].keys():
                        if oper == '$bet':
                            permission_args[j][
                                '$bet'] = self._parse_permission_args(
                                    skip_events=skip_events,
                                    env=env,
                                    query=query,
                                    doc=doc,
                                    permission_args=permission_args[j]['$bet'],
                                )
                        else:
                            permission_args[j][
                                oper] = self._parse_permission_args(
                                    skip_events=skip_events,
                                    env=env,
                                    query=query,
                                    doc=doc,
                                    permission_args=[permission_args[j][oper]],
                                )[0]
                        # [DOC] Continue the iteration
                        continue
                # [DOC] Child args, parse
                permission_args[j] = self._parse_permission_args(
                    skip_events=skip_events,
                    env=env,
                    query=query,
                    doc=doc,
                    permission_args=permission_args[j],
                )
            elif type(permission_args[j]) == list:
                permission_args[j] = self._parse_permission_args(
                    skip_events=skip_events,
                    env=env,
                    query=query,
                    doc=doc,
                    permission_args=permission_args[j],
                )
            elif type(permission_args[j]) == str:
                # [DOC] Check for variables
                if permission_args[j] == '$__user':
                    permission_args[j] = user._id
                elif permission_args[j].startswith('$__user.'):
                    permission_args[j] = extract_attr(
                        scope=user,
                        attr_path=permission_args[j].replace(
                            '$__user.', '$__'),
                    )
                elif permission_args[j] == '$__access':
                    permission_args[j] = {
                        '$__user': user._id,
                        '$__groups': user.groups
                    }
                elif permission_args[j] == '$__datetime':
                    permission_args[j] = datetime.datetime.utcnow().isoformat()
                elif permission_args[j] == '$__date':
                    permission_args[j] = datetime.date.today().isoformat()
                elif permission_args[j] == '$__time':
                    permission_args[j] = datetime.datetime.now().time(
                    ).isoformat()

        return permission_args