Skip to content
Draft
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
40 changes: 36 additions & 4 deletions .github/workflows/solana.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,22 @@ jobs:
runs-on: ubuntu-latest-8cores-32GB
steps:
- uses: actions/checkout@v4
- name: Collect Test Telemetry
uses: catchpoint/workflow-telemetry-action@94c3c3d9567a0205de6da68a76c428ce4e769af1 # v2.0.0
- name: Free Disk Space
uses: smartcontractkit/.github/actions/free-disk-space@free-disk-space/v1

- name: debug info
run: |
echo '=== cgroup memory limits ==='
cat /sys/fs/cgroup/memory.max 2>/dev/null || echo "no memory.max"
cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null || echo "no memory.limit_in_bytes"

echo '=== /proc/meminfo ==='
cat /proc/meminfo

echo '=== /tmp mount ==='
mount | grep ' /tmp' || echo "/tmp has no separate mount"
df -h /tmp || echo "df /tmp failed"
echo '=== /tmp listing ==='
ls -la /tmp || echo "ls /tmp failed"

- name: Cache cargo target dir
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
Expand Down Expand Up @@ -166,6 +178,23 @@ jobs:
run: |
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)" # always use latest stable release from solana
echo "PATH=$HOME/.local/share/solana/install/active_release/bin:$PATH" >> $GITHUB_ENV

- name: debug info
run: |
echo '=== cgroup memory limits ==='
cat /sys/fs/cgroup/memory.max 2>/dev/null || echo "no memory.max"
cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null || echo "no memory.limit_in_bytes"

echo '=== /proc/meminfo ==='
cat /proc/meminfo

echo '=== /tmp mount ==='
mount | grep ' /tmp' || echo "/tmp has no separate mount"
df -h /tmp || echo "df /tmp failed"

echo '=== /tmp listing ==='
ls -la /tmp || echo "ls /tmp failed"

- name: build + test
run: |
set -eoux pipefail
Expand All @@ -176,8 +205,11 @@ jobs:
FORCE_COLOR=1 &&\
cd /solana/contracts &&\
anchor build"

make go-tests



lint:
needs: [ changes, get_anchor_version, build_solana ]
if: ${{ needs.changes.outputs.solana_changes == 'true' }}
Expand Down
2 changes: 0 additions & 2 deletions chains/solana/contracts/tests/ccip/ccip_router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ import (
)

func TestCCIPRouter(t *testing.T) {
t.Parallel()

ccip_router.SetProgramID(config.CcipRouterProgram)
test_ccip_receiver.SetProgramID(config.CcipLogicReceiver)
test_token_pool.SetProgramID(config.CcipTokenPoolProgram)
Expand Down
2 changes: 0 additions & 2 deletions chains/solana/contracts/tests/ccip/tokenpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ import (
)

func TestTokenPool(t *testing.T) {
t.Parallel()

rmn_remote.SetProgramID(config.RMNRemoteProgram)
test_token_pool.SetProgramID(config.CcipTokenPoolProgram)
cctp_message_transmitter.SetProgramID(config.CctpMessageTransmitter)
Expand Down
3 changes: 3 additions & 0 deletions chains/solana/contracts/tests/examples/ping_pong_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ func getReusableAccounts(t *testing.T, linkMint solana.PublicKey) ReusableAccoun
// from the ping pong program to itself.
func TestPingPong(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

// acting as "dumb" offramp, proxying calls to the receiver that are signed by PDA
test_ccip_invalid_receiver.SetProgramID(config.CcipInvalidReceiverProgram)
Expand Down
5 changes: 4 additions & 1 deletion chains/solana/contracts/tests/examples/pools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ type ProgramData struct {
// more detailed token pool tests are handled by the test-token-pool which is used in the tokenpool_test.go and ccip_router_test.go
func TestBaseTokenPoolHappyPath(t *testing.T) {
t.Parallel()

g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

// acting as "dumb" onramp & offramp, proxying calls to the pool that are signed by PDA
test_ccip_invalid_receiver.SetProgramID(config.CcipInvalidReceiverProgram)
rmn_remote.SetProgramID(config.RMNRemoteProgram)
Expand Down
4 changes: 4 additions & 0 deletions chains/solana/contracts/tests/examples/receiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (

func TestCcipReceiver(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

ctx := tests.Context(t)

ccip_router.SetProgramID(config.CcipRouterProgram)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import (

func TestMcmMultipleInstances(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

mcm.SetProgramID(config.McmProgram)

ctx := tests.Context(t)
Expand Down
4 changes: 4 additions & 0 deletions chains/solana/contracts/tests/mcms/mcm_set_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import (

func TestMcmSetConfig(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

mcm.SetProgramID(config.McmProgram)

ctx := tests.Context(t)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ type TestMcmOperation struct {

func TestMcmSetRootAndExecute(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

mcm.SetProgramID(config.McmProgram)
external_program_cpi_stub.SetProgramID(config.ExternalCpiStubProgram) // testing program

Expand Down
4 changes: 4 additions & 0 deletions chains/solana/contracts/tests/mcms/mcm_timelock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ import (

func TestMcmWithTimelock(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

ctx := tests.Context(t)

mcm.SetProgramID(config.McmProgram)
Expand Down
4 changes: 4 additions & 0 deletions chains/solana/contracts/tests/mcms/mcms_tx_capacity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ import (

func TestMcmsCapacity(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

ctx := tests.Context(t)

mcm.SetProgramID(config.McmProgram)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import (

func TestTimelockBypasserExecute(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

ctx := tests.Context(t)

timelock.SetProgramID(config.TimelockProgram)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type TimelockInstance struct {

func TestTimelockMultipleInstances(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

ctx := tests.Context(t)

timelock.SetProgramID(config.TimelockProgram)
Expand Down
4 changes: 4 additions & 0 deletions chains/solana/contracts/tests/mcms/timelock_rbac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import (

func TestTimelockRBAC(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

ctx := tests.Context(t)

timelock.SetProgramID(config.TimelockProgram)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import (

func TestTimelockScheduleAndExecute(t *testing.T) {
t.Parallel()
g := testutils.GetConcurrencyGroup("solana-test-validator", 2) // max 2 concurrent tests
g.Enter()
defer g.Leave()

ctx := tests.Context(t)

timelock.SetProgramID(config.TimelockProgram)
Expand Down
44 changes: 44 additions & 0 deletions chains/solana/contracts/tests/testutils/concurrency_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package testutils

import "sync"

// ConcurrencyGroup is a counting semaphore.
type ConcurrencyGroup chan struct{}

// Registry manages named concurrency groups.
type Registry struct {
sync.Mutex
m map[string]ConcurrencyGroup
}

// NewRegistry creates a new, empty registry.
func newRegistry() *Registry {
return &Registry{m: make(map[string]ConcurrencyGroup)}
}

// Global registry used by the helper Get.
var defaultRegistry = newRegistry()

// Get returns the semaphore for id, creating it with the given
// concurrency level if it does not yet exist.
func (r *Registry) get(id string, concurrency int) ConcurrencyGroup {
r.Lock()
defer r.Unlock()
if s, ok := r.m[id]; ok {
return s
}
s := make(ConcurrencyGroup, concurrency)
r.m[id] = s
return s
}

// GetConcurrencyGroup uses the global registry.
func GetConcurrencyGroup(id string, concurrency int) ConcurrencyGroup {
return defaultRegistry.get(id, concurrency)
}

// Enter acquires a token (blocks until one is available).
func (s ConcurrencyGroup) Enter() { s <- struct{}{} }

// Leave releases a token.
func (s ConcurrencyGroup) Leave() { <-s }
Loading