mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			229 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package bake
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"os"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/require"
 | 
						|
)
 | 
						|
 | 
						|
func TestReadTargets(t *testing.T) {
 | 
						|
	t.Parallel()
 | 
						|
 | 
						|
	fp := File{
 | 
						|
		Name: "config.hcl",
 | 
						|
		Data: []byte(`
 | 
						|
target "webDEP" {
 | 
						|
	args = {
 | 
						|
		VAR_INHERITED = "webDEP"
 | 
						|
		VAR_BOTH = "webDEP"
 | 
						|
	}
 | 
						|
	no-cache = true
 | 
						|
}
 | 
						|
 | 
						|
target "webapp" {
 | 
						|
	dockerfile = "Dockerfile.webapp"
 | 
						|
	args = {
 | 
						|
		VAR_BOTH = "webapp"
 | 
						|
	}
 | 
						|
	inherits = ["webDEP"]
 | 
						|
}`),
 | 
						|
	}
 | 
						|
 | 
						|
	ctx := context.TODO()
 | 
						|
 | 
						|
	t.Run("NoOverrides", func(t *testing.T) {
 | 
						|
		m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, nil)
 | 
						|
		require.NoError(t, err)
 | 
						|
		require.Equal(t, 1, len(m))
 | 
						|
 | 
						|
		require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile)
 | 
						|
		require.Equal(t, ".", *m["webapp"].Context)
 | 
						|
		require.Equal(t, "webDEP", m["webapp"].Args["VAR_INHERITED"])
 | 
						|
		require.Equal(t, true, *m["webapp"].NoCache)
 | 
						|
		require.Nil(t, m["webapp"].Pull)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("InvalidTargetOverrides", func(t *testing.T) {
 | 
						|
		_, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"nosuchtarget.context=foo"})
 | 
						|
		require.NotNil(t, err)
 | 
						|
		require.Equal(t, err.Error(), "could not find any target matching 'nosuchtarget'")
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("ArgsOverrides", func(t *testing.T) {
 | 
						|
		t.Run("leaf", func(t *testing.T) {
 | 
						|
			os.Setenv("VAR_FROMENV"+t.Name(), "fromEnv")
 | 
						|
			defer os.Unsetenv("VAR_FROM_ENV" + t.Name())
 | 
						|
 | 
						|
			m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{
 | 
						|
				"webapp.args.VAR_UNSET",
 | 
						|
				"webapp.args.VAR_EMPTY=",
 | 
						|
				"webapp.args.VAR_SET=bananas",
 | 
						|
				"webapp.args.VAR_FROMENV" + t.Name(),
 | 
						|
				"webapp.args.VAR_INHERITED=override",
 | 
						|
				// not overriding VAR_BOTH on purpose
 | 
						|
			})
 | 
						|
			require.NoError(t, err)
 | 
						|
 | 
						|
			require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile)
 | 
						|
			require.Equal(t, ".", *m["webapp"].Context)
 | 
						|
 | 
						|
			_, isSet := m["webapp"].Args["VAR_UNSET"]
 | 
						|
			require.False(t, isSet, m["webapp"].Args["VAR_UNSET"])
 | 
						|
 | 
						|
			_, isSet = m["webapp"].Args["VAR_EMPTY"]
 | 
						|
			require.True(t, isSet, m["webapp"].Args["VAR_EMPTY"])
 | 
						|
 | 
						|
			require.Equal(t, m["webapp"].Args["VAR_SET"], "bananas")
 | 
						|
 | 
						|
			require.Equal(t, m["webapp"].Args["VAR_FROMENV"+t.Name()], "fromEnv")
 | 
						|
 | 
						|
			require.Equal(t, m["webapp"].Args["VAR_BOTH"], "webapp")
 | 
						|
			require.Equal(t, m["webapp"].Args["VAR_INHERITED"], "override")
 | 
						|
		})
 | 
						|
 | 
						|
		// building leaf but overriding parent fields
 | 
						|
		t.Run("parent", func(t *testing.T) {
 | 
						|
			m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{
 | 
						|
				"webDEP.args.VAR_INHERITED=override",
 | 
						|
				"webDEP.args.VAR_BOTH=override",
 | 
						|
			})
 | 
						|
			require.NoError(t, err)
 | 
						|
			require.Equal(t, m["webapp"].Args["VAR_INHERITED"], "override")
 | 
						|
			require.Equal(t, m["webapp"].Args["VAR_BOTH"], "webapp")
 | 
						|
		})
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("ContextOverride", func(t *testing.T) {
 | 
						|
		_, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context"})
 | 
						|
		require.NotNil(t, err)
 | 
						|
 | 
						|
		m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context=foo"})
 | 
						|
		require.NoError(t, err)
 | 
						|
 | 
						|
		require.Equal(t, "foo", *m["webapp"].Context)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("NoCacheOverride", func(t *testing.T) {
 | 
						|
		m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.no-cache=false"})
 | 
						|
		require.NoError(t, err)
 | 
						|
		require.Equal(t, false, *m["webapp"].NoCache)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("PullOverride", func(t *testing.T) {
 | 
						|
		m, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.pull=false"})
 | 
						|
		require.NoError(t, err)
 | 
						|
		require.Equal(t, false, *m["webapp"].Pull)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("PatternOverride", func(t *testing.T) {
 | 
						|
		// same check for two cases
 | 
						|
		multiTargetCheck := func(t *testing.T, m map[string]*Target, err error) {
 | 
						|
			require.NoError(t, err)
 | 
						|
			require.Equal(t, 2, len(m))
 | 
						|
			require.Equal(t, "foo", *m["webapp"].Dockerfile)
 | 
						|
			require.Equal(t, "webDEP", m["webapp"].Args["VAR_INHERITED"])
 | 
						|
			require.Equal(t, "foo", *m["webDEP"].Dockerfile)
 | 
						|
			require.Equal(t, "webDEP", m["webDEP"].Args["VAR_INHERITED"])
 | 
						|
		}
 | 
						|
 | 
						|
		cases := []struct {
 | 
						|
			name      string
 | 
						|
			targets   []string
 | 
						|
			overrides []string
 | 
						|
			check     func(*testing.T, map[string]*Target, error)
 | 
						|
		}{
 | 
						|
			{
 | 
						|
				name:      "multi target single pattern",
 | 
						|
				targets:   []string{"webapp", "webDEP"},
 | 
						|
				overrides: []string{"web*.dockerfile=foo"},
 | 
						|
				check:     multiTargetCheck,
 | 
						|
			},
 | 
						|
			{
 | 
						|
				name:      "multi target multi pattern",
 | 
						|
				targets:   []string{"webapp", "webDEP"},
 | 
						|
				overrides: []string{"web*.dockerfile=foo", "*.args.VAR_BOTH=bar"},
 | 
						|
				check:     multiTargetCheck,
 | 
						|
			},
 | 
						|
			{
 | 
						|
				name:      "single target",
 | 
						|
				targets:   []string{"webapp"},
 | 
						|
				overrides: []string{"web*.dockerfile=foo"},
 | 
						|
				check: func(t *testing.T, m map[string]*Target, err error) {
 | 
						|
					require.NoError(t, err)
 | 
						|
					require.Equal(t, 1, len(m))
 | 
						|
					require.Equal(t, "foo", *m["webapp"].Dockerfile)
 | 
						|
					require.Equal(t, "webDEP", m["webapp"].Args["VAR_INHERITED"])
 | 
						|
				},
 | 
						|
			},
 | 
						|
			{
 | 
						|
				name:      "nomatch",
 | 
						|
				targets:   []string{"webapp"},
 | 
						|
				overrides: []string{"nomatch*.dockerfile=foo"},
 | 
						|
				check: func(t *testing.T, m map[string]*Target, err error) {
 | 
						|
					// NOTE: I am unsure whether failing to match should always error out
 | 
						|
					// instead of simply skipping that override.
 | 
						|
					// Let's enforce the error and we can relax it later if users complain.
 | 
						|
					require.NotNil(t, err)
 | 
						|
					require.Equal(t, err.Error(), "could not find any target matching 'nomatch*'")
 | 
						|
				},
 | 
						|
			},
 | 
						|
		}
 | 
						|
		for _, test := range cases {
 | 
						|
			t.Run(test.name, func(t *testing.T) {
 | 
						|
				m, err := ReadTargets(ctx, []File{fp}, test.targets, test.overrides)
 | 
						|
				test.check(t, m, err)
 | 
						|
			})
 | 
						|
		}
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func TestReadTargetsCompose(t *testing.T) {
 | 
						|
	t.Parallel()
 | 
						|
 | 
						|
	fp := File{
 | 
						|
		Name: "docker-compose.yml",
 | 
						|
		Data: []byte(
 | 
						|
			`version: "3"
 | 
						|
services:
 | 
						|
  db:
 | 
						|
    build: .
 | 
						|
    command: ./entrypoint.sh
 | 
						|
    image: docker.io/tonistiigi/db
 | 
						|
  webapp:
 | 
						|
    build:
 | 
						|
      dockerfile: Dockerfile.webapp
 | 
						|
      args:
 | 
						|
        buildno: 1
 | 
						|
`),
 | 
						|
	}
 | 
						|
 | 
						|
	fp2 := File{
 | 
						|
		Name: "docker-compose2.yml",
 | 
						|
		Data: []byte(
 | 
						|
			`version: "3"
 | 
						|
services:
 | 
						|
  newservice:
 | 
						|
    build: .
 | 
						|
  webapp:
 | 
						|
    build:
 | 
						|
      args:
 | 
						|
        buildno2: 12
 | 
						|
`),
 | 
						|
	}
 | 
						|
 | 
						|
	ctx := context.TODO()
 | 
						|
 | 
						|
	m, err := ReadTargets(ctx, []File{fp, fp2}, []string{"default"}, nil)
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 3, len(m))
 | 
						|
	_, ok := m["newservice"]
 | 
						|
	require.True(t, ok)
 | 
						|
	require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile)
 | 
						|
	require.Equal(t, ".", *m["webapp"].Context)
 | 
						|
	require.Equal(t, "1", m["webapp"].Args["buildno"])
 | 
						|
	require.Equal(t, "12", m["webapp"].Args["buildno2"])
 | 
						|
}
 |