Skip to content

Commit

Permalink
Move ValidateZone|Region to internal/wire
Browse files Browse the repository at this point in the history
  • Loading branch information
tmdiep committed Nov 4, 2020
1 parent b96381c commit 4fc5521
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 104 deletions.
2 changes: 1 addition & 1 deletion pubsublite/admin.go
Expand Up @@ -35,7 +35,7 @@ type AdminClient struct {
// See https://cloud.google.com/pubsub/lite/docs/locations for the list of
// regions and zones where Cloud Pub/Sub Lite is available.
func NewAdminClient(ctx context.Context, region string, opts ...option.ClientOption) (*AdminClient, error) {
if err := validateRegion(region); err != nil {
if err := wire.ValidateRegion(region); err != nil {
return nil, err
}
admin, err := wire.NewAdminClient(ctx, region, opts...)
Expand Down
13 changes: 4 additions & 9 deletions pubsublite/internal/wire/message_router_test.go
Expand Up @@ -17,14 +17,9 @@ import (
"fmt"
"math/rand"
"testing"
)

type fakeSource struct {
ret int64
}

func (f *fakeSource) Int63() int64 { return f.ret }
func (f *fakeSource) Seed(seed int64) {}
"cloud.google.com/go/pubsublite/internal/test"
)

type fakeMsgRouter struct {
multiplier int
Expand All @@ -42,7 +37,7 @@ func (f *fakeMsgRouter) Route(orderingKey []byte) int {
func TestRoundRobinMsgRouter(t *testing.T) {
// Using the same msgRouter for each test run ensures that it reinitializes
// when the partition count changes.
source := &fakeSource{}
source := &test.FakeSource{}
msgRouter := &roundRobinMsgRouter{rng: rand.New(source)}

for _, tc := range []struct {
Expand All @@ -62,7 +57,7 @@ func TestRoundRobinMsgRouter(t *testing.T) {
},
} {
t.Run(fmt.Sprintf("partitionCount=%d", tc.partitionCount), func(t *testing.T) {
source.ret = tc.source
source.Ret = tc.source
msgRouter.SetPartitionCount(tc.partitionCount)
for i, want := range tc.want {
got := msgRouter.Route([]byte("IGNORED"))
Expand Down
27 changes: 27 additions & 0 deletions pubsublite/internal/wire/resources.go
Expand Up @@ -13,6 +13,33 @@

package wire

import (
"fmt"
"strings"
)

// ValidateZone verifies that the `input` string has the format of a valid
// Google Cloud zone. An example zone is "europe-west1-b".
// See https://cloud.google.com/compute/docs/regions-zones for more information.
func ValidateZone(input string) error {
parts := strings.Split(input, "-")
if len(parts) != 3 {
return fmt.Errorf("pubsublite: invalid zone %q", input)
}
return nil
}

// ValidateRegion verifies that the `input` string has the format of a valid
// Google Cloud region. An example region is "europe-west1".
// See https://cloud.google.com/compute/docs/regions-zones for more information.
func ValidateRegion(input string) error {
parts := strings.Split(input, "-")
if len(parts) != 2 {
return fmt.Errorf("pubsublite: invalid region %q", input)
}
return nil
}

type topicPartition struct {
Path string
Partition int
Expand Down
78 changes: 78 additions & 0 deletions pubsublite/internal/wire/resources_test.go
@@ -0,0 +1,78 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and

package wire

import "testing"

func TestValidateZone(t *testing.T) {
for _, tc := range []struct {
desc string
input string
wantErr bool
}{
{
desc: "valid",
input: "us-central1-a",
wantErr: false,
},
{
desc: "invalid: insufficient dashes",
input: "us-central1",
wantErr: true,
},
{
desc: "invalid: excess dashes",
input: "us-central1-a-b",
wantErr: true,
},
} {
t.Run(tc.desc, func(t *testing.T) {
err := ValidateZone(tc.input)
if (err != nil) != tc.wantErr {
t.Errorf("ValidateZone(%q) = %v, want err=%v", tc.input, err, tc.wantErr)
}
})
}
}

func TestValidateRegion(t *testing.T) {
for _, tc := range []struct {
desc string
input string
wantErr bool
}{
{
desc: "valid",
input: "europe-west1",
wantErr: false,
},
{
desc: "invalid: insufficient dashes",
input: "europewest1",
wantErr: true,
},
{
desc: "invalid: excess dashes",
input: "europe-west1-b",
wantErr: true,
},
} {
t.Run(tc.desc, func(t *testing.T) {
err := ValidateRegion(tc.input)
if (err != nil) != tc.wantErr {
t.Errorf("ValidateRegion(%q) = %v, want err=%v", tc.input, err, tc.wantErr)
}
})
}
}
44 changes: 12 additions & 32 deletions pubsublite/types.go
Expand Up @@ -17,6 +17,8 @@ import (
"fmt"
"regexp"
"strings"

"cloud.google.com/go/pubsublite/internal/wire"
)

// LocationPath stores a path consisting of a project and zone.
Expand All @@ -27,15 +29,15 @@ type LocationPath struct {

// A Google Cloud zone, for example "us-central1-a".
// See https://cloud.google.com/pubsub/lite/docs/locations for the list of
// zones where Google Pub/Sub Lite is available.
// zones where Cloud Pub/Sub Lite is available.
Zone string
}

func (l LocationPath) String() string {
return fmt.Sprintf("projects/%s/locations/%s", l.Project, l.Zone)
}

// TopicPath stores the full path of a Google Pub/Sub Lite topic.
// TopicPath stores the full path of a Cloud Pub/Sub Lite topic.
// See https://cloud.google.com/pubsub/lite/docs/topics for more information.
type TopicPath struct {
// A Google Cloud project. The project ID (e.g. "my-project") or the project
Expand All @@ -44,10 +46,10 @@ type TopicPath struct {

// A Google Cloud zone, for example "us-central1-a".
// See https://cloud.google.com/pubsub/lite/docs/locations for the list of
// zones where Google Pub/Sub Lite is available.
// zones where Cloud Pub/Sub Lite is available.
Zone string

// The ID of the Google Pub/Sub Lite topic, for example "my-topic-name".
// The ID of the Cloud Pub/Sub Lite topic, for example "my-topic-name".
// See https://cloud.google.com/pubsub/docs/admin#resource_names for more
// information.
TopicID string
Expand All @@ -63,7 +65,7 @@ func (t TopicPath) location() LocationPath {

var topicPathRE = regexp.MustCompile(`^projects/([^/]+)/locations/([^/]+)/topics/([^/]+)$`)

// parseTopicPath parses the full path of a Google Pub/Sub Lite topic, which
// parseTopicPath parses the full path of a Cloud Pub/Sub Lite topic, which
// should have the format: `projects/{project}/locations/{zone}/topics/{id}`.
func parseTopicPath(input string) (TopicPath, error) {
parts := topicPathRE.FindStringSubmatch(input)
Expand All @@ -73,7 +75,7 @@ func parseTopicPath(input string) (TopicPath, error) {
return TopicPath{Project: parts[1], Zone: parts[2], TopicID: parts[3]}, nil
}

// SubscriptionPath stores the full path of a Google Pub/Sub Lite subscription.
// SubscriptionPath stores the full path of a Cloud Pub/Sub Lite subscription.
// See https://cloud.google.com/pubsub/lite/docs/subscriptions for more
// information.
type SubscriptionPath struct {
Expand All @@ -83,10 +85,10 @@ type SubscriptionPath struct {

// A Google Cloud zone. An example zone is "us-central1-a".
// See https://cloud.google.com/pubsub/lite/docs/locations for the list of
// zones where Google Pub/Sub Lite is available.
// zones where Cloud Pub/Sub Lite is available.
Zone string

// The ID of the Google Pub/Sub Lite subscription, for example
// The ID of the Cloud Pub/Sub Lite subscription, for example
// "my-subscription-name".
// See https://cloud.google.com/pubsub/docs/admin#resource_names for more
// information.
Expand All @@ -103,7 +105,7 @@ func (s SubscriptionPath) location() LocationPath {

var subsPathRE = regexp.MustCompile(`^projects/([^/]+)/locations/([^/]+)/subscriptions/([^/]+)$`)

// parseSubscriptionPath parses the full path of a Google Pub/Sub Lite
// parseSubscriptionPath parses the full path of a Cloud Pub/Sub Lite
// subscription, which should have the format:
// `projects/{project}/locations/{zone}/subscriptions/{id}`.
func parseSubscriptionPath(input string) (SubscriptionPath, error) {
Expand All @@ -114,31 +116,9 @@ func parseSubscriptionPath(input string) (SubscriptionPath, error) {
return SubscriptionPath{Project: parts[1], Zone: parts[2], SubscriptionID: parts[3]}, nil
}

// validateZone verifies that the `input` string has the format of a valid
// Google Cloud zone. An example zone is "europe-west1-b".
// See https://cloud.google.com/compute/docs/regions-zones for more information.
func validateZone(input string) error {
parts := strings.Split(input, "-")
if len(parts) != 3 {
return fmt.Errorf("pubsublite: invalid zone %q", input)
}
return nil
}

// validateRegion verifies that the `input` string has the format of a valid
// Google Cloud region. An example region is "europe-west1".
// See https://cloud.google.com/compute/docs/regions-zones for more information.
func validateRegion(input string) error {
parts := strings.Split(input, "-")
if len(parts) != 2 {
return fmt.Errorf("pubsublite: invalid region %q", input)
}
return nil
}

// ZoneToRegion returns the region that the given zone is in.
func ZoneToRegion(zone string) (string, error) {
if err := validateZone(zone); err != nil {
if err := wire.ValidateZone(zone); err != nil {
return "", err
}
return zone[0:strings.LastIndex(zone, "-")], nil
Expand Down
62 changes: 0 additions & 62 deletions pubsublite/types_test.go
Expand Up @@ -129,68 +129,6 @@ func TestParseSubscriptionPath(t *testing.T) {
}
}

func TestValidateZone(t *testing.T) {
for _, tc := range []struct {
desc string
input string
wantErr bool
}{
{
desc: "valid",
input: "us-central1-a",
wantErr: false,
},
{
desc: "invalid: insufficient dashes",
input: "us-central1",
wantErr: true,
},
{
desc: "invalid: excess dashes",
input: "us-central1-a-b",
wantErr: true,
},
} {
t.Run(tc.desc, func(t *testing.T) {
err := validateZone(tc.input)
if (err != nil) != tc.wantErr {
t.Errorf("validateZone(%q) = %v, want err=%v", tc.input, err, tc.wantErr)
}
})
}
}

func TestValidateRegion(t *testing.T) {
for _, tc := range []struct {
desc string
input string
wantErr bool
}{
{
desc: "valid",
input: "europe-west1",
wantErr: false,
},
{
desc: "invalid: insufficient dashes",
input: "europewest1",
wantErr: true,
},
{
desc: "invalid: excess dashes",
input: "europe-west1-b",
wantErr: true,
},
} {
t.Run(tc.desc, func(t *testing.T) {
err := validateRegion(tc.input)
if (err != nil) != tc.wantErr {
t.Errorf("validateRegion(%q) = %v, want err=%v", tc.input, err, tc.wantErr)
}
})
}
}

func TestZoneToRegion(t *testing.T) {
for _, tc := range []struct {
desc string
Expand Down

0 comments on commit 4fc5521

Please sign in to comment.