1// Copyright 2016 The etcd Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package e2e 16 17import ( 18 "os" 19 "strings" 20 "testing" 21 "time" 22 23 "github.com/coreos/etcd/clientv3" 24 "golang.org/x/net/context" 25) 26 27func TestCtlV3Alarm(t *testing.T) { 28 // The boltdb minimum working set is six pages. 29 testCtl(t, alarmTest, withQuota(int64(13*os.Getpagesize()))) 30} 31 32func alarmTest(cx ctlCtx) { 33 // test small put still works 34 smallbuf := strings.Repeat("a", 64) 35 if err := ctlV3Put(cx, "1st_test", smallbuf, ""); err != nil { 36 cx.t.Fatal(err) 37 } 38 39 // write some chunks to fill up the database 40 buf := strings.Repeat("b", int(os.Getpagesize())) 41 for { 42 if err := ctlV3Put(cx, "2nd_test", buf, ""); err != nil { 43 if !strings.Contains(err.Error(), "etcdserver: mvcc: database space exceeded") { 44 cx.t.Fatal(err) 45 } 46 break 47 } 48 } 49 50 // quota alarm should now be on 51 if err := ctlV3Alarm(cx, "list", "alarm:NOSPACE"); err != nil { 52 cx.t.Fatal(err) 53 } 54 55 // check that Put is rejected when alarm is on 56 if err := ctlV3Put(cx, "3rd_test", smallbuf, ""); err != nil { 57 if !strings.Contains(err.Error(), "etcdserver: mvcc: database space exceeded") { 58 cx.t.Fatal(err) 59 } 60 } 61 62 eps := cx.epc.grpcEndpoints() 63 64 // get latest revision to compact 65 cli, err := clientv3.New(clientv3.Config{ 66 Endpoints: eps, 67 DialTimeout: 3 * time.Second, 68 }) 69 if err != nil { 70 cx.t.Fatal(err) 71 } 72 defer cli.Close() 73 sresp, err := cli.Status(context.TODO(), eps[0]) 74 if err != nil { 75 cx.t.Fatal(err) 76 } 77 78 // make some space 79 if err := ctlV3Compact(cx, sresp.Header.Revision, true); err != nil { 80 cx.t.Fatal(err) 81 } 82 if err := ctlV3Defrag(cx); err != nil { 83 cx.t.Fatal(err) 84 } 85 86 // turn off alarm 87 if err := ctlV3Alarm(cx, "disarm", "alarm:NOSPACE"); err != nil { 88 cx.t.Fatal(err) 89 } 90 91 // put one more key below quota 92 if err := ctlV3Put(cx, "4th_test", smallbuf, ""); err != nil { 93 cx.t.Fatal(err) 94 } 95} 96 97func ctlV3Alarm(cx ctlCtx, cmd string, as ...string) error { 98 cmdArgs := append(cx.PrefixArgs(), "alarm", cmd) 99 return spawnWithExpects(cmdArgs, as...) 100} 101