Repository: FairwindsOps/pluto
Pull request #17 (2020-03-27 18:55:46)

Adding helm tests + goreportcard fixes
* made Kube struct private to the helm pkg
* added helm tests for things that don't interact with kube
  * I might be able to improve coverage moving some things around later

codecov[bot]: # [Codecov](https://codecov.io/gh/FairwindsOps/pluto/pull/17?src=pr&el=h1) Report
> Merging [#17](https://codecov.io/gh/FairwindsOps/pluto/pull/17?src=pr&el=desc) into [master](https://codecov.io/gh/FairwindsOps/pluto/commit/c8fedace5c2152c381c1ffab9bca159a6792e44b&el=desc) will **increase** coverage by `12.19%`.
> The diff coverage is `71.42%`.

[![Impacted file tree graph](https://codecov.io/gh/FairwindsOps/pluto/pull/17/graphs/tree.svg?width=650&height=150&src=pr&token=A23F79JTNA)](https://codecov.io/gh/FairwindsOps/pluto/pull/17?src=pr&el=tree)

```diff
@@             Coverage Diff             @@
##           master      #17       +/-   ##
===========================================
+ Coverage   52.36%   64.55%   +12.19%     
===========================================
  Files           5        5               
  Lines         254      268       +14     
===========================================
+ Hits          133      173       +40     
+ Misses        111       77       -34     
- Partials       10       18        +8     
```


| [Impacted Files](https://codecov.io/gh/FairwindsOps/pluto/pull/17?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/api/versions.go](https://codecov.io/gh/FairwindsOps/pluto/pull/17/diff?src=pr&el=tree#diff-cGtnL2FwaS92ZXJzaW9ucy5nbw==) | `100.00% <ø> (ø)` | |
| [pkg/helm/kube.go](https://codecov.io/gh/FairwindsOps/pluto/pull/17/diff?src=pr&el=tree#diff-cGtnL2hlbG0va3ViZS5nbw==) | `0.00% <0.00%> (ø)` | |
| [pkg/helm/helm.go](https://codecov.io/gh/FairwindsOps/pluto/pull/17/diff?src=pr&el=tree#diff-cGtnL2hlbG0vaGVsbS5nbw==) | `39.56% <60.00%> (+39.56%)` | :arrow_up: |
| [pkg/api/output.go](https://codecov.io/gh/FairwindsOps/pluto/pull/17/diff?src=pr&el=tree#diff-cGtnL2FwaS9vdXRwdXQuZ28=) | `74.54% <80.00%> (-4.18%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/FairwindsOps/pluto/pull/17?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/FairwindsOps/pluto/pull/17?src=pr&el=footer). Last update [c8fedac...5cd5852](https://codecov.io/gh/FairwindsOps/pluto/pull/17?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

sudermanjr: Thanks!!!!

Patch:
diff --git a/go.sum b/go.sum
index 60e382e..79b34b3 100644
--- a/go.sum
+++ b/go.sum
@@ -1,13 +1,20 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
 cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
+github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
 github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
 github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
 github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
 github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
 github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
 github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
 github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@@ -50,6 +57,7 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@@ -65,6 +73,7 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -75,6 +84,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54=
 github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
 github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
 github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@@ -137,6 +147,7 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
@@ -150,6 +161,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
 github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
+github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -162,10 +174,12 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
 github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -180,9 +194,11 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -213,14 +229,17 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
 github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
 github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -289,8 +308,11 @@ go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
 go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -382,6 +404,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
 golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
 gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
@@ -390,6 +413,7 @@ gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmK
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -401,14 +425,17 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/pkg/api/output.go b/pkg/api/output.go
index e0c43e7..0532aba 100644
--- a/pkg/api/output.go
+++ b/pkg/api/output.go
@@ -17,43 +17,17 @@ func DisplayOutput(outputs []*Output, outputFormat string, showNonDeprecated boo
 	}
 	var err error
 	var outData []byte
-	var usableOutputs []*Output
 	switch outputFormat {
 	case "tabular":
-		if showNonDeprecated {
-			usableOutputs = outputs
-		} else {
-			for _, output := range outputs {
-				if output.APIVersion.Deprecated {
-					usableOutputs = append(usableOutputs, output)
-				}
-			}
-		}
-		if len(usableOutputs) == 0 {
-			fmt.Println("APIVersions were found, but none were deprecated. Try --show-non-deprecated.")
-			return nil
-		}
-		w := new(tabwriter.Writer)
-		w.Init(os.Stdout, 0, 8, 2, ' ', 0)
-		_, err = fmt.Fprintln(w, "KIND\t VERSION\t DEPRECATED\t RESOURCE NAME")
+		t, err := tabOut(outputs, showNonDeprecated)
 		if err != nil {
 			return err
 		}
-		for _, output := range usableOutputs {
-			kind := output.APIVersion.Kind
-			deprecated := fmt.Sprintf("%t", output.APIVersion.Deprecated)
-			version := output.APIVersion.Name
-			fileName := output.Name
-
-			_, err = fmt.Fprintf(w, "%s\t %s\t %s\t %s\t\n", kind, version, deprecated, fileName)
-			if err != nil {
-				return err
-			}
-		}
-		err = w.Flush()
+		err = t.Flush()
 		if err != nil {
 			return err
 		}
+		return nil
 	case "json":
 		outData, err = json.Marshal(outputs)
 		if err != nil {
@@ -71,3 +45,42 @@ func DisplayOutput(outputs []*Output, outputFormat string, showNonDeprecated boo
 	}
 	return nil
 }
+
+func tabOut(outputs []*Output, showNonDeprecated bool) (*tabwriter.Writer, error) {
+	var usableOutputs []*Output
+	w := new(tabwriter.Writer)
+	w.Init(os.Stdout, 0, 8, 2, ' ', 0)
+
+	if showNonDeprecated {
+		usableOutputs = outputs
+	} else {
+		for _, output := range outputs {
+			if output.APIVersion.Deprecated {
+				usableOutputs = append(usableOutputs, output)
+			}
+		}
+	}
+	if len(usableOutputs) == 0 {
+		_, err := fmt.Fprintln(w, "APIVersions were found, but none were deprecated. Try --show-non-deprecated.")
+		if err != nil {
+			return nil, err
+		}
+		return w, nil
+	}
+	_, err := fmt.Fprintln(w, "KIND\t VERSION\t DEPRECATED\t RESOURCE NAME")
+	if err != nil {
+		return nil, err
+	}
+	for _, output := range usableOutputs {
+		kind := output.APIVersion.Kind
+		deprecated := fmt.Sprintf("%t", output.APIVersion.Deprecated)
+		version := output.APIVersion.Name
+		fileName := output.Name
+
+		_, err = fmt.Fprintf(w, "%s\t %s\t %s\t %s\t\n", kind, version, deprecated, fileName)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return w, nil
+}
diff --git a/pkg/api/versions.go b/pkg/api/versions.go
index 1a048b3..4326a6d 100644
--- a/pkg/api/versions.go
+++ b/pkg/api/versions.go
@@ -31,6 +31,7 @@ type Stub struct {
 	Metadata   StubMeta `json:"metadata" yaml:"metadata"`
 }
 
+// StubMeta will catch kube resource metadata
 type StubMeta struct {
 	Name string `json:"name" yaml:"name"`
 }
@@ -145,7 +146,6 @@ func jsonToStub(data []byte) ([]*Stub, error) {
 	if err != nil {
 		return nil, err
 	}
-	// sort of hacky just to get us a slice. json parse will always return a single element
 	stubs = append(stubs, stub)
 	return stubs, nil
 }
diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go
index eb17f1b..d26626c 100644
--- a/pkg/helm/helm.go
+++ b/pkg/helm/helm.go
@@ -30,23 +30,27 @@ import (
 	"github.com/fairwindsops/pluto/pkg/api"
 )
 
+// Helm represents all current releases that we can find in the cluster
 type Helm struct {
 	CurrentReleases []*Release
 	Outputs         []*api.Output
 	Version         string
 }
 
+// Release is a single version of a chart release
 type Release struct {
 	Name     string `json:"metadata.name" yaml:"metadata.name"`
 	Manifest string `json:"manifest,omitempty"`
 }
 
+// NewHelm returns a basic helm struct with the version of helm requested
 func NewHelm(version string) *Helm {
 	return &Helm{
 		Version: version,
 	}
 }
 
+// FindVersions is the primary method in the package. It ties together all the functionality
 func (h *Helm) FindVersions() error {
 	var err error
 	var k = getConfigInstance()
@@ -63,12 +67,12 @@ func (h *Helm) FindVersions() error {
 }
 
 // getManifestsVersionTwo retrieves helm 2 manifests from ConfigMaps
-func (h *Helm) getManifestsVersionTwo(k *Kube) error {
+func (h *Helm) getManifestsVersionTwo(k *kube) error {
 	return fmt.Errorf("helm 2 check not implemented")
 }
 
 // getManifestsVersionThree retrieves helm 3 manifests from Secrets
-func (h *Helm) getManifestsVersionThree(k *Kube) error {
+func (h *Helm) getManifestsVersionThree(k *kube) error {
 	secrets, err := k.Client.CoreV1().Secrets("").List(metav1.ListOptions{})
 	if err != nil {
 		return err
@@ -107,8 +111,11 @@ func (h *Helm) setCurrentReleases(allReleases []*Release) error {
 	regex := regexp.MustCompile(`^(sh\.helm\.release)\.(v[0-9]+)\.([\w\-]+)\.v([0-9]+)$`)
 	for _, release := range allReleases {
 		parts := regex.FindStringSubmatch(release.Name)
+		if len(parts) < 5 {
+			return fmt.Errorf("unexpected helm release name: %s", release.Name)
+		}
 		releaseName := parts[3]
-		thisVersion, err := strconv.Atoi(parts[4])
+		releaseVersion, err := strconv.Atoi(parts[4])
 		if err != nil {
 			return err
 		}
@@ -118,7 +125,7 @@ func (h *Helm) setCurrentReleases(allReleases []*Release) error {
 			if err != nil {
 				return err
 			}
-			if thisVersion > storedVersion {
+			if releaseVersion > storedVersion {
 				found[releaseName] = release
 			}
 		} else {
@@ -134,6 +141,9 @@ func (h *Helm) setCurrentReleases(allReleases []*Release) error {
 // This function is ripped straight out of the helm 3 codebase with slight modification
 // https://github.com/helm/helm/blob/193850a9e2c509acf1a499d98e8d23c12c134f11/pkg/storage/driver/util.go#L56-L84
 func decodeReleaseSecret(data string) (*Release, error) {
+	if len(data) < 1 {
+		return nil, fmt.Errorf("no secret data to decode")
+	}
 	var magicGzip = []byte{0x1f, 0x8b, 0x08}
 	var b64 = base64.StdEncoding
 	// base64 decode string
@@ -141,7 +151,9 @@ func decodeReleaseSecret(data string) (*Release, error) {
 	if err != nil {
 		return nil, err
 	}
-
+	if len(b) < 4 {
+		return nil, fmt.Errorf("not valid secret data")
+	}
 	// For backwards compatibility with releases that were stored before
 	// compression was introduced we skip decompression if the
 	// gzip magic header is not found
diff --git a/pkg/helm/kube.go b/pkg/helm/kube.go
index 33af1a8..69cb14d 100644
--- a/pkg/helm/kube.go
+++ b/pkg/helm/kube.go
@@ -20,21 +20,23 @@ import (
 	"sync"
 
 	"k8s.io/client-go/kubernetes"
+	// This is required to auth to various managed kube clusters (i.e. GKE)
+	_ "k8s.io/client-go/plugin/pkg/client/auth"
 	"sigs.k8s.io/controller-runtime/pkg/client/config"
 )
 
-type Kube struct {
+type kube struct {
 	Client kubernetes.Interface
 }
 
-var kubeClient *Kube
+var kubeClient *kube
 var once sync.Once
 
 // GetConfigInstance returns a Kubernetes interface based on the current configuration
-func getConfigInstance() *Kube {
+func getConfigInstance() *kube {
 	once.Do(func() {
 		if kubeClient == nil {
-			kubeClient = &Kube{
+			kubeClient = &kube{
 				Client: getKubeClient(),
 			}
 		}


Test patch:
diff --git a/pkg/api/versions_test.go b/pkg/api/versions_test.go
index 8929a7b..fa5b216 100644
--- a/pkg/api/versions_test.go
+++ b/pkg/api/versions_test.go
@@ -31,7 +31,7 @@ func Test_jsonToStub(t *testing.T) {
 		{
 			name:    "json not stub",
 			data:    []byte("{}"),
-			want:    []*Stub{&Stub{}},
+			want:    []*Stub{{}},
 			wantErr: false,
 		},
 		{
diff --git a/pkg/helm/helm_test.go b/pkg/helm/helm_test.go
index 99cf84b..74b478b 100644
--- a/pkg/helm/helm_test.go
+++ b/pkg/helm/helm_test.go
@@ -14,4 +14,146 @@
 
 package helm
 
-// TODO: Make tests.
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var (
+	multipleReleaseVersionsList = []*Release{
+		{
+			Name: "sh.helm.release.v1.example-app.v1",
+		},
+		{
+			Name: "sh.helm.release.v1.example-app.v2",
+		},
+		{
+			Name: "sh.helm.release.v1.example-app.v123",
+		},
+		{
+			Name: "sh.helm.release.v1.example-app.v3",
+		},
+	}
+	badReleaseName = []*Release{
+		{
+			Name: "sh.helm.release.v1.example-app.vOne",
+		},
+	}
+	gzippedReleaseDataString    = "H4sIACgjfl4AA3WSTW8TMRCG7/kVo0XiREjSVgi5p4qPA0oBIcGF5TDxTpIBf2w9dsIK8d+xt02zm4a5WJ535rHntf9MACqLjtcksVJQYcvfKAh7pwDbVma7Re1+sWsUvKXW+M6Si7WzFLHBiKp2AA4tKUiRDUcmKSmDKzLSq1A4I1la0r0UMpE1ioJF2QoZ0tGHhzaLUW+XQ9BTFEAk2xqMdGgaXqyEGQPOIfLJhxuV0N5FZJddeExNz814H2xxk5W7hN1L9jNJDYVs6M8weyxW5X4Sjz3P4EOSmE9lB89hjxxh7QPtKBxrtLcZk23/DnU1W7GbrVC2dfUib6f6YZ3WFfwYjBY2ct+w37IhiCHRNTQexBC1cDkvG0fX4y4hnQLH7k2em37HgVXlhbD55Ez3xfv4PiOlk2y46snDOjTG7z8H3uWaDb0TjXnm/hOt0cioNCR3Ix+9K8inoF79KhTyn5hfXlwNNY0trg6eDgWAJvj2JFVe7Wa5PCYDiU9Bn/QGukv5cU6Buk0qG2bHWUvWh07Bq6tbHiqGLZ9HLOb/YywuXt9yNfk7+QdmzTSnhAMAAA=="
+	notGzippedReleaseDataString = "ewogICJtYW5pZmVzdCI6ICJhcGlWZXJzaW9uOiBhcHBzL3YxXG5raW5kOiBEZXBsb3ltZW50XG5tZXRhZGF0YTpcbiAgbmFtZTogdXRpbGl0aWVzXG4gIGxhYmVsczpcbiAgICBhcHA6IHV0aWxpdGllc1xuc3BlYzpcbiAgcmVwbGljYXM6IDFcbiAgc2VsZWN0b3I6XG4gICAgbWF0Y2hMYWJlbHM6XG4gICAgICBhcHA6IHV0aWxpdGllc1xuICB0ZW1wbGF0ZTpcbiAgICBtZXRhZGF0YTpcbiAgICAgIGxhYmVsczpcbiAgICAgICAgYXBwOiB1dGlsaXRpZXNcbiAgICBzcGVjOlxuICAgICAgY29udGFpbmVyczpcbiAgICAgIC0gbmFtZTogdXRpbGl0aWVzXG4gICAgICAgIGltYWdlOiBxdWF5LmlvL3N1ZGVybWFuanIvdXRpbGl0aWVzOmxhdGVzdFxuICAgICAgICAjIEp1c3Qgc3BpbiAmIHdhaXQgZm9yZXZlclxuICAgICAgICBjb21tYW5kOiBbIFwiL2Jpbi9iYXNoXCIsIFwiLWNcIiwgXCItLVwiIF1cbiAgICAgICAgYXJnczogWyBcIndoaWxlIHRydWU7IGRvIHNsZWVwIDMwOyBkb25lO1wiIF1cbiAgICAgICAgc2VjdXJpdHlDb250ZXh0OlxuICAgICAgICAgIHJlYWRPbmx5Um9vdEZpbGVzeXN0ZW06IHRydWVcbiAgICAgICAgICBhbGxvd1ByaXZpbGVnZUVzY2FsYXRpb246IGZhbHNlXG4gICAgICAgICAgcnVuQXNOb25Sb290OiB0cnVlXG4gICAgICAgICAgcnVuQXNVc2VyOiAxMDMyNFxuICAgICAgICAgIGNhcGFiaWxpdGllczpcbiAgICAgICAgICAgIGRyb3A6XG4gICAgICAgICAgICAgIC0gQUxMXG4gICAgICAgIHJlc291cmNlczpcbiAgICAgICAgICByZXF1ZXN0czpcbiAgICAgICAgICAgIGNwdTogMzBtXG4gICAgICAgICAgICBtZW1vcnk6IDY0TWlcbiAgICAgICAgICBsaW1pdHM6XG4gICAgICAgICAgICBjcHU6IDEwMG1cbiAgICAgICAgICAgIG1lbW9yeTogMTI4TWkiCn0K"
+	decodedRelease              = &Release{
+		Manifest: "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: utilities\n  labels:\n    app: utilities\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: utilities\n  template:\n    metadata:\n      labels:\n        app: utilities\n    spec:\n      containers:\n      - name: utilities\n        image: quay.io/sudermanjr/utilities:latest\n        # Just spin & wait forever\n        command: [ \"/bin/bash\", \"-c\", \"--\" ]\n        args: [ \"while true; do sleep 30; done;\" ]\n        securityContext:\n          readOnlyRootFilesystem: true\n          allowPrivilegeEscalation: false\n          runAsNonRoot: true\n          runAsUser: 10324\n          capabilities:\n            drop:\n              - ALL\n        resources:\n          requests:\n            cpu: 30m\n            memory: 64Mi\n          limits:\n            cpu: 100m\n            memory: 128Mi",
+	}
+)
+
+func TestNewHelm(t *testing.T) {
+	tests := []struct {
+		name    string
+		version string
+		want    *Helm
+	}{
+		{
+			name:    "version two",
+			version: "2",
+			want:    &Helm{Version: "2"},
+		},
+		{
+			// This is a bit silly, but it does test the return of the function.
+			name:    "version three",
+			version: "3",
+			want:    &Helm{Version: "3"},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got := NewHelm(tt.version)
+			assert.Equal(t, tt.want, got)
+		})
+	}
+}
+
+func TestSetCurrentRelease(t *testing.T) {
+	tests := []struct {
+		name        string
+		releaseList []*Release
+		want        []*Release
+		wantErr     bool
+	}{
+		{
+			name:        "empty",
+			releaseList: []*Release{},
+			want:        nil,
+			wantErr:     false,
+		},
+		{
+			name:        "multiple release versions",
+			releaseList: multipleReleaseVersionsList,
+			want:        []*Release{multipleReleaseVersionsList[2]},
+			wantErr:     false,
+		},
+		{
+			name:        "bad name",
+			releaseList: badReleaseName,
+			want:        nil,
+			wantErr:     true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			h := Helm{}
+			err := h.setCurrentReleases(tt.releaseList)
+			if tt.wantErr {
+				assert.Error(t, err)
+			} else {
+				assert.NoError(t, err)
+				assert.EqualValues(t, tt.want, h.CurrentReleases)
+			}
+		})
+	}
+}
+
+func TestDecodeReleaseSecret(t *testing.T) {
+	tests := []struct {
+		name    string
+		data    string
+		want    *Release
+		wantErr bool
+	}{
+		{
+			name:    "empty",
+			data:    "",
+			want:    nil,
+			wantErr: true,
+		},
+		{
+			name:    "invalid b64",
+			data:    "notb64",
+			want:    nil,
+			wantErr: true,
+		},
+		{
+			name:    "regular decode",
+			data:    gzippedReleaseDataString,
+			want:    decodedRelease,
+			wantErr: false,
+		},
+		{
+			name:    "regular decode",
+			data:    notGzippedReleaseDataString,
+			want:    decodedRelease,
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := decodeReleaseSecret(tt.data)
+			if tt.wantErr {
+				assert.Error(t, err)
+			} else {
+				assert.NoError(t, err)
+				assert.EqualValues(t, tt.want, got)
+			}
+		})
+	}
+}