diff options
10 files changed, 218 insertions, 63 deletions
diff --git a/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml b/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml index 1e28f6730709..2a254df2302a 100644 --- a/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml +++ b/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml @@ -160,13 +160,6 @@ android:layout_width="1dp" android:layout_height="30dp"/> - <Button - android:id="@+id/display_output" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/display_output" - android:textSize="30dp"/> - <Space android:layout_width="1dp" android:layout_height="30dp"/> diff --git a/cmds/statsd/tools/loadtest/res/raw/loadtest_config b/cmds/statsd/tools/loadtest/res/raw/loadtest_config Binary files differindex 78223674285d..fbce0e870e57 100755 --- a/cmds/statsd/tools/loadtest/res/raw/loadtest_config +++ b/cmds/statsd/tools/loadtest/res/raw/loadtest_config diff --git a/cmds/statsd/tools/loadtest/res/values/strings.xml b/cmds/statsd/tools/loadtest/res/values/strings.xml index cb38298873f0..522337ee656d 100644 --- a/cmds/statsd/tools/loadtest/res/values/strings.xml +++ b/cmds/statsd/tools/loadtest/res/values/strings.xml @@ -20,7 +20,6 @@ <string name="app_name">Statsd Loadtest</string> <string name="bucket_label">bucket size (mins): </string> <string name="burst_label">burst: </string> - <string name="display_output">Show metrics data</string> <string name="placebo">placebo</string> <string name="period_label">logging period (secs): </string> <string name="replication_label">metric replication: </string> diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java index 522dea61d188..a72f72e60faf 100644 --- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java +++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java @@ -15,6 +15,7 @@ */ package com.android.statsd.loadtest; +import android.annotation.Nullable; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; @@ -43,6 +44,10 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; +import com.android.os.StatsLog.ConfigMetricsReport; +import com.android.os.StatsLog.ConfigMetricsReportList; +import com.android.os.StatsLog.StatsdStatsReport; +import java.util.List; /** * Runs a load test for statsd. @@ -191,13 +196,6 @@ public class LoadtestActivity extends Activity { } }); - findViewById(R.id.display_output).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - fetchAndDisplayData(); - } - }); - mAlarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mStatsManager = (StatsManager) getSystemService("stats"); mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); @@ -239,6 +237,48 @@ public class LoadtestActivity extends Activity { super.onDestroy(); } + @Nullable + public StatsdStatsReport getMetadata() { + if (!statsdRunning()) { + return null; + } + if (mStatsManager != null) { + byte[] data = mStatsManager.getMetadata(); + if (data != null) { + StatsdStatsReport report = null; + boolean good = false; + try { + return StatsdStatsReport.parseFrom(data); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + Log.d(TAG, "Bad StatsdStatsReport"); + } + } + } + return null; + } + + @Nullable + public List<ConfigMetricsReport> getData() { + if (!statsdRunning()) { + return null; + } + if (mStatsManager != null) { + byte[] data = mStatsManager.getData(ConfigFactory.CONFIG_NAME); + if (data != null) { + ConfigMetricsReportList reports = null; + try { + reports = ConfigMetricsReportList.parseFrom(data); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + Log.d(TAG, "Invalid data"); + } + if (reports != null) { + return reports.getReportsList(); + } + } + } + return null; + } + private void onPerfAlarm() { if (mPerfData != null) { mPerfData.onAlarm(this); @@ -285,6 +325,9 @@ public class LoadtestActivity extends Activity { // Prepare to push a sequence of atoms to logd. mPusher = new SequencePusher(mBurst, mPlacebo); + // Force a data flush by requesting data. + getData(); + // Create a config and push it to statsd. if (!setConfig(mFactory.getConfig(mReplication, mBucketMins * 60 * 1000, mPlacebo))) { return; @@ -355,42 +398,6 @@ public class LoadtestActivity extends Activity { mPlaceboCheckBox.setEnabled(!mStarted); } - private void fetchAndDisplayData() { - if (!statsdRunning()) { - return; - } - if (mStatsManager != null) { - byte[] data = mStatsManager.getData(ConfigFactory.CONFIG_NAME); - if (data != null) { - displayData(data); - } else { - mReportText.setText("Failed to pull data"); - } - } - } - - private void displayData(byte[] data) { - com.android.os.StatsLog.ConfigMetricsReportList reports = null; - boolean good = false; - if (data != null) { - try { - reports = com.android.os.StatsLog.ConfigMetricsReportList.parseFrom(data); - good = true; - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - // display it in the text view. - } - } - int size = data == null ? 0 : data.length; - StringBuilder sb = new StringBuilder(); - sb.append(good ? "Proto parsing OK!" : "Proto parsing Error!"); - sb.append(" size:").append(size).append("\n"); - - if (good && reports != null) { - DisplayProtoUtils.displayLogReport(sb, reports); - mReportText.setText(sb.toString()); - } - } - private boolean statsdRunning() { if (IStatsManager.Stub.asInterface(ServiceManager.getService("stats")) == null) { Log.d(TAG, "Statsd not running"); diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java index d82a0eadea65..d9513a15208a 100644 --- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java +++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java @@ -39,7 +39,6 @@ public class MemoryDataRecorder extends PerfDataRecorder { @Override public void onAlarm(Context context) { - Log.d(TAG, "GOT ALARM IN MEM"); runDumpsysStats(context, DUMP_FILENAME, "meminfo"); readDumpData(context, DUMP_FILENAME, new MemInfoParser(mStartTimeMillis), mSb); } diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java index 81a84f53b503..555e6dd2d99d 100644 --- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java +++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java @@ -22,7 +22,7 @@ import android.widget.TextView; public abstract class NumericalWatcher implements TextWatcher { - private static final String TAG = "loadtest.NumericalWatcher"; + private static final String TAG = "loadtest.NumericalWatcher"; private final TextView mTextView; private final int mMin; @@ -45,9 +45,6 @@ public abstract class NumericalWatcher implements TextWatcher { } int unsanitized = Integer.parseInt(s); int newValue = sanitize(unsanitized); - - Log.d(TAG, "YOYO " + currentValue + " " + newValue + " " + unsanitized); - if (currentValue != newValue || unsanitized != newValue) { currentValue = newValue; editable.clear(); diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java index 466524756c48..22ba9c5aca39 100644 --- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java +++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java @@ -51,13 +51,17 @@ public class PerfData extends PerfDataRecorder { private final Set<PerfDataRecorder> mRecorders; - public PerfData(Context context, boolean placebo, int replication, long bucketMins, - long periodSecs, int burst) { + public PerfData(LoadtestActivity loadtestActivity, boolean placebo, int replication, + long bucketMins, long periodSecs, int burst) { super(placebo, replication, bucketMins, periodSecs, burst); mRecorders = new HashSet(); mRecorders.add(new BatteryDataRecorder(placebo, replication, bucketMins, periodSecs, burst)); mRecorders.add(new MemoryDataRecorder(placebo, replication, bucketMins, periodSecs, burst)); - mAlarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + mRecorders.add(new StatsdStatsRecorder(loadtestActivity, placebo, replication, bucketMins, + periodSecs, burst)); + mRecorders.add(new ValidationRecorder(loadtestActivity, placebo, replication, bucketMins, + periodSecs, burst)); + mAlarmMgr = (AlarmManager) loadtestActivity.getSystemService(Context.ALARM_SERVICE); } public void onDestroy() { diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java index 15a8e5c87131..5b5ba3766d04 100644 --- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java +++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java @@ -35,12 +35,12 @@ import java.util.Date; public abstract class PerfDataRecorder { private static final String TAG = "loadtest.PerfDataRecorder"; - protected final String mFileSuffix; + protected final String mTimeAsString; protected final String mColumnSuffix; protected PerfDataRecorder(boolean placebo, int replication, long bucketMins, long periodSecs, int burst) { - mFileSuffix = new SimpleDateFormat("YYYY_MM_dd_HH_mm_ss").format(new Date()); + mTimeAsString = new SimpleDateFormat("YYYY_MM_dd_HH_mm_ss").format(new Date()); mColumnSuffix = getColumnSuffix(placebo, replication, bucketMins, periodSecs, burst); } @@ -103,7 +103,7 @@ public abstract class PerfDataRecorder { /** Writes CSV data to a file. */ protected void writeData(Context context, String filePrefix, String columnPrefix, StringBuilder sb) { - File dataFile = new File(getStorageDir(), filePrefix + mFileSuffix + ".csv"); + File dataFile = new File(getStorageDir(), filePrefix + mTimeAsString + ".csv"); FileWriter writer = null; try { @@ -131,7 +131,7 @@ public abstract class PerfDataRecorder { private File getStorageDir() { File file = new File(Environment.getExternalStoragePublicDirectory( - Environment.DIRECTORY_DOCUMENTS), "loadtest"); + Environment.DIRECTORY_DOCUMENTS), "loadtest/" + mTimeAsString); if (!file.mkdirs()) { Log.e(TAG, "Directory not created"); } diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java new file mode 100644 index 000000000000..4ef5dc2f6ca8 --- /dev/null +++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * 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. + */ +package com.android.statsd.loadtest; + +import android.content.Context; +import android.util.Log; +import com.android.os.StatsLog.StatsdStatsReport; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StatsdStatsRecorder extends PerfDataRecorder { + private static final String TAG = "loadtest.StatsdStatsRecorder"; + + private final LoadtestActivity mLoadtestActivity; + + public StatsdStatsRecorder(LoadtestActivity loadtestActivity, boolean placebo, int replication, + long bucketMins, long periodSecs, int burst) { + super(placebo, replication, bucketMins, periodSecs, burst); + mLoadtestActivity = loadtestActivity; + } + + @Override + public void startRecording(Context context) { + // Nothing to do. + } + + @Override + public void onAlarm(Context context) { + // Nothing to do. + } + + @Override + public void stopRecording(Context context) { + StatsdStatsReport metadata = mLoadtestActivity.getMetadata(); + if (metadata != null) { + int numConfigs = metadata.getConfigStatsCount(); + StringBuilder sb = new StringBuilder(); + StatsdStatsReport.ConfigStats configStats = metadata.getConfigStats(numConfigs - 1); + sb.append("metric_count,") + .append(configStats.getMetricCount() + "\n") + .append("condition_count,") + .append(configStats.getConditionCount() + "\n") + .append("matcher_count,") + .append(configStats.getMatcherCount() + "\n"); + writeData(context, "statsdstats_", "", sb); + } + } +} diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ValidationRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ValidationRecorder.java new file mode 100644 index 000000000000..4b614aa19492 --- /dev/null +++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ValidationRecorder.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * 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. + */ +package com.android.statsd.loadtest; + +import android.content.Context; +import android.util.Log; +import com.android.os.StatsLog.ConfigMetricsReport; +import com.android.os.StatsLog.EventMetricData; +import com.android.os.StatsLog.StatsLogReport; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Checks the correctness of the stats. + */ +public class ValidationRecorder extends PerfDataRecorder { + private static final String TAG = "loadtest.ValidationRecorder"; + + private final LoadtestActivity mLoadtestActivity; + + public ValidationRecorder(LoadtestActivity loadtestActivity, boolean placebo, int replication, + long bucketMins, long periodSecs, int burst) { + super(placebo, replication, bucketMins, periodSecs, burst); + mLoadtestActivity = loadtestActivity; + } + + @Override + public void startRecording(Context context) { + // Nothing to do. + } + + @Override + public void onAlarm(Context context) { + validateData(); + } + + @Override + public void stopRecording(Context context) { + validateData(); + } + + private void validateData() { + List<ConfigMetricsReport> reports = mLoadtestActivity.getData(); + if (reports != null) { + Log.d(TAG, "GOT DATA"); + for (ConfigMetricsReport report : reports) { + for (StatsLogReport logReport : report.getMetricsList()) { + if (!logReport.hasMetricName()) { + Log.e(TAG, "Metric missing name."); + continue; + } + String metricName = logReport.getMetricName(); + if (metricName.startsWith("EVENT_BATTERY_LEVEL_CHANGES_WHILE_SCREEN_IS_ON_")) { + validateEventBatteryLevelChangesWhileScreenIsOn(logReport); + continue; + } + if (metricName.startsWith("EVENT_BATTERY_LEVEL_CHANGES_")) { + validateEventBatteryLevelChanges(logReport); + continue; + } + } + } + } + } + + private void validateEventBatteryLevelChanges(StatsLogReport logReport) { + Log.d(TAG, "Validating " + logReport.getMetricName()); + if (logReport.hasEventMetrics()) { + Log.d(TAG, "Num events captured: " + logReport.getEventMetrics().getDataCount()); + for (EventMetricData data : logReport.getEventMetrics().getDataList()) { + Log.d(TAG, " Event : " + data.getAtom()); + } + } else { + Log.d(TAG, "Metric is invalid"); + } + } + + private void validateEventBatteryLevelChangesWhileScreenIsOn(StatsLogReport logReport) { + Log.d(TAG, "Validating " + logReport.getMetricName()); + } +} |