github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/client/getter/getter_test.go (about)

     1  package getter
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"path/filepath"
    10  	"reflect"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/hashicorp/nomad/client/driver/env"
    15  	"github.com/hashicorp/nomad/nomad/mock"
    16  	"github.com/hashicorp/nomad/nomad/structs"
    17  )
    18  
    19  func TestGetArtifact_FileAndChecksum(t *testing.T) {
    20  	// Create the test server hosting the file to download
    21  	ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
    22  	defer ts.Close()
    23  
    24  	// Create a temp directory to download into
    25  	taskDir, err := ioutil.TempDir("", "nomad-test")
    26  	if err != nil {
    27  		t.Fatalf("failed to make temp directory: %v", err)
    28  	}
    29  	defer os.RemoveAll(taskDir)
    30  
    31  	// Create the artifact
    32  	file := "test.sh"
    33  	artifact := &structs.TaskArtifact{
    34  		GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
    35  		GetterOptions: map[string]string{
    36  			"checksum": "md5:bce963762aa2dbfed13caf492a45fb72",
    37  		},
    38  	}
    39  
    40  	// Download the artifact
    41  	taskEnv := env.NewTaskEnvironment(mock.Node(), false)
    42  	if err := GetArtifact(taskEnv, artifact, taskDir); err != nil {
    43  		t.Fatalf("GetArtifact failed: %v", err)
    44  	}
    45  
    46  	// Verify artifact exists
    47  	if _, err := os.Stat(filepath.Join(taskDir, file)); err != nil {
    48  		t.Fatalf("file not found: %s", err)
    49  	}
    50  }
    51  
    52  func TestGetArtifact_File_RelativeDest(t *testing.T) {
    53  	// Create the test server hosting the file to download
    54  	ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
    55  	defer ts.Close()
    56  
    57  	// Create a temp directory to download into
    58  	taskDir, err := ioutil.TempDir("", "nomad-test")
    59  	if err != nil {
    60  		t.Fatalf("failed to make temp directory: %v", err)
    61  	}
    62  	defer os.RemoveAll(taskDir)
    63  
    64  	// Create the artifact
    65  	file := "test.sh"
    66  	relative := "foo/"
    67  	artifact := &structs.TaskArtifact{
    68  		GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
    69  		GetterOptions: map[string]string{
    70  			"checksum": "md5:bce963762aa2dbfed13caf492a45fb72",
    71  		},
    72  		RelativeDest: relative,
    73  	}
    74  
    75  	// Download the artifact
    76  	taskEnv := env.NewTaskEnvironment(mock.Node(), false)
    77  	if err := GetArtifact(taskEnv, artifact, taskDir); err != nil {
    78  		t.Fatalf("GetArtifact failed: %v", err)
    79  	}
    80  
    81  	// Verify artifact was downloaded to the correct path
    82  	if _, err := os.Stat(filepath.Join(taskDir, relative, file)); err != nil {
    83  		t.Fatalf("file not found: %s", err)
    84  	}
    85  }
    86  
    87  func TestGetGetterUrl_Interprolation(t *testing.T) {
    88  	// Create the artifact
    89  	artifact := &structs.TaskArtifact{
    90  		GetterSource: "${NOMAD_META_ARTIFACT}",
    91  	}
    92  
    93  	url := "foo.com"
    94  	taskEnv := env.NewTaskEnvironment(mock.Node(), false).SetTaskMeta(map[string]string{"artifact": url})
    95  	act, err := getGetterUrl(taskEnv, artifact)
    96  	if err != nil {
    97  		t.Fatalf("getGetterUrl() failed: %v", err)
    98  	}
    99  
   100  	if act != url {
   101  		t.Fatalf("getGetterUrl() returned %q; want %q", act, url)
   102  	}
   103  }
   104  
   105  func TestGetArtifact_InvalidChecksum(t *testing.T) {
   106  	// Create the test server hosting the file to download
   107  	ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
   108  	defer ts.Close()
   109  
   110  	// Create a temp directory to download into
   111  	taskDir, err := ioutil.TempDir("", "nomad-test")
   112  	if err != nil {
   113  		t.Fatalf("failed to make temp directory: %v", err)
   114  	}
   115  	defer os.RemoveAll(taskDir)
   116  
   117  	// Create the artifact with an incorrect checksum
   118  	file := "test.sh"
   119  	artifact := &structs.TaskArtifact{
   120  		GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
   121  		GetterOptions: map[string]string{
   122  			"checksum": "md5:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
   123  		},
   124  	}
   125  
   126  	// Download the artifact and expect an error
   127  	taskEnv := env.NewTaskEnvironment(mock.Node(), false)
   128  	if err := GetArtifact(taskEnv, artifact, taskDir); err == nil {
   129  		t.Fatalf("GetArtifact should have failed")
   130  	}
   131  }
   132  
   133  func createContents(basedir string, fileContents map[string]string, t *testing.T) {
   134  	for relPath, content := range fileContents {
   135  		folder := basedir
   136  		if strings.Index(relPath, "/") != -1 {
   137  			// Create the folder.
   138  			folder = filepath.Join(basedir, filepath.Dir(relPath))
   139  			if err := os.Mkdir(folder, 0777); err != nil {
   140  				t.Fatalf("failed to make directory: %v", err)
   141  			}
   142  		}
   143  
   144  		// Create a file in the existing folder.
   145  		file := filepath.Join(folder, filepath.Base(relPath))
   146  		if err := ioutil.WriteFile(file, []byte(content), 0777); err != nil {
   147  			t.Fatalf("failed to write data to file %v: %v", file, err)
   148  		}
   149  	}
   150  }
   151  
   152  func checkContents(basedir string, fileContents map[string]string, t *testing.T) {
   153  	for relPath, content := range fileContents {
   154  		path := filepath.Join(basedir, relPath)
   155  		actual, err := ioutil.ReadFile(path)
   156  		if err != nil {
   157  			t.Fatalf("failed to read file %q: %v", path, err)
   158  		}
   159  
   160  		if !reflect.DeepEqual(actual, []byte(content)) {
   161  			t.Fatalf("%q: expected %q; got %q", path, content, string(actual))
   162  		}
   163  	}
   164  }
   165  
   166  func TestGetArtifact_Archive(t *testing.T) {
   167  	// Create the test server hosting the file to download
   168  	ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("./test-fixtures/"))))
   169  	defer ts.Close()
   170  
   171  	// Create a temp directory to download into and create some of the same
   172  	// files that exist in the artifact to ensure they are overridden
   173  	taskDir, err := ioutil.TempDir("", "nomad-test")
   174  	if err != nil {
   175  		t.Fatalf("failed to make temp directory: %v", err)
   176  	}
   177  	defer os.RemoveAll(taskDir)
   178  
   179  	create := map[string]string{
   180  		"exist/my.config": "to be replaced",
   181  		"untouched":       "existing top-level",
   182  	}
   183  	createContents(taskDir, create, t)
   184  
   185  	file := "archive.tar.gz"
   186  	artifact := &structs.TaskArtifact{
   187  		GetterSource: fmt.Sprintf("%s/%s", ts.URL, file),
   188  		GetterOptions: map[string]string{
   189  			"checksum": "sha1:20bab73c72c56490856f913cf594bad9a4d730f6",
   190  		},
   191  	}
   192  
   193  	taskEnv := env.NewTaskEnvironment(mock.Node(), false)
   194  	if err := GetArtifact(taskEnv, artifact, taskDir); err != nil {
   195  		t.Fatalf("GetArtifact failed: %v", err)
   196  	}
   197  
   198  	// Verify the unarchiving overrode files properly.
   199  	expected := map[string]string{
   200  		"untouched":       "existing top-level",
   201  		"exist/my.config": "hello world\n",
   202  		"new/my.config":   "hello world\n",
   203  		"test.sh":         "sleep 1\n",
   204  	}
   205  	checkContents(taskDir, expected, t)
   206  }