Files
quantconnect--lean/Tests/Api/NodeTests.cs
T
Colton Sellers ab6027723f
Build & Test Lean / build (push) Has been cancelled
Refactor Api (#5251)
* Use lean data key as param for request

* key -> filePath rename and some cleanup

* Refactor

* Add Organizations Endpoints

* Add some organization api wrapper objects

* Address namespace issue

* Reorganize Api Test into seperate files using one ApiTestBase

* Add Organization tests

* Use capitalized "API" test namespace to reduce amount of file changes

* Add License to test base

* Update /data endpoint functions and response objects

* Update ApiDataProvider Logic

* Handle deserialization of organization products

* Simplify converter

* Only throw for equity requests when not subscribed to map/factor files

* Add missing header

* Make arguement exception

* Api adjustments

* Add Zip factor and map file providers

- Common project will now reference Compression project and not the other way
  round.
- Adding Zip FactorFile and MapFile providers

* Refactor FactorFileProvider to use DataProvider to fetch files

* Use resulting MinimumDate in construction of FactorFile

* Nit FactorFile comments and arrangement

* Refactor MapFileProviders to use DataProvider for fetching files

* Refactor ZipFileProvider

* Clean up

* Refactor Backtesting Future/Option chain providers to use dataprovider

* Fixes for data/ endpoints and test adjustments

* Response objects adjustments/cleanups

* ApiDateProvider fixes and testing

* Add LocalZipFactorFileTests

* Update ApiDataProvider download test to verify stream is not null

* Implement posting of agreement summary and signed time

* Mark all Api related tests as explicit and document details on running

* Clarify default token on ApiTestBase

* Adjust summary

* Update Api responses for QCC, except org products which are sold in USD

* Implement cache expiration for zip MapFile and FactorFiles. Adding unit tests

* Fix multiple markets for ZipFactorFile provider

* Use Symbol as cache key

* Api.cs review

* Dispose of factorFileStream after reading

* Use zip.EntryFileNames

* Address a few reviews

* Few more fixes

* Address Api Review

* Add Job Org id to config

* Minor tweaks

* Compare with invariant culture

* Fixes Option Universe selection

* ZipEntryNameSubscriptionDataSourceReader will use IDataProvider

* Fix research

* Fix null reference exception

* Make duplicate log debug

Co-authored-by: Martin-Molinero <martin@quantconnect.com>
2021-06-07 11:37:44 -03:00

166 lines
6.5 KiB
C#

/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* 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.
*/
using System;
using System.Linq;
using NUnit.Framework;
using QuantConnect.Api;
namespace QuantConnect.Tests.API
{
/// <summary>
/// Test class for all nodes/ endpoints:
/// create, read, update, delete, stop
/// </summary>
[TestFixture, Explicit("Requires configured api access, account with credit, and node creation permission")]
public class NodeTests : ApiTestBase
{
/// <summary>
/// Create a new backtest node with 2 CPU cores and 8GB of RAM check for successful
/// creation in API response.
/// </summary>
[Test]
public void CreateNewNode()
{
var sku = new SKU(2, 8, NodeType.Backtest);
var nodeName = $"{DateTime.UtcNow.Minute}:{DateTime.UtcNow.Second}-Pinocho";
var newNode = ApiClient.CreateNode(nodeName, TestOrganization, sku);
Assert.IsTrue(newNode.Success);
}
/// <summary>
/// Read all the nodes from the organization and check for a successful reply
/// from the API.
/// </summary>
[Test]
public void ReadNode()
{
var result = ApiClient.ReadNodes(TestOrganization);
Assert.IsTrue(result.Success);
}
/// <summary>
/// Create, Read, Update, and Delete a node!
/// </summary>
/// <param name="cores">Number of cores for the node</param>
/// <param name="memory">Amount of RAM in GB for the node</param>
/// <param name="target">Target environment for the node</param>
[TestCase(2, 8, NodeType.Backtest)]
[TestCase(0, 0, NodeType.Live)]
[TestCase(8, 16, NodeType.Research)]
public void CRUDNodes(int cores, int memory, NodeType target)
{
var sku = new SKU(cores, memory, target);
var nodeName = $"{DateTime.UtcNow.Minute}:{DateTime.UtcNow.Second}-Pinocho";
var nodeName2 = $"{DateTime.UtcNow.Minute}:{DateTime.UtcNow.Second}-Monstro";
// First create a new node
var createdNode = ApiClient.CreateNode(nodeName, TestOrganization, sku);
//Check for the nodes existance using the helper function
var foundNode = FindNodeByName(nodeName);
Assert.IsNotNull(foundNode);
//Update that node with a new name
var updateNodeRequest = ApiClient.UpdateNode(foundNode.Id, nodeName2, TestOrganization);
Assert.IsTrue(updateNodeRequest.Success);
//Read again and check for the new name (nodeName2)
foundNode = FindNodeByName(nodeName2);
Assert.IsNotNull(foundNode);
//Delete this node
var deleteNodeRequest = ApiClient.DeleteNode(foundNode.Id, TestOrganization);
Assert.IsTrue(deleteNodeRequest.Success);
//Read again and ensure the node does not exist.
foundNode = FindNodeByName(nodeName2);
Assert.IsNull(foundNode);
}
/// <summary>
/// Helper function for finding a node by name, used by tests that are looking
/// for a certain node.
/// With some small adjustments could be moved to an api function.
/// </summary>
/// <param name="name">Name of the node</param>
/// <returns>The Node if found, null if not</returns>
public Node FindNodeByName(string name)
{
Node result = null;
var readNodeRequest = ApiClient.ReadNodes(TestOrganization);
var allNodes = readNodeRequest.BacktestNodes.Concat(readNodeRequest.LiveNodes).Concat(readNodeRequest.ResearchNodes);
foreach (var Node in allNodes)
{
if (Node.Name == name)
{
result = Node;
break;
}
}
return result;
}
/// <summary>
/// Test to ensure SKUs are generated correctly for a given Node configuration
/// </summary>
/// <param name="cores">Number of cores</param>
/// <param name="memory">Size of memory</param>
/// <param name="target">Target node environment</param>
/// <param name="expectedResult">Expected Result</param>
[TestCase(0, 0, NodeType.Live, "L-MICRO")]
[TestCase(1, 1, NodeType.Live, "L1-1")]
[TestCase(1, 2, NodeType.Live, "L1-2")]
[TestCase(1, 4, NodeType.Live, "L1-4")]
[TestCase(2, 8, NodeType.Backtest, "B2-8")]
[TestCase(4, 12, NodeType.Backtest, "B4-12")]
[TestCase(1, 4, NodeType.Research, "R1-4")]
[TestCase(2, 8, NodeType.Research, "R2-8")]
[TestCase(4, 12, NodeType.Research, "R4-12")]
[TestCase(8, 16, NodeType.Research, "R8-16")]
public void SkuIsGeneratedCorrectly(int cores, int memory, NodeType target, string expectedResult)
{
var SKU = new SKU(cores, memory, target);
Assert.IsTrue(SKU.ToString() == expectedResult);
}
/// <summary>
/// Read in the list of nodes from an organizations and stop any
/// that are currently busy
/// </summary>
[Test]
public void ReadAndStop()
{
// Then read the nodes from the org
var readNodeRequest = ApiClient.ReadNodes(TestOrganization);
Assert.IsTrue(readNodeRequest.Success);
//Iterate through all nodes and stop them if they are running
var allNodes = readNodeRequest.BacktestNodes.Concat(readNodeRequest.LiveNodes).Concat(readNodeRequest.ResearchNodes);
foreach (var Node in allNodes)
{
// If it is busy then stop it
if (Node.Busy)
{
var stopNodeRequest = ApiClient.StopNode(Node.Id, TestOrganization);
Assert.IsTrue(stopNodeRequest.Success);
}
}
}
}
}