github.com/vmware/go-vcloud-director/v2@v2.24.0/TESTING.md (about) 1 # Testing in go-vcloud-director 2 To run tests in go-vcloud-director, users must use a yaml file specifying information about the users vcd. Users can set the `GOVCD_CONFIG` environmental variable with the path. 3 4 ``` 5 export GOVCD_CONFIG=your/path/to/test-configuration.yaml 6 ``` 7 8 If no environmental variable is set it will default to `govcd_test_config.yaml` in the same path where the test files are (`./govcd`.) 9 10 ## Example Config file 11 12 See `./govcd/sample_govcd_test_config.yaml`. 13 14 Users must specify their username, password, API endpoint, vcd and org for any tests to run. Otherwise all tests get stopped. For more comprehensive testing the catalog, catalog item, storage profile, network, edge gateway, IP fields can be set using the format in the sample. 15 Note that all the entities included in the configuration file must exist already and will not be removed or left altered during the tests. Leaving a field blank will skip one or more corresponding tests. 16 17 If you are more comfortable with JSON, you can supply the configuration in that format. The field names are the same. See `./govcd/sample_govcd_test_config.json`. 18 19 ## Running Tests 20 Once you have a config file setup, you can run tests with either the makefile or with go itself. 21 22 To run tests with go use these commands: 23 24 ```bash 25 cd govcd 26 go test -tags "functional" -check.v . 27 ``` 28 29 If you want to see more details during the test run, use `-check.vv` instead of `-check.v`. 30 31 To run tests with the makefile: 32 33 ```bash 34 make test 35 ``` 36 37 To run a specific test: 38 39 ```bash 40 cd govcd 41 go test -check.f Test_SetOvf -check.vv . 42 ``` 43 44 The tests can run with several tags that define which components are tested. 45 Using the Makefile, you can run one of the following: 46 47 ```bash 48 make testcatalog 49 make testnetwork 50 make testvapp 51 ``` 52 53 For more options, you can run manually in `./govcd` 54 When running `go test` without tags, we'll get a list of tags that are available. 55 56 ```bash 57 $ go test -v . 58 === RUN TestTags 59 --- FAIL: TestTags (0.00s) 60 api_test.go:59: # No tags were defined 61 api_test.go:46: 62 # ----------------------------------------------------- 63 # Tags are required to run the tests 64 # ----------------------------------------------------- 65 66 At least one of the following tags should be defined: 67 68 * ALL : Runs all the tests (== functional + unit == all feature tests) 69 70 * functional: Runs all the tests that use check.v1 71 * unit: Runs unit tests that do not need a live vCD 72 73 * catalog: Runs catalog related tests (also catalog_item, media) 74 * disk: Runs disk related tests 75 * extnetwork: Runs external network related tests 76 * lb: Runs load balancer related tests 77 * network: Runs network related tests 78 * gateway: Runs edge gateway related tests 79 * org: Runs org related tests 80 * query: Runs query related tests 81 * system: Runs system related tests 82 * task: Runs task related tests 83 * user: Runs user related tests 84 * vapp: Runs vapp related tests 85 * vdc: Runs vdc related tests 86 * vm: Runs vm related tests 87 88 Examples: 89 90 go test -tags functional -check.vv -timeout=45m . 91 go test -tags catalog -check.vv -timeout=45m . 92 go test -tags "query extnetwork" -check.vv -timeout=45m . 93 FAIL 94 FAIL github.com/vmware/go-vcloud-director/v2/govcd 0.011s 95 ``` 96 97 To run tests with `concurency` build tag (omitted by default) and Go race detector: 98 99 ```bash 100 make testconcurrent 101 ``` 102 __Note__. At the moment they are failing because go-vcloud-director is not thread safe. 103 104 ## How to write a test 105 106 go-vcloud-director tests are written using [check.v1](https://labix.org/gocheck), an auxiliary library for tests that provides several methods to help developers write comprehensive tests. 107 108 109 ### Imports 110 111 The tests for `govcd` package must belong to the same package, so no need to import govcd. 112 The mandatory import is 113 114 ```go 115 checks "gopkg.in/check.v1" 116 ``` 117 118 We refer to this package as `checks`. There are examples online using a dot (".") instead of an explicit name, but please don't do it, as it pollutes the name space and makes code readability harder. 119 120 ### Test function header 121 122 Every function that tests something related to govcd should have this header: 123 124 ```go 125 func (vcd *TestVCD) Test_SomeFunctionality(check *checks.C) { 126 ... 127 } 128 ``` 129 130 The `vcd` variable is our handler of the govcd functions. Its type is declared within `./govcd/api_vcd_test.go` and contains accessors to the main structures needed for running tests: 131 132 ```go 133 type TestVCD struct { 134 client *VCDClient 135 org Org 136 vdc Vdc 137 vapp VApp 138 config TestConfig 139 } 140 ``` 141 This entity is initialized when the test starts. You can assume that the variable is ready for usage. If something happens during initialization, it should fail before it comes to your function. 142 143 The `check` variable is our interface with the `check.v1` package. We can do several things with it, such as skipping a test, probing a condition, declare success or failure, and more. 144 145 146 ### Adding build tags. 147 148 All tests need to have a build tag. The tag should be the first line of the file, followed by a blank line 149 150 ```go 151 // +build functional featurename ALL 152 153 package govcd 154 ``` 155 156 Tests that integrate in the functional suite use the tag `functional`. Using that tag, we can run all functional tests 157 at once. 158 We define as `functional` the tests that need a live vCD to run. 159 160 1. The test should always define the `ALL` tag: 161 162 * ALL : Runs all the tests 163 164 2. The test should also always define either the `unit` or `functional` tag: 165 166 * functional: Runs all the tests that use check.v1 167 * unit: Runs unit tests that do not need a live vCD 168 169 3. Finally, the test should always define the feature tag. For example: 170 171 * catalog: Runs catalog related tests (also `catalog_item`, `media`) 172 * disk: Runs disk related tests 173 174 The `ALL` tag includes tests that use a different framework. At the moment, this is useful to run a global compilation test. 175 Depending on which additional tests we will implement, we may change the dependency on the `ALL` tag if we detect 176 clashes between frameworks. 177 178 If the test file defines a new feature tag (i.e. one that has not been used before) the file should also implement an 179 `init` function that sets the tag in the global tag list. 180 This information is used by the main tag test in `api_test.go` to determine which tags were activated. 181 182 ```go 183 func init() { 184 testingTags["newtag"] = "filename_test.go" 185 } 186 ``` 187 188 **VERY IMPORTANT**: if we add a test that runs using a different tag (i.e. it is not included in `functional` tests), we need 189 to add such test to the Makefile under `make test`. **The general principle is that `make test` runs all tests**. If this can't be 190 achieved by adding the new test to the `functional` tag (perhaps because we foresee framework conflicts), we need to add the 191 new test as a separate command. 192 For example: 193 194 ``` 195 test: fmtcheck 196 @echo "==> Running Tests" 197 cd govcd && \ 198 go test -tags "MyNewTag" -timeout=10m -check.vv . && \ 199 go test -tags "functional" -timeout=60m -check.vv . 200 ``` 201 202 or we can encapsulate a complex test into a self containing script. 203 204 ``` 205 test: fmtcheck 206 @echo "==> Running Tests" 207 ./scripts/my_complicated_test.sh 208 cd govcd && go test -tags "functional" -timeout=60m -check.vv . 209 ``` 210 211 ### Basic test function organization. 212 213 Within the testing function, you should perform four actions: 214 215 1. Run all operations that are needed for the test, such as finding a particular organization, or vDC, or vApp, deploying a VM, etc. 216 2. Run the operation being tested (such as deploy a VM, retrieve a VM or vApp, etc.) 217 3. Run the tests, which usually means using `check.Assert` or `check.Check` to compare known data with what was found during the test execution 218 4. Clean up all entities and data that was created or altered during the test. For example: delete a vApp that was deployed, or remove a setting that was added to a network. 219 220 An example: 221 222 ```go 223 package govcd 224 225 import ( 226 "fmt" 227 checks "gopkg.in/check.v1" 228 ) 229 230 func (vcd *TestVCD) Test_GetVAppTemplate(check *checks.C) { 231 232 fmt.Printf("Running: %s\n", check.TestName()) 233 234 // #0 Check that the data needed for this test is in the configuration 235 if vcd.config.VCD.Catalog.Name == "" { 236 check.Skip("Catalog name not provided. Test can't proceed") 237 } 238 239 // #1: preliminary data 240 cat, err := vcd.org.FindCatalog(vcd.config.VCD.Catalog.Name) 241 if err != nil { 242 check.Skip("Catalog not found. Test can't proceed") 243 } 244 245 // #2: Run the operation being tested 246 catitem, err := cat.FindCatalogItem(vcd.config.VCD.Catalog.Catalogitem) 247 check.Assert(err, checks.IsNil) 248 249 vapptemplate, err := catitem.GetVAppTemplate() 250 251 // #3: Tests the object contents 252 check.Assert(err, checks.IsNil) 253 check.Assert(vapptemplate.VAppTemplate.Name, checks.Equals, vcd.config.VCD.Catalog.Catalogitem) 254 if vcd.config.VCD.Catalog.Description != "" { 255 check.Assert(vapptemplate.VAppTemplate.Description, checks.Equals, vcd.config.VCD.Catalog.CatalogItemDescription) 256 } 257 // #4 is not needed here, as the test did not modify anything 258 } 259 ``` 260 261 When step #4 is also used, we should make sure that the cleanup step is always reached. 262 Here's another simplified example 263 264 ```go 265 func (vcd *TestVCD) Test_ComposeVApp(check *checks.C) { 266 267 fmt.Printf("Running: %s\n", check.TestName()) 268 269 // Populate the input data 270 // [ ... ] 271 // See the full function in govcd/vcd_test.go 272 273 // Run the main operation 274 task, err := vcd.vdc.ComposeVApp(networks, vapptemplate, storageprofileref, temp_vapp_name, temp_vapp_description) 275 276 // These tests can fail: we need to make sure that the new entity was created 277 check.Assert(err, checks.IsNil) 278 check.Assert(task.Task.OperationName, checks.Equals, composeVappName) 279 // Get VApp 280 vapp, err := vcd.vdc.FindVAppByName(temp_vapp_name) 281 check.Assert(err, checks.IsNil) 282 283 // After a successful creation, the entity is added to the cleanup list. 284 // If something fails after this point, the entity will be removed 285 AddToCleanupList(composeVappName, "vapp", "", "Test_ComposeVApp") 286 287 // Once the operation is successful, we won't trigger a failure 288 // until after the vApp deletion 289 // Instead of "Assert" we run "Check". If one of the following 290 // checks fails, it won't terminate the test, and we can reach the cleanup point. 291 check.Check(vapp.VApp.Name, checks.Equals, temp_vapp_name) 292 check.Check(vapp.VApp.Description, checks.Equals, temp_vapp_description) 293 294 // [ ... ] 295 // More checks follow 296 297 // Here's the cleanup point 298 // Deleting VApp 299 task, err = vapp.Delete() 300 task.WaitTaskCompletion() 301 302 // Here we can fail again. 303 check.Assert(err, checks.IsNil) 304 no_such_vapp, err := vcd.vdc.FindVAppByName(temp_vapp_name) 305 check.Assert(err, checks.NotNil) 306 check.Assert(no_such_vapp.VApp, checks.IsNil) 307 // If this deletion fails, a further attempt will be made 308 // by the cleanup function at the end of all tests 309 } 310 ``` 311 312 # Golden test files 313 314 In some tests (especially unit) there is a need for data samples (Golden files). There are a few 315 helpers in `api_vcd_test_unit.go` - `goldenString` and `goldenBytes`. These helpers are here to 316 unify data storage naming formats. All files will be stored in `test-resources/golden/`. File name 317 will be formatted as `t.Name() + "custompart" + ".golden"` (e.g. 318 "TestSamlAdfsAuthenticate_custompart.golden"). These functions allow to update existing data by 319 supplying actual data and setting `update=true`. As an example `TestSamlAdfsAuthenticate` test uses 320 golden data. 321 322 # Environment variables and corresponding flags 323 324 While running tests, the following environment variables can be used: 325 326 * `GOVCD_CONFIG=/path/file`: sets an alternative configuration file for the tests. 327 e.g.: `GOVCD_CONFIG=/some/path/govcd_test_config.yaml go test -tags functional -timeout 0 .` 328 * `GOVCD_DEBUG=1` (`-vcd-debug`): enable debug output on screen. 329 * `GOVCD_TEST_VERBOSE=1` (`-vcd-verbose`): shows execution details in some tests. 330 * `GOVCD_SKIP_VAPP_CREATION=1` (`-vcd-skip-vapp-creation`): will not create the initial vApp. All tests that 331 depend on a vApp availability will be skipped. 332 * `GOVCD_TASK_MONITOR=show|log|simple_show|simple|log`: sets a task monitor function when running `task.WaitCompletion` 333 * `show` : displays full task details on screen 334 * `log` : writes full task details in the log 335 * `simple_show` : displays a summary line for the task on screen 336 * `simple_log` : writes a summary line for the task in the log 337 * `GOVCD_IGNORE_CLEANUP_FILE` (`-vcd-ignore-cleanup-file`): Ignore the cleanup file if it is left behind after a test failure. 338 This could be useful after running a single test, when we need to check how the test behaves with the resource still 339 in place. 340 * `GOVCD_SHOW_REQ` (`-vcd-show-request`): shows the API request on standard output 341 * `GOVCD_SHOW_RESP` (`-vcd-show-response`): shows the API response on standard output 342 * `VCD_TOKEN` : specifies the authorization token to use instead of username/password 343 (Use `./scripts/get_token.sh` to retrieve one) 344 * `GOVCD_KEEP_TEST_OBJECTS` will skip deletion of objects created during tests. 345 * `GOVCD_API_VERSION` allows to select the API version to use. This must be used **for testing purposes only** as the SDK 346 has been tested to use certain version of the API. Using this environment variable may lead to unexpected failures. 347 348 When both the environment variable and the command line option are possible, the environment variable gets evaluated first. 349 350 # SAML auth testing with Active Directory Federation Services (ADFS) as Identity Provider (IdP) 351 352 This package supports SAML authentication with ADFS. It can be achieved by supplying 353 `WithSamlAdfs()` function to `NewVCDClient`. Testing framework also supports SAML auth and there are 354 a few ways to test it: 355 * There is a unit test `TestSamlAdfsAuthenticate` which spawns mock servers and does not require 356 ADFS or SAML being configured. It tests the flow based on mock endpoints. 357 * Using regular `user` and `password` to supply SAML credentials and `true` for `useSamlAdfs` 358 variable (optionally one can override Relaying Party Trust ID with variable `customAdfsRptId`). 359 That way all tests would run using SAML authentication flow. 360 * Using `samlUser`, `samlPassword` and optionally `samlCustomRptId` variables will enable 361 `Test_SamlAdfsAuth` test run. Test_SamlAdfsAuth will test and compare VDC retrieved using main 362 authentication credentials vs the one retrieved using specific SAML credentials. 363 364 All these tests can run in combination. 365 366 # Final Words 367 Be careful about using our tests as these tests run on a real vcd. If you don't have 1 gb of ram and 2 vcpus available then you should not be running tests that deploy your vm/change memory and cpu. However everything created will be removed at the end of testing. 368 369 Have fun using our SDK!!