<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package addressupdater

import (
	stderrors "errors"
	"fmt"
	"math"
	"sync"
	"sync/atomic"
	"time"

	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/errors"
	"launchpad.net/juju-core/instance"
	"launchpad.net/juju-core/state"
	coretesting "launchpad.net/juju-core/testing"
	jc "launchpad.net/juju-core/testing/checkers"
	"launchpad.net/juju-core/testing/testbase"
)

var _ = gc.Suite(&machineSuite{})

type machineSuite struct {
	testbase.LoggingSuite
}

var testAddrs = []instance.Address{instance.NewAddress("127.0.0.1")}

func (*machineSuite) TestSetsAddressInitially(c *gc.C) {
	context := &testMachineContext{
		getAddresses: addressesGetter(c, "i1234", testAddrs, nil),
		dyingc:       make(chan struct{}),
	}
	m := &testMachine{
		id:         "99",
		instanceId: "i1234",
		refresh:    func() error { return nil },
		life:       state.Alive,
	}
	died := make(chan machine)
	// Change the poll intervals to be short, so that we know
	// that we've polled (probably) at least a few times.
	defer testbase.PatchValue(&ShortPoll, coretesting.ShortWait/10).Restore()
	defer testbase.PatchValue(&LongPoll, coretesting.ShortWait/10).Restore()

	go runMachine(context, m, nil, died)
	time.Sleep(coretesting.ShortWait)

	killMachineLoop(c, m, context.dyingc, died)
	c.Assert(context.killAllErr, gc.Equals, nil)
	c.Assert(m.addresses, gc.DeepEquals, testAddrs)
	c.Assert(m.setAddressCount, gc.Equals, 1)
}

func (*machineSuite) TestShortPollIntervalWhenNoAddress(c *gc.C) {
	defer testbase.PatchValue(&ShortPoll, 1*time.Millisecond).Restore()
	defer testbase.PatchValue(&LongPoll, coretesting.LongWait).Restore()
	count := countPolls(c, nil)
	c.Assert(count, jc.GreaterThan, 2)
}

func (*machineSuite) TestShortPollIntervalExponent(c *gc.C) {
	defer testbase.PatchValue(&ShortPoll, 1*time.Microsecond).Restore()
	defer testbase.PatchValue(&LongPoll, coretesting.LongWait).Restore()
	defer testbase.PatchValue(&ShortPollBackoff, 2.0).Restore()

	// With an exponent of 2, the maximum number of polls that can
	// occur within the given interval ShortWait is log to the base
	// base ShortPollBackoff of ShortWait/ShortPoll, given that sleep will
	// sleep for at least the requested interval.
	maxCount := int(math.Log(float64(coretesting.ShortWait)/float64(ShortPoll))/math.Log(ShortPollBackoff) + 1)
	count := countPolls(c, nil)
	c.Assert(count, jc.GreaterThan, 2)
	c.Assert(count, jc.LessThan, maxCount)
	c.Logf("actual count: %v; max %v", count, maxCount)
}

func (*machineSuite) TestLongPollIntervalWhenHasAddress(c *gc.C) {
	defer testbase.PatchValue(&ShortPoll, coretesting.LongWait).Restore()
	defer testbase.PatchValue(&LongPoll, 1*time.Millisecond).Restore()
	count := countPolls(c, testAddrs)
	c.Assert(count, jc.GreaterThan, 2)
}

// countPolls sets up a machine loop with the given
// addresses to be returned from getAddresses,
// waits for coretesting.ShortWait, and returns the
// number of times the addresses are polled.<commit_msg>worker/addressupdater: fix comment<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package addressupdater

import (
	stderrors "errors"
	"fmt"
	"math"
	"sync"
	"sync/atomic"
	"time"

	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/errors"
	"launchpad.net/juju-core/instance"
	"launchpad.net/juju-core/state"
	coretesting "launchpad.net/juju-core/testing"
	jc "launchpad.net/juju-core/testing/checkers"
	"launchpad.net/juju-core/testing/testbase"
)

var _ = gc.Suite(&machineSuite{})

type machineSuite struct {
	testbase.LoggingSuite
}

var testAddrs = []instance.Address{instance.NewAddress("127.0.0.1")}

func (*machineSuite) TestSetsAddressInitially(c *gc.C) {
	context := &testMachineContext{
		getAddresses: addressesGetter(c, "i1234", testAddrs, nil),
		dyingc:       make(chan struct{}),
	}
	m := &testMachine{
		id:         "99",
		instanceId: "i1234",
		refresh:    func() error { return nil },
		life:       state.Alive,
	}
	died := make(chan machine)
	// Change the poll intervals to be short, so that we know
	// that we've polled (probably) at least a few times.
	defer testbase.PatchValue(&ShortPoll, coretesting.ShortWait/10).Restore()
	defer testbase.PatchValue(&LongPoll, coretesting.ShortWait/10).Restore()

	go runMachine(context, m, nil, died)
	time.Sleep(coretesting.ShortWait)

	killMachineLoop(c, m, context.dyingc, died)
	c.Assert(context.killAllErr, gc.Equals, nil)
	c.Assert(m.addresses, gc.DeepEquals, testAddrs)
	c.Assert(m.setAddressCount, gc.Equals, 1)
}

func (*machineSuite) TestShortPollIntervalWhenNoAddress(c *gc.C) {
	defer testbase.PatchValue(&ShortPoll, 1*time.Millisecond).Restore()
	defer testbase.PatchValue(&LongPoll, coretesting.LongWait).Restore()
	count := countPolls(c, nil)
	c.Assert(count, jc.GreaterThan, 2)
}

func (*machineSuite) TestShortPollIntervalExponent(c *gc.C) {
	defer testbase.PatchValue(&ShortPoll, 1*time.Microsecond).Restore()
	defer testbase.PatchValue(&LongPoll, coretesting.LongWait).Restore()
	defer testbase.PatchValue(&ShortPollBackoff, 2.0).Restore()

	// With an exponent of 2, the maximum number of polls that can
	// occur within the given interval ShortWait is log to the base
	// ShortPollBackoff of ShortWait/ShortPoll, given that sleep will
	// sleep for at least the requested interval.
	maxCount := int(math.Log(float64(coretesting.ShortWait)/float64(ShortPoll))/math.Log(ShortPollBackoff) + 1)
	count := countPolls(c, nil)
	c.Assert(count, jc.GreaterThan, 2)
	c.Assert(count, jc.LessThan, maxCount)
	c.Logf("actual count: %v; max %v", count, maxCount)
}

func (*machineSuite) TestLongPollIntervalWhenHasAddress(c *gc.C) {
	defer testbase.PatchValue(&ShortPoll, coretesting.LongWait).Restore()
	defer testbase.PatchValue(&LongPoll, 1*time.Millisecond).Restore()
	count := countPolls(c, testAddrs)
	c.Assert(count, jc.GreaterThan, 2)
}

// countPolls sets up a machine loop with the given
// addresses to be returned from getAddresses,
// waits for coretesting.ShortWait, and returns the
// number of times the addresses are polled.
{'fraction_non_alphanumeric': 0.12935809710003257, 'fraction_numerical': 0.013033561420658195, 'mean_word_length': 4.989268292682927, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, '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': '6703965', 'n_tokens_mistral': 2270, 'n_tokens_neox': 2142, 'n_words': 496}