• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender-server / 1622978334

13 Jan 2025 03:51PM UTC coverage: 72.802% (-3.8%) from 76.608%
1622978334

Pull #300

gitlab-ci

alfrunes
fix: Deployment device count should not exceed max devices

Added a condition to skip deployments when the device count reaches max
devices.

Changelog: Title
Ticket: MEN-7847
Signed-off-by: Alf-Rune Siqveland <alf.rune@northern.tech>
Pull Request #300: fix: Deployment device count should not exceed max devices

4251 of 6164 branches covered (68.96%)

Branch coverage included in aggregate %.

0 of 18 new or added lines in 1 file covered. (0.0%)

2544 existing lines in 83 files now uncovered.

42741 of 58384 relevant lines covered (73.21%)

21.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.19
/backend/services/deployments/model/configuration_deployment.go
1
// Copyright 2022 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
package model
16

17
import (
18
        "bytes"
19
        "encoding/json"
20
        "time"
21

22
        validation "github.com/go-ozzo/ozzo-validation/v4"
23
        "github.com/pkg/errors"
24
)
25

26
const (
27
        omitted        = "...<omitted>"
28
        lengthOmission = 3
29
)
30

31
// configuration saves the configuration as a binary blob
32
// It unmarshals any JSON type into a binary blob. Strings
33
// are escaped as it's decoded.
34
// The value marshals into a JSON string.
35
type configuration []byte
36

UNCOV
37
func (c *configuration) UnmarshalJSON(b []byte) error {
×
UNCOV
38
        if b == nil {
×
39
                return errors.New("error decoding configuration: received nil pointer buffer")
×
UNCOV
40
        } else if len(b) >= 2 {
×
UNCOV
41
                // Check if JSON value is string
×
UNCOV
42
                bs := bytes.Trim(b, " ")
×
UNCOV
43
                if bs[0] == '"' && bs[len(b)-1] == '"' {
×
UNCOV
44
                        var str string
×
UNCOV
45
                        err := json.Unmarshal(b, &str)
×
UNCOV
46
                        if err == nil {
×
UNCOV
47
                                *c = []byte(str)
×
UNCOV
48
                                return nil
×
UNCOV
49
                        }
×
50
                }
51
        }
52
        *c = append((*c)[0:0], b...)
×
53
        return nil
×
54
}
55

56
// ConfigurationDeploymentConstructor represent input data needed for creating new Configuration
57
// Deployment
58
type ConfigurationDeploymentConstructor struct {
59
        // Deployment name, required
60
        Name string `json:"name"`
61

62
        // A string containing a configuration object.
63
        // The deployments service will use it to generate configuration
64
        // artifact for the device.
65
        // The artifact will be generated when the device will ask
66
        // for an update.
67
        Configuration configuration `json:"configuration,omitempty"`
68

69
        // Retries represents the number of retries in case of deployment failures
70
        Retries uint `json:"retries,omitempty"`
71
}
72

73
// Validate validates the structure.
74
func (c ConfigurationDeploymentConstructor) Validate() error {
1✔
75
        return validation.ValidateStruct(&c,
1✔
76
                validation.Field(&c.Name, validation.Required, lengthIn1To4096),
1✔
77
                validation.Field(&c.Configuration, validation.Required),
1✔
78
        )
1✔
79
}
1✔
80

81
// NewDeploymentWithID creates new configuration deployment object, sets create data by default.
82
func NewDeploymentWithID(ID string) (*Deployment, error) {
1✔
83
        now := time.Now()
1✔
84

1✔
85
        return &Deployment{
1✔
86
                Created: &now,
1✔
87
                Id:      ID,
1✔
88
                Stats:   NewDeviceDeploymentStats(),
1✔
89
                Status:  DeploymentStatusPending,
1✔
90
        }, nil
1✔
91
}
1✔
92

93
// NewConfigurationDeploymentFromConstructor creates new Deployments object based onconfiguration
94
// deployment constructor data
95
func NewDeploymentFromConfigurationDeploymentConstructor(
96
        constructor *ConfigurationDeploymentConstructor,
97
        deploymentID string,
98
) (*Deployment, error) {
1✔
99

1✔
100
        deployment, err := NewDeploymentWithID(deploymentID)
1✔
101
        if err != nil {
1✔
102
                return nil, errors.Wrap(err, "failed to create deployment from constructor")
×
103
        }
×
104

105
        deployment.DeploymentConstructor = &DeploymentConstructor{
1✔
106
                Name: constructor.Name,
1✔
107
                // save constructor name as artifact name just to make deployment valid;
1✔
108
                // this field will be overwritten by the name of the auto-generated
1✔
109
                // configuration artifact
1✔
110
                ArtifactName: constructor.Name,
1✔
111
        }
1✔
112

1✔
113
        deviceCount := 0
1✔
114
        deployment.DeviceCount = &deviceCount
1✔
115

1✔
116
        return deployment, nil
1✔
117
}
118

119
type deploymentConfiguration []byte
120

121
func (c deploymentConfiguration) MarshalJSON() ([]byte, error) {
1✔
122
        var configuration map[string]string
1✔
123
        err := json.Unmarshal(c, &configuration)
1✔
124
        if err != nil {
1✔
125
                return json.Marshal(c)
×
126
        }
×
127
        for key, value := range configuration {
2✔
128
                if len(value) > lengthOmission {
2✔
129
                        configuration[key] = value[0:lengthOmission] + omitted
1✔
130
                }
1✔
131
        }
132
        data, err := json.Marshal(configuration)
1✔
133
        if err != nil {
1✔
134
                return nil, err
×
135
        }
×
136
        return json.Marshal(data)
1✔
137
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc