ciocore 8.0.0b28__py2.py3-none-any.whl → 8.0.0b30__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ciocore might be problematic. Click here for more details.

Binary file
@@ -35,9 +35,9 @@ class PackageEnvironment(object):
35
35
 
36
36
  The first time data is added to a PackageEnvironment, the platform is set in stone. Subsequent `adds` that try to change the platform are considered an error.
37
37
 
38
- Each variable to be added specifies a merge_policy: `append` or `exclusive`. Once an individual variable has been initialized with a merge policy, it can't be changed. This means:
38
+ Each variable to be added specifies a merge_policy: `append`, `prepend`, or `exclusive` `append` and `prepend` can be thought of as lists= types. Once an individual variable has been initialized as a list, it can't be changed to `exclusive`. This means:
39
39
 
40
- 1. It's not possible to overwrite variables that have been set as append.
40
+ 1. It's not possible to overwrite variables that have been added as `append` or `prepend`.
41
41
  2. Exclusive variables are always overwritten by subsequent adds.
42
42
 
43
43
  Raises:
@@ -95,11 +95,13 @@ class PackageEnvironment(object):
95
95
  name = var["name"]
96
96
  value = var["value"]
97
97
  policy = var["merge_policy"]
98
- if policy not in ["append", "exclusive"]:
98
+ if policy not in ["append", "prepend", "exclusive"]:
99
99
  raise ValueError("Unexpected merge policy: %s" % policy)
100
100
 
101
101
  if policy == "append":
102
102
  self._append(name, value)
103
+ elif policy == "prepend":
104
+ self._prepend(name, value)
103
105
  else:
104
106
  self._set(name, value)
105
107
 
@@ -133,6 +135,22 @@ class PackageEnvironment(object):
133
135
  self._env[name] = []
134
136
  self._env[name].append(value)
135
137
 
138
+ def _prepend(self, name, value):
139
+ """Set the value of an append/prepend variable.
140
+
141
+ Can be appended to with subsequent adds.
142
+
143
+ It is an error if the variable has already been declared with policy=exclusive.
144
+ """
145
+ if self._env.get(name):
146
+ if not isinstance(self._env[name], list):
147
+ raise ValueError(
148
+ "Can't change merge policy for '{}' from 'exclusive' to 'prepend'.".format(name)
149
+ )
150
+ else:
151
+ self._env[name] = []
152
+ self._env[name].insert(0, value)
153
+
136
154
  def __iter__(self):
137
155
  """Cast the object as a dict."""
138
156
  sep = ";" if self.platform == "windows" else ":"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ciocore
3
- Version: 8.0.0b28
3
+ Version: 8.0.0b30
4
4
  Summary: Core functionality for Conductor's client tools
5
5
  Home-page: https://github.com/ConductorTechnologies/ciocore
6
6
  Author: conductor
@@ -51,75 +51,19 @@ See [CONTRIBUTING](CONTRIBUTING.md)
51
51
 
52
52
  ## Changelog
53
53
 
54
- ## Unreleased:
55
-
56
- * 8.0.0-beta.28
57
- * Renamed DaemonDownloader to PerpetualDownloader.
58
- * Changed argument --destination to --output-path to free up -d flag.
59
- * Beter regex filtering of filenames. Only tasks with files matching the filter contribute to the downloader's sense of task-done.
60
- * Tasks with all preexisting files are reported as downloaded.
61
- * Reporting back to the server can now be disabled. Therefore, artists can download scout frames without affecting the studio's perpetual downloader.
62
- * Added colored log lines for better clarity.
63
- * Provided more detailed info in DEBUG level logs.
64
- * Refactored PerpetualDownloader::get_some_tasks() to eliminate loops and fix bug where it was not interruptible.
65
- * Added an ASCII spinner for visual feedback while waiting for tasks.
66
-
67
- * 8.0.0-beta.26
68
- * Fix a bug where the perpetual downloader ignored Ctrl+C interrupts.
69
- * Change destination flag to output_path so that later we can introduce real daemon mode.
70
- * Report to server now reports tasks as downloaded even if they were skipped due to pre-existing.
71
- * Report to server now respects the filter and reports tasks as downloaded if the desired subset of files were downloaded.
72
- * Perpetual downloader prints an ascii spinner to the console.
73
-
74
- * 8.0.0-beta.24
75
- * adds the ability to disable reporting with a cli flag and functionality in the download runner class.
76
- * Update logger name and try to guard against multiple loggers
77
- * Add file filtering functionality to BaseDownloader and its subclasses
78
- * Ensure log to stdout so that it's greppable
79
-
80
- * 8.0.0-beta.20
81
- * Colored logging and better error detection when request for url fails.
82
-
83
- * 8.0.0-beta.19
84
- * Refactor and improvements to threading and logging.
85
-
86
- * 8.0.0-beta.18
87
- * Adds robustness to handling of Ctrl+C, errors, threads, and logging.
88
-
89
- * 8.0.0-beta.17
90
- * Ignores redundant tasks in the download queue
91
-
92
- * 8.0.0-beta.15
93
- * remove sequence checker and unnecessary dependencies
94
-
95
- * 8.0.0-beta.14
96
- * fixed permissions error bug with file downloads
97
-
98
- * 8.0.0-beta.13
99
- * fixed permissions error bug with file downloads
100
-
101
- * 8.0.0-beta.5
102
- * adds kill_tasks kill_jobs get_jobs get_log
103
- * remove old docs stuff
104
-
105
- * 8.0.0-beta.4
106
- * updates in changelog for dev
107
- * dev updates in changelog
108
- * minor
109
- * refactor datacache to use tables
110
- * some python 3 updates
111
- * fixed bug where read_creds hung
112
- * requests+chardet as charset_normalizer breaks m23
113
- * Adds DataCache class and tests
114
- * adds data cache instead of fixtures
115
- * cull bad 3dsmax entries
116
- * start data_cache
117
- * tidy based on comparison with ref repo
118
- * some formatting and fstrings
119
- * minor uploader additions
120
- * adds build_docs back in to cicd
121
- * skulk 3 compatibility
122
- * wip testing page downloader
54
+ ## Version: 8.0.0-beta.30 -- 30 Mar 2024
55
+
56
+
57
+ Major Updates in Version 8.0.0
58
+
59
+
60
+ * The `conductor` commandline interface (CLI) has undergone a complete overhaul to improve its functionality and performance. It is now installed as a Python console script, which simplifies the installation process on all platforms and ensures that the tool is always accessible. In addition, this standardized installation allows for better integration into our Companion application and potentially customers' own proprietary tools.
61
+ * The commandline downloader has been rewritten to improve its performance and reliability. In previous versions, the downloader would fetch all download URLs from the server before starting any downloads. This approach was inefficient and would lead to performance issues when handling jobs with large numbers of tasks. The new downloader fetches tasks in small batches, which allows the download to start almost immediately, regardless of the number of tasks. It provides several new commandline flags, such as filtering based on filenames, and better logging, giving users more control and visibility over the download process. In addition, the new downloader has been written as an event based system that can be seamlessly integrated into other pipeline tools and GUIs. Pipeline TDs need only to register handlers to any of the events that the downloader emits.
62
+ * The `conductor` commandline now supports a new subcommand, `docs`, which opens API and commandline documentation in a local web browser. The documentation is generated using `mkdocs` and is included in the package. This command is useful as it ensures the **API** documentation is relevant to the version of the tool being used.
63
+ * The `conductor` commandline now supports a new subcommand, `packages`, which displays all available software packages on Conductor's cloud. The command can output the document as text, markdown, or nicely formatted HTML. The data is pulled from the Conductor server and is always up-to-date.
64
+ * The Python API now provides four new endpoints: `kill_tasks`, `kill_jobs`, `get_jobs`, and `get_log`.
65
+ * The Python API now provides access to entries in the Dashboard's Extra Environment Variables section. This feature allows administrators to set environment variables that are passed to all jobs run on the cloud. It's useful for setting up access to license servers or other shared resources. The API is open to clients so that they may insert account-widse variables with the correct level of precedence.
66
+ * In addition, the environment variable schema has been extended to support a merge policy of `prepend`. This policy allows users to add new values to the beginning of the list of values for an environment variable and is useful for search paths.
123
67
 
124
68
 
125
69
  ## Version:7.0.2 -- 10 Nov 2023
@@ -1,19 +1,19 @@
1
- ciocore/VERSION,sha256=SglkYtDPwTwzGil6vhrRZdOWWjXFKgm6qw__RjsQEFw,13
1
+ ciocore/VERSION,sha256=Vkxt3Epb7bEJgkFq0a_kSETZOTosIK30xjlYmzpMRB0,13
2
2
  ciocore/__init__.py,sha256=aTP7LeeosQA8BZE67gDV4jgfTK5zxmwZRjiTRu_ZWj0,646
3
- ciocore/api_client.py,sha256=BTDGXT-59-48SLz3BzP8OtGEhBYDiiEvyytsRUxaK9I,23555
4
- ciocore/cli.py,sha256=6DaZHUBWYkRjsFft5tLrEnp2CrfX5l1i1kAJvW6Z1iI,15400
3
+ ciocore/api_client.py,sha256=TyHXGmK4uTmKV93O_IpAvttZhbexIIZTGP-IVn_WyWM,24599
4
+ ciocore/cli.py,sha256=BXgULpqElTHwX6nUcSFVVh99MCBSG2FjuOzRKhIa6Hk,15399
5
5
  ciocore/client_db.py,sha256=tTz3bl2xeDPPcYSDS3g3QgV_xYihJMx0Kj6OeN2klK0,12978
6
6
  ciocore/common.py,sha256=FnggAL-IGW8VQB6kLsrKLnxWFgLpwGBhOtiZSHz130M,14725
7
7
  ciocore/compat.py,sha256=5uEXPSog_jxsDMaHBswAKEtfyXT25VgU6WNGIhz9PHU,256
8
8
  ciocore/conductor_submit.py,sha256=ONE0LsA5hGavTJIOXXYx8qzl8_vBPADwhd6Ytq_0E0c,9382
9
9
  ciocore/config.py,sha256=rCL7kaFn1tYgSglN8q9Wx6SwMpoXTq0BMQGwPRVwVIg,8973
10
- ciocore/data.py,sha256=pO_hQGI7dwHwmfkTUjVA3WOWGn4mYbsDUG5w7hlktZ4,6791
10
+ ciocore/data.py,sha256=Ji0qUk8nJXBNakoHSqBiVx8O58SbZXyt273SHlEDn3U,7027
11
11
  ciocore/dev_inst_tagger.py,sha256=bPfoFbE7IPCpDbtbVHxW7IlMwvspdnJhPuNq-u4fJN4,3497
12
12
  ciocore/exceptions.py,sha256=4Oq-WX-qiN6kPUdBCHvvd6mtSQ0nCkDbJxWt2CNtpv8,1504
13
13
  ciocore/file_utils.py,sha256=bAlL31B4YkRgX-yT8kF8UXBFktQlsE1PvxbKqTeAeOU,17174
14
14
  ciocore/hardware_set.py,sha256=FlRQiGCLRcSW7Oko_gzgVK8ZqJ_J92eT8e_AleAbS2E,17047
15
15
  ciocore/loggeria.py,sha256=2xdQRFb9NyXynU2O_pSOszJWcpoHgPwTUWJvERg7ODY,15251
16
- ciocore/package_environment.py,sha256=9lPyZqFPnycDcGKpL8HG2XMxmblrRTK00ze8-peS5mE,7045
16
+ ciocore/package_environment.py,sha256=MEHV7jfs3NJIEYCIaW8JfJdBmelvPHZMmBzPlXETiRo,7808
17
17
  ciocore/package_query.py,sha256=2m5EBXfu1lmqupZrFF8f8mfkX_PgijpdMxCtFI5e5s0,5574
18
18
  ciocore/package_tree.py,sha256=vkORKXxQ7dO8l0_96eFwm-5AUVL0rP9bhgWYhW_v3lo,15649
19
19
  ciocore/post_install.py,sha256=zu5Ctz2ANbKD-f5G2ODLIhKkWENBi4F3UKKu50OEWrg,1000
@@ -25,15 +25,15 @@ ciocore/auth/server.py,sha256=8btX9-EokUl6q55V8muDmEV2tvvbTBD0BHeWFbwkzUc,3892
25
25
  ciocore/docsite/404.html,sha256=DQCrQsaKh8M0zlCFZmjFHUtqy7_gx_i2Rpc3OoDdDI4,17207
26
26
  ciocore/docsite/index.html,sha256=p_Dq_6_8cwZZPDI5zjahfCWUkfbSj14NJtoQFAZv0WI,20945
27
27
  ciocore/docsite/logo.png,sha256=gArgFFWdw8w985-0TkuGIgU_pW9sziEMZdqytXb5WLo,2825
28
- ciocore/docsite/objects.inv,sha256=UhlZWOqRV8tA4CzS8HKmk322X-so5ZmIe55155t_7Ls,746
28
+ ciocore/docsite/objects.inv,sha256=s2FKStLlVIQbfG7U2-nw-7rz4unvd1W0u00YtLBxAKo,758
29
29
  ciocore/docsite/sitemap.xml,sha256=M_V85zl0y2adRvzJAnoCxlZH_Hl7TLnIb1A-6l_xGmI,109
30
- ciocore/docsite/sitemap.xml.gz,sha256=xW3ehtD0sXOVA4xId_amQVbSPsc358_bj31TbIZsNik,127
31
- ciocore/docsite/apidoc/api_client/index.html,sha256=DYVIV4xZRhTEiDJoIRn-76YRjGia_ce6LDss7G2stsE,164621
30
+ ciocore/docsite/sitemap.xml.gz,sha256=tbhqnE2N3ntESeUk70fCrxZKJ1spKDyCkwJGAC9CnL0,127
31
+ ciocore/docsite/apidoc/api_client/index.html,sha256=mHDq-zdWuilDKUluzmQNdOsImRoGEnnK5Ul2ApajgdU,170218
32
32
  ciocore/docsite/apidoc/apidoc/index.html,sha256=NQn8wjapxa7O2IQhsbE7Y-VMfMFL6Tby-L7qIF6K3m4,26171
33
33
  ciocore/docsite/apidoc/config/index.html,sha256=1GWkyClM7LJlLBpx07BqCi3xDkU-SKVPjNUEeKuwbNs,72559
34
- ciocore/docsite/apidoc/data/index.html,sha256=c7FJVeXgqlaj5f_BTndVJfjADUkEJ7PyV3lLUfmiR8I,50095
34
+ ciocore/docsite/apidoc/data/index.html,sha256=9DonjpASPYZGYRHjyaodkK3AxSlTHsvm1xdq2cqMxPI,50850
35
35
  ciocore/docsite/apidoc/hardware_set/index.html,sha256=DMlpzQCy2ypJ078tcFNrZAvG2sU7P5-ZwU4ZRCObtQg,123042
36
- ciocore/docsite/apidoc/package_environment/index.html,sha256=S5IE1EgnJaaLVsEpgPogwBvj3jxT6ycNp-1GAlJrPt4,65729
36
+ ciocore/docsite/apidoc/package_environment/index.html,sha256=M2L6Pu00jYj5AdhHQXrNZjOKVWCXYtgL8I34zL6B0i4,69248
37
37
  ciocore/docsite/apidoc/package_tree/index.html,sha256=wKW5dsHBlcDyvCGakSNzYHX8z99F1Vhu2NyqAW6c1ko,109393
38
38
  ciocore/docsite/assets/_mkdocstrings.css,sha256=K3bqYEmxlOHQ3-M11JNbBWHCBDBLarkFRm8HuEYrAG4,341
39
39
  ciocore/docsite/assets/images/favicon.png,sha256=AjhUxD_Eslt5XuSVHIAZ494Fk__rb5GLXR8qm0elfP4,1870
@@ -82,7 +82,7 @@ ciocore/docsite/cmdline/downloader/index.html,sha256=DAVErhWEPuEtkQr7y9D_wjylzM9
82
82
  ciocore/docsite/cmdline/packages/index.html,sha256=j1YeMgdwZ6FyJGJii05AdtUWKRjyu1fOr3_bKJsLfEU,20923
83
83
  ciocore/docsite/cmdline/uploader/index.html,sha256=y0728lIAYC4b9mfpjNVfwQqXoqJrsdG49UY5u7B1p94,25123
84
84
  ciocore/docsite/how-to-guides/index.html,sha256=OFrFBTb9tuMn60Jd4oeM10Mw-d-0pyqwoKoo9g1biBM,20100
85
- ciocore/docsite/search/search_index.json,sha256=t-RJBVqxWPIzkjKMY9dMfpuwzVnJIeHkrZ6eWHrmkLM,179918
85
+ ciocore/docsite/search/search_index.json,sha256=ZMAbHLAlwOTujgA32XJTA7SHogRYh9i-ioPFOxjjJ0s,182633
86
86
  ciocore/docsite/stylesheets/extra.css,sha256=qgfcao9TEBzf6ieAWN5rPyrea7YM_YgVg5qr4NPrxoU,354
87
87
  ciocore/docsite/stylesheets/tables.css,sha256=O2PEwlKC0RfvZCRV9UERqQRvhb6jcqO84PLew0bafF0,3279
88
88
  ciocore/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -100,10 +100,11 @@ ciocore/uploader/_uploader.py,sha256=AaCwRo1rGkdMA-XACx9k4Z73R97ndJUVMemUZNV-Ark
100
100
  ciocore/uploader/upload_stats/__init__.py,sha256=Lg1y4zq1i0cwc6Hh2K1TAQDYymLff49W-uIo1xjcvdI,5309
101
101
  ciocore/uploader/upload_stats/stats_formats.py,sha256=giNirtObU66VALWghPFSRhg3q_vw5MvESsnXhb_I3y8,2402
102
102
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
+ tests/extra_env_fixtures.py,sha256=8qvU4d8SXGKzRVNR5whVqKCQOwOVMiFVfbKBAjxa2gE,1119
103
104
  tests/instance_type_fixtures.py,sha256=uIzQduqKQVgjllMuyXaYnRC-pwqk5lnTx3NY2M5Nujo,4320
104
105
  tests/package_fixtures.py,sha256=CsJnhB7oYzIxJH7b1tCOPyvnnVSCqEbSPhtCnsHL-nA,5070
105
106
  tests/project_fixtures.py,sha256=iBm_th_JtAw76vlNu7Jjhh9tLH4oOaNi-MgtPzCV7yQ,138
106
- tests/test_api_client.py,sha256=lDUkVi6Xq1ilkSepFLebgBAhgchumvfyZnTtei1fnrI,3642
107
+ tests/test_api_client.py,sha256=tnYkIYvDILGJRatZM0nrtr83x8yBJstMP0Rt151U2gI,6757
107
108
  tests/test_base_downloader.py,sha256=SS7tWKv2ZZhpUDk4UCg1TkrNrpntjSewgzLl1mEubSE,3603
108
109
  tests/test_cli.py,sha256=yWWGLip8WgnDAB0vg7uhBU5eeEJieFLQ78Pn7IN-uWI,6088
109
110
  tests/test_common.py,sha256=tY_-SY-JmJX09UehFs9RIDqZ785AmhfTl6eVKJeIUFY,763
@@ -120,8 +121,8 @@ tests/test_uploader.py,sha256=B1llTJt_fqR6e_V_Jxfw9z73QgkFlEPU87xLYGzt-TQ,2914
120
121
  tests/test_validator.py,sha256=2fY66ayNc08PGyj2vTI-V_1yeCWJDngkj2zkUM5TTCI,1526
121
122
  tests/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
123
  tests/mocks/glob.py,sha256=J2MH7nqi6NJOHuGdVWxhfeBd700_Ckj6cLh_8jSNkfg,215
123
- ciocore-8.0.0b28.dist-info/METADATA,sha256=FScRnzjzJwKZZnKRD0qMR9_NTFfAtSTHotBOG5uvP-M,18209
124
- ciocore-8.0.0b28.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
125
- ciocore-8.0.0b28.dist-info/entry_points.txt,sha256=cCqcALMYbC4d8545V9w0Zysfg9MVuKWhzDQ2er4UfGE,47
126
- ciocore-8.0.0b28.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
127
- ciocore-8.0.0b28.dist-info/RECORD,,
124
+ ciocore-8.0.0b30.dist-info/METADATA,sha256=kTpsGj7FxL7iWHOoxVXXifNG-Zi75_KJvRbUTCJAzto,18201
125
+ ciocore-8.0.0b30.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
126
+ ciocore-8.0.0b30.dist-info/entry_points.txt,sha256=cCqcALMYbC4d8545V9w0Zysfg9MVuKWhzDQ2er4UfGE,47
127
+ ciocore-8.0.0b30.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
128
+ ciocore-8.0.0b30.dist-info/RECORD,,
@@ -0,0 +1,57 @@
1
+
2
+
3
+ EXTRA_ENV = [
4
+ {
5
+ "account_id": "6649535867387904",
6
+ "env": [],
7
+ },
8
+ {
9
+ "account_id": "5767615549800448",
10
+ "env": [
11
+ {
12
+ "merge_policy": "prepend",
13
+ "name": "test",
14
+ "value": "test"
15
+ }
16
+ ],
17
+ },
18
+ {
19
+ "account_id": "6649535867387904",
20
+ "env": [],
21
+ },
22
+ {
23
+ "account_id": "5669544198668288",
24
+ "env": [
25
+ {
26
+ "merge_policy": "append",
27
+ "name": "PATH",
28
+ "value": "/path/to/scripts"
29
+ },
30
+ {
31
+ "merge_policy": "exclusive",
32
+ "name": "RENDER_LOCATION",
33
+ "value": "cloud"
34
+ },
35
+ {
36
+ "merge_policy": "exclusive",
37
+ "name": "VARIABLE_USED_IN_SCRIPTS",
38
+ "value": "true"
39
+ },
40
+ {
41
+ "merge_policy": "exclusive",
42
+ "name": "testvar",
43
+ "value": "somevalue"
44
+ }
45
+ ],
46
+ },
47
+ {
48
+ "account_id": "6649535867387904",
49
+ "env": [
50
+ {
51
+ "merge_policy": "exclusive",
52
+ "name": "JMEYER",
53
+ "value": "JMEYER_ENV_VALUE"
54
+ }
55
+ ],
56
+ }
57
+ ]
tests/test_api_client.py CHANGED
@@ -4,7 +4,7 @@
4
4
  """
5
5
  import sys
6
6
  import unittest
7
-
7
+ import json
8
8
  try:
9
9
  from unittest import mock
10
10
  except ImportError:
@@ -12,6 +12,7 @@ except ImportError:
12
12
 
13
13
  from ciocore import api_client
14
14
 
15
+ from ciocore.api_client import request_extra_environment
15
16
 
16
17
  class ApiClientTest(unittest.TestCase):
17
18
  @staticmethod
@@ -105,3 +106,61 @@ class TestRegisterClient(unittest.TestCase):
105
106
 
106
107
  self.assertTrue(user_agent.startswith(expected_user_agent))
107
108
 
109
+
110
+ class TestRequestExtraEnvironment(unittest.TestCase):
111
+
112
+ def setUp(self):
113
+ self.api_response_data = {
114
+ "data": [
115
+ {"account_id": "123", "env": ["VAR1=value1", "VAR2=value2"]},
116
+ {"account_id": "456", "env": ["VAR3=value3", "VAR4=value4"]}
117
+ ]
118
+ }
119
+ self.response_ok = mock.MagicMock(status_code=200, text=json.dumps(self.api_response_data))
120
+ self.response_error = mock.MagicMock(status_code=500, text=json.dumps({"error": "Internal Server Error"}))
121
+
122
+ @mock.patch("ciocore.api_client.ApiClient")
123
+ @mock.patch("ciocore.api_client.read_conductor_credentials")
124
+ @mock.patch("ciocore.api_client.account_id_from_jwt")
125
+ def test_request_extra_environment_success(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
126
+ # Set up mocks for successful execution
127
+ mock_read_conductor_credentials.return_value = "valid_token"
128
+ mock_account_id_from_jwt.return_value = "123"
129
+ mock_api_instance = mock_ApiClient.return_value
130
+ mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
131
+
132
+ result = request_extra_environment()
133
+
134
+ self.assertEqual(result, ["VAR1=value1", "VAR2=value2"])
135
+ mock_ApiClient.assert_called_once()
136
+ mock_read_conductor_credentials.assert_called_once_with(True)
137
+ mock_account_id_from_jwt.assert_called_once_with("valid_token")
138
+
139
+ @mock.patch("ciocore.api_client.ApiClient")
140
+ def test_request_extra_environment_api_failure(self, mock_ApiClient):
141
+ # Set up mock for API failure
142
+ mock_api_instance = mock_ApiClient.return_value
143
+ mock_api_instance.make_request.return_value = (self.response_error.text, self.response_error.status_code)
144
+
145
+ # Assert exception raised when the API call fails
146
+ with self.assertRaises(Exception) as context:
147
+ request_extra_environment()
148
+
149
+ self.assertIn('Failed to get extra environment', str(context.exception))
150
+ mock_ApiClient.assert_called_once()
151
+
152
+ @mock.patch("ciocore.api_client.ApiClient")
153
+ @mock.patch("ciocore.api_client.read_conductor_credentials")
154
+ @mock.patch("ciocore.api_client.account_id_from_jwt")
155
+ def test_request_extra_environment_no_account_env(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
156
+ # Set up mocks to simulate valid token and account ID but no matching environment
157
+ mock_read_conductor_credentials.return_value = "valid_token"
158
+ mock_account_id_from_jwt.return_value = "invalid_id" # This won't match any 'account_id' in response
159
+ mock_api_instance = mock_ApiClient.return_value
160
+ mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
161
+
162
+ with self.assertRaises(Exception) as context:
163
+ request_extra_environment()
164
+
165
+ self.assertEqual("Error: Could not get account environment!", str(context.exception))
166
+ mock_ApiClient.assert_called_once()