From e23da802c29314c272250d9a37e3dc5f439c6398 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 13 Oct 2023 11:51:23 +0200 Subject: [PATCH 1/2] google: mark cache as ready after it got populated The googleImagesCache is currently not marked `ready` AFAICT. This means while it is correctly build it is not used in subsequent calls to projectImages(). This commit set the cache to ready after it got populated. --- spread/google.go | 1 + 1 file changed, 1 insertion(+) diff --git a/spread/google.go b/spread/google.go index d1b08a5b..fe6633f9 100644 --- a/spread/google.go +++ b/spread/google.go @@ -369,6 +369,7 @@ func (p *googleProvider) projectImages(project string) ([]googleImage, error) { Terms: toTerms(item.Description), }) } + cache.ready = true return cache.images, err } From 0b21f7394b600cc91abe2b62db52578d6115f6a9 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 13 Oct 2023 12:14:46 +0200 Subject: [PATCH 2/2] google: add test if image cache works --- spread/export_test.go | 17 +++++++++++ spread/google.go | 6 +++- spread/google_test.go | 69 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 spread/google_test.go diff --git a/spread/export_test.go b/spread/export_test.go index d20b407b..c27fca27 100644 --- a/spread/export_test.go +++ b/spread/export_test.go @@ -1,6 +1,7 @@ package spread import ( + "net/http" "time" "golang.org/x/crypto/ssh" @@ -38,3 +39,19 @@ func MockSshDial(f func(network, addr string, config *ssh.ClientConfig) (*ssh.Cl } var QemuCmd = qemuCmd + +func NewGoogleProviderForTesting(mockApiURL string, p *Project, b *Backend, o *Options) *googleProvider { + provider := Google(p, b, o) + ggl := provider.(*googleProvider) + ggl.apiURL = mockApiURL + ggl.keyChecked = true + ggl.client = &http.Client{} + + return ggl +} + +func (p *googleProvider) ProjectImages(project string) ([]googleImage, error) { + return p.projectImages(project) +} + +type GoogleImage = googleImage diff --git a/spread/google.go b/spread/google.go index fe6633f9..9e82835c 100644 --- a/spread/google.go +++ b/spread/google.go @@ -31,6 +31,8 @@ func Google(p *Project, b *Backend, o *Options) Provider { options: o, imagesCache: make(map[string]*googleImagesCache), + + apiURL: "https://www.googleapis.com", } } @@ -50,6 +52,8 @@ type googleProvider struct { keyErr error imagesCache map[string]*googleImagesCache + + apiURL string } type googleServer struct { @@ -899,7 +903,7 @@ func (p *googleProvider) dofl(method, subpath string, params interface{}, result <-googleThrottle - url := "https://www.googleapis.com" + url := p.apiURL if flags&noPathPrefix == 0 { url += "/compute/v1/projects/" + p.gproject() + subpath } else { diff --git a/spread/google_test.go b/spread/google_test.go new file mode 100644 index 00000000..6e5c839d --- /dev/null +++ b/spread/google_test.go @@ -0,0 +1,69 @@ +package spread_test + +import ( + "net/http" + "net/http/httptest" + + "github.com/snapcore/spread/spread" + + . "gopkg.in/check.v1" +) + +type googleSuite struct{} + +var _ = Suite(&googleSuite{}) + +func (s *googleSuite) TestImagesCache(c *C) { + n := 0 + mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch n { + case 0: + c.Check(r.URL.Path, Equals, "/compute/v1/projects/snapd/global/images") + w.Write([]byte(` + { + "items": [{"status":"READY","name":"ubuntu-1910-64-v20190826", "description":"ubuntu-19.10-64"}, {"status":"READY","name":"ubuntu-1904-64-v20190726", "description":"ubuntu-19.04-64"}] + } + `)) + case 1: + c.Check(r.URL.Path, Equals, "/compute/v1/projects/other-project/global/images") + w.Write([]byte(` + { + "items": [{"status":"READY","name":"ubuntu-2004-64-v20190826", "description":"ubuntu-19.10-64"}] + } + `)) + default: + c.Fatalf("unexpected number of requests") + } + n++ + })) + defer mockServer.Close() + + g := spread.NewGoogleProviderForTesting(mockServer.URL, nil, nil, nil) + c.Assert(g, NotNil) + + // Request the project images + images, err := g.ProjectImages("snapd") + c.Assert(err, IsNil) + c.Assert(images, HasLen, 2) + c.Check(images, DeepEquals, []spread.GoogleImage{ + {"snapd", "ubuntu-1910-64-v20190826", "", []string{"ubuntu", "19.10", "64"}}, + {"snapd", "ubuntu-1904-64-v20190726", "", []string{"ubuntu", "19.04", "64"}}, + }) + c.Check(n, Equals, 1) + + // do it again, now it comes from the cache + images, err = g.ProjectImages("snapd") + c.Assert(err, IsNil) + c.Assert(images, HasLen, 2) + c.Check(images, DeepEquals, []spread.GoogleImage{ + {"snapd", "ubuntu-1910-64-v20190826", "", []string{"ubuntu", "19.10", "64"}}, + {"snapd", "ubuntu-1904-64-v20190726", "", []string{"ubuntu", "19.04", "64"}}, + }) + c.Check(n, Equals, 1) + + // again, this time for another project + images, err = g.ProjectImages("other-project") + c.Assert(err, IsNil) + c.Assert(images, HasLen, 1) + c.Check(n, Equals, 2) +}