17574: Update replication_confirmed fields after keep-balance run.
[arvados.git] / services / keep-balance / integration_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package main
6
7 import (
8         "bytes"
9         "io"
10         "os"
11         "strings"
12         "testing"
13         "time"
14
15         "git.arvados.org/arvados.git/lib/config"
16         "git.arvados.org/arvados.git/sdk/go/arvados"
17         "git.arvados.org/arvados.git/sdk/go/arvadosclient"
18         "git.arvados.org/arvados.git/sdk/go/arvadostest"
19         "git.arvados.org/arvados.git/sdk/go/ctxlog"
20         "git.arvados.org/arvados.git/sdk/go/keepclient"
21         "github.com/prometheus/client_golang/prometheus"
22         "github.com/sirupsen/logrus"
23         check "gopkg.in/check.v1"
24 )
25
26 var _ = check.Suite(&integrationSuite{})
27
28 type integrationSuite struct {
29         config     *arvados.Cluster
30         client     *arvados.Client
31         keepClient *keepclient.KeepClient
32 }
33
34 func (s *integrationSuite) SetUpSuite(c *check.C) {
35         if testing.Short() {
36                 c.Skip("-short")
37         }
38         arvadostest.ResetEnv()
39         arvadostest.StartAPI()
40         arvadostest.StartKeep(4, true)
41
42         arv, err := arvadosclient.MakeArvadosClient()
43         arv.ApiToken = arvadostest.SystemRootToken
44         c.Assert(err, check.IsNil)
45
46         s.keepClient, err = keepclient.MakeKeepClient(arv)
47         c.Assert(err, check.IsNil)
48         s.putReplicas(c, "foo", 4)
49         s.putReplicas(c, "bar", 1)
50 }
51
52 func (s *integrationSuite) putReplicas(c *check.C, data string, replicas int) {
53         s.keepClient.Want_replicas = replicas
54         _, _, err := s.keepClient.PutB([]byte(data))
55         c.Assert(err, check.IsNil)
56 }
57
58 func (s *integrationSuite) TearDownSuite(c *check.C) {
59         if testing.Short() {
60                 c.Skip("-short")
61         }
62         arvadostest.StopKeep(4)
63         arvadostest.StopAPI()
64 }
65
66 func (s *integrationSuite) SetUpTest(c *check.C) {
67         cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load()
68         c.Assert(err, check.Equals, nil)
69         s.config, err = cfg.GetCluster("")
70         c.Assert(err, check.Equals, nil)
71         s.config.Collections.BalancePeriod = arvados.Duration(time.Second)
72
73         s.client = &arvados.Client{
74                 APIHost:   os.Getenv("ARVADOS_API_HOST"),
75                 AuthToken: arvadostest.SystemRootToken,
76                 Insecure:  true,
77         }
78 }
79
80 func (s *integrationSuite) TestBalanceAPIFixtures(c *check.C) {
81         var logBuf bytes.Buffer
82         for iter := 0; iter < 20; iter++ {
83                 logBuf.Reset()
84                 logger := logrus.New()
85                 logger.Out = io.MultiWriter(&logBuf, os.Stderr)
86                 opts := RunOptions{
87                         CommitPulls: true,
88                         CommitTrash: true,
89                         Logger:      logger,
90                 }
91
92                 bal := &Balancer{
93                         Logger:  logger,
94                         Metrics: newMetrics(prometheus.NewRegistry()),
95                 }
96                 nextOpts, err := bal.Run(s.client, s.config, opts)
97                 c.Check(err, check.IsNil)
98                 c.Check(nextOpts.SafeRendezvousState, check.Not(check.Equals), "")
99                 c.Check(nextOpts.CommitPulls, check.Equals, true)
100                 if iter == 0 {
101                         c.Check(logBuf.String(), check.Matches, `(?ms).*ChangeSet{Pulls:1.*`)
102                         c.Check(logBuf.String(), check.Not(check.Matches), `(?ms).*ChangeSet{.*Trashes:[^0]}*`)
103                 } else if strings.Contains(logBuf.String(), "ChangeSet{Pulls:0") {
104                         break
105                 }
106                 time.Sleep(200 * time.Millisecond)
107         }
108         c.Check(logBuf.String(), check.Not(check.Matches), `(?ms).*0 replicas (0 blocks, 0 bytes) underreplicated.*`)
109
110         for _, trial := range []struct {
111                 uuid    string
112                 repl    int
113                 classes []string
114         }{
115                 {arvadostest.EmptyCollectionUUID, 0, []string{"default"}},
116                 {arvadostest.FooCollection, 4, []string{"default"}},                                // "foo" blk
117                 {arvadostest.StorageClassesDesiredDefaultConfirmedDefault, 2, []string{"default"}}, // "bar" blk
118                 {arvadostest.StorageClassesDesiredArchiveConfirmedDefault, 0, []string{"archive"}}, // "bar" blk
119         } {
120                 c.Logf("%#v", trial)
121                 var coll arvados.Collection
122                 s.client.RequestAndDecode(&coll, "GET", "arvados/v1/collections/"+trial.uuid, nil, nil)
123                 if c.Check(coll.ReplicationConfirmed, check.NotNil) {
124                         c.Check(*coll.ReplicationConfirmed, check.Equals, trial.repl)
125                 }
126                 c.Check(coll.StorageClassesConfirmed, check.DeepEquals, trial.classes)
127         }
128 }