Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
PKGS=$(go list ./pkg/... | grep -v '/monitoring$' | tr '\n' ' ')
# Run tests with coverage
# Use -coverpkg to measure client package coverage through server tests
go test -p 1 -race -coverprofile=coverage.raw -covermode=atomic -coverpkg=./pkg/... $PKGS
go test -race -coverprofile=coverage.raw -covermode=atomic -coverpkg=./pkg/... $PKGS
# Filter out test utilities, mocks, and monitoring from coverage report
grep -v 'pkg/server/test_utils.go' coverage.raw | \
grep -v 'pkg/monitoring/' | \
Expand Down
10 changes: 8 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ The deployment docker-compose files expect `colonyos/colonies:latest`. Using a d

### Testing
```bash
make test # Run all tests (requires grc for colored output)
make github_test # Run tests without grc (for CI)
make test # Run all tests: needs Postgres on localhost:5432 (make startdb)
# and an S3 server on localhost:9000 for pkg/fs
make github_test # Alias for test (used by CI)
```

Set a timezone when running tests, e.g. `export TZ=Europe/Stockholm` (the
database layer refuses to connect without TZ, and one core test expects a
non-UTC zone). Test packages use per-process databases and dynamic ports, so
they run in parallel.

### Development Environment
```bash
docker-compose up -d # Start Colonies server with dependencies (TimescaleDB, MinIO)
Expand Down
53 changes: 8 additions & 45 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
all: build
.PHONY: all build
.PHONY: all build container container-multiplatform container-multiplatform-push push coverage test test-all test-compat github_test install startdb nukedb

BUILD_IMAGE ?= colonyos/colonies
PUSH_IMAGE ?= colonyos/colonies:v1.9.10
Expand Down Expand Up @@ -34,55 +34,18 @@ push:
docker push $(PUSH_IMAGE)

coverage:
./buildtools/coverage.sh
./buildtools/codecov
@go test -coverprofile=coverage.txt -covermode=atomic ./...

build_cryptolib_ubuntu_2020:
cd buildtools; ./build_cryptolib_ubuntu.sh

# Runs all tests: needs Postgres on localhost:5432 (make startdb) and an S3
# server on localhost:9000 for pkg/fs. Test packages use per-process databases
# and dynamic ports, so they run in parallel.
test:
@cd tests/reliability; go test -v --race
@cd internal/crypto; go test -v --race
@cd pkg/core; go test -v --race
@cd pkg/database/postgresql; go test -v --race
@cd pkg/rpc; go test -v --race
@cd pkg/security; go test -v --race
@cd pkg/security/crypto; go test -v --race
@cd pkg/security/validator; go test -v --race
@cd pkg/backends/gin; go test -v --race
@cd pkg/client; go test -v --race
@cd pkg/client/backends; go test -v --race
@cd pkg/client/gin; go test -v --race
@cd pkg/server; go test -v --race
@cd pkg/server/controllers; go test -v --race
@cd pkg/server/handlers/attribute; go test -v --race
@cd pkg/server/handlers/blueprint; go test -v --race
@cd pkg/server/handlers/channel; go test -v --race
@cd pkg/server/handlers/colony; go test -v --race
@cd pkg/server/handlers/cron; go test -v --race
@cd pkg/server/handlers/executor; go test -v --race
@cd pkg/server/handlers/file; go test -v --race
@cd pkg/server/handlers/function; go test -v --race
@cd pkg/server/handlers/generator; go test -v --race
@cd pkg/server/handlers/location; go test -v --race
@cd pkg/server/handlers/log; go test -v --race
@cd pkg/server/handlers/process; go test -v --race
@cd pkg/server/handlers/processgraph; go test -v --race
@cd pkg/server/handlers/security; go test -v --race
@cd pkg/server/handlers/server; go test -v --race
@cd pkg/server/handlers/snapshot; go test -v --race
@cd pkg/server/handlers/user; go test -v --race
@cd pkg/server/handlers/realtime; go test -v --race
@cd pkg/server/registry; go test -v --race
@cd pkg/server/utils; go test -v --race
@cd pkg/scheduler; go test -v --race
@cd pkg/parsers; go test -v --race
@cd pkg/utils; go test -v --race
@cd pkg/validate; go test -v --race
@cd pkg/channel; go test -v --race
@cd pkg/cluster; go test -v --race
@cd pkg/cron; go test -v --race
@cd pkg/fs; go test -v --race
@go test -race ./...

github_test: test

install:
cp ./bin/colonies /usr/local/bin
Expand Down
2 changes: 2 additions & 0 deletions internal/cryptolib.wasm/cryptolib.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build js && wasm

package main

import (
Expand Down
2 changes: 1 addition & 1 deletion pkg/cluster/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (config *Config) Equals(config2 *Config) bool {
}
}

if counter == len(config.Nodes) && counter == len(config.Nodes) {
if counter == len(config.Nodes) && counter == len(config2.Nodes) {
return true
}

Expand Down
37 changes: 20 additions & 17 deletions pkg/cluster/etcd_test.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
package cluster

import (
"fmt"
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestCreateEtcdCluster(t *testing.T) {
node1 := Node{Name: "etcd1", Host: "localhost", EtcdClientPort: 24100, EtcdPeerPort: 23100, RelayPort: 25100, APIPort: 26100}
node2 := Node{Name: "etcd2", Host: "localhost", EtcdClientPort: 24200, EtcdPeerPort: 23200, RelayPort: 25200, APIPort: 26200}
node3 := Node{Name: "etcd3", Host: "localhost", EtcdClientPort: 24300, EtcdPeerPort: 23300, RelayPort: 25300, APIPort: 26300}
node4 := Node{Name: "etcd4", Host: "localhost", EtcdClientPort: 24400, EtcdPeerPort: 23400, RelayPort: 25400, APIPort: 26400}
nodes := testClusterNodes(t, "etcd1", "etcd2", "etcd3", "etcd4")
node1, node2, node3, node4 := nodes[0], nodes[1], nodes[2], nodes[3]

config := Config{}
config.AddNode(node1)
config.AddNode(node2)
config.AddNode(node3)
config.AddNode(node4)

server1 := CreateEtcdServer(node1, config, ".")
server2 := CreateEtcdServer(node2, config, ".")
server3 := CreateEtcdServer(node3, config, ".")
server4 := CreateEtcdServer(node4, config, ".")
dataPath := t.TempDir()
server1 := CreateEtcdServer(node1, config, dataPath)
server2 := CreateEtcdServer(node2, config, dataPath)
server3 := CreateEtcdServer(node3, config, dataPath)
server4 := CreateEtcdServer(node4, config, dataPath)

assert.Equal(t, server1.buildInitialClusterStr(), "etcd1=http://localhost:23100,etcd2=http://localhost:23200,etcd3=http://localhost:23300,etcd4=http://localhost:23400")
expectedClusterStr := fmt.Sprintf("etcd1=http://localhost:%d,etcd2=http://localhost:%d,etcd3=http://localhost:%d,etcd4=http://localhost:%d",
node1.EtcdPeerPort, node2.EtcdPeerPort, node3.EtcdPeerPort, node4.EtcdPeerPort)
assert.Equal(t, server1.buildInitialClusterStr(), expectedClusterStr)

server1.Start()
server2.Start()
Expand Down Expand Up @@ -70,11 +72,11 @@ func TestCreateEtcdCluster(t *testing.T) {
}

func TestEtcdAssignmentsPauseResume(t *testing.T) {
node := Node{Name: "etcd1", Host: "localhost", EtcdClientPort: 24500, EtcdPeerPort: 23500, RelayPort: 25500, APIPort: 26500}
node := testClusterNodes(t, "etcd1")[0]
config := Config{}
config.AddNode(node)

server := CreateEtcdServer(node, config, ".")
server := CreateEtcdServer(node, config, t.TempDir())
server.Start()
server.WaitToStart()

Expand Down Expand Up @@ -123,11 +125,11 @@ func TestEtcdAssignmentsPauseResume(t *testing.T) {
}

func TestEtcdAssignmentsPauseResumeWithoutClient(t *testing.T) {
node := Node{Name: "etcd2", Host: "localhost", EtcdClientPort: 24600, EtcdPeerPort: 23600, RelayPort: 25600, APIPort: 26600}
node := testClusterNodes(t, "etcd2")[0]
config := Config{}
config.AddNode(node)

server := CreateEtcdServer(node, config, ".")
server := CreateEtcdServer(node, config, t.TempDir())
colonyName := "test_colony"

// Test methods fail when etcd client is not initialized
Expand All @@ -146,15 +148,16 @@ func TestEtcdAssignmentsPauseResumeWithoutClient(t *testing.T) {
}

func TestEtcdAssignmentsPauseResumeMultiNode(t *testing.T) {
node1 := Node{Name: "etcd1", Host: "localhost", EtcdClientPort: 24700, EtcdPeerPort: 23700, RelayPort: 25700, APIPort: 26700}
node2 := Node{Name: "etcd2", Host: "localhost", EtcdClientPort: 24800, EtcdPeerPort: 23800, RelayPort: 25800, APIPort: 26800}
nodes := testClusterNodes(t, "etcd1", "etcd2")
node1, node2 := nodes[0], nodes[1]

config := Config{}
config.AddNode(node1)
config.AddNode(node2)

server1 := CreateEtcdServer(node1, config, ".")
server2 := CreateEtcdServer(node2, config, ".")
dataPath := t.TempDir()
server1 := CreateEtcdServer(node1, config, dataPath)
server2 := CreateEtcdServer(node2, config, dataPath)

server1.Start()
server2.Start()
Expand Down
5 changes: 2 additions & 3 deletions pkg/cluster/relay_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ func TestRelayServer(t *testing.T) {
gin.SetMode(gin.ReleaseMode)
gin.DefaultWriter = ioutil.Discard

node1 := Node{Name: "etcd1", Host: "localhost", EtcdClientPort: 24100, EtcdPeerPort: 23100, RelayPort: 25100, APIPort: 26100}
node2 := Node{Name: "etcd2", Host: "localhost", EtcdClientPort: 24200, EtcdPeerPort: 23200, RelayPort: 25200, APIPort: 26200}
node3 := Node{Name: "etcd3", Host: "localhost", EtcdClientPort: 24300, EtcdPeerPort: 23300, RelayPort: 25300, APIPort: 26300}
nodes := testClusterNodes(t, "etcd1", "etcd2", "etcd3")
node1, node2, node3 := nodes[0], nodes[1], nodes[2]

config := Config{}
config.AddNode(node1)
Expand Down
30 changes: 30 additions & 0 deletions pkg/cluster/test_helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cluster

import (
"testing"

"github.com/colonyos/colonies/pkg/utils"
)

// testClusterNodes returns n cluster nodes with kernel-assigned free ports so
// tests never collide on fixed port numbers.
func testClusterNodes(t *testing.T, names ...string) []Node {
t.Helper()
ports, err := utils.FreePorts(4 * len(names))
if err != nil {
t.Fatalf("failed to allocate ports: %v", err)
}

nodes := make([]Node, len(names))
for i, name := range names {
nodes[i] = Node{
Name: name,
Host: "localhost",
EtcdClientPort: ports[4*i],
EtcdPeerPort: ports[4*i+1],
RelayPort: ports[4*i+2],
APIPort: ports[4*i+3],
}
}
return nodes
}
1 change: 0 additions & 1 deletion pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const MAX_LOG_COUNT = 500 // Maximum number of log entries that can be reque

// Test Configuration - Default values used in test environments
const TESTHOST = "localhost" // Default hostname for test servers
const TESTPORT = 28088 // Default port for test servers

// Background Processing Periods - How frequently various system tasks run
const RELEASE_PERIOD = 1 // Period in seconds when processes are checked for max exec time or max wait time
Expand Down
Loading
Loading