-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
provisioner.go
131 lines (109 loc) · 4.54 KB
/
provisioner.go
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
package framework
import (
"fmt"
"os"
"testing"
capi "github.com/hashicorp/consul/api"
napi "github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/helper/uuid"
vapi "github.com/hashicorp/vault/api"
)
// ClusterInfo is a handle to a provisioned cluster, along with clients
// a test run can use to connect to the cluster.
type ClusterInfo struct {
ID string
Name string
NomadClient *napi.Client
ConsulClient *capi.Client
VaultClient *vapi.Client
}
// SetupOptions defines options to be given to the Provisioner when
// calling Setup* methods.
type SetupOptions struct {
Name string
ExpectConsul bool // If true, fails if a Consul client can't be configured
ExpectVault bool // If true, fails if a Vault client can't be configured
}
// Provisioner interface is used by the test framework to provision API
// clients for a Nomad cluster, with the possibility of extending to provision
// standalone clusters for each test case in the future.
//
// The Setup* methods are hooks that get run at the appropriate stage. They
// return a ClusterInfo handle that helps TestCases isolate test state if
// they use the ClusterInfo.ID as part of job IDs.
//
// The TearDown* methods are hooks to clean up provisioned cluster state
// that isn't covered by the test case's implementation of AfterEachTest.
type Provisioner interface {
// SetupTestRun is called at the start of the entire test run.
SetupTestRun(t *testing.T, opts SetupOptions) (*ClusterInfo, error)
// SetupTestSuite is called at the start of each TestSuite.
// TODO: no current provisioner implementation uses this, but we
// could use it to provide each TestSuite with an entirely separate
// Nomad cluster.
SetupTestSuite(t *testing.T, opts SetupOptions) (*ClusterInfo, error)
// SetupTestCase is called at the start of each TestCase in every TestSuite.
SetupTestCase(t *testing.T, opts SetupOptions) (*ClusterInfo, error)
// TODO: no current provisioner implementation uses any of these,
// but it's the obvious need if we setup/teardown after each TestSuite
// or TestCase.
// TearDownTestCase is called after each TestCase in every TestSuite.
TearDownTestCase(t *testing.T, clusterID string) error
// TearDownTestSuite is called after every TestSuite.
TearDownTestSuite(t *testing.T, clusterID string) error
// TearDownTestRun is called at the end of the entire test run.
TearDownTestRun(t *testing.T, clusterID string) error
}
// DefaultProvisioner is a Provisioner that doesn't deploy a Nomad cluster
// (because that's handled by Terraform elsewhere), but build clients from
// environment variables.
var DefaultProvisioner Provisioner = new(singleClusterProvisioner)
type singleClusterProvisioner struct{}
// SetupTestRun in the default case is a no-op.
func (p *singleClusterProvisioner) SetupTestRun(t *testing.T, opts SetupOptions) (*ClusterInfo, error) {
return &ClusterInfo{ID: "framework", Name: "framework"}, nil
}
// SetupTestSuite in the default case is a no-op.
func (p *singleClusterProvisioner) SetupTestSuite(t *testing.T, opts SetupOptions) (*ClusterInfo, error) {
return &ClusterInfo{
ID: uuid.Generate()[:8],
Name: opts.Name,
}, nil
}
// SetupTestCase in the default case only creates new clients and embeds the
// TestCase name into the ClusterInfo handle.
func (p *singleClusterProvisioner) SetupTestCase(t *testing.T, opts SetupOptions) (*ClusterInfo, error) {
// Build ID based off given name
info := &ClusterInfo{
ID: uuid.Generate()[:8],
Name: opts.Name,
}
// Build Nomad api client
nomadClient, err := napi.NewClient(napi.DefaultConfig())
if err != nil {
return nil, err
}
info.NomadClient = nomadClient
if opts.ExpectConsul {
consulClient, err := capi.NewClient(capi.DefaultConfig())
if err != nil {
return nil, fmt.Errorf("expected Consul: %v", err)
}
info.ConsulClient = consulClient
}
if len(os.Getenv(vapi.EnvVaultAddress)) != 0 {
vaultClient, err := vapi.NewClient(vapi.DefaultConfig())
if err != nil && opts.ExpectVault {
return nil, err
}
info.VaultClient = vaultClient
} else if opts.ExpectVault {
return nil, fmt.Errorf("vault client expected but environment variable %s not set",
vapi.EnvVaultAddress)
}
return info, err
}
// all TearDown* methods of the default provisioner leave the test environment in place
func (p *singleClusterProvisioner) TearDownTestCase(_ *testing.T, _ string) error { return nil }
func (p *singleClusterProvisioner) TearDownTestSuite(_ *testing.T, _ string) error { return nil }
func (p *singleClusterProvisioner) TearDownTestRun(_ *testing.T, _ string) error { return nil }