sus-fixtures-time 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9184183528fd5ea79bfab1932b3d59f93ecfcee6a067726e14a866ca00dd1623
4
+ data.tar.gz: 03a56c62889f1950bfca0fd9c83bda2496243272828a0016ca57c75830beb077
5
+ SHA512:
6
+ metadata.gz: ddc8526ba5b3b97eb7d8bc44dfa718f222197a76225a88917d2038697fb1919e024e66cc7b4451af44a98fead7fb51eef2d0a0b99da3475b0cab4f7fbbbc6f55
7
+ data.tar.gz: 1cff6d88529eeb390cefbb5949ebc54f11f37ce0f6dfed5fbbe01feade018363f696493719e3838a54f53957ff0d2682b53d4ddbad7100310b3d2be98924225f
checksums.yaml.gz.sig ADDED
Binary file
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require 'time'
7
+ require 'date'
8
+
9
+ module Sus
10
+ module Fixtures
11
+ module Time
12
+ # Mocks the current time.
13
+ CurrentContext = Sus::Shared("mocked time context") do |time|
14
+ attr_accessor :current_time
15
+
16
+ def time_travel(time)
17
+ current_time = @current_time
18
+ @current_time = time
19
+ yield
20
+ ensure
21
+ @current_time = current_time
22
+ end
23
+
24
+ before do
25
+ @current_time = time
26
+
27
+ mock(::Time) do |mock|
28
+ mock.wrap(:now) do |original|
29
+ if @current_time
30
+ @current_time.dup
31
+ else
32
+ original.call
33
+ end
34
+ end
35
+
36
+ mock.wrap(:new) do |original, *arguments|
37
+ if arguments.empty? && @current_time
38
+ @current_time.dup
39
+ else
40
+ original.call(*arguments)
41
+ end
42
+ end
43
+ end
44
+
45
+ mock(::Date) do |mock|
46
+ mock.wrap(:today) do |original|
47
+ if @current_time
48
+ @current_time.to_date
49
+ else
50
+ original.call
51
+ end
52
+ end
53
+ end
54
+
55
+ mock(::DateTime) do |mock|
56
+ mock.wrap(:now) do |original|
57
+ if @current_time
58
+ @current_time.to_datetime
59
+ else
60
+ original.call
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require_relative 'quantum'
7
+
8
+ module Sus
9
+ module Fixtures
10
+ module Time
11
+ # A context for comparing measured durations, taking into account the overhead (quantum) of the system.
12
+ module MeasuredContext
13
+ # The measured duration is less than the given duration plus the quantum.
14
+ #
15
+ # @parameter duration [Numeric] The expected duration.
16
+ def be_measured_faster_than(duration)
17
+ be < (duration + QUANTUM)
18
+ end
19
+
20
+ # The measured duration is greater than the given duration minus the quantum.
21
+ #
22
+ # @parameter duration [Numeric] The expected duration.
23
+ def be_measured_slower_than(duration)
24
+ be > (duration - QUANTUM)
25
+ end
26
+
27
+ # The measured duration is within the given duration plus or minus the quantum.
28
+ #
29
+ # @parameter duration [Numeric] The expected duration.
30
+ def be_measured_within(duration)
31
+ be_within(QUANTUM).of(duration)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023-2024, by Samuel Williams.
5
+
6
+ module Sus
7
+ module Fixtures
8
+ module Time
9
+ # Represents the smallest possible time interval that can be measured given the current system overheads.
10
+ class Quantum
11
+ # Resolve the quantum for the current system.
12
+ #
13
+ # @returns [Float] The quantum for the current system in seconds.
14
+ def self.resolve
15
+ self.new.to_f
16
+ end
17
+
18
+ # @returns [Float] the quantum for the current system in seconds.
19
+ def to_f
20
+ precision
21
+ end
22
+
23
+ # Lazily compute the precision of the current system.
24
+ #
25
+ # @returns [Float] the quantum for the current system in seconds.
26
+ def precision
27
+ @precision ||= self.measure_host_precision
28
+ end
29
+
30
+ # Measure the precision of the current system.
31
+ #
32
+ # @parameter repeats [Integer] The number of times to repeat the measurement.
33
+ # @parameter duration [Float] The duration of the measurement in seconds.
34
+ # @parameter factor [Float] A scaling factor to apply to the measured overhead.
35
+ # @returns [Float] the quantum for the current system in seconds.
36
+ def measure_host_precision(repeats: 1000, duration: 0.1, factor: 2.0)
37
+ step = duration / repeats
38
+
39
+ start_time = self.now
40
+ repeats.times do
41
+ sleep(step)
42
+ end
43
+ end_time = self.now
44
+
45
+ actual_duration = end_time - start_time
46
+
47
+ if actual_duration < duration
48
+ warn "Expected to sleep for #{duration}+ seconds, but only slept for #{actual_duration} seconds."
49
+ error = 0.1
50
+ else
51
+ # Total execution time, minus the expected execution time = overhead.
52
+ error = actual_duration - duration
53
+ end
54
+
55
+ # It's not like this is a precise measurement anyway...
56
+ return error * factor
57
+ end
58
+
59
+ private
60
+
61
+ def now
62
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
63
+ end
64
+ end
65
+
66
+ QUANTUM = Quantum.resolve
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ module Sus
7
+ module Fixtures
8
+ module Time
9
+ VERSION = "0.1.0"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ require_relative 'time/quantum'
7
+ require_relative 'time/version'
8
+
9
+ # @namespace
10
+ module Sus
11
+ # @namespace
12
+ module Fixtures
13
+ # @namespace
14
+ module Time
15
+ end
16
+ end
17
+ end
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright, 2023-2024, by Samuel Williams.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,33 @@
1
+ # Sus::Fixtures::Time
2
+
3
+ Provides a convenient fixtures for time-related tests.
4
+
5
+ [![Development Status](https://github.com/socketry/sus-fixtures-time/workflows/Test/badge.svg)](https://github.com/socketry/sus-fixtures-time/actions?workflow=Test)
6
+
7
+ ## Motivation
8
+
9
+ Time-related tests are notoriously flakey due to changes in hardware performance and software load. Typically, a test that measures duration will work fine locally, but fail on a continuous integration (CI) server. This is because the CI server is under load which results in significantly slower test execution times. This gem provides a mechanism to try and measure this overhead, and adjust the test expectations to account for it. This is done by measuring the time taken to perform a simple operation, and then using that as a baseline.
10
+
11
+ ## Usage
12
+
13
+ Please see the [project documentation](https://socketry.github.io/sus-fixtures-time/) for more details.
14
+
15
+ - [Getting Started](https://socketry.github.io/sus-fixtures-time/guides/getting-started/index) - This guide explains how to use the `sus-fixtures-time` gem to test time-related code.
16
+
17
+ ## Contributing
18
+
19
+ We welcome contributions to this project.
20
+
21
+ 1. Fork it.
22
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
23
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
24
+ 4. Push to the branch (`git push origin my-new-feature`).
25
+ 5. Create new Pull Request.
26
+
27
+ ### Developer Certificate of Origin
28
+
29
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
30
+
31
+ ### Community Guidelines
32
+
33
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sus-fixtures-time
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
14
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
15
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
16
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
17
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
18
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
19
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
20
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
21
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
22
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
23
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
24
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
25
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
26
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
27
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
28
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
29
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
30
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
31
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
32
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
33
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
34
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
35
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
36
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
37
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
+ -----END CERTIFICATE-----
40
+ date: 2024-07-23 00:00:00.000000000 Z
41
+ dependencies:
42
+ - !ruby/object:Gem::Dependency
43
+ name: sus
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0.10'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0.10'
56
+ description:
57
+ email:
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/sus/fixtures/time.rb
63
+ - lib/sus/fixtures/time/current_context.rb
64
+ - lib/sus/fixtures/time/measured_context.rb
65
+ - lib/sus/fixtures/time/quantum.rb
66
+ - lib/sus/fixtures/time/version.rb
67
+ - license.md
68
+ - readme.md
69
+ homepage: https://github.com/socketry/sus-fixtures-time
70
+ licenses:
71
+ - MIT
72
+ metadata:
73
+ documentation_uri: https://socketry.github.io/sus-fixtures-time/
74
+ funding_uri: https://github.com/sponsors/ioquatix/
75
+ source_code_uri: https://github.com/socketry/sus-fixtures-time.git
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '3.1'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.5.11
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Test fixtures for manipulating time.
95
+ test_files: []
metadata.gz.sig ADDED
Binary file