Skip to content

Commit 35748e4

Browse files
authored
CLOUDP-57857: Describe available measurements for the given partition of the given process, Atlas (#100)
1 parent f58bfb3 commit 35748e4

16 files changed

+316
-31
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ gen-mocks: ## Generate mocks
6767
mockgen -source=internal/store/events.go -destination=internal/mocks/mock_events.go -package=mocks
6868
mockgen -source=internal/store/process_measurements.go -destination=internal/mocks/mock_process_measurements.go -package=mocks
6969
mockgen -source=internal/store/process_disks.go -destination=internal/mocks/mock_process_disks.go -package=mocks
70+
mockgen -source=internal/store/process_disk_measurements.go -destination=internal/mocks/mock_process_disk_measurements.go -package=mocks
7071
mockgen -source=internal/store/process_databases.go -destination=internal/mocks/mock_process_databases.go -package=mocks
7172
mockgen -source=internal/store/host_measurements.go -destination=internal/mocks/mock_host_measurements.go -package=mocks
7273
mockgen -source=internal/store/indexes.go -destination=internal/mocks/mock_indexes.go -package=mocks

internal/cli/atlas_measurements_databases_list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func AtlasMeasurementsDatabasesListBuilder() *cobra.Command {
6565
},
6666
RunE: func(cmd *cobra.Command, args []string) error {
6767
var err error
68-
if opts.host, opts.port, err = GetHostNameAndPort(args[0]); err != nil {
68+
if opts.host, opts.port, err = getHostNameAndPort(args[0]); err != nil {
6969
return err
7070
}
7171

internal/cli/atlas_measurements_databases_list_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,13 @@ func TestAtlasMeasurementsDatabasesListsOpts_Run(t *testing.T) {
3535
store: mockStore,
3636
}
3737

38-
hostName, port, err := GetHostNameAndPort("hard-00-00.mongodb.net:27017")
39-
if err != nil {
40-
t.Fatalf("Run() unexpected error: %v", err)
41-
}
42-
4338
opts := listOpts.newListOptions()
4439
mockStore.
45-
EXPECT().ProcessDatabases(listOpts.projectID, hostName, port, opts).
40+
EXPECT().ProcessDatabases(listOpts.projectID, listOpts.host, listOpts.port, opts).
4641
Return(expected, nil).
4742
Times(1)
4843

49-
err = listOpts.Run()
50-
if err != nil {
44+
if err := listOpts.Run(); err != nil {
5145
t.Fatalf("Run() unexpected error: %v", err)
5246
}
5347
}

internal/cli/atlas_measurements_disks.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func AtlasMeasurementsDisksBuilder() *cobra.Command {
2727
}
2828

2929
cmd.AddCommand(AtlasMeasurementsDisksListBuilder())
30+
cmd.AddCommand(AtlasMeasurementsDisksDescribeBuilder())
3031

3132
return cmd
3233
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2020 MongoDB Inc
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+
15+
package cli
16+
17+
import (
18+
"github.com/mongodb/mongocli/internal/description"
19+
"github.com/mongodb/mongocli/internal/flags"
20+
"github.com/mongodb/mongocli/internal/json"
21+
"github.com/mongodb/mongocli/internal/store"
22+
"github.com/mongodb/mongocli/internal/usage"
23+
"github.com/spf13/cobra"
24+
)
25+
26+
type atlasMeasurementsDisksDescribeOpts struct {
27+
globalOpts
28+
measurementsOpts
29+
host string
30+
port int
31+
name string
32+
store store.ProcessDiskMeasurementsLister
33+
}
34+
35+
func (opts *atlasMeasurementsDisksDescribeOpts) init() error {
36+
if opts.ProjectID() == "" {
37+
return errMissingProjectID
38+
}
39+
40+
var err error
41+
opts.store, err = store.New()
42+
return err
43+
}
44+
45+
func (opts *atlasMeasurementsDisksDescribeOpts) Run() error {
46+
listOpts := opts.newProcessMeasurementListOptions()
47+
result, err := opts.store.ProcessDiskMeasurements(opts.ProjectID(), opts.host, opts.port, opts.name, listOpts)
48+
49+
if err != nil {
50+
return err
51+
}
52+
53+
return json.PrettyPrint(result)
54+
}
55+
56+
// mcli atlas measurements disk(s) describe [host:port] [name] --granularity g --period p --start start --end end [--type type] [--projectId projectId]
57+
func AtlasMeasurementsDisksDescribeBuilder() *cobra.Command {
58+
opts := &atlasMeasurementsDisksDescribeOpts{}
59+
cmd := &cobra.Command{
60+
Use: "describe [host:port] [name]",
61+
Short: description.ListDisks,
62+
Args: cobra.ExactArgs(2),
63+
PreRunE: func(cmd *cobra.Command, args []string) error {
64+
return opts.init()
65+
},
66+
RunE: func(cmd *cobra.Command, args []string) error {
67+
var err error
68+
opts.host, opts.port, err = getHostNameAndPort(args[0])
69+
if err != nil {
70+
return err
71+
}
72+
opts.name = args[1]
73+
return opts.Run()
74+
},
75+
}
76+
77+
cmd.Flags().IntVar(&opts.pageNum, flags.Page, 0, usage.Page)
78+
cmd.Flags().IntVar(&opts.itemsPerPage, flags.Limit, 0, usage.Limit)
79+
80+
cmd.Flags().StringVar(&opts.granularity, flags.Granularity, "", usage.Granularity)
81+
cmd.Flags().StringVar(&opts.period, flags.Period, "", usage.Period)
82+
cmd.Flags().StringVar(&opts.start, flags.Start, "", usage.Start)
83+
cmd.Flags().StringVar(&opts.end, flags.End, "", usage.End)
84+
cmd.Flags().StringVar(&opts.measurementType, flags.MeasurementType, "", usage.MeasurementType)
85+
86+
cmd.Flags().StringVar(&opts.projectID, flags.ProjectID, "", usage.ProjectID)
87+
88+
_ = cmd.MarkFlagRequired(flags.Granularity)
89+
90+
return cmd
91+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2020 MongoDB Inc
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+
package cli
15+
16+
import (
17+
"testing"
18+
19+
"github.com/golang/mock/gomock"
20+
"github.com/mongodb/mongocli/internal/fixtures"
21+
"github.com/mongodb/mongocli/internal/mocks"
22+
)
23+
24+
func TestAtlasMeasurementsDisksDescribeOpts_Run(t *testing.T) {
25+
ctrl := gomock.NewController(t)
26+
mockStore := mocks.NewMockProcessDiskMeasurementsLister(ctrl)
27+
28+
defer ctrl.Finish()
29+
30+
expected := fixtures.DiskMeasurements()
31+
32+
listOpts := &atlasMeasurementsDisksDescribeOpts{
33+
host: "hard-00-00.mongodb.net",
34+
port: 27017,
35+
name: "test",
36+
store: mockStore,
37+
}
38+
39+
opts := listOpts.newProcessMeasurementListOptions()
40+
mockStore.
41+
EXPECT().ProcessDiskMeasurements(listOpts.projectID, listOpts.host, listOpts.port, listOpts.name, opts).
42+
Return(expected, nil).
43+
Times(1)
44+
45+
err := listOpts.Run()
46+
if err != nil {
47+
t.Fatalf("Run() unexpected error: %v", err)
48+
}
49+
}

internal/cli/atlas_measurements_disks_list.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ func (opts *atlasMeasurementsDisksListsOpts) Run() error {
5252
return json.PrettyPrint(result)
5353
}
5454

55-
// mongocli atlas measurements process(es) disks lists host:port
55+
// mongocli atlas measurements process(es) disks lists [host:port]
5656
func AtlasMeasurementsDisksListBuilder() *cobra.Command {
5757
opts := &atlasMeasurementsDisksListsOpts{}
5858
cmd := &cobra.Command{
59-
Use: "list",
59+
Use: "list [host:port]",
6060
Short: description.ListDisks,
6161
Aliases: []string{"ls"},
6262
Args: cobra.ExactArgs(1),
@@ -65,7 +65,7 @@ func AtlasMeasurementsDisksListBuilder() *cobra.Command {
6565
},
6666
RunE: func(cmd *cobra.Command, args []string) error {
6767
var err error
68-
opts.host, opts.port, err = GetHostNameAndPort(args[0])
68+
opts.host, opts.port, err = getHostNameAndPort(args[0])
6969
if err != nil {
7070
return err
7171
}

internal/cli/atlas_measurements_disks_list_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,13 @@ func TestAtlasMeasurementsDisksListsOpts_Run(t *testing.T) {
3535
store: mockStore,
3636
}
3737

38-
hostName, port, err := GetHostNameAndPort("hard-00-00.mongodb.net:27017")
39-
if err != nil {
40-
t.Fatalf("Run() unexpected error: %v", err)
41-
}
42-
4338
opts := listOpts.newListOptions()
4439
mockStore.
45-
EXPECT().ProcessDisks(listOpts.projectID, hostName, port, opts).
40+
EXPECT().ProcessDisks(listOpts.projectID, listOpts.host, listOpts.port, opts).
4641
Return(expected, nil).
4742
Times(1)
4843

49-
err = listOpts.Run()
50-
if err != nil {
44+
if err := listOpts.Run(); err != nil {
5145
t.Fatalf("Run() unexpected error: %v", err)
5246
}
5347
}

internal/cli/atlas_measurements_processes.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func AtlasMeasurementsProcessBuilder() *cobra.Command {
6565
},
6666
RunE: func(cmd *cobra.Command, args []string) error {
6767
var err error
68-
opts.host, opts.port, err = GetHostNameAndPort(args[0])
68+
opts.host, opts.port, err = getHostNameAndPort(args[0])
6969
if err != nil {
7070
return err
7171
}
@@ -84,5 +84,7 @@ func AtlasMeasurementsProcessBuilder() *cobra.Command {
8484

8585
cmd.Flags().StringVar(&opts.projectID, flags.ProjectID, "", usage.ProjectID)
8686

87+
_ = cmd.MarkFlagRequired(flags.Granularity)
88+
8789
return cmd
8890
}

internal/cli/atlas_measurements_processes_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,13 @@ func TestAtlasMeasurementsProcess_Run(t *testing.T) {
3737
listOpts.granularity = "PT1M"
3838
listOpts.period = "PT1M"
3939

40-
hostName, port, err := GetHostNameAndPort("hard-00-00.mongodb.net:27017")
41-
if err != nil {
42-
t.Fatalf("Run() unexpected error: %v", err)
43-
}
44-
4540
opts := listOpts.newProcessMeasurementListOptions()
4641
mockStore.
47-
EXPECT().ProcessMeasurements(listOpts.projectID, hostName, port, opts).
42+
EXPECT().ProcessMeasurements(listOpts.projectID, listOpts.host, listOpts.port, opts).
4843
Return(expected, nil).
4944
Times(1)
5045

51-
err = listOpts.Run()
52-
if err != nil {
46+
if err := listOpts.Run(); err != nil {
5347
t.Fatalf("Run() unexpected error: %v", err)
5448
}
5549
}

internal/cli/cli.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ func (opts *listOpts) newListOptions() *atlas.ListOptions {
255255
}
256256
}
257257

258-
// GetHostNameAndPort return the hostname and the port starting from the string hostname:port
259-
func GetHostNameAndPort(hostInfo string) (string, int, error) {
258+
// getHostNameAndPort return the hostname and the port starting from the string hostname:port
259+
func getHostNameAndPort(hostInfo string) (string, int, error) {
260260
host := strings.SplitN(hostInfo, ":", -1)
261261
if len(host) != 2 {
262262
return "", 0, fmt.Errorf("expected hostname:port, got %s", host)

internal/cli/cli_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package cli
2+
3+
import "testing"
4+
5+
func TestGetHostNameAndPort(t *testing.T) {
6+
t.Run("valid parameter", func(t *testing.T) {
7+
host, port, err := getHostNameAndPort("test:2000")
8+
if err != nil {
9+
t.Fatalf("getHostNameAndPort unexpecteted err: %#v\n", err)
10+
}
11+
if host != "test" {
12+
t.Errorf("Expected '%s', got '%s'\n", "test", host)
13+
}
14+
if port != 2000 {
15+
t.Errorf("Expected '%d', got '%d'\n", 2000, port)
16+
}
17+
})
18+
t.Run("incomplete format", func(t *testing.T) {
19+
_, _, err := getHostNameAndPort("test")
20+
if err == nil {
21+
t.Fatal("getHostNameAndPort should return an error\n")
22+
}
23+
})
24+
t.Run("incomplete format", func(t *testing.T) {
25+
_, _, err := getHostNameAndPort(":test")
26+
if err == nil {
27+
t.Fatal("getHostNameAndPort should return an error\n")
28+
}
29+
})
30+
}

internal/description/description.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ A user’s roles apply to all the clusters in the project.`
5656
ProcessMeasurements = "Get measurements for a given host."
5757
Disks = "List available disks or disks measurements for a given host."
5858
ListDisks = "List available disks for a given host."
59+
DescribeDisks = "Describe disks measurements for a given host partition."
5960
Databases = "List available databases or databases measurements for a given host."
6061
ListDatabases = "List available databases for a given host."
6162
Whitelist = "Manage the IP whitelist for a project."

internal/fixtures/measurements.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,47 @@ func ProcessDatabases() *atlas.ProcessDatabasesResponse {
6262
}
6363
}
6464

65+
func DiskMeasurements() *atlas.ProcessDiskMeasurements {
66+
m := &atlas.ProcessDiskMeasurements{
67+
ProcessMeasurements: &atlas.ProcessMeasurements{},
68+
PartitionName: "test",
69+
}
70+
m.End = "2017-08-22T20:31:14Z"
71+
m.Granularity = "PT1M"
72+
m.GroupID = "12345678"
73+
m.HostID = "shard-00-00.mongodb.net:27017"
74+
m.ProcessID = "shard-00-00.mongodb.net:27017"
75+
m.Start = "2017-08-22T20:30:45Z"
76+
m.Links = []*atlas.Link{
77+
{
78+
Rel: "self",
79+
Href: "https://cloud.mongodb.com/api/atlas/v1.0/groups/12345678/processes/shard-00-00.mongodb.net:27017/disks/data/measurements?granularity=PT1M&period=PT1M",
80+
},
81+
{
82+
Href: "https://cloud.mongodb.com/api/atlas/v1.0/groups/12345678/processes/shard-00-00.mongodb.net:27017",
83+
Rel: "http://mms.mongodb.com/host",
84+
},
85+
}
86+
m.Measurements = []*atlas.Measurements{
87+
{
88+
DataPoints: []*atlas.DataPoints{
89+
{
90+
Timestamp: "2017-08-22T20:31:12Z",
91+
Value: nil,
92+
},
93+
{
94+
Timestamp: "2017-08-22T20:31:14Z",
95+
Value: nil,
96+
},
97+
},
98+
Name: "ASSERT_REGULAR",
99+
Units: "SCALAR_PER_SECOND",
100+
},
101+
}
102+
103+
return &atlas.ProcessDiskMeasurements{}
104+
}
105+
65106
func ProcessMeasurements() *atlas.ProcessMeasurements {
66107
return &atlas.ProcessMeasurements{
67108
End: "2017-08-22T20:31:14Z",

0 commit comments

Comments
 (0)