Пример #1
0
        private async Task <Videos> GetVideosEndpoint(int offset, int retry)
        {
            await RateLimit.WaitAsync();

            var rateLimitTask = StartRatelimit();

            try
            {
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("User-Agent", "KiteBotCore 1.1 GB Discord Bot for fetching wiki information");
                    return(JsonConvert.DeserializeObject <Videos>(await client.GetStringAsync($@"{_apiCallUrl}&offset={offset}")));
                }
            }
            catch (Exception)
            {
                if (++retry < 3)
                {
                    await Task.Delay(5000);

                    await rateLimitTask;
                    return(await GetVideosEndpoint(offset, retry));
                }
                throw new TimeoutException();
            }
        }
Пример #2
0
        public void GetRateLimits(string mess)
        {
            var rateLimits = RateLimit.GetCurrentCredentialsRateLimits();

            if (rateLimits != null)
            {
                try
                {
                    var currentUser = User.GetLoggedUser().Name;
                    FOutputStatus[0] = "F**k YEAH! Logged in as " + currentUser;
                    FLogger.Log(LogType.Debug, "F**k YEAH! Logged in as " + currentUser);
                    FOutputSearchesRemaining[0] = rateLimits.SearchTweetsLimit.Limit;
                    FOutputSearchesReset[0]     = rateLimits.SearchTweetsLimit.ResetDateTime.ToString();
                    FOutputStatusBool[0]        = true;
                    loggedIn = true;
                }
                catch
                {
                    FOutputStatus[0] = mess;
                    FLogger.Log(LogType.Debug, mess);
                    ClearOutputPins();
                    FOutputStatusBool[0] = false;
                    loggedIn             = false;
                }
            }
            else
            {
                FOutputStatus[0] = mess;
                FLogger.Log(LogType.Debug, mess);
                ClearOutputPins();
                FOutputStatusBool[0] = false;
                loggedIn             = false;
            }
        }
Пример #3
0
            public void CanPopulateObjectFromSerializedData()
            {
                var headers = new Dictionary<string, string>
                {
                    { "X-RateLimit-Limit", "100" },
                    { "X-RateLimit-Remaining", "42" },
                    { "X-RateLimit-Reset", "1372700873" }
                };

                var rateLimit = new RateLimit(headers);

                using (var stream = new MemoryStream())
                {
                    var formatter = new BinaryFormatter();
                    formatter.Serialize(stream, rateLimit);
                    stream.Position = 0;
                    var deserialized = (RateLimit)formatter.Deserialize(stream);

                    Assert.Equal(100, deserialized.Limit);
                    Assert.Equal(42, deserialized.Remaining);
                    var expectedReset = DateTimeOffset.ParseExact(
                        "Mon 01 Jul 2013 5:47:53 PM -00:00",
                        "ddd dd MMM yyyy h:mm:ss tt zzz",
                        CultureInfo.InvariantCulture);
                    Assert.Equal(expectedReset, deserialized.Reset);
                }
            }
Пример #4
0
        private async Task <GameResult> GetGameEndpoint(int gameId, int retry)
        {
            await RateLimit.WaitAsync().ConfigureAwait(false);

            var rateLimitTask = StartRatelimit();

            try
            {
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("User-Agent",
                                                     "KiteBotCore 1.1 GB Discord Bot for fetching wiki information");
                    return(JsonConvert.DeserializeObject <GameResult>(await client.GetStringAsync(_gameAPIUrl(gameId))
                                                                      .ConfigureAwait(false)));
                }
            }
            catch (TimeoutException timeoutEx)
            {
                Log.Debug(timeoutEx, timeoutEx.Message);
                if (retry > 0)
                {
                    await Task.Delay(2000).ConfigureAwait(false);

                    await rateLimitTask.ConfigureAwait(false);

                    return(await GetGameEndpoint(gameId, retry - 1).ConfigureAwait(false));
                }
                throw;
            }
        }
Пример #5
0
 public static void Postfix(RateLimit __instance, ref bool __result)
 {
     if (__result == false)
     {
         Log.Debug($"[RateLimitPatch] {__instance._usagesAllowed}:{__instance._timeWindow}");
     }
 }
Пример #6
0
        private readonly RateLimiter _privateApiRateLimiter; // Nullable.

        /// <summary>
        /// Initializes a new instance of the <see cref="KrakenClient"/> class.
        /// </summary>
        /// <param name="apiKey">Key required to make private queries to the API.</param>
        /// <param name="privateKey">Secret required to sign private messages.</param>
        /// <param name="rateLimit">
        /// Used to enable API call rate limiter conforming to Kraken rules. To disable, use <see cref="RateLimit.None"/>.
        /// </param>
        public KrakenClient(
            string apiUrl,
            string apiKey,
            string privateKey,
            RateLimit rateLimit = RateLimit.None)
        {
            if (apiKey == null)
            {
                throw new ArgumentNullException(nameof(apiKey));
            }
            if (privateKey == null)
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            ApiKey     = apiKey;
            PrivateKey = privateKey;

            RateLimit = rateLimit;
            TierInfo info = null;

            if (TierInfo.TryGetValue(rateLimit, out info))
            {
                _privateApiRateLimiter = new RateLimiter(info.Limit, info.DecreaseTime, new Stopwatch());
                // If private rate limiter enabled, also enable public rate limiter.
                _publicApiRateLimiter = new RateLimiter(20, TimeSpan.FromSeconds(1), new Stopwatch());
            }

            _httpClient.BaseAddress = new Uri(apiUrl);

            _sha512PrivateKey = new HMACSHA512(Convert.FromBase64String(privateKey));
        }
Пример #7
0
            public void CanPopulateObjectFromSerializedData()
            {
                var headers = new Dictionary <string, string>
                {
                    { "X-RateLimit-Limit", "100" },
                    { "X-RateLimit-Remaining", "42" },
                    { "X-RateLimit-Reset", "1372700873" }
                };

                var rateLimit = new RateLimit(headers);

                using (var stream = new MemoryStream())
                {
                    var formatter = new BinaryFormatter();
                    formatter.Serialize(stream, rateLimit);
                    stream.Position = 0;
                    var deserialized = (RateLimit)formatter.Deserialize(stream);

                    Assert.Equal(100, deserialized.Limit);
                    Assert.Equal(42, deserialized.Remaining);
                    var expectedReset = DateTimeOffset.ParseExact(
                        "Mon 01 Jul 2013 5:47:53 PM -00:00",
                        "ddd dd MMM yyyy h:mm:ss tt zzz",
                        CultureInfo.InvariantCulture);
                    Assert.Equal(expectedReset, deserialized.Reset);
                }
            }
Пример #8
0
        public override TimeSpan CalcReloadTime(RateLimit rateLimit)
        {
            var currentTime   = DateTimeOffset.Now.ToUniversalTime();
            var remainingTime = rateLimit.Reset - currentTime;

            // 切り捨てたいからint/intでシンプルに
            var totalRemaining = rateLimit.Remaining / CntTabs;

            if (totalRemaining == 0)
            {
                if (TimeSpan.Zero < (rateLimit.Reset - DateTimeOffset.Now))
                {
                    return(CompareMinReloadTime(remainingTime.Add(TimeSpan.FromSeconds(1.5d))));
                }
                else
                {
                    var limitDictionary = Authorization.GetToken().Application.RateLimitStatus("statuses").GetValueOrDefault("statuses");
                    if (limitDictionary.TryGetValue("/statuses/home_timeline", out var limit))
                    {
                        return(CompareMinReloadTime(CalcReloadTime(limit)));
                    }
                }
            }
            else if (totalRemaining <= Buffer)
            {
                return(CompareMinReloadTime(TimeSpan.FromTicks(remainingTime.Ticks / totalRemaining)));
            }
            return(CompareMinReloadTime(TimeSpan.FromTicks(remainingTime.Ticks / (totalRemaining - Buffer))));
        }
Пример #9
0
        public void GetDelayTest()
        {
            var limit = new RateLimit();

            // Test passing 0 for the request per hour.
            Assert.AreEqual(0, limit.GetDelay(0));

            // No web calls yet.
            Assert.AreEqual(0, limit.GetDelay(2000));

            // Test being under the limit.
            limit.AddApiCall();
            Thread.Sleep(500);
            limit.AddApiCall();
            Assert.AreEqual(0, limit.GetDelay(2000));

            // Test being over the limit.
            Thread.Sleep(500);
            limit.AddApiCall();
            Thread.Sleep(500);
            limit.AddApiCall();
            Thread.Sleep(500);
            limit.AddApiCall();
            Thread.Sleep(500);
            limit.AddApiCall();
            Assert.AreNotEqual(0, limit.GetDelay(2000));
        }
Пример #10
0
        public void ContructerTest()
        {
            var limit         = new RateLimit();
            var privateObject = new PrivateObject(limit);

            Assert.IsNotNull(privateObject.GetFieldOrProperty("_webServiceCalls"));
        }
Пример #11
0
        private async Task <Search> GetSearchEndpoint(string gameTitle, int retry)
        {
            await RateLimit.WaitAsync().ConfigureAwait(false);

            var rateLimitTask = StartRatelimit();

            try
            {
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("User-Agent", "KiteBotCore 1.1 GB Discord Bot for fetching wiki information");
                    return(JsonConvert.DeserializeObject <Search>(await client.GetStringAsync(Uri.EscapeUriString($@"{_searchAPIUrl}""{gameTitle}""")).ConfigureAwait(false)));
                }
            }
            catch (Exception)
            {
                if (retry > 0)
                {
                    await Task.Delay(2000).ConfigureAwait(false);

                    await rateLimitTask.ConfigureAwait(false);

                    return(await GetSearchEndpoint(gameTitle, retry - 1).ConfigureAwait(false));
                }
                throw new TimeoutException();
            }
        }
Пример #12
0
        static void PrintRateLimitInfo(RateLimit limit)
        {
            var percentLeft = 100 * limit.Remaining / limit.Limit;

            if (percentLeft <= 25)
            {
                Console.ForegroundColor = ConsoleColor.Red;
            }
            else if (percentLeft <= 50)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Green;
            }

            Console.Write($"{limit.Remaining} ({percentLeft}%)");
            Console.ResetColor();

            Console.Write(" API calls remaining out of " + limit.Limit + ", resetting on ");

            Console.ForegroundColor = ConsoleColor.DarkCyan;
            Console.WriteLine(limit.Reset.ToLocalTime().ToString("f"));
            Console.ResetColor();
        }
Пример #13
0
    public static void ResetRateLimit()
    {
        _semaphoreSlim.Wait();

        _apiRateLimit = new RateLimit();

        _semaphoreSlim.Release();
    }
Пример #14
0
 public static void RateLimits_ManualAwait()
 {
     TweetinviEvents.QueryBeforeExecute += (sender, args) =>
     {
         var queryRateLimit = RateLimit.GetQueryRateLimit(args.QueryURL);
         RateLimit.AwaitForQueryRateLimit(queryRateLimit);
     };
 }
Пример #15
0
 private async Task CreatePersonGroup(string groupId)
 {
     await RateLimit.Perform(async() =>
     {
         await Client.LargePersonGroup.CreateAsync(groupId, groupId);
         await Console.Error.WriteLineAsync($"Created person group {groupId}");
     });
 }
Пример #16
0
        public static void GetCurrentCredentialsRateLimits()
        {
            var tokenRateLimits = RateLimit.GetCurrentCredentialsRateLimits();

            Console.WriteLine("Remaning Requests for GetRate : {0}", tokenRateLimits.ApplicationRateLimitStatusLimit.Remaining);
            Console.WriteLine("Total Requests Allowed for GetRate : {0}", tokenRateLimits.ApplicationRateLimitStatusLimit.Limit);
            Console.WriteLine("GetRate limits will reset at : {0} local time", tokenRateLimits.ApplicationRateLimitStatusLimit.ResetDateTime.ToString("T"));
        }
Пример #17
0
        /// <summary>
        /// Make a request to a path on the API
        /// </summary>
        /// <param name="url">Path and query</param>
        /// <param name="baseUrl">Override the base url, null for the default BaseUrl</param>
        /// <param name="payload">Payload, can be null. For private API end points, the payload must contain a 'nonce' key with a string value, set to unix timestamp in milliseconds, or seconds with decimal depending on the API.</param>
        /// The encoding of payload is API dependant but is typically json.</param>
        /// <param name="method">Request method or null for default</param>
        /// <returns>Raw response</returns>
        public string MakeRequest(string url, string baseUrl = null, Dictionary <string, object> payload = null, string method = null)
        {
            RateLimit.WaitToProceed();

            if (string.IsNullOrEmpty(url))
            {
                return(null);
            }
            else if (url[0] != '/')
            {
                url = $"/{url}";
            }

            string         fullUrl = $"{(baseUrl ?? BaseUrl)}{url}";
            Uri            uri     = ProcessRequestUrl(new UriBuilder(fullUrl), payload); // new Uri(fullUrl); // new Uri("https://api.gdax.com/products/BTC-EUR/candles?granularity=3600&start=2018-01-04T06%3A31%3A19&end=2018-01-04T08%3A31%3A19"); //
            HttpWebRequest request = HttpWebRequest.CreateHttp(uri);

            request.Method                 = method ?? RequestMethod;
            request.ContentType            = RequestContentType;
            request.UserAgent              = RequestUserAgent;
            request.CachePolicy            = CachePolicy;
            request.Timeout                = (int)RequestTimeout.TotalMilliseconds;
            request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            ProcessRequest(request, payload);

            HttpWebResponse response;

            try
            {
                response = request.GetResponse() as HttpWebResponse;
                if (response == null)
                {
                    throw new APIException("Unknown response from server");
                }
            }
            catch (WebException we)
            {
                response = we.Response as HttpWebResponse;
                if (response == null)
                {
                    throw new APIException(we.Message ?? "Unknown response from server");
                }
            }
            string responseString = null;

            using (Stream responseStream = response.GetResponseStream())
            {
                responseString = new StreamReader(responseStream).ReadToEnd();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new APIException(responseString);
                }
                ProcessResponse(response);
            }
            response.Dispose();
            return(responseString);
        }
Пример #18
0
        public RateGate(RateLimit rateLimit)
        {
            _timeUnitMilliseconds = (int)rateLimit.TimspSpan.TotalMilliseconds;
            _timeoutMilliseconds  = (int)rateLimit.Timeout.TotalMilliseconds;

            _semaphore = new SemaphoreSlim(rateLimit.RequestCount, rateLimit.RequestCount);
            _exitTimes = new ConcurrentQueue <int>();
            _exitTimer = new Timer(ExitTimerCallback, null, _timeUnitMilliseconds, Timeout.Infinite);
        }
 private new Dictionary <string, object> GetNoncePayload()
 {
     RateLimit.WaitToProceed();
     return(new Dictionary <string, object>
     {
         { "nonce", ((long)DateTime.UtcNow.UnixTimestampFromDateTimeMilliseconds()).ToString() },
         { "recvWindow", 60000 }
     });
 }
Пример #20
0
        /// <summary>
        /// Make a request to a path on the API
        /// </summary>
        /// <param name="url">Path and query</param>
        /// <param name="baseUrl">Override the base url, null for the default BaseUrl</param>
        /// <param name="payload">Payload, can be null. For private API end points, the payload must contain a 'nonce' key set to GenerateNonce value.</param>
        /// The encoding of payload is API dependant but is typically json.</param>
        /// <param name="method">Request method or null for default</param>
        /// <returns>Raw response</returns>
        public string MakeRequest(string url, string baseUrl = null, Dictionary <string, object> payload = null, string method = null)
        {
            RateLimit.WaitToProceed();
            if (string.IsNullOrWhiteSpace(url))
            {
                return(null);
            }
            else if (url[0] != '/')
            {
                url = "/" + url;
            }

            string         fullUrl = (baseUrl ?? BaseUrl) + url;
            Uri            uri     = ProcessRequestUrl(new UriBuilder(fullUrl), payload);
            HttpWebRequest request = HttpWebRequest.CreateHttp(uri);

            request.Headers["Accept-Language"] = "en-us; q=1.0;";
            request.Method                 = method ?? RequestMethod;
            request.ContentType            = RequestContentType;
            request.UserAgent              = RequestUserAgent;
            request.CachePolicy            = CachePolicy;
            request.Timeout                = (int)RequestTimeout.TotalMilliseconds;
            request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            ProcessRequest(request, payload);
            HttpWebResponse response;

            try
            {
                response = request.GetResponse() as HttpWebResponse;
                if (response == null)
                {
                    throw new APIException("Unknown response from server");
                }
            }
            catch (WebException we)
            {
                response = we.Response as HttpWebResponse;
                if (response == null)
                {
                    throw new APIException(we.Message ?? "Unknown response from server");
                }
            }
            string responseString = null;

            using (Stream responseStream = response.GetResponseStream())
            {
                responseString = new StreamReader(responseStream).ReadToEnd();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new APIException(responseString);
                }
                ProcessResponse(response);
            }
            response.Dispose();
            return(responseString);
        }
Пример #21
0
    internal RateLimiter(RateLimit rateLimit, ILogger <IRateLimiter <T> >?logger)
    {
        this._serviceName = $"{typeof(RateLimiter<T>).Name}<{typeof(T).Name}>";
        this.RateLimit    = rateLimit;

        this.Logger            = logger ?? NullLogger <RateLimiter <T> > .Instance;
        this._lastUpdateTime   = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
        this._availablePermits = rateLimit.AmountOfRequests;
        this._semaphoreSlim    = new(1, 1);
    }
        public void RateLimitsAreSetCorrectly()
        {
            var rateLimit = new RateLimit(1, TimeSpan.FromSeconds(1));

            var rateLimiter = RateLimiter
                              .WithRateLimit(rateLimit)
                              .Build();

            rateLimiter.GetRateLimit().Should().Be(rateLimit);
        }
Пример #23
0
        private async Task <OperationResult <GatewayMessage> > RetryPostMessage(RateLimit rateLimit,
                                                                                string channelId, Message message)
        {
            var retryAfter = (int)rateLimit.RetryAfter * 1000;
            await Task.Delay(retryAfter);

            _logger.LogWarning("Retrying POST request after rate limit - {0}ms", retryAfter);

            return(await PostMessage(channelId, message));
        }
Пример #24
0
        private async Task <OperationResult <GatewayMessage> > RetryPutReaction(RateLimit rateLimit,
                                                                                string channelId, string messageId, Emoji emoji)
        {
            var retryAfter = (int)rateLimit.RetryAfter * 1000;
            await Task.Delay(retryAfter);

            _logger.LogWarning("Retrying PATCH request after rate limit - {0}ms", retryAfter);

            return(await AddReactionToMessage(channelId, messageId, emoji));
        }
Пример #25
0
        public RateGate(RateLimit rateLimit, IHaloSharpTimer timer)
        {
            _timeUnitMilliseconds = (int)rateLimit.TimeSpan.TotalMilliseconds;
            _timeoutMilliseconds  = (int)rateLimit.Timeout.TotalMilliseconds;

            _semaphore = new SemaphoreSlim(rateLimit.RequestCount, rateLimit.RequestCount);
            _exitTimes = new ConcurrentQueue <int>();
            timer.Setup(ExitTimerCallback, _timeUnitMilliseconds, Timeout.Infinite);
            _exitTimer = timer; //new HaloSharpTimer(ExitTimerCallback, null, _timeUnitMilliseconds, Timeout.Infinite);
        }
Пример #26
0
        /// <summary>
        /// Make a JSON request to an API end point
        /// </summary>
        /// <typeparam name="T">Type of object to parse JSON as</typeparam>
        /// <param name="url">Path and query</param>
        /// <param name="baseUrl">Override the base url, null for the default BaseUrl</param>
        /// <param name="payload">Payload, can be null. For private API end points, the payload must contain a 'nonce' key with a string value, set to unix timestamp in milliseconds, or seconds with decimal depending on the API.</param>
        /// <param name="requestMethod">Request method or null for default</param>
        /// <returns>Result decoded from JSON response</returns>
        public T MakeJsonRequest <T>(string url, string baseUrl = null, Dictionary <string, object> payload = null, string requestMethod = null)
        {
            if (payload == null)
            {
                RateLimit.WaitToProceed();
            }

            string response = MakeRequest(url, baseUrl, payload, requestMethod);

            return(JsonConvert.DeserializeObject <T>(response));
        }
Пример #27
0
        public async Task Delay_ZeroRequestsPerHour_NoDelay()
        {
            // arrange
            const int REQUESTS_PER_HOUR = 0;
            var       rateLimit         = new RateLimit(true);

            // act
            var result = await rateLimit.Delay(REQUESTS_PER_HOUR);

            Assert.Equal(0, result);
        }
Пример #28
0
        public async Task Delay_TurnedOff_NoDelay()
        {
            // arrange
            const int REQUESTS_PER_HOUR = 10;
            var       rateLimit         = new RateLimit(false);

            // act
            var result = await rateLimit.Delay(REQUESTS_PER_HOUR);

            Assert.Equal(0, result);
        }
Пример #29
0
        public void CanGetRateLimit()
        {
            var rateLimit = new RateLimit(1, TimeSpan.FromSeconds(1));

            var rateLimiter = new RateLimiter <int>(new[]
            {
                new KeyValuePair <int, RateLimit>(1, rateLimit)
            });

            rateLimiter.GetRateLimit(1).Should().Be(rateLimit);
        }
Пример #30
0
 public RateLimitChangedNotification(
     RateLimit oldLocalRateLimit,
     RateLimit newLocalRateLimit,
     RateLimit oldGlobalRateLimit,
     RateLimit newGlobalRateLimit)
 {
     OldLocalRateLimit  = oldLocalRateLimit;
     NewLocalRateLimit  = newLocalRateLimit;
     OldGlobalRateLimit = oldGlobalRateLimit;
     NewGlobalRateLimit = newGlobalRateLimit;
 }
Пример #31
0
 private async Task <IEnumerable <Person> > CreatePeople(string groupId, IEnumerable <string> names)
 {
     return(await Task.WhenAll(names.Select(name =>
                                            RateLimit.Perform(async() =>
     {
         var result = await Client.LargePersonGroupPerson.CreateAsync(groupId, name);
         await Console.Error.WriteLineAsync($"Created person {name}");
         result.Name = name;
         return result;
     }))));
 }
Пример #32
0
            public void HandlesMissingHeaderValues()
            {
                var headers = new Dictionary<string, string>();

                var rateLimit = new RateLimit(headers);

                Assert.Equal(0, rateLimit.Limit);
                Assert.Equal(0, rateLimit.Remaining);
                var expectedReset = DateTimeOffset.ParseExact(
                    "Thu 01 Jan 1970 0:00:00 AM -00:00",
                    "ddd dd MMM yyyy h:mm:ss tt zzz",
                    CultureInfo.InvariantCulture);
                Assert.Equal(expectedReset, rateLimit.Reset);
            }
Пример #33
0
            public void ParsesRateLimitsFromHeaders()
            {
                var headers = new Dictionary<string, string>
                {
                    { "X-RateLimit-Limit", "100" },
                    { "X-RateLimit-Remaining", "42" },
                    { "X-RateLimit-Reset", "1372700873" }
                };

                var rateLimit = new RateLimit(headers);

                Assert.Equal(100, rateLimit.Limit);
                Assert.Equal(42, rateLimit.Remaining);
                var expectedReset = DateTimeOffset.ParseExact(
                    "Mon 01 Jul 2013 5:47:53 PM -00:00",
                    "ddd dd MMM yyyy h:mm:ss tt zzz",
                    CultureInfo.InvariantCulture);
                Assert.Equal(expectedReset, rateLimit.Reset);
            }
Пример #34
0
            public void HandlesInvalidHeaderValues()
            {
                var headers = new Dictionary<string, string>
                {
                    { "X-RateLimit-Limit", "1234scoobysnacks1234" },
                    { "X-RateLimit-Remaining", "xanadu" },
                    { "X-RateLimit-Reset", "garbage" }
                };

                var rateLimit = new RateLimit(headers);

                Assert.Equal(0, rateLimit.Limit);
                Assert.Equal(0, rateLimit.Remaining);
                var expectedReset = DateTimeOffset.ParseExact(
                    "Thu 01 Jan 1970 0:00:00 AM -00:00",
                    "ddd dd MMM yyyy h:mm:ss tt zzz",
                    CultureInfo.InvariantCulture);
                Assert.Equal(expectedReset, rateLimit.Reset);
            }
Пример #35
0
 /// <summary>
 /// Creates a new instance of the ApiInfo class.
 /// </summary>
 /// <param name="rateLimit">The current rate limit information.</param>
 public ApiInfo(RateLimit rateLimit)
 {
     RateLimit = rateLimit;
 }
Пример #36
0
            public void CanClone()
            {
                var original = new RateLimit(100, 42, 1372700873);

                var clone = original.Clone();

                // Note the use of Assert.NotSame tests for value types - this should continue to test should the underlying 
                // model are changed to Object types
                Assert.NotSame(original, clone);
                Assert.Equal(original.Limit, clone.Limit);
                Assert.NotSame(original.Limit, clone.Limit);
                Assert.Equal(original.Remaining, clone.Remaining);
                Assert.NotSame(original.Remaining, clone.Remaining);
                Assert.Equal(original.ResetAsUtcEpochSeconds, clone.ResetAsUtcEpochSeconds);
                Assert.NotSame(original.ResetAsUtcEpochSeconds, clone.ResetAsUtcEpochSeconds);
                Assert.Equal(original.Reset, clone.Reset);
                Assert.NotSame(original.Reset, clone.Reset);
            }