swift/go/hummingbird/utils_test.go

325 lines
9.8 KiB
Go

// Copyright (c) 2015 Rackspace
//
// 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 hummingbird
import (
"bytes"
"io/ioutil"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestParseRange(t *testing.T) {
//Setting up individual test data
tests := []struct {
fileSize int64
rangeHeader string
exError string
exRanges []httpRange
}{
{12345, "bytes=12346-123457", "Unsatisfiable range", nil},
{12345, "bytes=12346-", "Unsatisfiable range", nil},
{12345, " ", "", nil},
{12345, "nonbytes=1-2", "", nil},
{12345, "bytes=", "", nil},
{12345, "bytes=-", "", nil},
{12345, "bytes=-cv", "", nil},
{12345, "bytes=cv-", "", nil},
{12345, "bytes=-12346", "", []httpRange{httpRange{0, 12345}}},
{12345, "bytes=-12345", "", []httpRange{httpRange{0, 12345}}},
{12345, "bytes=-12344", "", []httpRange{httpRange{1, 12345}}},
{12345, "bytes=12344-", "", []httpRange{httpRange{12344, 12345}}},
{12345, "bytes=12344-cv", "", nil},
{12345, "bytes=13-12", "", nil},
{12345, "bytes=cv-12345", "", nil},
{12345, "bytes=12342-12343", "", []httpRange{httpRange{12342, 12344}}},
{12345, "bytes=12342-12344", "", []httpRange{httpRange{12342, 12345}}},
{12345, "bytes=12342-12345", "", []httpRange{httpRange{12342, 12345}}},
{12345, "bytes=0-1,2-3", "", []httpRange{httpRange{0, 2}, httpRange{2, 4}}},
{12345, "bytes=0-1,x-x", "", nil},
{12345, "bytes=0-1,x-x,2-3", "", nil},
{12345, "bytes=0-1,x-", "", nil},
{12345, "bytes=0-1,2-3,4-5", "", []httpRange{httpRange{0, 2}, httpRange{2, 4}, httpRange{4, 6}}},
{10000, "bytes=0-99,200-299,10000-10099", "", []httpRange{httpRange{0, 100}, httpRange{200, 300}}},
{10000, "bytes=-0", "Unsatisfiable range", nil},
{10000, "bytes=-0", "Unsatisfiable range", nil},
{10000, "bytes=0-1,-0", "", []httpRange{httpRange{0, 2}}},
{0, "bytes=-0", "Unsatisfiable range", nil},
{0, "bytes=0-", "Unsatisfiable range", nil},
{0, "bytes=0-1", "Unsatisfiable range", nil},
{10000, "bytes=0-1,1-2,2-3,3-4,4-5,5-6,6-7,7-8,8-9,9-10,10-11,11-12,12-13,13-14,14-15,15-16,16-17," +
"17-18,18-19,19-20,20-21,21-22,22-23,23-24,24-25,25-26,26-27,27-28,28-29,29-30,30-31,31-32," +
"32-33,33-34,34-35,35-36,36-37,37-38,38-39,39-40,40-41,41-42,42-43,43-44,44-45,45-46,46-47," +
"47-48,48-49,49-50,50-51,51-52,52-53,53-54,54-55,55-56,56-57,57-58,58-59,59-60,60-61,61-62," +
"62-63,63-64,64-65,65-66,66-67,67-68,68-69,69-70,70-71,71-72,72-73,73-74,74-75,75-76,76-77," +
"77-78,78-79,79-80,80-81,81-82,82-83,83-84,84-85,85-86,86-87,87-88,88-89,89-90,90-91,91-92," +
"92-93,93-94,94-95,95-96,96-97,97-98,98-99,99-100,100-101", "Too many ranges", nil},
}
//Run tests with data from above
for _, test := range tests {
result, err := ParseRange(test.rangeHeader, test.fileSize)
if test.rangeHeader == " " {
require.Nil(t, result, test.rangeHeader)
require.Nil(t, err, test.rangeHeader)
continue
}
if test.exError == "" {
require.Nil(t, err, test.rangeHeader)
} else {
require.NotNil(t, err, test.rangeHeader)
require.Equal(t, test.exError, err.Error(), test.rangeHeader)
}
require.Equal(t, len(result), len(test.exRanges), test.rangeHeader)
for i, _ := range result {
require.Equal(t, test.exRanges[i], result[i], test.rangeHeader)
}
}
}
func TestParseDate(t *testing.T) {
//Setup tests with individual data
tests := []string{
"Mon, 02 Jan 2006 15:04:05 MST",
"Mon, 02 Jan 2006 15:04:05 -0700",
"Mon Jan 02 15:04:05 2006",
"Monday, 02-Jan-06 15:04:05 MST",
"1136214245",
"1136214245.1234",
"2006-01-02 15:04:05",
}
//Run Tests from above
for _, timestamp := range tests {
timeResult, err := ParseDate(timestamp)
if err == nil {
assert.Equal(t, timeResult.Day(), 2)
assert.Equal(t, timeResult.Month(), time.Month(1))
assert.Equal(t, timeResult.Year(), 2006)
assert.Equal(t, timeResult.Hour(), 15)
assert.Equal(t, timeResult.Minute(), 4)
assert.Equal(t, timeResult.Second(), 5)
} else {
assert.Equal(t, err.Error(), "invalid time")
}
}
}
func TestStandardizeTimestamp(t *testing.T) {
//Setup tests with individual data
tests := []struct {
timestamp string
expectedResult string
}{
{"12345.12345", "0000012345.12345"},
{"12345.1234", "0000012345.12340"},
{"12345.1234_123455", "0000012345.12340_0000000000123455"},
{"12345.12343_12345a", "0000012345.12343_000000000012345a"},
}
//Run Tests from above
for _, test := range tests {
result, _ := StandardizeTimestamp(test.timestamp)
assert.Equal(t, test.expectedResult, result)
}
}
func TestStandardizeTimestamp_invalidTimestamp(t *testing.T) {
//Setup test data
tests := []struct {
timestamp string
errorMsg string
}{
{"invalidTimestamp", "Could not parse float from 'invalidTimestamp'."},
{"1234.1234_invalidOffset", "Could not parse int from 'invalidOffset'."},
}
for _, test := range tests {
_, err := StandardizeTimestamp(test.timestamp)
assert.Equal(t, err.Error(), test.errorMsg)
}
}
func TestGetEpochFromTimestamp(t *testing.T) {
//Setup tests with individual data
tests := []struct {
timestamp string
expectedResult string
}{
{"12345.12345", "0000012345.12345"},
{"12345.1234", "0000012345.12340"},
{"12345.1234_123455", "0000012345.12340"},
{"12345.12343_12345a", "0000012345.12343"},
}
//Run Tests from above
for _, test := range tests {
result, _ := GetEpochFromTimestamp(test.timestamp)
assert.Equal(t, test.expectedResult, result)
}
}
func TestGetEpochFromTimestamp_invalidTimestamp(t *testing.T) {
_, err := GetEpochFromTimestamp("invalidTimestamp")
assert.Equal(t, err.Error(), "Could not parse float from 'invalidTimestamp'.")
}
func TestParseTimestamp(t *testing.T) {
tests := []string{
"2006-01-02 15:04:05",
"Mon, 02 Jan 2006 15:04:05 MST",
}
for _, timestamp := range tests {
timeResult, err := FormatTimestamp(timestamp)
if err != nil {
assert.Equal(t, err.Error(), "invalid time")
assert.Empty(t, timeResult)
} else {
assert.Equal(t, "2006-01-02T15:04:05", timeResult)
}
}
}
func TestLooksTrue(t *testing.T) {
tests := []string{
"true ", "true", "t", "yes", "y", "1", "on",
}
for _, test := range tests {
assert.True(t, LooksTrue(test))
}
}
func TestUrlencode(t *testing.T) {
assert.True(t, Urlencode("HELLO%2FTHERE") == "HELLO%252FTHERE")
assert.True(t, Urlencode("HELLOTHERE") == "HELLOTHERE")
assert.True(t, Urlencode("HELLO THERE, YOU TWO//\x00\xFF") == "HELLO%20THERE%2C%20YOU%20TWO//%00%FF")
assert.True(t, Urlencode("鐋댋") == "%E9%90%8B%EB%8C%8B")
}
func TestIsMount(t *testing.T) {
isMount, err := IsMount("/dev")
assert.Nil(t, err)
assert.True(t, isMount)
isMount, err = IsMount(".")
assert.Nil(t, err)
assert.False(t, isMount)
isMount, err = IsMount("/slartibartfast")
assert.NotNil(t, err)
}
func TestIsNotDir(t *testing.T) {
tempFile, _ := ioutil.TempFile("", "INI")
defer os.RemoveAll(tempFile.Name())
_, err := ioutil.ReadDir(tempFile.Name())
assert.True(t, IsNotDir(err))
_, err = ioutil.ReadDir("/aseagullstolemysailorhat")
assert.True(t, IsNotDir(err))
}
func TestCopy(t *testing.T) {
src := bytes.NewBuffer([]byte("WELL HELLO THERE"))
dst1 := &bytes.Buffer{}
dst2 := &bytes.Buffer{}
Copy(src, dst1, dst2)
assert.Equal(t, []byte("WELL HELLO THERE"), dst1.Bytes())
assert.Equal(t, []byte("WELL HELLO THERE"), dst2.Bytes())
}
func TestCopyN(t *testing.T) {
src := bytes.NewBuffer([]byte("WELL HELLO THERE"))
dst1 := &bytes.Buffer{}
dst2 := &bytes.Buffer{}
CopyN(src, 10, dst1, dst2)
assert.Equal(t, []byte("WELL HELLO"), dst1.Bytes())
assert.Equal(t, []byte("WELL HELLO"), dst2.Bytes())
}
func TestWriteFileAtomic(t *testing.T) {
tempFile, _ := ioutil.TempFile("", "INI")
defer os.RemoveAll(tempFile.Name())
WriteFileAtomic(tempFile.Name(), []byte("HI THERE"), 0600)
fi, err := os.Stat(tempFile.Name())
assert.Nil(t, err)
assert.Equal(t, 8, int(fi.Size()))
}
func TestReadDirNames(t *testing.T) {
tempDir, _ := ioutil.TempDir("", "RDN")
defer os.RemoveAll(tempDir)
ioutil.WriteFile(tempDir+"/Z", []byte{}, 0666)
ioutil.WriteFile(tempDir+"/X", []byte{}, 0666)
ioutil.WriteFile(tempDir+"/Y", []byte{}, 0666)
fileNames, err := ReadDirNames(tempDir)
assert.Nil(t, err)
assert.Equal(t, fileNames, []string{"X", "Y", "Z"})
}
func fakeHashPrefixAndSuffix() (filename string, err error) {
var config_source []byte = []byte(
"[swift-hash]\n" +
"swift_hash_path_suffix = 983abc1de3ff4258\n")
tempFile, err := ioutil.TempFile("", "swift.conf-")
if err != nil {
return "", err
}
ioutil.WriteFile(tempFile.Name(), config_source, 0600)
configLocations = []string{tempFile.Name()}
return tempFile.Name(), nil
}
func TestGetHashPrefixAndSuffix(t *testing.T) {
swift_conf_name, err := fakeHashPrefixAndSuffix()
assert.Nil(t, err)
defer os.Remove(swift_conf_name)
_, suffix, err := GetHashPrefixAndSuffix()
assert.Nil(t, err, "Error getting hash path prefix or suffix")
if suffix == "" {
t.Error("Error prefix and suffix not being set")
}
}
func TestLockPath(t *testing.T) {
tempDir, err := ioutil.TempDir("", "")
defer os.RemoveAll(tempDir)
require.Nil(t, err)
c := make(chan bool)
ended := make(chan struct{})
defer close(ended)
go func() {
f, err := LockPath(tempDir, time.Millisecond)
c <- true
require.Nil(t, err)
require.NotNil(t, f)
defer f.Close()
select {
case <-time.After(time.Second):
case <-ended:
}
}()
<-c
f, err := LockPath(tempDir, time.Millisecond)
require.Nil(t, f)
require.NotNil(t, err)
}