def testMeasurementCreate(self): # Test that a Measurement can be created. measurement = model.Measurement(key_name='mymeasurement') measurement.type = 'sometype' measurement.put() self.assertEqual(1, len(model.Measurement().all().fetch(2))) result = model.Measurement().get_by_key_name('mymeasurement') self.assertEqual(result.type, 'sometype') self.assertEqual(result.GetTaskID(), None)
def testMeasurementCreateWithTask(self): # Test that a Measurement can be created with a corresponding Task. task = model.Task() task.tag = 'faketag' task.put() task_id = task.key().id() measurement = model.Measurement(key_name='mymeasurement') measurement.type = 'sometype' measurement.task = task measurement.put() self.assertEqual(1, len(model.Measurement().all().fetch(2))) result = model.Measurement().get_by_key_name('mymeasurement') self.assertEqual(result.type, 'sometype') self.assertEqual(result.task.tag, 'faketag') self.assertEqual(result.GetTaskID(), task_id)
def PostMeasurement(self, **unused_args): """Handler used to post a measurement from a device.""" if self.request.method.lower() != 'post': raise error.BadRequest('Not a POST request.') try: measurement_list = json.loads(self.request.body) logging.info('PostMeasurement: Got %d measurements to write', len(measurement_list)) for measurement_dict in measurement_list: device_info = model.DeviceInfo.get_or_insert( measurement_dict['device_id']) # Write new device properties, if present if 'properties' in measurement_dict: device_properties = model.DeviceProperties( parent=device_info) device_properties.device_info = device_info properties_dict = measurement_dict['properties'] # TODO(wenjiezeng): Sanitize input that contains bad fields util.ConvertFromDict(device_properties, properties_dict) # Don't want the embedded properties in the Measurement object del measurement_dict['properties'] else: # Get most recent device properties device_properties = device.GetLatestDeviceProperties( device_info, create_new_if_none=True) device_properties.put() measurement = model.Measurement(parent=device_info) util.ConvertFromDict(measurement, measurement_dict) measurement.device_properties = device_properties measurement.put() except Exception, e: logging.exception('Got exception posting measurements')
def testMeasurementExpando(self): # Test that Measurement Expando functions work as expected. measurement = model.Measurement() measurement.mparam_foo = 'somevalue1' measurement.mparam_bar = 'somevalue2' measurement.mval_baz = 'somevalue3' measurement.put() self.assertEqual(measurement.GetParam('foo'), 'somevalue1') self.assertEqual(measurement.GetParam('bar'), 'somevalue2') self.assertEqual(measurement.GetValue('baz'), 'somevalue3') params = measurement.Params() self.assertEqual(params['foo'], 'somevalue1') self.assertEqual(params['bar'], 'somevalue2') self.assertEqual(len(params), 2) params = measurement.Values() self.assertEqual(params['baz'], 'somevalue3') self.assertEqual(len(params), 1)
def PostMeasurement(self, **unused_args): """Handler used to post a measurement from a device.""" if self.request.method.lower() != 'post': raise error.BadRequest('Not a POST request.') try: measurement_list = json.loads(self.request.body) logging.info('PostMeasurement: Got %d measurements to write', len(measurement_list)) for measurement_dict in measurement_list: # Change device id such that it is anonymized, but preserve the TAC. measurement_dict['tac'] = util.GetTypeAllocationCode( measurement_dict['device_id']) measurement_dict['device_id'] = util.HashDeviceId( measurement_dict['device_id']) device_info = model.DeviceInfo.get_or_insert( measurement_dict['device_id']) # Write new device properties, if present if 'properties' in measurement_dict: device_properties = model.DeviceProperties( parent=device_info) device_properties.device_info = device_info properties_dict = measurement_dict['properties'] # TODO(wenjiezeng): Sanitize input that contains bad fields util.ConvertFromDict(device_properties, properties_dict) # Don't want the embedded properties in the Measurement object del measurement_dict['properties'] else: # Get most recent device properties device_properties = device.GetLatestDeviceProperties( device_info, create_new_if_none=True) device_properties.put() if 'context_results' in measurement_dict: if 'values' in measurement_dict: measurement_dict['values']['context_results'] = str( measurement_dict['context_results']) del measurement_dict['context_results'] measurement = model.Measurement(parent=device_info) util.ConvertFromDict(measurement, measurement_dict) measurement.device_properties = device_properties measurement.put() #extracting the IPs from the ping measurement results to the main CDN domain if measurement.success == True and measurement.type == "ping": if ('target' in measurement_dict['parameters'] ) and measurement_dict['parameters'][ 'target'] in CDN_TARGETS: ipdata = model.CDNIpData() target_ip = measurement_dict['values'][ 'target_ip'].replace('"', '') if ':' in target_ip: continue prefix = target_ip[:target_ip.rfind('.') + 1].replace( '"', '') q = model.CDNIpData.all() q.filter("prefix =", prefix) record = q.get() if record != None: #updating timestamp (expiration time) record.put() else: #inserting the new IP record to the data store record = model.CDNIpData() record.ip = target_ip record.prefix = prefix record.cdn_domain = measurement_dict['parameters'][ 'target'] record.put() nettype = properties_dict['network_type'].lower().replace( " ", "") # map from deviceid to the list of high ping rtts low_performance_devices = {} if measurement.success == True and measurement.type == "ping" and nettype != "wifi": if ('target' in measurement_dict['parameters'] ) and measurement_dict['parameters'][ 'target'] in CDN_TARGETS: mean_rtt = float( measurement_dict['values']['mean_rtt_ms']) if util.IsLowPerformance("ping", nettype, mean_rtt): lat = float( properties_dict['location']['latitude']) lon = float( properties_dict['location']['longitude']) carrier = properties_dict['carrier'].lower( ).replace(" ", "") timestamp = measurement_dict['timestamp'] target = measurement_dict['parameters']['target'] # get all the measurement results from the last 24 hours q = model.Measurement.all() q.filter("type =", "ping") q.filter("success =", True) q.filter("timestamp >", datetime.now() - timedelta(hours=24)) for record in q.run(): record_nettype = record.device_properties.network_type.lower( ).replace(" ", "") if record.GetParam( 'target' ) == target and record_nettype != "wifi": record_rtt = record.GetValue('mean_rtt_ms') if util.IsLowPerformance( "ping", record_nettype, record_rtt): record_location = record.device_properties.location record_carrier = record.device_properties.carrier distance = -1 if record_location.lat != 0.0 and record_location.lon != 0.0: distance = util.Distance( lat, lon, record_location.lat, record_location.lon) if ( distance != -1 and distance < 2000 ) or record_carrier == carrier: #distance in km if not (record.device_properties. device_info.id in low_performance_devices): low_performance_devices[ record.device_properties. device_info.id] = [] low_performance_devices[ record.device_properties. device_info.id].append( record_rtt) #the number of devices should be at-least two if len(low_performance_devices.keys()) >= 2: query = model.Task.all() query.filter( "tag = ", "DIAG_TARGET" ) #specific ping tasks for target diagnosis, for example, ping to www.facebook.com for diag_target_task in query.run(): filter = diag_target_task.filter if not (str(device_info.id) in filter): if filter == None: diag_target_task.filter = "id = " + str( device_info.id) else: diag_target_task.filter = diag_target_task.filter + " OR id = " + str( device_info.id) diag_target_task.put() except Exception, e: logging.exception('Got exception posting measurements')