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