Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
a7e1d16b
Commit
a7e1d16b
authored
Oct 23, 2019
by
Miguel Rincon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Vuex store for logs
- Add environments and logs page - Simplify error handling for environments
parent
92490c32
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
561 additions
and
0 deletions
+561
-0
ee/app/assets/javascripts/logs/stores/actions.js
ee/app/assets/javascripts/logs/stores/actions.js
+70
-0
ee/app/assets/javascripts/logs/stores/getters.js
ee/app/assets/javascripts/logs/stores/getters.js
+9
-0
ee/app/assets/javascripts/logs/stores/index.js
ee/app/assets/javascripts/logs/stores/index.js
+23
-0
ee/app/assets/javascripts/logs/stores/mutation_types.js
ee/app/assets/javascripts/logs/stores/mutation_types.js
+14
-0
ee/app/assets/javascripts/logs/stores/mutations.js
ee/app/assets/javascripts/logs/stores/mutations.js
+49
-0
ee/app/assets/javascripts/logs/stores/state.js
ee/app/assets/javascripts/logs/stores/state.js
+27
-0
ee/spec/frontend/logs/mock_data.js
ee/spec/frontend/logs/mock_data.js
+40
-0
ee/spec/frontend/logs/stores/actions_spec.js
ee/spec/frontend/logs/stores/actions_spec.js
+181
-0
ee/spec/frontend/logs/stores/mutations_spec.js
ee/spec/frontend/logs/stores/mutations_spec.js
+145
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
ee/app/assets/javascripts/logs/stores/actions.js
0 → 100644
View file @
a7e1d16b
import
{
backOff
}
from
'
~/lib/utils/common_utils
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
flash
from
'
~/flash
'
;
import
{
s__
}
from
'
~/locale
'
;
import
*
as
types
from
'
./mutation_types
'
;
const
requestUntilData
=
(
url
,
params
)
=>
backOff
((
next
,
stop
)
=>
{
axios
.
get
(
url
,
{
params
,
})
.
then
(
res
=>
{
if
(
!
res
.
data
)
{
next
();
return
;
}
stop
(
res
);
})
.
catch
(
err
=>
{
stop
(
err
);
});
});
export
const
setLogsEndpoint
=
({
commit
},
logsEndpoint
)
=>
{
commit
(
types
.
SET_LOGS_ENDPOINT
,
logsEndpoint
);
};
export
const
fetchEnvironments
=
({
commit
},
environmentsPath
)
=>
{
commit
(
types
.
REQUEST_ENVIRONMENTS_DATA
);
axios
.
get
(
environmentsPath
)
.
then
(({
data
})
=>
{
commit
(
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
,
data
.
environments
);
})
.
catch
(()
=>
{
commit
(
types
.
RECEIVE_ENVIRONMENTS_DATA_ERROR
);
flash
(
s__
(
'
Metrics|There was an error fetching the environments data, please try again
'
));
});
};
export
const
fetchLogs
=
({
commit
,
state
},
podName
)
=>
{
if
(
podName
)
{
commit
(
types
.
SET_CURRENT_POD_NAME
,
podName
);
}
commit
(
types
.
REQUEST_PODS_DATA
);
commit
(
types
.
REQUEST_LOGS_DATA
);
return
requestUntilData
(
state
.
logs
.
endpoint
,
{
pod_name
:
podName
})
.
then
(
res
=>
res
.
data
)
.
then
(
data
=>
{
const
{
pods
,
logs
}
=
data
;
// Set first pod as default, if none is set
if
(
!
podName
&&
pods
[
0
])
{
commit
(
types
.
SET_CURRENT_POD_NAME
,
pods
[
0
]);
}
commit
(
types
.
RECEIVE_PODS_DATA_SUCCESS
,
pods
);
commit
(
types
.
RECEIVE_LOGS_DATA_SUCCESS
,
logs
);
})
.
catch
(()
=>
{
commit
(
types
.
RECEIVE_PODS_DATA_ERROR
);
commit
(
types
.
RECEIVE_LOGS_DATA_ERROR
);
flash
(
s__
(
'
Metrics|There was an error fetching the logs, please try again
'
));
});
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export
default
()
=>
{};
ee/app/assets/javascripts/logs/stores/getters.js
0 → 100644
View file @
a7e1d16b
export
const
trace
=
state
=>
{
if
(
state
.
logs
.
lines
)
{
return
state
.
logs
.
lines
.
join
(
'
\n
'
);
}
return
''
;
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export
default
()
=>
{};
ee/app/assets/javascripts/logs/stores/index.js
0 → 100644
View file @
a7e1d16b
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
*
as
actions
from
'
./actions
'
;
import
*
as
getters
from
'
./getters
'
;
import
mutations
from
'
./mutations
'
;
import
state
from
'
./state
'
;
Vue
.
use
(
Vuex
);
export
const
createStore
=
()
=>
new
Vuex
.
Store
({
modules
:
{
environmentLogs
:
{
namespaced
:
true
,
actions
,
mutations
,
state
,
getters
,
},
},
});
export
default
createStore
;
ee/app/assets/javascripts/logs/stores/mutation_types.js
0 → 100644
View file @
a7e1d16b
export
const
SET_LOGS_ENDPOINT
=
'
SET_LOGS_ENDPOINT
'
;
export
const
SET_CURRENT_POD_NAME
=
'
SET_CURRENT_POD_NAME
'
;
export
const
REQUEST_ENVIRONMENTS_DATA
=
'
REQUEST_ENVIRONMENTS_DATA
'
;
export
const
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
=
'
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
'
;
export
const
RECEIVE_ENVIRONMENTS_DATA_ERROR
=
'
RECEIVE_ENVIRONMENTS_DATA_ERROR
'
;
export
const
REQUEST_LOGS_DATA
=
'
REQUEST_LOGS_DATA
'
;
export
const
RECEIVE_LOGS_DATA_SUCCESS
=
'
RECEIVE_LOGS_DATA_SUCCESS
'
;
export
const
RECEIVE_LOGS_DATA_ERROR
=
'
RECEIVE_LOGS_DATA_ERROR
'
;
export
const
REQUEST_PODS_DATA
=
'
REQUEST_PODS_DATA
'
;
export
const
RECEIVE_PODS_DATA_SUCCESS
=
'
RECEIVE_PODS_DATA_SUCCESS
'
;
export
const
RECEIVE_PODS_DATA_ERROR
=
'
RECEIVE_PODS_DATA_ERROR
'
;
ee/app/assets/javascripts/logs/stores/mutations.js
0 → 100644
View file @
a7e1d16b
import
*
as
types
from
'
./mutation_types
'
;
export
default
{
[
types
.
SET_LOGS_ENDPOINT
](
state
,
endpoint
)
{
state
.
logs
.
endpoint
=
endpoint
;
},
[
types
.
SET_CURRENT_POD_NAME
](
state
,
podName
)
{
state
.
pods
.
current
=
podName
;
},
[
types
.
REQUEST_ENVIRONMENTS_DATA
](
state
)
{
state
.
environments
.
options
=
[];
state
.
environments
.
isLoading
=
true
;
},
[
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
](
state
,
environmentOptions
)
{
state
.
environments
.
options
=
environmentOptions
;
state
.
environments
.
isLoading
=
false
;
},
[
types
.
RECEIVE_ENVIRONMENTS_DATA_ERROR
](
state
)
{
state
.
environments
.
options
=
[];
state
.
environments
.
isLoading
=
false
;
},
[
types
.
REQUEST_LOGS_DATA
](
state
)
{
state
.
logs
.
lines
=
[];
state
.
logs
.
isLoading
=
true
;
state
.
logs
.
isComplete
=
false
;
},
[
types
.
RECEIVE_LOGS_DATA_SUCCESS
](
state
,
lines
)
{
state
.
logs
.
lines
=
lines
;
state
.
logs
.
isLoading
=
false
;
state
.
logs
.
isComplete
=
true
;
},
[
types
.
RECEIVE_LOGS_DATA_ERROR
](
state
)
{
state
.
logs
.
lines
=
[];
state
.
logs
.
isLoading
=
false
;
state
.
logs
.
isComplete
=
true
;
},
[
types
.
REQUEST_PODS_DATA
](
state
)
{
state
.
pods
.
options
=
[];
},
[
types
.
RECEIVE_PODS_DATA_SUCCESS
](
state
,
podOptions
)
{
state
.
pods
.
options
=
podOptions
;
},
[
types
.
RECEIVE_PODS_DATA_ERROR
](
state
)
{
state
.
pods
.
options
=
[];
},
};
ee/app/assets/javascripts/logs/stores/state.js
0 → 100644
View file @
a7e1d16b
export
default
()
=>
({
/**
* Environments list information
*/
environments
:
{
options
:
[],
isLoading
:
false
,
},
/**
* Logs including trace
*/
logs
:
{
endpoint
:
null
,
lines
:
[],
isLoading
:
false
,
isComplete
:
true
,
},
/**
* Pods list information
*/
pods
:
{
options
:
[],
current
:
null
,
},
});
ee/spec/frontend/logs/mock_data.js
0 → 100644
View file @
a7e1d16b
const
makeMockLogsPath
=
id
=>
`/root/autodevops-deploy/environments/
${
id
}
/logs`
;
const
makeMockEnvironment
=
(
id
,
name
)
=>
({
id
,
logs_path
:
makeMockLogsPath
(
id
),
name
,
});
export
const
mockEnvironment
=
makeMockEnvironment
(
99
,
'
production
'
);
export
const
mockEnvironmentsEndpoint
=
'
/root/autodevops-deploy/environments.json
'
;
export
const
mockEnvironments
=
[
mockEnvironment
,
makeMockEnvironment
(
101
,
'
staging
'
),
makeMockEnvironment
(
102
,
'
review/a-feature
'
),
];
export
const
mockPodName
=
'
production-764c58d697-aaaaa
'
;
export
const
mockPods
=
[
mockPodName
,
'
production-764c58d697-bbbbb
'
,
'
production-764c58d697-ccccc
'
,
'
production-764c58d697-ddddd
'
,
];
export
const
mockLogsEndpoint
=
`/root/autodevops-deploy/environments/
${
mockEnvironment
.
id
}
/logs.json`
;
export
const
mockLines
=
[
'
10.36.0.1 - - [16/Oct/2019:06:29:48 UTC] "GET / HTTP/1.1" 200 13
'
,
'
- -> /
'
,
'
10.36.0.1 - - [16/Oct/2019:06:29:57 UTC] "GET / HTTP/1.1" 200 13
'
,
'
- -> /
'
,
'
10.36.0.1 - - [16/Oct/2019:06:29:58 UTC] "GET / HTTP/1.1" 200 13
'
,
'
- -> /
'
,
'
10.36.0.1 - - [16/Oct/2019:06:30:07 UTC] "GET / HTTP/1.1" 200 13
'
,
'
- -> /
'
,
'
10.36.0.1 - - [16/Oct/2019:06:30:08 UTC] "GET / HTTP/1.1" 200 13
'
,
'
- -> /
'
,
'
10.36.0.1 - - [16/Oct/2019:06:30:17 UTC] "GET / HTTP/1.1" 200 13
'
,
'
- -> /
'
,
'
10.36.0.1 - - [16/Oct/2019:06:30:18 UTC] "GET / HTTP/1.1" 200 13
'
,
'
- -> /
'
,
];
ee/spec/frontend/logs/stores/actions_spec.js
0 → 100644
View file @
a7e1d16b
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
*
as
types
from
'
ee/logs/stores/mutation_types
'
;
import
logsPageState
from
'
ee/logs/stores/state
'
;
import
{
setLogsEndpoint
,
fetchEnvironments
,
fetchLogs
}
from
'
ee/logs/stores/actions
'
;
import
flash
from
'
~/flash
'
;
import
{
mockLogsEndpoint
,
mockEnvironments
,
mockPods
,
mockPodName
,
mockLines
,
mockEnvironmentsEndpoint
,
}
from
'
../mock_data
'
;
jest
.
mock
(
'
~/flash
'
);
describe
(
'
Logs Store actions
'
,
()
=>
{
let
state
;
let
mock
;
beforeEach
(()
=>
{
state
=
logsPageState
();
});
afterEach
(()
=>
{
flash
.
mockClear
();
});
describe
(
'
setLogsEndpoint
'
,
()
=>
{
it
(
'
should commit SET_LOGS_ENDPOINT mutation
'
,
done
=>
{
testAction
(
setLogsEndpoint
,
mockLogsEndpoint
,
state
,
[{
type
:
types
.
SET_LOGS_ENDPOINT
,
payload
:
mockLogsEndpoint
}],
[],
done
,
);
});
});
describe
(
'
fetchEnvironments
'
,
()
=>
{
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
it
(
'
should commit RECEIVE_ENVIRONMENTS_DATA_SUCCESS mutation on correct data
'
,
done
=>
{
mock
.
onGet
(
mockEnvironmentsEndpoint
).
replyOnce
(
200
,
{
environments
:
mockEnvironments
});
testAction
(
fetchEnvironments
,
mockEnvironmentsEndpoint
,
state
,
[
{
type
:
types
.
REQUEST_ENVIRONMENTS_DATA
},
{
type
:
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
,
payload
:
mockEnvironments
},
],
[],
done
,
);
});
it
(
'
should commit RECEIVE_ENVIRONMENTS_DATA_ERROR on wrong data
'
,
done
=>
{
mock
.
onGet
(
mockEnvironmentsEndpoint
).
replyOnce
(
500
);
testAction
(
fetchEnvironments
,
mockEnvironmentsEndpoint
,
state
,
[
{
type
:
types
.
REQUEST_ENVIRONMENTS_DATA
},
{
type
:
types
.
RECEIVE_ENVIRONMENTS_DATA_ERROR
},
],
[],
()
=>
{
expect
(
flash
).
toHaveBeenCalledTimes
(
1
);
done
();
},
);
});
it
(
'
should commit RECEIVE_ENVIRONMENTS_DATA_ERROR on error
'
,
done
=>
{
mock
.
onGet
(
'
/root/autodevops-deploy/environments.json
'
).
replyOnce
(
500
);
testAction
(
fetchEnvironments
,
'
/root/autodevops-deploy/environments.json
'
,
state
,
[
{
type
:
types
.
REQUEST_ENVIRONMENTS_DATA
},
{
type
:
types
.
RECEIVE_ENVIRONMENTS_DATA_ERROR
},
],
[],
()
=>
{
expect
(
flash
).
toHaveBeenCalledTimes
(
1
);
done
();
},
);
});
});
describe
(
'
fetchLogs
'
,
()
=>
{
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
it
(
'
should commit logs and pod data when there is pod name defined
'
,
done
=>
{
state
.
logs
.
endpoint
=
mockLogsEndpoint
;
mock
.
onGet
(
mockLogsEndpoint
).
replyOnce
(
200
,
{
pods
:
mockPods
,
logs
:
mockLines
,
});
testAction
(
fetchLogs
,
mockPodName
,
state
,
[
{
type
:
types
.
SET_CURRENT_POD_NAME
,
payload
:
mockPodName
},
{
type
:
types
.
REQUEST_PODS_DATA
},
{
type
:
types
.
REQUEST_LOGS_DATA
},
{
type
:
types
.
RECEIVE_PODS_DATA_SUCCESS
,
payload
:
mockPods
},
{
type
:
types
.
RECEIVE_LOGS_DATA_SUCCESS
,
payload
:
mockLines
},
],
[],
done
,
);
});
it
(
'
should commit logs and pod data when no pod name defined
'
,
done
=>
{
state
.
logs
.
endpoint
=
mockLogsEndpoint
;
mock
.
onGet
(
mockLogsEndpoint
).
replyOnce
(
200
,
{
pods
:
mockPods
,
logs
:
mockLines
,
});
testAction
(
fetchLogs
,
null
,
state
,
[
{
type
:
types
.
REQUEST_PODS_DATA
},
{
type
:
types
.
REQUEST_LOGS_DATA
},
{
type
:
types
.
SET_CURRENT_POD_NAME
,
payload
:
mockPods
[
0
]
},
{
type
:
types
.
RECEIVE_PODS_DATA_SUCCESS
,
payload
:
mockPods
},
{
type
:
types
.
RECEIVE_LOGS_DATA_SUCCESS
,
payload
:
mockLines
},
],
[],
done
,
);
});
it
(
'
should commit logs and pod errors
'
,
done
=>
{
state
.
logs
.
endpoint
=
mockLogsEndpoint
;
mock
.
onGet
(
mockLogsEndpoint
).
replyOnce
(
500
);
testAction
(
fetchLogs
,
mockPodName
,
state
,
[
{
type
:
types
.
SET_CURRENT_POD_NAME
,
payload
:
mockPodName
},
{
type
:
types
.
REQUEST_PODS_DATA
},
{
type
:
types
.
REQUEST_LOGS_DATA
},
{
type
:
types
.
RECEIVE_PODS_DATA_ERROR
},
{
type
:
types
.
RECEIVE_LOGS_DATA_ERROR
},
],
[],
()
=>
{
expect
(
flash
).
toHaveBeenCalledTimes
(
1
);
done
();
},
);
});
});
});
ee/spec/frontend/logs/stores/mutations_spec.js
0 → 100644
View file @
a7e1d16b
import
mutations
from
'
ee/logs/stores/mutations
'
;
import
*
as
types
from
'
ee/logs/stores/mutation_types
'
;
import
logsPageState
from
'
ee/logs/stores/state
'
;
import
{
mockLogsEndpoint
,
mockEnvironments
,
mockPods
,
mockPodName
,
mockLines
,
}
from
'
../mock_data
'
;
describe
(
'
Logs Store Mutations
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
logsPageState
();
});
it
(
'
ensures mutation types are correctly named
'
,
()
=>
{
Object
.
keys
(
types
).
forEach
(
k
=>
{
expect
(
k
).
toEqual
(
types
[
k
]);
});
});
describe
(
'
SET_LOGS_ENDPOINT
'
,
()
=>
{
it
(
'
sets the logs json endpoint
'
,
()
=>
{
mutations
[
types
.
SET_LOGS_ENDPOINT
](
state
,
mockLogsEndpoint
);
expect
(
state
.
logs
.
endpoint
).
toEqual
(
mockLogsEndpoint
);
});
});
describe
(
'
SET_CURRENT_POD_NAME
'
,
()
=>
{
it
(
'
sets current pod name
'
,
()
=>
{
mutations
[
types
.
SET_CURRENT_POD_NAME
](
state
,
mockPodName
);
expect
(
state
.
pods
.
current
).
toEqual
(
mockPodName
);
});
});
describe
(
'
REQUEST_ENVIRONMENTS_DATA
'
,
()
=>
{
it
(
'
inits data
'
,
()
=>
{
mutations
[
types
.
REQUEST_ENVIRONMENTS_DATA
](
state
);
expect
(
state
.
environments
.
options
).
toEqual
([]);
expect
(
state
.
environments
.
isLoading
).
toEqual
(
true
);
});
});
describe
(
'
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
'
,
()
=>
{
it
(
'
receives environments data and stores it as options
'
,
()
=>
{
expect
(
state
.
environments
.
options
).
toEqual
([]);
mutations
[
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
](
state
,
mockEnvironments
);
expect
(
state
.
environments
.
options
).
toEqual
(
mockEnvironments
);
expect
(
state
.
environments
.
isLoading
).
toEqual
(
false
);
});
});
describe
(
'
RECEIVE_ENVIRONMENTS_DATA_ERROR
'
,
()
=>
{
it
(
'
captures an error loading environments
'
,
()
=>
{
mutations
[
types
.
RECEIVE_ENVIRONMENTS_DATA_ERROR
](
state
);
expect
(
state
.
environments
).
toEqual
({
options
:
[],
isLoading
:
false
,
});
});
});
describe
(
'
REQUEST_LOGS_DATA
'
,
()
=>
{
it
(
'
starts loading for logs
'
,
()
=>
{
mutations
[
types
.
REQUEST_LOGS_DATA
](
state
);
expect
(
state
.
logs
).
toEqual
(
expect
.
objectContaining
({
lines
:
[],
isLoading
:
true
,
isComplete
:
false
,
}),
);
});
});
describe
(
'
RECEIVE_LOGS_DATA_SUCCESS
'
,
()
=>
{
it
(
'
receives logs lines
'
,
()
=>
{
mutations
[
types
.
RECEIVE_LOGS_DATA_SUCCESS
](
state
,
mockLines
);
expect
(
state
.
logs
).
toEqual
(
expect
.
objectContaining
({
lines
:
mockLines
,
isLoading
:
false
,
isComplete
:
true
,
}),
);
});
});
describe
(
'
RECEIVE_LOGS_DATA_ERROR
'
,
()
=>
{
it
(
'
receives log data error and stops loading
'
,
()
=>
{
mutations
[
types
.
RECEIVE_LOGS_DATA_ERROR
](
state
);
expect
(
state
.
logs
).
toEqual
(
expect
.
objectContaining
({
lines
:
[],
isLoading
:
false
,
isComplete
:
true
,
}),
);
});
});
describe
(
'
REQUEST_PODS_DATA
'
,
()
=>
{
it
(
'
receives log data error and stops loading
'
,
()
=>
{
mutations
[
types
.
REQUEST_PODS_DATA
](
state
);
expect
(
state
.
pods
).
toEqual
(
expect
.
objectContaining
({
options
:
[],
}),
);
});
});
describe
(
'
RECEIVE_PODS_DATA_SUCCESS
'
,
()
=>
{
it
(
'
receives pods data success
'
,
()
=>
{
mutations
[
types
.
RECEIVE_PODS_DATA_SUCCESS
](
state
,
mockPods
);
expect
(
state
.
pods
).
toEqual
(
expect
.
objectContaining
({
options
:
mockPods
,
}),
);
});
});
describe
(
'
RECEIVE_PODS_DATA_ERROR
'
,
()
=>
{
it
(
'
receives pods data error
'
,
()
=>
{
mutations
[
types
.
RECEIVE_PODS_DATA_ERROR
](
state
);
expect
(
state
.
pods
).
toEqual
(
expect
.
objectContaining
({
options
:
[],
}),
);
});
});
});
locale/gitlab.pot
View file @
a7e1d16b
...
...
@@ -10508,6 +10508,9 @@ msgstr ""
msgid "Metrics|There was an error fetching the environments data, please try again"
msgstr ""
msgid "Metrics|There was an error fetching the logs, please try again"
msgstr ""
msgid "Metrics|There was an error getting deployment information."
msgstr ""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment