示例#1
0
 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)
示例#2
0
 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)
示例#3
0
    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')
示例#4
0
    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)
示例#5
0
    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')