1// 2// Copyright (c) 2018, Joyent, Inc. All rights reserved. 3// 4// This Source Code Form is subject to the terms of the Mozilla Public 5// License, v. 2.0. If a copy of the MPL was not distributed with this 6// file, You can obtain one at http://mozilla.org/MPL/2.0/. 7// 8 9package testutils 10 11import ( 12 "errors" 13 "fmt" 14 "log" 15 "os" 16 "testing" 17 18 triton "github.com/joyent/triton-go" 19 "github.com/joyent/triton-go/authentication" 20) 21 22const TestEnvVar = "TRITON_TEST" 23 24type TestCase struct { 25 Steps []Step 26 State TritonStateBag 27} 28 29func AccTest(t *testing.T, c TestCase) { 30 // We only run acceptance tests if an env var is set because they're 31 // slow and generally require some outside configuration. 32 if os.Getenv(TestEnvVar) == "" { 33 t.Skip(fmt.Sprintf( 34 "Acceptance tests skipped unless env '%s' set", 35 TestEnvVar)) 36 return 37 } 38 39 // We require verbose mode so that the user knows what is going on. 40 if !testing.Verbose() { 41 t.Fatal("Acceptance tests must be run with the -v flag on tests") 42 return 43 } 44 45 tritonURL := triton.GetEnv("URL") 46 tritonAccount := triton.GetEnv("ACCOUNT") 47 tritonKeyID := triton.GetEnv("KEY_ID") 48 tritonKeyMaterial := triton.GetEnv("KEY_MATERIAL") 49 userName := triton.GetEnv("USER") 50 mantaURL := triton.GetEnv("MANTA_URL") 51 52 var prerollErrors []error 53 if tritonURL == "" { 54 prerollErrors = append(prerollErrors, 55 errors.New("The TRITON_URL environment variable must be set to run acceptance tests")) 56 } 57 if tritonAccount == "" { 58 prerollErrors = append(prerollErrors, 59 errors.New("The TRITON_ACCOUNT environment variable must be set to run acceptance tests")) 60 } 61 if tritonKeyID == "" { 62 prerollErrors = append(prerollErrors, 63 errors.New("The TRITON_KEY_ID environment variable must be set to run acceptance tests")) 64 } 65 if len(prerollErrors) > 0 { 66 for _, err := range prerollErrors { 67 t.Error(err) 68 } 69 t.FailNow() 70 } 71 72 var signer authentication.Signer 73 var err error 74 if tritonKeyMaterial != "" { 75 log.Println("[INFO] Creating Triton Client with Private Key Signer...") 76 input := authentication.PrivateKeySignerInput{ 77 KeyID: tritonKeyID, 78 PrivateKeyMaterial: []byte(tritonKeyMaterial), 79 AccountName: tritonAccount, 80 Username: userName, 81 } 82 signer, err = authentication.NewPrivateKeySigner(input) 83 if err != nil { 84 t.Fatalf("Error creating private key signer: %s", err) 85 } 86 } else { 87 log.Println("[INFO] Creating Triton Client with SSH Key Signer...") 88 input := authentication.SSHAgentSignerInput{ 89 KeyID: tritonKeyID, 90 AccountName: tritonAccount, 91 Username: userName, 92 } 93 signer, err = authentication.NewSSHAgentSigner(input) 94 if err != nil { 95 t.Fatalf("Error creating SSH Agent signer: %s", err) 96 } 97 } 98 99 // Old world... we spun up a universal client. This is pushed deeper into 100 // the process within `testutils.StepClient`. 101 // 102 // client, err := NewClient(tritonURL, tritonAccount, signer) 103 // if err != nil { 104 // t.Fatalf("Error creating Triton Client: %s", err) 105 // } 106 107 config := &triton.ClientConfig{ 108 TritonURL: tritonURL, 109 MantaURL: mantaURL, 110 AccountName: tritonAccount, 111 Username: userName, 112 Signers: []authentication.Signer{signer}, 113 } 114 115 state := &basicTritonStateBag{ 116 TritonConfig: config, 117 } 118 119 runner := &basicRunner{ 120 Steps: c.Steps, 121 } 122 123 runner.Run(state) 124 125 if errs := state.ErrorsOrNil(); errs != nil { 126 for _, err := range errs { 127 t.Error(err) 128 } 129 t.Fatal("\n\nThere may be dangling resources in your Triton account!") 130 } 131} 132