<commit_before>/*
Copyright 2014 Google Inc. All rights reserved.

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 aws_cloud

import (
	"reflect"
	"strings"
	"testing"

	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/ec2"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
)

func TestReadAWSCloudConfig(t *testing.T) {
	_, err1 := readAWSCloudConfig(nil, nil)
	if err1 == nil {
		t.Errorf("Should error when no config reader is given")
	}

	_, err2 := readAWSCloudConfig(strings.NewReader(""), nil)
	if err2 == nil {
		t.Errorf("Should error when config is empty")
	}

	_, err3 := readAWSCloudConfig(strings.NewReader("[global]\n"), nil)
	if err3 == nil {
		t.Errorf("Should error when no zone is specified")
	}

	cfg, err4 := readAWSCloudConfig(strings.NewReader("[global]\nzone = eu-west-1a"), nil)
	if err4 != nil {
		t.Errorf("Should succeed when a zone is specified: %s", err4)
	}
	if cfg.Global.Zone != "eu-west-1a" {
		t.Errorf("Should read zone from config")
	}

	_, err5 := readAWSCloudConfig(strings.NewReader("[global]\n"), &FakeMetadata{})
	if err5 == nil {
		t.Errorf("Should error when no zone is specified in metadata")
	}

	cfg, err6 := readAWSCloudConfig(strings.NewReader("[global]\n"),
		&FakeMetadata{availabilityZone: "eu-west-1a"})
	if err6 != nil {
		t.Errorf("Should succeed when getting zone from metadata: %s", err6)
	}
	if cfg.Global.Zone != "eu-west-1a" {
		t.Errorf("Should read zone from metadata")
	}

	cfg, err7 := readAWSCloudConfig(strings.NewReader("[global]\nzone = us-east-1a"),
		&FakeMetadata{availabilityZone: "eu-west-1a"})
	if err7 != nil {
		t.Errorf("Should succeed when zone is specified: %s", err7)
	}
	if cfg.Global.Zone != "us-east-1a" {
		t.Errorf("Should prefer zone from config over metadata")
	}
}

func TestNewAWSCloud(t *testing.T) {
	fakeAuthFunc := func() (auth aws.Auth, err error) {
		return aws.Auth{"", "", ""}, nil
	}

	_, err1 := newAWSCloud(nil, fakeAuthFunc, nil)
	if err1 == nil {
		t.Errorf("Should error when no config reader is given")
	}

	_, err2 := newAWSCloud(strings.NewReader(
		"[global]\nzone = blahonga"),
		fakeAuthFunc, nil)
	if err2 == nil {
		t.Errorf("Should error when config specifies invalid zone")
	}

	_, err3 := newAWSCloud(
		strings.NewReader("[global]\nzone = eu-west-1a"),
		fakeAuthFunc, nil)
	if err3 != nil {
		t.Errorf("Should succeed when a valid zone is specified: %s", err3)
	}

	_, err4 := newAWSCloud(strings.NewReader(
		"[global]\n"),
		fakeAuthFunc, &FakeMetadata{availabilityZone: "us-east-1a"})
	if err4 != nil {
		t.Errorf("Should success when zone is in metadata")
	}

	_, err5 := newAWSCloud(strings.NewReader(
		"[global]\n"),
		fakeAuthFunc, &FakeMetadata{})
	if err5 == nil {
		t.Errorf("Should error when AZ cannot be found in metadata")
	}
}

type FakeEC2 struct {
	instances []ec2.Instance
}

func (self *FakeEC2) Instances(instanceIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error) {
	matches := []ec2.Instance{}
	for _, instance := range self.instances {
		if filter == nil || filter.Matches(instance) {
			matches = append(matches, instance)
		}
	}
	return &ec2.InstancesResp{"",
		[]ec2.Reservation{
			{"", "", "", nil, matches}}}, nil
}

type FakeMetadata struct {
	availabilityZone string<commit_msg>Make some of the more repetitive AWS tests table-driven<commit_after>/*
Copyright 2014 Google Inc. All rights reserved.

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 aws_cloud

import (
	"io"
	"reflect"
	"strings"
	"testing"

	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/ec2"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
)

func TestReadAWSCloudConfig(t *testing.T) {
	tests := []struct {
		name string

		reader   io.Reader
		metadata AWSMetadata

		expectError bool
		zone        string
	}{
		{
			"No config reader",
			nil, nil,
			true, "",
		},
		{
			"Empty config, no metadata",
			strings.NewReader(""), nil,
			true, "",
		},
		{
			"No zone in config, no metadata",
			strings.NewReader("[global]\n"), nil,
			true, "",
		},
		{
			"Zone in config, no metadata",
			strings.NewReader("[global]\nzone = eu-west-1a"), nil,
			false, "eu-west-1a",
		},
		{
			"No zone in config, metadata does not have zone",
			strings.NewReader("[global]\n"), &FakeMetadata{},
			true, "",
		},
		{
			"No zone in config, metadata has zone",
			strings.NewReader("[global]\n"), &FakeMetadata{availabilityZone: "eu-west-1a"},
			false, "eu-west-1a",
		},
		{
			"Zone in config should take precedence over metadata",
			strings.NewReader("[global]\nzone = us-east-1a"), &FakeMetadata{availabilityZone: "eu-west-1a"},
			false, "us-east-1a",
		},
	}

	for _, test := range tests {
		t.Logf("Running test case %s", test.name)
		cfg, err := readAWSCloudConfig(test.reader, test.metadata)
		if test.expectError {
			if err == nil {
				t.Errorf("Should error for case %s", test.name)
			}
		} else {
			if err != nil {
				t.Errorf("Should succeed for case: %s", test.name)
			}
			if cfg.Global.Zone != test.zone {
				t.Errorf("Incorrect zone value (%s vs %s) for case: %s",
					cfg.Global.Zone, test.zone, test.name)
			}
		}
	}
}

func TestNewAWSCloud(t *testing.T) {
	fakeAuthFunc := func() (auth aws.Auth, err error) {
		return aws.Auth{"", "", ""}, nil
	}

	tests := []struct {
		name string

		reader   io.Reader
		authFunc AuthFunc
		metadata AWSMetadata

		expectError bool
		zone        string
	}{
		{
			"No config reader",
			nil, fakeAuthFunc, nil,
			true, "",
		},
		{
			"Config specified invalid zone",
			strings.NewReader("[global]\nzone = blahonga"), fakeAuthFunc, nil,
			true, "",
		},
		{
			"Config specifies valid zone",
			strings.NewReader("[global]\nzone = eu-west-1a"), fakeAuthFunc, nil,
			false, "eu-west-1a",
		},
		{
			"Gets zone from metadata when not in config",

			strings.NewReader("[global]\n"),
			fakeAuthFunc,
			&FakeMetadata{availabilityZone: "us-east-1a"},

			false, "us-east-1a",
		},
		{
			"No zone in config or metadata",
			strings.NewReader("[global]\n"), fakeAuthFunc, &FakeMetadata{},
			true, "",
		},
	}

	for _, test := range tests {
		t.Logf("Running test case %s", test.name)
		c, err := newAWSCloud(test.reader, test.authFunc, test.metadata)
		if test.expectError {
			if err == nil {
				t.Errorf("Should error for case %s", test.name)
			}
		} else {
			if err != nil {
				t.Errorf("Should succeed for case: %s", test.name)
			}
			if c.availabilityZone != test.zone {
				t.Errorf("Incorrect zone value (%s vs %s) for case: %s",
					c.availabilityZone, test.zone, test.name)
			}
		}
	}
}

type FakeEC2 struct {
	instances []ec2.Instance
}

func (self *FakeEC2) Instances(instanceIds []string, filter *ec2InstanceFilter) (resp *ec2.InstancesResp, err error) {
	matches := []ec2.Instance{}
	for _, instance := range self.instances {
		if filter == nil || filter.Matches(instance) {
			matches = append(matches, instance)
		}
	}
	return &ec2.InstancesResp{"",
		[]ec2.Reservation{
			{"", "", "", nil, matches}}}, nil
}

type FakeMetadata struct {
	availabilityZone string
{'fraction_non_alphanumeric': 0.14312084666502584, 'fraction_numerical': 0.010091065714988924, 'mean_word_length': 3.7526315789473683, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '952238', 'n_tokens_mistral': 3002, 'n_tokens_neox': 2737, 'n_words': 770}