github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/e2e/framework/provisioner.go (about) 1 package framework 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 8 capi "github.com/hashicorp/consul/api" 9 napi "github.com/hashicorp/nomad/api" 10 "github.com/hashicorp/nomad/helper/uuid" 11 vapi "github.com/hashicorp/vault/api" 12 ) 13 14 // ClusterInfo is a handle to a provisioned cluster, along with clients 15 // a test run can use to connect to the cluster. 16 type ClusterInfo struct { 17 ID string 18 Name string 19 NomadClient *napi.Client 20 ConsulClient *capi.Client 21 VaultClient *vapi.Client 22 } 23 24 // SetupOptions defines options to be given to the Provisioner when 25 // calling Setup* methods. 26 type SetupOptions struct { 27 Name string 28 ExpectConsul bool // If true, fails if a Consul client can't be configured 29 ExpectVault bool // If true, fails if a Vault client can't be configured 30 } 31 32 // Provisioner interface is used by the test framework to provision API 33 // clients for a Nomad cluster, with the possibility of extending to provision 34 // standalone clusters for each test case in the future. 35 // 36 // The Setup* methods are hooks that get run at the appropriate stage. They 37 // return a ClusterInfo handle that helps TestCases isolate test state if 38 // they use the ClusterInfo.ID as part of job IDs. 39 // 40 // The TearDown* methods are hooks to clean up provisioned cluster state 41 // that isn't covered by the test case's implementation of AfterEachTest. 42 type Provisioner interface { 43 // SetupTestRun is called at the start of the entire test run. 44 SetupTestRun(t *testing.T, opts SetupOptions) (*ClusterInfo, error) 45 46 // SetupTestSuite is called at the start of each TestSuite. 47 // TODO: no current provisioner implementation uses this, but we 48 // could use it to provide each TestSuite with an entirely separate 49 // Nomad cluster. 50 SetupTestSuite(t *testing.T, opts SetupOptions) (*ClusterInfo, error) 51 52 // SetupTestCase is called at the start of each TestCase in every TestSuite. 53 SetupTestCase(t *testing.T, opts SetupOptions) (*ClusterInfo, error) 54 55 // TODO: no current provisioner implementation uses any of these, 56 // but it's the obvious need if we setup/teardown after each TestSuite 57 // or TestCase. 58 59 // TearDownTestCase is called after each TestCase in every TestSuite. 60 TearDownTestCase(t *testing.T, clusterID string) error 61 62 // TearDownTestSuite is called after every TestSuite. 63 TearDownTestSuite(t *testing.T, clusterID string) error 64 65 // TearDownTestRun is called at the end of the entire test run. 66 TearDownTestRun(t *testing.T, clusterID string) error 67 } 68 69 // DefaultProvisioner is a Provisioner that doesn't deploy a Nomad cluster 70 // (because that's handled by Terraform elsewhere), but build clients from 71 // environment variables. 72 var DefaultProvisioner Provisioner = new(singleClusterProvisioner) 73 74 type singleClusterProvisioner struct{} 75 76 // SetupTestRun in the default case is a no-op. 77 func (p *singleClusterProvisioner) SetupTestRun(t *testing.T, opts SetupOptions) (*ClusterInfo, error) { 78 return &ClusterInfo{ID: "framework", Name: "framework"}, nil 79 } 80 81 // SetupTestSuite in the default case is a no-op. 82 func (p *singleClusterProvisioner) SetupTestSuite(t *testing.T, opts SetupOptions) (*ClusterInfo, error) { 83 return &ClusterInfo{ 84 ID: uuid.Generate()[:8], 85 Name: opts.Name, 86 }, nil 87 } 88 89 // SetupTestCase in the default case only creates new clients and embeds the 90 // TestCase name into the ClusterInfo handle. 91 func (p *singleClusterProvisioner) SetupTestCase(t *testing.T, opts SetupOptions) (*ClusterInfo, error) { 92 // Build ID based off given name 93 info := &ClusterInfo{ 94 ID: uuid.Generate()[:8], 95 Name: opts.Name, 96 } 97 98 // Build Nomad api client 99 nomadClient, err := napi.NewClient(napi.DefaultConfig()) 100 if err != nil { 101 return nil, err 102 } 103 info.NomadClient = nomadClient 104 105 if opts.ExpectConsul { 106 consulClient, err := capi.NewClient(capi.DefaultConfig()) 107 if err != nil { 108 return nil, fmt.Errorf("expected Consul: %v", err) 109 } 110 info.ConsulClient = consulClient 111 } 112 113 if len(os.Getenv(vapi.EnvVaultAddress)) != 0 { 114 vaultClient, err := vapi.NewClient(vapi.DefaultConfig()) 115 if err != nil && opts.ExpectVault { 116 return nil, err 117 } 118 info.VaultClient = vaultClient 119 } else if opts.ExpectVault { 120 return nil, fmt.Errorf("vault client expected but environment variable %s not set", 121 vapi.EnvVaultAddress) 122 } 123 124 return info, err 125 } 126 127 // all TearDown* methods of the default provisioner leave the test environment in place 128 129 func (p *singleClusterProvisioner) TearDownTestCase(_ *testing.T, _ string) error { return nil } 130 func (p *singleClusterProvisioner) TearDownTestSuite(_ *testing.T, _ string) error { return nil } 131 func (p *singleClusterProvisioner) TearDownTestRun(_ *testing.T, _ string) error { return nil }