diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f4a67d05..00000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: go - -go: - - "1.x" - -dist: trusty - -matrix: - include: - - os: linux - - os: osx - -install: - - source scripts/ci_install_tiledb.sh - # Testify/asset is only depenencies and used only for testing. - # Install single go dependency so tests explicitly break if - # more dependencies are added - - go get github.com/stretchr/testify/assert -script: - - | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/build_deps/TileDB/dist/lib:/usr/local/lib:$LD_LIBRARY_PATH - else - export DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/build_deps/TileDB/dist/lib:$DYLD_LIBRARY_PATH - fi - - export CGO_CFLAGS="${CGO_CFLAGS} -I${TRAVIS_BUILD_DIR}/build_deps/TileDB/dist/include" - - export CGO_LDFLAGS="${CGO_LDFLAGS} -L${TRAVIS_BUILD_DIR}/build_deps/TileDB/dist/lib" - - scripts/travis.gofmt.sh - - go test -v ./... diff --git a/README.md b/README.md index cc448363..ef1bfa87 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # TileDB Go Bindings [![GoDoc](https://godoc.org/github.com/TileDB-Inc/TileDB-Go?status.svg)](http://godoc.org/github.com/TileDB-Inc/TileDB-Go) -[![Build Status](https://travis-ci.org/TileDB-Inc/TileDB-Go.svg?branch=master)](https://travis-ci.org/TileDB-Inc/TileDB-Go) +[![Build Status](https://dev.azure.com/TileDB-Inc/CI/_apis/build/status/TileDB-Inc.TileDB-Go?branchName=refs%2Fpull%2F123%2Fmerge)](https://dev.azure.com/TileDB-Inc/CI/_build/latest?definitionId=25&branchName=refs%2Fpull%2F123%2Fmerge) This package provides [TileDB](https://github.com/TileDB-Inc/TileDB) golang bindings via cgo. The bindings have been designed to be idomatic Go. `runtime.set_finalizer` is used to ensure proper diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000..adf97e4d --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,45 @@ +# Go +# Build your Go project. +# Add steps that test, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/go + +trigger: + batch: true + branches: + include: + - master + paths: + exclude: + - README.md + - LICENSE + - .gitignore + +pr: + autoCancel: true + branches: + include: + - master + paths: + exclude: + - README.md + - LICENSE + - .gitignore + +variables: + GOPATH: '$(Pipeline.Workspace)/go' + +stages: + - stage: Linux_Test + jobs: + - template: templates/azure/jobs/test.yml + parameters: + pool: + vmImage: 'ubuntu-18.04' + os: 'linux' + - stage: Mac_Test + jobs: + - template: templates/azure/jobs/test.yml + parameters: + pool: + vmImage: 'macos-10.14' + os: 'macos' \ No newline at end of file diff --git a/config_test.go b/config_test.go index d78f21cb..11082478 100644 --- a/config_test.go +++ b/config_test.go @@ -116,7 +116,8 @@ func TestFileConfig(t *testing.T) { os.Remove(tmpPath) } - config.SaveToFile(tmpPath) + err = config.SaveToFile(tmpPath) + assert.Nil(t, err) config2, err := LoadConfig(tmpPath) assert.Nil(t, err) diff --git a/context.go b/context.go index ea9ba90f..bc04aaf4 100644 --- a/context.go +++ b/context.go @@ -45,7 +45,10 @@ func NewContext(config *Config) (*Context, error) { context.Free() }) - context.setDefaultTags() + err1 := context.setDefaultTags() + if err != nil { + return nil, fmt.Errorf("Error creating tiledb context: %s", err1.Error()) + } return &context, nil } diff --git a/context_test.go b/context_test.go index 527c9f1d..f0da75fd 100644 --- a/context_test.go +++ b/context_test.go @@ -38,7 +38,7 @@ func ExampleNewContext() { // handle error return } - // Output: false + // Output: true fmt.Println(isS3Supported) } @@ -56,6 +56,7 @@ func TestNewContext(t *testing.T) { // Test context with config context, err = NewContext(config) assert.Nil(t, err) + assert.NotNil(t, context) } // TestGetContextConfig tests setting a new context diff --git a/enums.go b/enums.go index bf5644ff..185a1fa4 100644 --- a/enums.go +++ b/enums.go @@ -128,10 +128,13 @@ func (d *Datatype) FromString(s string) error { } // DatatypeFromString converts from a datatype string to enum -func DatatypeFromString(s string) Datatype { +func DatatypeFromString(s string) (Datatype, error) { var d Datatype - d.FromString(s) - return d + err := d.FromString(s) + if err != nil { + return TILEDB_ANY, err + } + return d, nil } // ReflectKind returns the reflect kind given a datatype diff --git a/query.go b/query.go index c096a427..8fae7cf8 100644 --- a/query.go +++ b/query.go @@ -22,7 +22,6 @@ type Query struct { tiledbQuery *C.tiledb_query_t array *Array context *Context - uri string buffers []interface{} bufferMutex sync.Mutex resultBufferElements map[string][2]*uint64 @@ -36,7 +35,7 @@ type RangeLimits struct { // MarshalJSON implements the Marshaler interface for RangeLimits func (r RangeLimits) MarshalJSON() ([]byte, error) { - rangeLimitMap := make(map[string]interface{}, 0) + rangeLimitMap := make(map[string]interface{}) rangeLimitMap["end"] = r.end rangeLimitMap["start"] = r.start @@ -75,7 +74,7 @@ func NewQuery(ctx *Context, array *Array) (*Query, error) { query.Free() }) - query.resultBufferElements = make(map[string][2]*uint64, 0) + query.resultBufferElements = make(map[string][2]*uint64) return &query, nil } @@ -1209,7 +1208,7 @@ func (q *Query) SetBufferVar(attributeOrDimension string, offset []uint64, buffe // second is number of elements in the data buffer. For fixed sized attributes // (and coordinates), the first is always 0. func (q *Query) ResultBufferElements() (map[string][2]uint64, error) { - elements := make(map[string][2]uint64, 0) + elements := make(map[string][2]uint64) // Will need the schema to infer data type size for attributes schema, err := q.array.Schema() @@ -1756,16 +1755,16 @@ is the maximum number of elements for that attribute in the given subarray. */ func (q *Query) EstimateBufferElements() (map[string][2]uint64, error) { // Build map - ret := make(map[string][2]uint64, 0) + ret := make(map[string][2]uint64) // Get schema schema, err := q.array.Schema() if err != nil { - return nil, fmt.Errorf("Error getting MaxBufferElements for array: %s", err) + return nil, fmt.Errorf("Error getting EstimateBufferElements for array: %s", err) } attributes, err := schema.Attributes() if err != nil { - return nil, fmt.Errorf("Error getting MaxBufferElements for array: %s", err) + return nil, fmt.Errorf("Error getting EstimateBufferElements for array: %s", err) } // Loop through each attribute for _, attribute := range attributes { @@ -1773,23 +1772,27 @@ func (q *Query) EstimateBufferElements() (map[string][2]uint64, error) { // Check if attribute is variable attribute or not cellValNum, err := attribute.CellValNum() if err != nil { - return nil, fmt.Errorf("Error getting MaxBufferElements for array: %s", err) + return nil, fmt.Errorf("Error getting EstimateBufferElements for array: %s", err) } // Get datatype size to convert byte lengths to needed buffer sizes dataType, err := attribute.Type() + if err != nil { + return nil, fmt.Errorf("Error getting EstimateBufferElements for array: %s", err) + } + dataTypeSize := dataType.Size() // Get attribute name name, err := attribute.Name() if err != nil { - return nil, fmt.Errorf("Error getting MaxBufferElements for array: %s", err) + return nil, fmt.Errorf("Error getting EstimateBufferElements for array: %s", err) } if cellValNum == TILEDB_VAR_NUM { bufferOffsetSize, bufferValSize, err := q.EstResultSizeVar(name) if err != nil { - return nil, fmt.Errorf("Error getting MaxBufferElements for array: %s", err) + return nil, fmt.Errorf("Error getting EstimateBufferElements for array: %s", err) } // Set sizes for attribute in return map ret[name] = [2]uint64{ @@ -1798,7 +1801,7 @@ func (q *Query) EstimateBufferElements() (map[string][2]uint64, error) { } else { bufferValSize, err := q.EstResultSize(name) if err != nil { - return nil, fmt.Errorf("Error getting MaxBufferElements for array: %s", err) + return nil, fmt.Errorf("Error getting EstimateBufferElements for array: %s", err) } ret[name] = [2]uint64{0, *bufferValSize / dataTypeSize} } @@ -1807,7 +1810,7 @@ func (q *Query) EstimateBufferElements() (map[string][2]uint64, error) { // Handle coordinates domain, err := schema.Domain() if err != nil { - return nil, fmt.Errorf("Could not get domain for MaxBufferElements: %s", err) + return nil, fmt.Errorf("Could not get domain for EstimateBufferElements: %s", err) } ndims, err := domain.NDim() diff --git a/query_test.go b/query_test.go index e06b260f..5708bd86 100644 --- a/query_test.go +++ b/query_test.go @@ -1289,8 +1289,6 @@ func TestQueryWrite(t *testing.T) { assert.Equal(t, len(bufferA4), elementsCopied) _, _, err = query.SetBufferVar("a4", offsetBufferA4, bufferA4) - // Immediately set bufferA4 to nil to validate underlying array is not GC'ed - bufferA4 = nil assert.Nil(t, err) bufferA5 := "hello" + "world" diff --git a/scripts/ci_install_tiledb.sh b/scripts/ci_install_tiledb.sh deleted file mode 100755 index 7829064f..00000000 --- a/scripts/ci_install_tiledb.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -set -v -x - -original_dir=$PWD - -# Install tiledb using 2.0.0 release -mkdir build_deps && cd build_deps \ -&& git clone https://github.com/TileDB-Inc/TileDB.git -b 2.0.0 && cd TileDB \ -&& export deps_args="" \ -&& export bootstrap_args="--enable=verbose,static-tiledb,serialization" \ -&& mkdir -p build && cd build - -# Configure and build TileDB -../bootstrap $bootstrap_args \ -&& make -j4 \ -&& make -j4 -C tiledb install - -cd $original_dir - -set +v +x diff --git a/scripts/travis.gofmt.sh b/scripts/travis.gofmt.sh deleted file mode 100755 index 24244813..00000000 --- a/scripts/travis.gofmt.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -if [[ -n "$(gofmt -l .)" ]]; then - echo "TileDB-Go code is not formatted:" - gofmt -d . - exit 1 -else - echo "TileDB-Go code is well formatted." -fi \ No newline at end of file diff --git a/templates/azure/jobs/test.yml b/templates/azure/jobs/test.yml new file mode 100644 index 00000000..96bfe97c --- /dev/null +++ b/templates/azure/jobs/test.yml @@ -0,0 +1,64 @@ +jobs: + - job: RunTests + strategy: + matrix: + GoVersion_1_13: + go.version: '1.13' + GoVersion_1_14: + go.version: '1.14' + + pool: + vmImage: 'ubuntu-18.04' + + steps: + - script: echo ${{ parameters.os }} + + - template: ../steps/setup_go.yml + parameters: + goVersion: '$(go.version)' + + - template: ../steps/format_go.yml + + - ${{ if eq(parameters.os, 'linux') }}: + - template: ../steps/install_tiledb_linux.yml + + - ${{ if eq(parameters.os, 'macos') }}: + - template: ../steps/install_tiledb_macos.yml + + - script: | + set -e -x + go version + go get -u github.com/jstemmer/go-junit-report + go get github.com/axw/gocov/gocov + go get github.com/AlekSi/gocov-xml + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.24.0 + curl https://cdn.shiftleft.io/download/sl > $(go env GOPATH)/bin/sl && chmod a+rx $(go env GOPATH)/bin/sl + displayName: 'Install Dependencies' + + - ${{ if eq(parameters.os, 'linux') }}: + - script: | + set -e -x + golangci-lint run + displayName: 'Run Code Quality Checks' + + - script: | + set -v -x + go test -v -coverprofile=coverage.txt -covermode count ./... > test_results.txt + go-junit-report < test_results.txt > report.xml + displayName: 'Run Unit Tests' + - task: PublishTestResults@2 + displayName: 'Publish Test Results' + inputs: + testRunner: JUnit + testResultsFiles: $(System.DefaultWorkingDirectory)/**/report.xml + + - script: | + set -e -x + gocov convert coverage.txt > coverage.json + gocov-xml < coverage.json > coverage.xml + displayName: 'Run Code Coverage Tests' + - task: PublishCodeCoverageResults@1 + displayName: 'Publish Code Coverage' + inputs: + codeCoverageTool: Cobertura + summaryFileLocation: $(System.DefaultWorkingDirectory)/**/coverage.xml \ No newline at end of file diff --git a/templates/azure/steps/format_go.yml b/templates/azure/steps/format_go.yml new file mode 100644 index 00000000..b7732f9b --- /dev/null +++ b/templates/azure/steps/format_go.yml @@ -0,0 +1,11 @@ +steps: + - script: | + ls -al + if [[ -n "$(gofmt -l .)" ]]; then + echo "TileDB-Go code is not formatted:" + gofmt -d . + exit 1 + else + echo "TileDB-Go code is well formatted." + fi + displayName: 'Checks formatting of Go code' \ No newline at end of file diff --git a/templates/azure/steps/install_tiledb_linux.yml b/templates/azure/steps/install_tiledb_linux.yml new file mode 100644 index 00000000..9cd53a33 --- /dev/null +++ b/templates/azure/steps/install_tiledb_linux.yml @@ -0,0 +1,8 @@ +# Install TileDB in a system location +steps: + - script: | + set -e -x + curl --location -o tiledb.tar.gz https://github.com/TileDB-Inc/TileDB/releases/download/2.0.8/tiledb-linux-2.0.8-db41376-full.tar.gz \ + && sudo tar -C /usr/local -xf tiledb.tar.gz + sudo ldconfig /usr/local/lib + displayName: 'Install TileDB' \ No newline at end of file diff --git a/templates/azure/steps/install_tiledb_macos.yml b/templates/azure/steps/install_tiledb_macos.yml new file mode 100644 index 00000000..bb136c67 --- /dev/null +++ b/templates/azure/steps/install_tiledb_macos.yml @@ -0,0 +1,7 @@ +# Install TileDB in a system location +steps: + - script: | + set -e -x + curl --location -o tiledb.tar.gz https://github.com/TileDB-Inc/TileDB/releases/download/2.0.8/tiledb-macos-2.0.8-db41376-full.tar.gz \ + && sudo tar -C /usr/local -xf tiledb.tar.gz + displayName: 'Install TileDB' \ No newline at end of file diff --git a/templates/azure/steps/setup_go.yml b/templates/azure/steps/setup_go.yml new file mode 100644 index 00000000..9938f6e9 --- /dev/null +++ b/templates/azure/steps/setup_go.yml @@ -0,0 +1,15 @@ +parameters: + goVersion: '1.14' + +steps: + - task: GoTool@0 + displayName: 'Use Go ${{ parameters.goVersion }}' + inputs: + version: ${{ parameters.goVersion }} + + - script: | + set -e -x + mkdir -p '$(GOPATH)/bin' + echo '##vso[task.prependpath]$(GOROOT)/bin' + echo '##vso[task.prependpath]$(GOPATH)/bin' + displayName: 'Create Go Workspace' \ No newline at end of file