github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/internal/planner/external.go (about) 1 // Copyright 2022 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package planner 6 7 import ( 8 "context" 9 10 "go.chromium.org/tast/core/internal/minidriver" 11 "go.chromium.org/tast/core/internal/minidriver/failfast" 12 "go.chromium.org/tast/core/internal/minidriver/target" 13 "go.chromium.org/tast/core/internal/planner/internal/fixture" 14 "go.chromium.org/tast/core/internal/planner/internal/output" 15 "go.chromium.org/tast/core/internal/protocol" 16 "go.chromium.org/tast/core/internal/testing" 17 18 frameworkprotocol "go.chromium.org/tast/core/framework/protocol" 19 ) 20 21 // ExternalTarget specifies the external target bundle to run. 22 type ExternalTarget struct { 23 Device *protocol.TargetDevice 24 Config *protocol.RunTargetConfig 25 Bundle string 26 } 27 28 // runExternalTests runs tests in primary target. 29 // It sends a request to run the tests to the target bundle, and handles fixture 30 // stack operation requests. 31 // It returns an error If a test could not be run, or an internal framework 32 // error has happened. 33 // It returns unstarted tests. 34 // External tests might not fully finish in case Stack Reset failure. 35 // unstarted tests are returned for allowing retry unstarted tests. 36 func runExternalTests(ctx context.Context, names []string, stack *fixture.CombinedStack, pcfg *Config, out output.Stream) (unstarted []string, err error) { 37 scfg := &target.ServiceConfig{ 38 Devservers: pcfg.ExternalTarget.Config.GetDevservers(), 39 TLWServer: pcfg.Service.GetTlwServer(), 40 41 UseEphemeralDevserver: pcfg.Service.GetUseEphemeralDevservers(), 42 TastDir: pcfg.Service.GetTastDir(), 43 ExtraAllowedBuckets: pcfg.Service.GetExtraAllowedBuckets(), 44 DebuggerPorts: []int{int(pcfg.ExternalTarget.Config.GetDebugPort())}, 45 } 46 tcfg := &target.Config{ 47 SSHConfig: pcfg.ExternalTarget.Device.GetDutConfig().GetSshConfig(), 48 TastVars: pcfg.Features.GetInfra().GetVars(), 49 ServiceConfig: scfg, 50 } 51 cc, err := target.NewConnCache(ctx, tcfg, pcfg.ExternalTarget.Device.GetDutConfig().GetSshConfig().GetConnectionSpec(), pcfg.ExternalTarget.Device.GetDutConfig().GetSshConfig().GetProxyCommand(), "") 52 if err != nil { 53 return nil, err 54 } 55 56 fixtureServer := fixture.NewStackServer(&fixture.StackServerConfig{ 57 Out: out, 58 Stack: stack, 59 OutDir: pcfg.Dirs.GetOutDir(), 60 CloudStorage: testing.NewCloudStorage( 61 pcfg.Service.GetDevservers(), 62 pcfg.Service.GetTlwServer(), 63 pcfg.Service.GetTlwSelfName(), 64 pcfg.Service.GetDutServer(), 65 pcfg.DataFile.GetBuildArtifactsUrl(), 66 pcfg.Service.GetSwarmingTaskID(), 67 pcfg.Service.GetBuildBucketID(), 68 ), 69 RemoteData: pcfg.RemoteData, 70 }) 71 72 counter := failfast.NewCounter(int(pcfg.ExternalTarget.Config.GetMaxTestFailures())) 73 factory := minidriver.NewIntermediateHandlersFactory(pcfg.Dirs.GetOutDir(), counter, out.ExternalEvent, fixtureServer.Handle) 74 75 companionFeatures := make(map[string]*frameworkprotocol.DUTFeatures) 76 companionFeatures[""] = pcfg.Features.GetDut() 77 for key, value := range pcfg.Features.GetCompanionFeatures() { 78 companionFeatures[key] = value 79 } 80 81 cfg := &minidriver.Config{ 82 Retries: int(pcfg.ExternalTarget.Config.GetRetries()), 83 ResDir: pcfg.Dirs.GetOutDir(), 84 Devservers: pcfg.ExternalTarget.Config.GetDevservers(), 85 Target: pcfg.ExternalTarget.Device.GetDutConfig().GetSshConfig().GetConnectionSpec(), 86 LocalDataDir: pcfg.ExternalTarget.Config.GetDirs().GetDataDir(), 87 LocalOutDir: pcfg.ExternalTarget.Config.GetDirs().GetOutDir(), 88 LocalTempDir: pcfg.ExternalTarget.Config.GetDirs().GetTempDir(), 89 LocalBundleDir: pcfg.ExternalTarget.Device.GetBundleDir(), 90 DownloadMode: pcfg.DataFile.GetDownloadMode(), 91 SwarmingTaskID: pcfg.ExternalTarget.Config.GetSwarmingTaskID(), 92 BuildBucketID: pcfg.ExternalTarget.Config.GetBuildBucketID(), 93 94 WaitUntilReady: pcfg.ExternalTarget.Config.GetWaitUntilReady(), 95 CheckTestDeps: pcfg.Features.GetCheckDeps(), 96 TestVars: pcfg.Features.GetInfra().GetVars(), 97 MaybeMissingVars: pcfg.Features.GetInfra().GetMaybeMissingVars(), 98 MsgTimeout: pcfg.ExternalTarget.Config.GetMsgTimeout().AsDuration(), 99 SystemServicesTimeout: pcfg.ExternalTarget.Config.GetSystemServicesTimeout().AsDuration(), 100 WaitUntilReadyTimeout: pcfg.ExternalTarget.Config.GetWaitUntilReadyTimeout().AsDuration(), 101 102 DebuggerPort: int(pcfg.ExternalTarget.Config.GetDebugPort()), 103 Proxy: pcfg.ExternalTarget.Config.GetProxy(), 104 105 DUTFeatures: companionFeatures, 106 ForceSkips: pcfg.Features.ForceSkips, 107 Factory: factory, 108 BuildArtifactsURL: pcfg.DataFile.GetBuildArtifactsUrl(), 109 110 Recursive: true, 111 } 112 113 d := minidriver.NewDriver(cfg, cc) 114 115 startFixture := stack.Top() 116 117 jsonResults, err := d.RunLocalTests(ctx, pcfg.ExternalTarget.Bundle, names, startFixture) 118 if err == minidriver.ErrNoTestRanInLastAttempt { 119 if len(jsonResults) == 0 { 120 return nil, err 121 } 122 // Fixture failure stopped local tests running. 123 } else if err != nil { 124 return nil, err 125 } 126 startedSet := make(map[string]struct{}) 127 for _, t := range jsonResults { 128 startedSet[t.Name] = struct{}{} 129 } 130 for _, name := range names { 131 if _, ok := startedSet[name]; !ok { 132 unstarted = append(unstarted, name) 133 } 134 } 135 return unstarted, nil 136 }