File: testing_target.go

package info (click to toggle)
vagrant 2.3.7%2Bgit20230731.5fc64cde%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 17,616 kB
  • sloc: ruby: 111,820; sh: 462; makefile: 123; ansic: 34; lisp: 1
file content (132 lines) | stat: -rw-r--r-- 3,620 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package core

import (
	"fmt"
	"path/filepath"

	"github.com/imdario/mergo"

	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/vagrant-plugin-sdk/component"
	"github.com/hashicorp/vagrant-plugin-sdk/core"
	"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
	"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
	"github.com/mitchellh/go-testing-interface"
	"github.com/stretchr/testify/require"
)

// TestTarget returns a fully in-memory and side-effect free Target that
// can be used for testing. Additional options can be given to provide your own
// factories, configuration, etc.
func TestTarget(t testing.T, p *Project, st *vagrant_server.Target, opts ...TestTargetOption) (target *Target) {
	if st.Name == "" {
		st.Name = filepath.Base(testTempDir(t))
	}

	target, err := p.factory.NewTarget(
		[]TargetOption{
			WithTargetRef(
				&vagrant_plugin_sdk.Ref_Target{
					Project:    p.Ref().(*vagrant_plugin_sdk.Ref_Project),
					Name:       st.Name,
					ResourceId: st.ResourceId,
				},
			),
		}...,
	)
	require.NoError(t, err)
	require.NoError(t, mergo.Merge(target.target, st))

	for _, opt := range opts {
		if oerr := opt(target); oerr != nil {
			err = multierror.Append(err, oerr)
		}
	}
	require.NoError(t, err)
	require.NoError(t, target.Save())
	require.NoError(t, p.Reload())

	return
}

// TestMinimalTarget uses a minimal project to setup the most basic target
// that will work for testing
func TestMinimalTarget(t testing.T) (target *Target) {
	tp := TestMinimalProject(t)
	target, err := tp.factory.NewTarget(
		[]TargetOption{
			WithProject(tp),
			WithTargetRef(
				&vagrant_plugin_sdk.Ref_Target{
					Project: tp.Ref().(*vagrant_plugin_sdk.Ref_Project),
					Name:    filepath.Base(testTempDir(t)),
				},
			),
		}...,
	)
	require.NoError(t, err)
	require.NoError(t, target.Save())
	require.NoError(t, tp.Reload())

	return
}

// TestMachine returns a fully in-memory and side-effect free Machine that
// can be used for testing. Additional options can be given to provide your own
// factories, configuration, etc.
func TestMachine(t testing.T, tp *Project, opts ...TestTargetOption) (machine *Machine) {
	tt := TestTarget(t, tp, &vagrant_server.Target{})
	specialized, err := tt.Specialize((*core.Machine)(nil))
	require.NoError(t, err)

	machine = specialized.(*Machine)
	for _, opt := range opts {
		if oerr := opt(machine); oerr != nil {
			err = multierror.Append(err, oerr)
		}
	}
	require.NoError(t, err)

	return
}

// TestMinimalMachine uses a minimal project to setup the most basic machine
// that will work for testing
func TestMinimalMachine(t testing.T) (machine *Machine) {
	tp := TestMinimalProject(t)
	tt := TestTarget(t, tp, &vagrant_server.Target{})
	specialized, err := tt.Specialize((*core.Machine)(nil))
	require.NoError(t, err)

	machine = specialized.(*Machine)
	return
}

type TestTargetOption func(interface{}) error

func WithTestTargetConfig(config *component.ConfigData) TestTargetOption {
	return func(raw interface{}) (err error) {
		switch v := raw.(type) {
		case *Target:
			return mergo.Merge(v.vagrantfile.root, config)
		case *Machine:
			return mergo.Merge(v.vagrantfile.root, config)
		default:
			panic(fmt.Sprintf("Invalid type for TestTargetOption (%T)", raw))
		}
	}
}

func WithTestTargetProvider(provider string) TestTargetOption {
	return func(raw interface{}) (err error) {
		switch v := raw.(type) {
		case *Target:
			v.target.Provider = provider
		case *Machine:
			v.target.Provider = provider
		default:
			panic(fmt.Sprintf("Invalid type for TestTargetOption (%T)", raw))
		}
		return
	}
}