Browse Source

Add redux integration tests for build actions

This also moves the build "slice" of our redux state into an
initialState variable that allow using the same state for testing.

We should move the others slices to the initialState later on as well.

Change-Id: Id1a476a3b82df530a859732f8dab9ef7c11939e5
changes/04/755504/7
Felix Edel 4 weeks ago
parent
commit
97810c00b1
No known key found for this signature in database GPG Key ID: E95717A102DD3030
4 changed files with 253 additions and 12 deletions
  1. +2
    -2
      web/src/actions/build.js
  2. +3
    -10
      web/src/reducers/build.js
  3. +9
    -0
      web/src/reducers/initialState.js
  4. +239
    -0
      web/src/store.test.js

+ 2
- 2
web/src/actions/build.js View File

@@ -140,7 +140,7 @@ export function taskPathMatches (ref, test) {
}


const receiveBuildOutput = (buildId, output) => {
export const receiveBuildOutput = (buildId, output) => {
const hosts = {}
// Compute stats
output.forEach(phase => {
@@ -220,7 +220,7 @@ export const requestBuildManifest = () => ({
type: BUILD_MANIFEST_REQUEST
})

const receiveBuildManifest = (buildId, manifest) => {
export const receiveBuildManifest = (buildId, manifest) => {
const index = {}

const renderNode = (root, object) => {


+ 3
- 10
web/src/reducers/build.js View File

@@ -27,16 +27,9 @@ import {
BUILD_MANIFEST_SUCCESS,
} from '../actions/build'

export default (
state = {
isFetching: false,
isFetchingOutput: false,
isFetchingManifest: false,
builds: {},
buildsets: {},
},
action
) => {
import initialState from './initialState'

export default (state = initialState.build, action) => {
switch (action.type) {
case BUILD_FETCH_REQUEST:
case BUILDSET_FETCH_REQUEST:


+ 9
- 0
web/src/reducers/initialState.js View File

@@ -0,0 +1,9 @@
export default {
build: {
builds: {},
buildsets: {},
isFetching: false,
isFetchingOutput: false,
isFetchingManifest: false,
},
}

+ 239
- 0
web/src/store.test.js View File

@@ -0,0 +1,239 @@
import { createStore } from 'redux'

import rootReducer from './reducers'
import initialState from './reducers/initialState'
import * as buildActions from './actions/build'

it('should fetch a build', () => {
const store = createStore(rootReducer, initialState)
const build = {
uuid: '1234',
job_name: 'run-tox',
}

const action = buildActions.receiveBuild(build.uuid, build)
store.dispatch(action)

const fetchedBuild = store.getState().build.builds[build.uuid]
expect(fetchedBuild).toEqual(build)
})

it('should fetch output and update the build in the store', () => {
const store = createStore(rootReducer, initialState)
const build = {
uuid: '1234',
job_name: 'run-tox',
}
const output = [
{
branch: 'master',
index: '0',
phase: 'pre',
playbook: 'opendev.org/opendev/base-jobs/playbooks/base/pre.yaml',
plays: [
{
play: {
duration: {
end: '2020-09-24T23:24:02.272988Z',
start: '2020-09-24T23:23:52.900231Z',
},
id: 'bc764e04-8d26-889a-2270-000000000006',
name: 'localhost',
},
tasks: [
{
hosts: {
localhost: {
action: 'include_role',
changed: false,
include_args: {
name: 'set-zuul-log-path-fact',
},
},
},
role: {
id: 'bc764e04-8d26-889a-2270-000000000009',
name: 'emit-job-header',
path:
'/var/lib/zuul/builds/79dea00ae4dd4943a09a8bb701488bb5/trusted/project_1/opendev.org/zuul/zuul-jobs/roles/emit-job-header',
},
task: {
duration: {
end: '2020-09-24T23:23:55.818592Z',
start: '2020-09-24T23:23:55.724571Z',
},
id: 'bc764e04-8d26-889a-2270-00000000000c',
name: 'Setup log path fact',
},
},
],
},
],
stats: {
localhost: {
changed: 2,
failures: 0,
ignored: 0,
ok: 6,
rescued: 0,
skipped: 5,
unreachable: 0,
},
'ubuntu-bionic': {
changed: 22,
failures: 0,
ignored: 0,
ok: 47,
rescued: 0,
skipped: 7,
unreachable: 0,
},
},
trusted: true,
},
]

// Fetch the build
store.dispatch(buildActions.receiveBuild(build.uuid, build))

// Fetch the output
store.dispatch(buildActions.receiveBuildOutput(build.uuid, output))

const newState = store.getState()
expect(Object.keys(newState.build.builds).length).toEqual(1)

const expectedHosts = {
localhost: {
changed: 2,
failures: 0,
ignored: 0,
ok: 6,
rescued: 0,
skipped: 5,
unreachable: 0,
failed: [],
},
'ubuntu-bionic': {
changed: 22,
failures: 0,
ignored: 0,
ok: 47,
rescued: 0,
skipped: 7,
unreachable: 0,
failed: [],
},
}

const fetchedBuild = newState.build.builds[build.uuid]
expect(fetchedBuild.errorIds).toEqual(new Set())
expect(fetchedBuild.hosts).toEqual(expectedHosts)
expect(fetchedBuild.output).toEqual(output)
})

it('should fetch manifest and update the build in the store', () => {
const store = createStore(rootReducer, initialState)
const build = {
uuid: '1234',
job_name: 'run-tox',
}
const manifest = {
tree: [
{
name: 'zuul-info',
mimetype: 'application/directory',
encoding: null,
children: [
{
name: 'host-info.ubuntu-bionic.yaml',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600989879,
size: 12895,
},
{
name: 'inventory.yaml',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600989840,
size: 3734,
},
{
name: 'zuul-info.ubuntu-bionic.txt',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600989881,
size: 2584,
},
],
},
{
name: 'job-output.json',
mimetype: 'application/json',
encoding: null,
last_modified: 1600990084,
size: 612933,
},
{
name: 'job-output.txt',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600990088,
size: 84764,
},
],
}

// Fetch the build
store.dispatch(buildActions.receiveBuild(build.uuid, build))

// Fetch the manifest
store.dispatch(buildActions.receiveBuildManifest(build.uuid, manifest))

const newState = store.getState()
expect(Object.keys(newState.build.builds).length).toEqual(1)

const expectedManifestIndex = {
'/zuul-info/host-info.ubuntu-bionic.yaml': {
name: 'host-info.ubuntu-bionic.yaml',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600989879,
size: 12895,
},
'/zuul-info/inventory.yaml': {
name: 'inventory.yaml',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600989840,
size: 3734,
},
'/zuul-info/zuul-info.ubuntu-bionic.txt': {
name: 'zuul-info.ubuntu-bionic.txt',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600989881,
size: 2584,
},
'/job-output.json': {
name: 'job-output.json',
mimetype: 'application/json',
encoding: null,
last_modified: 1600990084,
size: 612933,
},
'/job-output.txt': {
name: 'job-output.txt',
mimetype: 'text/plain',
encoding: null,
last_modified: 1600990088,
size: 84764,
},
}

const fetchedBuild = newState.build.builds[build.uuid]
expect(fetchedBuild.manifest).toEqual({
index: expectedManifestIndex,
tree: manifest.tree,
})
})

Loading…
Cancel
Save