blob: 84295ec64bc7592b8f9351c1bfb052594e49071a [file] [log] [blame]
// Copyright 2018 The LUCI 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 ensure
import (
"bytes"
"fmt"
"strings"
"testing"
"go.chromium.org/luci/cipd/common"
. "github.com/smartystreets/goconvey/convey"
. "go.chromium.org/luci/common/testing/assertions"
)
func TestVersionsFile(t *testing.T) {
t.Parallel()
const (
iid1 = "11111joOfFfFcq7fHCKAIrU34oeFAT174Bf8eHMajMUC"
iid2 = "22222joOfFfFcq7fHCKAIrU34oeFAT174Bf8eHMajMUC"
)
Convey("Setter/getter", t, func() {
v := VersionsFile{}
_, err := v.ResolveVersion("pkg", "ver")
So(err, ShouldErrLike, "not in the versions file")
So(v.AddVersion("pkg", "ver", iid1), ShouldBeNil)
So(v.AddVersion("pkg", iid1, iid1), ShouldBeNil) // noop
So(v, ShouldHaveLength, 1)
pin, err := v.ResolveVersion("pkg", "ver")
So(err, ShouldBeNil)
So(pin, ShouldResemble, common.Pin{
PackageName: "pkg",
InstanceID: iid1,
})
pin, err = v.ResolveVersion("other-pkg", iid1)
So(err, ShouldBeNil)
So(pin, ShouldResemble, common.Pin{
PackageName: "other-pkg",
InstanceID: iid1,
})
})
Convey("AddVersion errors", t, func() {
v := VersionsFile{}
So(v.AddVersion("???", "ver", iid1), ShouldErrLike, "invalid package name")
So(v.AddVersion("pkg", "???", iid1), ShouldErrLike, "bad version")
So(v.AddVersion("pkg", "ver", "not-id"), ShouldErrLike, "not a valid package instance ID")
So(v.AddVersion("pkg", iid1, iid2), ShouldErrLike, "should resolve into that ID")
})
Convey("Equal", t, func() {
v1 := VersionsFile{
{"pkg1", "ver1"}: iid1,
{"pkg1", "ver2"}: iid2,
}
v2 := VersionsFile{
{"pkg1", "ver1"}: iid1,
{"pkg1", "ver2"}: iid1,
}
v3 := VersionsFile{
{"pkg1", "ver1"}: iid1,
}
So(v1.Equal(v1), ShouldBeTrue)
So(v1.Equal(v2), ShouldBeFalse)
So(v1.Equal(v3), ShouldBeFalse)
})
Convey("Serialization and successful parsing", t, func() {
testVersion := VersionsFile{
{"pkg1", "ver1"}: iid1,
{"pkg1", "ver2"}: iid1,
{"pkg2", "tag:works"}: iid2,
}
expectedSerialization := fmt.Sprintf(`# This file is auto-generated by 'cipd ensure-file-resolve'.
# Do not modify manually. All changes will be overwritten.
pkg1
ver1
%s
pkg1
ver2
%s
pkg2
tag:works
%s
`, iid1, iid1, iid2)
Convey("Serialization", func() {
b := bytes.Buffer{}
So(testVersion.Serialize(&b), ShouldBeNil)
So(b.String(), ShouldEqual, expectedSerialization)
})
Convey("Parsing success", func() {
v, err := ParseVersionsFile(strings.NewReader(expectedSerialization))
So(err, ShouldBeNil)
So(v, ShouldResemble, testVersion)
})
Convey("Parsing empty", func() {
v, err := ParseVersionsFile(strings.NewReader(""))
So(err, ShouldBeNil)
So(v, ShouldResemble, VersionsFile{})
})
Convey("Parsing one", func() {
v, err := ParseVersionsFile(strings.NewReader(fmt.Sprintf("pkg\nver\n%s", iid1)))
So(err, ShouldBeNil)
So(v, ShouldResemble, VersionsFile{
{"pkg", "ver"}: iid1,
})
})
Convey("Many new lines", func() {
v, err := ParseVersionsFile(strings.NewReader(
fmt.Sprintf("pkg\nver1\n%s\n\n\npkg\nver2\n%s", iid1, iid2)))
So(err, ShouldBeNil)
So(v, ShouldResemble, VersionsFile{
{"pkg", "ver1"}: iid1,
{"pkg", "ver2"}: iid2,
})
})
})
Convey("Parsing errors", t, func() {
p := func(text string, args ...interface{}) error {
v, err := ParseVersionsFile(strings.NewReader(fmt.Sprintf(text, args...)))
So(err, ShouldNotBeNil)
So(v, ShouldBeNil)
return err
}
Convey("Bad format of identifiers", func() {
So(p("???\nver\n%s", iid1), ShouldErrLike,
"failed to parse versions file (line 1): invalid package name")
So(p("pkg\n???\n%s", iid1), ShouldErrLike,
"failed to parse versions file (line 2): bad version")
So(p("pkg\nver\nnotid"), ShouldErrLike,
"failed to parse versions file (line 3): not a valid package instance ID")
})
Convey("Unexpected empty line", func() {
So(p("pkg\n\nver\n%s\n", iid1), ShouldErrLike,
"failed to parse versions file (line 2): expecting a version name, not a new line")
So(p("pkg\nver\n\n%s\n", iid1), ShouldErrLike,
"failed to parse versions file (line 3): expecting an instance ID, not a new line")
})
Convey("Unexpected EOF", func() {
So(p("pkg\n"), ShouldErrLike,
"failed to parse versions file (line 1): unexpected EOF, expecting a package version")
So(p("pkg\nver\n"), ShouldErrLike,
"failed to parse versions file (line 2): unexpected EOF, expecting an instance ID")
})
Convey("Unexpected line after the triple", func() {
So(p("pkg\nver\n%s\nsomething", iid1), ShouldErrLike,
"failed to parse versions file (line 4): expecting an empty line between each version definition triple")
})
})
}