Skip to content

Commit

Permalink
Feedback improvements to main and test file
Browse files Browse the repository at this point in the history
  • Loading branch information
BartoszBlizniak committed Nov 24, 2023
1 parent 2257b92 commit cd15bcb
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 20 deletions.
110 changes: 92 additions & 18 deletions cloudsmith/data_source_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,23 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"path"
"strconv"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

type Checksums struct {
MD5 string
SHA1 string
SHA256 string
SHA512 string
}

func dataSourcePackageRead(d *schema.ResourceData, m interface{}) error {
pc := m.(*providerConfig)
namespace := requiredString(d, "namespace")
Expand Down Expand Up @@ -50,23 +60,71 @@ func dataSourcePackageRead(d *schema.ResourceData, m interface{}) error {
d.SetId(fmt.Sprintf("%s_%s_%s", namespace, repository, pkg.GetSlugPerm()))

if download {
outputPath, err := downloadPackage(pkg.GetCdnUrl(), downloadDir, pc)
outputPath, err := downloadPackage(pkg.GetCdnUrl(), downloadDir, pc, false)
if err != nil {
return err
}
d.Set("output_path", outputPath)
d.Set("output_directory", downloadDir)

// Calculate checksums for the downloaded file
md5Checksum, sha1Checksum, sha256Checksum, sha512Checksum, err := calculateChecksums(outputPath)
localChecksums, err := calculateChecksums(outputPath)
if err != nil {
return err
}

d.Set("checksum_md5", md5Checksum)
d.Set("checksum_sha1", sha1Checksum)
d.Set("checksum_sha256", sha256Checksum)
d.Set("checksum_sha512", sha512Checksum)
localMD5 := localChecksums.MD5
localSHA1 := localChecksums.SHA1
localSHA256 := localChecksums.SHA256
localSHA512 := localChecksums.SHA512

// Check against API checksums
if localMD5 != pkg.GetChecksumMd5() || localSHA1 != pkg.GetChecksumSha1() || localSHA256 != pkg.GetChecksumSha256() || localSHA512 != pkg.GetChecksumSha512() {
// Checksum doesn't match, try to download again with isCached set to true
outputPath, err := downloadPackage(pkg.GetCdnUrl(), downloadDir, pc, true)
if err != nil {
return err
}

// Calculate checksums for the downloaded file again
localChecksums, err := calculateChecksums(outputPath)
if err != nil {
return err
}

localMD5 = localChecksums.MD5
localSHA1 = localChecksums.SHA1
localSHA256 = localChecksums.SHA256
localSHA512 = localChecksums.SHA512

// Check again after the retry
if localMD5 != pkg.GetChecksumMd5() || localSHA1 != pkg.GetChecksumSha1() || localSHA256 != pkg.GetChecksumSha256() || localSHA512 != pkg.GetChecksumSha512() {
// Checksum still doesn't match, set the flag, and provide a warning
d.Set("download_checksum_mismatch", true)

// Set the content for each checksum to "Checksum mismatch: Local File: <Checksum> , Remote File: <Checksum_from_api>"
mismatchMessageMD5 := fmt.Sprintf("Checksum mismatch: Local File: %s, Remote File: %s", localMD5, pkg.GetChecksumMd5())
d.Set("checksum_md5", mismatchMessageMD5)
fmt.Println("Warning:", mismatchMessageMD5)

mismatchMessageSHA1 := fmt.Sprintf("Checksum mismatch: Local File: %s, Remote File: %s", localSHA1, pkg.GetChecksumSha1())
d.Set("checksum_sha1", mismatchMessageSHA1)
fmt.Println("Warning:", mismatchMessageSHA1)

mismatchMessageSHA256 := fmt.Sprintf("Checksum mismatch: Local File: %s, Remote File: %s", localSHA256, pkg.GetChecksumSha256())
d.Set("checksum_sha256", mismatchMessageSHA256)
fmt.Println("Warning:", mismatchMessageSHA256)

mismatchMessageSHA512 := fmt.Sprintf("Checksum mismatch: Local File: %s, Remote File: %s", localSHA512, pkg.GetChecksumSha512())
d.Set("checksum_sha512", mismatchMessageSHA512)
fmt.Println("Warning:", mismatchMessageSHA512)
}
}

d.Set("checksum_md5", localMD5)
d.Set("checksum_sha1", localSHA1)
d.Set("checksum_sha256", localSHA256)
d.Set("checksum_sha512", localSHA512)
} else {
d.Set("output_path", pkg.GetCdnUrl())
d.Set("output_directory", "")
Expand All @@ -75,27 +133,41 @@ func dataSourcePackageRead(d *schema.ResourceData, m interface{}) error {
return nil
}

func downloadPackage(url string, downloadDir string, pc *providerConfig) (string, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
func downloadPackage(urlStr string, downloadDir string, pc *providerConfig, isCached bool) (string, error) {
req, err := http.NewRequest(http.MethodGet, urlStr, nil)
if err != nil {
return "", err
}

req.Header.Add("Authorization", fmt.Sprintf("Token %s", pc.GetAPIKey()))

client := pc.APIClient.GetConfig().HTTPClient
if isCached {
timestamp := time.Now().Unix()
parsedURL, err := url.Parse(urlStr)
if err != nil {
return "", err
}

queryValues := parsedURL.Query()
queryValues.Set("time", strconv.FormatInt(timestamp, 10))
parsedURL.RawQuery = queryValues.Encode()

req.URL = parsedURL
}

resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("failed to download file: %s, status code: %d", url, resp.StatusCode)
return "", fmt.Errorf("failed to download file: %s, status code: %d", urlStr, resp.StatusCode)
}

// Extract filename from CDN URL
filename := path.Base(url)
filename := path.Base(urlStr)
outputPath := path.Join(downloadDir, filename)

outputFile, err := os.Create(outputPath)
Expand All @@ -112,10 +184,12 @@ func downloadPackage(url string, downloadDir string, pc *providerConfig) (string
return outputPath, nil
}

func calculateChecksums(filePath string) (string, string, string, string, error) {
func calculateChecksums(filePath string) (Checksums, error) {
var checksums Checksums

file, err := os.Open(filePath)
if err != nil {
return "", "", "", "", err
return checksums, err
}
defer file.Close()

Expand All @@ -125,15 +199,15 @@ func calculateChecksums(filePath string) (string, string, string, string, error)
sha512hash := sha512.New()

if _, err := io.Copy(io.MultiWriter(md5hash, sha1hash, sha256hash, sha512hash), file); err != nil {
return "", "", "", "", err
return checksums, err
}

md5Checksum := hex.EncodeToString(md5hash.Sum(nil))
sha1Checksum := hex.EncodeToString(sha1hash.Sum(nil))
sha256Checksum := hex.EncodeToString(sha256hash.Sum(nil))
sha512Checksum := hex.EncodeToString(sha512hash.Sum(nil))
checksums.MD5 = hex.EncodeToString(md5hash.Sum(nil))
checksums.SHA1 = hex.EncodeToString(sha1hash.Sum(nil))
checksums.SHA256 = hex.EncodeToString(sha256hash.Sum(nil))
checksums.SHA512 = hex.EncodeToString(sha512hash.Sum(nil))

return md5Checksum, sha1Checksum, sha256Checksum, sha512Checksum, nil
return checksums, nil
}

func dataSourcePackage() *schema.Resource {
Expand Down
72 changes: 70 additions & 2 deletions cloudsmith/data_source_package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestAccPackage_data(t *testing.T) {
resource.TestCheckResourceAttr("cloudsmith_repository.test", "name", dsPackageTestRepository),
// Custom TestCheckFunc to upload the package and wait for sync after repository creation
func(s *terraform.State) error {
return uploadPackage(testAccProvider.Meta().(*providerConfig))
return uploadPackage(testAccProvider.Meta().(*providerConfig), false)
},
),
},
Expand All @@ -58,16 +58,59 @@ func TestAccPackage_data(t *testing.T) {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return fmt.Errorf("file does not exist at path: %s", filePath)
}
expectedContent := "Hello world"
if err := checkFileContent(filePath, expectedContent); err != nil {
return fmt.Errorf("file content check failed: %w", err)
}
return nil
},
),
},
{
Config: testAccPackageDataReadPackageDownloadRepublish(dsPackageTestNamespace, dsPackageTestRepository),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.cloudsmith_package.test", "namespace", dsPackageTestNamespace),
resource.TestCheckResourceAttr("data.cloudsmith_package.test", "repository", dsPackageTestRepository),
func(s *terraform.State) error {
return uploadPackage(testAccProvider.Meta().(*providerConfig), true)
},
func(s *terraform.State) error {
filePath := filepath.Join("/Users/bblizniak/Desktop/terrafor_test/2", "hello.txt")
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return fmt.Errorf("file does not exist at path: %s", filePath)
}

expectedContent := "Hello world updated content"
if err := checkFileContent(filePath, expectedContent); err != nil {
return fmt.Errorf("file content check failed: %w", err)
}

return nil
},
),
},
},
})
}
func checkFileContent(filePath string, expectedContent string) error {
content, err := os.ReadFile(filePath)
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
}

func uploadPackage(pc *providerConfig) error {
if string(content) != expectedContent {
return fmt.Errorf("file content does not match expected. Got: %s, Expected: %s", content, expectedContent)
}

return nil
}

func uploadPackage(pc *providerConfig, republish bool) error {
fileContent := []byte("Hello world")
if republish {
updatedContent := []byte(" updated content")
fileContent = append(fileContent, updatedContent...)
}

initPayload := cloudsmith.PackageFileUploadRequest{
Filename: "hello.txt",
Expand Down Expand Up @@ -154,6 +197,7 @@ func testAccPackageDataSetup(namespace, repository string) string {
resource "cloudsmith_repository" "test" {
name = "%s"
namespace = "%s"
replace_packages_by_default = true
}
`, repository, namespace)
}
Expand All @@ -163,6 +207,7 @@ func testAccPackageDataReadPackage(namespace, repository string) string {
resource "cloudsmith_repository" "test" {
name = "%s"
namespace = "%s"
replace_packages_by_default = true
}
data "cloudsmith_package_list" "test" {
Expand All @@ -183,6 +228,29 @@ func testAccPackageDataReadPackageDownload(namespace, repository string) string
resource "cloudsmith_repository" "test" {
name = "%s"
namespace = "%s"
replace_packages_by_default = true
}
data "cloudsmith_package_list" "test" {
repository = "%s"
namespace = "%s"
}
data "cloudsmith_package" "test" {
repository = "%s"
namespace = "%s"
identifier = data.cloudsmith_package_list.test.packages[0].slug_perm
download = true
}
`, repository, namespace, repository, namespace, repository, namespace)
}

func testAccPackageDataReadPackageDownloadRepublish(namespace, repository string) string {
return fmt.Sprintf(`
resource "cloudsmith_repository" "test" {
name = "%s"
namespace = "%s"
replace_packages_by_default = true
}
data "cloudsmith_package_list" "test" {
Expand Down

0 comments on commit cd15bcb

Please sign in to comment.