예제 #1
0
def consumption_lower_than_app(sample, app, use_case=None):
    """Test that a given sample spends less energy than a known app.

    Args:
        sample (list of Measurement): sample of measurements
        app (string): identifier/package of the app to be compared
        use_case (string): select only data from a given use case
    """
    baseline_measurements = Measurement.get_all_entries_of_app(app, use_case)
    baseline_consumption = Measurement.mean_energy_consumption(
        baseline_measurements)
    consumption_below(sample, baseline_consumption)
예제 #2
0
    def profile(self,
                power_meter=default_power_meter,
                verbose=True,
                count=30,
                retry_limit=1,
                save_to_csv=None):
        """Run a batch of measurements.

        Args:
            power_meter     Power meter to use in measurements.
            verbose         Log activiy (default=True).
            count           Run experiment several times (default=30).
            retry_limit     Number of times to retry on error.
            save_to_csv     File name to store measurement.
        Returns: Set of measurements

        """
        results = []
        for i in range(count):
            result = self.run(power_meter=power_meter, retry_limit=retry_limit)
            if result:
                results.append(result)
                if save_to_csv:
                    result.save_to_csv(save_to_csv)
            else:
                click.secho("Error in execution {} of {}. Skipping.".format(
                    i, self.name),
                            fg="red")
        if verbose and results:
            click.secho("Energy consumption results for {}: "
                        "{:.3f} Joules (s = {:.3f}).\n"
                        "It took {:.1f} seconds (s = {:.1f}).".format(
                            self.app_pkg, *Measurement.describe(results)),
                        fg='green')
        return results
예제 #3
0
 def test_get_unique_use_cases(self):
     measurements = []
     for _ in range(10):
         measurements.append(create_measurement(use_case="one"))
         measurements.append(create_measurement(use_case="two"))
         measurements.append(create_measurement(use_case="three"))
     self.assertEqual(Measurement.get_unique_use_cases(measurements),
                      {"one", "two", "three"})
예제 #4
0
def consumption_below(sample, energy_consumption_baseline):
    """Test for energy consumption lower than a given value in Joules (avg).

    Args:
        sample (list of Measurement): sample of measurements
        energy_consumption (number): baseline energy consumption in Joules.
    """
    energy_consumption_mean = Measurement.mean_energy_consumption(sample)
    assert energy_consumption_mean < energy_consumption_baseline
예제 #5
0
 def test_get_unique_apps(self):
     for _ in range(10):
         measurement = create_measurement(app_pkg="com.test.one")
         measurement.persist()
         measurement = create_measurement(app_pkg="com.test.two")
         measurement.persist()
         measurement = create_measurement(app_pkg="com.test.three")
         measurement.persist()
     self.assertEqual(set(Measurement.get_unique_apps()),
                      {"com.test.one", "com.test.two", "com.test.three"})
예제 #6
0
 def test_get_energy_ranking(self):
     sample = (create_random_sample(10, 1, app_pkg="com.app1") +
               create_random_sample(11, 1, app_pkg="com.app2") +
               create_random_sample(12, 1, app_pkg="com.app3") +
               create_random_sample(13, 1, app_pkg="com.app4") +
               create_random_sample(14, 1, app_pkg="com.app5") +
               create_random_sample(15, 1, app_pkg="com.app6"))
     for measurement in sample:
         measurement.persist()
     ranking = Measurement.get_energy_ranking()
     self.assertEqual(list(ranking.keys()), [
         "com.app1",
         "com.app2",
         "com.app3",
         "com.app4",
         "com.app5",
         "com.app6",
     ])
     compare_sample = create_random_sample(12.5, 0.5, app_pkg="com.app7")
     self.assertEqual(Measurement.get_position_in_ranking(compare_sample),
                      (4, 6))
예제 #7
0
 def test_describe_app_use_case(self):
     for i in range(10):
         measurement = create_measurement(use_case="login",
                                          duration=i,
                                          energy_consumption=i * 2)
         measurement.persist()
     real_stats = Measurement.describe_app_use_case(measurement.app_pkg,
                                                    measurement.use_case)
     expected_stats = (9, 5.745, 4.5, 2.872)
     # pairwise assertion:
     for (first, second) in zip(real_stats, expected_stats):
         self.assertAlmostEqual(first, second, places=3)
예제 #8
0
파일: models.py 프로젝트: TQRG/physalia
def create_measurement(use_case='login',
                       app_pkg='com.package',
                       duration=2,
                       energy_consumption=30):
    """Fake data for measurement."""
    return Measurement(
        1485634263.096069,  # timestamp
        use_case,           # use_case
        app_pkg,            # application package
        '1.0.0',            # version
        'Nexus 5X',         # device model
        duration,           # duration
        energy_consumption  # energy consumption
    )
예제 #9
0
def top_percentile(sample, nth):
    """Test that a given sample is in the top nth percentile.

    Args:
        sample (list of Measurement): sample of measurements
        nth (number): percentage of the position in which the sample should fit
        app (string): identifier of the application within the sample should be compared
        use_case (string: identifier of the use case used to create the ranking
    """
    position, total = Measurement.get_position_in_ranking(sample)
    percentile_position = float(position) / total * 100
    assert percentile_position <= nth,\
           ("Given sample is not on {:.1f}% top percentile "
            "(Position: {:.1f}%)".format(
                nth,
                percentile_position
            ))
예제 #10
0
    def run(self, power_meter=default_power_meter, retry_limit=1):
        """Measure the routine stored in `_run`.

        Returns:
            Measurement: data collected from experiment

        """
        try:
            self.prepare()
            power_meter.start()
            success = self._run()
            energy_consumption, duration, error_flag = power_meter.stop()
            self.cleanup()
            if error_flag:
                raise PhysaliaExecutionFailed()

            measurement = Measurement(time.time(), self.name, self.app_pkg,
                                      self.app_version,
                                      android_utils.get_device_model(),
                                      duration, energy_consumption,
                                      str(power_meter), success is None
                                      or success, self.notes)

            return measurement
        except KeyboardInterrupt as error:
            raise error
        except BaseException as error:
            click.secho("Measurement {} has failed".format(self.name),
                        fg='red')
            click.secho(str(error), fg='red')
            if retry_limit == 1:
                # click.secho("Waiting 5 minutes for Monsoon to recover...", fg='red')
                # time.sleep(5*60)
                # hack: reinit power_meter
                power_meter.reinit()

            if retry_limit > 0:
                click.secho("Retrying...", fg='yellow')
                return self.run(power_meter, retry_limit - 1)
            printstack = getattr(error, "printStackTrace", None)
            if callable(printstack):
                printstack()
            raise error
예제 #11
0
def tool(results_input, results_output):

    with open(results_input, 'rt') as csv_file:
        csv_reader = csv.reader(csv_file)
        data = []
        for row in csv_reader:
            # row[6] = float(row[6])*1000 # convert to mJ
            data.append(Measurement(*row))
    if not os.path.isdir(results_output):
        os.makedirs(results_output)

    use_case_categories = [
        "find_by_id",
        "find_by_description",
        "find_by_content",
        "tap",
        "long_tap",
        "multi_finger_tap",
        "dragndrop",
        "swipe",
        "pinch_and_spread",
        "back_button",
        "input_text",
    ]
    scores = defaultdict(lambda: 0)
    for use_case_category in use_case_categories:
        click.secho("----------------------------------------", fg="blue")
        click.secho("         {}".format(use_case_category), fg="blue")
        click.secho("----------------------------------------", fg="blue")
        use_case_data = list(
            Measurement.get_entries_with_name_like("-" + use_case_category,
                                                   data))
        unique_use_cases = list(
            Measurement.get_unique_use_cases(use_case_data))
        number_of_frameworks = len(unique_use_cases)
        names_dict = {
            name: name.replace("-" + use_case_category, "")
            for name in unique_use_cases
        }
        groups = [
            list(Measurement.get_entries_with_name(use_case, use_case_data))
            for use_case in unique_use_cases
        ]
        names = [
            name.replace("-" + use_case_category, "")
            for name in unique_use_cases
        ]
        names, groups = zip(*sorted(zip(names, groups)))
        title = use_case_category.title().replace('_', " ")
        violinplot(*groups,
                   save_fig=results_output + "/" + use_case_category + ".pdf",
                   names_dict=names_dict,
                   sort=True,
                   millijoules=True)
        n_loop_iterations = _get_interactions_count(use_case_category)
        # Descriptive statistics
        with open(
                results_output + "/table_description_" + use_case_category +
                ".tex", "w") as file:
            table = describe(*groups,
                             names=names,
                             loop_count=n_loop_iterations,
                             ranking=True,
                             out=file,
                             table_fmt="latex",
                             float_fmt='.3f',
                             mili_joules=True)
        # Update Ranking
        for name, row in zip(names, table):
            scores[name] += (number_of_frameworks -
                             row["Rank"]) / float(number_of_frameworks)
        # Welchs ttest
        with open(
                results_output + "/table_welchsttest_" + use_case_category +
                ".tex", "w") as file:
            pairwise_welchs_ttest(*groups,
                                  names=names,
                                  out=file,
                                  table_fmt='latex')

    # Ranking
    click.secho("\nRanking".format(use_case_category), fg="blue")
    sorted_scores = sorted(scores.items(), key=itemgetter(1), reverse=True)
    with open(results_output + "/table_ranking.tex", "w") as file:
        file.write(
            tabulate(sorted_scores,
                     headers=["Framework", "Score"],
                     tablefmt="latex",
                     floatfmt=".4f"))

    frameworks = [
        "AndroidViewClient",
        "Appium",
        "Calabash",
        "Espresso",
        "Monkeyrunner",
        "PythonUiAutomator",
        "Robotium",
        "UiAutomator",
    ]
    framework_results_dir = results_output + "/frameworks/"
    if not os.path.isdir(framework_results_dir):
        os.makedirs(framework_results_dir)
    for framework in frameworks:
        means = []
        for interaction in use_case_categories:
            use_case = "{}-{}".format(framework, interaction)
            use_case_data = np.array(list(
                Measurement.get_entries_with_name(use_case, data)),
                                     dtype='float')
            if len(use_case_data):
                n_loop_iterations = _get_interactions_count(interaction)
                mean = np.mean(use_case_data) / n_loop_iterations * 1000
            else:
                mean = 0
            bisect.insort(means, (interaction, mean))
        # means = means[::-1]
        figure = plt.figure()
        figure.suptitle(framework)
        X = range(len(means))
        names, Y = zip(*means)
        plt.bar(X, Y)
        axes = figure.gca()
        axes.set_xticks(X)
        axes.set_xticklabels(
            [name.replace("_", " ").title() for name in names],
            rotation='vertical')
        axes.set_ylabel("Energy Consumption (mJ)")

        figure.subplots_adjust(bottom=0.31)

        bar_labels = [y == 0 and "n.a." or format(y, ".2f") for y in Y]
        for x, y, label in zip(X, Y, bar_labels):
            plt.text(x, y, label, ha='center', va='bottom')
        figure.savefig(results_output + "/frameworks/" + framework)