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 }