Jiri Simsa | d7616c9 | 2015-03-24 23:44:30 -0700 | [diff] [blame] | 1 | // Copyright 2015 The Vanadium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 5 | // Test the device manager and related services and tools. |
| 6 | // |
| 7 | // By default, this script tests the device manager in a fashion amenable |
| 8 | // to automatic testing: the --single_user is passed to the device |
| 9 | // manager so that all device manager components run as the same user and |
| 10 | // no user input (such as an agent pass phrase) is needed. |
| 11 | // |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 12 | // This script can exercise the device manager in two different modes. It |
| 13 | // can be executed like so: |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 14 | // |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 15 | // v23 go test -v . --v23.tests |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 16 | // |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 17 | // This will exercise the device manager's single user mode where all |
| 18 | // processes run as the same invoking user. |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 19 | // |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 20 | // Alternatively, the device manager can be executed in multiple account |
| 21 | // mode by providing the --deviceuser <deviceuser> and --appuser |
| 22 | // <appuser> flags. In this case, the device manager will run as user |
| 23 | // <devicemgr> and the test will run applications as user <appuser>. If |
| 24 | // executed in this fashion, root permissions will be required to install |
| 25 | // and it may require configuring an agent passphrase. For example: |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 26 | // |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 27 | // v23 go test -v . --v23.tests --deviceuser devicemanager --appuser vana |
| 28 | // |
| 29 | // NB: the accounts provided as arguments to this test must already exist. |
| 30 | // Also, the --v23.tests.shell-on-fail flag is useful to enable debugging |
Robert Kroeger | ac7f57b | 2015-07-28 17:56:13 -0700 | [diff] [blame] | 31 | // output. Note that this flag does not work for some shells. Set |
| 32 | // $SHELL in that case. |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 33 | |
Todd Wang | cd4b3cc | 2015-04-06 16:42:02 -0700 | [diff] [blame] | 34 | package device_test |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 35 | |
| 36 | //go:generate v23 test generate . |
| 37 | |
| 38 | import ( |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 39 | "errors" |
| 40 | "flag" |
| 41 | "fmt" |
Bogdan Caprita | 3c31921 | 2015-08-19 18:12:53 -0700 | [diff] [blame] | 42 | "io" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 43 | "io/ioutil" |
| 44 | "math/rand" |
| 45 | "os" |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 46 | "os/user" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 47 | "path/filepath" |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 48 | "regexp" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 49 | "strings" |
Bogdan Caprita | 3c31921 | 2015-08-19 18:12:53 -0700 | [diff] [blame] | 50 | "sync" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 51 | "time" |
| 52 | |
Todd Wang | 8123b5e | 2015-05-14 18:44:43 -0700 | [diff] [blame] | 53 | "v.io/x/ref" |
Suharsh Sivakumar | dcc11d7 | 2015-05-11 12:19:20 -0700 | [diff] [blame] | 54 | _ "v.io/x/ref/runtime/factories/generic" |
Cosmos Nicolaou | 1381f8a | 2015-03-13 09:40:34 -0700 | [diff] [blame] | 55 | "v.io/x/ref/test/v23tests" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 56 | ) |
| 57 | |
| 58 | var ( |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 59 | appUserFlag string |
| 60 | deviceUserFlag string |
| 61 | hostname string |
| 62 | errTimeout = errors.New("timeout") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 63 | ) |
| 64 | |
| 65 | func init() { |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 66 | flag.StringVar(&appUserFlag, "appuser", "", "launch apps as the specified user") |
| 67 | flag.StringVar(&deviceUserFlag, "deviceuser", "", "run the device manager as the specified user") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 68 | name, err := os.Hostname() |
| 69 | if err != nil { |
| 70 | panic(fmt.Sprintf("Hostname() failed: %v", err)) |
| 71 | } |
| 72 | hostname = name |
| 73 | } |
| 74 | |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 75 | func V23TestDeviceManager(i *v23tests.T) { |
Robert Kroeger | 769353e | 2015-05-05 19:10:07 -0700 | [diff] [blame] | 76 | u, err := user.Current() |
| 77 | if err != nil { |
| 78 | i.Fatalf("couldn't get the current user: %v", err) |
| 79 | } |
| 80 | testCore(i, u.Username, "", false) |
| 81 | } |
| 82 | |
| 83 | func V23TestDeviceManagerMultiUser(i *v23tests.T) { |
| 84 | u, err := user.Current() |
| 85 | if err != nil { |
| 86 | i.Fatalf("couldn't get the current user: %v", err) |
| 87 | } |
| 88 | |
| 89 | if u.Username == "veyron" && runTestOnThisPlatform { |
| 90 | // We are running on the builder so run the multiuser |
| 91 | // test with default user names. These will be created as |
| 92 | // required. |
| 93 | makeTestAccounts(i) |
| 94 | testCore(i, "vana", "devicemanager", true) |
| 95 | return |
| 96 | } |
| 97 | |
| 98 | if len(deviceUserFlag) > 0 && len(appUserFlag) > 0 { |
| 99 | testCore(i, appUserFlag, deviceUserFlag, true) |
| 100 | } else { |
| 101 | i.Logf("Test skipped because running in multiuser mode requires --appuser and --deviceuser flags") |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | func testCore(i *v23tests.T, appUser, deviceUser string, withSuid bool) { |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 106 | defer fmt.Fprintf(os.Stderr, "--------------- SHUTDOWN ---------------\n") |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 107 | tempDir := "" |
Robert Kroeger | 769353e | 2015-05-05 19:10:07 -0700 | [diff] [blame] | 108 | |
| 109 | if withSuid { |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 110 | // When running --with_suid, TMPDIR must grant the |
| 111 | // invoking user rwx permissions and world x permissions for |
| 112 | // all parent directories back to /. Otherwise, the |
| 113 | // with_suid user will not be able to use absolute paths. |
| 114 | // On Darwin, TMPDIR defaults to a directory hieararchy |
| 115 | // in /var that is 0700. This is unworkable so force |
| 116 | // TMPDIR to /tmp in this case. |
| 117 | tempDir = "/tmp" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 118 | } |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 119 | |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 120 | var ( |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 121 | workDir = i.NewTempDir(tempDir) |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 122 | binStagingDir = mkSubdir(i, workDir, "bin") |
| 123 | dmInstallDir = filepath.Join(workDir, "dm") |
| 124 | |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 125 | // Most vanadium command-line utilities will be run by a |
| 126 | // principal that has "root/u/alice" as its blessing. |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 127 | // (Where "root" comes from i.Principal().BlessingStore().Default()). |
| 128 | // Create those credentials and options to use to setup the |
| 129 | // binaries with them. |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 130 | aliceCreds, _ = i.Shell().NewChildCredentials("u/alice") |
Todd Wang | 9587390 | 2015-05-22 14:21:30 -0700 | [diff] [blame] | 131 | aliceOpts = i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(aliceCreds) |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 132 | |
| 133 | // Build all the command-line tools and set them up to run as alice. |
| 134 | // applicationd/binaryd servers will be run by alice too. |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 135 | // TODO: applicationd/binaryd should run as a separate "service" role, as |
| 136 | // alice is just a user. |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 137 | namespaceBin = i.BuildV23Pkg("v.io/x/ref/cmd/namespace").WithStartOpts(aliceOpts) |
Todd Wang | cd4b3cc | 2015-04-06 16:42:02 -0700 | [diff] [blame] | 138 | deviceBin = i.BuildV23Pkg("v.io/x/ref/services/device/device").WithStartOpts(aliceOpts) |
Todd Wang | 1f7a6c6 | 2015-04-03 17:05:09 -0700 | [diff] [blame] | 139 | binarydBin = i.BuildV23Pkg("v.io/x/ref/services/binary/binaryd").WithStartOpts(aliceOpts) |
Todd Wang | 159f6ee | 2015-04-02 18:57:46 -0700 | [diff] [blame] | 140 | applicationdBin = i.BuildV23Pkg("v.io/x/ref/services/application/applicationd").WithStartOpts(aliceOpts) |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 141 | |
| 142 | // The devicex script is not provided with any credentials, it |
| 143 | // will generate its own. This means that on "devicex start" |
| 144 | // the device will have no useful credentials and until "device |
| 145 | // claim" is invoked (as alice), it will just sit around |
| 146 | // waiting to be claimed. |
| 147 | // |
| 148 | // Other binaries, like applicationd and binaryd will be run by alice. |
Bogdan Caprita | cb055fa | 2015-04-08 10:21:23 -0700 | [diff] [blame] | 149 | deviceScript = i.BinaryFromPath("./devicex").WithEnv("V23_DEVICE_DIR=" + dmInstallDir) |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 150 | |
| 151 | mtName = "devices/" + hostname // Name under which the device manager will publish itself. |
| 152 | ) |
| 153 | |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 154 | // We also need some tools running with different sets of credentials... |
| 155 | |
| 156 | // Administration tasks will be performed with a blessing that represents a corporate |
| 157 | // adminstrator (which is usually a role account) |
| 158 | adminCreds, err := i.Shell().NewChildCredentials("r/admin") |
| 159 | if err != nil { |
| 160 | i.Fatalf("generating admin creds: %v", err) |
| 161 | } |
| 162 | adminOpts := i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(adminCreds) |
| 163 | adminDeviceBin := deviceBin.WithStartOpts(adminOpts) |
| 164 | debugBin := i.BuildV23Pkg("v.io/x/ref/services/debug/debug").WithStartOpts(adminOpts) |
| 165 | |
| 166 | // A special set of credentials will be used to give two blessings to the device manager |
| 167 | // when claiming it -- one blessing will be from the corporate administrator role who owns |
| 168 | // the machine, and the other will be a manufacturer blessing. (This is a hack until |
| 169 | // there's a way to separately supply a manufacturer blessing. Eventually, the claim |
| 170 | // would really be done by the administator, and the adminstrator's blessing would get |
| 171 | // added to the manufacturer's blessing, which would already be present.) |
| 172 | claimCreds, err := i.Shell().AddToChildCredentials(adminCreds, "m/orange/zphone5/ime-i007") |
| 173 | if err != nil { |
| 174 | i.Fatalf("adding the mfr blessing to admin creds: %v", err) |
| 175 | } |
| 176 | claimOpts := i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(claimCreds) |
| 177 | claimDeviceBin := deviceBin.WithStartOpts(claimOpts) |
| 178 | |
| 179 | // Another set of credentials be used to represent the application publisher, who |
| 180 | // signs and pushes binaries |
| 181 | pubCreds, err := i.Shell().NewChildCredentials("a/rovio") |
| 182 | if err != nil { |
| 183 | i.Fatalf("generating publisher creds: %v", err) |
| 184 | } |
| 185 | pubOpts := i.Shell().DefaultStartOpts().ExternalProgram().WithCustomCredentials(pubCreds) |
| 186 | pubDeviceBin := deviceBin.WithStartOpts(pubOpts) |
| 187 | applicationBin := i.BuildV23Pkg("v.io/x/ref/services/application/application").WithStartOpts(pubOpts) |
| 188 | binaryBin := i.BuildV23Pkg("v.io/x/ref/services/binary/binary").WithStartOpts(pubOpts) |
| 189 | |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 190 | if withSuid { |
| 191 | // In multiuser mode, deviceUserFlag needs execute access to |
| 192 | // tempDir. |
| 193 | if err := os.Chmod(workDir, 0711); err != nil { |
| 194 | i.Fatalf("os.Chmod() failed: %v", err) |
| 195 | } |
| 196 | } |
| 197 | |
Asim Shankar | f32d24d | 2015-04-01 16:34:26 -0700 | [diff] [blame] | 198 | v23tests.RunRootMT(i, "--v23.tcp.address=127.0.0.1:0") |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 199 | buildAndCopyBinaries( |
| 200 | i, |
| 201 | binStagingDir, |
Todd Wang | cd4b3cc | 2015-04-06 16:42:02 -0700 | [diff] [blame] | 202 | "v.io/x/ref/services/device/deviced", |
Todd Wang | b351149 | 2015-04-07 23:32:34 -0700 | [diff] [blame] | 203 | "v.io/x/ref/services/agent/agentd", |
Todd Wang | 392a9cc | 2015-04-06 14:35:11 -0700 | [diff] [blame] | 204 | "v.io/x/ref/services/device/suidhelper", |
| 205 | "v.io/x/ref/services/device/inithelper") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 206 | |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 207 | appDName := "applications" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 208 | devicedAppName := filepath.Join(appDName, "deviced", "test") |
| 209 | |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 210 | deviceScriptArguments := []string{ |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 211 | "install", |
| 212 | binStagingDir, |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 213 | } |
| 214 | |
| 215 | if withSuid { |
Robert Kroeger | 769353e | 2015-05-05 19:10:07 -0700 | [diff] [blame] | 216 | deviceScriptArguments = append(deviceScriptArguments, "--devuser="+deviceUser) |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 217 | } else { |
Bogdan Caprita | 3c31921 | 2015-08-19 18:12:53 -0700 | [diff] [blame] | 218 | deviceScriptArguments = append(deviceScriptArguments, "--single_user") |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 219 | } |
| 220 | |
| 221 | deviceScriptArguments = append(deviceScriptArguments, []string{ |
| 222 | "--origin=" + devicedAppName, |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 223 | "--", |
Asim Shankar | f32d24d | 2015-04-01 16:34:26 -0700 | [diff] [blame] | 224 | "--v23.tcp.address=127.0.0.1:0", |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 225 | "--neighborhood-name=" + fmt.Sprintf("%s-%d-%d", hostname, os.Getpid(), rand.Int()), |
| 226 | }...) |
| 227 | |
| 228 | deviceScript.Start(deviceScriptArguments...).WaitOrDie(os.Stdout, os.Stderr) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 229 | deviceScript.Start("start").WaitOrDie(os.Stdout, os.Stderr) |
Bogdan Caprita | 3c31921 | 2015-08-19 18:12:53 -0700 | [diff] [blame] | 230 | dmLog := filepath.Join(dmInstallDir, "dmroot/device-manager/logs/deviced.INFO") |
| 231 | stopDevMgr := func() { |
| 232 | deviceScript.Run("stop") |
| 233 | if dmLogF, err := os.Open(dmLog); err != nil { |
| 234 | i.Errorf("Failed to read dm log: %v", err) |
| 235 | } else { |
| 236 | fmt.Fprintf(os.Stderr, "--------------- START DM LOG ---------------\n") |
| 237 | defer dmLogF.Close() |
| 238 | if _, err := io.Copy(os.Stderr, dmLogF); err != nil { |
| 239 | i.Errorf("Error dumping dm log: %v", err) |
| 240 | } |
| 241 | fmt.Fprintf(os.Stderr, "--------------- END DM LOG ---------------\n") |
| 242 | } |
| 243 | } |
| 244 | var stopDevMgrOnce sync.Once |
| 245 | defer stopDevMgrOnce.Do(stopDevMgr) |
Bogdan Caprita | e807368 | 2015-04-25 15:37:53 -0700 | [diff] [blame] | 246 | // Grab the endpoint for the claimable service from the device manager's |
| 247 | // log. |
Bogdan Caprita | e807368 | 2015-04-25 15:37:53 -0700 | [diff] [blame] | 248 | var claimableEP string |
| 249 | expiry := time.Now().Add(30 * time.Second) |
| 250 | for { |
| 251 | if time.Now().After(expiry) { |
| 252 | i.Fatalf("Timed out looking for claimable endpoint in %v", dmLog) |
| 253 | } |
| 254 | startLog, err := ioutil.ReadFile(dmLog) |
| 255 | if err != nil { |
| 256 | i.Logf("Couldn't read log %v: %v", dmLog, err) |
| 257 | time.Sleep(time.Second) |
| 258 | continue |
| 259 | } |
| 260 | re := regexp.MustCompile(`Unclaimed device manager \((.*)\)`) |
| 261 | matches := re.FindSubmatch(startLog) |
| 262 | if len(matches) == 0 { |
| 263 | i.Logf("Couldn't find match in %v [%v]", dmLog, startLog) |
| 264 | time.Sleep(time.Second) |
| 265 | continue |
| 266 | } |
| 267 | if len(matches) != 2 { |
| 268 | i.Fatalf("Wrong match in %v (%d) %v", dmLog, len(matches), string(matches[0])) |
| 269 | } |
| 270 | claimableEP = string(matches[1]) |
| 271 | break |
| 272 | } |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 273 | // Claim the device as "root/u/alice/myworkstation". |
| 274 | claimDeviceBin.Start("claim", claimableEP, "myworkstation") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 275 | |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 276 | resolve := func(name string) string { |
| 277 | resolver := func() (interface{}, error) { |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 278 | // Use Start, rather than Run, since it's ok for 'namespace resolve' |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 279 | // to fail with 'name doesn't exist' |
| 280 | inv := namespaceBin.Start("resolve", name) |
| 281 | // Cleanup after ourselves to avoid leaving a ton of invocations |
| 282 | // lying around which obscure logging output. |
| 283 | defer inv.Wait(nil, os.Stderr) |
| 284 | if r := strings.TrimRight(inv.Output(), "\n"); len(r) > 0 { |
| 285 | return r, nil |
| 286 | } |
| 287 | return nil, nil |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 288 | } |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 289 | return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 290 | } |
Bogdan Caprita | e807368 | 2015-04-25 15:37:53 -0700 | [diff] [blame] | 291 | |
| 292 | // Wait for the device manager to publish its mount table entry. |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 293 | mtEP := resolve(mtName) |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 294 | adminDeviceBin.Run("acl", "set", mtName+"/devmgr/device", "root/u/alice", "Read,Resolve,Write") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 295 | |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 296 | if withSuid { |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 297 | adminDeviceBin.Start("associate", "add", mtName+"/devmgr/device", appUser, "root/u/alice") |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 298 | |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 299 | aai := adminDeviceBin.Start("associate", "list", mtName+"/devmgr/device") |
| 300 | if got, expected := strings.Trim(aai.Output(), "\n "), "root/u/alice "+appUser; got != expected { |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 301 | i.Fatalf("association test, got %v, expected %v", got, expected) |
| 302 | } |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 303 | } |
| 304 | |
| 305 | // Verify the device's default blessing is as expected. |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 306 | mfrBlessing := "root/m/orange/zphone5/ime-i007/myworkstation" |
| 307 | ownerBlessing := "root/r/admin/myworkstation" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 308 | inv := debugBin.Start("stats", "read", mtName+"/devmgr/__debug/stats/security/principal/*/blessingstore") |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 309 | inv.ExpectSetEventuallyRE(".*Default Blessings[ ]+" + mfrBlessing + "," + ownerBlessing) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 310 | |
| 311 | // Get the device's profile, which should be set to non-empty string |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 312 | inv = adminDeviceBin.Start("describe", mtName+"/devmgr/device") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 313 | |
| 314 | parts := inv.ExpectRE(`{Profiles:map\[(.*):{}\]}`, 1) |
| 315 | expectOneMatch := func(parts [][]string) string { |
| 316 | if len(parts) != 1 || len(parts[0]) != 2 { |
| 317 | loc := v23tests.Caller(1) |
| 318 | i.Fatalf("%s: failed to match profile: %#v", loc, parts) |
| 319 | } |
| 320 | return parts[0][1] |
| 321 | } |
| 322 | deviceProfile := expectOneMatch(parts) |
| 323 | if len(deviceProfile) == 0 { |
| 324 | i.Fatalf("failed to get profile") |
| 325 | } |
| 326 | |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 327 | // Start a binaryd server that will serve the binary for the test |
| 328 | // application to be installed on the device. |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 329 | binarydName := "binaries" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 330 | binarydBin.Start( |
| 331 | "--name="+binarydName, |
Suharsh Sivakumar | 65e3850 | 2015-04-01 18:33:18 -0700 | [diff] [blame] | 332 | "--root-dir="+filepath.Join(workDir, "binstore"), |
Asim Shankar | f32d24d | 2015-04-01 16:34:26 -0700 | [diff] [blame] | 333 | "--v23.tcp.address=127.0.0.1:0", |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 334 | "--http=127.0.0.1:0") |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 335 | // Allow publishers to update binaries |
| 336 | deviceBin.Run("acl", "set", binarydName, "root/a", "Write") |
| 337 | |
| 338 | // We are also going to use the binaryd binary as our test app binary. Once our test app |
| 339 | // binary is published to the binaryd server started above, this (augmented with a |
| 340 | // timestamp) is the name the test app binary will have. |
| 341 | sampleAppBinName := binarydName + "/binaryd" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 342 | |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 343 | // Start an applicationd server that will serve the application |
| 344 | // envelope for the test application to be installed on the device. |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 345 | applicationdBin.Start( |
| 346 | "--name="+appDName, |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 347 | "--store="+mkSubdir(i, workDir, "appstore"), |
Asim Shankar | f32d24d | 2015-04-01 16:34:26 -0700 | [diff] [blame] | 348 | "--v23.tcp.address=127.0.0.1:0", |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 349 | ) |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 350 | // Allow publishers to create and update envelopes |
| 351 | deviceBin.Run("acl", "set", appDName, "root/a", "Read,Write,Resolve") |
| 352 | |
Bogdan Caprita | a49fe64 | 2015-09-15 10:43:12 -0700 | [diff] [blame] | 353 | sampleAppName := appDName + "/testapp" |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 354 | appPubName := "testbinaryd" |
| 355 | appEnvelopeFilename := filepath.Join(workDir, "app.envelope") |
Suharsh Sivakumar | 65e3850 | 2015-04-01 18:33:18 -0700 | [diff] [blame] | 356 | appEnvelope := fmt.Sprintf("{\"Title\":\"BINARYD\", \"Args\":[\"--name=%s\", \"--root-dir=./binstore\", \"--v23.tcp.address=127.0.0.1:0\", \"--http=127.0.0.1:0\"], \"Binary\":{\"File\":%q}, \"Env\":[]}", appPubName, sampleAppBinName) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 357 | ioutil.WriteFile(appEnvelopeFilename, []byte(appEnvelope), 0666) |
| 358 | defer os.Remove(appEnvelopeFilename) |
| 359 | |
Bogdan Caprita | a49fe64 | 2015-09-15 10:43:12 -0700 | [diff] [blame] | 360 | output := applicationBin.Run("put", sampleAppName+"/0", deviceProfile, appEnvelopeFilename) |
Bogdan Caprita | 164ddcb | 2015-09-03 11:14:10 -0700 | [diff] [blame] | 361 | if got, want := output, fmt.Sprintf("Application envelope added for profile %s.", deviceProfile); got != want { |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 362 | i.Fatalf("got %q, want %q", got, want) |
| 363 | } |
| 364 | |
| 365 | // Verify that the envelope we uploaded shows up with glob. |
| 366 | inv = applicationBin.Start("match", sampleAppName, deviceProfile) |
| 367 | parts = inv.ExpectSetEventuallyRE(`"Title": "(.*)",`, `"File": "(.*)",`) |
| 368 | if got, want := len(parts), 2; got != want { |
| 369 | i.Fatalf("got %d, want %d", got, want) |
| 370 | } |
| 371 | for line, want := range []string{"BINARYD", sampleAppBinName} { |
| 372 | if got := parts[line][1]; got != want { |
| 373 | i.Fatalf("got %q, want %q", got, want) |
| 374 | } |
| 375 | } |
| 376 | |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 377 | // Publish the app (This uses the binarydBin binary and the testapp envelope from above) |
| 378 | pubDeviceBin.Start("publish", "-from", filepath.Dir(binarydBin.Path()), "-readers", "root/r/admin", filepath.Base(binarydBin.Path())+":testapp").WaitOrDie(os.Stdout, os.Stderr) |
| 379 | if got := namespaceBin.Run("glob", sampleAppBinName); len(got) == 0 { |
| 380 | i.Fatalf("glob failed for %q", sampleAppBinName) |
| 381 | } |
| 382 | |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 383 | // Install the app on the device. |
| 384 | inv = deviceBin.Start("install", mtName+"/devmgr/apps", sampleAppName) |
Bogdan Caprita | 2b05032 | 2015-04-17 09:04:03 -0700 | [diff] [blame] | 385 | installationName := inv.ReadLine() |
| 386 | if installationName == "" { |
| 387 | i.Fatalf("got empty installation name from install") |
| 388 | } |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 389 | |
| 390 | // Verify that the installation shows up when globbing the device manager. |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 391 | output = namespaceBin.Run("glob", mtName+"/devmgr/apps/BINARYD/*") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 392 | if got, want := output, installationName; got != want { |
| 393 | i.Fatalf("got %q, want %q", got, want) |
| 394 | } |
| 395 | |
| 396 | // Start an instance of the app, granting it blessing extension myapp. |
Bogdan Caprita | 2b05032 | 2015-04-17 09:04:03 -0700 | [diff] [blame] | 397 | inv = deviceBin.Start("instantiate", installationName, "myapp") |
| 398 | instanceName := inv.ReadLine() |
| 399 | if instanceName == "" { |
| 400 | i.Fatalf("got empty instance name from new") |
| 401 | } |
| 402 | deviceBin.Start("run", instanceName) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 403 | |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 404 | resolve(mtName + "/" + appPubName) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 405 | |
| 406 | // Verify that the instance shows up when globbing the device manager. |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 407 | output = namespaceBin.Run("glob", mtName+"/devmgr/apps/BINARYD/*/*") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 408 | if got, want := output, instanceName; got != want { |
| 409 | i.Fatalf("got %q, want %q", got, want) |
| 410 | } |
| 411 | |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 412 | inv = debugBin.Start("stats", "read", instanceName+"/stats/system/pid") |
| 413 | pid := inv.ExpectRE("[0-9]+$", 1)[0][0] |
| 414 | uname, err := getUserForPid(i, pid) |
| 415 | if err != nil { |
| 416 | i.Errorf("getUserForPid could not determine the user running pid %v", pid) |
Robin Thellend | f0a422b | 2015-08-27 09:55:07 -0700 | [diff] [blame] | 417 | } else if uname != appUser { |
Robert Kroeger | 769353e | 2015-05-05 19:10:07 -0700 | [diff] [blame] | 418 | i.Errorf("app expected to be running as %v but is running as %v", appUser, uname) |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 419 | } |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 420 | |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 421 | // Verify the app's blessings. We check the default blessing, as well as the |
| 422 | // "..." blessing, which should be the default blessing plus a publisher blessing. |
| 423 | userBlessing := "root/u/alice/myapp" |
| 424 | pubBlessing := "root/a/rovio/apps/published/binaryd" |
| 425 | appBlessing := mfrBlessing + "/a/" + pubBlessing + "," + ownerBlessing + "/a/" + pubBlessing |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 426 | inv = debugBin.Start("stats", "read", instanceName+"/stats/security/principal/*/blessingstore") |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 427 | inv.ExpectSetEventuallyRE(".*Default Blessings[ ]+"+userBlessing+"$", "[.][.][.][ ]+"+userBlessing+","+appBlessing) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 428 | |
Bogdan Caprita | 2b05032 | 2015-04-17 09:04:03 -0700 | [diff] [blame] | 429 | // Kill and delete the instance. |
| 430 | deviceBin.Run("kill", instanceName) |
| 431 | deviceBin.Run("delete", instanceName) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 432 | |
| 433 | // Verify that logs, but not stats, show up when globbing the |
Bogdan Caprita | 2b05032 | 2015-04-17 09:04:03 -0700 | [diff] [blame] | 434 | // not-running instance. |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 435 | if output = namespaceBin.Run("glob", instanceName+"/stats/..."); len(output) > 0 { |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 436 | i.Fatalf("no output expected for glob %s/stats/..., got %q", output, instanceName) |
| 437 | } |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 438 | if output = namespaceBin.Run("glob", instanceName+"/logs/..."); len(output) == 0 { |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 439 | i.Fatalf("output expected for glob %s/logs/..., but got none", instanceName) |
| 440 | } |
| 441 | |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 442 | // TODO: The deviced binary should probably be published by someone other than rovio :-) |
| 443 | // Maybe publishing the deviced binary should eventually use "device publish" too? |
| 444 | // For now, it uses the "application" and "binary" tools directly to ensure that those work |
| 445 | |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 446 | // Upload a deviced binary |
| 447 | devicedAppBinName := binarydName + "/deviced" |
Todd Wang | cd4b3cc | 2015-04-06 16:42:02 -0700 | [diff] [blame] | 448 | binaryBin.Run("upload", devicedAppBinName, i.BuildGoPkg("v.io/x/ref/services/device/deviced").Path()) |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 449 | // Allow root/r/admin and its devices to read the binary |
| 450 | deviceBin.Run("acl", "set", devicedAppBinName, "root/r/admin", "Read") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 451 | |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 452 | // Upload a device manager envelope. |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 453 | devicedEnvelopeFilename := filepath.Join(workDir, "deviced.envelope") |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 454 | devicedEnvelope := fmt.Sprintf("{\"Title\":\"device manager\", \"Binary\":{\"File\":%q}}", devicedAppBinName) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 455 | ioutil.WriteFile(devicedEnvelopeFilename, []byte(devicedEnvelope), 0666) |
| 456 | defer os.Remove(devicedEnvelopeFilename) |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 457 | applicationBin.Run("put", devicedAppName, deviceProfile, devicedEnvelopeFilename) |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 458 | // Allow root/r/admin and its devices to read the envelope |
| 459 | deviceBin.Run("acl", "set", devicedAppName, "root/r/admin", "Read") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 460 | |
| 461 | // Update the device manager. |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 462 | adminDeviceBin.Run("update", mtName+"/devmgr/device") |
Bogdan Caprita | e807368 | 2015-04-25 15:37:53 -0700 | [diff] [blame] | 463 | resolveChange := func(name, old string) string { |
| 464 | resolver := func() (interface{}, error) { |
| 465 | inv := namespaceBin.Start("resolve", name) |
| 466 | defer inv.Wait(nil, os.Stderr) |
| 467 | if r := strings.TrimRight(inv.Output(), "\n"); len(r) > 0 && r != old { |
| 468 | return r, nil |
| 469 | } |
| 470 | return nil, nil |
| 471 | } |
| 472 | return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string) |
| 473 | } |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 474 | mtEP = resolveChange(mtName, mtEP) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 475 | |
| 476 | // Verify that device manager's mounttable is still published under the |
| 477 | // expected name (hostname). |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 478 | if namespaceBin.Run("glob", mtName) == "" { |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 479 | i.Fatalf("failed to glob %s", mtName) |
| 480 | } |
| 481 | |
| 482 | // Revert the device manager |
Robin Thellend | f0a422b | 2015-08-27 09:55:07 -0700 | [diff] [blame] | 483 | // The argument to "device revert" is a glob pattern. So we need to |
| 484 | // wait for devmgr to be mounted before running the command. |
| 485 | resolve(mtEP + "/devmgr") |
Arup Mukherjee | d804828 | 2015-06-26 23:18:44 -0700 | [diff] [blame] | 486 | adminDeviceBin.Run("revert", mtName+"/devmgr/device") |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 487 | mtEP = resolveChange(mtName, mtEP) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 488 | |
| 489 | // Verify that device manager's mounttable is still published under the |
| 490 | // expected name (hostname). |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 491 | if namespaceBin.Run("glob", mtName) == "" { |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 492 | i.Fatalf("failed to glob %s", mtName) |
| 493 | } |
| 494 | |
| 495 | // Verify that the local mounttable exists, and that the device manager, |
| 496 | // the global namespace, and the neighborhood are mounted on it. |
Robin Thellend | f0a422b | 2015-08-27 09:55:07 -0700 | [diff] [blame] | 497 | resolve(mtEP + "/devmgr") |
| 498 | resolve(mtEP + "/nh") |
| 499 | resolve(mtEP + "/global") |
| 500 | |
Todd Wang | 8123b5e | 2015-05-14 18:44:43 -0700 | [diff] [blame] | 501 | namespaceRoot, _ := i.GetVar(ref.EnvNamespacePrefix) |
Robin Thellend | f0a422b | 2015-08-27 09:55:07 -0700 | [diff] [blame] | 502 | if got, want := namespaceBin.Run("resolve", mtEP+"/global"), namespaceRoot; got != want { |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 503 | i.Fatalf("got %q, want %q", got, want) |
| 504 | } |
| 505 | |
Bogdan Caprita | 2b05032 | 2015-04-17 09:04:03 -0700 | [diff] [blame] | 506 | // Kill the device manager (which causes it to be restarted), wait for |
| 507 | // the endpoint to change. |
| 508 | deviceBin.Run("kill", mtName+"/devmgr/device") |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 509 | mtEP = resolveChange(mtName, mtEP) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 510 | |
Bogdan Caprita | 2b05032 | 2015-04-17 09:04:03 -0700 | [diff] [blame] | 511 | // Shut down the device manager. |
Bogdan Caprita | 3c31921 | 2015-08-19 18:12:53 -0700 | [diff] [blame] | 512 | stopDevMgrOnce.Do(stopDevMgr) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 513 | |
| 514 | // Wait for the mounttable entry to go away. |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 515 | resolveGone := func(name string) string { |
| 516 | resolver := func() (interface{}, error) { |
| 517 | inv := namespaceBin.Start("resolve", name) |
| 518 | defer inv.Wait(nil, os.Stderr) |
| 519 | if r := strings.TrimRight(inv.Output(), "\n"); len(r) == 0 { |
| 520 | return r, nil |
| 521 | } |
| 522 | return nil, nil |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 523 | } |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 524 | return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 525 | } |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 526 | resolveGone(mtName) |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 527 | |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 528 | var fi []os.FileInfo |
| 529 | |
| 530 | // This doesn't work in multiuser mode because dmInstallDir is |
| 531 | // owned by the device manager user and unreadable by the user |
| 532 | // running this test. |
| 533 | if !withSuid { |
| 534 | fi, err = ioutil.ReadDir(dmInstallDir) |
| 535 | if err != nil { |
| 536 | i.Fatalf("failed to readdir for %q: %v", dmInstallDir, err) |
| 537 | } |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 538 | } |
| 539 | |
Cosmos Nicolaou | abbcb20 | 2015-02-26 11:24:52 -0800 | [diff] [blame] | 540 | deviceScript.Run("uninstall") |
Cosmos Nicolaou | 93dd88b | 2015-02-19 15:10:53 -0800 | [diff] [blame] | 541 | |
| 542 | fi, err = ioutil.ReadDir(dmInstallDir) |
| 543 | if err == nil || len(fi) > 0 { |
| 544 | i.Fatalf("managed to read %d entries from %q", len(fi), dmInstallDir) |
| 545 | } |
| 546 | if err != nil && !strings.Contains(err.Error(), "no such file or directory") { |
| 547 | i.Fatalf("wrong error: %v", err) |
| 548 | } |
| 549 | } |
Asim Shankar | 6cc759d | 2015-03-14 03:31:44 -0700 | [diff] [blame] | 550 | |
| 551 | func buildAndCopyBinaries(i *v23tests.T, destinationDir string, packages ...string) { |
| 552 | var args []string |
| 553 | for _, pkg := range packages { |
| 554 | args = append(args, i.BuildGoPkg(pkg).Path()) |
| 555 | } |
| 556 | args = append(args, destinationDir) |
| 557 | i.BinaryFromPath("/bin/cp").Start(args...).WaitOrDie(os.Stdout, os.Stderr) |
| 558 | } |
| 559 | |
| 560 | func mkSubdir(i *v23tests.T, parent, child string) string { |
| 561 | dir := filepath.Join(parent, child) |
| 562 | if err := os.Mkdir(dir, 0755); err != nil { |
| 563 | i.Fatalf("failed to create %q: %v", dir, err) |
| 564 | } |
| 565 | return dir |
| 566 | } |
Robert Kroeger | 02714b7 | 2015-04-14 18:02:38 -0700 | [diff] [blame] | 567 | |
| 568 | var re = regexp.MustCompile("[ \t]+") |
| 569 | |
| 570 | // getUserForPid determines the username running process pid. |
| 571 | func getUserForPid(i *v23tests.T, pid string) (string, error) { |
| 572 | pidString := i.BinaryFromPath("/bin/ps").Start(psFlags).Output() |
| 573 | for _, line := range strings.Split(pidString, "\n") { |
| 574 | fields := re.Split(line, -1) |
| 575 | if len(fields) > 1 && pid == fields[1] { |
| 576 | return fields[0], nil |
| 577 | } |
| 578 | } |
| 579 | return "", fmt.Errorf("Couldn't determine the user for pid %s", pid) |
| 580 | } |