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!!