Skip to content

Commit

Permalink
[cloudprober] Add support for reading files from S3 and GCS. (#396)
Browse files Browse the repository at this point in the history
* This applies to all kinds of file resources:

 - File based targets
 - TLS certificate files
 - OAuth token files
 - Cloudprober config itself.
  • Loading branch information
manugarg committed May 10, 2024
1 parent 09d8af6 commit 9e5800a
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 52 deletions.
3 changes: 2 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package config
import (
"bufio"
"bytes"
"context"
"errors"
"flag"
"fmt"
Expand Down Expand Up @@ -113,7 +114,7 @@ func handleIncludes(baseDir string, content []byte) (string, error) {
}

func readConfigFile(fileName string) (string, error) {
b, err := file.ReadFile(fileName)
b, err := file.ReadFile(context.Background(), fileName)
if err != nil {
return "", err
}
Expand Down
18 changes: 12 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ require (
cloud.google.com/go/logging v1.8.1
cloud.google.com/go/pubsub v1.33.0
github.com/Masterminds/sprig/v3 v3.2.3
github.com/aws/aws-sdk-go-v2 v1.16.10
github.com/aws/aws-sdk-go-v2 v1.21.0
github.com/aws/aws-sdk-go-v2/config v1.15.9
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.11
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.18.3
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5
github.com/fullstorydev/grpcurl v1.8.7
github.com/google/go-jsonnet v0.20.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
Expand All @@ -34,7 +35,7 @@ require (
google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.33.0
sigs.k8s.io/yaml v1.3.0
sigs.k8s.io/yaml v1.4.0
)

require (
Expand All @@ -47,14 +48,19 @@ require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/apache/arrow/go/v12 v12.0.0 // indirect
github.com/apache/thrift v0.16.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.12.12 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.18 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.11.15 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.16.12 // indirect
github.com/aws/smithy-go v1.12.1 // indirect
github.com/aws/smithy-go v1.14.2 // indirect
github.com/bufbuild/protocompile v0.4.0 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
Expand Down
32 changes: 25 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/P
github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY=
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
github.com/aws/aws-sdk-go-v2 v1.16.4/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
github.com/aws/aws-sdk-go-v2 v1.16.10 h1:+yDD0tcuHRQZgqONkpDwzepqmElQaSlFPymHRHR9mrc=
github.com/aws/aws-sdk-go-v2 v1.16.10/go.mod h1:WTACcleLz6VZTp7fak4EO5b9Q4foxbn+8PIz3PmyKlo=
github.com/aws/aws-sdk-go-v2 v1.21.0 h1:gMT0IW+03wtYJhRqTVYn0wLzwdnK9sRMcxmtfGzRdJc=
github.com/aws/aws-sdk-go-v2 v1.21.0/go.mod h1:/RfNgGmRxI+iFOB1OeJUyxiU+9s88k3pfHvDagGEp0M=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM=
github.com/aws/aws-sdk-go-v2/config v1.15.9 h1:TK5yNEnFDQ9iaO04gJS/3Y+eW8BioQiCUafW75/Wc3Q=
github.com/aws/aws-sdk-go-v2/config v1.15.9/go.mod h1:rv/l/TbZo67kp99v/3Kb0qV6Fm1KEtKyruEV2GvVfgs=
github.com/aws/aws-sdk-go-v2/credentials v1.12.4/go.mod h1:7g+GGSp7xtR823o1jedxKmqRZGqLdoHQfI4eFasKKxs=
Expand All @@ -72,28 +75,42 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.5/go.mod h1:WAPnuhG5IQ/i6DET
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.11 h1:zZHPdM2x09/0F8D7XyVvQnP2/jaW7bEMmtcSCPYq/iI=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.11/go.mod h1:38Asv/UyQbDNpSXCurZRlDMjzIl6J+wUe8vY3TtUuzA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.11/go.mod h1:tmUB6jakq5DFNcXsXOA/ZQ7/C8VnSKYkx58OI7Fh79g=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.17 h1:U8DZvyFFesBmK62dYC6BRXm4Cd/wPP3aPcecu3xv/F4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.17/go.mod h1:6qtGip7sJEyvgsLjphRZWF9qPe3xJf1mL/MM01E35Wc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 h1:22dGT7PneFMx4+b3pz7lMTRyN8ZKH7M2cW4GP9yUS2g=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41/go.mod h1:CrObHAuPneJBlfEJ5T3szXOUkLEThaGfvnhTf33buas=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.5/go.mod h1:fV1AaS2gFc1tM0RCb015FJ0pvWVUfJZANzjwoO4YakM=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.11 h1:GMp98usVW5tzQhxd26KWhoNQPlR2noIlfbzqjVGBhLU=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.11/go.mod h1:cYAfnB+9ZkmZWpQWmPDsuIGm4EA+6k2ZVtxKjw/XJBY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 h1:SijA0mgjV8E+8G45ltVHs0fvKpTj8xmZJ3VwhGKtUSI=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35/go.mod h1:SJC1nEVVva1g3pHAIdCp7QsRIkMmLAgoDquQ9Rr8kYw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.12/go.mod h1:00c7+ALdPh4YeEUPXJzyU0Yy01nPGOq2+9rUaz05z9g=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.18 h1:/spg6h3tG4pefphbvhpgdMtFMegSajPPSEJd1t8lnpc=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.18/go.mod h1:hTHq8hL4bAxJyng364s9d4IUGXZOs7Y5LSqAhIiIQ2A=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4 h1:6lJvvkQ9HmbHZ4h/IEwclwv2mrTW8Uq1SOB/kXy0mfw=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.4/go.mod h1:1PrKYwxTM+zjpw9Y41KFtoJCQrJ34Z47Y4VgVbfndjo=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.18.3 h1:PK6c4wYv3wbb88eH0X0FjJwRykEoJwAesuslNReY7iE=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.18.3/go.mod h1:BrAJyOMrnwzYVQcP5ziqlCpnEuFfkNppZLzqDyW/YTg=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14 h1:m0QTSI6pZYJTk5WSKx3fm5cNW/DCicVzULBgU/6IyD0=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.14/go.mod h1:dDilntgHy9WnHXsh7dDtUPgHKEfTJIBUTHM8OWm0f/0=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36 h1:eev2yZX7esGRjqRbnVk1UxMLw4CyVZDpZXRCcy75oQk=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.36/go.mod h1:lGnOkH9NJATw0XEPcAknFBj3zzNTEGRHtSw+CwC1YTg=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.5/go.mod h1:ZbkttHXaVn3bBo/wpJbQGiiIWR90eTBUVBrEHUEQlho=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.11 h1:GkYtp4gi4wdWUV+pPetjk5y2aDxbr0t8n5OjVBwZdII=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.11/go.mod h1:OEofCUKF7Hri4ShOCokF6k6hGq9PCB2sywt/9rLSXjY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 h1:CdzPW9kKitgIiLV1+MHobfR5Xg25iYnyzWZhyQuSlDI=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35/go.mod h1:QGF2Rs33W5MaN9gYdEQOBBFPLwTZkEhRwI33f7KIG0o=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4 h1:v0jkRigbSD6uOdwcaUQmgEwG1BkPfAPDqaeNt/29ghg=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.4/go.mod h1:LhTyt8J04LL+9cIt7pYJ5lbS/U98ZmXovLOR/4LUsk8=
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5 h1:A42xdtStObqy7NGvzZKpnyNXvoOmm+FENobZ0/ssHWk=
github.com/aws/aws-sdk-go-v2/service/s3 v1.38.5/go.mod h1:rDGMZA7f4pbmTtPOk5v5UM2lmX6UAbRnMDJeDvnH7AM=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.7/go.mod h1:TFVe6Rr2joVLsYQ1ABACXgOC6lXip/qpX2x5jWg/A9w=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.15 h1:HaIE5/TtKr66qZTJpvMifDxH4lRt2JZawbkLYOo1F+Y=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.15/go.mod h1:dDVD4ElJRTQXx7dOQ59EkqGyNU9tnwy1RKln+oLIOTU=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.6/go.mod h1:rP1rEOKAGZoXp4iGDxSXFvODAtXpm34Egf0lL0eshaQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.12 h1:YU9UHPukkCCnETHEExOptF/BxPvGJKXO/NBx+RMQ/2A=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.12/go.mod h1:b53qpmhHk7mTL2J/tfG6f38neZiyBQSiNXGCuNKq4+4=
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
github.com/aws/smithy-go v1.12.1 h1:yQRC55aXN/y1W10HgwHle01DRuV9Dpf31iGkotjt3Ag=
github.com/aws/smithy-go v1.12.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
Expand Down Expand Up @@ -192,6 +209,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g=
Expand Down Expand Up @@ -609,5 +627,5 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
78 changes: 55 additions & 23 deletions internal/file/file.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020 The Cloudprober Authors.
// Copyright 2020-2023 The Cloudprober Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -19,16 +19,13 @@ package file

import (
"context"
"errors"
"fmt"
"io"
"net/http"
"os"
"strings"
"sync"
"time"

"golang.org/x/oauth2/google"
)

type cacheEntry struct {
Expand All @@ -43,64 +40,99 @@ var global = struct {
cache: make(map[string]cacheEntry),
}

type readFunc func(path string) ([]byte, error)
type modTimeFunc func(path string) (time.Time, error)
type readFunc func(ctx context.Context, path string) ([]byte, error)
type modTimeFunc func(ctx context.Context, path string) (time.Time, error)

var zeroTime = time.Time{}

var prefixToReadfunc = map[string]readFunc{
"gs://": readFileFromGCS,
"gs://": readFileFromGCS,
"s3://": readFileFromS3,
"http://": readFileFromHTTP,
"https://": readFileFromHTTP,
}

var prefixToModTimeFunc = map[string]modTimeFunc{
"gs://": modTimeGCS,
"gs://": gcsModTime,
"s3://": s3ModTime,
"http://": httpModTime,
"https://": httpModTime,
}

func readFileFromGCS(objectPath string) ([]byte, error) {
hc, err := google.DefaultClient(context.Background())
if err != nil {
return nil, err
func parseObjectURL(objectPath string) (bucket, object string, err error) {
parts := strings.SplitN(objectPath, "/", 2)
if len(parts) != 2 {
return "", "", fmt.Errorf("invalid object URL: %s", objectPath)
}
return parts[0], parts[1], nil
}

objURL := "https://storage.googleapis.com/" + objectPath
res, err := hc.Get(objURL)
func httpLastModified(res *http.Response) (time.Time, error) {
t, err := time.Parse(time.RFC1123, res.Header.Get("Last-Modified"))
if err != nil {
return zeroTime, fmt.Errorf("error parsing Last-Modified header: %v", err)
}
return t, nil
}

func readFileFromHTTP(ctx context.Context, fileURL string) ([]byte, error) {
req, err := http.NewRequestWithContext(ctx, "GET", fileURL, nil)
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}

if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("got error while retrieving GCS object, http status: %s, status code: %d", res.Status, res.StatusCode)
return nil, fmt.Errorf("got error while retrieving HTTP object, http status: %s, status code: %d", res.Status, res.StatusCode)
}

defer res.Body.Close()
return io.ReadAll(res.Body)
}

func modTimeGCS(objectPath string) (time.Time, error) {
return time.Time{}, errors.New("mod-time is not implemented for GCS files yet")
func httpModTime(ctx context.Context, fileURL string) (time.Time, error) {
req, err := http.NewRequestWithContext(ctx, "HEAD", fileURL, nil)
if err != nil {
return zeroTime, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return zeroTime, err
}

if res.StatusCode != http.StatusOK {
return zeroTime, fmt.Errorf("got error while retrieving HTTP object, http status: %s, status code: %d", res.Status, res.StatusCode)
}

defer res.Body.Close()
return httpLastModified(res)
}

// ReadFile returns file contents as a slice of bytes. It's similar to ioutil's
// ReadFile, but includes support for files on non-disk locations. For example,
// files with paths starting with gs:// are assumed to be on GCS, and are read
// from GCS.
func ReadFile(fname string) ([]byte, error) {
func ReadFile(ctx context.Context, fname string) ([]byte, error) {
for prefix, f := range prefixToReadfunc {
if strings.HasPrefix(fname, prefix) {
return f(fname[len(prefix):])
return f(ctx, fname[len(prefix):])
}
}
return os.ReadFile(fname)
}

func ReadWithCache(fname string, refreshInterval time.Duration) ([]byte, error) {
func ReadWithCache(ctx context.Context, fname string, refreshInterval time.Duration) ([]byte, error) {
global.mu.RLock()
fc, ok := global.cache[fname]
global.mu.RUnlock()
if ok && (time.Since(fc.lastReload) < refreshInterval) {
return fc.b, nil
}

b, err := ReadFile(fname)
b, err := ReadFile(ctx, fname)
if err != nil {
return nil, err
}
Expand All @@ -112,10 +144,10 @@ func ReadWithCache(fname string, refreshInterval time.Duration) ([]byte, error)
}

// ModTime returns file's modified timestamp.
func ModTime(fname string) (time.Time, error) {
func ModTime(ctx context.Context, fname string) (time.Time, error) {
for prefix, f := range prefixToModTimeFunc {
if strings.HasPrefix(fname, prefix) {
return f(fname[len(prefix):])
return f(ctx, fname[len(prefix):])
}
}

Expand Down
10 changes: 5 additions & 5 deletions internal/file/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package file

import (
"io/ioutil"
"context"
"os"
"testing"
"time"
Expand All @@ -24,7 +24,7 @@ import (
)

func createTempFile(t *testing.T, b []byte) string {
tmpfile, err := ioutil.TempFile("", "")
tmpfile, err := os.CreateTemp("", "")
if err != nil {
t.Fatal(err)
return ""
Expand All @@ -38,7 +38,7 @@ func createTempFile(t *testing.T, b []byte) string {
return tmpfile.Name()
}

func testReadFile(path string) ([]byte, error) {
func testReadFile(ctx context.Context, path string) ([]byte, error) {
return []byte("content-for-" + path), nil
}

Expand All @@ -59,7 +59,7 @@ func TestReadFile(t *testing.T) {

for path, expectedContent := range testData {
t.Run("ReadFile("+path+")", func(t *testing.T) {
b, err := ReadFile(path)
b, err := ReadFile(context.Background(), path)
if err != nil {
t.Fatalf("Error while reading the file: %s", path)
}
Expand All @@ -85,7 +85,7 @@ func TestReadWithCache(t *testing.T) {
}

readAndVerify := func(expectedContent string, reloadInterval time.Duration) {
b, err := ReadWithCache(f.Name(), reloadInterval)
b, err := ReadWithCache(context.Background(), f.Name(), reloadInterval)
assert.NoError(t, err, "reading file")
assert.Equal(t, expectedContent, string(b))
}
Expand Down

0 comments on commit 9e5800a

Please sign in to comment.