Skip to content

Commit

Permalink
Merge branch 'main' into context-support
Browse files Browse the repository at this point in the history
* main: (34 commits)
  fix: only upload to sonar on ubuntu-latest (testcontainers#2891)
  fix: build artifact name properly (testcontainers#2890)
  fix: do not run sonar upload when ryuk is disabled (testcontainers#2889)
  fix: update GH actions for uploading/downloading artifacts (testcontainers#2888)
  feat(ci): Enable master moby with rootless (testcontainers#2880)
  fix(redpanda): temporary file use
  chore(deps): bump actions/download-artifact from 3.0.2 to 4.1.8 (testcontainers#2676)
  chore(deps): bump actions/upload-artifact from 3.1.3 to 4.4.3 (testcontainers#2885)
  fix!: port forwarding clean up and make private (testcontainers#2881)
  chore: resolve AWS deprecations for localstack (testcontainers#2879)
  docs: fix new lifecycle hooks section (testcontainers#2875)
  fix: host access port instability (testcontainers#2867)
  feat: add build to life cycle hooks (testcontainers#2653)
  fix: typo in containerd integration (testcontainers#2873)
  chore(deps): bump mkdocs-include-markdown-plugin from 6.0.4 to 6.2.2 (testcontainers#2806)
  chore: use testify instead of t.Error (testcontainers#2871)
  ci: enable perfsprint linter (testcontainers#2872)
  chore(deps): bump mkdocs-markdownextradata-plugin from 0.2.5 to 0.2.6 (testcontainers#2807)
  chore: use testcontainers.RequireContainerExec (testcontainers#2870)
  chore(deps): bump golangci/golangci-lint-action from 6.1.0 to 6.1.1 (testcontainers#2868)
  ...
  • Loading branch information
mdelapenya committed Nov 19, 2024
2 parents 5511d17 + 1b26907 commit b38e857
Show file tree
Hide file tree
Showing 213 changed files with 2,192 additions and 1,954 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/ci-test-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:

- name: golangci-lint
if: ${{ inputs.platform == 'ubuntu-latest' }}
uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: v1.61.0
Expand Down Expand Up @@ -119,11 +119,18 @@ jobs:
timeout-minutes: 30
run: make test-unit

- name: Set sonar artifact name
# For the core library, where the project directory is '.', we'll use "core" as artifact name.
# For the modules, we'll remove the slashes, keeping the name of the module
if: ${{ github.ref_name == 'main' && github.repository_owner == 'testcontainers' && inputs.platform == 'ubuntu-latest' && inputs.run-tests && !inputs.rootless-docker && !inputs.ryuk-disabled }}
run: |
echo "ARTIFACT_NAME=$(basename ${{ inputs.project-directory == '.' && 'core' || inputs.project-directory }})-${{ inputs.go-version }}-${{ inputs.platform }}" >> $GITHUB_ENV
- name: Upload SonarCloud files
if: ${{ github.ref_name == 'main' && github.repository_owner == 'testcontainers' && inputs.run-tests && !inputs.rootless-docker }}
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3
if: ${{ github.ref_name == 'main' && github.repository_owner == 'testcontainers' && inputs.platform == 'ubuntu-latest' && inputs.run-tests && !inputs.rootless-docker && !inputs.ryuk-disabled }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: sonarcloud
name: sonarcloud-${{ env.ARTIFACT_NAME }}
path: |
./sonar-project.properties
${{ inputs.project-directory }}/TEST-unit.xml
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,10 @@ jobs:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0

- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: sonarcloud
pattern: sonarcloud-*
merge-multiple: true

- name: Analyze with SonarCloud
uses: sonarsource/sonarcloud-github-action@49e6cd3b187936a73b8280d59ffd9da69df63ec9 # v2.1.1
Expand Down
26 changes: 16 additions & 10 deletions .github/workflows/docker-moby-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,16 @@ jobs:
strategy:
matrix:
rootless-docker: [true, false]
containerd-integration: [true, false]

name: "Core tests using latest moby/moby"
runs-on: 'ubuntu-latest'
continue-on-error: true
steps:
- name: Set the Docker Install type
run: |
echo "docker_install_type=${{ matrix.rootless-docker == true && 'Rootless' || 'Rootful' }}" >> "$GITHUB_ENV"
- name: Setup rootless Docker
if: ${{ matrix.rootless-docker }}
uses: ScribeMD/rootless-docker@6bd157a512c2fafa4e0243a8aa87d964eb890886 # v0.2.2

- name: Remove Docker root socket
if: ${{ matrix.rootless-docker }}
run: sudo rm -rf /var/run/docker.sock
echo "containerd_integration=${{ matrix.containerd-integration == true && 'containerd' || '' }}" >> "$GITHUB_ENV"
- name: Check out code into the Go module directory
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
Expand All @@ -42,8 +37,18 @@ jobs:
- name: modTidy
run: go mod tidy

- name: Install Latest Docker
run: curl https://get.docker.com | CHANNEL=test sh
- name: Install Nightly Docker
uses: crazy-max/ghaction-setup-docker@master
with:
rootless: ${{ matrix.rootless-docker }}
version: type=image,tag=master
daemon-config: |
{
"debug": true,
"features": {
"containerd-snapshotter": ${{ matrix.containerd-integration }}
}
}
- name: go test
timeout-minutes: 30
Expand All @@ -56,6 +61,7 @@ jobs:
{
"tc_project": "testcontainers-go",
"tc_docker_install_type": "${docker_install_type}",
"tc_containerd_integration": "${containerd_integration}",
"tc_github_action_url": "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}",
"tc_github_action_status": "FAILED",
"tc_slack_channel_id": "${{ secrets.SLACK_DOCKER_LATEST_CHANNEL_ID }}"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: SARIF file
path: results.sarif
Expand Down
6 changes: 5 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ linters:
- gofumpt
- misspell
- nolintlint
- nonamedreturns
- nakedret
- perfsprint
- testifylint
- thelper
- usestdlibvars

linters-settings:
nakedret:
max-func-lines: 0
errorlint:
# Check whether fmt.Errorf uses the %w verb for formatting errors.
# See the https://github.com/polyfloyd/go-errorlint for caveats.
Expand Down
3 changes: 2 additions & 1 deletion commons-test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ test-%: $(GOBIN)/gotestsum
-- \
-v \
-coverprofile=coverage.out \
-timeout=30m
-timeout=30m \
-race

.PHONY: tools
tools:
Expand Down
41 changes: 25 additions & 16 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type Container interface {
type ImageBuildInfo interface {
BuildOptions() (types.ImageBuildOptions, error) // converts the ImageBuildInfo to a types.ImageBuildOptions
GetContext() (io.Reader, error) // the path to the build context
GetDockerfile() string // the relative path to the Dockerfile, including the fileitself
GetDockerfile() string // the relative path to the Dockerfile, including the file itself
GetRepo() string // get repo label for image
GetTag() string // get tag label for image
ShouldPrintBuildLog() bool // allow build log to be printed to stdout
Expand Down Expand Up @@ -167,6 +167,15 @@ type ContainerRequest struct {
LogConsumerCfg *LogConsumerConfig // define the configuration for the log producer and its log consumers to follow the logs
}

// sessionID returns the session ID for the container request.
func (c *ContainerRequest) sessionID() string {
if sessionID := c.Labels[core.LabelSessionID]; sessionID != "" {
return sessionID
}

return core.SessionID()
}

// containerOptions functional options for a container
type containerOptions struct {
ImageName string
Expand Down Expand Up @@ -277,34 +286,34 @@ func (c *ContainerRequest) GetBuildArgs() map[string]*string {
return c.FromDockerfile.BuildArgs
}

// GetDockerfile returns the Dockerfile from the ContainerRequest, defaults to "Dockerfile"
// GetDockerfile returns the Dockerfile from the ContainerRequest, defaults to "Dockerfile".
// Sets FromDockerfile.Dockerfile to the default if blank.
func (c *ContainerRequest) GetDockerfile() string {
f := c.FromDockerfile.Dockerfile
if f == "" {
return "Dockerfile"
if c.FromDockerfile.Dockerfile == "" {
c.FromDockerfile.Dockerfile = "Dockerfile"
}

return f
return c.FromDockerfile.Dockerfile
}

// GetRepo returns the Repo label for image from the ContainerRequest, defaults to UUID
// GetRepo returns the Repo label for image from the ContainerRequest, defaults to UUID.
// Sets FromDockerfile.Repo to the default value if blank.
func (c *ContainerRequest) GetRepo() string {
r := c.FromDockerfile.Repo
if r == "" {
return uuid.NewString()
if c.FromDockerfile.Repo == "" {
c.FromDockerfile.Repo = uuid.NewString()
}

return strings.ToLower(r)
return strings.ToLower(c.FromDockerfile.Repo)
}

// GetTag returns the Tag label for image from the ContainerRequest, defaults to UUID
// GetTag returns the Tag label for image from the ContainerRequest, defaults to UUID.
// Sets FromDockerfile.Tag to the default value if blank.
func (c *ContainerRequest) GetTag() string {
t := c.FromDockerfile.Tag
if t == "" {
return uuid.NewString()
if c.FromDockerfile.Tag == "" {
c.FromDockerfile.Tag = uuid.NewString()
}

return strings.ToLower(t)
return strings.ToLower(c.FromDockerfile.Tag)
}

// Deprecated: Testcontainers will detect registry credentials automatically, and it will be removed in the next major release.
Expand Down
20 changes: 7 additions & 13 deletions container_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
package testcontainers

import (
"errors"
"os"
"path/filepath"
"testing"
Expand All @@ -14,7 +13,7 @@ import (
func TestContainerFileValidation(t *testing.T) {
type ContainerFileValidationTestCase struct {
Name string
ExpectedError error
ExpectedError string
File ContainerFile
}

Expand All @@ -38,7 +37,7 @@ func TestContainerFileValidation(t *testing.T) {
},
{
Name: "invalid container file",
ExpectedError: errors.New("either HostFilePath or Reader must be specified"),
ExpectedError: "either HostFilePath or Reader must be specified",
File: ContainerFile{
HostFilePath: "",
Reader: nil,
Expand All @@ -47,7 +46,7 @@ func TestContainerFileValidation(t *testing.T) {
},
{
Name: "invalid container file",
ExpectedError: errors.New("ContainerFilePath must be specified"),
ExpectedError: "ContainerFilePath must be specified",
File: ContainerFile{
HostFilePath: "/path/to/host",
ContainerFilePath: "",
Expand All @@ -58,15 +57,10 @@ func TestContainerFileValidation(t *testing.T) {
for _, testCase := range testTable {
t.Run(testCase.Name, func(t *testing.T) {
err := testCase.File.validate()
switch {
case err == nil && testCase.ExpectedError == nil:
return
case err == nil && testCase.ExpectedError != nil:
t.Errorf("did not receive expected error: %s", testCase.ExpectedError.Error())
case err != nil && testCase.ExpectedError == nil:
t.Errorf("received unexpected error: %s", err.Error())
case err.Error() != testCase.ExpectedError.Error():
t.Errorf("errors mismatch: %s != %s", err.Error(), testCase.ExpectedError.Error())
if testCase.ExpectedError != "" {
require.EqualError(t, err, testCase.ExpectedError)
} else {
require.NoError(t, err)
}
})
}
Expand Down
34 changes: 12 additions & 22 deletions container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ import (
func Test_ContainerValidation(t *testing.T) {
type ContainerValidationTestCase struct {
Name string
ExpectedError error
ExpectedError string
ContainerRequest testcontainers.ContainerRequest
}

testTable := []ContainerValidationTestCase{
{
Name: "cannot set both context and image",
ExpectedError: errors.New("you cannot specify both an Image and Context in a ContainerRequest"),
ExpectedError: "you cannot specify both an Image and Context in a ContainerRequest",
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: ".",
Expand All @@ -39,24 +39,21 @@ func Test_ContainerValidation(t *testing.T) {
},
},
{
Name: "can set image without context",
ExpectedError: nil,
Name: "can set image without context",
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
},
},
{
Name: "can set context without image",
ExpectedError: nil,
Name: "can set context without image",
ContainerRequest: testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: ".",
},
},
},
{
Name: "Can mount same source to multiple targets",
ExpectedError: nil,
Name: "Can mount same source to multiple targets",
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
HostConfigModifier: func(hc *container.HostConfig) {
Expand All @@ -66,7 +63,7 @@ func Test_ContainerValidation(t *testing.T) {
},
{
Name: "Cannot mount multiple sources to same target",
ExpectedError: errors.New("duplicate mount target detected: /data"),
ExpectedError: "duplicate mount target detected: /data",
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
HostConfigModifier: func(hc *container.HostConfig) {
Expand All @@ -76,7 +73,7 @@ func Test_ContainerValidation(t *testing.T) {
},
{
Name: "Invalid bind mount",
ExpectedError: errors.New("invalid bind mount: /data:/data:/data"),
ExpectedError: "invalid bind mount: /data:/data:/data",
ContainerRequest: testcontainers.ContainerRequest{
Image: "redis:latest",
HostConfigModifier: func(hc *container.HostConfig) {
Expand All @@ -89,15 +86,10 @@ func Test_ContainerValidation(t *testing.T) {
for _, testCase := range testTable {
t.Run(testCase.Name, func(t *testing.T) {
err := testCase.ContainerRequest.Validate()
switch {
case err == nil && testCase.ExpectedError == nil:
return
case err == nil && testCase.ExpectedError != nil:
t.Errorf("did not receive expected error: %s", testCase.ExpectedError.Error())
case err != nil && testCase.ExpectedError == nil:
t.Errorf("received unexpected error: %s", err.Error())
case err.Error() != testCase.ExpectedError.Error():
t.Errorf("errors mismatch: %s != %s", err.Error(), testCase.ExpectedError.Error())
if testCase.ExpectedError != "" {
require.EqualError(t, err, testCase.ExpectedError)
} else {
require.NoError(t, err)
}
})
}
Expand Down Expand Up @@ -137,9 +129,7 @@ func Test_GetDockerfile(t *testing.T) {
for _, testCase := range testTable {
t.Run(testCase.name, func(t *testing.T) {
n := testCase.ContainerRequest.GetDockerfile()
if n != testCase.ExpectedDockerfileName {
t.Fatalf("expected Dockerfile name: %s, received: %s", testCase.ExpectedDockerfileName, n)
}
require.Equalf(t, n, testCase.ExpectedDockerfileName, "expected Dockerfile name: %s, received: %s", testCase.ExpectedDockerfileName, n)
})
}
}
Expand Down
Loading

0 comments on commit b38e857

Please sign in to comment.