Пример #1
0
 def test_new_build_id_generates_monotonicaly_decreasing_ids(self):
   now = datetime.datetime(2015, 2, 24)
   self.mock(utils, 'utcnow', lambda: now)
   last_id = None
   for i in xrange(1000):
     now += datetime.timedelta(seconds=i)
     new_id = model.new_build_id()
     if last_id is not None:
       self.assertLess(new_id, last_id)
     last_id = new_id
Пример #2
0
 def test_new_build_id_generates_monotonicaly_decreasing_ids(self):
     now = datetime.datetime(2015, 2, 24)
     self.mock(utils, 'utcnow', lambda: now)
     last_id = None
     for i in xrange(1000):
         now += datetime.timedelta(seconds=i)
         new_id = model.new_build_id()
         if last_id is not None:
             self.assertLess(new_id, last_id)
         last_id = new_id
Пример #3
0
 def test_peek_multi(self):
   self.test_build.key = ndb.Key(model.Build, model.new_build_id())
   self.test_build.put()
   # We test that peek returns builds in decreasing order of the build key. The
   # build key is derived from the inverted current time, so later builds get
   # smaller ids. Only exception: if the time is the same, randomness decides
   # the order. So artificially create an id here to avoid flakiness.
   build2 = model.Build(id=self.test_build.key.id() - 1, bucket='bucket2')
   build2.put()
   builds, _ = service.peek(buckets=[self.test_build.bucket, 'bucket2'])
   self.assertEqual(builds, [self.test_build, build2])
Пример #4
0
def add_async(
    bucket, tags=None, parameters=None, lease_expiration_date=None,
    client_operation_id=None, pubsub_callback=None):
  """Adds the build entity to the build bucket.

  Requires the current user to have permissions to add builds to the
  |bucket|.

  Args:
    bucket (str): destination bucket. Required.
    tags (model.Tags): build tags.
    parameters (dict): arbitrary build parameters. Cannot be changed after
      build creation.
    lease_expiration_date (datetime.datetime): if not None, the build is
      created as leased and its lease_key is not None.
    pubsub_callback (model.PubsubCallback): callback parameters.
    client_operation_id (str): client-supplied operation id. If an
      a build with the same client operation id was added during last minute,
      it will be returned instead.

  Returns:
    A new Build.
  """
  if client_operation_id is not None:
    if not isinstance(client_operation_id, basestring):  # pragma: no cover
      raise errors.InvalidInputError('client_operation_id must be string')
    if '/' in client_operation_id:  # pragma: no cover
      raise errors.InvalidInputError('client_operation_id must not contain /')
  validate_bucket_name(bucket)
  if parameters is not None and not isinstance(parameters, dict):
    raise errors.InvalidInputError('parameters must be a dict or None')
  validate_lease_expiration_date(lease_expiration_date)
  validate_tags(tags)
  tags = tags or []

  ctx = ndb.get_context()
  identity = auth.get_current_identity()
  if not (yield acl.can_add_build_async(bucket)):  # pragma: no branch
    raise current_identity_cannot('add builds to bucket %s', bucket)

  if client_operation_id is not None:
    client_operation_cache_key = (
      'client_op/%s/%s/add_build' % (
        identity.to_bytes(), client_operation_id))
    build_id = yield ctx.memcache_get(client_operation_cache_key)
    if build_id:
      build = yield model.Build.get_by_id_async(build_id)
      if build:  # pragma: no branch
        raise ndb.Return(build)

  build = model.Build(
    id=model.new_build_id(),
    bucket=bucket,
    tags=tags,
    parameters=parameters,
    status=model.BuildStatus.SCHEDULED,
    created_by=identity,
    never_leased=lease_expiration_date is None,
    pubsub_callback=pubsub_callback,
  )
  if lease_expiration_date is not None:
    build.lease_expiration_date = lease_expiration_date
    build.leasee = auth.get_current_identity()
    build.regenerate_lease_key()

  for_swarming = yield swarming.is_for_swarming_async(build)
  if for_swarming:  # pragma: no cover
    yield swarming.create_task_async(build)

  try:
    yield build.put_async()
  except:  # pragma: no cover
    # Best effort.
    if for_swarming:
      yield swarming.cancel_task_async(build)
    raise
  logging.info(
    'Build %s was created by %s', build.key.id(), identity.to_bytes())
  metrics.increment(metrics.CREATE_COUNT, build)

  if client_operation_id is not None:
    yield ctx.memcache_set(client_operation_cache_key, build.key.id(), 60)
  raise ndb.Return(build)
Пример #5
0
    def add_async(self,
                  bucket,
                  tags=None,
                  parameters=None,
                  lease_expiration_date=None,
                  client_operation_id=None):
        """Adds the build entity to the build bucket.

    Requires the current user to have permissions to add builds to the
    |bucket|.

    Args:
      bucket (str): destination bucket. Required.
      tags (model.Tags): build tags.
      parameters (dict): arbitrary build parameters. Cannot be changed after
        build creation.
      lease_expiration_date (datetime.datetime): if not None, the build is
        created as leased and its lease_key is not None.
      client_operation_id (str): client-supplied operation id. If an
        a build with the same client operation id was added during last minute,
        it will be returned instead.

    Returns:
      A new Build.
    """
        if client_operation_id is not None:
            if not isinstance(client_operation_id,
                              basestring):  # pragma: no cover
                raise errors.InvalidInputError(
                    'client_operation_id must be string')
            if '/' in client_operation_id:  # pragma: no cover
                raise errors.InvalidInputError(
                    'client_operation_id must not contain /')
        validate_bucket_name(bucket)
        if parameters is not None and not isinstance(parameters, dict):
            raise errors.InvalidInputError('parameters must be a dict or None')
        validate_lease_expiration_date(lease_expiration_date)
        validate_tags(tags)
        tags = tags or []

        ctx = ndb.get_context()
        identity = auth.get_current_identity()
        if not (yield acl.can_add_build_async(bucket)):  # pragma: no branch
            raise current_identity_cannot('add builds to bucket %s', bucket)

        if client_operation_id is not None:
            client_operation_cache_key = (
                'client_op/%s/%s/add_build' %
                (identity.to_bytes(), client_operation_id))
            build_id = yield ctx.memcache_get(client_operation_cache_key)
            if build_id:
                build = yield model.Build.get_by_id_async(build_id)
                if build:  # pragma: no branch
                    raise ndb.Return(build)

        build = model.Build(
            id=model.new_build_id(),
            bucket=bucket,
            tags=tags,
            parameters=parameters,
            status=model.BuildStatus.SCHEDULED,
            created_by=identity,
        )
        if lease_expiration_date is not None:
            build.lease_expiration_date = lease_expiration_date
            build.leasee = auth.get_current_identity()
            build.regenerate_lease_key()
        yield build.put_async()
        logging.info('Build %s was created by %s', build.key.id(),
                     identity.to_bytes())

        if client_operation_id is not None:
            yield ctx.memcache_set(client_operation_cache_key, build.key.id(),
                                   60)
        raise ndb.Return(build)