github.com/gophercloud/gophercloud@v1.11.0/.github/CONTRIBUTING.md (about)

     1  # Contributing to Gophercloud
     2  
     3  - [New Contributor Tutorial](#new-contributor-tutorial)
     4  - [3 ways to get involved](#3-ways-to-get-involved)
     5  - [Getting started](#getting-started)
     6  - [Tests](#tests)
     7  - [Style guide](#basic-style-guide)
     8  
     9  ## New Contributor Tutorial
    10  
    11  For new contributors, we've put together a detailed tutorial
    12  [here](https://github.com/gophercloud/gophercloud/tree/master/docs/contributor-tutorial)!
    13  
    14  ## 3 ways to get involved
    15  
    16  There are three main ways you can get involved in our open-source project, and
    17  each is described briefly below.
    18  
    19  ### 1. Fixing bugs
    20  
    21  If you want to start fixing open bugs, we'd really appreciate that! Bug fixing
    22  is central to any project. The best way to get started is by heading to our
    23  [bug tracker](https://github.com/gophercloud/gophercloud/issues) and finding open
    24  bugs that you think nobody is working on. It might be useful to comment on the
    25  thread to see the current state of the issue and if anybody has made any
    26  breakthroughs on it so far.
    27  
    28  ### 2. Improving documentation
    29  
    30  Gophercloud's documentation is automatically generated from the source code
    31  and can be read online at [godoc.org](https://godoc.org/github.com/gophercloud/gophercloud).
    32  
    33  If you feel that a certain section could be improved - whether it's to clarify
    34  ambiguity, correct a technical mistake, or to fix a grammatical error - please
    35  feel entitled to do so! We welcome doc pull requests with the same childlike
    36  enthusiasm as any other contribution!
    37  
    38  ### 3. Working on a new feature
    39  
    40  If you've found something we've left out, we'd love for you to add it! Please
    41  first open an issue to indicate your interest to a core contributor - this
    42  enables quick/early feedback and can help steer you in the right direction by
    43  avoiding known issues. It might also help you avoid losing time implementing
    44  something that might not ever work or is outside the scope of the project.
    45  
    46  While you're implementing the feature, one tip is to prefix your Pull Request
    47  title with `[wip]` - then people know it's a work in progress. Once the PR is
    48  ready for review, you can remove the `[wip]` tag and request a review.
    49  
    50  We ask that you do not submit a feature that you have not spent time researching
    51  and testing first-hand in an actual OpenStack environment. While we appreciate
    52  the contribution, submitting code which you are unfamiliar with is a risk to the
    53  users who will ultimately use it. See our [acceptance tests readme](/acceptance)
    54  for information about how you can create a local development environment to
    55  better understand the feature you're working on.
    56  
    57  Please do not hesitate to ask questions or request clarification. Your
    58  contribution is very much appreciated and we are happy to work with you to get
    59  it merged.
    60  
    61  ## Getting Started
    62  
    63  As a contributor you will need to setup your workspace in a slightly different
    64  way than just downloading it. Here are the basic instructions:
    65  
    66  1. Configure your `$GOPATH` and run `go get` as described in the main
    67  [README](/README.md#how-to-install) but add `-tags "fixtures acceptance"` to
    68  get dependencies for unit and acceptance tests.
    69  
    70     ```bash
    71     go get -tags "fixtures acceptance" github.com/gophercloud/gophercloud
    72     ```
    73  
    74  2. Move into the directory that houses your local repository:
    75  
    76     ```bash
    77     cd ${GOPATH}/src/github.com/gophercloud/gophercloud
    78     ```
    79  
    80  3. Fork the `gophercloud/gophercloud` repository and update your remote refs. You
    81  will need to rename the `origin` remote branch to `upstream`, and add your
    82  fork as `origin` instead:
    83  
    84     ```bash
    85     git remote rename origin upstream
    86     git remote add origin git@github.com:<my_username>/gophercloud.git
    87     ```
    88  
    89  4. Checkout the latest development branch:
    90  
    91     ```bash
    92     git checkout master
    93     ```
    94  
    95  5. If you're working on something (discussed more in detail below), you will
    96  need to checkout a new feature branch:
    97  
    98     ```bash
    99     git checkout -b my-new-feature
   100     ```
   101  
   102  6. Use a standard text editor or IDE of your choice to make your changes to the code or documentation. Once finished, commit them.
   103  
   104     ```bash
   105     git status
   106     git add path/to/changed/file.go
   107     git commit
   108     ```
   109  
   110  7. Submit your branch as a [Pull Request](https://help.github.com/articles/creating-a-pull-request/). When submitting a Pull Request, please follow our [Style Guide](https://github.com/gophercloud/gophercloud/blob/master/docs/STYLEGUIDE.md).
   111  
   112  > Further information about using Git can be found [here](https://git-scm.com/book/en/v2).
   113  
   114  Happy Hacking!
   115  
   116  ## Tests
   117  
   118  When working on a new or existing feature, testing will be the backbone of your
   119  work since it helps uncover and prevent regressions in the codebase. There are
   120  two types of test we use in Gophercloud: unit tests and acceptance tests, which
   121  are both described below.
   122  
   123  ### Unit tests
   124  
   125  Unit tests are the fine-grained tests that establish and ensure the behavior
   126  of individual units of functionality. We usually test on an
   127  operation-by-operation basis (an operation typically being an API action) with
   128  the use of mocking to set up explicit expectations. Each operation will set up
   129  its HTTP response expectation, and then test how the system responds when fed
   130  this controlled, pre-determined input.
   131  
   132  To make life easier, we've introduced a bunch of test helpers to simplify the
   133  process of testing expectations with assertions:
   134  
   135  ```go
   136  import (
   137    "testing"
   138  
   139    "github.com/gophercloud/gophercloud/testhelper"
   140  )
   141  
   142  func TestSomething(t *testing.T) {
   143    result, err := Operation()
   144  
   145    testhelper.AssertEquals(t, "foo", result.Bar)
   146    testhelper.AssertNoErr(t, err)
   147  }
   148  
   149  func TestSomethingElse(t *testing.T) {
   150    testhelper.CheckEquals(t, "expected", "actual")
   151  }
   152  ```
   153  
   154  `AssertEquals` and `AssertNoErr` will throw a fatal error if a value does not
   155  match an expected value or if an error has been declared, respectively. You can
   156  also use `CheckEquals` and `CheckNoErr` for the same purpose; the only difference
   157  being that `t.Errorf` is raised rather than `t.Fatalf`.
   158  
   159  Here is a truncated example of mocked HTTP responses:
   160  
   161  ```go
   162  import (
   163  	"testing"
   164  
   165  	th "github.com/gophercloud/gophercloud/testhelper"
   166  	fake "github.com/gophercloud/gophercloud/testhelper/client"
   167  	"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
   168  )
   169  
   170  func TestGet(t *testing.T) {
   171  	// Setup the HTTP request multiplexer and server
   172  	th.SetupHTTP()
   173  	defer th.TeardownHTTP()
   174  
   175  	th.Mux.HandleFunc("/networks/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
   176  		// Test we're using the correct HTTP method
   177  		th.TestMethod(t, r, "GET")
   178  
   179  		// Test we're setting the auth token
   180  		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
   181  
   182  		// Set the appropriate headers for our mocked response
   183  		w.Header().Add("Content-Type", "application/json")
   184  		w.WriteHeader(http.StatusOK)
   185  
   186  		// Set the HTTP body
   187  		fmt.Fprintf(w, `
   188  {
   189      "network": {
   190          "status": "ACTIVE",
   191          "name": "private-network",
   192          "admin_state_up": true,
   193          "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
   194          "shared": true,
   195          "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
   196      }
   197  }
   198  			`)
   199  	})
   200  
   201  	// Call our API operation
   202  	network, err := networks.Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
   203  
   204  	// Assert no errors and equality
   205  	th.AssertNoErr(t, err)
   206  	th.AssertEquals(t, n.Status, "ACTIVE")
   207  }
   208  ```
   209  
   210  ### Acceptance tests
   211  
   212  As we've already mentioned, unit tests have a very narrow and confined focus -
   213  they test small units of behavior. Acceptance tests on the other hand have a
   214  far larger scope: they are fully functional tests that test the entire API of a
   215  service in one fell swoop. They don't care about unit isolation or mocking
   216  expectations, they instead do a full run-through and consequently test how the
   217  entire system _integrates_ together. When an API satisfies expectations, it
   218  proves by default that the requirements for a contract have been met.
   219  
   220  Please be aware that acceptance tests will hit a live API - and may incur
   221  service charges from your provider. Although most tests handle their own
   222  teardown procedures, it is always worth manually checking that resources are
   223  deleted after the test suite finishes.
   224  
   225  We provide detailed information about how to set up local acceptance test
   226  environments in our [acceptance tests readme](/acceptance).
   227  
   228  ### Running tests
   229  
   230  To run all tests:
   231  
   232    ```bash
   233    go test -tags fixtures ./...
   234    ```
   235  
   236  To run all tests with verbose output:
   237  
   238    ```bash
   239    go test -v -tags fixtures ./...
   240    ```
   241  
   242  To run tests that match certain [build tags]():
   243  
   244    ```bash
   245    go test -tags "fixtures foo bar" ./...
   246    ```
   247  
   248  To run tests for a particular sub-package:
   249  
   250    ```bash
   251    cd ./path/to/package && go test -tags fixtures ./...
   252    ```
   253  
   254  ## Style guide
   255  
   256  See [here](/docs/STYLEGUIDE.md)