Files
bootstrap_dev_env/net_test.go
2026-05-26 09:36:05 -05:00

239 lines
6.3 KiB
Go

package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"testing"
)
type mockTripper struct {
roundTripFunc func(req *http.Request) (*http.Response, error)
}
func (m *mockTripper) RoundTrip(req *http.Request) (*http.Response, error) {
return m.roundTripFunc(req)
}
func TestDownloadReal(t *testing.T) {
defer resetMocks()
// Mock HTTP client
oldTransport := httpClient.Transport
defer func() { httpClient.Transport = oldTransport }()
httpClient.Transport = &mockTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
if req.URL.String() == "https://example.com/file" {
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString("hello download")),
}, nil
}
return &http.Response{
StatusCode: 404,
Body: io.NopCloser(bytes.NewBufferString("not found")),
}, nil
},
}
tmpDir := t.TempDir()
destFile := filepath.Join(tmpDir, "out.txt")
// Successful download
success := downloadReal("https://example.com/file", destFile)
if !success {
t.Fatal("expected download to succeed")
}
data, err := os.ReadFile(destFile)
if err != nil {
t.Fatalf("failed to read downloaded file: %v", err)
}
if string(data) != "hello download" {
t.Errorf("expected 'hello download', got %q", string(data))
}
// Failed download (404)
failDest := filepath.Join(tmpDir, "out_fail.txt")
successFail := downloadReal("https://example.com/nonexistent", failDest)
if successFail {
t.Error("expected download to fail with 404")
}
}
func TestFetchJSONReal(t *testing.T) {
defer resetMocks()
oldTransport := httpClient.Transport
defer func() { httpClient.Transport = oldTransport }()
httpClient.Transport = &mockTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
if req.URL.String() == "https://example.com/api" {
// Verify auth header if token is set
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString(`{"key": "value"}`)),
}, nil
}
return &http.Response{
StatusCode: 500,
Body: io.NopCloser(bytes.NewBufferString("internal error")),
}, nil
},
}
type MockResponse struct {
Key string `json:"key"`
}
var res MockResponse
success := fetchJSONReal("https://example.com/api", &res)
if !success {
t.Fatal("expected fetchJSON to succeed")
}
if res.Key != "value" {
t.Errorf("expected Key to be 'value', got %q", res.Key)
}
successFail := fetchJSONReal("https://example.com/bad", &res)
if successFail {
t.Error("expected fetchJSON to fail with 500")
}
}
func TestFetchTextReal(t *testing.T) {
defer resetMocks()
oldTransport := httpClient.Transport
defer func() { httpClient.Transport = oldTransport }()
httpClient.Transport = &mockTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
if req.URL.String() == "https://example.com/text" {
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString(" Adoptium Latest \n")),
}, nil
}
return &http.Response{
StatusCode: 403,
Body: io.NopCloser(bytes.NewBufferString("forbidden")),
}, nil
},
}
text := fetchTextReal("https://example.com/text")
if text != "Adoptium Latest" {
t.Errorf("expected trimmed text 'Adoptium Latest', got %q", text)
}
textFail := fetchTextReal("https://example.com/forbidden")
if textFail != "" {
t.Errorf("expected empty string for failed request, got %q", textFail)
}
}
func TestSha256Of(t *testing.T) {
tmpDir := t.TempDir()
path := filepath.Join(tmpDir, "hash.txt")
if err := os.WriteFile(path, []byte("hello sha256"), 0644); err != nil {
t.Fatal(err)
}
// Hex of sha256("hello sha256") is 433855b7d2b96c23a6f60e70c655eb4305e8806b682a9596a200642f947259b1
expected := "433855b7d2b96c23a6f60e70c655eb4305e8806b682a9596a200642f947259b1"
actual, err := sha256Of(path)
if err != nil {
t.Fatalf("failed to calculate hash: %v", err)
}
if actual != expected {
t.Errorf("expected %s, got %s", expected, actual)
}
// Nonexistent file
_, errNonexistent := sha256Of(filepath.Join(tmpDir, "nonexistent"))
if errNonexistent == nil {
t.Error("expected error for nonexistent file")
}
}
func TestNetRealErrors(t *testing.T) {
defer resetMocks()
oldTransport := httpClient.Transport
defer func() { httpClient.Transport = oldTransport }()
// 1. NewRequest error
if downloadReal("%%%", "dest") {
t.Error("expected downloadReal to fail for invalid URL")
}
if fetchJSONReal("%%%", nil) {
t.Error("expected fetchJSONReal to fail for invalid URL")
}
if fetchTextReal("%%%") != "" {
t.Error("expected fetchTextReal to fail for invalid URL")
}
// 2. Transport Do error
httpClient.Transport = &mockTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
return nil, fmt.Errorf("connection refused")
},
}
if downloadReal("https://example.com/file", "dest") {
t.Error("expected downloadReal to fail on connection error")
}
if fetchJSONReal("https://example.com/api", nil) {
t.Error("expected fetchJSONReal to fail on connection error")
}
if fetchTextReal("https://example.com/text") != "" {
t.Error("expected fetchTextReal to fail on connection error")
}
// 3. os.Create error
httpClient.Transport = &mockTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString("ok")),
}, nil
},
}
if downloadReal("https://example.com/file", "/nonexistent-dir/dest") {
t.Error("expected downloadReal to fail when creating destination file fails")
}
// 4. json Decode error
httpClient.Transport = &mockTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString("invalid json")),
}, nil
},
}
var v any
if fetchJSONReal("https://example.com/api", &v) {
t.Error("expected fetchJSONReal to fail on invalid JSON")
}
// 5. io.ReadAll error
httpClient.Transport = &mockTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(&errReader{}),
}, nil
},
}
if fetchTextReal("https://example.com/text") != "" {
t.Error("expected fetchTextReal to fail on read error")
}
}