Commit Graph

163 Commits

Author SHA1 Message Date
James Bardin 074be9ae56 Another race in resource.Retry 2016-07-29 18:35:54 -04:00
Paul Hinze 261043fd1a Merge pull request #7523 from hashicorp/f-aws-beanstalk-env-poll-timing
provider/aws: Beanstalk environments, bump the minimum timeout between API calls
2016-07-21 16:43:21 -05:00
Paul Hinze 614806d59f
helper/resource: Fix import test harness, which was modifying state
Maps are reference types, it turns out :D
2016-07-15 13:15:47 -06:00
clint shryock de60481428 provider/aws: Rework Beanstalk optional polling
expose a poll_interval for users to configure polling for updates
2016-07-13 15:38:23 -06:00
Paul Hinze 3b732131d2 Merge pull request #7446 from hashicorp/b-jit-resource-validate
core: rerun resource validation before plan and apply
2016-07-01 15:00:40 -05:00
Paul Hinze ad27190852 Merge pull request #7448 from dtolnay/timeout
Timing out is not success
2016-07-01 14:28:11 -05:00
Paul Hinze 4a1b36ac0d
core: rerun resource validation before plan and apply
In #7170 we found two scenarios where the type checking done during the
`context.Validate()` graph walk was circumvented, and the subsequent
assumption of type safety in the provider's `Diff()` implementation
caused panics.

Both scenarios have to do with interpolations that reference Computed
values. The sentinel we use to indicate that a value is Computed does
not carry any type information with it yet.

That means that an incorrect reference to a list or a map in a string
attribute can "sneak through" validation only to crop up...

 1. ...during Plan for Data Source References
 2. ...during Apply for Resource references

In order to address this, we:

 * add high-level tests for each of these two scenarios in `provider/test`
 * add context-level tests for the same two scenarios in `terraform`
   (these tests proved _really_ tricky to write!)
 * place an `EvalValidateResource` just before `EvalDiff` and `EvalApply` to
   catch these errors
 * add some plumbing to `Plan()` and `Apply()` to return validation
   errors, which were previously only generated during `Validate()`
 * wrap unit-tests around `EvalValidateResource`
 * add an `IgnoreWarnings` option to `EvalValidateResource` to prevent
   active warnings from halting execution on the second-pass validation

Eventually, we might be able to attach type information to Computed
values, which would allow for these errors to be caught earlier. For
now, this solution keeps us safe from panics and raises the proper
errors to the user.

Fixes #7170
2016-07-01 13:12:57 -05:00
Paul Hinze 5656d7388c
helper/resource: Consolidate unit test override
I noticed we had two mechanisms for unit test override. One that dropped
a sentinel into the env var, and another with a struct member on
TestCase. This consolidates the two, using the cleaner struct member
internal mechanism and the nicer `resource.UnitTest()` entry point.
2016-07-01 13:08:43 -05:00
David Tolnay 7e1cd34819 Timing out is not success 2016-06-30 18:07:56 -07:00
Patrick Sodré 80936e3562 provider/triton: add machine domain names (#7149)
* vendor joyent/gosdc/cloudapi

* provider/triton: Add machine domain names

 - Includes acceptance test.
2016-06-26 22:18:17 +01:00
James Nugent 9c7cf639b3 testing: Allow acceptance test to run as unit test
This commit adds a flag to acceptance tests in order to make
appropriately named tests work during `make test` irrespective of the
TF_ACC environment variable. This should only be used on tests which are
known to be fast.
2016-06-11 12:55:14 +01:00
Radek Simko 1ea5cff9b3 Merge pull request #6946 from TimeIncOSS/f-aws-s3-object-data-source
provider/aws: Add aws_s3_bucket_object data source
2016-06-02 07:04:46 +01:00
Radek Simko bf8931b1ab provider/aws: Mark Lambda function as gone when it's gone (#6924)
* helper/error: Introduce TimeoutError & UnexpectedStateError

* provider/aws: Mark Lambda function as gone when it's gone
2016-06-02 00:50:43 +01:00
Radek Simko 84ab00d92e helper/resource: Add TestStep.PreventPostDestroyRefresh
- This is to allow easier testing of data sources which read data from resources created in the same scope
2016-06-01 19:13:00 +01:00
Martin Atkins 031b561ef0 helper/resource: ignore data resource diffs during destroy
When testing destroy, the test harness calls Refresh followed by Plan,
with the expectation that the resulting diff will be empty.

Data resources challenge this expectation, because they will always be
instantiated during refresh if their configuration isn't computed, and so
the subsequent diff will want to destroy what was instantiated.

To work around this, we make an exception that data resource destroy
diffs may appear in the plan but nothing else.

This fixes #6713.
2016-05-21 14:16:02 -07:00
Mitchell Hashimoto 55583baa7e
Merge branch 'f-aws-import' 2016-05-18 15:28:12 -06:00
James Nugent 3ea3c657b5 core: Use OutputState in JSON instead of map
This commit forward ports the changes made for 0.6.17, in order to store
the type and sensitive flag against outputs.

It also refactors the logic of the import for V0 to V1 state, and
fixes up the call sites of the new format for outputs in V2 state.

Finally we fix up tests which did not previously set a state version
where one is required.
2016-05-18 13:25:20 -05:00
Mitchell Hashimoto 884980da1a
providers/aws: instance, nat, internet gateway 2016-05-16 10:03:57 -07:00
Mitchell Hashimoto 6a675b4a15
helper/resource: ImportState test can verify states 2016-05-11 13:02:37 -07:00
Mitchell Hashimoto ec02c8c0e2
helper/resource: testing of almost all aspects of ImportState tests 2016-05-11 13:02:37 -07:00
Mitchell Hashimoto 2d99c451fb
helper/resource: basic ImportState acceptance testing
Still some TODOs, and more test cases to write, but the basics are all
here.
2016-05-11 13:02:37 -07:00
Mitchell Hashimoto 9bd1c9e7ca
helper/resource: reshuffling to prepare for importstate testing 2016-05-11 13:02:37 -07:00
Mitchell Hashimoto 35c87836b4 core: Add terraform_version to state
This adds a field terraform_version to the state that represents the
Terraform version that wrote that state. If Terraform encounters a state
written by a future version, it will error. You must use at least the
version that wrote that state.

Internally we have fields to override this behavior (StateFutureAllowed),
but I chose not to expose them as CLI flags, since the user can just
modify the state directly. This is tricky, but should be tricky to
represent the horrible disaster that can happen by enabling it.

We didn't have to bump the state format version since the absense of the
field means it was written by version "0.0.0" which will always be
older. In effect though this change will always apply to version 2 of
the state since it appears in 0.7 which bumped the version for other
purposes.
2016-05-10 14:40:11 -04:00
Mitchell Hashimoto d85df63526
providers/aws: aws_instance id-only 2016-04-22 09:37:41 -07:00
Mitchell Hashimoto e0da21d381
helper/resource: make id-only check opt-in
As I've been working through the resources, I'm finding that a lot are
going to need some serious work. Given we have hundreds, I think it
might be prudent to make this opt-in for now and we can revisit
automatic/opt-out at some future point.

Importability will likely be opt-in it appears so this will match up
with that.
2016-04-21 08:37:08 -07:00
Mitchell Hashimoto ff7b58f032
providers/aws: peering connection id-only test settings 2016-04-20 12:19:21 -07:00
Mitchell Hashimoto 0ef1b3b84a
providers/aws: response value for DescribeVpcAttribute needs to be
.Value
2016-04-20 11:35:43 -07:00
Mitchell Hashimoto 1db1bf6639
helper/resource: use the full config for id-only checks
Originally I used an empty config module. This caused problems since
important provider configurations weren't available. Instead, I now set
it to use the full config. This isn't an issue since the attributes
themselves aren't available to Refresh anyways.
2016-04-20 11:18:13 -07:00
Mitchell Hashimoto 0c8b0bff2c
helper/resource: can specify specific name to id refresh test 2016-04-20 11:12:30 -07:00
Mitchell Hashimoto 1a9fae6b2e
helper/resource: can disable ID refresh check 2016-04-20 11:09:54 -07:00
Mitchell Hashimoto 35f4201b9e
providers/aws: instance_tenancy is computed, set 2016-04-20 10:48:22 -07:00
Mitchell Hashimoto f2c4f8e9ba
helper/resource: fix tests 2016-04-20 10:08:34 -07:00
Mitchell Hashimoto 5c4f78796b
helper/resource: don't need to id-only check if no test steps 2016-04-20 09:52:53 -07:00
Mitchell Hashimoto a285c04dc9
helper/resource: only verify id-only run if no error 2016-04-20 09:50:59 -07:00
Mitchell Hashimoto baac14aaeb
helper/resource: guard id-only by acc var 2016-04-20 09:34:54 -07:00
Mitchell Hashimoto cb32cb8947
helper/resource: error if id-only check didn't run 2016-04-20 09:25:23 -07:00
Mitchell Hashimoto 86e0c853db
helper/resource: test for failing id-only refresh check 2016-04-20 09:18:25 -07:00
Mitchell Hashimoto 060b43fbd9
helper/resource: remove debug 2016-04-20 09:17:04 -07:00
Mitchell Hashimoto 4f6edf4fe4
helper/resource: id-only refresh testing 2016-04-20 09:16:48 -07:00
James Nugent cb8a0549e1 Merge pull request #5757 from hashicorp/f-output-testing
Add TestCheckOutput helper to resource testing
2016-03-21 17:19:08 +00:00
James Nugent 35f9d2e081 Add TestCheckOutput helper to resource testing
This allows outputs in test configuration to have test functions written
conveniently. Useful for azurerm_template_deployment.
2016-03-21 16:54:02 +00:00
Radek Simko bf9f5879ca helper/resource: Remove NotFoundError function 2016-03-21 16:47:50 +00:00
James Nugent f946695187 Merge pull request #5444 from TimeIncOSS/f-aws-logs-metric-filter
provider/aws: Add support for CloudWatch Log Metric Filter
2016-03-21 16:43:38 +00:00
Paul Hinze c3e27b3e0a provider/test: a test provider
Here we also introduce a `test` provider meant as an aid to exposing
via automated tests issues involving interactions between
`helper/schema` and Terraform core.

This has been helpful so far in diagnosing `ignore_changes` problems,
and I imagine it will be helpful in other contexts as well.

We'll have to be careful to prevent the `test` provider from becoming a
dumping ground for poorly specified tests that have a clear home
elsewhere. But for bug exposure I think it's useful to have.
2016-03-21 08:59:54 -05:00
Radek Simko fd2fcaf1d5 helper/resource: Implement resource-wide NotFoundError 2016-03-15 13:58:25 +00:00
Radek Simko 034287fdc2 helper/resource: Error shouldn't be returned in case of success 2016-03-10 14:14:14 +00:00
Radek Simko 8582f4df9f helper/resource: Fix TestRetry 2016-03-10 14:13:23 +00:00
Paul Hinze 108ccf0007 builtin: Refactor resource.Retry to clarify return
Change the `RetryFunc` from a plain `error` return type to a
specialized `RetryError` which must decide whether it is
retryable or not.

Add `RetryableError` / `NonRetryableError` factory functions that
callers are meant to use to build up these errors.

This makes it eminently clear whether or not a given error is
retryable from inside the client code.

Goal here is to _not_ change any behavior, simply reflect the
existing behavior with the new, clearer, API.
2016-03-09 17:37:56 -06:00
Paul Hinze 5160578e18 helper/resource: restore retval of resource.Retry on timeout
In #4700 while fixing a data race I made an incorrect assumption about
the return value of StateChangeConf, and ended up changing the behavior
in the timeout case to always return:

> timeout while waiting for state to become '[success]'

When it used to capture the "most recent error" from the function
itself.

It's much more useful to see that error bubbling up, so here we revert
to pulling it out of the function as we did before, and we protect
against the data race with a good old fashioned mutex.
2016-03-04 11:20:48 -06:00
Paul Hinze bba8a79a52 acctests: log a line w/ the non-empty plan
Helpful when iterating on a drift test.

Eventually I think this assertion could be fanned out to something much
more targeted like:

    ExpectAttributeDiff(resource, attr, oldval, newval)

But this is a step in the right direction.
2016-02-29 11:50:42 -06:00
Radek Simko ab73f2b762 helper: Add StateChangeConf.ContinuousTargetOccurence (int) 2016-02-23 20:18:57 +00:00
Paul Hinze 24048b4dca providers: Mention check number when acctest fails 2016-02-02 10:57:28 -06:00
Ian Duffy 47ac10d66b Change resource.StateChangeConf to use an array for target states
Signed-off-by: Ian Duffy <ian@ianduffy.ie>
2016-01-21 01:20:41 +00:00
Paul Hinze d59db52f06 helper/resource: Fix data race in resource.Retry
The implementation was attempting to capture the error using a scoped
variable reference, but the error value is already exposed via the
return value of `WaitForState()`. Using that instead fixes the data
race.

Fixes the following data race:

```
==================
WARNING: DATA RACE
Read by goroutine 74:
  github.com/hashicorp/terraform/helper/resource.Retry()
      /Users/phinze/go/src/github.com/hashicorp/terraform/helper/resource/wait.go:35 +0x284
  github.com/hashicorp/terraform/helper/resource.TestRetry_timeout()
      /Users/phinze/go/src/github.com/hashicorp/terraform/helper/resource/wait_test.go:35 +0x60
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc

Previous write by goroutine 90:
  github.com/hashicorp/terraform/helper/resource.Retry.func1()
      /Users/phinze/go/src/github.com/hashicorp/terraform/helper/resource/wait.go:20 +0x87
  github.com/hashicorp/terraform/helper/resource.(*StateChangeConf).WaitForState.func1()
      /Users/phinze/go/src/github.com/hashicorp/terraform/helper/resource/state.go:83 +0x284

Goroutine 74 (running) created at:
  testing.RunTests()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:561 +0xaa3
  testing.(*M).Run()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:494 +0xe4
  main.main()
      github.com/hashicorp/terraform/helper/resource/_test/_testmain.go:84 +0x20f

Goroutine 90 (running) created at:
  github.com/hashicorp/terraform/helper/resource.(*StateChangeConf).WaitForState()
      /Users/phinze/go/src/github.com/hashicorp/terraform/helper/resource/state.go:127 +0x283
  github.com/hashicorp/terraform/helper/resource.Retry()
      /Users/phinze/go/src/github.com/hashicorp/terraform/helper/resource/wait.go:34 +0x276
  github.com/hashicorp/terraform/helper/resource.TestRetry_timeout()
      /Users/phinze/go/src/github.com/hashicorp/terraform/helper/resource/wait_test.go:35 +0x60
  testing.tRunner()
      /private/var/folders/vd/7l9ys5k57l91x63sh28wl_kc0000gn/T/workdir/go/src/testing/testing.go:456 +0xdc
==================
```
2016-01-16 13:38:50 -05:00
Paul Hinze a8d2ad3ebe refactor s3 bucket test to expect non-empty plan
pushing to master but paging @catsby for post-hoc review
2016-01-05 17:38:38 -06:00
James Nugent e976d6e787 testing: Use a copy of pre-destroy state in destroy check
In the acceptance testing framework, it is neccessary to provide a copy
of the state _before_ the destroy is applied to the check in order that
it can loop over resources to verify their destruction. This patch makes
a deep copy of the state prior to applying test steps which have the
Destroy option set and then passes that to the destroy check.
2015-12-10 13:14:17 -05:00
Paul Hinze 4bd4e18def core: use same logging setup for acctests
We weren't doing any log setup for acceptance tests, which made it
difficult to wrangle log output in CI.

This moves the log setup functions we use in `main` over into a helper
package so we can use them for acceptance tests as well.

This means that acceptance tests will by default be a _lot_ quieter,
only printing out actual test output. Setting `TF_LOG=trace` will
restore the full prior noise level.

Only minor behavior change is to make `ioutil.Discard` the default
return value rather than a `nil` that needs to be checked for.
2015-12-08 17:50:36 -06:00
Mitchell Hashimoto 344e7c26b5 fix a bunch of tests from go-getter import 2015-10-15 13:48:58 -07:00
Clint f979fd7dee Merge pull request #2571 from TimeIncOSS/f-aws-autogenerated-elb-name
provider/aws: Allow ELB name to be generated
2015-07-21 15:52:36 -05:00
Radek Simko 9882cc59d8 aws: Add regression test for renaming ecs_cluster 2015-07-12 14:37:39 +01:00
Radek Simko 70b7243dd6 helper: Add resource.PrefixedUniqueId 2015-06-30 12:54:54 +01:00
Paul Hinze 385b17d679 provider/template: don't error when rendering fails in Exists
The Exists function can run in a context where the contents of the
template have changed, but it uses the old set of variables from the
state. This means that when the set of variables changes, rendering will
fail in Exists. This was returning an error, but really it just needs to
be treated as a scenario where the template needs re-rendering.

fixes #2344 and possibly a few other template issues floating around
2015-06-17 15:33:07 -05:00
Paul Hinze a96a3372c6 provider/template: don't diff when there's no diff
This reworks the template lifecycle a bit such that we get nicer diff
behavior.

First, we tick ForceNew on for both filename and vars, so that the diff
indicates that the template will be "replaced" on change. This is mostly
cosmetic, but it also tracks conceptually with the fact that the
identifier we use is a hash of the contents, so any change essentially
makes a "new resource".

Second, we change the Exists implementation to only return `false` when
there has been a change in the rendered template. This lets descendent
resources see the computed value changing so that they'll properly
trigger in the plan.

Fixes #1898
Refs #1866 (but does not fix, there's another deeper issue there)
2015-05-11 10:38:19 -05:00
Paul Hinze fbce3a3caa helper/resource: don't fail test on config warnings
AccTests like TestAccComputeInstance_basic_deprecated_network were
failing early on "invalid config" when we are explictly testing behavior
that we know generates warnings.
2015-05-06 13:17:56 -05:00
Josh Bleecher Snyder 76bcac3031 providers/template: add tests, address review comments
Do directory expansion on filenames.

Add basic acceptance tests. Code coverage is 72.5%.
Uncovered code is uninteresting and/or impossible error cases.

Note that this required adding a knob to
helper/resource.TestStep to allow transient
resources.
2015-05-04 10:26:17 -07:00
Paul Hinze 88744d569f helper/resource/testing: unit tests to cover #1770
Also clarified that final return value of testStep is now only for the
happy path.
2015-05-01 11:22:06 -05:00
Paul Hinze dbf6d1bd00 helper/resource: fix accidentaly swallowing of acctest step errors
With #1757 I unwittingly reused an err variable, causing all test check
errors to be swallowed. -_-
2015-05-01 11:11:16 -05:00
Paul Hinze 149e52ad1f helper/resource: verify refresh+plan after each step
I forgot to add `Computed: true` when I made the "key_name" field
optional in #1751.

This made the behavior:

 * Name generated in Create and set as ID
 * Follow up plan (without refresh) was nice and empty
 * During refresh, name gets cleared out on Read, causing a bad diff on
   subsequent plans

We can automatically catch bugs like this if we add yet another
verification step to our resource acceptance tests -> a post
Refresh+Plan that we verify is empty.

I left the non-refresh Plan verification in, because it's important that
_both_ of these are empty after an Apply.
2015-04-30 12:52:25 -05:00
Phil Frost bd8ac4fe5e Better document StateChangeConf.WaitForState 2015-04-28 12:33:23 -04:00
Paul Hinze 92ebb60293 helper/resource: ok let's actually use RFC4122 2015-04-22 13:16:44 -05:00
Paul Hinze d1106e9e22 helper/resource: add UniqueId() helper
A generic function for provider resources to use to get a unique
identifier.
2015-04-22 12:53:05 -05:00
Mitchell Hashimoto dc69603cd4 helper/resource: docs 2015-04-20 14:14:34 -07:00
Matt Good 21b0a03d70 Support for multiple providers of the same type
Adds an "alias" field to the provider which allows creating multiple instances
of a provider under different names. This provides support for configurations
such as multiple AWS providers for different regions. In each resource, the
provider can be set with the "provider" field.

(thanks to Cisco Cloud for their support)
2015-04-20 14:14:34 -07:00
Paul Hinze 7fe34d4547 providers: check for empty plan after each test step
Each acceptance test step plays a Refresh, Plan, Apply for a given
config. This adds a follow up Plan and fails the test if it does not
come back empty. This will catch issues with perpetual, unresolvable
diffs that crop up here and there.

This is going to cause a lot of our existing acceptance tests to fail -
too many to roll into a single PR. I think the best plan is to land this
in master and then fix the failures (each of which should be catching a
legitimate provider bug) one by one until we get the provider suites
back to green.
2015-04-09 10:19:01 -05:00
Paul Hinze 97acccd3ed core: targeted operations
Add `-target=resource` flag to core operations, allowing users to
target specific resources in their infrastructure. When `-target` is
used, the operation will only apply to that resource and its
dependencies.

The calculated dependencies are different depending on whether we're
running a normal operation or a `terraform destroy`.

Generally, "dependencies" refers to ancestors: resources falling
_before_ the target in the graph, because their changes are required to
accurately act on the target.

For destroys, "dependencies" are descendents: those resources which fall
_after_ the target. These resources depend on our target, which is going
to be destroyed, so they should also be destroyed.
2015-03-31 14:49:38 -05:00
Jack Pearkes c180487af6 helper/resource: allow configuration of not found checks in state change 2015-02-26 09:59:42 -08:00
Mitchell Hashimoto 5a64d0900b providers/aws: test for allowing in-place lC update 2015-02-17 16:12:02 -08:00
Mitchell Hashimoto b4f8b7f43b helper/resource: RetryError for quitting quickly 2014-10-17 18:28:03 -07:00
Mitchell Hashimoto 36f225dea0 fmt 2014-10-10 14:50:35 -07:00
Mitchell Hashimoto ef62fa80db helper/resource: add Retry function 2014-10-07 21:44:51 -07:00
Mitchell Hashimoto 9ba39d93b7 helper/resource: compile 2014-09-24 14:23:29 -07:00
Mitchell Hashimoto 9b2b3a963f ResourceDiff => InstanceDiff 2014-09-17 16:33:24 -07:00
Mitchell Hashimoto 0bcbccf046 helper/resource: compiles, fails because Context doesn't work, probably 2014-09-16 17:02:05 -07:00
Alex Gaynor 46154ca1d3 Fixed a ton of typos in docs and comments 2014-08-07 00:19:56 -07:00
Mitchell Hashimoto d7ecc76148 helper/resource: refactor wait a bit and introduce delay/mintimeout 2014-07-17 11:03:30 -07:00
Mitchell Hashimoto f8b974c9aa helper/resource: never use an interval more than 10 seconds on wait 2014-07-14 13:28:48 -07:00
Mitchell Hashimoto 91ad873113 helper/resource: improve logging and output for tests 2014-07-11 11:20:18 -07:00
Mitchell Hashimoto dbe5a1254a helper/resource: better error if config doesn't validate 2014-07-10 17:01:21 -07:00
Mitchell Hashimoto 9ab4a5bf88 helper/resource: exponential backoff 2014-07-10 14:40:18 -07:00
Mitchell Hashimoto 63ef4cf28a helper/resource: stdlib to check resource attribute 2014-07-10 14:00:20 -07:00
Mitchell Hashimoto 4a3d51f40e helper/resource: can compose TestCheckFuncs 2014-07-10 13:29:38 -07:00
Mitchell Hashimoto 8229758806 helper/resource: refresh during test 2014-07-10 13:21:34 -07:00
Mitchell Hashimoto 83f73e63aa helper/resource: add PreCheck 2014-07-10 13:12:47 -07:00
Mitchell Hashimoto bc146d21a3 helper/resource: persist state, log 2014-07-10 11:31:07 -07:00
Mitchell Hashimoto be82499f3c helper/resource: remove debugging stuff 2014-07-10 10:31:06 -07:00
Mitchell Hashimoto 55c1bf7f79 helper/resource: more tests 2014-07-10 10:30:41 -07:00
Mitchell Hashimoto e0fbd48afd helper/resource: Acceptance test framework 2014-07-10 10:20:21 -07:00
Mitchell Hashimoto fa3e9fab42 helper/resource: wait 2 seconds between each 2014-07-09 09:16:46 -07:00
Mitchell Hashimoto 0c812ba9e8 helper/resource: automatically validate resources
/cc @pearkes - So, just set a ConfigValidator struct up on your
resources and it'll now automatically validate.
2014-07-08 10:17:36 -07:00
Mitchell Hashimoto f1d782031b helper/resource: don't assign to nil map 2014-07-07 20:45:09 -07:00