blob: 305e5bfca5db3960be6baafa7d8d7f5842cc5242 [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 fixtures
import (
"context"
"time"
"chromiumos/tast/common/fixture"
"chromiumos/tast/errors"
"chromiumos/tast/local/apps"
"chromiumos/tast/local/chrome"
"chromiumos/tast/local/chrome/ash"
"chromiumos/tast/local/chrome/uiauto/faillog"
"chromiumos/tast/local/input"
"chromiumos/tast/local/uidetection"
vdiApps "chromiumos/tast/local/vdi/apps"
"chromiumos/tast/local/vdi/apps/citrix"
"chromiumos/tast/local/vdi/apps/vmware"
"chromiumos/tast/testing"
)
func init() {
testing.AddFixture(&testing.Fixture{
Name: fixture.CitrixLaunched,
Desc: "Starts DUT using TOA with Citrix application installed, started and logged in",
Contacts: []string{
"kamilszare@google.com",
"cros-engprod-muc@google.com",
},
Impl: &fixtureState{
vdiApplicationToStart: apps.Citrix,
vdiConnector: &citrix.Connector{},
usernameKey: "vdi.ota_citrix_username",
passwordKey: "vdi.ota_citrix_password",
vdiServerKey: "vdi.citrix_url",
vdiUsernameKey: "vdi.citrix_username",
vdiPasswordKey: "vdi.citrix_password",
},
Vars: []string{
"vdi.ota_citrix_username",
"vdi.ota_citrix_password",
"vdi.citrix_url",
"vdi.citrix_username",
"vdi.citrix_password",
"uidetection.key_type",
"uidetection.key",
"uidetection.server",
},
SetUpTimeout: chrome.EnrollmentAndLoginTimeout + vdiApps.VDILoginTimeout,
ResetTimeout: chrome.ResetTimeout,
TearDownTimeout: chrome.ResetTimeout,
PostTestTimeout: 15 * time.Second,
Data: citrix.CitrixData,
})
testing.AddFixture(&testing.Fixture{
Name: fixture.VmwareLaunched,
Desc: "Starts DUT using TOA with VMware application installed, started and logged in",
Contacts: []string{
"kamilszare@google.com",
"cros-engprod-muc@google.com",
},
Impl: &fixtureState{
vdiApplicationToStart: apps.VMWare,
vdiConnector: &vmware.Connector{},
usernameKey: "vdi.ota_vmware_username",
passwordKey: "vdi.ota_vmware_password",
vdiServerKey: "vdi.vmware_url",
vdiUsernameKey: "vdi.vmware_username",
vdiPasswordKey: "vdi.vmware_password",
},
Vars: []string{
"vdi.ota_vmware_username",
"vdi.ota_vmware_password",
"vdi.vmware_url",
"vdi.vmware_username",
"vdi.vmware_password",
"uidetection.key_type",
"uidetection.key",
"uidetection.server",
},
SetUpTimeout: chrome.EnrollmentAndLoginTimeout + vdiApps.VDILoginTimeout,
ResetTimeout: chrome.ResetTimeout,
TearDownTimeout: chrome.ResetTimeout,
PostTestTimeout: 15 * time.Second,
Data: vmware.VmwareData,
})
}
type fixtureState struct {
// cr is a connection to an already-started Chrome instance that loads
// policies from FakeDMS.
cr *chrome.Chrome
// vdiApplicationToStart is the VDI application that is launched.
vdiApplicationToStart apps.App
// vdiConnector
vdiConnector vdiApps.VDIInt
// usernameKey is a key to retrieve ota username. That user is configured
// to install and pin dedicated VDI extension.
usernameKey string
// passwordKey is a key to retrieve ota user password.
passwordKey string
// vdiServerKey is a key to retrieve VDI server url.
vdiServerKey string
// vdiUsernameKey is a key to retrieve user name to access VDI app.
vdiUsernameKey string
// vdiPasswordKey is a key to retrieve VDI user password.
vdiPasswordKey string
}
// FixtureData is the type returned by vdi related fixtures. It holds the vdi
// connector providing to common actions that could be performed from the test
// side.
type FixtureData struct {
vdiConnector vdiApps.VDIInt
cr *chrome.Chrome
uidetector *uidetection.Context
inKioskMode bool
}
// VDIConnector returns VDI connector.
func (fd *FixtureData) VDIConnector() vdiApps.VDIInt {
return fd.vdiConnector
}
// Chrome returns Chrome. This adds support for chrome.HasChrome interface.
func (fd *FixtureData) Chrome() *chrome.Chrome {
return fd.cr
}
// UIDetector returns uidetector.
func (fd *FixtureData) UIDetector() *uidetection.Context {
return fd.uidetector
}
// InKioskMode returns boolean indicating whether it is a Kiosk session.
func (fd *FixtureData) InKioskMode() bool {
return fd.inKioskMode
}
// HasVDIConnector is an interface that can be attached to a type that returns
// vdi connector.
type HasVDIConnector interface {
VDIConnector() vdiApps.VDIInt
}
// HasUIDetector is an interface that can be attached to a type that returns
// uidetector.
type HasUIDetector interface {
UIDetector() *uidetection.Context
}
// IsInKioskMode is an interface that can be attached to a type that returns
// whether fixture runs in Kiosk mode.
type IsInKioskMode interface {
InKioskMode() bool
}
func (v *fixtureState) SetUp(ctx context.Context, s *testing.FixtState) interface{} {
username := s.RequiredVar(v.usernameKey)
password := s.RequiredVar(v.passwordKey)
cr, err := chrome.New(ctx,
chrome.GAIALogin(chrome.Creds{User: username, Pass: password}),
chrome.ProdPolicy(),
)
if err != nil {
s.Fatal("Failed to start Chrome: ", err)
}
ok := false
defer func(ctx context.Context) {
if !ok {
if err := cr.Close(ctx); err != nil {
s.Error("Failed to close Chrome: ", err)
}
}
}(ctx)
v.cr = cr
defer faillog.DumpUITreeWithScreenshotOnError(ctx, s.OutDir(), s.HasError, cr, "vdi_fixt_ui_tree")
// Connect to Test API to use it with the UI library.
tconn, err := cr.TestAPIConn(ctx)
if err != nil {
s.Fatal("Failed to create Test API connection: ", err)
}
s.Log("Waiting for apps to be installed before launching")
if err := ash.WaitForChromeAppInstalled(ctx, tconn, v.vdiApplicationToStart.ID, 2*time.Minute); err != nil {
s.Fatal("Failed to wait for app to install: ", err)
}
s.Log("VDI: Starting VDI app")
if err := apps.Launch(ctx, tconn, v.vdiApplicationToStart.ID); err != nil {
s.Fatal("Failed to launch vdi app: ", err)
}
if err := ash.WaitForApp(ctx, tconn, v.vdiApplicationToStart.ID, time.Minute); err != nil {
s.Fatal("The VDI app did not appear in shelf after launch: ", err)
}
detector := uidetection.New(tconn,
s.RequiredVar("uidetection.key_type"),
s.RequiredVar("uidetection.key"),
s.RequiredVar("uidetection.server"),
).WithScreenshotStrategy(uidetection.ImmediateScreenshot)
v.vdiConnector.Init(s, detector)
kb, err := input.Keyboard(ctx)
if err != nil {
s.Fatal("Failed to get a keyboard")
}
defer kb.Close()
if err := v.vdiConnector.Login(
ctx,
kb,
&vdiApps.VDILoginConfig{
Server: s.RequiredVar(v.vdiServerKey),
Username: s.RequiredVar(v.vdiUsernameKey),
Password: s.RequiredVar(v.vdiPasswordKey),
}); err != nil {
s.Fatal("Was not able to login to the VDI application: ", err)
}
if err := v.vdiConnector.WaitForMainScreenVisible(ctx); err != nil {
s.Fatal("Main screen of the VDI application was not visible: ", err)
}
chrome.Lock()
// Mark that everything is okay and defer Chrome.Close() should not happen.
ok = true
return &FixtureData{vdiConnector: v.vdiConnector, cr: cr, uidetector: detector, inKioskMode: false}
}
func (v *fixtureState) TearDown(ctx context.Context, s *testing.FixtState) {
chrome.Unlock()
if v.cr == nil {
s.Fatal("Chrome not yet started")
}
if err := v.cr.Close(ctx); err != nil {
s.Error("Failed to close Chrome connection: ", err)
}
v.cr = nil
}
func (v *fixtureState) Reset(ctx context.Context) error {
// Check the connection to Chrome.
if err := v.cr.Responded(ctx); err != nil {
return errors.Wrap(err, "existing Chrome connection is unusable")
}
// Check the main VDI screen is on.
if err := v.vdiConnector.WaitForMainScreenVisible(ctx); err != nil {
return errors.Wrap(err, "VDi main screen was not present")
}
return nil
}
func (v *fixtureState) PreTest(ctx context.Context, s *testing.FixtTestState) {}
func (v *fixtureState) PostTest(ctx context.Context, s *testing.FixtTestState) {}