def test_running_task(self): payload_key, meta_key = 'payload_key', 'meta_key' redis.set(meta_key, '{}') redis.set(payload_key, '{}') trace = SocketEndpointTrace.create(socket_endpoint=self.socket_endpoint_script) AsyncScriptTask.delay( result_key='cokolwiek', incentive_pk=self.socket_endpoint_script.pk, script_pk=CodeBox.objects.get(path=self.socket_endpoint_script.calls[0]['path']).pk, instance_pk=self.instance.pk, payload_key=payload_key, meta_key=meta_key, trace_pk=trace.pk, ) trace = SocketEndpointTrace.get(trace.pk) self.assertEqual(trace.status, SocketEndpointTrace.STATUS_CHOICES.SUCCESS) self.assertEqual(trace.result['stdout'], self.socket.name) # Check if trace is in eventlog channel room = 'socket:{}'.format(self.socket.name) url = reverse('v2:change-list', args=(self.instance.name, Channel.EVENTLOG_NAME)) response = self.client.get(url, {'room': room}) self.assertEqual(len(response.data['objects']), 1) self.assertEqual(response.data['objects'][0]['metadata'], {'source': 'endpoint', 'endpoint': 'abc1/script/public', 'type': 'trace', 'socket': 'abc1'})
def publish_codebox_spec(cls, instance_pk, incentive_pk, spec): serialized_spec = json.dumps(spec) spec_id = generate_key() spec_key = SPEC_TEMPLATE.format(instance_pk=instance_pk, incentive_pk=incentive_pk, spec_id=spec_id) redis.set(spec_key, serialized_spec, SPEC_TIMEOUT) return spec_key
def setUp(self): super().setUp() set_current_instance(self.instance) self.codebox = G(CodeBox, label="test", runtime_name='python', source="print 'hello world'") self.webhook = G(Webhook, name="test", codebox=self.codebox) self.payload_key = 'payload_key' self.meta_key = 'meta_key' redis.set(self.payload_key, '{}') redis.set(self.meta_key, '{}')
def run(self, instance_pks): for instance_pk in instance_pks: instance = _get_instance(instance_pk) if instance is None: continue if not OwnerInGoodStanding.is_admin_in_good_standing( instance.owner_id): continue set_current_instance(instance) schedules = CodeBoxSchedule.objects.get_for_process() for schedule in schedules: key = PERIODIC_SCHEDULE_TEMPLATE.format( instance_pk=instance.pk, schedule_pk=schedule.pk, scheduled_at=schedule.scheduled_next.isoformat()) can_run = redis.set(name=key, value=1, nx=True, ex=SCHEDULE_TRACE_TIMEOUT) if not can_run: time_in_queue = timezone.now() - schedule.scheduled_next if time_in_queue > timedelta(minutes=2): self.get_logger().warning( "%s in %s cannot be run yet, because it was already scheduled for %s, time in queue: %s.", schedule, instance, schedule.scheduled_next.isoformat(), time_in_queue) else: ScheduleTask.delay(schedule.id, instance_pk) if schedules: admin = Cached(Admin, kwargs={'id': instance.owner_id}).get() admin.update_last_access()
def test_invalidating_endpoint_cache(self): url = reverse('v2:socket-endpoint-invalidate', args=(self.instance.name, self.socket_endpoint_script.name)) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) self.socket.refresh_from_db() cache_key = ENDPOINT_CACHE_KEY_TEMPLATE.format( schema=self.instance.pk, name=self.socket_endpoint_script.name, hash=self.socket.get_hash(), ) redis.set(cache_key, '1') response = self.client.post(url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertFalse(redis.exists(cache_key))
def test_passing_metadata(self): webhook = self.create_webhook(source="import json; print(json.dumps(META))") payload_key, meta_key = 'payload_key', 'meta_key' meta = {'request': {'arg1': 'value'}, 'metadata': {'arg2': 'value2'}} redis.set(meta_key, json.dumps(meta)) redis.set(payload_key, '{}') trace = WebhookTrace.create(webhook=webhook, meta=meta['request']) WebhookTask.delay( result_key='cokolwiek', incentive_pk=webhook.pk, instance_pk=self.instance.pk, payload_key=payload_key, meta_key=meta_key, trace_pk=trace.pk, ) trace = WebhookTrace.get(trace.pk) self.assertEqual(trace.status, WebhookTrace.STATUS_CHOICES.SUCCESS) self.assertDictContainsSubset(meta, json.loads(trace.result['stdout']))
def test_webhook_expire_at(self): source = "print 'World'" webhook = self.create_webhook(source) payload_key, meta_key = 'payload_key', 'meta_key' redis.set(meta_key, '{}') redis.set(payload_key, '{}') trace = WebhookTrace.create(webhook=webhook, meta={}) WebhookTask.delay( result_key='cokolwiek', incentive_pk=webhook.pk, instance_pk=self.instance.pk, payload_key=payload_key, meta_key=meta_key, trace_pk=trace.pk, expire_at=timezone.now().isoformat() ) trace = WebhookTrace.get(trace.pk) self.assertEqual(trace.status, WebhookTrace.STATUS_CHOICES.QUEUE_TIMEOUT) self.assertTrue(trace.result['stderr'])
def process_codebox(self): self.handler = WebhookHandler() redis.set('payload_key', '{}') redis.set('meta_key', '{}') return self.handler.process_task('abc', 2, 'payload_key', 'meta_key', 1, 'webhook')
def run_view(self, request, *args, **kwargs): if 'obj' in kwargs: obj = kwargs.pop('obj') else: obj = self.get_object() instance = request.instance offload_handler_class = kwargs.get('offload_handler_class') uwsgi_handler = kwargs.get('uwsgi_handler') payload_data = None if kwargs.get('skip_payload', False): trace_args = request.query_params.dict() else: flat_args = kwargs.get('flat_args', False) or instance.created_at.year >= 2017 or \ (hasattr(obj, 'created_at') and obj.created_at.year >= 2017) payload_data, trace_args = self.get_payload(request, flat_args=flat_args) request_meta = strip_meta_from_uwsgi_info(request.META) # we use getattr below because webhook can be called # from public view without authentication_classes as_staff = getattr(request, 'staff_user', None) is not None trace = self.create_trace(meta=request_meta, args=trace_args, executed_by_staff=as_staff, obj=obj, **kwargs) meta = {'request': request_meta, 'metadata': kwargs.get('metadata', {})} user = getattr(request, 'auth_user', None) if user: meta['user'] = { 'id': user.id, 'username': user.username, 'user_key': user.key } admin = getattr(request, 'user', None) if admin.is_authenticated: meta['admin'] = { 'id': admin.id, 'email': admin.email, } spec = kwargs.get('spec') if spec is None: # Save payload and meta to redis payload_key = None if payload_data is not None: payload_key = PAYLOAD_TEMPLATE.format(instance_pk=instance.pk, trace_type=self.trace_type, trace_pk=trace.pk) redis.set(payload_key, payload_data, ex=PAYLOAD_TIMEOUT) meta_key = METADATA_TEMPLATE.format(instance_pk=instance.pk, trace_type=self.trace_type, trace_pk=trace.pk) redis.set(meta_key, json.dumps(meta), ex=PAYLOAD_TIMEOUT) return self.create_uwsgi_response(request, obj, instance, trace, payload_key, meta_key, script=kwargs.get('script'), offload_handler_class=offload_handler_class, uwsgi_handler=uwsgi_handler) # TODO: sockets only? meta.update({'executed_by': AsyncScriptTask.trace_type, 'executor': obj.name, 'instance': instance.name}) trace_spec = AsyncScriptTask.create_trace_spec(instance, obj=obj, trace_pk=trace.pk) task_spec = AsyncScriptTask.create_script_spec(instance, kwargs['script'], payload_data, meta, '', trace_spec, obj.socket) spec.update(task_spec) # Save spec to redis payload_key = PAYLOAD_TEMPLATE.format(instance_pk=instance.pk, trace_type=self.trace_type, trace_pk=trace.pk) redis.set(payload_key, json.dumps(spec), ex=PAYLOAD_TIMEOUT) return self.create_uwsgi_response(request, obj, instance, trace, payload_key, offload_handler_class=offload_handler_class, uwsgi_handler=uwsgi_handler)