Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
interactions:
- request:
body: 'b''b\''b\\\''b\\\\\\\''{"subscriptions": ["00000000-0000-0000-0000-000000000000"],
"query": "project id, tags, properties | limit 2"}\\\\\\\''\\\''\'''''
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
Connection: [keep-alive]
Content-Length: ['110']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.3 (Windows-10-10.0.17134-SP0) requests/2.19.1 msrest/0.5.4
msrest_azure/0.4.34 azure-mgmt-resourcegraph/0.6.0 Azure-SDK-For-Python]
accept-language: [en-US]
method: POST
uri: https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2018-09-01-preview
response:
body: {string: '{"totalRecords":2,"count":2,"data":{"columns":[{"name":"id","type":"string"},{"name":"tags","type":"object"},{"name":"properties","type":"object"}],"rows":[["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/zarttest1faaede5-14b9-43b9-8836-3b8df81aa6f2/providers/Microsoft.StreamAnalytics/streamingjobs/zarttest28000000",{},{"provisioningState":"Succeeded","sku":{"name":"Standard"},"eventsLateArrivalMaxDelayInSeconds":5,"createdDate":"2018-07-26T01:17:29.3470000Z","compatibilityLevel":"1.0","outputErrorPolicy":"Stop","dataLocale":"en-US","jobState":"Created","package":null,"jobType":"Cloud","jobId":"00000000-0000-0000-0000-000000000000"}],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/newzarttestefd4b1a7-6480-40bb-bac5-f23376ebb04d/providers/Microsoft.Storage/storageAccounts/zarttest9b000000",{},{"provisioningState":"Succeeded","creationTime":"2018-08-04T19:23:48.4690000Z","supportsHttpsTrafficOnly":true,"trustedDirectories":["72f988bf-86f1-41af-91ab-2d7cd011db47"],"primaryEndpoints":{"blob":"https://zarttest9b000000.blob.core.windows.net/","file":"https://zarttest9b000000.file.core.windows.net/","table":"https://zarttest9b000000.table.core.windows.net/","queue":"https://zarttest9b000000.queue.core.windows.net/"},"statusOfPrimary":"available","primaryLocation":"eastus","networkAcls":{"virtualNetworkRules":[],"defaultAction":"Allow","ipRules":[],"bypass":"AzureServices"},"encryption":{"services":{"blob":{"lastEnabledTime":"2018-08-04T19:23:48.5940000Z","enabled":true},"file":{"lastEnabledTime":"2018-08-04T19:23:48.5940000Z","enabled":true}},"keySource":"Microsoft.Storage"}}]]},"facets":[],"resultTruncated":"false"}'}
headers:
cache-control: [no-cache]
content-length: ['1679']
content-type: [application/json; charset=utf-8]
date: ['Wed, 29 Aug 2018 02:06:58 GMT']
expires: ['-1']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
transfer-encoding: [chunked]
vary: [Accept-Encoding]
x-content-type-options: [nosniff]
x-ms-ratelimit-remaining-tenant-writes: ['1198']
status: {code: 200, message: OK}
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
interactions:
- request:
body: 'b''b\''b\\\''b\\\\\\\''{"subscriptions": ["00000000-0000-0000-0000-000000000000"],
"query": "project id, location | limit 10", "facets": [{"expression": "location",
"options": {"sortOrder": "desc", "$top": 4}}, {"expression": "nonExistingColumn",
"options": {"sortOrder": "desc", "$top": 4}}]}\\\\\\\''\\\''\'''''
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
Connection: [keep-alive]
Content-Length: ['270']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.3 (Windows-10-10.0.17134-SP0) requests/2.19.1 msrest/0.5.4
msrest_azure/0.4.34 azure-mgmt-resourcegraph/0.6.0 Azure-SDK-For-Python]
accept-language: [en-US]
method: POST
uri: https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2018-09-01-preview
response:
body: {string: '{"totalRecords":10,"count":10,"data":{"columns":[{"name":"id","type":"string"},{"name":"location","type":"string"}],"rows":[["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/zarttest1f000000-14b9-43b9-8836-3b8df81aa6f2/providers/Microsoft.StreamAnalytics/streamingjobs/zarttest28000000","southcentralus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test/providers/Microsoft.Storage/storageAccounts/testsouthcentralus","southcentralus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/newzarttest30000000-5d0c-432c-8652-102e3aa336b6/providers/Microsoft.Storage/storageAccounts/zarttest93000000","eastus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/backup/providers/Microsoft.ClassicCompute/domainNames/rp-a","westcentralus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test/providers/Microsoft.Storage/storageAccounts/test1","southcentralus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/k8stest_centralus/providers/Microsoft.Compute/virtualMachines/aks-default-34000000-0/extensions/cse-agent-0","centralus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/pere/providers/Microsoft.Network/networkSecurityGroups/shouldFail-nsg","eastus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/newzarttestdd000000-bfc5-44f1-b6a9-aabdc7a1e614/providers/Microsoft.Storage/storageAccounts/zarttest43000000","eastus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/newzarttest60000000-3713-4c51-9e6b-c96a30f0fbb7/providers/Microsoft.Storage/storageAccounts/zarttestd2000000","eastus"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/ManageRG/providers/Microsoft.EventHub/namespaces/resourceuse","eastus"]]},"facets":[{"expression":"location","totalRecords":4,"count":4,"data":{"columns":[{"name":"location","type":"string"},{"name":"count","type":"integer"}],"rows":[["eastus",5],["southcentralus",3],["centralus",1],["westcentralus",1]]},"resultType":"FacetResult"},{"expression":"nonExistingColumn","errors":[{"code":"NoValidColumns","message":"No
valid columns in facet expression."},{"code":"InvalidColumnNames","message":"Invalid
column names: [nonExistingColumn]."}],"resultType":"FacetError"}],"resultTruncated":"false"}'}
headers:
cache-control: [no-cache]
content-length: ['2472']
content-type: [application/json; charset=utf-8]
date: ['Wed, 29 Aug 2018 02:06:59 GMT']
expires: ['-1']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
transfer-encoding: [chunked]
vary: [Accept-Encoding]
x-content-type-options: [nosniff]
x-ms-ratelimit-remaining-tenant-writes: ['1197']
status: {code: 200, message: OK}
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
interactions:
- request:
body: 'b''b\''b\\\''b\\\\\\\''{"subscriptions": ["00000000-0000-0000-0000-000000000000"],
"query": "project id, location | where where"}\\\\\\\''\\\''\'''''
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
Connection: [keep-alive]
Content-Length: ['106']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.3 (Windows-10-10.0.17134-SP0) requests/2.19.1 msrest/0.5.4
msrest_azure/0.4.34 azure-mgmt-resourcegraph/0.6.0 Azure-SDK-For-Python]
accept-language: [en-US]
method: POST
uri: https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2018-09-01-preview
response:
body: {string: "{\"error\":{\"code\":\"InvalidQuery\",\"message\":\"Query validation
error\",\"details\":[{\"code\":\"ParserFailure\",\"message\":\"Parser failure\",\"additionalProperties\":{\"line\":1,\"characterPositionInLine\":34,\"token\":\"<EOF>\",\"expectedToken\":\"\u0178\"}}]}}"}
headers:
cache-control: [no-cache]
content-length: ['232']
content-type: [application/json; charset=utf-8]
date: ['Wed, 29 Aug 2018 02:47:47 GMT']
expires: ['-1']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
x-content-type-options: [nosniff]
x-ms-ratelimit-remaining-tenant-writes: ['1197']
status: {code: 400, message: Bad Request}
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
interactions:
- request:
body: 'b''b\''b\\\''b\\\\\\\''{"subscriptions": ["00000000-0000-0000-0000-000000000000"],
"query": "project id", "options": {"$skipToken": "82aw3vQlArEastJ24LABY8oPgQLesIyAyzYs2g6/aOOOmJHSYFj39fODurJV5e2tTFFebWcfxn7n5edicA8u6HgSJe1GCEk5HjxwLkeJiye2LVZDC7TaValkJbsk9JqY4yv5c7iRiLqgO34RbHEeVfLJpa56u4RZu0K+GpQvnBRPyAhy3KbwhZWpU5Nnqnud2whGb5WKdlL8xF7wnQaUnUN2lns8WwqwM4rc0VK4BbQt/WfWWcYJivSAyB3m4Z5g73df1KiU4C+K8auvUMpLPYVxxnKC/YZz42YslVAWXXUmuGOaM2SfLHRO6o4O9DgXlUgYjeFWqIbAkmMiVEqU",
"$top": 4, "$skip": 8}}\\\\\\\''\\\''\'''''
headers:
Accept: [application/json]
Accept-Encoding: ['gzip, deflate']
Connection: [keep-alive]
Content-Length: ['416']
Content-Type: [application/json; charset=utf-8]
User-Agent: [python/3.6.3 (Windows-10-10.0.17134-SP0) requests/2.19.1 msrest/0.5.4
msrest_azure/0.4.34 azure-mgmt-resourcegraph/0.6.0 Azure-SDK-For-Python]
accept-language: [en-US]
method: POST
uri: https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2018-09-01-preview
response:
body: {string: '{"totalRecords":743,"count":4,"data":{"columns":[{"name":"id","type":"string"}],"rows":[["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/backup/providers/Microsoft.ClassicCompute/domainNames/admin-a"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/backup/providers/Microsoft.ClassicCompute/domainNames/admin-b"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/backup/providers/Microsoft.Network/trafficmanagerprofiles/admin"],["/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/RP/providers/Microsoft.ClassicCompute/domainNames/rp-a"]]},"facets":[],"resultTruncated":"false","$skipToken":"ceXHDV/5yajn1stYtSCyQ32ULLF0jGv9oazG14qvdgwdAQNDUPHjt6MIlJZ2Y/K8z7fb+qo9wguegf8QYW0c7rqwtXUghJvKkPBENcn1O17nQxtjXeq6s8sD64D8t5P9NIHntl70D95yuVUjHF6/dsvVK33wKyvORwPTCbZrSj+pfz2yd5spa93izzOu06PcyFvcvCJAzZ5scImnVDqS700hR63izVwyETJtQluoqSPYkhxAOVk/+ThWlN0DKy9OfUE34M9PZSQz2QTWXKpUK1+okRfH/B2RVdXro60ZnNMrdPtglA5w7oEs5Ivq20IE4RtPfg97UEbkfyMP9huC="}'}
headers:
cache-control: [no-cache]
content-length: ['1098']
content-type: [application/json; charset=utf-8]
date: ['Wed, 29 Aug 2018 02:07:01 GMT']
expires: ['-1']
pragma: [no-cache]
server: [Microsoft-HTTPAPI/2.0]
strict-transport-security: [max-age=31536000; includeSubDomains]
transfer-encoding: [chunked]
vary: [Accept-Encoding]
x-content-type-options: [nosniff]
x-ms-ratelimit-remaining-tenant-writes: ['1199']
status: {code: 200, message: OK}
version: 1
180 changes: 180 additions & 0 deletions azure-mgmt-resourcegraph/tests/test_mgmt_resourcegraph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# coding: utf-8

#-------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
#--------------------------------------------------------------------------
import unittest

from azure.mgmt.resourcegraph import ResourceGraphClient
from azure.mgmt.resourcegraph.models import *
from devtools_testutils import AzureMgmtTestCase
import six


class MgmtResourceGraphTest(AzureMgmtTestCase):

def setUp(self):
super(MgmtResourceGraphTest, self).setUp()
self.resourcegraph_client = self.create_basic_client(
ResourceGraphClient
)

def test_resources_basic_query(self):
query = QueryRequest(
query='project id, tags, properties | limit 2',
subscriptions=[self.settings.SUBSCRIPTION_ID]
)

query_response = self.resourcegraph_client.resources(query)

# Top-level response fields
self.assertEqual(query_response.count, 2)
self.assertEqual(query_response.total_records, 2)
self.assertIsNone(query_response.skip_token)
self.assertEqual(query_response.result_truncated, ResultTruncated.false)
self.assertIsNotNone(query_response.data)
self.assertIsNotNone(query_response.facets)
self.assertEqual(len(query_response.facets), 0)

# Data columns
self.assertIsNotNone(query_response.data.columns)
self.assertEqual(len(query_response.data.columns), 3)
self.assertIsNotNone(query_response.data.columns[0].name)
self.assertIsNotNone(query_response.data.columns[1].name)
self.assertIsNotNone(query_response.data.columns[2].name)
self.assertEqual(query_response.data.columns[0].type, ColumnDataType.string)
self.assertEqual(query_response.data.columns[1].type, ColumnDataType.object_enum)
self.assertEqual(query_response.data.columns[2].type, ColumnDataType.object_enum)

# Data rows
self.assertIsNotNone(query_response.data.rows)
self.assertEqual(len(query_response.data.rows), 2)
self.assertEqual(len(query_response.data.rows[0]), 3)
self.assertIsInstance(query_response.data.rows[0][0], six.string_types)
self.assertIsInstance(query_response.data.rows[0][1], dict)
self.assertIsInstance(query_response.data.rows[0][2], dict)

def test_resources_query_options(self):
query = QueryRequest(
query='project id',
subscriptions=[self.settings.SUBSCRIPTION_ID],
options=QueryRequestOptions(
skip_token='82aw3vQlArEastJ24LABY8oPgQLesIyAyzYs2g6/aOOOmJHSYFj39fODurJV5e2tTFFebWcfxn7n5edicA8u6HgSJe1GCEk5HjxwLkeJiye2LVZDC7TaValkJbsk9JqY4yv5c7iRiLqgO34RbHEeVfLJpa56u4RZu0K+GpQvnBRPyAhy3KbwhZWpU5Nnqnud2whGb5WKdlL8xF7wnQaUnUN2lns8WwqwM4rc0VK4BbQt/WfWWcYJivSAyB3m4Z5g73df1KiU4C+K8auvUMpLPYVxxnKC/YZz42YslVAWXXUmuGOaM2SfLHRO6o4O9DgXlUgYjeFWqIbAkmMiVEqU',
top=4,
skip=8
)
)

query_response = self.resourcegraph_client.resources(query)

# Top-level response fields
self.assertEqual(query_response.count, 4)
self.assertEqual(query_response.total_records, 743)
self.assertIsNotNone(query_response.skip_token)
self.assertEqual(query_response.result_truncated, ResultTruncated.false)
self.assertIsNotNone(query_response.data)
self.assertIsNotNone(query_response.facets)
self.assertEqual(len(query_response.facets), 0)

# Data columns
self.assertIsNotNone(query_response.data.columns)
self.assertEqual(len(query_response.data.columns), 1)
self.assertIsNotNone(query_response.data.columns[0].name)
self.assertEqual(query_response.data.columns[0].type, ColumnDataType.string)

# Data rows
self.assertIsNotNone(query_response.data.rows)
self.assertEqual(len(query_response.data.rows), 4)
self.assertEqual(len(query_response.data.rows[0]), 1)
self.assertIsInstance(query_response.data.rows[0][0], six.string_types)

def test_resources_facet_query(self):
facet_expression0 = 'location'
facet_expression1 = 'nonExistingColumn'

query = QueryRequest(
query='project id, location | limit 10',
subscriptions=[self.settings.SUBSCRIPTION_ID],
facets=[
FacetRequest(
expression=facet_expression0,
options=FacetRequestOptions(
sort_order='desc',
top=4
)
),
FacetRequest(
expression=facet_expression1,
options=FacetRequestOptions(
sort_order='desc',
top=4
)
)
]
)

query_response = self.resourcegraph_client.resources(query)

# Top-level response fields
self.assertEqual(query_response.count, 10)
self.assertEqual(query_response.total_records, 10)
self.assertIsNone(query_response.skip_token)
self.assertEqual(query_response.result_truncated, ResultTruncated.false)
self.assertIsNotNone(query_response.data)
self.assertIsNotNone(query_response.facets)
self.assertEqual(len(query_response.facets), 2)

# Successful facet fields
self.assertIsInstance(query_response.facets[0], FacetResult)
self.assertEqual(query_response.facets[0].expression, facet_expression0)
self.assertEqual(query_response.facets[0].total_records, 4)
self.assertEqual(query_response.facets[0].count, 4)

# Successful facet columns
self.assertIsNotNone(query_response.facets[0].data.columns)
self.assertEqual(len(query_response.facets[0].data.columns), 2)
self.assertIsNotNone(query_response.facets[0].data.columns[0].name)
self.assertIsNotNone(query_response.facets[0].data.columns[1].name)
self.assertEqual(query_response.facets[0].data.columns[0].type, ColumnDataType.string)
self.assertEqual(query_response.facets[0].data.columns[1].type, ColumnDataType.integer)

# Successful facet rows
self.assertIsNotNone(query_response.facets[0].data.rows)
self.assertEqual(len(query_response.facets[0].data.rows), 4)
self.assertEqual(len(query_response.facets[0].data.rows[0]), 2)
self.assertIsInstance(query_response.facets[0].data.rows[0][0], six.string_types)
self.assertIsInstance(query_response.facets[0].data.rows[0][1], six.integer_types)

# Failed facet
self.assertIsInstance(query_response.facets[1], FacetError)
self.assertEqual(query_response.facets[1].expression, facet_expression1)
self.assertIsNotNone(query_response.facets[1].errors)
self.assertGreater(len(query_response.facets[1].errors), 0)
self.assertIsNotNone(query_response.facets[1].errors[0].code)
self.assertIsNotNone(query_response.facets[1].errors[0].message)

def test_resources_malformed_query(self):
query = QueryRequest(
query='project id, location | where where',
subscriptions=[self.settings.SUBSCRIPTION_ID]
)

with self.assertRaises(ErrorResponseException) as cm:
self.resourcegraph_client.resources(query)

error = cm.exception.error.error
self.assertIsNotNone(error.code)
self.assertIsNotNone(error.message)
self.assertIsNotNone(error.details)
self.assertGreater(len(error.details), 0)
self.assertIsNotNone(error.details[0].code)
self.assertIsNotNone(error.details[0].message)
self.assertIsNotNone(error.details[0].additional_properties)
self.assertGreater(len(error.details[0].additional_properties), 0)


#------------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()