Completed
Pull Request — master (#77)
by Jindun
03:08
created

ServiceTest::testInvalidRequestMemoryPattern()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TheAentMachine\Registry;
4
5
use PHPUnit\Framework\TestCase;
6
use TheAentMachine\Aenthill\CommonMetadata;
7
use TheAentMachine\Service\Enum\VolumeTypeEnum;
8
use TheAentMachine\Service\Exception\ServiceException;
9
use TheAentMachine\Service\Service;
10
use TheAentMachine\Service\Volume\BindVolume;
11
use TheAentMachine\Service\Volume\NamedVolume;
12
13
class ServiceTest extends TestCase
14
{
15
    private const VALID_PAYLOAD = <<< 'JSON'
16
{
17
  "serviceName" : "foo",
18
  "service": {
19
    "image"         : "foo/bar:baz",
20
    "command"       : ["foo", "-bar", "-baz", "--qux"],
21
    "internalPorts" : [1, 2, 3],
22
    "dependsOn"     : ["foo", "bar"],
23
    "ports"         : [{"source": 80, "target": 8080, "comment": "a line of comment"}],
24
    "environment"   : {
25
                        "FOO": {"value": "foo", "type": "sharedEnvVariable", "comment": "foo"},
26
                        "BAR": {"value": "bar", "type": "sharedSecret", "comment": "bar"},
27
                        "BAZ": {"value": "baz", "type": "imageEnvVariable", "comment": "baz"},
28
                        "QUX": {"value": "qux", "type": "containerEnvVariable", "comment": "qux"}
29
                      },
30
    "labels"        : {
31
                        "foo": {"value": "fooo", "comment": "fooo"},
32
                        "bar": {"value": "baar", "comment": "baar"}
33
                      },               
34
    "volumes"       : [
35
                        {"type": "volume", "source": "foo", "target": "/foo", "readOnly": true, "comment": "it's a named volume tho"},
36
                        {"type": "bind", "source": "/bar", "target": "/bar", "readOnly": false, "comment": "a bind volume"},
37
                        {"type": "tmpfs", "source": "baz", "comment": "a tmpfs"}
38
                      ],
39
    "needVirtualHost": true,
40
    "needBuild": true
41
  },
42
  "dockerfileCommands": [
43
    "RUN composer install"
44
  ],
45
  "destEnvTypes": [
46
    "DEV"
47
  ],
48
  "requestMemory": "64Mi",
49
  "requestCpu": "250m",
50
  "limitMemory": "128Mi",
51
  "limitCpu": "500m"
52
}
53
JSON;
54
55
    private const MISSING_SERVICE_NAME_PAYLOAD = <<< 'JSON'
56
{
57
  "service": {
58
    "internalPorts": [80]
59
  }
60
}
61
JSON;
62
63
    private const UNKNOWN_ENV_VARIABLE_TYPE_PAYLOAD = <<< 'JSON'
64
{
65
  "serviceName": "foo",
66
  "service": {
67
    "environment": {
68
      "FOO": {
69
        "value": "fooo",
70
        "type": "YIKES_THATS_SOME_BAD_TYPE_HERE"
71
      }
72
    }
73
  }
74
}
75
JSON;
76
77
    private const UNKNOWN_VOLUME_TYPE_PAYLOAD = <<< 'JSON'
78
{
79
  "serviceName": "foo",
80
  "service": {
81
    "volumes": [
82
      {
83
        "type": "AGAIN?WTH",
84
        "source": "foo"
85
      }
86
    ]
87
  }
88
}
89
JSON;
90
91
    /** @throws ServiceException */
92
    public function testValidPayload(): void
93
    {
94
        $array = \GuzzleHttp\json_decode(self::VALID_PAYLOAD, true);
95
        $service = Service::parsePayload($array);
96
        $out = $service->jsonSerialize();
97
        $this->assertEquals($array, $out);
98
        $this->assertTrue($service->isForDevEnvType());
99
        $this->assertFalse($service->isForTestEnvType());
100
        $this->assertFalse($service->isForProdEnvType());
101
    }
102
103
    /** @throws ServiceException */
104
    public function testMissingServiceNamePayload(): void
105
    {
106
        $this->expectException(ServiceException::class);
107
        $array = \GuzzleHttp\json_decode(self::MISSING_SERVICE_NAME_PAYLOAD, true);
108
        Service::parsePayload($array)->jsonSerialize();
109
    }
110
111
    /** @throws ServiceException */
112
    public function testUnknownEnvVariableTypePayload(): void
113
    {
114
        $this->expectException(ServiceException::class);
115
        $array = \GuzzleHttp\json_decode(self::UNKNOWN_ENV_VARIABLE_TYPE_PAYLOAD, true);
116
        Service::parsePayload($array)->jsonSerialize();
117
    }
118
119
    /** @throws ServiceException */
120
    public function testUnknownVolumeTypePayload(): void
121
    {
122
        $this->expectException(ServiceException::class);
123
        $array = \GuzzleHttp\json_decode(self::UNKNOWN_VOLUME_TYPE_PAYLOAD, true);
124
        Service::parsePayload($array)->jsonSerialize();
125
    }
126
127
    /** @throws ServiceException */
128
    public function testSettersAndAdders(): void
129
    {
130
        $s = new Service();
131
        $s->setServiceName('foo');
132
        $s->setImage('foo/bar:baz');
133
        $s->setCommand(['foo', '-bar', '-baz']);
134
        $s->addCommand('--qux');
135
        $s->setInternalPorts([1, 2]);
136
        $s->addInternalPort(3);
137
        $s->setDependsOn(['foo']);
138
        $s->addDependsOn('bar');
139
        $s->addPort(80, 8080, 'a line of comment');
140
        $s->addLabel('foo', 'fooo', 'fooo');
141
        $s->addLabel('bar', 'baar', 'baar');
142
        $s->addSharedEnvVariable('FOO', 'foo', 'foo');
143
        $s->addSharedSecret('BAR', 'bar', 'bar');
144
        $s->addImageEnvVariable('BAZ', 'baz', 'baz');
145
        $s->addContainerEnvVariable('QUX', 'qux', 'qux');
146
        $s->addNamedVolume('foo', '/foo', true, 'it\'s a named volume tho');
147
        $s->addBindVolume('/bar', '/bar', false, 'a bind volume');
148
        $s->addTmpfsVolume('baz', 'a tmpfs');
149
        $s->addDockerfileCommand('RUN composer install');
150
        $s->setNeedVirtualHost(true);
151
        $s->setNeedBuild(true);
152
        $s->addDestEnvType(CommonMetadata::ENV_TYPE_DEV, true);
153
        $s->setRequestMemory('64Mi');
154
        $s->setRequestCpu('250m');
155
        $s->setLimitMemory('128Mi');
156
        $s->setLimitCpu('500m');
157
        $outArray = $s->jsonSerialize();
158
        $expectedArray = \GuzzleHttp\json_decode(self::VALID_PAYLOAD, true);
159
        $this->assertEquals($outArray, $expectedArray);
160
161
        $outArray = $s->imageJsonSerialize();
162
        $expectedArray = [
163
            'serviceName' => 'foo',
164
            'dockerfileCommands' => [
165
                'FROM foo/bar:baz',
166
                'ENV BAZ=baz',
167
                'COPY /bar /bar',
168
                'CMD foo -bar -baz --qux',
169
                'RUN composer install'
170
            ],
171
            'destEnvTypes' => ['DEV']
172
        ];
173
        $this->assertEquals($outArray, $expectedArray);
174
    }
175
176
    /** @throws ServiceException */
177
    public function testInvalidRequestMemoryPattern(): void
178
    {
179
        $s = new Service();
180
        $s->setServiceName('foo');
181
        $s->setRequestMemory('0.5Zi');
182
        $this->expectException(ServiceException::class);
183
        $s->jsonSerialize();
184
    }
185
186
    /** @throws ServiceException */
187
    public function testInvalidRequestCpuPattern(): void
188
    {
189
        $s = new Service();
190
        $s->setServiceName('foo');
191
        $s->setRequestCpu('0,1');
192
        $this->expectException(ServiceException::class);
193
        $s->jsonSerialize();
194
    }
195
196
    public function testVolumeRemovers(): void
197
    {
198
        $s = new Service();
199
        $s->setServiceName('my-service');
200
        $s->addBindVolume('./foo', '/opt/app/foo', true);
201
        $s->addBindVolume('./bar', '/opt/app/baz', false);
202
        $s->addNamedVolume('my-data', '/data', true);
203
        $s->removeVolumesBySource('./bar');
204
        /** @var BindVolume[]|NamedVolume[] $volumes */
205
        $volumes = $s->getVolumes();
206
        $this->assertEquals(count($volumes), 2);
207
        $this->assertEquals($volumes[0]->getType(), VolumeTypeEnum::BIND_VOLUME);
208
        $this->assertEquals($volumes[0]->getSource(), './foo');
209
        $this->assertEquals($volumes[1]->getType(), VolumeTypeEnum::NAMED_VOLUME);
210
211
        $s->addBindVolume('./bar', '/opt/app/baz', false);
212
        $s->removeAllBindVolumes();
213
        $volumes = $s->getVolumes();
214
        $this->assertEquals(count($volumes), 1);
215
        $this->assertEquals($volumes[0]->getType(), VolumeTypeEnum::NAMED_VOLUME);
216
        $this->assertEquals($volumes[0]->getTarget(), '/data');
217
    }
218
219
    public function testEnvVariableContains(): void
220
    {
221
        $s = new Service();
222
        $s->setServiceName('my-service');
223
        $s->addSharedSecret('MYSQL_ROOT_PASSWORD', 'foo');
224
        self::assertCount(0, $s->getAllSharedEnvVariable());
225
        self::assertCount(1, $s->getAllSharedSecret());
226
        self::assertCount(0, $s->getAllImageEnvVariable());
227
        self::assertCount(0, $s->getAllContainerEnvVariable());
228
    }
229
}