Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,18 @@ jobs:
# the file with `test_registry` also requires windows, so we can safely add this tag
# without it running on non-windows OSes
run: go test -v -tags test_registry ./...
- name: Run User Integration Tests (Unix)
if: runner.os != 'Windows'
env:
DBC_RUN_INTEGRATION_TESTS: 1
run: go test -v -tags test_integration,test_user -run TestIntegration ./cmd/dbc
- name: Run System Integration Tests (Unix)
if: runner.os != 'Windows'
env:
DBC_RUN_INTEGRATION_TESTS: 1
run: sudo go test -v -tags test_integration,test_system -run TestIntegration ./cmd/dbc
- name: Run Integration Tests (Windows)
if: runner.os == 'Windows'
env:
DBC_RUN_INTEGRATION_TESTS: 1
run: go test -v -tags test_integration -run TestIntegration ./cmd/dbc
35 changes: 35 additions & 0 deletions cmd/dbc/integation_user_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2025 Columnar Technologies Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build test_integration && test_user

package main

import (
"path/filepath"

"github.com/columnar-tech/dbc/config"
)

func (suite *IntegrationTestSuite) TestInstallUser() {
m := InstallCmd{Driver: "test-driver-1", Level: config.ConfigUser}.
GetModelCustom(baseModel{getDriverRegistry: getTestDriverRegistry, downloadPkg: downloadTestPkg})
out := suite.run(m)

loc := config.GetLocation(config.ConfigUser)
suite.Equal("\nInstalled test-driver-1 1.1.0 to "+loc+"\n", out)
suite.driverIsInstalled(config.ConfigUser, "test-driver-1")
suite.FileExists(filepath.Join(loc, "test-driver-1.1", "test-driver-1-not-valid.so"))
suite.FileExists(filepath.Join(loc, "test-driver-1.1", "test-driver-1-not-valid.so.sig"))
}
35 changes: 35 additions & 0 deletions cmd/dbc/integration_system_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2025 Columnar Technologies Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build test_integration && test_system

package main

import (
"path/filepath"

"github.com/columnar-tech/dbc/config"
)

func (suite *IntegrationTestSuite) TestInstallSystem() {
m := InstallCmd{Driver: "test-driver-1", Level: config.ConfigSystem}.
GetModelCustom(baseModel{getDriverRegistry: getTestDriverRegistry, downloadPkg: downloadTestPkg})
out := suite.run(m)

loc := config.GetLocation(config.ConfigSystem)
suite.Equal("\nInstalled test-driver-1 1.1.0 to "+loc+"\n", out)
suite.driverIsInstalled(config.ConfigSystem, "test-driver-1")
suite.FileExists(filepath.Join(loc, "test-driver-1.1", "test-driver-1-not-valid.so"))
suite.FileExists(filepath.Join(loc, "test-driver-1.1", "test-driver-1-not-valid.so.sig"))
}
66 changes: 66 additions & 0 deletions cmd/dbc/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2025 Columnar Technologies Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build test_integration

package main

import (
"bytes"
"context"
"os"
"testing"
"time"

tea "github.com/charmbracelet/bubbletea"
"github.com/stretchr/testify/suite"
)

type IntegrationTestSuite struct {
suite.Suite
}

func (suite *IntegrationTestSuite) SetupSuite() {
// Integration tests require both the build tag AND environment variable
if os.Getenv("DBC_RUN_INTEGRATION_TESTS") == "" {
suite.T().Skip("Set DBC_RUN_INTEGRATION_TESTS=1 to run integration tests")
}
}

func (s *IntegrationTestSuite) run(m tea.Model) string {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

var out bytes.Buffer
p := tea.NewProgram(m, tea.WithInput(nil), tea.WithOutput(&out),
tea.WithContext(ctx), tea.WithoutRenderer())

var err error
m, err = p.Run()
s.Require().NoError(err)
s.Equal(0, m.(HasStatus).Status(), "exited with a non-zero status")

var extra string
if fo, ok := m.(HasFinalOutput); ok {
extra = fo.FinalOutput()
}
return out.String() + extra
}

// This test suite only runs when the "test_integration" build tag is set. These
// tests are intended to only be run in VMs or on CI because they may modify
// user and system files and the Windows registry.
func TestIntegration(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}
42 changes: 42 additions & 0 deletions cmd/dbc/integration_test_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//go:build test_integration && !windows

// Copyright 2025 Columnar Technologies Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"os"

"github.com/columnar-tech/dbc/config"
)

func (suite *IntegrationTestSuite) TearDownTest() {
os.RemoveAll(config.GetLocation(config.ConfigUser))
os.RemoveAll(config.GetLocation(config.ConfigSystem))
}

func (suite *IntegrationTestSuite) driverIsInstalled(level config.ConfigLevel, driverID string) {
cfg := config.Config{
Level: level,
Location: config.GetLocation(level),
}

driverInfo, err := config.GetDriver(cfg, driverID)
suite.Require().NoError(err, "should be able to load driver from manifest")

// Get and verify driver path exists
driverPath := driverInfo.Driver.Shared.Get(config.PlatformTuple())
suite.FileExists(driverPath)
}
58 changes: 58 additions & 0 deletions cmd/dbc/integration_test_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2025 Columnar Technologies Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build test_integration && windows

package main

import (
"os"

"github.com/columnar-tech/dbc/config"
"golang.org/x/sys/windows/registry"
)

func (suite *IntegrationTestSuite) TearDownTest() {
// Clean up the registry and filesystem between each test
//
// `regKeyADBC` isn't exported, we redefine it here
regKeyADBC := "SOFTWARE\\ADBC\\Drivers"
// We ignore registry errors. The `registry` package doesn't have a method to
// explicitly check key existence we could either check the error or just try
// and ignore
registry.DeleteKey(registry.CURRENT_USER, regKeyADBC)
registry.DeleteKey(registry.LOCAL_MACHINE, regKeyADBC)

// Clean up filesystem
os.RemoveAll(config.GetLocation(config.ConfigUser))
os.RemoveAll(config.GetLocation(config.ConfigSystem))
}

func (suite *IntegrationTestSuite) driverIsInstalled(level config.ConfigLevel, driverID string) {
var rootKey registry.Key
if level == config.ConfigUser {
rootKey = registry.CURRENT_USER
} else {
rootKey = registry.LOCAL_MACHINE
}

k, err := registry.OpenKey(rootKey, `SOFTWARE\ADBC\Drivers\`+driverID, registry.QUERY_VALUE)
suite.Require().NoError(err, "registry key should exist")
defer k.Close()

// Get and verify driver path exists
driverPath, _, err := k.GetStringValue("driver")
suite.Require().NoError(err)
suite.FileExists(driverPath)
}
5 changes: 5 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ func (c ConfigLevel) String() string {
}
}

// GetLocation returns the filesystem path for the given config level.
func GetLocation(level ConfigLevel) string {
return level.configLocation()
}

func (c *ConfigLevel) UnmarshalText(b []byte) error {
switch strings.ToLower(strings.TrimSpace(string(b))) {
case "system":
Expand Down
Loading