Fix RunCommand missing output lines bug

There's an intermittent bug where RunCommand returns incomplete output.
This can lead to flaky tests depending on if that missing output is critical.

ex: https://ci.chromium.org/p/celab/builders/luci.celab.ci/Linux/b8922309052533242736

^ This test was missing the <title> line for one of our `Invoke-WebRequest`.

Looking at the instance & StackDriver logs for that test, missing lines were
logged normally and in the right order. StackDriver timestamps also looked OK.

I tried to get a repro with this powershell command:
```
  for ($i = 0; $i -lt %s; $i++) {
    Write-Host "This is line #$i"
  }
```

Most of the time, this works fine. However, about 1/20 times, we see a gap.
In one of those instance, we got the following batches from StackDriver:
[3 seconds between reads]
- nofilter: []
- nofilter: []
- nofilter: [0-43]
- InsertId > 43: [45-<end>]

And we missed line #44.

This is confusing because the StackDriver APIs promise to [return logs sorted by (Time,InsertID)](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry).

However, it does not promise in-order log visibility.

I already knew there was some weird buffering there, but adding more traces
showed this interesting scenario (3s between reads):
[3 seconds between reads]
- nofilter: []
- nofilter: []
- nofilter: [0-9]
- InsertId > 9: [11-<end>]
- InsertId > 9: [11-<end>]
- InsertId > 9: [10-<end>]

Where we would've missed out on 10 had we not waited for it.

Thankfully, gaps in our logs are easy to identify, so I added some code to wait
for expected InsertIds when we can.
I considered adding a time out, printing "[missing lines N-M]" and succeeding
the command when a line is 100% missing, but decided against it.
I've never seen such a case so far and I'd be interested in debugging that if
it happened. Clearly failing RunCommand in this case will make it easier to
find/fix this bug (if it exists) rather than silently succeed after N seconds.

Tested with the IISSitesTest on an infinite loop until I got a [8-<end>] fetch
which would've failed the test (like in the failed CI), but actually succeeded
after the 4th stackdriver refetch.

Change-Id: Id50ea1682d3e7cdbe664882b915d5c9b6c0e60d9
Reviewed-on: https://chromium-review.googlesource.com/c/1457306
Reviewed-by: Fei Ling <feiling@chromium.org>
1 file changed
tree: 41bfb84e70902b93d205f56267ad15c93ab96a5d
  1. build/
  2. docs/
  3. examples/
  4. go/
  5. infra/
  6. resources/
  7. schema/
  8. scripts/
  9. test/
  10. .gitignore
  11. .gitmodules
  12. .style.yapf
  13. .vpython
  14. build.py
  15. CODE_OF_CONDUCT.md
  16. codereview.settings
  17. CONTRIBUTING.md
  18. Gopkg.lock
  19. Gopkg.toml
  20. LICENSE
  21. navbar.md
  22. OWNERS
  23. PRESUBMIT.py
  24. README.md
  25. run_tests.py
  26. test.py
  27. VERSION
README.md

Chrome Enterprise Lab

Chrome Enterprise Lab is an inaccurately named set of tools for building enterprise labs quickly and easily. The labs so built can be used for system level end-to-end testing of Google Chrome/Chromium.

Have a peek at the Design document.

Also have a peek at the Code of Conduct.

Most of the code is in Go. See Guide to code to get a head start on the code in this repository.

Building

Prerequisites

  • Go: Download Go from the Go download page. This project requires Go 1.9.4 or later. The build will fail with prior versions.

  • Depot Tools: Used for managing the checkout and the contributor workflow.

  • Protocol Buffers Compiler: Protocol buffers are used extensively for wranging all the data that needs to be shuttled around. Can be installed automatically via ./build.py deps --install.

  • Dep : Used for Go depedency management. This can be installed automatically by running ./build.py deps --install from the root of the source tree.

  • Go support for Protocol Buffers : This can be installed automatically by running ./build.py deps --install from the root of the source tree.

Get The Source

There are two ways to get the source. One is to use managed deps, and the other is to use plain go get. The latter workflow doesn't quite work yet due to this repository not being integrated with go.chromium.org. So this page only mentions the managed dependency workflow.

  1. Clone this repository:

    Assumes that $GOPATH is a single path and not a : delimited list.

    mkdir -p ${GOPATH}/src/chromium.googlesource.com/enterprise
    cd ${GOPATH}/src/chromium.googlesource.com/enterprise
    git clone https://chromium.googlesource.com/enterprise/cel
    cd cel
    
  2. Get the dependencies:

    python build.py deps --install
    

Build It

  1. Use the build script:

    python build.py build
    
  2. Also make sure the tests pass.

    python build.py test
    

Contributing

See CONTRIBUTING.