blob: 9e9d1d39df0787740485c60c9665303fd876f0be [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package assistant
import (
"context"
"fmt"
"time"
"chromiumos/tast/common/perf"
"chromiumos/tast/errors"
"chromiumos/tast/local/assistant"
"chromiumos/tast/local/chrome"
"chromiumos/tast/local/chrome/ash"
"chromiumos/tast/local/chrome/metrics"
"chromiumos/tast/testing"
"chromiumos/tast/testing/hwdep"
)
func init() {
testing.AddTest(&testing.Test{
Func: BetterOnboardingAnimationPerf,
Desc: "Measures animation smoothness of opening assistant with Better Onboarding enabled",
Contacts: []string{"cowmoo@chromium.org", "xiaohuic@chromium.org"},
Attr: []string{"group:crosbolt", "crosbolt_perbuild"},
SoftwareDeps: []string{"chrome", "chrome_internal"},
HardwareDeps: hwdep.D(hwdep.InternalDisplay()),
Pre: chrome.LoggedIn(),
})
}
// BetterOnboardingAnimationPerf measures the performance of opening the Assistant UI
// for the first and second time in a session when Better Onboarding shows. It is believed
// that loading Better Onboarding assets from disk on first launch causes a noticeable
// animation smoothness performance hit.
func BetterOnboardingAnimationPerf(ctx context.Context, s *testing.State) {
cr := s.PreValue().(*chrome.Chrome)
tconn, err := cr.TestAPIConn(ctx)
if err != nil {
s.Fatal("Creating test API connection failed: ", err)
}
if err := assistant.EnableAndWaitForReady(ctx, tconn); err != nil {
s.Fatal("Failed to enable Assistant: ", err)
}
defer func() {
if err := assistant.Cleanup(ctx, s.HasError, cr, tconn); err != nil {
s.Error("Failed to disable Assistant: ", err)
}
}()
if err := assistant.SetBetterOnboardingEnabled(ctx, tconn, true); err != nil {
s.Fatal("Failed to enable better onboarding: ", err)
}
defer func() {
// Send a text query to clear "stickiness" of better onboarding for this
// session. This prevents other Assistant tests from hitting better
// onboarding if they run after this one.
if _, err := assistant.SendTextQuery(ctx, tconn, "test query"); err != nil {
s.Error("Failed to run text query to clear better onboarding: ", err)
}
if err := assistant.SetBetterOnboardingEnabled(ctx, tconn, false); err != nil {
s.Error("Failed to disable better onboarding: ", err)
}
}()
cleanupTabletMode, err := ash.EnsureTabletModeEnabled(ctx, tconn, false)
if err != nil {
s.Fatal("Failed to enable tablet mode: ", err)
}
defer cleanupTabletMode(ctx)
pv := perf.NewValues()
// Open and close Assistant UI for the first time in the session.
if err := recordAssistantToggleSmoothness(ctx, tconn, pv, "first_run"); err != nil {
s.Fatal("Failed to gather first run metrics: ", err)
}
// Open and close Assistant UI again for comparison.
if err := recordAssistantToggleSmoothness(ctx, tconn, pv, "second_run"); err != nil {
s.Fatal("Failed to gather second run metrics: ", err)
}
if err := pv.Save(s.OutDir()); err != nil {
s.Error("Failed saving perf data: ", err)
}
}
func recordAssistantToggleSmoothness(ctx context.Context, tconn *chrome.TestConn, pv *perf.Values, postfix string) error {
// Open the Assistant UI and gather metrics.
// TODO(b:178409604) add "Apps.StateTransition.AnimationSmoothness.Half.ClamshellMode" when it is recorded properly.
histograms, err := metrics.RunAndWaitAll(
ctx,
tconn,
3*time.Second,
func(ctx context.Context) error {
return toggleAssistantUI(ctx, tconn)
},
"Ash.Assistant.AnimationSmoothness.ResizeAssistantPageView",
"Apps.StateTransition.AnimationSmoothness.Close.ClamshellMode",
)
if err != nil {
return errors.Wrap(err, "failed to collect histogram")
}
for _, h := range histograms {
mean, err := h.Mean()
if err != nil {
return errors.Wrapf(err, "failed to get mean for histogram %s", h.Name)
}
pv.Set(perf.Metric{
Name: fmt.Sprintf("%s.%s", h.Name, postfix),
Unit: "percent",
Direction: perf.BiggerIsBetter,
}, mean)
}
return nil
}
// toggleAssistantUI opens and then closes the Assistant UI via hotkey. Launcher
// opens to Half state, rather than Peeking, because Better Onboarding requires extra space.
func toggleAssistantUI(ctx context.Context, tconn *chrome.TestConn) error {
// Closed->Peeking.
if err := assistant.ToggleUIWithHotkey(ctx, tconn); err != nil {
return errors.Wrap(err, "failed to open the embedded UI")
}
if err := ash.WaitForLauncherState(ctx, tconn, ash.Half); err != nil {
return errors.Wrap(err, "failed to switch the state to 'Half'")
}
// Peeking->Closed.
if err := assistant.ToggleUIWithHotkey(ctx, tconn); err != nil {
return errors.Wrap(err, "failed to close the embedded UI")
}
if err := ash.WaitForLauncherState(ctx, tconn, ash.Closed); err != nil {
return errors.Wrap(err, "failed to switch the state to 'Closed'")
}
return nil
}