Skip to content

Commit 395c004

Browse files
committed
C++ SDK: initial import from Jenkins
1 parent d928a25 commit 395c004

File tree

1 file changed

+334
-0
lines changed

1 file changed

+334
-0
lines changed
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
def PLATFORMS = [ "ubuntu20", "centos7", "centos8", "macos", "m1", "amzn2", "qe-grav2-amzn2", "alpine", "windows", "qe-ubuntu20-arm64" ]
2+
def CB_VERSIONS = [
3+
"66release": [tag: "6.6-release"],
4+
"71release": [tag: "7.1-release"],
5+
"71stable": [tag: "7.1-stable"],
6+
"72stable": [tag: "7.2-stable"]
7+
]
8+
// no 7.0.4 release for community
9+
if (USE_CE.toBoolean()) {
10+
CB_VERSIONS["70release"] = [tag: "7.0.2", label: "7.0-release"]
11+
} else {
12+
CB_VERSIONS["70release"] = [tag: "7.0-release"]
13+
// 7.5 only supported on EE
14+
CB_VERSIONS["75stable"] = [tag: "7.5-stable"]
15+
CB_VERSIONS["75serverless"] = [tag: "7.5-stable", serverless: true, label: "7.5-serverless"]
16+
}
17+
def COMBINATION_PLATFORM = "centos7"
18+
19+
def checkout() {
20+
dir("couchbase-cxx-client") {
21+
checkout([
22+
$class: "GitSCM",
23+
branches: [[name: "$SHA"]],
24+
userRemoteConfigs: [[url: "$REPO", refspec: "$REFSPEC"]],
25+
extensions: [[
26+
$class: "SubmoduleOption",
27+
disableSubmodules: false,
28+
parentCredentials: false,
29+
recursiveSubmodules: true,
30+
reference: "",
31+
trackingSubmodules: false
32+
]]
33+
])
34+
}
35+
}
36+
37+
stage("prepare and validate") {
38+
node("sdkqe-$COMBINATION_PLATFORM") {
39+
cleanWs()
40+
checkout()
41+
42+
stash includes: "couchbase-cxx-client/", name: "couchbase-cxx-client", useDefaultExcludes: false
43+
}
44+
}
45+
46+
stage("build") {
47+
def builds = [:]
48+
for (p in PLATFORMS) {
49+
def platform = p
50+
builds[platform]= {
51+
node(platform) {
52+
stage("prep") {
53+
dir("ws_${platform}") {
54+
deleteDir()
55+
if (platform == "windows") {
56+
checkout()
57+
} else {
58+
unstash "couchbase-cxx-client"
59+
}
60+
}
61+
}
62+
stage("build") {
63+
def envs = ["CB_NUMBER_OF_JOBS=4"]
64+
if (platform == "macos") {
65+
envs.push("OPENSSL_ROOT_DIR=/usr/local/opt/openssl")
66+
} else if (platform == "m1") {
67+
envs.push("OPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl")
68+
} else if (platform == "qe-grav2-amzn2") {
69+
envs.push("CB_CC=/usr/bin/gcc10-cc")
70+
envs.push("CB_CXX=/usr/bin/gcc10-c++")
71+
} else if (platform == "amzn2") {
72+
envs.push("CB_CC=/opt/gcc-10.2.0/bin/cc")
73+
envs.push("CB_CXX=/opt/gcc-10.2.0/bin/c++")
74+
} else if (platform == "centos7") {
75+
envs.push("CB_CC=/opt/rh/devtoolset-9/root/usr/bin/cc")
76+
envs.push("CB_CXX=/opt/rh/devtoolset-9/root/usr/bin/c++")
77+
}
78+
if (platform == "windows") {
79+
bat("cbdep install -d deps openssl 1.1.1g-sdk2")
80+
path = PATH
81+
path += ";$WORKSPACE/deps/openssl-1.1.1g-sdk2"
82+
envs.push("PATH=$path")
83+
}
84+
withEnv(envs) {
85+
dir("ws_${platform}/couchbase-cxx-client") {
86+
if (platform == "windows") {
87+
dir("build") {
88+
bat("cmake ..")
89+
bat("cmake --build . --parallel $CB_NUMBER_OF_JOBS")
90+
}
91+
} else {
92+
sh("./bin/build-tests")
93+
}
94+
}
95+
}
96+
if (platform == COMBINATION_PLATFORM) {
97+
stash(includes: "ws_${platform}/", name: "${platform}_build", useDefaultExcludes: false)
98+
}
99+
}
100+
}
101+
}
102+
}
103+
parallel(builds)
104+
}
105+
106+
class DynamicCluster {
107+
String id_ = null;
108+
String ips_ = null;
109+
String version_ = null;
110+
boolean useTLS = false;
111+
boolean useCertAuth = false;
112+
String certsDir = null;
113+
String connstr = null;
114+
115+
DynamicCluster(String version) {
116+
this.version_ = version
117+
}
118+
119+
String clusterId() {
120+
return id_
121+
}
122+
123+
String connectionString() {
124+
if (connstr != null) {
125+
return connstr
126+
}
127+
def prefix = "couchbase://"
128+
if (useTLS) {
129+
prefix = "couchbases://"
130+
}
131+
def connstr = prefix + ips_
132+
if (useTLS) {
133+
connstr += "?trust_certificate=$certsDir/ca.pem"
134+
}
135+
return connstr
136+
}
137+
138+
String firstIP() {
139+
return ips_.tokenize(",")[0]
140+
}
141+
142+
String version() {
143+
return version_.tokenize("_")[0]
144+
}
145+
146+
int major() {
147+
return version().tokenize(".")[0] as Integer
148+
}
149+
150+
int minor() {
151+
// e.g. 7.1-stable or 7.1.0 becomes 1
152+
return version().tokenize("-")[0].tokenize(".")[1] as Integer
153+
}
154+
155+
int numRootCAs() {
156+
if (major() > 7 || (major() == 7 && minor() >= 1)) {
157+
return 2
158+
} else {
159+
return 1
160+
}
161+
}
162+
163+
String certPath() {
164+
if (useCertAuth) {
165+
return "$certsDir/client.pem"
166+
} else {
167+
return ""
168+
}
169+
}
170+
171+
String keyPath() {
172+
if (useCertAuth) {
173+
return "$certsDir/client.key"
174+
} else {
175+
return ""
176+
}
177+
}
178+
179+
boolean supportsStorageBackend() {
180+
return major() > 7 || (major() == 7 && minor() >= 1)
181+
}
182+
}
183+
184+
if (!SKIP_TESTS.toBoolean()) {
185+
stage("combination-test") {
186+
def cbverStages = [:]
187+
CB_VERSIONS.each{cb_version ->
188+
def v = cb_version.value
189+
def version = v["tag"]
190+
def label = version
191+
def serverless = false
192+
if (v["label"] != null) {
193+
label = v["label"]
194+
}
195+
if (v["serverless"] != null) {
196+
serverless = v["serverless"].toBoolean()
197+
}
198+
cbverStages[label] = {
199+
node("sdkqe-$COMBINATION_PLATFORM") {
200+
def CLUSTER = new DynamicCluster(version)
201+
try {
202+
stage("env") {
203+
withEnv([
204+
"AUTH=cxx-sdk-${BUILD_NUMBER}@couchbase.com"
205+
]){
206+
deleteDir()
207+
def allocate_cmd = "cbdyncluster allocate --num-nodes=3 --server-version=${version} --platform ec2"
208+
if (USE_CE.toBoolean()) {
209+
allocate_cmd += " --use-ce"
210+
}
211+
if (serverless) {
212+
allocate_cmd += " --serverless-mode"
213+
}
214+
CLUSTER.id_ = sh(script: allocate_cmd, returnStdout: true).trim()
215+
CLUSTER.ips_ = sh(script: "cbdyncluster ips ${CLUSTER.clusterId()}", returnStdout: true).trim()
216+
def secondNodeServices = "kv"
217+
if (USE_CE.toBoolean()) {
218+
sh("cbdyncluster setup ${CLUSTER.clusterId()} --node=kv,index,n1ql,fts --node ${secondNodeServices} --node=kv --storage-mode=forestdb --ram-quota 2048")
219+
} else {
220+
// all indexes in serverless mode must be created with 2 replicas
221+
if (serverless) {
222+
secondNodeServices = "kv,index,fts"
223+
}
224+
sh("cbdyncluster setup ${CLUSTER.clusterId()} --node=kv,index,n1ql --node ${secondNodeServices} --node=fts,cbas,eventing --storage-mode=plasma --ram-quota 2048")
225+
}
226+
if (USE_TLS.toBoolean()) {
227+
CLUSTER.useTLS = true
228+
CLUSTER.certsDir = WORKSPACE
229+
sh("cbdyncluster setup-cert-auth ${CLUSTER.clusterId()} --user Administrator --num-roots ${CLUSTER.numRootCAs()}")
230+
}
231+
CLUSTER.useCertAuth = USE_CERT_AUTH.toBoolean()
232+
def add_bucket_cmd = "cbdyncluster add-bucket ${CLUSTER.clusterId()} --name default --ram-quota 256"
233+
if (serverless) {
234+
// FIXME: Just add more kv nodes
235+
// because we don't create server groups the bucket only gets placed on 1 node so we can't do durable operations if we have replicas
236+
add_bucket_cmd += " --width 1 --replica-count 0 --storage-backend magma"
237+
} else if (CLUSTER.supportsStorageBackend()) {
238+
add_bucket_cmd += " --storage-backend ${STORAGE_BACKEND}"
239+
}
240+
sh(add_bucket_cmd)
241+
sh("cbdyncluster add-sample-bucket ${CLUSTER.clusterId()} --name travel-sample")
242+
sh("curl -sS -uAdministrator:password http://${CLUSTER.firstIP()}:8093/query/service -d'statement=CREATE PRIMARY INDEX ON default USING GSI' -d 'timeout=300s'")
243+
}
244+
}
245+
timeout(unit: 'MINUTES', time: 30) {
246+
stage("test") {
247+
unstash("${COMBINATION_PLATFORM}_build")
248+
withEnv([
249+
"TEST_CONNECTION_STRING=${CLUSTER.connectionString()}",
250+
"CTEST_OUTPUT_ON_FAILURE=1",
251+
"TEST_LOG_LEVEL=trace",
252+
"TEST_CERTIFICATE_PATH=${CLUSTER.certPath()}",
253+
"TEST_KEY_PATH=${CLUSTER.keyPath()}",
254+
"AUTH=cxx-sdk-${BUILD_NUMBER}@couchbase.com"
255+
]) {
256+
dir("ws_${COMBINATION_PLATFORM}/couchbase-cxx-client") {
257+
try {
258+
sh("./bin/run-unit-tests")
259+
} catch(e) {
260+
dir("server_logs_${label}") {
261+
sh("cbdyncluster cbcollect ${CLUSTER.clusterId()}")
262+
}
263+
archiveArtifacts(artifacts: "server_logs_${label}/*.zip", allowEmptyArchive: true)
264+
throw e
265+
} finally {
266+
junit("cmake-build-tests/results.xml")
267+
}
268+
}
269+
}
270+
}
271+
}
272+
} finally {
273+
stage("cleanup") {
274+
withEnv([
275+
"AUTH=cxx-sdk-${BUILD_NUMBER}@couchbase.com"
276+
]) {
277+
sh("cbdyncluster rm ${CLUSTER.clusterId()}")
278+
}
279+
}
280+
}
281+
}
282+
}
283+
}
284+
cbverStages["capella"] = {
285+
node("sdkqe-$COMBINATION_PLATFORM") {
286+
def CLUSTER = new DynamicCluster("capella")
287+
try {
288+
stage("env") {
289+
withEnv([
290+
"AUTH=cxx-sdk-${BUILD_NUMBER}@couchbase.com"
291+
]){
292+
deleteDir()
293+
CLUSTER.id_ = sh(script: "cbdyncluster create-cloud --node kv,index,n1ql,eventing,fts,cbas --node kv,index,n1ql,eventing,fts,cbas --node kv,index,n1ql,eventing,fts,cbas", returnStdout: true).trim()
294+
CLUSTER.ips_ = sh(script: "cbdyncluster ips ${CLUSTER.clusterId()}", returnStdout: true).trim()
295+
sh("cbdyncluster add-bucket ${CLUSTER.clusterId()} --name default --ram-quota 256")
296+
sh("cbdyncluster add-sample-bucket ${CLUSTER.clusterId()} --name travel-sample")
297+
sh("curl -k -sS -uAdministrator:P@ssword1 https://${CLUSTER.firstIP()}:18093/query/service -d'statement=CREATE PRIMARY INDEX ON default USING GSI' -d 'timeout=300s'")
298+
CLUSTER.connstr = sh(script: "cbdyncluster connstr ${CLUSTER.clusterId()} --ssl", returnStdout: true).trim()
299+
}
300+
}
301+
timeout(unit: 'MINUTES', time: 30) {
302+
stage("test") {
303+
unstash("${COMBINATION_PLATFORM}_build")
304+
withEnv([
305+
"TEST_CONNECTION_STRING=${CLUSTER.connectionString()}",
306+
"CTEST_OUTPUT_ON_FAILURE=1",
307+
"TEST_LOG_LEVEL=trace",
308+
"TEST_PASSWORD=P@ssword1",
309+
"TEST_DEPLOYMENT_TYPE=capella"
310+
]) {
311+
dir("ws_${COMBINATION_PLATFORM}/couchbase-cxx-client") {
312+
try {
313+
sh("./bin/run-unit-tests")
314+
} finally {
315+
junit("cmake-build-tests/results.xml")
316+
}
317+
}
318+
}
319+
}
320+
}
321+
} finally {
322+
stage("cleanup") {
323+
withEnv([
324+
"AUTH=cxx-sdk-${BUILD_NUMBER}@couchbase.com"
325+
]) {
326+
sh("cbdyncluster rm ${CLUSTER.clusterId()}")
327+
}
328+
}
329+
}
330+
}
331+
}
332+
parallel(cbverStages)
333+
}
334+
}

0 commit comments

Comments
 (0)