1
- import { DisposableCollection } from '@theia/core/lib/common/disposable' ;
1
+ import {
2
+ Disposable ,
3
+ DisposableCollection ,
4
+ } from '@theia/core/lib/common/disposable' ;
2
5
import { deepClone } from '@theia/core/lib/common/objects' ;
3
6
import type { MaybePromise , Mutable } from '@theia/core/lib/common/types' ;
4
- import { Container } from '@theia/core/shared/inversify' ;
7
+ import type { Container } from '@theia/core/shared/inversify' ;
5
8
import { expect } from 'chai' ;
6
9
import { load as parseYaml } from 'js-yaml' ;
7
10
import { promises as fs } from 'node:fs' ;
8
- import { Config , Network } from '../../common/protocol/config-service' ;
11
+ import { join } from 'node:path' ;
12
+ import temp from 'temp' ;
13
+ import {
14
+ Config ,
15
+ Network ,
16
+ ProxySettings ,
17
+ } from '../../common/protocol/config-service' ;
9
18
import { CLI_CONFIG , DefaultCliConfig } from '../../node/cli-config' ;
10
19
import { ConfigServiceImpl } from '../../node/config-service-impl' ;
11
20
import { ConfigDirUriProvider } from '../../node/theia/env-variables/env-variables-server' ;
12
- import { createBaseContainer , startDaemon } from './node-test-bindings' ;
21
+ import {
22
+ createBaseContainer ,
23
+ createCliConfig ,
24
+ startDaemon ,
25
+ } from './node-test-bindings' ;
13
26
14
27
describe ( 'config-service-impl' , ( ) => {
15
- describe ( 'setConfiguration' , ( ) => {
16
- const manualProxy : Network = {
17
- protocol : 'http' ,
18
- hostname : 'hostname' ,
19
- password : 'secret' ,
20
- username : 'username' ,
21
- port : '1234' ,
22
- } ;
23
- const noProxy : Network = 'none' ;
28
+ const noProxy = 'none' ;
29
+ const manualProxy : ProxySettings = {
30
+ protocol : 'http' ,
31
+ hostname : 'hostname' ,
32
+ password : 'secret' ,
33
+ username : 'username' ,
34
+ port : '1234' ,
35
+ } ;
24
36
37
+ describe ( 'setConfiguration' , ( ) => {
25
38
let configService : ConfigServiceImpl ;
26
39
let toDispose : DisposableCollection ;
27
40
let cliConfigPath : string ;
28
41
29
42
beforeEach ( async ( ) => {
30
- const container = await createContainer ( ) ;
43
+ const container = await createBaseContainer ( ) ;
31
44
toDispose = new DisposableCollection ( ) ;
32
45
await startDaemon ( container , toDispose ) ;
33
46
configService = container . get < ConfigServiceImpl > ( ConfigServiceImpl ) ;
34
- const configDirUriProvider =
35
- container . get < ConfigDirUriProvider > ( ConfigDirUriProvider ) ;
36
- cliConfigPath = configDirUriProvider
37
- . configDirUri ( )
38
- . resolve ( CLI_CONFIG )
39
- . path . fsPath ( ) ;
47
+ cliConfigPath = getCliConfigPath ( container ) ;
40
48
} ) ;
41
49
42
50
afterEach ( ( ) => toDispose . dispose ( ) ) ;
@@ -47,7 +55,7 @@ describe('config-service-impl', () => {
47
55
const config = < Config > state . config ;
48
56
expect ( config . network ) . to . be . equal ( noProxy ) ;
49
57
expect ( Network . stringify ( config . network ) ) . is . undefined ;
50
- await assertRawConfigModel ( ( actualModel ) => {
58
+ await assertRawConfigModel ( cliConfigPath , ( actualModel ) => {
51
59
expect ( actualModel . network ) . to . be . undefined ;
52
60
} ) ;
53
61
} ) ;
@@ -74,7 +82,7 @@ describe('config-service-impl', () => {
74
82
expect ( beforeState . config ) . to . be . not . deep . equal ( afterState . config ) ;
75
83
expect ( afterState . config ?. network ) . to . be . deep . equal ( manualProxy ) ;
76
84
expect ( eventCounter ) . to . be . equal ( 1 ) ;
77
- await assertRawConfigModel ( ( actualModel ) => {
85
+ await assertRawConfigModel ( cliConfigPath , ( actualModel ) => {
78
86
expect ( actualModel . network ?. proxy ) . to . be . equal (
79
87
Network . stringify ( manualProxy )
80
88
) ;
@@ -96,21 +104,75 @@ describe('config-service-impl', () => {
96
104
expect ( beforeState . config ) . to . be . not . deep . equal ( afterState . config ) ;
97
105
expect ( afterState . config ?. network ) . to . be . deep . equal ( noProxy ) ;
98
106
expect ( eventCounter ) . to . be . equal ( 2 ) ;
99
- await assertRawConfigModel ( ( actualModel ) => {
107
+ await assertRawConfigModel ( cliConfigPath , ( actualModel ) => {
100
108
expect ( actualModel . network ?. proxy ) . to . be . undefined ;
101
109
} ) ;
102
110
} ) ;
111
+ } ) ;
112
+
113
+ describe ( 'setConfiguration (multiple CLI daemon sessions)' , ( ) => {
114
+ let tracked : typeof temp ;
115
+ let toDispose : DisposableCollection ;
116
+
117
+ before ( ( ) => {
118
+ tracked = temp . track ( ) ;
119
+ toDispose = new DisposableCollection (
120
+ Disposable . create ( ( ) => tracked . cleanupSync ( ) )
121
+ ) ;
122
+ } ) ;
123
+
124
+ after ( ( ) => toDispose . dispose ( ) ) ;
125
+
126
+ it ( "should unset the 'network#proxy' config value between daemon sessions" , async ( ) => {
127
+ const configDirPath = tracked . mkdirSync ( ) ;
128
+ const cliConfigPath = join ( configDirPath , CLI_CONFIG ) ;
129
+ const cliConfig = await createCliConfig ( configDirPath ) ;
130
+ const setupContainer = await createBaseContainer ( {
131
+ cliConfig,
132
+ configDirPath,
133
+ } ) ;
134
+ const toDisposeAfterFirstStart = new DisposableCollection ( ) ;
135
+ toDispose . push ( toDisposeAfterFirstStart ) ;
136
+ await startDaemon ( setupContainer , toDisposeAfterFirstStart ) ;
137
+ toDisposeAfterFirstStart . dispose ( ) ;
138
+
139
+ // second startup when the indexes are all downloaded and the daemon is initialized with the network#proxy
140
+ cliConfig . network = { proxy : Network . stringify ( manualProxy ) } ;
141
+ const container = await createBaseContainer ( { cliConfig, configDirPath } ) ;
142
+ await startDaemon ( container , toDispose ) ;
143
+ const configService = container . get < ConfigServiceImpl > ( ConfigServiceImpl ) ;
144
+ let eventCounter = 0 ;
145
+ toDispose . push ( configService . onConfigChange ( ( ) => eventCounter ++ ) ) ;
103
146
104
- async function createContainer ( ) : Promise < Container > {
105
- return createBaseContainer ( ) ;
106
- }
107
-
108
- async function assertRawConfigModel (
109
- assert : ( actual : DefaultCliConfig ) => MaybePromise < void >
110
- ) : Promise < void > {
111
- const raw = await fs . readFile ( cliConfigPath , { encoding : 'utf8' } ) ;
112
- const model = parseYaml ( raw ) ;
113
- await assert ( model ) ;
114
- }
147
+ const beforeState = await configService . getConfiguration ( ) ;
148
+ const config = < Mutable < Config > > deepClone ( beforeState . config ) ;
149
+ config . network = noProxy ;
150
+ await configService . setConfiguration ( config ) ;
151
+ const afterState = await configService . getConfiguration ( ) ;
152
+ expect ( beforeState . config ) . to . be . not . deep . equal ( afterState . config ) ;
153
+ expect ( afterState . config ?. network ) . to . be . deep . equal ( noProxy ) ;
154
+ expect ( eventCounter ) . to . be . equal ( 1 ) ;
155
+ await assertRawConfigModel ( cliConfigPath , ( actualModel ) => {
156
+ expect ( actualModel . network ?. proxy ) . to . be . undefined ; // currently fails due to arduino/arduino-cli#2275
157
+ } ) ;
158
+ } ) ;
115
159
} ) ;
160
+
161
+ async function assertRawConfigModel (
162
+ cliConfigPath : string ,
163
+ assert : ( actual : DefaultCliConfig ) => MaybePromise < void >
164
+ ) : Promise < void > {
165
+ const raw = await fs . readFile ( cliConfigPath , { encoding : 'utf8' } ) ;
166
+ const model = parseYaml ( raw ) ;
167
+ await assert ( model ) ;
168
+ }
169
+
170
+ function getCliConfigPath ( container : Container ) : string {
171
+ const configDirUriProvider =
172
+ container . get < ConfigDirUriProvider > ( ConfigDirUriProvider ) ;
173
+ return configDirUriProvider
174
+ . configDirUri ( )
175
+ . resolve ( CLI_CONFIG )
176
+ . path . fsPath ( ) ;
177
+ }
116
178
} ) ;
0 commit comments