Skip to content

Commit 4c9642a

Browse files
committed
Merge remote-tracking branch 'origin/main' into CBG-4267
2 parents 61b4a72 + 8a7f39c commit 4c9642a

20 files changed

+398
-289
lines changed

Jenkinsfile

Lines changed: 3 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ pipeline {
1111
EE_BUILD_TAG = "cb_sg_enterprise"
1212
SGW_REPO = "github.com/couchbase/sync_gateway"
1313
GH_ACCESS_TOKEN_CREDENTIAL = "github_cb-robot-sg_access_token"
14-
GO111MODULE = "on"
15-
GOCACHE = "${WORKSPACE}/.gocache"
1614
}
1715

1816
tools {
@@ -42,7 +40,7 @@ pipeline {
4240
sh "which go"
4341
sh "go version"
4442
sh "go env"
45-
sshagent(credentials: ['CB SG Robot Github SSH Key']) {
43+
sshagent(credentials: ['CB_SG_Robot_Github_SSH_Key']) {
4644
sh '''
4745
[ -d ~/.ssh ] || mkdir ~/.ssh && chmod 0700 ~/.ssh
4846
ssh-keyscan -t rsa,dsa github.com >> ~/.ssh/known_hosts
@@ -66,12 +64,6 @@ pipeline {
6664

6765
stage('Builds') {
6866
parallel {
69-
stage('Test compile') {
70-
steps {
71-
// run no tests but force them to be compiled
72-
sh "go test -run=- -count=1 ./..."
73-
}
74-
}
7567
stage('CE Linux') {
7668
steps {
7769
sh "GOOS=linux go build -o sync_gateway_ce-linux -v ${SGW_REPO}"
@@ -82,38 +74,6 @@ pipeline {
8274
sh "GOOS=linux go build -o sync_gateway_ee-linux -tags ${EE_BUILD_TAG} -v ${SGW_REPO}"
8375
}
8476
}
85-
stage('CE macOS') {
86-
// TODO: Remove skip
87-
when { expression { return false } }
88-
steps {
89-
withEnv(["PATH+GO=${GOPATH}/bin"]) {
90-
echo 'TODO: figure out why build issues are caused by gosigar'
91-
sh "GOOS=darwin go build -o sync_gateway_ce-darwin -v ${SGW_REPO}"
92-
}
93-
}
94-
}
95-
stage('EE macOS') {
96-
// TODO: Remove skip
97-
when { expression { return false } }
98-
steps {
99-
withEnv(["PATH+GO=${GOPATH}/bin"]) {
100-
echo 'TODO: figure out why build issues are caused by gosigar'
101-
sh "GOOS=darwin go build -o sync_gateway_ee-darwin -tags ${EE_BUILD_TAG} -v ${SGW_REPO}"
102-
}
103-
}
104-
}
105-
/* can't build windows with cgo
106-
stage('CE Windows') {
107-
steps {
108-
sh "GOOS=windows go build -o sync_gateway_ce-windows -v ${SGW_REPO}"
109-
}
110-
}
111-
stage('EE Windows') {
112-
steps {
113-
sh "GOOS=windows go build -o sync_gateway_ee-windows -tags ${EE_BUILD_TAG} -v ${SGW_REPO}"
114-
}
115-
}
116-
*/
11777
stage('Windows Service') {
11878
steps {
11979
sh "GOOS=windows go build -o sync_gateway_ce-windows-service -v ${SGW_REPO}/service/sg-windows/sg-service"
@@ -122,68 +82,6 @@ pipeline {
12282
}
12383
}
12484

125-
stage('Checks') {
126-
parallel {
127-
stage('gofmt') {
128-
steps {
129-
script {
130-
try {
131-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-gofmt', description: 'Running', status: 'PENDING')
132-
sh "which gofmt" // check if gofmt is installed
133-
sh "gofmt -d -e . | tee gofmt.out"
134-
sh "test -z \"\$(cat gofmt.out)\""
135-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-gofmt', description: 'OK', status: 'SUCCESS')
136-
} catch (Exception e) {
137-
sh "wc -l < gofmt.out | awk '{printf \$1}' > gofmt.count"
138-
script {
139-
env.GOFMT_COUNT = readFile 'gofmt.count'
140-
}
141-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-gofmt', description: "found "+env.GOFMT_COUNT+" problems", status: 'FAILURE')
142-
unstable("gofmt failed")
143-
}
144-
}
145-
}
146-
}
147-
stage('go vet') {
148-
steps {
149-
warnError(message: "go vet failed") {
150-
sh "go vet -tags ${EE_BUILD_TAG} ./..."
151-
}
152-
}
153-
}
154-
stage('go fix') {
155-
steps {
156-
warnError(message: "go fix failed") {
157-
sh "go tool fix -diff . | tee gofix.out"
158-
sh "test -z \"\$(cat gofix.out)\""
159-
}
160-
}
161-
}
162-
stage('errcheck') {
163-
steps {
164-
script {
165-
try {
166-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-errcheck', description: 'Running', status: 'PENDING')
167-
withEnv(["PATH+GO=${env.GOTOOLS}/bin"]) {
168-
sh "which errcheck" // check if errcheck is installed
169-
sh "errcheck ./... | tee errcheck.out"
170-
}
171-
sh "test -z \"\$(cat errcheck.out)\""
172-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-errcheck', description: 'OK', status: 'SUCCESS')
173-
} catch (Exception e) {
174-
sh "wc -l < errcheck.out | awk '{printf \$1}' > errcheck.count"
175-
script {
176-
env.ERRCHECK_COUNT = readFile 'errcheck.count'
177-
}
178-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-errcheck', description: "found "+env.ERRCHECK_COUNT+" unhandled errors", status: 'FAILURE')
179-
unstable("errcheck failed")
180-
}
181-
}
182-
}
183-
}
184-
}
185-
}
186-
18785
stage('Tests') {
18886
parallel {
18987
stage('Unit') {
@@ -285,41 +183,6 @@ pipeline {
285183
}
286184
}
287185
}
288-
289-
stage('LiteCore') {
290-
stages {
291-
stage('against CE') {
292-
// TODO: Remove skip
293-
when { expression { return false } }
294-
steps {
295-
echo 'Example of where we could run an alternate version of lite-core unit tests, or against a running SG CE'
296-
}
297-
}
298-
stage('against EE') {
299-
// CBG-2237 skipping stage due to regular litecore test segfaults
300-
when { expression { return false } }
301-
steps {
302-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-litecore-ee', description: 'Running LiteCore Tests', status: 'PENDING')
303-
sh 'touch verbose_litecore.out'
304-
sh 'touch verbose_litecore-sg_trace.out'
305-
script {
306-
withCredentials([sshUserPrivateKey(credentialsId: 'CB SG Robot Github SSH Key', keyFileVariable: 'KEY')]) {
307-
try {
308-
sh 'docker run --rm -v $KEY:/root/.ssh/id_rsa -v `pwd`/sync_gateway_ee-linux:/sync_gateway -v `pwd`/verbose_litecore.out:/output.out -v `pwd`/verbose_litecore-sg_trace.out:/tmp/sglog/sg_trace.log couchbase/sg-test-litecore:latest -legacy-config'
309-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-litecore-ee', description: 'EE with LiteCore Test Passed', status: 'SUCCESS')
310-
} catch (Exception e) {
311-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-litecore-ee', description: 'EE with LiteCore Test Failed', status: 'FAILURE')
312-
// archive verbose test logs in the event of a test failure
313-
archiveArtifacts artifacts: 'verbose_litecore*.out', fingerprint: false
314-
unstable("EE LIteCore Test Failed")
315-
}
316-
}
317-
}
318-
}
319-
}
320-
}
321-
}
322-
323186
stage('Integration') {
324187
stages {
325188
stage('main') {
@@ -328,23 +191,7 @@ pipeline {
328191
echo 'Queueing Integration test for branch "main" ...'
329192
// Queues up an async integration test run using default build params (main branch),
330193
// but waits up to an hour for batches of PR merges before actually running (via quietPeriod)
331-
build job: 'MasterIntegration', quietPeriod: 3600, wait: false
332-
}
333-
}
334-
335-
stage('PR') {
336-
// TODO: Remove skip
337-
when { expression { return false } }
338-
steps {
339-
// TODO: Read labels on PR for 'integration-test'
340-
// if present, run stage as separate GH status
341-
echo 'Example of where we can run integration tests for this commit'
342-
gitStatusWrapper(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", description: 'Running EE Integration Test', failureDescription: 'EE Integration Test Failed', gitHubContext: 'sgw-pipeline-integration-ee', successDescription: 'EE Integration Test Passed') {
343-
echo "Waiting for integration test to finish..."
344-
// TODO: add commit parameter
345-
// Block the pipeline, but don't propagate a failure up to the top-level job - rely on gitStatusWrapper letting us know it failed
346-
build job: 'sync-gateway-integration-master', wait: true, propagate: false
347-
}
194+
build job: 'MainIntegration', quietPeriod: 3600, wait: false
348195
}
349196
}
350197
}
@@ -397,7 +244,6 @@ pipeline {
397244
}
398245
cleanup {
399246
cleanWs(disableDeferredWipeout: true)
400-
sh "go clean -cache"
401-
}
247+
}
402248
}
403249
}

base/logging_context.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ func NewTaskID(contextID string, taskName string) string {
176176

177177
// TestCtx creates a context for the given test which is also cancelled once the test has completed.
178178
func TestCtx(t testing.TB) context.Context {
179-
return LogContextWith(t.Context(), &LogContext{TestName: t.Name()})
179+
ctx, cancelCtx := context.WithCancel(context.Background())
180+
t.Cleanup(cancelCtx)
181+
return LogContextWith(ctx, &LogContext{TestName: t.Name()})
180182
}
181183

182184
// BucketCtx extends the parent context with a bucket name.

base/util.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,3 +1814,14 @@ func SlicesEqualIgnoreOrder[T comparable](a, b []T) bool {
18141814
}
18151815
return true
18161816
}
1817+
1818+
// KeysPresent returns the subset of keys that are present in m, preserving input order of keys.
1819+
func KeysPresent[K comparable, V any](m map[K]V, keys []K) []K {
1820+
result := make([]K, 0, len(keys))
1821+
for _, k := range keys {
1822+
if _, ok := m[k]; ok {
1823+
result = append(result, k)
1824+
}
1825+
}
1826+
return result
1827+
}

base/util_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,3 +1807,50 @@ func TestSlicesEqualUnordered(t *testing.T) {
18071807
})
18081808
}
18091809
}
1810+
1811+
func TestKeysPresent(t *testing.T) {
1812+
tests := []struct {
1813+
name string
1814+
m map[string]int
1815+
keys []string
1816+
want []string
1817+
}{
1818+
{
1819+
name: "all present",
1820+
m: map[string]int{"a": 1, "b": 2, "c": 3},
1821+
keys: []string{"a", "b"},
1822+
want: []string{"a", "b"},
1823+
},
1824+
{
1825+
name: "some present",
1826+
m: map[string]int{"a": 1, "b": 2},
1827+
keys: []string{"a", "x", "b", "y"},
1828+
want: []string{"a", "b"},
1829+
},
1830+
{
1831+
name: "none present",
1832+
m: map[string]int{"a": 1},
1833+
keys: []string{"x", "y"},
1834+
want: []string{},
1835+
},
1836+
{
1837+
name: "empty keys",
1838+
m: map[string]int{"a": 1},
1839+
keys: nil,
1840+
want: []string{},
1841+
},
1842+
{
1843+
name: "empty map",
1844+
m: map[string]int{},
1845+
keys: []string{"a"},
1846+
want: []string{},
1847+
},
1848+
}
1849+
1850+
for _, tc := range tests {
1851+
t.Run(tc.name, func(t *testing.T) {
1852+
got := KeysPresent(tc.m, tc.keys)
1853+
assert.Equal(t, tc.want, got)
1854+
})
1855+
}
1856+
}

db/active_replicator.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ func connect(arc *activeReplicatorCommon, idSuffix string) (blipSender *blip.Sen
258258
return nil, nil, err
259259
}
260260

261+
// set client type to SGW on active peer
262+
bsc.SetClientType(BLIPClientTypeSGR2)
263+
261264
// set active subprotocol after handshake
262265
err = bsc.SetActiveCBMobileSubprotocol(blipContext.ActiveSubprotocol())
263266
if err != nil {

db/active_replicator_common.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@ func newActiveReplicatorCommon(ctx context.Context, config *ActiveReplicatorConf
123123
statusKey: metakeys.ReplicationStatusKey(checkpointID),
124124
direction: direction,
125125
}
126-
// CBG-4780: WIll hard code to use < 4 protocols for now, as the ISGR doesn't support 4+ protocols.
127-
arc.config.SupportedBLIPProtocols = []string{CBMobileReplicationV3.SubprotocolString(), CBMobileReplicationV2.SubprotocolString()}
128126

129127
if config.CollectionsEnabled {
130128
arc.namedCollections = make(map[base.ScopeAndCollectionName]*activeReplicatorCollection)

db/blip.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func defaultBlipLogger(ctx context.Context) blip.LogFn {
8484
}
8585

8686
// blipRevMessageProperties returns a set of BLIP message properties for the given parameters.
87-
func blipRevMessageProperties(revisionHistory []string, deleted bool, seq SequenceID, replacedRevID string) blip.Properties {
87+
func blipRevMessageProperties(revisionHistory []string, deleted bool, seq SequenceID, replacedRevID string, revTreeProperty []string) blip.Properties {
8888
properties := make(blip.Properties)
8989

9090
// TODO: Assert? db.SequenceID.MarshalJSON can never error
@@ -95,6 +95,10 @@ func blipRevMessageProperties(revisionHistory []string, deleted bool, seq Sequen
9595
properties[RevMessageHistory] = strings.Join(revisionHistory, ",")
9696
}
9797

98+
if len(revTreeProperty) > 0 {
99+
properties[RevMessageTreeHistory] = strings.Join(revTreeProperty, ",")
100+
}
101+
98102
if deleted {
99103
properties[RevMessageDeleted] = "1"
100104
}

0 commit comments

Comments
 (0)