dep ensure

This commit is contained in:
Benjamin Elder
2018-10-24 17:24:58 -07:00
parent 41845522f6
commit 163515c5a0
6525 changed files with 84 additions and 3291220 deletions

View File

@@ -1,30 +0,0 @@
# cleanhttp
Functions for accessing "clean" Go http.Client values
-------------
The Go standard library contains a default `http.Client` called
`http.DefaultClient`. It is a common idiom in Go code to start with
`http.DefaultClient` and tweak it as necessary, and in fact, this is
encouraged; from the `http` package documentation:
> The Client's Transport typically has internal state (cached TCP connections),
so Clients should be reused instead of created as needed. Clients are safe for
concurrent use by multiple goroutines.
Unfortunately, this is a shared value, and it is not uncommon for libraries to
assume that they are free to modify it at will. With enough dependencies, it
can be very easy to encounter strange problems and race conditions due to
manipulation of this shared value across libraries and goroutines (clients are
safe for concurrent use, but writing values to the client struct itself is not
protected).
Making things worse is the fact that a bare `http.Client` will use a default
`http.Transport` called `http.DefaultTransport`, which is another global value
that behaves the same way. So it is not simply enough to replace
`http.DefaultClient` with `&http.Client{}`.
This repository provides some simple functions to get a "clean" `http.Client`
-- one that uses the same default values as the Go standard library, but
returns a client that does not share any state with other clients.

View File

@@ -1,72 +0,0 @@
package cleanhttp
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestPrintablePathCheckHandler(t *testing.T) {
getTestHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
})
cases := map[string]struct {
path string
expectCode int
input *HandlerInput
}{
"valid nil input": {
path: "/valid",
expectCode: http.StatusOK,
input: nil,
},
"valid empty error status": {
path: "/valid",
expectCode: http.StatusOK,
input: &HandlerInput{},
},
"invalid newline": {
path: "/invalid\n",
expectCode: http.StatusBadRequest,
},
"invalid carriage return": {
path: "/invalid\r",
expectCode: http.StatusBadRequest,
},
"invalid null": {
path: "/invalid\x00",
expectCode: http.StatusBadRequest,
},
"invalid alternate status": {
path: "/invalid\n",
expectCode: http.StatusInternalServerError,
input: &HandlerInput{
ErrStatus: http.StatusInternalServerError,
},
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
// Create test HTTP server
ts := httptest.NewServer(PrintablePathCheckHandler(getTestHandler, tc.input))
defer ts.Close()
res, err := http.Get(ts.URL + tc.path)
if err != nil {
t.Fatal(err)
}
if tc.expectCode != res.StatusCode {
t.Fatalf("expected %d, got :%d", tc.expectCode, res.StatusCode)
}
})
}
}

View File

@@ -1,23 +0,0 @@
sudo: false
addons:
apt:
sources:
- sourceline: 'ppa:git-core/ppa'
packages:
- git
language: go
go:
- 1.8.x
- 1.9.x
- master
branches:
only:
- master
matrix:
allow_failures:
- go: master

View File

@@ -1,301 +0,0 @@
# go-getter
[![Build Status](http://img.shields.io/travis/hashicorp/go-getter.svg?style=flat-square)][travis]
[![Build status](https://ci.appveyor.com/api/projects/status/ulq3qr43n62croyq/branch/master?svg=true)][appveyor]
[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs]
[travis]: http://travis-ci.org/hashicorp/go-getter
[godocs]: http://godoc.org/github.com/hashicorp/go-getter
[appveyor]: https://ci.appveyor.com/project/hashicorp/go-getter/branch/master
go-getter is a library for Go (golang) for downloading files or directories
from various sources using a URL as the primary form of input.
The power of this library is being flexible in being able to download
from a number of different sources (file paths, Git, HTTP, Mercurial, etc.)
using a single string as input. This removes the burden of knowing how to
download from a variety of sources from the implementer.
The concept of a _detector_ automatically turns invalid URLs into proper
URLs. For example: "github.com/hashicorp/go-getter" would turn into a
Git URL. Or "./foo" would turn into a file URL. These are extensible.
This library is used by [Terraform](https://terraform.io) for
downloading modules and [Nomad](https://nomadproject.io) for downloading
binaries.
## Installation and Usage
Package documentation can be found on
[GoDoc](http://godoc.org/github.com/hashicorp/go-getter).
Installation can be done with a normal `go get`:
```
$ go get github.com/hashicorp/go-getter
```
go-getter also has a command you can use to test URL strings:
```
$ go install github.com/hashicorp/go-getter/cmd/go-getter
...
$ go-getter github.com/foo/bar ./foo
...
```
The command is useful for verifying URL structures.
## URL Format
go-getter uses a single string URL as input to download from a variety of
protocols. go-getter has various "tricks" with this URL to do certain things.
This section documents the URL format.
### Supported Protocols and Detectors
**Protocols** are used to download files/directories using a specific
mechanism. Example protocols are Git and HTTP.
**Detectors** are used to transform a valid or invalid URL into another
URL if it matches a certain pattern. Example: "github.com/user/repo" is
automatically transformed into a fully valid Git URL. This allows go-getter
to be very user friendly.
go-getter out of the box supports the following protocols. Additional protocols
can be augmented at runtime by implementing the `Getter` interface.
* Local files
* Git
* Mercurial
* HTTP
* Amazon S3
In addition to the above protocols, go-getter has what are called "detectors."
These take a URL and attempt to automatically choose the best protocol for
it, which might involve even changing the protocol. The following detection
is built-in by default:
* File paths such as "./foo" are automatically changed to absolute
file URLs.
* GitHub URLs, such as "github.com/mitchellh/vagrant" are automatically
changed to Git protocol over HTTP.
* BitBucket URLs, such as "bitbucket.org/mitchellh/vagrant" are automatically
changed to a Git or mercurial protocol using the BitBucket API.
### Forced Protocol
In some cases, the protocol to use is ambiguous depending on the source
URL. For example, "http://github.com/mitchellh/vagrant.git" could reference
an HTTP URL or a Git URL. Forced protocol syntax is used to disambiguate this
URL.
Forced protocol can be done by prefixing the URL with the protocol followed
by double colons. For example: `git::http://github.com/mitchellh/vagrant.git`
would download the given HTTP URL using the Git protocol.
Forced protocols will also override any detectors.
In the absense of a forced protocol, detectors may be run on the URL, transforming
the protocol anyways. The above example would've used the Git protocol either
way since the Git detector would've detected it was a GitHub URL.
### Protocol-Specific Options
Each protocol can support protocol-specific options to configure that
protocol. For example, the `git` protocol supports specifying a `ref`
query parameter that tells it what ref to checkout for that Git
repository.
The options are specified as query parameters on the URL (or URL-like string)
given to go-getter. Using the Git example above, the URL below is a valid
input to go-getter:
github.com/hashicorp/go-getter?ref=abcd1234
The protocol-specific options are documented below the URL format
section. But because they are part of the URL, we point it out here so
you know they exist.
### Subdirectories
If you want to download only a specific subdirectory from a downloaded
directory, you can specify a subdirectory after a double-slash `//`.
go-getter will first download the URL specified _before_ the double-slash
(as if you didn't specify a double-slash), but will then copy the
path after the double slash into the target directory.
For example, if you're downloading this GitHub repository, but you only
want to download the `test-fixtures` directory, you can do the following:
```
https://github.com/hashicorp/go-getter.git//test-fixtures
```
If you downloaded this to the `/tmp` directory, then the file
`/tmp/archive.gz` would exist. Notice that this file is in the `test-fixtures`
directory in this repository, but because we specified a subdirectory,
go-getter automatically copied only that directory contents.
Subdirectory paths may contain may also use filesystem glob patterns.
The path must match _exactly one_ entry or go-getter will return an error.
This is useful if you're not sure the exact directory name but it follows
a predictable naming structure.
For example, the following URL would also work:
```
https://github.com/hashicorp/go-getter.git//test-*
```
### Checksumming
For file downloads of any protocol, go-getter can automatically verify
a checksum for you. Note that checksumming only works for downloading files,
not directories, but checksumming will work for any protocol.
To checksum a file, append a `checksum` query parameter to the URL.
The paramter value should be in the format of `type:value`, where
type is "md5", "sha1", "sha256", or "sha512". The "value" should be
the actual checksum value. go-getter will parse out this query parameter
automatically and use it to verify the checksum. An example URL
is shown below:
```
./foo.txt?checksum=md5:b7d96c89d09d9e204f5fedc4d5d55b21
```
The checksum query parameter is never sent to the backend protocol
implementation. It is used at a higher level by go-getter itself.
### Unarchiving
go-getter will automatically unarchive files into a file or directory
based on the extension of the file being requested (over any protocol).
This works for both file and directory downloads.
go-getter looks for an `archive` query parameter to specify the format of
the archive. If this isn't specified, go-getter will use the extension of
the path to see if it appears archived. Unarchiving can be explicitly
disabled by setting the `archive` query parameter to `false`.
The following archive formats are supported:
* `tar.gz` and `tgz`
* `tar.bz2` and `tbz2`
* `tar.xz` and `txz`
* `zip`
* `gz`
* `bz2`
* `xz`
For example, an example URL is shown below:
```
./foo.zip
```
This will automatically be inferred to be a ZIP file and will be extracted.
You can also be explicit about the archive type:
```
./some/other/path?archive=zip
```
And finally, you can disable archiving completely:
```
./some/path?archive=false
```
You can combine unarchiving with the other features of go-getter such
as checksumming. The special `archive` query parameter will be removed
from the URL before going to the final protocol downloader.
## Protocol-Specific Options
This section documents the protocol-specific options that can be specified
for go-getter. These options should be appended to the input as normal query
parameters. Depending on the usage of go-getter, applications may provide
alternate ways of inputting options. For example, [Nomad](https://www.nomadproject.io)
provides a nice options block for specifying options rather than in the URL.
## General (All Protocols)
The options below are available to all protocols:
* `archive` - The archive format to use to unarchive this file, or "" (empty
string) to disable unarchiving. For more details, see the complete section
on archive support above.
* `checksum` - Checksum to verify the downloaded file or archive. See
the entire section on checksumming above for format and more details.
* `filename` - When in file download mode, allows specifying the name of the
downloaded file on disk. Has no effect in directory mode.
### Local Files (`file`)
None
### Git (`git`)
* `ref` - The Git ref to checkout. This is a ref, so it can point to
a commit SHA, a branch name, etc. If it is a named ref such as a branch
name, go-getter will update it to the latest on each get.
* `sshkey` - An SSH private key to use during clones. The provided key must
be a base64-encoded string. For example, to generate a suitable `sshkey`
from a private key file on disk, you would run `base64 -w0 <file>`.
**Note**: Git 2.3+ is required to use this feature.
### Mercurial (`hg`)
* `rev` - The Mercurial revision to checkout.
### HTTP (`http`)
#### Basic Authentication
To use HTTP basic authentication with go-getter, simply prepend `username:password@` to the
hostname in the URL such as `https://Aladdin:OpenSesame@www.example.com/index.html`. All special
characters, including the username and password, must be URL encoded.
### S3 (`s3`)
S3 takes various access configurations in the URL. Note that it will also
read these from standard AWS environment variables if they're set. S3 compliant servers like Minio
are also supported. If the query parameters are present, these take priority.
* `aws_access_key_id` - AWS access key.
* `aws_access_key_secret` - AWS access key secret.
* `aws_access_token` - AWS access token if this is being used.
#### Using IAM Instance Profiles with S3
If you use go-getter and want to use an EC2 IAM Instance Profile to avoid
using credentials, then just omit these and the profile, if available will
be used automatically.
### Using S3 with Minio
If you use go-gitter for Minio support, you must consider the following:
* `aws_access_key_id` (required) - Minio access key.
* `aws_access_key_secret` (required) - Minio access key secret.
* `region` (optional - defaults to us-east-1) - Region identifier to use.
* `version` (optional - defaults to Minio default) - Configuration file format.
#### S3 Bucket Examples
S3 has several addressing schemes used to reference your bucket. These are
listed here: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro
Some examples for these addressing schemes:
- s3::https://s3.amazonaws.com/bucket/foo
- s3::https://s3-eu-west-1.amazonaws.com/bucket/foo
- bucket.s3.amazonaws.com/foo
- bucket.s3-eu-west-1.amazonaws.com/foo/bar
- "s3::http://127.0.0.1:9000/test-bucket/hello.txt?aws_access_key_id=KEYID&aws_access_key_secret=SECRETKEY&region=us-east-2"

View File

@@ -1,16 +0,0 @@
version: "build-{branch}-{build}"
image: Visual Studio 2017
clone_folder: c:\gopath\github.com\hashicorp\go-getter
environment:
GOPATH: c:\gopath
install:
- cmd: >-
echo %Path%
go version
go env
go get -d -v -t ./...
build_script:
- cmd: go test -v ./...

View File

@@ -1,55 +0,0 @@
package main
import (
"flag"
"log"
"os"
"github.com/hashicorp/go-getter"
)
func main() {
modeRaw := flag.String("mode", "any", "get mode (any, file, dir)")
flag.Parse()
args := flag.Args()
if len(args) < 2 {
log.Fatalf("Expected two args: URL and dst")
os.Exit(1)
}
// Get the mode
var mode getter.ClientMode
switch *modeRaw {
case "any":
mode = getter.ClientModeAny
case "file":
mode = getter.ClientModeFile
case "dir":
mode = getter.ClientModeDir
default:
log.Fatalf("Invalid client mode, must be 'any', 'file', or 'dir': %s", *modeRaw)
os.Exit(1)
}
// Get the pwd
pwd, err := os.Getwd()
if err != nil {
log.Fatalf("Error getting wd: %s", err)
os.Exit(1)
}
// Build the client
client := &getter.Client{
Src: args[0],
Dst: args[1],
Pwd: pwd,
Mode: mode,
}
if err := client.Get(); err != nil {
log.Fatalf("Error downloading: %s", err)
os.Exit(1)
}
log.Println("Success!")
}

View File

@@ -1,34 +0,0 @@
package getter
import (
"path/filepath"
"testing"
)
func TestBzip2Decompressor(t *testing.T) {
cases := []TestDecompressCase{
{
"single.bz2",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
{
"single.bz2",
true,
true,
nil,
"",
nil,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-bz2", tc.Input)
}
TestDecompressor(t, new(Bzip2Decompressor), cases)
}

View File

@@ -1,34 +0,0 @@
package getter
import (
"path/filepath"
"testing"
)
func TestGzipDecompressor(t *testing.T) {
cases := []TestDecompressCase{
{
"single.gz",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
{
"single.gz",
true,
true,
nil,
"",
nil,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-gz", tc.Input)
}
TestDecompressor(t, new(GzipDecompressor), cases)
}

View File

@@ -1,43 +0,0 @@
package getter
import (
"path/filepath"
"testing"
"time"
)
func TestTar(t *testing.T) {
mtime := time.Unix(0, 0)
cases := []TestDecompressCase{
{
"extended_header.tar",
true,
false,
[]string{"directory/", "directory/a", "directory/b"},
"",
nil,
},
{
"implied_dir.tar",
true,
false,
[]string{"directory/", "directory/sub/", "directory/sub/a", "directory/sub/b"},
"",
nil,
},
{
"unix_time_0.tar",
true,
false,
[]string{"directory/", "directory/sub/", "directory/sub/a", "directory/sub/b"},
"",
&mtime,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-tar", tc.Input)
}
TestDecompressor(t, new(tarDecompressor), cases)
}

View File

@@ -1,73 +0,0 @@
package getter
import (
"path/filepath"
"testing"
)
func TestTarBzip2Decompressor(t *testing.T) {
orderingPaths := []string{"workers/", "workers/mq/", "workers/mq/__init__.py"}
cases := []TestDecompressCase{
{
"empty.tar.bz2",
false,
true,
nil,
"",
nil,
},
{
"single.tar.bz2",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
{
"single.tar.bz2",
true,
false,
[]string{"file"},
"",
nil,
},
{
"multiple.tar.bz2",
true,
false,
[]string{"file1", "file2"},
"",
nil,
},
{
"multiple.tar.bz2",
false,
true,
nil,
"",
nil,
},
// Tests when the file is listed before the parent folder
{
"ordering.tar.bz2",
true,
false,
orderingPaths,
"",
nil,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-tbz2", tc.Input)
}
TestDecompressor(t, new(TarBzip2Decompressor), cases)
}

View File

@@ -1,95 +0,0 @@
package getter
import (
"path/filepath"
"testing"
)
func TestTarGzipDecompressor(t *testing.T) {
multiplePaths := []string{"dir/", "dir/test2", "test1"}
orderingPaths := []string{"workers/", "workers/mq/", "workers/mq/__init__.py"}
cases := []TestDecompressCase{
{
"empty.tar.gz",
false,
true,
nil,
"",
nil,
},
{
"single.tar.gz",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
{
"single.tar.gz",
true,
false,
[]string{"file"},
"",
nil,
},
{
"multiple.tar.gz",
true,
false,
[]string{"file1", "file2"},
"",
nil,
},
{
"multiple.tar.gz",
false,
true,
nil,
"",
nil,
},
{
"multiple_dir.tar.gz",
true,
false,
multiplePaths,
"",
nil,
},
// Tests when the file is listed before the parent folder
{
"ordering.tar.gz",
true,
false,
orderingPaths,
"",
nil,
},
// Tests that a tar.gz can't contain references with "..".
// GNU `tar` also disallows this.
{
"outside_parent.tar.gz",
true,
true,
nil,
"",
nil,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-tgz", tc.Input)
}
TestDecompressor(t, new(TarGzipDecompressor), cases)
}

View File

@@ -1,84 +0,0 @@
package getter
import (
"path/filepath"
"testing"
)
func TestTarXzDecompressor(t *testing.T) {
multiplePaths := []string{"dir/", "dir/test2", "test1"}
orderingPaths := []string{"workers/", "workers/mq/", "workers/mq/__init__.py"}
cases := []TestDecompressCase{
{
"empty.tar.xz",
false,
true,
nil,
"",
nil,
},
{
"single.tar.xz",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
{
"single.tar.xz",
true,
false,
[]string{"file"},
"",
nil,
},
{
"multiple.tar.xz",
true,
false,
[]string{"file1", "file2"},
"",
nil,
},
{
"multiple.tar.xz",
false,
true,
nil,
"",
nil,
},
{
"multiple_dir.tar.xz",
true,
false,
multiplePaths,
"",
nil,
},
// Tests when the file is listed before the parent folder
{
"ordering.tar.xz",
true,
false,
orderingPaths,
"",
nil,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-txz", tc.Input)
}
TestDecompressor(t, new(TarXzDecompressor), cases)
}

View File

@@ -1,34 +0,0 @@
package getter
import (
"path/filepath"
"testing"
)
func TestXzDecompressor(t *testing.T) {
cases := []TestDecompressCase{
{
"single.xz",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
{
"single.xz",
true,
true,
nil,
"",
nil,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-xz", tc.Input)
}
TestDecompressor(t, new(XzDecompressor), cases)
}

View File

@@ -1,98 +0,0 @@
package getter
import (
"path/filepath"
"testing"
)
func TestZipDecompressor(t *testing.T) {
cases := []TestDecompressCase{
{
"empty.zip",
false,
true,
nil,
"",
nil,
},
{
"single.zip",
false,
false,
nil,
"d3b07384d113edec49eaa6238ad5ff00",
nil,
},
{
"single.zip",
true,
false,
[]string{"file"},
"",
nil,
},
{
"multiple.zip",
true,
false,
[]string{"file1", "file2"},
"",
nil,
},
{
"multiple.zip",
false,
true,
nil,
"",
nil,
},
{
"subdir.zip",
true,
false,
[]string{"file1", "subdir/", "subdir/child"},
"",
nil,
},
{
"subdir_empty.zip",
true,
false,
[]string{"file1", "subdir/"},
"",
nil,
},
{
"subdir_missing_dir.zip",
true,
false,
[]string{"file1", "subdir/", "subdir/child"},
"",
nil,
},
// Tests that a zip can't contain references with "..".
{
"outside_parent.zip",
true,
true,
nil,
"",
nil,
},
}
for i, tc := range cases {
cases[i].Input = filepath.Join("./test-fixtures", "decompress-zip", tc.Input)
}
TestDecompressor(t, new(ZipDecompressor), cases)
}

View File

@@ -1,67 +0,0 @@
package getter
import (
"net/http"
"strings"
"testing"
)
const testBBUrl = "https://bitbucket.org/hashicorp/tf-test-git"
func TestBitBucketDetector(t *testing.T) {
t.Parallel()
if _, err := http.Get(testBBUrl); err != nil {
t.Log("internet may not be working, skipping BB tests")
t.Skip()
}
cases := []struct {
Input string
Output string
}{
// HTTP
{
"bitbucket.org/hashicorp/tf-test-git",
"git::https://bitbucket.org/hashicorp/tf-test-git.git",
},
{
"bitbucket.org/hashicorp/tf-test-git.git",
"git::https://bitbucket.org/hashicorp/tf-test-git.git",
},
{
"bitbucket.org/hashicorp/tf-test-hg",
"hg::https://bitbucket.org/hashicorp/tf-test-hg",
},
}
pwd := "/pwd"
f := new(BitBucketDetector)
for i, tc := range cases {
var err error
for i := 0; i < 3; i++ {
var output string
var ok bool
output, ok, err = f.Detect(tc.Input, pwd)
if err != nil {
if strings.Contains(err.Error(), "invalid character") {
continue
}
t.Fatalf("err: %s", err)
}
if !ok {
t.Fatal("not ok")
}
if output != tc.Output {
t.Fatalf("%d: bad: %#v", i, output)
}
break
}
if i >= 3 {
t.Fatalf("failure from bitbucket: %s", err)
}
}
}

View File

@@ -1,118 +0,0 @@
package getter
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
)
type fileTest struct {
in, pwd, out string
err bool
}
var fileTests = []fileTest{
{"./foo", "/pwd", "file:///pwd/foo", false},
{"./foo?foo=bar", "/pwd", "file:///pwd/foo?foo=bar", false},
{"foo", "/pwd", "file:///pwd/foo", false},
}
var unixFileTests = []fileTest{
{"./foo", "test-fixtures/detect-file-symlink-pwd/syml/pwd",
"test-fixtures/detect-file-symlink-pwd/real/foo", false},
{"/foo", "/pwd", "file:///foo", false},
{"/foo?bar=baz", "/pwd", "file:///foo?bar=baz", false},
}
var winFileTests = []fileTest{
{"/foo", "/pwd", "file:///pwd/foo", false},
{`C:\`, `/pwd`, `file://C:/`, false},
{`C:\?bar=baz`, `/pwd`, `file://C:/?bar=baz`, false},
}
func TestFileDetector(t *testing.T) {
if runtime.GOOS == "windows" {
fileTests = append(fileTests, winFileTests...)
} else {
fileTests = append(fileTests, unixFileTests...)
}
// Get the pwd
pwdRoot, err := os.Getwd()
if err != nil {
t.Fatalf("err: %s", err)
}
pwdRoot, err = filepath.Abs(pwdRoot)
if err != nil {
t.Fatalf("err: %s", err)
}
f := new(FileDetector)
for i, tc := range fileTests {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
pwd := tc.pwd
if !filepath.IsAbs(pwd) {
pwd = filepath.Join(pwdRoot, pwd)
}
out, ok, err := f.Detect(tc.in, pwd)
if err != nil {
t.Fatalf("err: %s", err)
}
if !ok {
t.Fatal("not ok")
}
expected := tc.out
if !strings.HasPrefix(expected, "file://") {
expected = "file://" + filepath.Join(pwdRoot, expected)
}
if out != expected {
t.Fatalf("input: %q\npwd: %q\nexpected: %q\nbad output: %#v",
tc.in, pwd, expected, out)
}
})
}
}
var noPwdFileTests = []fileTest{
{in: "./foo", pwd: "", out: "", err: true},
{in: "foo", pwd: "", out: "", err: true},
}
var noPwdUnixFileTests = []fileTest{
{in: "/foo", pwd: "", out: "file:///foo", err: false},
}
var noPwdWinFileTests = []fileTest{
{in: "/foo", pwd: "", out: "", err: true},
{in: `C:\`, pwd: ``, out: `file://C:/`, err: false},
}
func TestFileDetector_noPwd(t *testing.T) {
if runtime.GOOS == "windows" {
noPwdFileTests = append(noPwdFileTests, noPwdWinFileTests...)
} else {
noPwdFileTests = append(noPwdFileTests, noPwdUnixFileTests...)
}
f := new(FileDetector)
for i, tc := range noPwdFileTests {
out, ok, err := f.Detect(tc.in, tc.pwd)
if err != nil != tc.err {
t.Fatalf("%d: err: %s", i, err)
}
if !ok {
t.Fatal("not ok")
}
if out != tc.out {
t.Fatalf("%d: bad: %#v", i, out)
}
}
}

View File

@@ -1,70 +0,0 @@
// +build test unix
package getter
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
// If a relative symlink is passed in as the pwd to Detect, the resulting URL
// can have an invalid path.
func TestFileDetector_relativeSymlink(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "go-getter")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
// We may have a symlinked tmp dir,
// e.g. OSX uses /var -> /private/var
tmpDir, err = filepath.EvalSymlinks(tmpDir)
if err != nil {
t.Fatal(err)
}
err = os.Mkdir(filepath.Join(tmpDir, "realPWD"), 0755)
if err != nil {
t.Fatal(err)
}
subdir := filepath.Join(tmpDir, "subdir")
err = os.Mkdir(subdir, 0755)
if err != nil {
t.Fatal(err)
}
prevDir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
defer os.Chdir(prevDir)
err = os.Chdir(subdir)
if err != nil {
t.Fatal(err)
}
err = os.Symlink("../realPWD", "linkedPWD")
if err != nil {
t.Fatal(err)
}
// if detech doesn't fully resolve the pwd symlink, the output will be the
// invalid path: "file:///../modules/foo"
f := new(FileDetector)
out, ok, err := f.Detect("../modules/foo", "./linkedPWD")
if err != nil {
t.Fatalf("err: %v", err)
}
if !ok {
t.Fatal("not ok")
}
if out != "file://"+filepath.Join(tmpDir, "modules/foo") {
t.Logf("expected: %v", "file://"+filepath.Join(tmpDir, "modules/foo"))
t.Fatalf("bad: %v", out)
}
}

View File

@@ -1,55 +0,0 @@
package getter
import (
"testing"
)
func TestGitHubDetector(t *testing.T) {
cases := []struct {
Input string
Output string
}{
// HTTP
{"github.com/hashicorp/foo", "git::https://github.com/hashicorp/foo.git"},
{"github.com/hashicorp/foo.git", "git::https://github.com/hashicorp/foo.git"},
{
"github.com/hashicorp/foo/bar",
"git::https://github.com/hashicorp/foo.git//bar",
},
{
"github.com/hashicorp/foo?foo=bar",
"git::https://github.com/hashicorp/foo.git?foo=bar",
},
{
"github.com/hashicorp/foo.git?foo=bar",
"git::https://github.com/hashicorp/foo.git?foo=bar",
},
// SSH
{"git@github.com:hashicorp/foo.git", "git::ssh://git@github.com/hashicorp/foo.git"},
{
"git@github.com:hashicorp/foo.git//bar",
"git::ssh://git@github.com/hashicorp/foo.git//bar",
},
{
"git@github.com:hashicorp/foo.git?foo=bar",
"git::ssh://git@github.com/hashicorp/foo.git?foo=bar",
},
}
pwd := "/pwd"
f := new(GitHubDetector)
for i, tc := range cases {
output, ok, err := f.Detect(tc.Input, pwd)
if err != nil {
t.Fatalf("err: %s", err)
}
if !ok {
t.Fatal("not ok")
}
if output != tc.Output {
t.Fatalf("%d: bad: %#v", i, output)
}
}
}

View File

@@ -1,84 +0,0 @@
package getter
import (
"testing"
)
func TestS3Detector(t *testing.T) {
cases := []struct {
Input string
Output string
}{
// Virtual hosted style
{
"bucket.s3.amazonaws.com/foo",
"s3::https://s3.amazonaws.com/bucket/foo",
},
{
"bucket.s3.amazonaws.com/foo/bar",
"s3::https://s3.amazonaws.com/bucket/foo/bar",
},
{
"bucket.s3.amazonaws.com/foo/bar.baz",
"s3::https://s3.amazonaws.com/bucket/foo/bar.baz",
},
{
"bucket.s3-eu-west-1.amazonaws.com/foo",
"s3::https://s3-eu-west-1.amazonaws.com/bucket/foo",
},
{
"bucket.s3-eu-west-1.amazonaws.com/foo/bar",
"s3::https://s3-eu-west-1.amazonaws.com/bucket/foo/bar",
},
{
"bucket.s3-eu-west-1.amazonaws.com/foo/bar.baz",
"s3::https://s3-eu-west-1.amazonaws.com/bucket/foo/bar.baz",
},
// Path style
{
"s3.amazonaws.com/bucket/foo",
"s3::https://s3.amazonaws.com/bucket/foo",
},
{
"s3.amazonaws.com/bucket/foo/bar",
"s3::https://s3.amazonaws.com/bucket/foo/bar",
},
{
"s3.amazonaws.com/bucket/foo/bar.baz",
"s3::https://s3.amazonaws.com/bucket/foo/bar.baz",
},
{
"s3-eu-west-1.amazonaws.com/bucket/foo",
"s3::https://s3-eu-west-1.amazonaws.com/bucket/foo",
},
{
"s3-eu-west-1.amazonaws.com/bucket/foo/bar",
"s3::https://s3-eu-west-1.amazonaws.com/bucket/foo/bar",
},
{
"s3-eu-west-1.amazonaws.com/bucket/foo/bar.baz",
"s3::https://s3-eu-west-1.amazonaws.com/bucket/foo/bar.baz",
},
// Misc tests
{
"s3-eu-west-1.amazonaws.com/bucket/foo/bar.baz?version=1234",
"s3::https://s3-eu-west-1.amazonaws.com/bucket/foo/bar.baz?version=1234",
},
}
pwd := "/pwd"
f := new(S3Detector)
for i, tc := range cases {
output, ok, err := f.Detect(tc.Input, pwd)
if err != nil {
t.Fatalf("err: %s", err)
}
if !ok {
t.Fatal("not ok")
}
if output != tc.Output {
t.Fatalf("%d: bad: %#v", i, output)
}
}
}

View File

@@ -1,57 +0,0 @@
package getter
import (
"testing"
)
func TestDetect(t *testing.T) {
cases := []struct {
Input string
Pwd string
Output string
Err bool
}{
{"./foo", "/foo", "file:///foo/foo", false},
{"git::./foo", "/foo", "git::file:///foo/foo", false},
{
"git::github.com/hashicorp/foo",
"",
"git::https://github.com/hashicorp/foo.git",
false,
},
{
"./foo//bar",
"/foo",
"file:///foo/foo//bar",
false,
},
{
"git::github.com/hashicorp/foo//bar",
"",
"git::https://github.com/hashicorp/foo.git//bar",
false,
},
{
"git::https://github.com/hashicorp/consul.git",
"",
"git::https://github.com/hashicorp/consul.git",
false,
},
{
"./foo/archive//*",
"/bar",
"file:///bar/foo/archive//*",
false,
},
}
for i, tc := range cases {
output, err := Detect(tc.Input, tc.Pwd, Detectors)
if err != nil != tc.Err {
t.Fatalf("%d: bad err: %s", i, err)
}
if output != tc.Output {
t.Fatalf("%d: bad output: %s\nexpected: %s", i, output, tc.Output)
}
}
}

View File

@@ -1,48 +0,0 @@
package getter
import (
"os"
"path/filepath"
"testing"
)
func TestFolderStorage_impl(t *testing.T) {
var _ Storage = new(FolderStorage)
}
func TestFolderStorage(t *testing.T) {
s := &FolderStorage{StorageDir: tempDir(t)}
module := testModule("basic")
// A module shouldn't exist at first...
_, ok, err := s.Dir(module)
if err != nil {
t.Fatalf("err: %s", err)
}
if ok {
t.Fatal("should not exist")
}
key := "foo"
// We can get it
err = s.Get(key, module, false)
if err != nil {
t.Fatalf("err: %s", err)
}
// Now the module exists
dir, ok, err := s.Dir(key)
if err != nil {
t.Fatalf("err: %s", err)
}
if !ok {
t.Fatal("should exist")
}
mainPath := filepath.Join(dir, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}

View File

@@ -1,202 +0,0 @@
package getter
import (
"os"
"path/filepath"
"testing"
)
func TestFileGetter_impl(t *testing.T) {
var _ Getter = new(FileGetter)
}
func TestFileGetter(t *testing.T) {
g := new(FileGetter)
dst := tempDir(t)
// With a dir that doesn't exist
if err := g.Get(dst, testModuleURL("basic")); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the destination folder is a symlink
fi, err := os.Lstat(dst)
if err != nil {
t.Fatalf("err: %s", err)
}
if fi.Mode()&os.ModeSymlink == 0 {
t.Fatal("destination is not a symlink")
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestFileGetter_sourceFile(t *testing.T) {
g := new(FileGetter)
dst := tempDir(t)
// With a source URL that is a path to a file
u := testModuleURL("basic")
u.Path += "/main.tf"
if err := g.Get(dst, u); err == nil {
t.Fatal("should error")
}
}
func TestFileGetter_sourceNoExist(t *testing.T) {
g := new(FileGetter)
dst := tempDir(t)
// With a source URL that doesn't exist
u := testModuleURL("basic")
u.Path += "/main"
if err := g.Get(dst, u); err == nil {
t.Fatal("should error")
}
}
func TestFileGetter_dir(t *testing.T) {
g := new(FileGetter)
dst := tempDir(t)
if err := os.MkdirAll(dst, 0755); err != nil {
t.Fatalf("err: %s", err)
}
// With a dir that exists that isn't a symlink
if err := g.Get(dst, testModuleURL("basic")); err == nil {
t.Fatal("should error")
}
}
func TestFileGetter_dirSymlink(t *testing.T) {
g := new(FileGetter)
dst := tempDir(t)
dst2 := tempDir(t)
// Make parents
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
t.Fatalf("err: %s", err)
}
if err := os.MkdirAll(dst2, 0755); err != nil {
t.Fatalf("err: %s", err)
}
// Make a symlink
if err := os.Symlink(dst2, dst); err != nil {
t.Fatalf("err: %s", err)
}
// With a dir that exists that isn't a symlink
if err := g.Get(dst, testModuleURL("basic")); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestFileGetter_GetFile(t *testing.T) {
g := new(FileGetter)
dst := tempFile(t)
// With a dir that doesn't exist
if err := g.GetFile(dst, testModuleURL("basic-file/foo.txt")); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the destination folder is a symlink
fi, err := os.Lstat(dst)
if err != nil {
t.Fatalf("err: %s", err)
}
if fi.Mode()&os.ModeSymlink == 0 {
t.Fatal("destination is not a symlink")
}
// Verify the main file exists
assertContents(t, dst, "Hello\n")
}
func TestFileGetter_GetFile_Copy(t *testing.T) {
g := new(FileGetter)
g.Copy = true
dst := tempFile(t)
// With a dir that doesn't exist
if err := g.GetFile(dst, testModuleURL("basic-file/foo.txt")); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the destination folder is a symlink
fi, err := os.Lstat(dst)
if err != nil {
t.Fatalf("err: %s", err)
}
if fi.Mode()&os.ModeSymlink != 0 {
t.Fatal("destination is a symlink")
}
// Verify the main file exists
assertContents(t, dst, "Hello\n")
}
// https://github.com/hashicorp/terraform/issues/8418
func TestFileGetter_percent2F(t *testing.T) {
g := new(FileGetter)
dst := tempDir(t)
// With a dir that doesn't exist
if err := g.Get(dst, testModuleURL("basic%2Ftest")); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestFileGetter_ClientMode_notexist(t *testing.T) {
g := new(FileGetter)
u := testURL("nonexistent")
if _, err := g.ClientMode(u); err == nil {
t.Fatal("expect source file error")
}
}
func TestFileGetter_ClientMode_file(t *testing.T) {
g := new(FileGetter)
// Check the client mode when pointed at a file.
mode, err := g.ClientMode(testModuleURL("basic-file/foo.txt"))
if err != nil {
t.Fatalf("err: %s", err)
}
if mode != ClientModeFile {
t.Fatal("expect ClientModeFile")
}
}
func TestFileGetter_ClientMode_dir(t *testing.T) {
g := new(FileGetter)
// Check the client mode when pointed at a directory.
mode, err := g.ClientMode(testModuleURL("basic"))
if err != nil {
t.Fatalf("err: %s", err)
}
if mode != ClientModeDir {
t.Fatal("expect ClientModeDir")
}
}

View File

@@ -1,425 +0,0 @@
package getter
import (
"encoding/base64"
"io/ioutil"
"net/url"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
var testHasGit bool
func init() {
if _, err := exec.LookPath("git"); err == nil {
testHasGit = true
}
}
func TestGitGetter_impl(t *testing.T) {
var _ Getter = new(GitGetter)
}
func TestGitGetter(t *testing.T) {
if !testHasGit {
t.Log("git not found, skipping")
t.Skip()
}
g := new(GitGetter)
dst := tempDir(t)
repo := testGitRepo(t, "basic")
repo.commitFile("foo.txt", "hello")
// With a dir that doesn't exist
if err := g.Get(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "foo.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGitGetter_branch(t *testing.T) {
if !testHasGit {
t.Log("git not found, skipping")
t.Skip()
}
g := new(GitGetter)
dst := tempDir(t)
repo := testGitRepo(t, "branch")
repo.git("checkout", "-b", "test-branch")
repo.commitFile("branch.txt", "branch")
q := repo.url.Query()
q.Add("ref", "test-branch")
repo.url.RawQuery = q.Encode()
if err := g.Get(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "branch.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
// Get again should work
if err := g.Get(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath = filepath.Join(dst, "branch.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGitGetter_branchUpdate(t *testing.T) {
if !testHasGit {
t.Log("git not found, skipping")
t.Skip()
}
g := new(GitGetter)
dst := tempDir(t)
// First setup the state with a fresh branch
repo := testGitRepo(t, "branch-update")
repo.git("checkout", "-b", "test-branch")
repo.commitFile("branch.txt", "branch")
// Get the "test-branch" branch
q := repo.url.Query()
q.Add("ref", "test-branch")
repo.url.RawQuery = q.Encode()
if err := g.Get(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "branch.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
// Commit an update to the branch
repo.commitFile("branch-update.txt", "branch-update")
// Get again should work
if err := g.Get(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath = filepath.Join(dst, "branch-update.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGitGetter_tag(t *testing.T) {
if !testHasGit {
t.Log("git not found, skipping")
t.Skip()
}
g := new(GitGetter)
dst := tempDir(t)
repo := testGitRepo(t, "tag")
repo.commitFile("tag.txt", "tag")
repo.git("tag", "v1.0")
q := repo.url.Query()
q.Add("ref", "v1.0")
repo.url.RawQuery = q.Encode()
if err := g.Get(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "tag.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
// Get again should work
if err := g.Get(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath = filepath.Join(dst, "tag.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGitGetter_GetFile(t *testing.T) {
if !testHasGit {
t.Log("git not found, skipping")
t.Skip()
}
g := new(GitGetter)
dst := tempFile(t)
repo := testGitRepo(t, "file")
repo.commitFile("file.txt", "hello")
// Download the file
repo.url.Path = filepath.Join(repo.url.Path, "file.txt")
if err := g.GetFile(dst, repo.url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
if _, err := os.Stat(dst); err != nil {
t.Fatalf("err: %s", err)
}
assertContents(t, dst, "hello")
}
func TestGitGetter_gitVersion(t *testing.T) {
dir, err := ioutil.TempDir("", "go-getter")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
script := filepath.Join(dir, "git")
err = ioutil.WriteFile(
script,
[]byte("#!/bin/sh\necho \"git version 2.0 (Some Metadata Here)\n\""),
0700)
if err != nil {
t.Fatal(err)
}
defer func(v string) {
os.Setenv("PATH", v)
}(os.Getenv("PATH"))
os.Setenv("PATH", dir)
// Asking for a higher version throws an error
if err := checkGitVersion("2.3"); err == nil {
t.Fatal("expect git version error")
}
// Passes when version is satisfied
if err := checkGitVersion("1.9"); err != nil {
t.Fatal(err)
}
}
func TestGitGetter_sshKey(t *testing.T) {
if !testHasGit {
t.Log("git not found, skipping")
t.Skip()
}
g := new(GitGetter)
dst := tempDir(t)
encodedKey := base64.StdEncoding.EncodeToString([]byte(testGitToken))
u, err := url.Parse("ssh://git@github.com/hashicorp/test-private-repo" +
"?sshkey=" + encodedKey)
if err != nil {
t.Fatal(err)
}
if err := g.Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
readmePath := filepath.Join(dst, "README.md")
if _, err := os.Stat(readmePath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGitGetter_submodule(t *testing.T) {
if !testHasGit {
t.Log("git not found, skipping")
t.Skip()
}
g := new(GitGetter)
dst := tempDir(t)
// Set up the grandchild
gc := testGitRepo(t, "grandchild")
gc.commitFile("grandchild.txt", "grandchild")
// Set up the child
c := testGitRepo(t, "child")
c.commitFile("child.txt", "child")
c.git("submodule", "add", gc.dir)
c.git("commit", "-m", "Add grandchild submodule")
// Set up the parent
p := testGitRepo(t, "parent")
p.commitFile("parent.txt", "parent")
p.git("submodule", "add", c.dir)
p.git("commit", "-m", "Add child submodule")
// Clone the root repository
if err := g.Get(dst, p.url); err != nil {
t.Fatalf("err: %s", err)
}
// Check that the files exist
for _, path := range []string{
filepath.Join(dst, "parent.txt"),
filepath.Join(dst, "child", "child.txt"),
filepath.Join(dst, "child", "grandchild", "grandchild.txt"),
} {
if _, err := os.Stat(path); err != nil {
t.Fatalf("err: %s", err)
}
}
}
func TestGitGetter_setupGitEnv_sshKey(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skipf("skipping on windows since the test requires sh")
return
}
cmd := exec.Command("/bin/sh", "-c", "echo $GIT_SSH_COMMAND")
setupGitEnv(cmd, "/tmp/foo.pem")
out, err := cmd.Output()
if err != nil {
t.Fatal(err)
}
actual := strings.TrimSpace(string(out))
if actual != "ssh -i /tmp/foo.pem" {
t.Fatalf("unexpected GIT_SSH_COMMAND: %q", actual)
}
}
func TestGitGetter_setupGitEnvWithExisting_sshKey(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skipf("skipping on windows since the test requires sh")
return
}
// start with an existing ssh command configuration
os.Setenv("GIT_SSH_COMMAND", "ssh -o StrictHostKeyChecking=no")
defer os.Setenv("GIT_SSH_COMMAND", "")
cmd := exec.Command("/bin/sh", "-c", "echo $GIT_SSH_COMMAND")
setupGitEnv(cmd, "/tmp/foo.pem")
out, err := cmd.Output()
if err != nil {
t.Fatal(err)
}
actual := strings.TrimSpace(string(out))
if actual != "ssh -o StrictHostKeyChecking=no -i /tmp/foo.pem" {
t.Fatalf("unexpected GIT_SSH_COMMAND: %q", actual)
}
}
// gitRepo is a helper struct which controls a single temp git repo.
type gitRepo struct {
t *testing.T
url *url.URL
dir string
}
// testGitRepo creates a new test git repository.
func testGitRepo(t *testing.T, name string) *gitRepo {
dir, err := ioutil.TempDir("", "go-getter")
if err != nil {
t.Fatal(err)
}
dir = filepath.Join(dir, name)
if err := os.Mkdir(dir, 0700); err != nil {
t.Fatal(err)
}
r := &gitRepo{
t: t,
dir: dir,
}
url, err := url.Parse("file://" + r.dir)
if err != nil {
t.Fatal(err)
}
r.url = url
r.git("init")
r.git("config", "user.name", "go-getter")
r.git("config", "user.email", "go-getter@hashicorp.com")
return r
}
// git runs a git command against the repo.
func (r *gitRepo) git(args ...string) {
cmd := exec.Command("git", args...)
cmd.Dir = r.dir
if err := cmd.Run(); err != nil {
r.t.Fatal(err)
}
}
// commitFile writes and commits a text file to the repo.
func (r *gitRepo) commitFile(file, content string) {
path := filepath.Join(r.dir, file)
if err := ioutil.WriteFile(path, []byte(content), 0600); err != nil {
r.t.Fatal(err)
}
r.git("add", file)
r.git("commit", "-m", "Adding "+file)
}
// This is a read-only deploy key for an empty test repository.
// Note: This is split over multiple lines to avoid being disabled by key
// scanners automatically.
var testGitToken = `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA9cHsxCl3Jjgu9DHpwvmfFOl1XEdY+ShHDR/cMnzJ5ddk5/oV
Wy6EWatvyHZfRSZMwzv4PtKeUPm6iXjqWp4xdWU9khlPzozyj+U9Fq70TRVUW9E5
T1XdQVwJE421yffr4VMMwu60wBqjI1epapH2i2inYvw9Zl9X2MXq0+jTvFvDerbT
mDtfStDPljenELAIZtWVETSvbI46gALwbxbM2292ZUIL4D6jRz0aZMmyy/twYv8r
9WGJLwmYzU518Ie7zqKW/mCTdTrV0WRiDj0MeRaPgrGY9amuHE4r9iG/cJkwpKAO
Ccz0Hs6i89u9vZnTqZU9V7weJqRAQcMjXXR6yQIDAQABAoIBAQDBzICKnGxiTlHw
rd+6qqChnAy5jWYDbZjCJ8q8YZ3RS08+g/8NXZxvHftTqM0uOaq1FviHig3gq15H
hHvCpBc6jXDFYoKFzq6FfO/0kFkE5HoWweIgxwRow0xBCDJAJ+ryUEyy+Ay/pQHb
IAjwilRS0V+WdnVw4mTjBAhPvb4jPOo97Yfy3PYUyx2F3newkqXOZy+zx3G/ANoa
ncypfMGyy76sfCWKqw4J1gVkVQLwbB6gQkXUFGYwY9sRrxbG93kQw76Flc/E/s52
62j4v1IM0fq0t/St+Y/+s6Lkw` + `aqt3ft1nsqWcRaVDdqvMfkzgJGXlw0bGzJG5MEQ
AIBq3dHRAoGBAP8OeG/DKG2Z1VmSfzuz1pas1fbZ+F7venOBrjez3sKlb3Pyl2aH
mt2wjaTUi5v10VrHgYtOEdqyhQeUSYydWXIBKNMag0NLLrfFUKZK+57wrHWFdFjn
VgpsdkLSNTOZpC8gA5OaJ+36IcOPfGqyyP9wuuRoaYnVT1KEzqLa9FEFAoGBAPaq
pglwhil2rxjJE4zq0afQLNpAfi7Xqcrepij+xvJIcIj7nawxXuPxqRFxONE/h3yX
zkybO8wLdbHX9Iw/wc1j50Uf1Z5gHdLf7/hQJoWKpz1RnkWRy6CYON8v1tpVp0tb
OAajR/kZnzebq2mfa7pyy5zDCX++2kp/dcFwHf31AoGAE8oupBVTZLWj7TBFuP8q
LkS40U92Sv9v09iDCQVmylmFvUxcXPM2m+7f/qMTNgWrucxzC7kB/6MMWVszHbrz
vrnCTibnemgx9sZTjKOSxHFOIEw7i85fSa3Cu0qOIDPSnmlwfZpfcMKQrhjLAYhf
uhooFiLX1X78iZ2OXup4PHUCgYEAsmBrm83sp1V1gAYBBlnVbXakyNv0pCk/Vz61
iFXeRt1NzDGxLxGw3kQnED8BaIh5kQcyn8Fud7sdzJMv/LAqlT4Ww60mzNYTGyjo
H3jOsqm3ESfRvduWFreeAQBWbiOczGjV1i8D4EbAFfWT+tjXjchwKBf+6Yt5zn/o
Bw/uEHUCgYAFs+JPOR25oRyBs7ujrMo/OY1z/eXTVVgZxY+tYGe1FJqDeFyR7ytK
+JBB1MuDwQKGm2wSIXdCzTNoIx2B9zTseiPTwT8G7vqNFhXoIaTBp4P2xIQb45mJ
7GkTsMBHwpSMOXgX9Weq3v5xOJ2WxVtjENmd6qzxcYCO5lP15O17hA==
-----END RSA PRIVATE KEY-----`

View File

@@ -1,98 +0,0 @@
package getter
import (
"os"
"os/exec"
"path/filepath"
"testing"
)
var testHasHg bool
func init() {
if _, err := exec.LookPath("hg"); err == nil {
testHasHg = true
}
}
func TestHgGetter_impl(t *testing.T) {
var _ Getter = new(HgGetter)
}
func TestHgGetter(t *testing.T) {
if !testHasHg {
t.Log("hg not found, skipping")
t.Skip()
}
g := new(HgGetter)
dst := tempDir(t)
// With a dir that doesn't exist
if err := g.Get(dst, testModuleURL("basic-hg")); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestHgGetter_branch(t *testing.T) {
if !testHasHg {
t.Log("hg not found, skipping")
t.Skip()
}
g := new(HgGetter)
dst := tempDir(t)
url := testModuleURL("basic-hg")
q := url.Query()
q.Add("rev", "test-branch")
url.RawQuery = q.Encode()
if err := g.Get(dst, url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main_branch.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
// Get again should work
if err := g.Get(dst, url); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath = filepath.Join(dst, "main_branch.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestHgGetter_GetFile(t *testing.T) {
if !testHasHg {
t.Log("hg not found, skipping")
t.Skip()
}
g := new(HgGetter)
dst := tempFile(t)
// Download
if err := g.GetFile(dst, testModuleURL("basic-hg/foo.txt")); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
if _, err := os.Stat(dst); err != nil {
t.Fatalf("err: %s", err)
}
assertContents(t, dst, "Hello\n")
}

View File

@@ -1,331 +0,0 @@
package getter
import (
"errors"
"fmt"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"testing"
)
func TestHttpGetter_impl(t *testing.T) {
var _ Getter = new(HttpGetter)
}
func TestHttpGetter_header(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/header"
// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestHttpGetter_meta(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/meta"
// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestHttpGetter_metaSubdir(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/meta-subdir"
// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "sub.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestHttpGetter_metaSubdirGlob(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/meta-subdir-glob"
// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "sub.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestHttpGetter_none(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/none"
// Get it!
if err := g.Get(dst, &u); err == nil {
t.Fatal("should error")
}
}
func TestHttpGetter_file(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempFile(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/file"
// Get it!
if err := g.GetFile(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
if _, err := os.Stat(dst); err != nil {
t.Fatalf("err: %s", err)
}
assertContents(t, dst, "Hello\n")
}
func TestHttpGetter_auth(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/meta-auth"
u.User = url.UserPassword("foo", "bar")
// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestHttpGetter_authNetrc(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/meta"
// Write the netrc file
path, closer := tempFileContents(t, fmt.Sprintf(testHttpNetrc, ln.Addr().String()))
defer closer()
defer tempEnv(t, "NETRC", path)()
// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
// test round tripper that only returns an error
type errRoundTripper struct{}
func (errRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
return nil, errors.New("test round tripper")
}
// verify that the default httpClient no longer comes from http.DefaultClient
func TestHttpGetter_cleanhttp(t *testing.T) {
ln := testHttpServer(t)
defer ln.Close()
// break the default http client
http.DefaultClient.Transport = errRoundTripper{}
defer func() {
http.DefaultClient.Transport = http.DefaultTransport
}()
g := new(HttpGetter)
dst := tempDir(t)
defer os.RemoveAll(dst)
var u url.URL
u.Scheme = "http"
u.Host = ln.Addr().String()
u.Path = "/header"
// Get it!
if err := g.Get(dst, &u); err != nil {
t.Fatalf("err: %s", err)
}
}
func testHttpServer(t *testing.T) net.Listener {
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("err: %s", err)
}
mux := http.NewServeMux()
mux.HandleFunc("/file", testHttpHandlerFile)
mux.HandleFunc("/header", testHttpHandlerHeader)
mux.HandleFunc("/meta", testHttpHandlerMeta)
mux.HandleFunc("/meta-auth", testHttpHandlerMetaAuth)
mux.HandleFunc("/meta-subdir", testHttpHandlerMetaSubdir)
mux.HandleFunc("/meta-subdir-glob", testHttpHandlerMetaSubdirGlob)
var server http.Server
server.Handler = mux
go server.Serve(ln)
return ln
}
func testHttpHandlerFile(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello\n"))
}
func testHttpHandlerHeader(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-Terraform-Get", testModuleURL("basic").String())
w.WriteHeader(200)
}
func testHttpHandlerMeta(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf(testHttpMetaStr, testModuleURL("basic").String())))
}
func testHttpHandlerMetaAuth(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok {
w.WriteHeader(401)
return
}
if user != "foo" || pass != "bar" {
w.WriteHeader(401)
return
}
w.Write([]byte(fmt.Sprintf(testHttpMetaStr, testModuleURL("basic").String())))
}
func testHttpHandlerMetaSubdir(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf(testHttpMetaStr, testModuleURL("basic//subdir").String())))
}
func testHttpHandlerMetaSubdirGlob(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf(testHttpMetaStr, testModuleURL("basic//sub*").String())))
}
func testHttpHandlerNone(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(testHttpNoneStr))
}
const testHttpMetaStr = `
<html>
<head>
<meta name="terraform-get" content="%s">
</head>
</html>
`
const testHttpNoneStr = `
<html>
<head>
</head>
</html>
`
const testHttpNetrc = `
machine %s
login foo
password bar
`

View File

@@ -1,250 +0,0 @@
package getter
import (
"net/url"
"os"
"path/filepath"
"testing"
"github.com/aws/aws-sdk-go/aws/awserr"
)
func init() {
// These are well known restricted IAM keys to a HashiCorp-managed bucket
// in a private AWS account that only has access to the open source test
// resources.
//
// We do the string concat below to avoid AWS autodetection of a key. This
// key is locked down an IAM policy that is read-only so we're purposely
// exposing it.
os.Setenv("AWS_ACCESS_KEY", "AKIAITTDR"+"WY2STXOZE2A")
os.Setenv("AWS_SECRET_KEY", "oMwSyqdass2kPF"+"/7ORZA9dlb/iegz+89B0Cy01Ea")
}
func TestS3Getter_impl(t *testing.T) {
var _ Getter = new(S3Getter)
}
func TestS3Getter(t *testing.T) {
g := new(S3Getter)
dst := tempDir(t)
// With a dir that doesn't exist
err := g.Get(
dst, testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/folder"))
if err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestS3Getter_subdir(t *testing.T) {
g := new(S3Getter)
dst := tempDir(t)
// With a dir that doesn't exist
err := g.Get(
dst, testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/folder/subfolder"))
if err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
subPath := filepath.Join(dst, "sub.tf")
if _, err := os.Stat(subPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestS3Getter_GetFile(t *testing.T) {
g := new(S3Getter)
dst := tempFile(t)
// Download
err := g.GetFile(
dst, testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/folder/main.tf"))
if err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
if _, err := os.Stat(dst); err != nil {
t.Fatalf("err: %s", err)
}
assertContents(t, dst, "# Main\n")
}
func TestS3Getter_GetFile_badParams(t *testing.T) {
g := new(S3Getter)
dst := tempFile(t)
// Download
err := g.GetFile(
dst,
testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/folder/main.tf?aws_access_key_id=foo&aws_access_key_secret=bar&aws_access_token=baz"))
if err == nil {
t.Fatalf("expected error, got none")
}
if reqerr, ok := err.(awserr.RequestFailure); !ok || reqerr.StatusCode() != 403 {
t.Fatalf("expected InvalidAccessKeyId error")
}
}
func TestS3Getter_GetFile_notfound(t *testing.T) {
g := new(S3Getter)
dst := tempFile(t)
// Download
err := g.GetFile(
dst, testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/folder/404.tf"))
if err == nil {
t.Fatalf("expected error, got none")
}
}
func TestS3Getter_ClientMode_dir(t *testing.T) {
g := new(S3Getter)
// Check client mode on a key prefix with only a single key.
mode, err := g.ClientMode(
testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/folder"))
if err != nil {
t.Fatalf("err: %s", err)
}
if mode != ClientModeDir {
t.Fatal("expect ClientModeDir")
}
}
func TestS3Getter_ClientMode_file(t *testing.T) {
g := new(S3Getter)
// Check client mode on a key prefix which contains sub-keys.
mode, err := g.ClientMode(
testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/folder/main.tf"))
if err != nil {
t.Fatalf("err: %s", err)
}
if mode != ClientModeFile {
t.Fatal("expect ClientModeFile")
}
}
func TestS3Getter_ClientMode_notfound(t *testing.T) {
g := new(S3Getter)
// Check the client mode when a non-existent key is looked up. This does not
// return an error, but rather should just return the file mode so that S3
// can return an appropriate error later on. This also checks that the
// prefix is handled properly (e.g., "/fold" and "/folder" don't put the
// client mode into "dir".
mode, err := g.ClientMode(
testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/fold"))
if err != nil {
t.Fatalf("err: %s", err)
}
if mode != ClientModeFile {
t.Fatal("expect ClientModeFile")
}
}
func TestS3Getter_ClientMode_collision(t *testing.T) {
g := new(S3Getter)
// Check that the client mode is "file" if there is both an object and a
// folder with a common prefix (i.e., a "collision" in the namespace).
mode, err := g.ClientMode(
testURL("https://s3.amazonaws.com/hc-oss-test/go-getter/collision/foo"))
if err != nil {
t.Fatalf("err: %s", err)
}
if mode != ClientModeFile {
t.Fatal("expect ClientModeFile")
}
}
func TestS3Getter_Url(t *testing.T) {
var s3tests = []struct {
name string
url string
region string
bucket string
path string
version string
}{
{
name: "AWSv1234",
url: "s3::https://s3-eu-west-1.amazonaws.com/bucket/foo/bar.baz?version=1234",
region: "eu-west-1",
bucket: "bucket",
path: "foo/bar.baz",
version: "1234",
},
{
name: "localhost-1",
url: "s3::http://127.0.0.1:9000/test-bucket/hello.txt?aws_access_key_id=TESTID&aws_access_key_secret=TestSecret&region=us-east-2&version=1",
region: "us-east-2",
bucket: "test-bucket",
path: "hello.txt",
version: "1",
},
{
name: "localhost-2",
url: "s3::http://127.0.0.1:9000/test-bucket/hello.txt?aws_access_key_id=TESTID&aws_access_key_secret=TestSecret&version=1",
region: "us-east-1",
bucket: "test-bucket",
path: "hello.txt",
version: "1",
},
{
name: "localhost-3",
url: "s3::http://127.0.0.1:9000/test-bucket/hello.txt?aws_access_key_id=TESTID&aws_access_key_secret=TestSecret",
region: "us-east-1",
bucket: "test-bucket",
path: "hello.txt",
version: "",
},
}
for i, pt := range s3tests {
t.Run(pt.name, func(t *testing.T) {
g := new(S3Getter)
forced, src := getForcedGetter(pt.url)
u, err := url.Parse(src)
if err != nil {
t.Errorf("test %d: unexpected error: %s", i, err)
}
if forced != "s3" {
t.Fatalf("expected forced protocol to be s3")
}
region, bucket, path, version, creds, err := g.parseUrl(u)
if err != nil {
t.Fatalf("err: %s", err)
}
if region != pt.region {
t.Fatalf("expected %s, got %s", pt.region, region)
}
if bucket != pt.bucket {
t.Fatalf("expected %s, got %s", pt.bucket, bucket)
}
if path != pt.path {
t.Fatalf("expected %s, got %s", pt.path, path)
}
if version != pt.version {
t.Fatalf("expected %s, got %s", pt.version, version)
}
if &creds == nil {
t.Fatalf("expected to not be nil")
}
})
}
}

View File

@@ -1,380 +0,0 @@
package getter
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestGet_badSchema(t *testing.T) {
dst := tempDir(t)
u := testModule("basic")
u = strings.Replace(u, "file", "nope", -1)
if err := Get(dst, u); err == nil {
t.Fatal("should error")
}
}
func TestGet_file(t *testing.T) {
dst := tempDir(t)
u := testModule("basic")
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
// https://github.com/hashicorp/terraform/issues/11438
func TestGet_fileDecompressorExt(t *testing.T) {
dst := tempDir(t)
u := testModule("basic-tgz")
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
// https://github.com/hashicorp/terraform/issues/8418
func TestGet_filePercent2F(t *testing.T) {
dst := tempDir(t)
u := testModule("basic%2Ftest")
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGet_fileDetect(t *testing.T) {
dst := tempDir(t)
u := filepath.Join("./test-fixtures", "basic")
pwd, err := os.Getwd()
if err != nil {
t.Fatalf("err: %s", err)
}
client := &Client{
Src: u,
Dst: dst,
Pwd: pwd,
Dir: true,
}
if err := client.Get(); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGet_fileForced(t *testing.T) {
dst := tempDir(t)
u := testModule("basic")
u = "file::" + u
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGet_fileSubdir(t *testing.T) {
dst := tempDir(t)
u := testModule("basic//subdir")
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "sub.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGet_archive(t *testing.T) {
dst := tempDir(t)
u := filepath.Join("./test-fixtures", "archive.tar.gz")
u, _ = filepath.Abs(u)
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGetAny_archive(t *testing.T) {
dst := tempDir(t)
u := filepath.Join("./test-fixtures", "archive.tar.gz")
u, _ = filepath.Abs(u)
if err := GetAny(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "main.tf")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGet_archiveRooted(t *testing.T) {
dst := tempDir(t)
u := testModule("archive-rooted/archive.tar.gz")
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "root", "hello.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGet_archiveSubdirWild(t *testing.T) {
dst := tempDir(t)
u := testModule("archive-rooted/archive.tar.gz")
u += "//*"
if err := Get(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "hello.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGet_archiveSubdirWildMultiMatch(t *testing.T) {
dst := tempDir(t)
u := testModule("archive-rooted-multi/archive.tar.gz")
u += "//*"
if err := Get(dst, u); err == nil {
t.Fatal("should error")
} else if !strings.Contains(err.Error(), "multiple") {
t.Fatalf("err: %s", err)
}
}
func TestGetAny_file(t *testing.T) {
dst := tempDir(t)
u := testModule("basic-file/foo.txt")
if err := GetAny(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "foo.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestGetAny_dir(t *testing.T) {
dst := tempDir(t)
u := filepath.Join("./test-fixtures", "basic")
u, _ = filepath.Abs(u)
if err := GetAny(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
check := []string{
"main.tf",
"foo/main.tf",
}
for _, name := range check {
mainPath := filepath.Join(dst, name)
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}
}
func TestGetFile(t *testing.T) {
dst := tempFile(t)
u := testModule("basic-file/foo.txt")
if err := GetFile(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
assertContents(t, dst, "Hello\n")
}
func TestGetFile_archive(t *testing.T) {
dst := tempFile(t)
u := testModule("basic-file-archive/archive.tar.gz")
if err := GetFile(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
assertContents(t, dst, "Hello\n")
}
func TestGetFile_archiveChecksum(t *testing.T) {
dst := tempFile(t)
u := testModule(
"basic-file-archive/archive.tar.gz?checksum=md5:fbd90037dacc4b1ab40811d610dde2f0")
if err := GetFile(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
assertContents(t, dst, "Hello\n")
}
func TestGetFile_archiveNoUnarchive(t *testing.T) {
dst := tempFile(t)
u := testModule("basic-file-archive/archive.tar.gz")
u += "?archive=false"
if err := GetFile(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
// Verify the main file exists
actual := testMD5(t, dst)
expected := "fbd90037dacc4b1ab40811d610dde2f0"
if actual != expected {
t.Fatalf("bad: %s", actual)
}
}
func TestGetFile_checksum(t *testing.T) {
cases := []struct {
Append string
Err bool
}{
{
"",
false,
},
// MD5
{
"?checksum=md5:09f7e02f1290be211da707a266f153b3",
false,
},
{
"?checksum=md5:09f7e02f1290be211da707a266f153b4",
true,
},
// SHA1
{
"?checksum=sha1:1d229271928d3f9e2bb0375bd6ce5db6c6d348d9",
false,
},
{
"?checksum=sha1:1d229271928d3f9e2bb0375bd6ce5db6c6d348d0",
true,
},
// SHA256
{
"?checksum=sha256:66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18",
false,
},
{
"?checksum=sha256:66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f19",
true,
},
// SHA512
{
"?checksum=sha512:c2bad2223811194582af4d1508ac02cd69eeeeedeeb98d54fcae4dcefb13cc882e7640328206603d3fb9cd5f949a9be0db054dd34fbfa190c498a5fe09750cef",
false,
},
{
"?checksum=sha512:c2bad2223811194582af4d1508ac02cd69eeeeedeeb98d54fcae4dcefb13cc882e7640328206603d3fb9cd5f949a9be0db054dd34fbfa190c498a5fe09750ced",
true,
},
}
for _, tc := range cases {
u := testModule("basic-file/foo.txt") + tc.Append
func() {
dst := tempFile(t)
defer os.Remove(dst)
if err := GetFile(dst, u); (err != nil) != tc.Err {
t.Fatalf("append: %s\n\nerr: %s", tc.Append, err)
}
// Verify the main file exists
assertContents(t, dst, "Hello\n")
}()
}
}
func TestGetFile_checksumURL(t *testing.T) {
dst := tempFile(t)
u := testModule("basic-file/foo.txt") + "?checksum=md5:09f7e02f1290be211da707a266f153b3"
getter := &MockGetter{Proxy: new(FileGetter)}
client := &Client{
Src: u,
Dst: dst,
Dir: false,
Getters: map[string]Getter{
"file": getter,
},
}
if err := client.Get(); err != nil {
t.Fatalf("err: %s", err)
}
if v := getter.GetFileURL.Query().Get("checksum"); v != "" {
t.Fatalf("bad: %s", v)
}
}
func TestGetFile_filename(t *testing.T) {
dst := tempDir(t)
u := testModule("basic-file/foo.txt")
u += "?filename=bar.txt"
if err := GetAny(dst, u); err != nil {
t.Fatalf("err: %s", err)
}
mainPath := filepath.Join(dst, "bar.txt")
if _, err := os.Stat(mainPath); err != nil {
t.Fatalf("err: %s", err)
}
}

View File

@@ -1,88 +0,0 @@
package url
import (
"runtime"
"testing"
)
type parseTest struct {
rawURL string
scheme string
host string
path string
str string
err bool
}
var parseTests = []parseTest{
{
rawURL: "/foo/bar",
scheme: "",
host: "",
path: "/foo/bar",
str: "/foo/bar",
err: false,
},
{
rawURL: "file:///dir/",
scheme: "file",
host: "",
path: "/dir/",
str: "file:///dir/",
err: false,
},
}
var winParseTests = []parseTest{
{
rawURL: `C:\`,
scheme: ``,
host: ``,
path: `C:/`,
str: `C:/`,
err: false,
},
{
rawURL: `file://C:\`,
scheme: `file`,
host: ``,
path: `C:/`,
str: `file://C:/`,
err: false,
},
{
rawURL: `file:///C:\`,
scheme: `file`,
host: ``,
path: `C:/`,
str: `file://C:/`,
err: false,
},
}
func TestParse(t *testing.T) {
if runtime.GOOS == "windows" {
parseTests = append(parseTests, winParseTests...)
}
for i, pt := range parseTests {
url, err := Parse(pt.rawURL)
if err != nil && !pt.err {
t.Errorf("test %d: unexpected error: %s", i, err)
}
if err == nil && pt.err {
t.Errorf("test %d: expected an error", i)
}
if url.Scheme != pt.scheme {
t.Errorf("test %d: expected Scheme = %q, got %q", i, pt.scheme, url.Scheme)
}
if url.Host != pt.host {
t.Errorf("test %d: expected Host = %q, got %q", i, pt.host, url.Host)
}
if url.Path != pt.path {
t.Errorf("test %d: expected Path = %q, got %q", i, pt.path, url.Path)
}
if url.String() != pt.str {
t.Errorf("test %d: expected url.String() = %q, got %q", i, pt.str, url.String())
}
}
}

View File

@@ -1,78 +0,0 @@
package getter
import (
"io/ioutil"
"net/url"
"os"
"path/filepath"
"reflect"
"testing"
urlhelper "github.com/hashicorp/go-getter/helper/url"
)
const fixtureDir = "./test-fixtures"
func tempDir(t *testing.T) string {
dir, err := ioutil.TempDir("", "tf")
if err != nil {
t.Fatalf("err: %s", err)
}
if err := os.RemoveAll(dir); err != nil {
t.Fatalf("err: %s", err)
}
return dir
}
func tempFile(t *testing.T) string {
dir := tempDir(t)
return filepath.Join(dir, "foo")
}
func testModule(n string) string {
p := filepath.Join(fixtureDir, n)
p, err := filepath.Abs(p)
if err != nil {
panic(err)
}
return fmtFileURL(p)
}
func testModuleURL(n string) *url.URL {
n, subDir := SourceDirSubdir(n)
u, err := urlhelper.Parse(testModule(n))
if err != nil {
panic(err)
}
if subDir != "" {
u.Path += "//" + subDir
u.RawPath = u.Path
}
return u
}
func testURL(s string) *url.URL {
u, err := urlhelper.Parse(s)
if err != nil {
panic(err)
}
return u
}
func testStorage(t *testing.T) Storage {
return &FolderStorage{StorageDir: tempDir(t)}
}
func assertContents(t *testing.T, path string, contents string) {
data, err := ioutil.ReadFile(path)
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(data, []byte(contents)) {
t.Fatalf("bad. expected:\n\n%s\n\nGot:\n\n%s", contents, string(data))
}
}

View File

@@ -1,63 +0,0 @@
package getter
import (
"net/url"
"testing"
)
func TestAddAuthFromNetrc(t *testing.T) {
defer tempEnv(t, "NETRC", "./test-fixtures/netrc/basic")()
u, err := url.Parse("http://example.com")
if err != nil {
t.Fatalf("err: %s", err)
}
if err := addAuthFromNetrc(u); err != nil {
t.Fatalf("err: %s", err)
}
expected := "http://foo:bar@example.com"
actual := u.String()
if expected != actual {
t.Fatalf("Mismatch: %q != %q", actual, expected)
}
}
func TestAddAuthFromNetrc_hasAuth(t *testing.T) {
defer tempEnv(t, "NETRC", "./test-fixtures/netrc/basic")()
u, err := url.Parse("http://username:password@example.com")
if err != nil {
t.Fatalf("err: %s", err)
}
expected := u.String()
if err := addAuthFromNetrc(u); err != nil {
t.Fatalf("err: %s", err)
}
actual := u.String()
if expected != actual {
t.Fatalf("Mismatch: %q != %q", actual, expected)
}
}
func TestAddAuthFromNetrc_hasUsername(t *testing.T) {
defer tempEnv(t, "NETRC", "./test-fixtures/netrc/basic")()
u, err := url.Parse("http://username@example.com")
if err != nil {
t.Fatalf("err: %s", err)
}
expected := u.String()
if err := addAuthFromNetrc(u); err != nil {
t.Fatalf("err: %s", err)
}
actual := u.String()
if expected != actual {
t.Fatalf("Mismatch: %q != %q", actual, expected)
}
}

View File

@@ -1,98 +0,0 @@
package getter
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestSourceDirSubdir(t *testing.T) {
cases := []struct {
Input string
Dir, Sub string
}{
{
"hashicorp.com",
"hashicorp.com", "",
},
{
"hashicorp.com//foo",
"hashicorp.com", "foo",
},
{
"hashicorp.com//foo?bar=baz",
"hashicorp.com?bar=baz", "foo",
},
{
"https://hashicorp.com/path//*?archive=foo",
"https://hashicorp.com/path?archive=foo", "*",
},
{
"file://foo//bar",
"file://foo", "bar",
},
}
for i, tc := range cases {
adir, asub := SourceDirSubdir(tc.Input)
if adir != tc.Dir {
t.Fatalf("%d: bad dir: %#v", i, adir)
}
if asub != tc.Sub {
t.Fatalf("%d: bad sub: %#v", i, asub)
}
}
}
func TestSourceSubdirGlob(t *testing.T) {
td, err := ioutil.TempDir("", "subdir-glob")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(td)
if err := os.Mkdir(filepath.Join(td, "subdir"), 0755); err != nil {
t.Fatal(err)
}
if err := os.Mkdir(filepath.Join(td, "subdir/one"), 0755); err != nil {
t.Fatal(err)
}
if err := os.Mkdir(filepath.Join(td, "subdir/two"), 0755); err != nil {
t.Fatal(err)
}
subdir := filepath.Join(td, "subdir")
// match the exact directory
res, err := SubdirGlob(td, "subdir")
if err != nil {
t.Fatal(err)
}
if res != subdir {
t.Fatalf(`expected "subdir", got: %q`, subdir)
}
// single match from a wildcard
res, err = SubdirGlob(td, "*")
if err != nil {
t.Fatal(err)
}
if res != subdir {
t.Fatalf(`expected "subdir", got: %q`, subdir)
}
// multiple matches
res, err = SubdirGlob(td, "subdir/*")
if err == nil {
t.Fatalf("expected multiple matches, got %q", res)
}
// non-existent
res, err = SubdirGlob(td, "foo")
if err == nil {
t.Fatalf("expected no matches, got %q", res)
}
}

View File

@@ -1 +0,0 @@
# Hello

View File

@@ -1,5 +0,0 @@
# Hello
module "foo" {
source = "./foo"
}

View File

@@ -1,5 +0,0 @@
# Hello
module "foo" {
source = "./foo"
}

View File

@@ -1 +0,0 @@
Hello

View File

@@ -1 +0,0 @@
default

View File

@@ -1,3 +0,0 @@
992604507bcd66370bf91a0c9d526ccd833412bf 2
992604507bcd66370bf91a0c9d526ccd833412bf o default
c65e998d747ffbb1fe3b1c067a50664bb3fb5da4 o test-branch

View File

@@ -1 +0,0 @@
checklink-target

View File

@@ -1 +0,0 @@
default

View File

@@ -1,2 +0,0 @@
1 c65e998d747ffbb1fe3b1c067a50664bb3fb5da4

View File

@@ -1 +0,0 @@
2 992604507bcd66370bf91a0c9d526ccd833412bf

View File

@@ -1,2 +0,0 @@
add file

View File

@@ -1,4 +0,0 @@
dotencode
fncache
revlogv1
store

View File

@@ -1,3 +0,0 @@
data/main.tf.i
data/foo.txt.i
data/main_branch.tf.i

View File

@@ -1 +0,0 @@
1 dcaed7754d58264cb9a5916215a5442377307bd1

View File

@@ -1,2 +0,0 @@
data/main.tf.i
data/main_branch.tf.i

View File

@@ -1 +0,0 @@
1 dcaed7754d58264cb9a5916215a5442377307bd1

View File

@@ -1 +0,0 @@
default

View File

@@ -1,2 +0,0 @@
2
commit

View File

@@ -1 +0,0 @@
Hello

View File

@@ -1,5 +0,0 @@
# Hello
module "foo" {
source = "./foo"
}

View File

@@ -1,3 +0,0 @@
module "b" {
source = "../c"
}

View File

@@ -1 +0,0 @@
# Hello

View File

@@ -1,3 +0,0 @@
module "a" {
source = "./a"
}

View File

@@ -1,3 +0,0 @@
module "bar" {
source = "./baz"
}

View File

@@ -1,3 +0,0 @@
module "foo" {
source = "./foo//sub"
}

View File

@@ -1 +0,0 @@
# Hello

View File

@@ -1 +0,0 @@
# Hello

View File

@@ -1,5 +0,0 @@
# Hello
module "foo" {
source = "./foo"
}

View File

@@ -1,2 +0,0 @@
# Hello

View File

@@ -1,5 +0,0 @@
# Hello
module "bar" {
source = "./bar"
}

View File

@@ -1,5 +0,0 @@
# Hello
module "foo" {
source = "./foo"
}

Some files were not shown because too many files have changed in this diff Show More