text:
import {expect} from 'chai'
import Ember from 'ember'
const {Logger} = Ember
import {afterEach, beforeEach, describe, it} from 'mocha'
import sinon from 'sinon'

import {unit} from 'dummy/tests/helpers/ember-test-utils/setup-component-test'
import Component from 'ember-frost-core/components/frost-component'

const test = unit('frost-button')
describe(test.label, function () {
  test.setup()

  let component, sandbox

  beforeEach(function () {
    sandbox = sinon.sandbox.create()
    component = this.subject({
      hook: 'myButton'
    })
  })

  afterEach(function () {
    sandbox.restore()
  })

  it('should default tagName to button', function () {
    expect(component.get('tagName')).to.equal('button')
  })

  it('should default autofocus to false', function () {
    expect(component.get('autofocus')).to.equal(false)
  })

  it('should default design to empty string', function () {
    expect(component.get('design')).to.equal('')
  })

  it('should default disabled to false', function () {
    expect(component.get('disabled')).to.equal(false)
  })

  it('should default icon to empty string', function () {
    expect(component.get('icon')).to.equal('')
  })

  it('should default pack to frost', function () {
    expect(component.get('pack')).to.equal('frost')
  })

  it('should default priority to empty string', function () {
    expect(component.get('priority')).to.equal('')
  })

  it('should default size to empty string', function () {
    expect(component.get('size')).to.equal('')
  })

  it('should default text to empty string', function () {
    expect(component.get('text')).to.equal('')
  })

  it('should default title to empty string', function () {
    expect(component.get('text')).to.equal('')
  })

  it('should default type to button', function () {
    expect(component.get('type')).to.equal('button')
  })

  it('should default vertical to false', function () {
    expect(component.get('vertical')).to.equal(false)
  })

  it('should extend the common frost component', function () {
    expect(component instanceof Component).to.equal(true)
  })

  describe('"isTextOnly" computed property', function () {
    describe('when text alone is set', function () {
      beforeEach(function () {
        component.set('text', 'some text')
      })

      it('should be true', function () {
        expect(component.get('isTextOnly')).to.equal(true)
      })
    })

    describe('when text and icon are set', function () {
      beforeEach(function () {
        component.setProperties({
          icon: 'round-add',
          text: 'some text'
        })
      })

      it('should be false', function () {
        expect(component.get('isTextOnly')).to.equal(false)
      })
    })
  })

  describe('"isIconOnly" computed property', function () {
    describe('when icon alone is set', function () {
      beforeEach(function () {
        component.set('icon', 'round-add')
      })

      it('should be true', function () {
        expect(component.get('isIconOnly')).to.equal(true)
      })
    })

    describe('when icon and text are set', function () {
      beforeEach(function () {
        component.setProperties({
          icon: 'round-add',
          text: 'some text'
        })
      })

      it('should be false', function () {
        expect(component.get('isIconOnly')).to.equal(false)
      })
    })
  })

  describe('"isIconAndText" computed property', function () {
    describe('when icon alone is set', function () {
      beforeEach(function () {
        component.set('icon', 'round-add')
      })

      it('should be false', function () {
        expect(component.get('isIconAndText')).to.equal(false)
      })
    })

    describe('when text alone is set', function () {
      beforeEach(function () {
        component.set('text', 'some text')
      })

      it('should be false', function () {
        expect(component.get('isIconAndText')).to.equal(false)
      })
    })

    describe('when icon and text are set', function () {
      beforeEach(function () {
        component.setProperties({
          icon: 'round-add',
          text: 'some text'
        })
      })

      it('should be true', function () {
        expect(component.get('isIconAndText')).to.equal(true)
      })
    })
  })

  describe('"extraClasses" computed property', function () {
    const validDesignClasses = [
      {in: 'app-bar', out: 'app-bar'},
      {in: 'info-bar', out: 'info-bar'},
      {in: 'tab', out: 'tab'}
    ]

    validDesignClasses.forEach((test) => {
      describe(`When design is set to "${test.in}"`, function () {
        beforeEach(function () {
          component.setProperties({
            design: test.in,
            text: 'some text'
          })
        })

        it(`should include "${test.out}"`, function () {
          expect(component.get('extraClasses')).to.include(test.out)
        })
      })
    })

    const validSizes = [
      {in: 'large', out: 'large'},
      {in: 'medium', out: 'medium'},
      {in: 'small', out: 'small'}
    ]

    validSizes.forEach((test) => {
      describe(`When size is set to "${test.in}"`, function () {
        beforeEach(function () {
          component.set('size', test.in)
        })

        it(`should include "${test.out}"`, function () {
          expect(component.get('extraClasses')).to.include(test.out)
        })
      })
    })

    const validPriorities = [
      {in: 'primary', out: 'primary'},
      {in: 'confirm', out: 'primary'},
      {in: 'secondary', out: 'secondary'},
      {in: 'normal', out: 'secondary'},
      {in: 'tertiary', out: 'tertiary'},
      {in: 'cancel', out: 'tertiary'}
    ]

    validPriorities.forEach((test) => {
      describe(`When priority is set to "${test.in}"`, function () {
        beforeEach(function () {
          component.set('priority', test.in)
        })

        it(`should include "${test.out}"`, function () {
          expect(component.get('extraClasses')).to.include(test.out)
        })
      })
    })

    describe('when "design" property is set', function () {
      beforeEach(function () {
        sandbox.spy(Logger, 'error')
        sandbox.spy(Logger, 'warn')

        component.set('design', 'app-bar')
      })

      describe('but neither "text" nor "icon" are set', function () {
        let extraClasses
        beforeEach(function () {
          component.setProperties({
            icon: '',
            text: ''
          })

          extraClasses = component.get('extraClasses')
        })

        it('should return with no class', function () {
          expect(extraClasses).to.equal(undefined)
        })

        it('should log an error', function () {
          const msg = 'Error: The `design` property requires `text` or `icon` property to be specified.'
          expect(Logger.error).to.have.been.calledWith(msg)
        })
      })

      describe('when "priority" is also set', function () {
        let extraClasses
        beforeEach(function () {
          component.setProperties({
            priority: 'primary',
            text: 'some text'
          })

          extraClasses = component.get('extraClasses')
        })

        it('should log a warning', function () {
          const msg = 'Warning: The `design` property takes precedence over `size` and `priority`.'
          expect(Logger.warn).to.have.been.calledWith(msg)
        })

        it('should still include the design class', function () {
          expect(extraClasses).to.include('app-bar')
        })
      })

      describe('when "size" is also set', function () {
        let extraClasses
        beforeEach(function () {
          component.setProperties({
            size: 'small',
            text: 'some text'
          })

          extraClasses = component.get('extraClasses')
        })

        it('should log a warning', function () {
          const msg = 'Warning: The `design` property takes precedence over `size` and `priority`.'
          expect(Logger.warn).to.have.been.calledWith(msg)
        })

        it('should still include the design class', function () {
          expect(extraClasses).to.include('app-bar')
        })
      })

      describe('when "size" and "priority" are both also set', function () {
        let extraClasses
        beforeEach(function () {
          component.setProperties({
            priority: 'primary',
            size: 'small',
            text: 'some text'
          })

          extraClasses = component.get('extraClasses')
        })

        it('should log a warning', function () {
          const msg = 'Warning: The `design` property takes precedence over `size` and `priority`.'
          expect(Logger.warn).to.have.been.calledWith(msg)
        })

        it('should still include the design class', function () {
          expect(extraClasses).to.include('app-bar')
        })
      })
    })

    describe('When "vertical" is true', function () {
      beforeEach(function () {
        component.set('vertical', true)
      })

      it('should include "vertical" class', function () {
        expect(component.get('extraClasses')).to.include('vertical')
      })
    })

    describe('When "vertical" is false', function () {
      beforeEach(function () {
        component.set('vertical', false)
      })

      it('should not include "vertical" class', function () {
        expect(component.get('extraClasses')).not.to.include('vertical')
      })
    })

    describe('when "size", "priority", and "vertical" are all set', function () {
      let extraClasses, priority, size
      beforeEach(function () {
        priority = 'primary'
        size = 'medium'
        component.setProperties({
          priority,
          size,
          vertical: true
        })

        extraClasses = component.get('extraClasses')
      })

      it('should include the "priority" class', function () {
        expect(extraClasses).to.include(priority)
      })

      it('should include the "size" class', function () {
        expect(extraClasses).to.include(size)
      })

      it('should include the "vertical" class', function () {
        expect(extraClasses).to.include('vertical')
      })
    })
  })
})


text:
@implementation Play
@synthesize isFav;
@synthesize playId;

@synthesize playTitle;
@synthesize imageURL;

@synthesize authorName;
@synthesize captionName;

@synthesize authorInfo;

- (void)dealloc {
    self.playTitle = nil;
    self.authorName = nil;
    self.captionName = nil;
    self.imageURL = nil;
    self.authorInfo  = nil;
}
@end

redpajama_set_name: RedPajamaGithub


text:
using google::devtools::cloudtrace::v1::TraceSpan;

namespace google {
namespace api_manager {
namespace cloud_trace {
namespace {

class SamplerTest : public ::testing::Test {};

TEST_F(SamplerTest, TestDefaultSetting) {
  Sampler sampler(0.1);

  ASSERT_TRUE(sampler.On());
  ASSERT_FALSE(sampler.On());
}

TEST_F(SamplerTest, TestLargeQps) {
  Sampler sampler(1.0);

  ASSERT_TRUE(sampler.On());
  std::this_thread::sleep_for(std::chrono::milliseconds(300));
  ASSERT_FALSE(sampler.On());
  std::this_thread::sleep_for(std::chrono::milliseconds(800));
  ASSERT_TRUE(sampler.On());
  std::this_thread::sleep_for(std::chrono::milliseconds(200));
  ASSERT_FALSE(sampler.On());
}

TEST_F(SamplerTest, TestRefresh) {
  Sampler sampler(1.0);
  ASSERT_TRUE(sampler.On());
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  ASSERT_FALSE(sampler.On());
  sampler.Refresh();
  std::this_thread::sleep_for(std::chrono::milliseconds(600));
  ASSERT_FALSE(sampler.On());
}

TEST_F(SamplerTest, TestDisabled) {
  Sampler sampler(0.0);
  ASSERT_FALSE(sampler.On());
}

}  // namespace

}  // cloud_trace
}  // namespace api_manager
}  // namespace google


text:
script_name = ('Create and Populate New "Bike Facility" Attribute')
script_version = '1.0'

__version__ = script_version
__author__ = 'Cyclopath <info@cyclopath.org>'
__date__ = '2013-05-11'

# ***

# SYNC_ME: Search: Scripts: Load pyserver.
import os
import sys
sys.path.insert(0, os.path.abspath('%s/../util'
                % (os.path.abspath(os.curdir),)))
import pyserver_glue
import time

import conf
import g

import logging
from util_ import logging2
from util_.console import Console
log_level = logging.DEBUG
#log_level = logging2.VERBOSE2
#log_level = logging2.VERBOSE4
#log_level = logging2.VERBOSE
conf.init_logging(True, True, Console.getTerminalSize()[0]-1, log_level)

log = g.log.getLogger('facils_popl')

# ***

import copy
import psycopg2
import time
import traceback

from grax.access_level import Access_Level
from grax.access_scope import Access_Scope
from grax.access_style import Access_Style
from grax.grac_manager import Grac_Manager
from grax.item_manager import Item_Manager
from grax.user import User
from gwis.query_overlord import Query_Overlord
from item import item_base
from item import item_user_access
from item import item_versioned
from item import link_value
from item.attc import attribute
from item.feat import branch
from item.feat import byway
from item.grac import group
from item.link import link_attribute
from item.util import revision
from item.util.item_query_builder import Item_Query_Builder
from item.util.item_type import Item_Type
from item.util.watcher_frequency import Watcher_Frequency
from util_ import db_glue
from util_ import geometry
from util_ import gml
from util_ import misc
from util_.log_progger import Debug_Progress_Logger
from util_.script_args import Ccp_Script_Args
from util_.script_base import Ccp_Script_Base

# *** Debug switches

debug_prog_log = Debug_Progress_Logger()
debug_prog_log.debug_break_loops = False
#debug_prog_log.debug_break_loops = True
#debug_prog_log.debug_break_loop_cnt = 3
##debug_prog_log.debug_break_loop_cnt = 10

debug_skip_commit = False
#debug_skip_commit = True

# This is shorthand for if one of the above is set.
debugging_enabled = (   False
                     or debug_prog_log.debug_break_loops
                     or debug_skip_commit
                     )

if debugging_enabled:
   log.warning('****************************************')
   log.warning('*                                      *')
   log.warning('*      WARNING: debugging_enabled      *')
   log.warning('*                                      *')
   log.warning('****************************************')

# ***

# 2013.05.11: [lb] doesn't quite remember when he sussed these tags out, so
# there might be some new ones we miss here... but probably not that many of
# them, it's not like people spend a lot of time tagging.

class Tag_Presumption(object):

   # 2013.05.12: On Mpls-St. Paul, applied to 2024 / 156378 line segments.
   tag_prohibited = (
      'prohibited',
      'closed',
      'biking prohibited',
      'closed - permanently',
      )

   # 2013.05.12: tag_bike_path + tag_bike_lane + tag_bike_shoulder:
#              On Mpls-St. Paul, applied to ??? / 156378 line segments.

   # 2013.05.12: trail: applied to 14764 / 156378 line segments.
   tag_bike_path = (
      'bikepath',
      'bike path',
      'combined path',
      #? 'path',
      #? 'paved path',
      #? 'wide sidewalk, bike path',
      )

   # 2013.05.12: blane: applied to 2116 / 156378 line segments.
   tag_bike_lane = (
      'bike lane',
      'bikelane',
      'bike lane one side',
      'bike lane on left',
      'bike lanes',
      )

# FIXME:
# 2013.05.13: shldr: applied to ??? / 156378 line segments.
   # FIXME: Sync with shoulder_dis
   tag_bike_shoulder = (
      'bike shoulder',
      'busy, good shoulder',
      'good shoulder',
      'great! recently repaved, wide shoulders',
      'nice shoulder',
      'shoulder',
      'shoulder lane',
      'striped shoulder',
      'striped shoulder on bridge',
      'wide shoulder',
      'wide shoulder path',
      'wide shoulder, safe',
      )

# FIXME: Wire this? ...
#        Make a boolean for unpaved??
#        And another boolean attribute for caution?
#        What about a temporal attribute for "xx (level?) of service"?
   tag_unpaved = (
      'dirt path',
      'Dirt path',
      'unpaved',
      )

   tag_bike_boulevard = (
      'bike boulevard',
      'bike boulevard marked with signage',
      # FIXME: Is bike route same as bike boulevard?:
      'bike route',
      ),

# *** Cli arg. parser

class ArgParser_Script(Ccp_Script_Args):

   #
   def __init__(self):
      Ccp_Script_Args.__init__(self, script_name, script_version)

   #
   def prepare(self):
      Ccp_Script_Args.prepare(self)

   #
   def verify_handler(self):
      ok = Ccp_Script_Args.verify_handler(self)
      return ok

# *** Bike_Facilities_Populate

class Bike_Facilities_Populate(Ccp_Script_Base):

   # *** Constructor

   def __init__(self):
      Ccp_Script_Base.__init__(self, ArgParser_Script)
      #
      self.attr_cycle_facil = None
      # Piggy-back! So we don't need another script, attaching,
      # for controlled-access roadways (well, highways and freeways):
      self.attr_no_access = None
      # 2013.06.14: [lb] made the cautionary facils their own attribute. But we
      # don't need those for this script, since CcpV1 has no cautionaries.
      #  Nope: self.attr_cautionary = None
      #
      self.stats = dict()
      self.stats['cnt_attrs_all'] = 0
      self.stats['cnt_attrs_cyle_facil'] = 0
      self.stats['cnt_attrs_no_access'] = 0
      self.stats['cnt_facils_kvals'] = {}

   # ***

   #
   def go_main(self):

      # Skipping: Ccp_Script_Base.go_main(self)

      do_commit = False

      try:

         log.debug('go_main: getting exclusive revision lock...')
         revision.Revision.revision_lock_dance(
            self.qb.db, caller='bike_facility_populate__go_main')
         log.debug('go_main: database is locked.')

         # MAYBE: There seems to be an awful lot of boilerplate code here.
         self.qb.grac_mgr = Grac_Manager()
         self.qb.grac_mgr.prepare_mgr('user', self.qb)
         # A developer is running this script.
         g.assurt(self.qb.username
                  and (self.qb.username != conf.anonymous_username))
         self.qb.user_group_id = User.private_group_id(self.qb.db,
                                                       self.qb.username)

         # Get a new revision ID.
         self.qb.item_mgr.start_new_revision(self.qb.db)
         log.debug('Got rid_new: %d' % (self.qb.item_mgr.rid_new,))

         # Get the Bike Facility attribute.
         internal_name = '/byway/cycle_facil'
         self.attr_cycle_facil = attribute.Many.get_system_attr(
                                          self.qb, internal_name)
         g.assurt(self.attr_cycle_facil is not None)

         # Get the Controlled Access attribute.
         internal_name = '/byway/no_access'
         self.attr_no_access = attribute.Many.get_system_attr(
                                          self.qb, internal_name)
         g.assurt(self.attr_no_access is not None)

         # BUG nnnn: New Script: Populate '/byway/cycle_route' by...
         #                       stack IDs? byway names? maybe easier
         #                       just to do in flashclient....

         self.byways_suss_out_facilities()

         # Save the new revision and finalize the sequence numbers.
         log.debug('go_main: saving rev # %d' % (self.qb.item_mgr.rid_new,))

         # NOTE: We're cheating here: We know only the public group needs
         #       group_revision records, since all new items were only public.
         # Either of these should be acceptable:
         # group_names_or_ids = ['Public',]
         group_names_or_ids = [group.Many.public_group_id(self.qb),]
         # MAYBE: Give credit to user who runs this script, or _script?
         #        I.e., where is the accountability if user like/dislike
         #        application (calculation) of this new attribute?
         #
         #complain_to_this_user = 'landonb'
         #complain_to_this_user = self.qb.username
         complain_to_this_user = '_script'
         #
         changenote = ('Populated new bike facility attr. using existing '
                       + 'tags and attrs. (i.e., guessing!).')
         #
         self.finish_script_save_revision(group_names_or_ids,
                                          username=complain_to_this_user,
                                          changenote=changenote)

         self.print_stats()

         if debug_skip_commit:
            raise Exception('DEBUG: Skipping commit: Debugging')
         do_commit = True

      except Exception, e:

         log.error('Exception!: "%s" / %s' % (str(e), traceback.format_exc(),))

      finally:

         self.cli_args.close_query(do_commit)

   # ***

   #
   def byways_suss_out_facilities(self):

      log.info('byways_suss_out_facilities: ready, set, suss!')

      time_0 = time.time()

      prog_log = Debug_Progress_Logger(copy_this=debug_prog_log)
      # 2013.05.12: Weird. At first, you'll see 1250 byways being processed
      # each second, but later in the processing, after 100,000 byways, you'll
      # see 250 byways being processed every one or two seconds.
      #prog_log.log_freq = 250
      #prog_log.log_freq = 2500
      prog_log.log_freq = 1000
      prog_log.loop_max = None

      feat_class = byway
      feat_search_fcn = 'search_for_items' # E.g. byway.Many().search_for_items
      processing_fcn = self.feat_suss_out_facil
      self.qb.item_mgr.load_feats_and_attcs(
            self.qb, feat_class, feat_search_fcn,
            processing_fcn, prog_log, heavyweight=False)

      log.info('... processed %d features in %s'
               % (prog_log.progress,
                  misc.time_format_elapsed(time_0),))

   # ***

   #
   def feat_suss_out_facil(self, qb, gf, prog_log):

      bike_facil = self.byway_deduce_bike_facility(gf)
      if bike_facil is not None:
         self.create_link_attr_feat(qb,
                                    self.attr_cycle_facil,
                                    gf,
                                    value_text=bike_facil)
         self.stats['cnt_attrs_cyle_facil'] += 1
         misc.dict_count_inc(self.stats['cnt_facils_kvals'], bike_facil)

      travel_restricted = self.byway_deduce_restricted(gf)
      if travel_restricted:
         self.create_link_attr_feat(qb,
                                    self.attr_no_access,
                                    gf,
                                    value_boolean=True)
         self.stats['cnt_attrs_no_access'] += 1

   # ***

   #
   def create_link_attr_feat(self, qb,
                                   attr,
                                   feat,
                                   value_boolean=None,
                                   value_integer=None,
                                   value_real=None,
                                   value_text=None,
                                   value_binary=None,
                                   value_date=None):

      g.assurt(id(qb) == id(self.qb))
      g.assurt(feat.item_type_id == Item_Type.BYWAY)

      client_id = self.qb.item_mgr.get_next_client_id()

      new_link = link_value.One(
         qb=self.qb,
         row={
            # *** from item_versioned:
            'system_id'             : None, # assigned later
            'branch_id'             : self.qb.branch_hier[0][0],
            'stack_id'              : client_id,
            'version'               : 0,
            'deleted'               : False,
            'reverted'              : False,
            'name'                  : '', # FIXME: Is this right?
            #'valid_start_rid'      : # assigned by
            #'valid_until_rid'      : #   version_finalize_and_increment
            # NOTE: We don't set valid_start_rid any earlier, so historic
            #       views obviously won't show bike facility ornamentation.
            'lhs_stack_id'          : attr.stack_id,
            'rhs_stack_id'          : feat.stack_id,
            # The item type IDs are saved to the group_item_access table.
            'link_lhs_type_id'      : attr.item_type_id,
            'link_rhs_type_id'      : feat.item_type_id,
            'value_boolean'         : value_boolean,
            'value_integer'         : value_integer,
            'value_real'            : value_real,
            'value_text'            : value_text,
            'value_binary'          : value_binary,
            'value_date'            : value_date,
            }
         )

      log.verbose2('create_link_facil: new_link: %s' % (new_link,))

      g.assurt(new_link.groups_access is None)
      new_link.stack_id_correct(self.qb)
      g.assurt(new_link.fresh)
      log.verbose('create_link_facil: not clearing item_cache')
      # NO: self.qb.item_mgr.item_cache_reset()
      self.qb.item_mgr.item_cache_add(new_link, client_id)
      self.qb.item_mgr.item_cache_add(attr)
      self.qb.item_mgr.item_cache_add(feat)

      prepared = self.qb.grac_mgr.prepare_item(self.qb,
         new_link, Access_Level.editor, ref_item=None)
      g.assurt(prepared)
      log.verbose2(' >> prepare_item: %s' % (new_link,))

      log.verbose2(' >> groups_access/1: %s' % (new_link.groups_access,))

      new_link.version_finalize_and_increment(
                  self.qb, self.qb.item_mgr.rid_new)
      log.verbose2(' >> version_finalize_and_increment: %s' % (new_link,))

      new_link.save(self.qb, self.qb.item_mgr.rid_new)
      log.verbose2(' >> saved: %s' % (new_link,))

      log.verbose2(' >> groups_access/2: %s' % (new_link.groups_access,))
      g.assurt(len(new_link.groups_access) == 1)
      try:
         group_id = group.Many.public_group_id(self.qb)
         new_link.groups_access[group_id]
      except KeyError:
         g.assurt(False) # Unexpected.

      self.stats['cnt_attrs_all'] += 1

   # ***

   #
   def byway_deduce_bike_facility(self, bway):

      bike_facil = None

      # MAYBE: Make stats for each bike facility value.
      # BUG nnnn: Or just calculate nightly, along with miles of road, etc.,
      #           I.e., a report for the agency clients. See also gnuplot.
      if bway.geofeature_layer_id in (byway.Geofeature_Layer.Bike_Trail,
                                      byway.Geofeature_Layer.Major_Trail,):
         bike_facil = 'paved_trail'
      # MAYBE: Also check Tag_Presumption.tag_bike_path?
      # 2013.05.11: Checking tag_bike_path is new:
      elif bway.tagged.intersection(Tag_Presumption.tag_bike_path):
         bike_facil = 'paved_trail'
      elif bway.tagged.intersection(Tag_Presumption.tag_bike_lane):
         bike_facil = 'bike_lane'
      elif bway.tagged.intersection(Tag_Presumption.tag_bike_shoulder):
         bike_facil = 'shld_lovol'
      # Skipping: 'Narrow Shoulder'
      # Skipping: Tag_Presumption.tag_unpaved
      # BUG nnnn: MAYBE: Use Tag_Presumption.tag_bike_boulevard... or just
      #                  use new attr instead and skip tags... maybe just
      #                  search for this tag and update their cycle_route
      #                  attr.

      return bike_facil

   #
   def byway_deduce_restricted(self, bway):

      # BUG nnnn: Do we need to support other reasons for restricted access?:
      #           Closed/Restricted: 'Controlled Access',
      #                              'Construction',
      #                              'Not Plowed/Nature',

      if bway.tagged.intersection(Tag_Presumption.tag_prohibited):
         travel_restricted = True
      else:
         travel_restricted = False

      return travel_restricted

   # ***

   #
   def print_stats(self):

      log.debug('*** stats: created %d new links total'
                % (self.stats['cnt_attrs_all'],))

      log.debug('*** stats: created %d new links for attr: %s'
                % (self.stats['cnt_attrs_cyle_facil'],
                   self.attr_cycle_facil.name,))

      log.debug('*** stats: created %d new links for attr: %s'
                % (self.stats['cnt_attrs_no_access'],
                   self.attr_no_access.name,))

      for attr_val, attr_cnt in self.stats['cnt_facils_kvals'].iteritems():
         log.debug('*** cnt: %6d / facil: %s'
                   % (attr_cnt, attr_val,))

   # ***

# ***

if (__name__ == '__main__'):
   bike_facils_pop = Bike_Facilities_Populate()
   bike_facils_pop.go()


text:
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Label" inherits="Control" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
	<brief_description>
		Displays plain text in a line or wrapped inside a rectangle. For formatted text, use [RichTextLabel].
	</brief_description>
	<description>
		Label displays plain text on the screen. It gives you control over the horizontal and vertical alignment and can wrap the text inside the node's bounding rectangle. It doesn't support bold, italics, or other formatting. For that, use [RichTextLabel] instead.
		[b]Note:[/b] Contrarily to most other [Control]s, Label's [member Control.mouse_filter] defaults to [constant Control.MOUSE_FILTER_IGNORE] (i.e. it doesn't react to mouse input events). This implies that a label won't display any configured [member Control.hint_tooltip], unless you change its mouse filter.
	</description>
	<tutorials>
		<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
	</tutorials>
	<methods>
		<method name="get_line_count" qualifiers="const">
			<return type="int" />
			<description>
				Returns the amount of lines of text the Label has.
			</description>
		</method>
		<method name="get_line_height" qualifiers="const">
			<return type="int" />
			<param index="0" name="line" type="int" default="-1" />
			<description>
				Returns the height of the line [code]line[/code].
				If [code]line[/code] is set to [code]-1[/code], returns the biggest line height.
				If there're no lines returns font size in pixels.
			</description>
		</method>
		<method name="get_total_character_count" qualifiers="const">
			<return type="int" />
			<description>
				Returns the total number of printable characters in the text (excluding spaces and newlines).
			</description>
		</method>
		<method name="get_visible_line_count" qualifiers="const">
			<return type="int" />
			<description>
				Returns the number of lines shown. Useful if the [Label]'s height cannot currently display all lines.
			</description>
		</method>
	</methods>
	<members>
		<member name="autowrap_mode" type="int" setter="set_autowrap_mode" getter="get_autowrap_mode" enum="TextServer.AutowrapMode" default="0">
			If set to something other than [constant TextServer.AUTOWRAP_OFF], the text gets wrapped inside the node's bounding rectangle. If you resize the node, it will change its height automatically to show all the text. To see how each mode behaves, see [enum TextServer.AutowrapMode].
		</member>
		<member name="clip_text" type="bool" setter="set_clip_text" getter="is_clipping_text" default="false">
			If [code]true[/code], the Label only shows the text that fits inside its bounding rectangle and will clip text horizontally.
		</member>
		<member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
			Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
		</member>
		<member name="label_settings" type="LabelSettings" setter="set_label_settings" getter="get_label_settings">
		</member>
		<member name="language" type="String" setter="set_language" getter="get_language" default="""">
			Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead.
		</member>
		<member name="lines_skipped" type="int" setter="set_lines_skipped" getter="get_lines_skipped" default="0">
			The node ignores the first [code]lines_skipped[/code] lines before it starts to display text.
		</member>
		<member name="max_lines_visible" type="int" setter="set_max_lines_visible" getter="get_max_lines_visible" default="-1">
			Limits the lines of text the node shows on screen.
		</member>
		<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="2" />
		<member name="percent_visible" type="float" setter="set_percent_visible" getter="get_percent_visible" default="1.0">
			Limits the amount of visible characters. If you set [code]percent_visible[/code] to 0.5, only up to half of the text's characters will display on screen. Useful to animate the text in a dialog box.
			[b]Note:[/b] Setting this property updates [member visible_characters] based on current [method get_total_character_count].
		</member>
		<member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="4" />
		<member name="structured_text_bidi_override" type="int" setter="set_structured_text_bidi_override" getter="get_structured_text_bidi_override" enum="TextServer.StructuredTextParser" default="0">
			Set BiDi algorithm override for the structured text.
		</member>
		<member name="structured_text_bidi_override_options" type="Array" setter="set_structured_text_bidi_override_options" getter="get_structured_text_bidi_override_options" default="[]">
			Set additional options for BiDi override.
		</member>
		<member name="text" type="String" setter="set_text" getter="get_text" default="""">
			The text to display on screen.
		</member>
		<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0">
			Base text writing direction.
		</member>
		<member name="text_overrun_behavior" type="int" setter="set_text_overrun_behavior" getter="get_text_overrun_behavior" enum="TextServer.OverrunBehavior" default="0">
			Sets the clipping behavior when the text exceeds the node's bounding rectangle. See [enum TextServer.OverrunBehavior] for a description of all modes.
		</member>
		<member name="uppercase" type="bool" setter="set_uppercase" getter="is_uppercase" default="false">
			If [code]true[/code], all the text displays as UPPERCASE.
		</member>
		<member name="vertical_alignment" type="int" setter="set_vertical_alignment" getter="get_vertical_alignment" enum="VerticalAlignment" default="0">
			Controls the text's vertical alignment. Supports top, center, bottom, and fill. Set it to one of the [enum VerticalAlignment] constants.
		</member>
		<member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" default="-1">
			Restricts the number of characters to display. Set to -1 to disable.
			[b]Note:[/b] Setting this property updates [member percent_visible] based on current [method get_total_character_count].
		</member>
		<member name="visible_characters_behavior" type="int" setter="set_visible_characters_behavior" getter="get_visible_characters_behavior" enum="TextServer.VisibleCharactersBehavior" default="0">
			Sets the clipping behavior when [member visible_characters] or [member percent_visible] is set. See [enum TextServer.VisibleCharactersBehavior] for more info.
		</member>
	</members>
	<theme_items>
		<theme_item name="font_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
			Default text [Color] of the [Label].
		</theme_item>
		<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
			The tint of text outline.
		</theme_item>
		<theme_item name="font_shadow_color" data_type="color" type="Color" default="Color(0, 0, 0, 0)">
			[Color] of the text's shadow effect.
		</theme_item>
		<theme_item name="line_spacing" data_type="constant" type="int" default="3">
			Vertical space between lines in multiline [Label].
		</theme_item>
		<theme_item name="outline_size" data_type="constant" type="int" default="0">
			Text outline size.
		</theme_item>
		<theme_item name="shadow_offset_x" data_type="constant" type="int" default="1">
			The horizontal offset of the text's shadow.
		</theme_item>
		<theme_item name="shadow_offset_y" data_type="constant" type="int" default="1">
			The vertical offset of the text's shadow.
		</theme_item>
		<theme_item name="shadow_outline_size" data_type="constant" type="int" default="1">
			The size of the shadow outline.
		</theme_item>
		<theme_item name="font" data_type="font" type="Font">
			[Font] used for the [Label]'s text.
		</theme_item>
		<theme_item name="font_size" data_type="font_size" type="int">
			Font size of the [Label]'s text.
		</theme_item>
		<theme_item name="normal" data_type="style" type="StyleBox">
			Background [StyleBox] for the [Label].
		</theme_item>
	</theme_items>
</class>


text:
"""Config options available for the Packet metadata service."""

from oslo_config import cfg

from cloudbaseinit.conf import base as conf_base

class PacketOptions(conf_base.Options):

    """Config options available for the Packet metadata service."""

    def __init__(self, config):
        super(PacketOptions, self).__init__(config, group="packet")
        self._options = [
            cfg.StrOpt(
                'metadata_base_url', default="https://metadata.packet.net/",
                help='The URL where the service looks for metadata'),
            cfg.BoolOpt(
                "https_allow_insecure", default=False,
                help="Whether to disable the validation of HTTPS "
                     "certificates."),
            cfg.StrOpt(
                "https_ca_bundle", default=None,
                help="The path to a CA_BUNDLE file or directory with "
                     "certificates of trusted CAs."),
        ]

    def register(self):
        """Register the current options to the global ConfigOpts object."""
        group = cfg.OptGroup(self.group_name, title='Packet Options')
        self._config.register_group(group)
        self._config.register_opts(self._options, group=group)

    def list(self):
        """Return a list which contains all the available options."""
        return self._options


text:
#include "ByteBuffer.h"
#include "Util.h"
#include "SocketClient.h"

ByteBuffer::ByteBuffer(int capacity){

	buffer = new char[capacity];
	position = 0;
	this->capacity = capacity;
	this->limit = capacity;
}
ByteBuffer::	ByteBuffer(char* data,int offset,int size){

	buffer = new char[size];
	position = 0;
	memcpy(buffer,data+offset,size);
	this->capacity = size;
	this->limit = this->capacity;
}
ByteBuffer::~ByteBuffer(){
	SAFE_DELETE_ARRAY( buffer);

}

int ByteBuffer::remaining(){
	return limit - position;
}

//void ByteBuffer::markPosition(){
//	mark = position;
//}
//
//void ByteBuffer::reset(){
//	if(mark != -1)
//		position = mark;
//	mark = -1;
//}

void ByteBuffer::put(const char* bytes,int offset,int len){
	if(position + len > capacity){
		printf("error -ByteBuffer::put(const char* bytes,int offset,int len)---position=%d,len=%d,capacity=%d\n",position,len,capacity);
		return;
	}
	memcpy(buffer+position,bytes+offset,len);
	position += len;
}
void ByteBuffer::putByte(byte n){
	if(position + 1 > capacity){
		printf("error ByteBuffer::putByte----position=%d,len=%d,capacity=%d\n",position,1,capacity);
		return;
	}
	buffer[position] = n;
	position++;
}

void ByteBuffer::put(int n){
	if(position + 1 > capacity){
		printf("error ByteBuffer::put---position=%d,len=%d,capacity=%d\n",position,1,capacity);
		return;
	}
	buffer[position] = (char)n;
	position++;
}

void ByteBuffer::putInt(int n){
	if(position + 4 > capacity){
		printf("error ByteBuffer::putInt--position=%d,len=%d,capacity=%d\n",position,4,capacity);
		return;
	}
	for(int i = 0 ; i < 4 ; i++){
		buffer[position] = (char)((n >> (8 *(3 - i))) & 0xFF);
		position++;
	}
}
void ByteBuffer::setIntAt(int n,int index){
	if(index + 4 > capacity){
		printf("error ByteBuffer::setIntAt--index=%d,len=%d,capacity=%d\n",index,4,capacity);
		return;
	}
	for(int i = 0 ; i < 4 ; i++){
		buffer[index] = (char)((n >> (8 *(3 - i))) & 0xFF);
		index++;
	}
}

void ByteBuffer::putFloat(float n){
	if(position + 4 > capacity){
		printf("error -ByteBuffer::putFloat---position=%d,len=%d,capacity=%d\n",position,4,capacity);
		return;
	}
	unsigned char* pBytes;
	pBytes = (unsigned char*)&n;

	buffer[position++] = pBytes[3];
	buffer[position++] = pBytes[2];
	buffer[position++] = pBytes[1];
	buffer[position++] = pBytes[0];

	//return floatValue;
}

void ByteBuffer::putShort(short n){
	if(position + 2 > capacity){
		printf("error -ByteBuffer::putShort---position=%d,len=%d,capacity=%d\n",position,2,capacity);
		return;

	}
	for(int i = 0 ; i < 2 ; i++){
		buffer[position] = (char)((n >> (8 *(1 - i))) & 0xFF);
		position++;
	}
}

void ByteBuffer::putLong(long long n){
	if(position + 8 > capacity){
		printf("error ByteBuffer::putLong-position=%d,len=%d,capacity=%d\n",position,8,capacity);
		return;
	}

	for(int i = 0 ; i < 8 ; i++){
		buffer[position] = (char)((n >> (8 *(7 - i))) & 0xFF);
		position++;
	}
}
void ByteBuffer::putUTF(const char* str){
	short len = strlen(str);
	if(position + 2+len > capacity){
		printf("error ByteBuffer::putUTF----position=%d,len=%d,capacity=%d\n",position,2+len,capacity);
		return;
	}
	putShort(len);
	if( len>0){
		put(str,0,len);
	}
}
void ByteBuffer::putUTF(const string& str){
	putUTF(str.c_str());

}

void ByteBuffer::putArray(vector<byte>& a){
	putInt(a.size());
	for(size_t i=0;i< a.size();++i){
		put(a[i]);
	}
}
void ByteBuffer::putArray(vector<bool>& a){
	putInt(a.size());
	for(size_t i=0;i< a.size();++i){
		put(a[i]);
	}
}
void ByteBuffer::putArray(vector<short>& a){
	putInt(a.size());
	//short* d = a.data();
	for(size_t i=0;i< a.size();++i){
		putShort(a[i]);
	}
}
void ByteBuffer::putArray(vector<int>& a){
	putInt(a.size());
	//int* d = a.data();
	for(size_t i=0;i< a.size();++i){
		putInt(a[i]);
	}
}
void ByteBuffer::putArray(vector<long long>& a){
	putInt(a.size());

	for(size_t i=0;i< a.size();++i){
		putLong(a[i]);
	}
}
void ByteBuffer::putArray(vector<string>& a){
	putInt(a.size());

	for(size_t i=0;i< a.size();++i){
		putUTF(a[i]);
	}
}

void ByteBuffer::getArray(vector<byte>& a){
	int size = getInt();
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = get();
	}

}
void ByteBuffer::getArray(vector<bool>& a){
	int size = getInt();
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getBoolean();
	}

}

void ByteBuffer::getArray(vector<short>& a){

	int size = getInt();
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getShort();
	}
}
void ByteBuffer::getArray(vector<int>& a){
	int size = getInt();
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getInt();
	}
}
void ByteBuffer::getArray(vector<long long>& a){

	int size = getInt();
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getLong();
	}

}
void ByteBuffer::getArray(vector<string>& a){
	int size =getInt();
	getArray(a,size);
}
void ByteBuffer::getArray(vector<byte>& a,int size){
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getByte();
	}
}
void ByteBuffer::getArray(vector<bool>& a,int size){
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getBoolean();
	}
}
void ByteBuffer::getArray(vector<short>& a,int size){
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getShort();
	}
}
void ByteBuffer::getArray(vector<int>& a,int size){
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getInt();
	}
}
void ByteBuffer::getArray(vector<long long>& a,int size){
	a.resize(size);
	for(int i=0;i< size;++i){
		a[i] = getLong();
	}
}
void ByteBuffer::getArray(vector<string>& a,int size){
	a.resize(size);
	for(int i=0;i< size;++i){
		getUTF(a[i]);
	}
}

void ByteBuffer::getUTF(string& str){
	short len = getShort();
	if( len>0){
		str.append(buffer+position,len);
		position+=len;
	}else {
		str="";
	}

}
string ByteBuffer::getUTF(){
	string str;
	getUTF(str);
	return str;
}

int ByteBuffer::getPosition(){
	return position;
}

void ByteBuffer::setPosition(int p){
	if(p > limit) {
		printf("error ByteBuffer::setPosition p> limit------------p=%d,limit=%d\n",p,limit);
	}
	position = p;
}

int ByteBuffer::getLimit(){
	return limit;
}

int ByteBuffer::getCapacity(){
	return this->capacity;
}

char* ByteBuffer::getBuffer(){
	return buffer;
}
char* ByteBuffer::toByteArray(){
	char* tmp = new char[position];
	memcpy( tmp,buffer,position);
	return tmp;
}

char ByteBuffer::get(){
	if(position < limit){
		return buffer[position++];
	}
	printf("error ByteBuffer::get() position+1> limit------------position=%d,limit=%d\n",position,limit);
	return 0;
}
byte ByteBuffer::getByte(){
	if(position + 1 > limit){
		printf("error ByteBuffer::getByte() position+1> limit------------position=%d,limit=%d\n",position,limit);
		return 0;
	}
	return buffer[position++];
}
bool ByteBuffer::getBoolean(){
	if(position + 1 > limit){
		printf("error ByteBuffer::getBoolean() position+1> limit------------position=%d,limit=%d\n",position,limit);
		return false;
	}
	return buffer[position++]!=0;
}

int readIntFromBuffer(byte* buffer,int position){
	int rt = 0;
	for(int i = 0 ; i < 4 ; i++){
		rt |=  ((buffer[position] & 0xFF) << (8 *(3 - i)));
		position++;
	}
	return rt;
}

int ByteBuffer::getLength(int offset)
{
    int lengthPos = position+ offset;
    byte* pos = new byte[4];
    for(int i = 0;i < 4 ;i++)
    {
        pos[i] = buffer[lengthPos+i];
    }

    for(int i = 0; i < 73; i ++)
    {
        printf("%d," , buffer[i]);
    }

    printf("\n %s \n" , buffer);
    return SocketClient::bytesToInt(pos);
}

void ByteBuffer::getAsBytes(byte* bytes)
{
    for(int i = 0 ; i < 4 ; i++){
		bytes[i]=  buffer[position];
		position++;
	}

}

int ByteBuffer::getInt(){
	if(position + 4 > limit){
		printf("error ByteBuffer::getInt() position+4> limit------------position=%d,limit=%d\n",position,limit);
		return 0;
	}
	int rt = 0;
	for(int i = 0 ; i < 4 ; i++){
		rt |=  ((buffer[position] & 0xFF) << (8 *(3 - i)));
		position++;
	}
	return rt;
}

float ByteBuffer::getFloat(){
	if(position + 4 > limit){
		printf("error ByteBuffer::getFloat() position+4> limit------------position=%d,limit=%d\n",position,limit);
		return 0;
	}
	float floatValue;
	unsigned char* pBytes;
	pBytes = (unsigned char*)&floatValue;
	pBytes[3] = buffer[position++];
	pBytes[2] = buffer[position++];
	pBytes[1] = buffer[position++];
	pBytes[0] = buffer[position++];
	return floatValue;
}

short ByteBuffer::getShort(){
	if(position + 2 > limit){
		printf("error ByteBuffer::getShort() position+2> limit------------position=%d,limit=%d\n",position,limit);
		return 0;
	}
	short n = 0;
	for(int i = 0 ; i < 2 ; i++){
		n |= ((buffer[position] & 0xFF) << (8 *(1 - i)));
		position++;
	}
	return n;
}

long long ByteBuffer::getLong(){
	if( position + 8 > limit ){

		printf("error ByteBuffer::getLong() position+8> limit------------position=%d,limit=%d\n",position,limit);
		return 0;

	}
	long long n = 0;
	for(int i = 0 ; i < 8 ; i++){
		long long tmp = (buffer[position] & 0xFF);
		n  |= (tmp << (8 *(7 - i)));

		position++;
	}
	return n;
}
void ByteBuffer::get(char* bytes,int size){
	get(bytes,0,size);
}

void ByteBuffer::get(char* bytes,int offset,int len){
	if(position + len > limit){
		memset(bytes+offset, 0, len );
		printf("error ByteBuffer::get(char* bytes,int offset,int len) position+len> limit------------position=%d,len=%d,limit=%d\n",position,len,limit);
		return;
	}
	memcpy(bytes+offset,buffer+position,len);
	position += len;
}
/**
 * makes a buffer ready for a new sequence of channel-read or relative put operations: It sets the limit to the capacity and the position to zero.
 */
void ByteBuffer::clear(){
	position = 0;
	this->limit = capacity;
}

/**
 * flip() makes a buffer ready for a new sequence of channel-write or relative get operations: It sets the limit to the current position and then sets the position to zero.
 */
void ByteBuffer::flip(){
	this->limit = position;
	position = 0;
}

void ByteBuffer::compact(){
	if(position > 0){
		for(int i = position; i < limit ; i++){
			buffer[i-position] = buffer[i];
		}
	}
	position = limit - position;
	limit = this->capacity;
}

void ByteBuffer::rewind(){
	position = 0;
}

void ByteBuffer::putBoolean(bool b)
{
	if( position+1> capacity ){
		printf("error putBoolean position+len> limit------------position=%d,len=%d,capacity=%d\n",position,1,capacity);

		return;
	}

	if(b)
		buffer[position] =(1&0xff);
	else
		buffer[position]=(0&0xff);
	position+=1;

}

//这个方法只能用于打开的是文本文件的时候
string ByteBuffer::getLine(){
    if( position>=capacity) return "";
	string line;
	for (int i = position; i<capacity; i++) {
		if (buffer[i] == '\n') {
			line.append(buffer + position, i - position);
			position = i + 1;
			return line;
		}
	}
	line.append(buffer + position, capacity - position);
	position = capacity +1;
	return line;
}


text:
using System;
using Xunit;

namespace SampleDynamicTests
{
    public delegate int MultiplyDelegate(int a, int b);

    public class DelegateTest
    {
        public int Mul(int a, int b)
        {
            return a * b;
        }

        [Fact]
        public static void DelegateTest_RunTest()
        {
            DelegateTest del = new DelegateTest();
            dynamic d = (MultiplyDelegate)del.Mul;
            int result = d(4, 6);
            Assert.Equal(24, result);
        }

        private static int Foo(string s, dynamic d, object o)
        {
            return s.Length + d.ToString().Length + o.ToString().Length;
        }

        private static void Bar(string s, dynamic d, object o)
        {
        }

        [Fact]
        public static void VariantFuncTest()
        {
            Func<string, dynamic, object, int> del = Foo;
            Func<string, dynamic, string, int> func = del;

            dynamic arg = "saw";

            Assert.Equal(16, func("came", arg, "conquered"));
        }

        [Fact]
        public static void VariantActTest()
        {
            Action<string, dynamic, object> del = Bar;
            Action<string, dynamic, string> act = del;

            dynamic arg = "saw";

            act("came", arg, "conquered");
        }
    }
}


text:
package com.thing.rpg_droid.app;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by jon on 8/08/14.
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CharSheet_PageInfo
{
    public String title() default "";
}


text:
package org.apache.druid.data.input.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.apache.druid.TestObjectMapper;
import org.apache.druid.data.input.ByteBufferInputRowParser;
import org.apache.druid.data.input.InputRow;
import org.apache.druid.java.util.common.DateTimes;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.parsers.JSONPathFieldSpec;
import org.apache.druid.java.util.common.parsers.JSONPathFieldType;
import org.apache.druid.java.util.common.parsers.JSONPathSpec;
import org.junit.Assert;
import org.junit.Test;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class InputRowParserSerdeTest
{
  private final ObjectMapper jsonMapper = new TestObjectMapper();

  @Test
  public void testStringInputRowParserSerde() throws Exception
  {
    final StringInputRowParser parser = new StringInputRowParser(
        new JSONParseSpec(
            new TimestampSpec("timestamp", "iso", null),
            new DimensionsSpec(DimensionsSpec.getDefaultSchemas(ImmutableList.of("foo", "bar")), null, null),
            null,
            null
        ),
        null
    );
    final ByteBufferInputRowParser parser2 = jsonMapper.readValue(
        jsonMapper.writeValueAsBytes(parser),
        ByteBufferInputRowParser.class
    );
    final InputRow parsed = parser2.parseBatch(
        ByteBuffer.wrap(StringUtils.toUtf8("{\"foo\":\"x\",\"bar\":\"y\",\"qux\":\"z\",\"timestamp\":\"2000\"}"))
    ).get(0);
    Assert.assertEquals(ImmutableList.of("foo", "bar"), parsed.getDimensions());
    Assert.assertEquals(ImmutableList.of("x"), parsed.getDimension("foo"));
    Assert.assertEquals(ImmutableList.of("y"), parsed.getDimension("bar"));
    Assert.assertEquals(DateTimes.of("2000").getMillis(), parsed.getTimestampFromEpoch());
  }

  @Test
  public void testStringInputRowParserSerdeMultiCharset() throws Exception
  {
    Charset[] testCharsets = {
        StandardCharsets.US_ASCII, StandardCharsets.ISO_8859_1, StandardCharsets.UTF_8,
        StandardCharsets.UTF_16BE, StandardCharsets.UTF_16LE, StandardCharsets.UTF_16
    };

    for (Charset testCharset : testCharsets) {
      InputRow parsed = testCharsetParseHelper(testCharset);
      Assert.assertEquals(ImmutableList.of("foo", "bar"), parsed.getDimensions());
      Assert.assertEquals(ImmutableList.of("x"), parsed.getDimension("foo"));
      Assert.assertEquals(ImmutableList.of("y"), parsed.getDimension("bar"));
      Assert.assertEquals(DateTimes.of("3000").getMillis(), parsed.getTimestampFromEpoch());
    }
  }

  @Test
  public void testMapInputRowParserSerde() throws Exception
  {
    final MapInputRowParser parser = new MapInputRowParser(
        new JSONParseSpec(
            new TimestampSpec("timeposix", "posix", null),
            new DimensionsSpec(
                DimensionsSpec.getDefaultSchemas(ImmutableList.of("foo", "bar")),
                ImmutableList.of("baz"),
                null
            ),
            null,
            null
        )
    );
    final MapInputRowParser parser2 = (MapInputRowParser) jsonMapper.readValue(
        jsonMapper.writeValueAsBytes(parser),
        InputRowParser.class
    );
    final InputRow parsed = parser2.parseBatch(
        ImmutableMap.of(
            "foo", "x",
            "bar", "y",
            "qux", "z",
            "timeposix", "1"
        )
    ).get(0);
    Assert.assertEquals(ImmutableList.of("foo", "bar"), parsed.getDimensions());
    Assert.assertEquals(ImmutableList.of("x"), parsed.getDimension("foo"));
    Assert.assertEquals(ImmutableList.of("y"), parsed.getDimension("bar"));
    Assert.assertEquals(1000, parsed.getTimestampFromEpoch());
  }

  @Test
  public void testMapInputRowParserNumbersSerde() throws Exception
  {
    final MapInputRowParser parser = new MapInputRowParser(
        new JSONParseSpec(
            new TimestampSpec("timemillis", "millis", null),
            new DimensionsSpec(
                DimensionsSpec.getDefaultSchemas(ImmutableList.of("foo", "values")),
                ImmutableList.of("toobig", "value"),
                null
            ),
            null,
            null
        )
    );
    final MapInputRowParser parser2 = (MapInputRowParser) jsonMapper.readValue(
        jsonMapper.writeValueAsBytes(parser),
        InputRowParser.class
    );
    final InputRow parsed = parser2.parseBatch(
        ImmutableMap.of(
            "timemillis", 1412705931123L,
            "toobig", 123E64,
            "value", 123.456,
            "long", 123456789000L,
            "values", Lists.newArrayList(1412705931123L, 123.456, 123E45, "hello")
        )
    ).get(0);
    Assert.assertEquals(ImmutableList.of("foo", "values"), parsed.getDimensions());
    Assert.assertEquals(ImmutableList.of(), parsed.getDimension("foo"));
    Assert.assertEquals(
        ImmutableList.of("1412705931123", "123.456", "1.23E47", "hello"),
        parsed.getDimension("values")
    );
    Assert.assertEquals(Float.POSITIVE_INFINITY, parsed.getMetric("toobig").floatValue(), 0.0);
    Assert.assertEquals(123E64, parsed.getRaw("toobig"));
    Assert.assertEquals(123.456f, parsed.getMetric("value").floatValue(), 0.0f);
    Assert.assertEquals(123456789000L, parsed.getRaw("long"));
    Assert.assertEquals(1.23456791E11f, parsed.getMetric("long").floatValue(), 0.0f);
    Assert.assertEquals(1412705931123L, parsed.getTimestampFromEpoch());
  }

  private InputRow testCharsetParseHelper(Charset charset) throws Exception
  {
    final StringInputRowParser parser = new StringInputRowParser(
        new JSONParseSpec(
            new TimestampSpec("timestamp", "iso", null),
            new DimensionsSpec(DimensionsSpec.getDefaultSchemas(ImmutableList.of("foo", "bar")), null, null),
            null,
            null
        ),
        charset.name()
    );

    final ByteBufferInputRowParser parser2 = jsonMapper.readValue(
        jsonMapper.writeValueAsBytes(parser),
        ByteBufferInputRowParser.class
    );

    final InputRow parsed = parser2.parseBatch(
        ByteBuffer.wrap(
            "{\"foo\":\"x\",\"bar\":\"y\",\"qux\":\"z\",\"timestamp\":\"3000\"}".getBytes(charset)
        )
    ).get(0);

    return parsed;
  }

  @Test
  public void testFlattenParse() throws Exception
  {
    List<JSONPathFieldSpec> fields = new ArrayList<>();
    fields.add(JSONPathFieldSpec.createNestedField("foobar1", "$.foo.bar1"));
    fields.add(JSONPathFieldSpec.createNestedField("foobar2", "$.foo.bar2"));
    fields.add(JSONPathFieldSpec.createNestedField("baz0", "$.baz[0]"));
    fields.add(JSONPathFieldSpec.createNestedField("baz1", "$.baz[1]"));
    fields.add(JSONPathFieldSpec.createNestedField("baz2", "$.baz[2]"));
    fields.add(JSONPathFieldSpec.createNestedField("hey0barx", "$.hey[0].barx"));
    fields.add(JSONPathFieldSpec.createNestedField("metA", "$.met.a"));
    fields.add(JSONPathFieldSpec.createNestedField("missing", "$.nonexistent.nested.field"));
    fields.add(JSONPathFieldSpec.createRootField("timestamp"));
    fields.add(JSONPathFieldSpec.createRootField("foo.bar1"));

    JSONPathSpec flattenSpec = new JSONPathSpec(true, fields);
    final StringInputRowParser parser = new StringInputRowParser(
        new JSONParseSpec(
            new TimestampSpec("timestamp", "iso", null),
            new DimensionsSpec(null, null, null),
            flattenSpec,
            null
        ),
        null
    );

    final StringInputRowParser parser2 = jsonMapper.readValue(
        jsonMapper.writeValueAsBytes(parser),
        StringInputRowParser.class
    );

    final InputRow parsed = parser2.parse(
        "{\"blah\":[4,5,6], \"newmet\":5, \"foo\":{\"bar1\":\"aaa\", \"bar2\":\"bbb\"}, \"baz\":[1,2,3], \"timestamp\":\"2999\", \"foo.bar1\":\"Hello world!\", \"hey\":[{\"barx\":\"asdf\"}], \"met\":{\"a\":456}}"
    );
    Assert.assertEquals(ImmutableList.of(
        "foobar1",
        "foobar2",
        "baz0",
        "baz1",
        "baz2",
        "hey0barx",
        "metA",
        "missing",
        "timestamp",
        "foo.bar1",
        "blah",
        "newmet",
        "baz"
    ), parsed.getDimensions());
    Assert.assertEquals(ImmutableList.of("aaa"), parsed.getDimension("foobar1"));
    Assert.assertEquals(ImmutableList.of("bbb"), parsed.getDimension("foobar2"));
    Assert.assertEquals(ImmutableList.of("1"), parsed.getDimension("baz0"));
    Assert.assertEquals(ImmutableList.of("2"), parsed.getDimension("baz1"));
    Assert.assertEquals(ImmutableList.of("3"), parsed.getDimension("baz2"));
    Assert.assertEquals(ImmutableList.of("Hello world!"), parsed.getDimension("foo.bar1"));
    Assert.assertEquals(ImmutableList.of("asdf"), parsed.getDimension("hey0barx"));
    Assert.assertEquals(ImmutableList.of("456"), parsed.getDimension("metA"));
    Assert.assertEquals(ImmutableList.of("5"), parsed.getDimension("newmet"));
    Assert.assertEquals(ImmutableList.of(), parsed.getDimension("missing"));
    Assert.assertEquals(DateTimes.of("2999").getMillis(), parsed.getTimestampFromEpoch());

    String testSpec = "{\"enabled\": true,\"useFieldDiscovery\": true, \"fields\": [\"parseThisRootField\"]}";
    final JSONPathSpec parsedSpec = jsonMapper.readValue(testSpec, JSONPathSpec.class);
    List<JSONPathFieldSpec> fieldSpecs = parsedSpec.getFields();
    Assert.assertEquals(JSONPathFieldType.ROOT, fieldSpecs.get(0).getType());
    Assert.assertEquals("parseThisRootField", fieldSpecs.get(0).getName());
    Assert.assertEquals("parseThisRootField", fieldSpecs.get(0).getExpr());
  }

}


text:
/*
 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * Indicates that the named compiler warnings should be suppressed in the
 * annotated element (and in all program elements contained in the annotated
 * element).  Note that the set of warnings suppressed in a given element is
 * a superset of the warnings suppressed in all containing elements.  For
 * example, if you annotate a class to suppress one warning and annotate a
 * method to suppress another, both warnings will be suppressed in the method.
 *
 *
As a matter of style, programmers should always use this annotation
 * on the most deeply nested element where it is effective.  If you want to
 * suppress a warning in a particular method, you should annotate that
 * method rather than its class.
 *
 * @author Josh Bloch
 * @since 1.5
 * @jls 4.8 Raw Types
 * @jls 4.12.2 Variables of Reference Type
 * @jls 5.1.9 Unchecked Conversion
 * @jls 5.5.2 Checked Casts and Unchecked Casts
 * @jls 9.6.3.5 @SuppressWarnings
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is not an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     *
 The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}


text:
package ru.vyarus.dropwizard.guice.debug;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.vyarus.dropwizard.guice.debug.report.yaml.BindingsConfig;
import ru.vyarus.dropwizard.guice.debug.report.yaml.ConfigBindingsRenderer;
import ru.vyarus.dropwizard.guice.module.installer.util.Reporter;
import ru.vyarus.dropwizard.guice.module.lifecycle.UniqueGuiceyLifecycleListener;
import ru.vyarus.dropwizard.guice.module.lifecycle.event.run.BeforeRunEvent;

/**
 * Configuration bindings debug listener. Must be registered with
 * {@link ru.vyarus.dropwizard.guice.GuiceBundle.Builder#listen(
 * ru.vyarus.dropwizard.guice.module.lifecycle.GuiceyLifecycleListener...)}.
 * Could be configured to filter out not required info.
 * <p>
 * If multiple listeners registered, only first registered will be actually used (allow safe multiple registrations).
 *
 * @author Vyacheslav Rusakov
 * @see ru.vyarus.dropwizard.guice.GuiceBundle.Builder#printConfigurationBindings()
 * @see ru.vyarus.dropwizard.guice.GuiceBundle.Builder#printCustomConfigurationBindings()
 * @since 13.06.2018
 */
public class YamlBindingsDiagnostic extends UniqueGuiceyLifecycleListener {

    private final Logger logger = LoggerFactory.getLogger(YamlBindingsDiagnostic.class);

    private final BindingsConfig config;

    public YamlBindingsDiagnostic() {
        this(new BindingsConfig()
                .showConfigurationTree()
                .showNullValues());
    }

    public YamlBindingsDiagnostic(final BindingsConfig config) {
        this.config = config;
    }

    @Override
    protected void beforeRun(final BeforeRunEvent event) {
        final boolean customOnly = config.isShowCustomConfigOnly();
        final String report;
        if (customOnly && event.getConfigurationTree().getRootTypes().size() == 1) {
            report = Reporter.NEWLINE + Reporter.NEWLINE + Reporter.TAB + "No custom bindings";
        } else {
            report = new ConfigBindingsRenderer(event.getConfigurationTree()).renderReport(config);
        }
        logger.info("Available {}configuration bindings = {}",
                customOnly ? "custom " : "", report);
    }
}


text:
<?php

namespace Joomla\Data;

use Joomla\Registry\Registry;

/**
 * DataObject is a class that is used to store data but allowing you to access the data
 * by mimicking the way PHP handles class properties.
 *
 * @since  1.0
 */
class DataObject implements DumpableInterface, \IteratorAggregate, \JsonSerializable, \Countable
{
	/**
	 * The data object properties.
	 *
	 * @var    array
	 * @since  1.0
	 */
	private $properties = array();

	/**
	 * The class constructor.
	 *
	 * @param   mixed  $properties  Either an associative array or another object
	 *                              by which to set the initial properties of the new object.
	 *
	 * @since   1.0
	 * @throws  \InvalidArgumentException
	 */
	public function __construct($properties = array())
	{
		// Check the properties input.
		if (!empty($properties))
		{
			// Bind the properties.
			$this->bind($properties);
		}
	}

	/**
	 * The magic get method is used to get a data property.
	 *
	 * This method is a public proxy for the protected getProperty method.
	 *
	 * Note: Magic __get does not allow recursive calls. This can be tricky because the error generated by recursing into
	 * __get is "Undefined property:  {CLASS}::{PROPERTY}" which is misleading. This is relevant for this class because
	 * requesting a non-visible property can trigger a call to a sub-function. If that references the property directly in
	 * the object, it will cause a recursion into __get.
	 *
	 * @param   string  $property  The name of the data property.
	 *
	 * @return  mixed  The value of the data property, or null if the data property does not exist.
	 *
	 * @see     DataObject::getProperty()
	 * @since   1.0
	 */
	public function __get($property)
	{
		return $this->getProperty($property);
	}

	/**
	 * The magic isset method is used to check the state of an object property.
	 *
	 * @param   string  $property  The name of the data property.
	 *
	 * @return  boolean  True if set, otherwise false is returned.
	 *
	 * @since   1.0
	 */
	public function __isset($property)
	{
		return isset($this->properties[$property]);
	}

	/**
	 * The magic set method is used to set a data property.
	 *
	 * This is a public proxy for the protected setProperty method.
	 *
	 * @param   string  $property  The name of the data property.
	 * @param   mixed   $value     The value to give the data property.
	 *
	 * @return  void
	 *
	 * @see     DataObject::setProperty()
	 * @since   1.0
	 */
	public function __set($property, $value)
	{
		$this->setProperty($property, $value);
	}

	/**
	 * The magic unset method is used to unset a data property.
	 *
	 * @param   string  $property  The name of the data property.
	 *
	 * @return  void
	 *
	 * @since   1.0
	 */
	public function __unset($property)
	{
		unset($this->properties[$property]);
	}

	/**
	 * Binds an array or object to this object.
	 *
	 * @param   mixed    $properties   An associative array of properties or an object.
	 * @param   boolean  $updateNulls  True to bind null values, false to ignore null values.
	 *
	 * @return  DataObject  Returns itself to allow chaining.
	 *
	 * @since   1.0
	 * @throws  \InvalidArgumentException
	 */
	public function bind($properties, $updateNulls = true)
	{
		// Check the properties data type.
		if (!is_array($properties) && !is_object($properties))
		{
			throw new \InvalidArgumentException(sprintf('%s(%s)', __METHOD__, gettype($properties)));
		}

		// Check if the object is traversable.
		if ($properties instanceof \Traversable)
		{
			// Convert iterator to array.
			$properties = iterator_to_array($properties);
		}
		elseif (is_object($properties))
		// Check if the object needs to be converted to an array.
		{
			// Convert properties to an array.
			$properties = (array) $properties;
		}

		// Bind the properties.
		foreach ($properties as $property => $value)
		{
			// Check if the value is null and should be bound.
			if ($value === null && !$updateNulls)
			{
				continue;
			}

			// Set the property.
			$this->setProperty($property, $value);
		}

		return $this;
	}

	/**
	 * Dumps the data properties into a stdClass object, recursively if appropriate.
	 *
	 * @param   integer            $depth   The maximum depth of recursion (default = 3).
	 *                                      For example, a depth of 0 will return a stdClass with all the properties in native
	 *                                      form. A depth of 1 will recurse into the first level of properties only.
	 * @param   \SplObjectStorage  $dumped  An array of already serialized objects that is used to avoid infinite loops.
	 *
	 * @return  \stdClass  The data properties as a simple PHP stdClass object.
	 *
	 * @since   1.0
	 */
	public function dump($depth = 3, \SplObjectStorage $dumped = null)
	{
		// Check if we should initialise the recursion tracker.
		if ($dumped === null)
		{
			$dumped = new \SplObjectStorage;
		}

		// Add this object to the dumped stack.
		$dumped->attach($this);

		// Setup a container.
		$dump = new \stdClass;

		// Dump all object properties.
		foreach (array_keys($this->properties) as $property)
		{
			// Get the property.
			$dump->$property = $this->dumpProperty($property, $depth, $dumped);
		}

		return $dump;
	}

	/**
	 * Gets this object represented as an ArrayIterator.
	 *
	 * This allows the data properties to be access via a foreach statement.
	 *
	 * @return  \ArrayIterator  This object represented as an ArrayIterator.
	 *
	 * @see     IteratorAggregate::getIterator()
	 * @since   1.0
	 */
	public function getIterator()
	{
		return new \ArrayIterator($this->dump(0));
	}

	/**
	 * Gets the data properties in a form that can be serialised to JSON format.
	 *
	 * @return  string  An object that can be serialised by json_encode().
	 *
	 * @since   1.0
	 */
	public function jsonSerialize()
	{
		return $this->dump();
	}

	/**
	 * Dumps a data property.
	 *
	 * If recursion is set, this method will dump any object implementing Data\Dumpable (like Data\Object and Data\Set); it will
	 * convert a Date object to a string; and it will convert a Registry to an object.
	 *
	 * @param   string             $property  The name of the data property.
	 * @param   integer            $depth     The current depth of recursion (a value of 0 will ignore recursion).
	 * @param   \SplObjectStorage  $dumped    An array of already serialized objects that is used to avoid infinite loops.
	 *
	 * @return  mixed  The value of the dumped property.
	 *
	 * @since   1.0
	 */
	protected function dumpProperty($property, $depth, \SplObjectStorage $dumped)
	{
		$value = $this->getProperty($property);

		if ($depth > 0)
		{
			// Check if the object is also an dumpable object.
			if ($value instanceof DumpableInterface)
			{
				// Do not dump the property if it has already been dumped.
				if (!$dumped->contains($value))
				{
					$value = $value->dump($depth - 1, $dumped);
				}
			}

			// Check if the object is a date.
			if ($value instanceof \DateTime)
			{
				$value = $value->format('Y-m-d H:i:s');
			}
			elseif ($value instanceof Registry)
			// Check if the object is a registry.
			{
				$value = $value->toObject();
			}
		}

		return $value;
	}

	/**
	 * Gets a data property.
	 *
	 * @param   string  $property  The name of the data property.
	 *
	 * @return  mixed  The value of the data property.
	 *
	 * @see     DataObject::__get()
	 * @since   1.0
	 */
	protected function getProperty($property)
	{
		// Get the raw value.
		$value = array_key_exists($property, $this->properties) ? $this->properties[$property] : null;

		return $value;
	}

	/**
	 * Sets a data property.
	 *
	 * If the name of the property starts with a null byte, this method will return null.
	 *
	 * @param   string  $property  The name of the data property.
	 * @param   mixed   $value     The value to give the data property.
	 *
	 * @return  mixed  The value of the data property.
	 *
	 * @see     DataObject::__set()
	 * @since   1.0
	 */
	protected function setProperty($property, $value)
	{
		/*
		 * Check if the property starts with a null byte. If so, discard it because a later attempt to try to access it
		 * can cause a fatal error. See http://us3.php.net/manual/en/language.types.array.php#language.types.array.casting
		 */
		if (strpos($property, "\0") === 0)
		{
			return null;
		}

		// Set the value.
		$this->properties[$property] = $value;

		return $value;
	}

	/**
	 * Count the number of data properties.
	 *
	 * @return  integer  The number of data properties.
	 *
	 * @since   1.0
	 */
	public function count()
	{
		return count($this->properties);
	}
}


text:
Designed by MVP
## Library
[RxJava](https://github.com/ReactiveX/RxJava)
[Gson](https://github.com/google/gson)
[Retrofit](https://github.com/square/retrofit)
[ButterKnife](https://github.com/JakeWharton/butterknife)
[Logger](https://github.com/orhanobut/logger)
[Fresco](https://github.com/facebook/fresco)
[BottomBar](https://github.com/roughike/BottomBar)
[RealTimeBlurView](https://github.com/mmin18/RealtimeBlurView)
[PhotoDraweeView](https://github.com/ongakuer/PhotoDraweeView)
## ScreenShots
 ![s1](https://github.com/HStanN/TakeRest/blob/master/images/screenshot1.png)
 ![s2](https://github.com/HStanN/TakeRest/blob/master/images/screenshot2.png)
 ![s3](https://github.com/HStanN/TakeRest/blob/master/images/screenshot3.png)
 ![s4](https://github.com/HStanN/TakeRest/blob/master/images/screenshot4.png)
 ![s5](https://github.com/HStanN/TakeRest/blob/master/images/screenshot5.png)
 ![s6](https://github.com/HStanN/TakeRest/blob/master/images/screenshot6.png)

# License

>  Copyright Hstan
>
>  Licensed under the Apache License, Version 2.0 (the "License");
>
>  you may not use this file except in compliance with the License.
>
>  You may obtain a copy of the License at
>
>        http://www.apache.org/licenses/LICENSE-2.0
>
>  Unless required by applicable law or agreed to in writing, software
>
>  distributed under the License is distributed on an "AS IS" BASIS,
>
>  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>
>  See the License for the specific language governing permissions and
>
>  limitations under the License


text:
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/network/sct_auditing/sct_auditing_cache.h"

#include "base/memory/scoped_refptr.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
#include "net/base/hash_value.h"
#include "net/base/host_port_pair.h"
#include "net/cert/ct_serialization.h"
#include "net/cert/sct_status_flags.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/proto/sct_audit_report.pb.h"
#include "services/network/sct_auditing/sct_auditing_handler.h"
#include "services/network/sct_auditing/sct_auditing_reporter.h"
#include "services/network/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/utility/utility.h"
#include "third_party/boringssl/src/include/openssl/pool.h"
#include "third_party/boringssl/src/include/openssl/sha.h"

namespace network {

namespace {

class SCTAuditingCacheTest : public testing::Test {
 public:
  SCTAuditingCacheTest() = default;
  ~SCTAuditingCacheTest() override = default;

  SCTAuditingCacheTest(const SCTAuditingCacheTest&) = delete;
  SCTAuditingCacheTest& operator=(const SCTAuditingCacheTest&) = delete;

  void SetUp() override {
    chain_ =
        net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
    ASSERT_TRUE(chain_.get());
  }

 protected:
  // Initializes the configuration for the SCTAuditingCache to defaults.
  void InitSCTAuditing(SCTAuditingCache* cache, double sampling_rate = 1.0) {
    mojom::SCTAuditingConfigurationPtr configuration(absl::in_place);
    configuration->sampling_rate = sampling_rate;
    configuration->traffic_annotation =
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
    cache->Configure(std::move(configuration));
  }

  // Use MOCK_TIME so tests (particularly those involving retry and backoff) can
  // use TaskEnvironment::FastForwardUntilNoTasksRemain() and FastForwardBy().
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::MainThreadType::IO,
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  scoped_refptr<net::X509Certificate> chain_;

  std::unique_ptr<base::RunLoop> run_loop_;
  size_t num_requests_seen_ = 0;
};

// Constructs a net::SignedCertificateTimestampAndStatus with the given
// information and appends it to |sct_list|.
void MakeTestSCTAndStatus(
    net::ct::SignedCertificateTimestamp::Origin origin,
    const std::string& extensions,
    const std::string& signature_data,
    const base::Time& timestamp,
    net::ct::SCTVerifyStatus status,
    net::SignedCertificateTimestampAndStatusList* sct_list) {
  scoped_refptr<net::ct::SignedCertificateTimestamp> sct(
      new net::ct::SignedCertificateTimestamp());
  sct->version = net::ct::SignedCertificateTimestamp::V1;

  // The particular value of the log ID doesn't matter; it just has to be the
  // correct length.
  const unsigned char kTestLogId[] = {
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
  const std::string log_id(reinterpret_cast<const char*>(kTestLogId),
                           sizeof(kTestLogId));
  sct->log_id = log_id;

  sct->extensions = extensions;
  sct->timestamp = timestamp;
  sct->signature.signature_data = signature_data;
  sct->origin = origin;
  sct_list->push_back(net::SignedCertificateTimestampAndStatus(sct, status));
}

// Computes the cache key from a list of SCTs. This matches how SCTAuditingCache
// computes cache keys internally.
net::HashValue ComputeCacheKey(
    net::SignedCertificateTimestampAndStatusList sct_list) {
  net::HashValue cache_key(net::HASH_VALUE_SHA256);
  SHA256_CTX ctx;
  SHA256_Init(&ctx);
  std::string encoded_sct;
  net::ct::EncodeSignedCertificateTimestamp(sct_list.at(0).sct, &encoded_sct);
  SHA256_Update(&ctx, encoded_sct.data(), encoded_sct.size());
  SHA256_Final(reinterpret_cast<uint8_t*>(cache_key.data()), &ctx);
  return cache_key;
}

}  // namespace

// Test that inserting and retrieving a report works.
TEST_F(SCTAuditingCacheTest, InsertAndRetrieveReport) {
  SCTAuditingCache cache(10);
  InitSCTAuditing(&cache);

  const net::HostPortPair host_port_pair("example.com", 443);
  net::SignedCertificateTimestampAndStatusList sct_list;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions1", "signature1", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list);
  EXPECT_TRUE(
      cache.MaybeGenerateReportEntry(host_port_pair, chain_.get(), sct_list));
  EXPECT_EQ(1u, cache.GetCacheForTesting()->size());
}

// Tests that old entries are evicted when the dedupe cache is full.
TEST_F(SCTAuditingCacheTest, EvictLRUAfterCacheFull) {
  SCTAuditingCache cache(2);
  InitSCTAuditing(&cache);

  const net::HostPortPair host_port_pair1("example1.com", 443);
  const net::HostPortPair host_port_pair2("example2.com", 443);
  const net::HostPortPair host_port_pair3("example3.com", 443);

  net::HashValue first_key(net::HASH_VALUE_SHA256);
  {
    net::SignedCertificateTimestampAndStatusList sct_list;
    MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                         "extensions1", "signature1", base::Time::Now(),
                         net::ct::SCT_STATUS_OK, &sct_list);
    ASSERT_TRUE(cache.MaybeGenerateReportEntry(host_port_pair1, chain_.get(),
                                               sct_list));
    ASSERT_EQ(1u, cache.GetCacheForTesting()->size());

    // Save the initial cache key for later inspection.
    first_key = ComputeCacheKey(sct_list);
  }

  {
    net::SignedCertificateTimestampAndStatusList sct_list;
    MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                         "extensions1", "signature2", base::Time::Now(),
                         net::ct::SCT_STATUS_OK, &sct_list);
    ASSERT_TRUE(cache.MaybeGenerateReportEntry(host_port_pair2, chain_.get(),
                                               sct_list));
    ASSERT_EQ(2u, cache.GetCacheForTesting()->size());
  }

  // Cache is now full. Add another entry to trigger eviction.
  {
    net::SignedCertificateTimestampAndStatusList sct_list;
    MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                         "extensions1", "signature3", base::Time::Now(),
                         net::ct::SCT_STATUS_OK, &sct_list);
    ASSERT_TRUE(cache.MaybeGenerateReportEntry(host_port_pair3, chain_.get(),
                                               sct_list));
    ASSERT_EQ(2u, cache.GetCacheForTesting()->size());
    // The key for the first entry should not be in the cache anymore.
    EXPECT_EQ(cache.GetCacheForTesting()->Get(first_key),
              cache.GetCacheForTesting()->end());
  }
}

// Tests that a new report gets dropped if the same SCTs are already in the
// cache.
TEST_F(SCTAuditingCacheTest, ReportWithSameSCTsDeduplicated) {
  SCTAuditingCache cache(10);
  InitSCTAuditing(&cache);

  const net::HostPortPair host_port_pair1("example.com", 443);
  const net::HostPortPair host_port_pair2("example.org", 443);

  net::SignedCertificateTimestampAndStatusList sct_list;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions1", "signature1", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list);
  ASSERT_TRUE(
      cache.MaybeGenerateReportEntry(host_port_pair1, chain_.get(), sct_list));

  ASSERT_EQ(1u, cache.GetCacheForTesting()->size());

  // Generating a report entry for the same SCTs won't cause a new report to be
  // generated (even if the connection origin is different).
  ASSERT_FALSE(
      cache.MaybeGenerateReportEntry(host_port_pair2, chain_.get(), sct_list));
  EXPECT_EQ(1u, cache.GetCacheForTesting()->size());
}

// When a report gets deduplicated, the existing entry should have its last-seen
// time bumped up.
TEST_F(SCTAuditingCacheTest, DeduplicationUpdatesLastSeenTime) {
  SCTAuditingCache cache(2);
  InitSCTAuditing(&cache);

  const net::HostPortPair host_port_pair1("example1.com", 443);
  const net::HostPortPair host_port_pair2("example2.com", 443);
  const net::HostPortPair host_port_pair3("example3.com", 443);

  // Fill the cache with two reports.
  net::SignedCertificateTimestampAndStatusList sct_list1;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions1", "signature1", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list1);
  cache.MaybeGenerateReportEntry(host_port_pair1, chain_.get(), sct_list1);

  net::SignedCertificateTimestampAndStatusList sct_list2;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions2", "signature2", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list2);
  cache.MaybeGenerateReportEntry(host_port_pair2, chain_.get(), sct_list2);

  EXPECT_EQ(2u, cache.GetCacheForTesting()->size());

  // Try to enqueue the report for "example1.com" again. It should be deduped.
  cache.MaybeGenerateReportEntry(host_port_pair1, chain_.get(), sct_list1);
  EXPECT_EQ(2u, cache.GetCacheForTesting()->size());

  // If we enqueue a new report causing the cache size limit to be exceeded,
  // "example1.com" should be the most-recent due to getting updated during
  // deduping, and "example2.com" should get evicted instead.
  net::SignedCertificateTimestampAndStatusList sct_list3;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions3", "signature3", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list3);
  cache.MaybeGenerateReportEntry(host_port_pair3, chain_.get(), sct_list3);

  EXPECT_EQ(2u, cache.GetCacheForTesting()->size());

  net::HashValue evicted_key = ComputeCacheKey(sct_list2);
  EXPECT_EQ(cache.GetCacheForTesting()->Get(evicted_key),
            cache.GetCacheForTesting()->end());
}

TEST_F(SCTAuditingCacheTest, ReportsCachedButNotSentWhenSamplingIsZero) {
  SCTAuditingCache cache(2);
  InitSCTAuditing(&cache, /*sampling_rate=*/0);

  // Generate a report.
  const net::HostPortPair host_port_pair("example.com", 443);
  net::SignedCertificateTimestampAndStatusList sct_list;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions", "signature", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list);
  // Check that no report is returned.
  EXPECT_FALSE(
      cache.MaybeGenerateReportEntry(host_port_pair, chain_.get(), sct_list));

  // Check that there is one entry in the cache.
  EXPECT_EQ(1u, cache.GetCacheForTesting()->size());
}

// Tests that cache size high water mark metrics are correctly logged.
TEST_F(SCTAuditingCacheTest, HighWaterMarkMetrics) {
  base::HistogramTester histograms;
  SCTAuditingCache cache(2);
  InitSCTAuditing(&cache);

  const net::HostPortPair host_port_pair1("example1.com", 443);
  const net::HostPortPair host_port_pair2("example2.com", 443);

  // Fill the cache with two reports.
  net::SignedCertificateTimestampAndStatusList sct_list1;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions1", "signature1", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list1);
  EXPECT_TRUE(
      cache.MaybeGenerateReportEntry(host_port_pair1, chain_.get(), sct_list1));

  net::SignedCertificateTimestampAndStatusList sct_list2;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions2", "signature2", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list2);
  EXPECT_TRUE(
      cache.MaybeGenerateReportEntry(host_port_pair2, chain_.get(), sct_list2));

  EXPECT_EQ(2u, cache.GetCacheForTesting()->size());

  // High-water-mark metrics are recorded once an hour.
  task_environment_.FastForwardBy(base::Hours(1));

  // The bucket for a HWM of 2 should have a single sample.
  histograms.ExpectUniqueSample("Security.SCTAuditing.OptIn.DedupeCacheHWM", 2,
                                1);
}

// Tests that generating a report causes its size to be logged. Trying to log
// the same SCTs a second time will cause the deduplication to be logged instead
// of logging the report size a second time.
TEST_F(SCTAuditingCacheTest, ReportSizeMetrics) {
  SCTAuditingCache cache(10);
  InitSCTAuditing(&cache);

  base::HistogramTester histograms;

  const net::HostPortPair host_port_pair("example.com", 443);
  net::SignedCertificateTimestampAndStatusList sct_list;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions", "signature", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list);
  absl::optional<SCTAuditingCache::ReportEntry> entry =
      cache.MaybeGenerateReportEntry(host_port_pair, chain_.get(), sct_list);
  ASSERT_TRUE(entry);

  // Get the size of the pending report and test that it is correctly logged.
  size_t report_size = entry->report->ByteSizeLong();
  ASSERT_GT(report_size, 0u);
  histograms.ExpectUniqueSample("Security.SCTAuditing.OptIn.ReportSize",
                                report_size, 1);

  // Retry enqueueing the same report which will be deduplicated.
  EXPECT_FALSE(
      cache.MaybeGenerateReportEntry(host_port_pair, chain_.get(), sct_list));

  histograms.ExpectTotalCount("Security.SCTAuditing.OptIn.ReportSampled", 1);
  histograms.ExpectTotalCount("Security.SCTAuditing.OptIn.ReportSize", 1);
  histograms.ExpectBucketCount("Security.SCTAuditing.OptIn.ReportDeduplicated",
                               true, 1);
}

// Test that metrics for when reports are dropped due to sampling are correctly
// logged.
TEST_F(SCTAuditingCacheTest, ReportSampleDroppedMetrics) {
  base::HistogramTester histograms;

  SCTAuditingCache cache(10);
  InitSCTAuditing(&cache, /*sampling_rate=*/0);

  const net::HostPortPair host_port_pair("example.com", 443);
  net::SignedCertificateTimestampAndStatusList sct_list;
  MakeTestSCTAndStatus(net::ct::SignedCertificateTimestamp::SCT_EMBEDDED,
                       "extensions", "signature", base::Time::Now(),
                       net::ct::SCT_STATUS_OK, &sct_list);
  EXPECT_FALSE(
      cache.MaybeGenerateReportEntry(host_port_pair, chain_.get(), sct_list));

  histograms.ExpectUniqueSample("Security.SCTAuditing.OptIn.ReportSampled",
                                false, 1);
  histograms.ExpectTotalCount("Security.SCTAuditing.OptIn.ReportSize", 0);
  histograms.ExpectBucketCount("Security.SCTAuditing.OptIn.ReportDeduplicated",
                               false, 1);
}

}  // namespace network


text:
package vis

// Access rights stated below
var (
	Private = 0
	Public  = 1
)


text:
"""Tests for remote eager execution."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import functools
import os

import numpy as np

from tensorflow.contrib.eager.python import parameter_server
from tensorflow.core.protobuf import cluster_pb2
from tensorflow.core.protobuf import tensorflow_server_pb2
from tensorflow.python import pywrap_tensorflow
from tensorflow.python.eager import backprop
from tensorflow.python.eager import context
from tensorflow.python.eager import function
from tensorflow.python.eager import remote
from tensorflow.python.framework import ops
from tensorflow.python.framework import test_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import resource_variable_ops
from tensorflow.python.ops import variables
from tensorflow.python.platform import test
from tensorflow.python.training import server_lib

JOB_NAME = "remote_device"
ALT_JOB_NAME = "alt_remote_device"

def run_sync_and_async(f):
  """Execute all test methods in the given class in sync and async modes."""

  @functools.wraps(f)
  def decorator(self, *args, **kwargs):
    with context.execution_mode(context.ASYNC):
      f(self, *args, **kwargs)

    with context.execution_mode(context.SYNC):
      f(self, *args, **kwargs)

  return decorator

def get_server_def(job_name, local_server_port, remote_server_addresses,
                   task_index):
  """Returns a server def with a single job + multiple tasks."""
  cluster_def = cluster_pb2.ClusterDef()
  job_def = cluster_def.job.add()
  job_def.name = job_name
  job_def.tasks[0] = "localhost:%d" % local_server_port

  for i, remote_server_address in enumerate(remote_server_addresses, start=1):
    job_def.tasks[i] = remote_server_address

  server_def = tensorflow_server_pb2.ServerDef(
      cluster=cluster_def,
      job_name=job_name,
      task_index=task_index,
      protocol="grpc")

  return server_def

class RemoteExecutionTest(test.TestCase):

  def __init__(self, methodName="runTest"):  # pylint: disable=invalid-name
    super(RemoteExecutionTest, self).__init__(methodName)
    self._cached_server1 = server_lib.Server.create_local_server()
    self._cached_server2 = server_lib.Server.create_local_server()

    os.environ["TF_EAGER_REMOTE_USE_SEND_TENSOR_RPC"] = "1"

    self._cached_server1_target = self._cached_server1.target[len("grpc://"):]
    self._cached_server2_target = self._cached_server2.target[len("grpc://"):]

  def setUp(self):
    # Start the local server.
    local_port = pywrap_tensorflow.TF_PickUnusedPortOrDie()
    context.set_server_def(
        server_def=get_server_def(
            JOB_NAME,
            local_server_port=local_port,
            remote_server_addresses=[
                self._cached_server1_target, self._cached_server2_target
            ],
            task_index=0))

  @test_util.run_gpu_only
  @run_sync_and_async
  def testGpuToRemoteCopy(self):
    with ops.device("gpu:0"):
      x = array_ops.ones([2, 2])
    with ops.device("job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME):
      y = math_ops.matmul(x, x)

    np.testing.assert_array_equal([[2, 2], [2, 2]], y.numpy())

  @run_sync_and_async
  def testDefunMatmul(self):
    """Basic remote eager execution with defun."""

    mm_defun = function.defun(math_ops.matmul)
    with ops.device("job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME):
      x1 = array_ops.ones([2, 2])
    with ops.device("job:%s/replica:0/task:2/device:CPU:0" % JOB_NAME):
      x2 = array_ops.ones([2, 2])
      y = mm_defun(x1, x2)
    np.testing.assert_array_equal([[2, 2], [2, 2]], y.numpy())

  @run_sync_and_async
  def testSimpleMatmul(self):
    """Basic remote eager execution."""

    with ops.device("job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME):
      x1 = array_ops.ones([2, 2])
    with ops.device("job:%s/replica:0/task:2/device:CPU:0" % JOB_NAME):
      x2 = array_ops.ones([2, 2])
      y = math_ops.matmul(x1, x2)
    np.testing.assert_array_equal([[2, 2], [2, 2]], y.numpy())

  def testParameterServer(self):
    with parameter_server.parameter_server_scope(
        is_chief=True, ps_job_name=JOB_NAME, num_ps_tasks=3):
      v0 = variables.Variable([1.0], name="v0")
      v1 = variables.Variable([2.0], name="v1")
    v0.assign(v0 * v1)
    self.assertAllEqual(v0.read_value(), [2.0])
    self.assertAllEqual(v0.device,
                        "/job:%s/replica:0/task:0/device:CPU:0" % JOB_NAME)
    self.assertAllEqual(v1.device,
                        "/job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME)
    v1.assign_add(v1)
    # Simulate aliasing another variable of the same name as v1
    with ops.device("/job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME):
      v1_replica = parameter_server.SharedVariable(
          [1.0], name="v1", initialize=False)
    self.assertAllEqual(v1_replica.read_value(), [4.0])

  @run_sync_and_async
  def testSimpleWeightRead(self):
    """Basic remote eager weight read."""

    with ops.device("job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME):
      w = resource_variable_ops.ResourceVariable([[2.0]])
      loss = w * w
    np.testing.assert_array_equal([[4.0]], loss.numpy())

  @run_sync_and_async
  def testTapeWeightRead(self):
    """Remote eager weight read in a tape."""

    with ops.device("job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME):
      w = resource_variable_ops.ResourceVariable([[3.0]])
      with backprop.GradientTape() as tape:
        loss = w * w

      grad = tape.gradient(loss, w)
    np.testing.assert_array_equal([[9.0]], loss.numpy())
    np.testing.assert_array_equal([[6.0]], grad.numpy())

  @run_sync_and_async
  def testServerDefChanged(self):
    """Update server def, and run ops on new cluster."""
    context.set_server_def(
        server_def=get_server_def(
            ALT_JOB_NAME,
            local_server_port=0,
            remote_server_addresses=[
                self._cached_server1_target, self._cached_server2_target
            ],
            task_index=0))

    with ops.device("job:%s/replica:0/task:1/device:CPU:0" % ALT_JOB_NAME):
      x1 = array_ops.ones([2, 2])
    y = math_ops.matmul(x1, x1)
    np.testing.assert_array_equal([[2, 2], [2, 2]], y.numpy())

    # Set the server def back to JOB_NAME
    context.set_server_def(
        server_def=get_server_def(
            JOB_NAME,
            local_server_port=0,
            remote_server_addresses=[
                self._cached_server1_target, self._cached_server2_target
            ],
            task_index=0))

    with ops.device("job:%s/replica:0/task:1/device:CPU:0" % JOB_NAME):
      x1 = array_ops.ones([2, 2])
    y = math_ops.matmul(x1, x1)
    np.testing.assert_array_equal([[2, 2], [2, 2]], y.numpy())

  @run_sync_and_async
  def testConnectToRemoteServer(self):
    """Basic server connection."""
    remote.connect_to_remote_host(self._cached_server1_target)

    with ops.device("job:worker/replica:0/task:0/device:CPU:0"):
      x1 = array_ops.ones([2, 2])
      x2 = array_ops.ones([2, 2])
      y = math_ops.matmul(x1, x2)
    np.testing.assert_array_equal([[2, 2], [2, 2]], y.numpy())

  @run_sync_and_async
  def testContextDeviceUpdated(self):
    """Tests that the context device is correctly updated."""

    with ops.device("cpu:0"):
      x1 = array_ops.ones([2, 2])
      x2 = array_ops.ones([2, 2])
      y = math_ops.matmul(x1, x2)
    np.testing.assert_array_equal([[2, 2], [2, 2]], y.numpy())

    # `y` is placed on the local CPU as expected.
    self.assertEqual(y.device,
                     "/job:%s/replica:0/task:0/device:CPU:0" % JOB_NAME)

  @test_util.run_gpu_only
  @run_sync_and_async
  def testGPUToRemoteCopy(self):
    """Tests that the remote copy happens satisfactorily."""
    x1 = array_ops.ones([2, 2]).gpu()

    with ops.device("/job:remote_device/replica:0/task:1/device:CPU:0"):
      x2 = x1._copy()  # pylint: disable=protected-access

    np.testing.assert_array_equal(x1.numpy(), x2.numpy())

if __name__ == "__main__":
  ops.enable_eager_execution()
  test.main()