Skip to content

Commit

Permalink
Stream switching (#160)
Browse files Browse the repository at this point in the history
  • Loading branch information
ca-johnson authored Apr 22, 2020
1 parent f8dcf33 commit acae0e0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 5 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ steps:
parallel: 16
```

### Share a stream workspace between pipelines.
### Share a stream workspace between pipelines

Useful to avoid syncing duplicate data with large workspaces.
Only allowed when there is a single buildkite agent running on the machine.
Expand All @@ -85,7 +85,10 @@ steps:
plugins:
- improbable-eng/perforce:
stream: //dev/buildkite
# Sync each stream once
share_workspace: true
# Sync once and switch streams in-place (requires share_workspace: true)
stream_switching: true
```

## Triggering Builds
Expand Down
11 changes: 8 additions & 3 deletions hooks/pre-checkout
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ if [[ "${BUILDKITE_PLUGIN_PERFORCE_SHARE_WORKSPACE}" == true ]] ; then
echo "Error: You cannot share stream workspaces when running more than one agent" >&2
exit 1
fi
# Sanitize //depot/stream-name to __depot_stream-name
SANITIZED_STREAM=$(echo $STREAM | python -c "import sys; print(sys.stdin.read().replace('/', '_'));")

if [[ "${BUILDKITE_PLUGIN_PERFORCE_STREAM_SWITCHING}" == true ]] ; then
echo "Stream switching enabled"
# Sanitize '//depot/stream-name' to 'depot'
SANITIZED_STREAM=$(echo $STREAM | python -c "import sys; print(sys.stdin.read().split('/')[2]);")
else # Create a directory per-stream
# Sanitize '//depot/stream-name' to '__depot_stream-name'
SANITIZED_STREAM=$(echo $STREAM | python -c "import sys; print(sys.stdin.read().replace('/', '_'));")
fi
# Instead of builds/<agent_number>/<pipeline>, checkout to builds/<stream_name>
PERFORCE_CHECKOUT_PATH="${BUILDKITE_BUILD_CHECKOUT_PATH}/../../${SANITIZED_STREAM}"
export BUILDKITE_BUILD_CHECKOUT_PATH="${PERFORCE_CHECKOUT_PATH}"
Expand Down
Binary file modified python/fixture/server.zip
Binary file not shown.
29 changes: 28 additions & 1 deletion python/test_perforce.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def test_fixture(capsys, server):
assert repo.info()['serverAddress'] == server

# To change the fixture server, uncomment the line below with 'store_server' and put a breakpoint on it
# Change __P4D_TIMEOUT__ to 'None' or an otherwise large amount of time
# Run unit tests in the debugger and hit the breakpoint
# Log in using details printed to stdout (port/user) via p4v or the command line
# Make changes to the p4 server
Expand All @@ -104,7 +105,8 @@ def test_fixture(capsys, server):
depotfile_to_content = {depotfile: repo.perforce.run_print(depotfile)[1] for depotfile in depotfiles}
assert depotfile_to_content == {
"//depot/file.txt": "Hello World\n",
"//stream-depot/main/file.txt": "Hello Stream World\n"
"//stream-depot/main/file.txt": "Hello Stream World\n",
"//stream-depot/dev/file.txt": "Hello Stream World (dev)\n",
}

# Check submitted changes
Expand Down Expand Up @@ -132,6 +134,16 @@ def test_fixture(capsys, server):
'depotFile': ['//depot/file.txt'],
'desc': 'modify //depot/file.txt\n'
},
'7': {
'action': ['branch'],
'depotFile': ['//stream-depot/dev/file.txt'],
'desc': 'Copy files from //stream-depot/main to //stream-depot/dev\n'
},
'8': {
'action': ['edit'],
'depotFile': ['//stream-depot/dev/file.txt'],
'desc': 'Update contents of //stream-depot/dev/file.txt\n'
}
}

# Check shelved changes
Expand Down Expand Up @@ -332,6 +344,21 @@ def test_client_migration(server, tmpdir):
synced = repo.sync() # Flushes to match previous client, since p4config is there on disk
assert synced == [], "Should not have synced any files in second client"

def test_stream_switching(server, tmpdir):
"""Test stream-switching within the same depot"""
repo = P4Repo(root=tmpdir, stream='//stream-depot/main')
synced = repo.sync()
assert len(synced) > 0, "Didn't sync any files"
with open(os.path.join(tmpdir, "file.txt")) as content:
assert content.read() == "Hello Stream World\n", "Unexpected content in workspace file"

# Re-use the same checkout directory, but switch streams
repo = P4Repo(root=tmpdir, stream='//stream-depot/dev')
repo.sync()
assert len(synced) > 0, "Didn't sync any files"
with open(os.path.join(tmpdir, "file.txt")) as content:
assert content.read() == "Hello Stream World (dev)\n", "Unexpected content in workspace file"


# def test_live_server():
# """Reproduce production issues quickly by writing tests which run against a real server"""
Expand Down

0 comments on commit acae0e0

Please sign in to comment.