From 55e632ca672ad4a1ac68e396ef2cb74f03de0c5a Mon Sep 17 00:00:00 2001 From: Dave Protasowski Date: Tue, 21 Jan 2020 17:25:24 -0500 Subject: [PATCH] add helpers to convert objects through Convertible proxies (#1002) --- apis/convert.go | 47 ++++++++++++++ apis/convert_test.go | 146 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 apis/convert.go create mode 100644 apis/convert_test.go diff --git a/apis/convert.go b/apis/convert.go new file mode 100644 index 000000000..e67a37930 --- /dev/null +++ b/apis/convert.go @@ -0,0 +1,47 @@ +/* +Copyright 2020 The Knative Authors + +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 + + http://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 +limitations under the License. +*/ + +package apis + +import "context" + +// ConvertUpViaProxy attempts to convert a specific source to a sink +// through a proxy +func ConvertUpViaProxy( + ctx context.Context, + source, proxy, sink Convertible, +) error { + + if err := source.ConvertUp(ctx, proxy); err != nil { + return err + } + + return proxy.ConvertUp(ctx, sink) +} + +// ConvertDownViaProxy attempts to convert a specific sink from a source +// through a proxy +func ConvertDownViaProxy( + ctx context.Context, + source, proxy, sink Convertible, +) error { + + if err := proxy.ConvertDown(ctx, source); err != nil { + return err + } + + return sink.ConvertDown(ctx, proxy) +} diff --git a/apis/convert_test.go b/apis/convert_test.go new file mode 100644 index 000000000..9484a37f7 --- /dev/null +++ b/apis/convert_test.go @@ -0,0 +1,146 @@ +/* +Copyright 2020 The Knative Authors + +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 + + http://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 +limitations under the License. +*/ + +package apis + +import ( + "context" + "errors" + "testing" +) + +func TestConvertUpViaProxy(t *testing.T) { + sink := &testResource{} + proxy := &testResource{} + source := &testResource{proxy: proxy} + + err := ConvertUpViaProxy(context.Background(), source, proxy, sink) + + if err != nil { + t.Errorf("ConvertUpViaProxy returned unexpected err: %s", err) + } + + if source.to != proxy { + t.Errorf("expected source to be converted to the proxy") + } + + if proxy.to != sink { + t.Errorf("expected proxy to be converted to the sink") + } +} + +func TestConvertUpViaProxyError(t *testing.T) { + tests := []struct { + name string + source, proxy testResource + }{{ + name: "converting source to proxy fails", + source: testResource{ + err: errors.New("converting up failed"), + }, + proxy: testResource{}, + }, { + name: "converting proxy to sink fails", + source: testResource{}, + proxy: testResource{ + err: errors.New("converting up failed"), + }, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := ConvertUpViaProxy(context.Background(), + &test.source, + &test.proxy, + nil, /* sink */ + ) + + if err == nil { + t.Errorf("expected error to have occurred") + } + }) + } +} + +func TestConvertDownViaProxy(t *testing.T) { + proxy := &testResource{} + sink := &testResource{} + source := &testResource{} + + err := ConvertDownViaProxy(context.Background(), source, proxy, sink) + + if err != nil { + t.Errorf("ConvertDownViaProxy returned unexpected err: %s", err) + } + + if proxy.from != source { + t.Errorf("expected proxy to be converted from the source") + } + + if sink.from != proxy { + t.Errorf("expected sink to be converted from the proxy") + } +} + +func TestConvertDownViaProxyError(t *testing.T) { + tests := []struct { + name string + sink, proxy testResource + }{{ + name: "converting proxy from source fails", + sink: testResource{}, + proxy: testResource{ + err: errors.New("converting down failed"), + }, + }, { + name: "converting sink from proxy fails", + sink: testResource{ + err: errors.New("converting down failed"), + }, + proxy: testResource{}, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + + err := ConvertDownViaProxy(context.Background(), + nil, /* source */ + &test.proxy, + &test.sink, + ) + if err == nil { + t.Errorf("expected error to have occurred") + } + }) + } +} + +type testResource struct { + proxy, to, from Convertible + err error +} + +var _ Convertible = (*testResource)(nil) + +func (r *testResource) ConvertUp(ctx context.Context, to Convertible) error { + r.to = to + return r.err +} + +func (r *testResource) ConvertDown(ctx context.Context, from Convertible) error { + r.from = from + return r.err +}