/ *
* MinIO Cloud Storage , ( C ) 2017 MinIO , Inc .
*
* 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 cmd
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"runtime"
"strings"
"testing"
"time"
)
func TestMinioVersionToReleaseTime ( t * testing . T ) {
testCases := [ ] struct {
version string
isOfficial bool
} {
{ "2017-09-29T19:16:56Z" , true } ,
{ "RELEASE.2017-09-29T19-16-56Z" , false } ,
{ "DEVELOPMENT.GOGET" , false } ,
}
for i , testCase := range testCases {
_ , err := minioVersionToReleaseTime ( testCase . version )
if ( err == nil ) != testCase . isOfficial {
t . Errorf ( "Test %d: Expected %v but got %v" ,
i + 1 , testCase . isOfficial , err == nil )
}
}
}
func TestReleaseTagToNFromTimeConversion ( t * testing . T ) {
utcLoc , _ := time . LoadLocation ( "" )
testCases := [ ] struct {
t time . Time
tag string
errStr string
} {
{ time . Date ( 2017 , time . September , 29 , 19 , 16 , 56 , 0 , utcLoc ) ,
"RELEASE.2017-09-29T19-16-56Z" , "" } ,
{ time . Date ( 2017 , time . August , 5 , 0 , 0 , 53 , 0 , utcLoc ) ,
"RELEASE.2017-08-05T00-00-53Z" , "" } ,
{ time . Now ( ) . UTC ( ) , "2017-09-29T19:16:56Z" ,
"2017-09-29T19:16:56Z is not a valid release tag" } ,
{ time . Now ( ) . UTC ( ) , "DEVELOPMENT.GOGET" ,
"DEVELOPMENT.GOGET is not a valid release tag" } ,
}
for i , testCase := range testCases {
if testCase . errStr != "" {
got := releaseTimeToReleaseTag ( testCase . t )
if got != testCase . tag && testCase . errStr == "" {
t . Errorf ( "Test %d: Expected %v but got %v" , i + 1 , testCase . tag , got )
}
}
tagTime , err := releaseTagToReleaseTime ( testCase . tag )
if err != nil && err . Error ( ) != testCase . errStr {
t . Errorf ( "Test %d: Expected %v but got %v" , i + 1 , testCase . errStr , err . Error ( ) )
}
if err == nil && tagTime != testCase . t {
t . Errorf ( "Test %d: Expected %v but got %v" , i + 1 , testCase . t , tagTime )
}
}
}
func TestDownloadURL ( t * testing . T ) {
sci := os . Getenv ( "MINIO_CI_CD" )
os . Setenv ( "MINIO_CI_CD" , "" )
defer os . Setenv ( "MINIO_CI_CD" , sci )
minioVersion1 := releaseTimeToReleaseTag ( UTCNow ( ) )
durl := getDownloadURL ( minioVersion1 )
if IsDocker ( ) {
if durl != "docker pull minio/minio:" + minioVersion1 {
t . Errorf ( "Expected %s, got %s" , "docker pull minio/minio:" + minioVersion1 , durl )
}
} else {
if runtime . GOOS == "windows" {
if durl != minioReleaseURL + "minio.exe" {
t . Errorf ( "Expected %s, got %s" , minioReleaseURL + "minio.exe" , durl )
}
} else {
if durl != minioReleaseURL + "minio" {
t . Errorf ( "Expected %s, got %s" , minioReleaseURL + "minio" , durl )
}
}
}
os . Setenv ( "KUBERNETES_SERVICE_HOST" , "10.11.148.5" )
durl = getDownloadURL ( minioVersion1 )
if durl != kubernetesDeploymentDoc {
t . Errorf ( "Expected %s, got %s" , kubernetesDeploymentDoc , durl )
}
os . Unsetenv ( "KUBERNETES_SERVICE_HOST" )
os . Setenv ( "MESOS_CONTAINER_NAME" , "mesos-1111" )
durl = getDownloadURL ( minioVersion1 )
if durl != mesosDeploymentDoc {
t . Errorf ( "Expected %s, got %s" , mesosDeploymentDoc , durl )
}
os . Unsetenv ( "MESOS_CONTAINER_NAME" )
}
// Tests user agent string.
func TestUserAgent ( t * testing . T ) {
testCases := [ ] struct {
envName string
envValue string
mode string
expectedStr string
} {
{
envName : "" ,
envValue : "" ,
mode : globalMinioModeFS ,
expectedStr : fmt . Sprintf ( "MinIO (%s; %s; %s; source) MinIO/DEVELOPMENT.GOGET MinIO/DEVELOPMENT.GOGET MinIO/DEVELOPMENT.GOGET" , runtime . GOOS , runtime . GOARCH , globalMinioModeFS ) ,
} ,
{
envName : "MESOS_CONTAINER_NAME" ,
envValue : "mesos-11111" ,
mode : globalMinioModeErasure ,
expectedStr : fmt . Sprintf ( "MinIO (%s; %s; %s; %s; source) MinIO/DEVELOPMENT.GOGET MinIO/DEVELOPMENT.GOGET MinIO/DEVELOPMENT.GOGET MinIO/universe-%s" , runtime . GOOS , runtime . GOARCH , globalMinioModeErasure , "dcos" , "mesos-1111" ) ,
} ,
{
envName : "KUBERNETES_SERVICE_HOST" ,
envValue : "10.11.148.5" ,
mode : globalMinioModeErasure ,
expectedStr : fmt . Sprintf ( "MinIO (%s; %s; %s; %s; source) MinIO/DEVELOPMENT.GOGET MinIO/DEVELOPMENT.GOGET MinIO/DEVELOPMENT.GOGET" , runtime . GOOS , runtime . GOARCH , globalMinioModeErasure , "kubernetes" ) ,
} ,
}
for i , testCase := range testCases {
sci := os . Getenv ( "MINIO_CI_CD" )
os . Setenv ( "MINIO_CI_CD" , "" )
os . Setenv ( testCase . envName , testCase . envValue )
if testCase . envName == "MESOS_CONTAINER_NAME" {
os . Setenv ( "MARATHON_APP_LABEL_DCOS_PACKAGE_VERSION" , "mesos-1111" )
}
str := getUserAgent ( testCase . mode )
expectedStr := testCase . expectedStr
if IsDocker ( ) {
expectedStr = strings . Replace ( expectedStr , "; source" , "; docker; source" , - 1 )
}
if str != expectedStr {
t . Errorf ( "Test %d: expected: %s, got: %s" , i + 1 , expectedStr , str )
}
os . Setenv ( "MINIO_CI_CD" , sci )
os . Unsetenv ( "MARATHON_APP_LABEL_DCOS_PACKAGE_VERSION" )
os . Unsetenv ( testCase . envName )
}
}
// Tests if the environment we are running is in DCOS.
func TestIsDCOS ( t * testing . T ) {
sci := os . Getenv ( "MINIO_CI_CD" )
os . Setenv ( "MINIO_CI_CD" , "" )
defer os . Setenv ( "MINIO_CI_CD" , sci )
os . Setenv ( "MESOS_CONTAINER_NAME" , "mesos-1111" )
dcos := IsDCOS ( )
if ! dcos {
t . Fatalf ( "Expected %t, got %t" , true , dcos )
}
os . Unsetenv ( "MESOS_CONTAINER_NAME" )
dcos = IsDCOS ( )
if dcos {
t . Fatalf ( "Expected %t, got %t" , false , dcos )
}
}
// Tests if the environment we are running is in kubernetes.
func TestIsKubernetes ( t * testing . T ) {
sci := os . Getenv ( "MINIO_CI_CD" )
os . Setenv ( "MINIO_CI_CD" , "" )
defer os . Setenv ( "MINIO_CI_CD" , sci )
os . Setenv ( "KUBERNETES_SERVICE_HOST" , "10.11.148.5" )
kubernetes := IsKubernetes ( )
if ! kubernetes {
t . Fatalf ( "Expected %t, got %t" , true , kubernetes )
}
os . Unsetenv ( "KUBERNETES_SERVICE_HOST" )
kubernetes = IsKubernetes ( )
if kubernetes {
t . Fatalf ( "Expected %t, got %t" , false , kubernetes )
}
}
// Tests if the environment we are running is Helm chart.
func TestGetHelmVersion ( t * testing . T ) {
createTempFile := func ( content string ) string {
tmpfile , err := ioutil . TempFile ( "" , "helm-testfile-" )
if err != nil {
t . Fatalf ( "Unable to create temporary file. %s" , err )
}
if _ , err = tmpfile . Write ( [ ] byte ( content ) ) ; err != nil {
t . Fatalf ( "Unable to create temporary file. %s" , err )
}
if err = tmpfile . Close ( ) ; err != nil {
t . Fatalf ( "Unable to create temporary file. %s" , err )
}
return tmpfile . Name ( )
}
filename := createTempFile (
` app = "virtuous-rat-minio"
chart = "minio-0.1.3"
heritage = "Tiller"
pod - template - hash = "818089471" ` )
defer os . Remove ( filename )
testCases := [ ] struct {
filename string
expectedResult string
} {
{ "" , "" } ,
{ "/tmp/non-existing-file" , "" } ,
{ filename , "minio-0.1.3" } ,
}
for _ , testCase := range testCases {
result := getHelmVersion ( testCase . filename )
if testCase . expectedResult != result {
t . Fatalf ( "result: expected: %v, got: %v" , testCase . expectedResult , result )
}
}
}
func TestDownloadReleaseData ( t * testing . T ) {
httpServer1 := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) { } ) )
defer httpServer1 . Close ( )
httpServer2 := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
fmt . Fprintln ( w , "fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z" )
} ) )
defer httpServer2 . Close ( )
httpServer3 := httptest . NewServer ( http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
http . Error ( w , "" , http . StatusNotFound )
} ) )
defer httpServer3 . Close ( )
testCases := [ ] struct {
releaseChecksumURL string
expectedResult string
expectedErr error
} {
{ httpServer1 . URL , "" , nil } ,
{ httpServer2 . URL , "fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z\n" , nil } ,
{ httpServer3 . URL , "" , fmt . Errorf ( "Error downloading URL " + httpServer3 . URL + ". Response: 404 Not Found" ) } ,
}
for _ , testCase := range testCases {
result , err := downloadReleaseURL ( testCase . releaseChecksumURL , 1 * time . Second , "" )
if testCase . expectedErr == nil {
if err != nil {
t . Fatalf ( "error: expected: %v, got: %v" , testCase . expectedErr , err )
}
} else if err == nil {
t . Fatalf ( "error: expected: %v, got: %v" , testCase . expectedErr , err )
} else if testCase . expectedErr . Error ( ) != err . Error ( ) {
t . Fatalf ( "error: expected: %v, got: %v" , testCase . expectedErr , err )
}
if testCase . expectedResult != result {
t . Fatalf ( "result: expected: %v, got: %v" , testCase . expectedResult , result )
}
}
}
func TestParseReleaseData ( t * testing . T ) {
releaseTime , _ := releaseTagToReleaseTime ( "RELEASE.2016-10-07T01-16-39Z" )
testCases := [ ] struct {
data string
expectedResult time . Time
expectedSha256hex string
expectedErr error
} {
{ "more than two fields" , time . Time { } , "" , fmt . Errorf ( "Unknown release data `more than two fields`" ) } ,
{ "more than" , time . Time { } , "" , fmt . Errorf ( "Unknown release information `than`" ) } ,
{ "more than.two.fields" , time . Time { } , "" , fmt . Errorf ( "Unknown release `than.two.fields`" ) } ,
{ "more minio.RELEASE.fields" , time . Time { } , "" , fmt . Errorf ( ` Unknown release tag format. parsing time "fields" as "2006-01-02T15-04-05Z": cannot parse "fields" as "2006" ` ) } ,
{ "more minio.RELEASE.2016-10-07T01-16-39Z" , releaseTime , "more" , nil } ,
{ "fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z\n" , releaseTime , "fbe246edbd382902db9a4035df7dce8cb441357d" , nil } ,
{ "fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z.customer-hotfix\n" , releaseTime , "fbe246edbd382902db9a4035df7dce8cb441357d" , nil } ,
}
for i , testCase := range testCases {
sha256Hex , result , err := parseReleaseData ( testCase . data )
if testCase . expectedErr == nil {
if err != nil {
t . Errorf ( "error case %d: expected: %v, got: %v" , i + 1 , testCase . expectedErr , err )
}
} else if err == nil {
t . Errorf ( "error case %d: expected: %v, got: %v" , i + 1 , testCase . expectedErr , err )
} else if testCase . expectedErr . Error ( ) != err . Error ( ) {
t . Errorf ( "error case %d: expected: %v, got: %v" , i + 1 , testCase . expectedErr , err )
}
if err == nil {
if sha256Hex != testCase . expectedSha256hex {
t . Errorf ( "case %d: result: expected: %v, got: %v" , i + 1 , testCase . expectedSha256hex , sha256Hex )
}
if ! testCase . expectedResult . Equal ( result ) {
t . Errorf ( "case %d: result: expected: %v, got: %v" , i + 1 , testCase . expectedResult , result )
}
}
}
}