From 77d6df6531591ece9d50e177bec6045f13c97ff5 Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Mon, 18 Feb 2013 16:09:40 -0500 Subject: [PATCH] basic ec2 and s3 working --- Makefile | 11 ++ README.md | 2 +- moto/__init__.py | 2 + moto/__init__.pyc | Bin 0 -> 233 bytes moto/core/__init__.py | 1 + moto/core/__init__.pyc | Bin 0 -> 197 bytes moto/core/models.py | 40 +++++++ moto/core/models.pyc | Bin 0 -> 1762 bytes moto/ec2/__init__.py | 2 + moto/ec2/__init__.pyc | Bin 0 -> 234 bytes moto/ec2/models.py | 44 +++++++ moto/ec2/models.pyc | Bin 0 -> 2063 bytes moto/ec2/responses.py | 224 ++++++++++++++++++++++++++++++++++++ moto/ec2/responses.pyc | Bin 0 -> 9317 bytes moto/ec2/urls.py | 5 + moto/ec2/urls.pyc | Bin 0 -> 194 bytes moto/ec2/utils.py | 15 +++ moto/ec2/utils.pyc | Bin 0 -> 1121 bytes moto/s3/__init__.py | 2 + moto/s3/__init__.pyc | Bin 0 -> 231 bytes moto/s3/models.py | 57 +++++++++ moto/s3/models.pyc | Bin 0 -> 2674 bytes moto/s3/responses.py | 72 ++++++++++++ moto/s3/responses.pyc | Bin 0 -> 2541 bytes moto/s3/urls.py | 6 + moto/s3/urls.pyc | Bin 0 -> 278 bytes requirements.txt | 6 + setup.py | 14 +++ tests/__init__.pyc | Bin 0 -> 135 bytes tests/test_ec2/test_ec2.py | 29 +++++ tests/test_ec2/test_ec2.pyc | Bin 0 -> 1167 bytes tests/test_s3/test_s3.py | 30 +++++ tests/test_s3/test_s3.pyc | Bin 0 -> 1514 bytes 33 files changed, 561 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 moto/__init__.py create mode 100644 moto/__init__.pyc create mode 100644 moto/core/__init__.py create mode 100644 moto/core/__init__.pyc create mode 100644 moto/core/models.py create mode 100644 moto/core/models.pyc create mode 100644 moto/ec2/__init__.py create mode 100644 moto/ec2/__init__.pyc create mode 100644 moto/ec2/models.py create mode 100644 moto/ec2/models.pyc create mode 100644 moto/ec2/responses.py create mode 100644 moto/ec2/responses.pyc create mode 100644 moto/ec2/urls.py create mode 100644 moto/ec2/urls.pyc create mode 100644 moto/ec2/utils.py create mode 100644 moto/ec2/utils.pyc create mode 100644 moto/s3/__init__.py create mode 100644 moto/s3/__init__.pyc create mode 100644 moto/s3/models.py create mode 100644 moto/s3/models.pyc create mode 100644 moto/s3/responses.py create mode 100644 moto/s3/responses.pyc create mode 100644 moto/s3/urls.py create mode 100644 moto/s3/urls.pyc create mode 100644 requirements.txt create mode 100644 setup.py create mode 100644 tests/__init__.pyc create mode 100644 tests/test_ec2/test_ec2.py create mode 100644 tests/test_ec2/test_ec2.pyc create mode 100644 tests/test_s3/test_s3.py create mode 100644 tests/test_s3/test_s3.pyc diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..94deffdd0 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +SHELL := /bin/bash + +init: + python setup.py develop + pip install -r requirements.txt + +test: + nosetests ./tests/ + +travis: + nosetests ./tests/ diff --git a/README.md b/README.md index 962983d9f..204f20bc4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ Imagine you have the following code that you want to test: ```python import boto from boto.s3.key import Key -conn = boto.connect_s3() class MyModel(object): def __init__(self, name, value): @@ -17,6 +16,7 @@ class MyModel(object): self.value = value def save(self): + conn = boto.connect_s3() bucket = conn.get_bucket('mybucket') k = Key(bucket) k.key = self.name diff --git a/moto/__init__.py b/moto/__init__.py new file mode 100644 index 000000000..8da1c85e7 --- /dev/null +++ b/moto/__init__.py @@ -0,0 +1,2 @@ +from .ec2 import mock_ec2 +from .s3 import mock_s3 diff --git a/moto/__init__.pyc b/moto/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0969fbd608532b765edf72fff4d50ba922b6c5bd GIT binary patch literal 233 zcmZSn%*&-dLn$zs0ScHH7#JKF7#NCG7#J8*7#LC*8FCmHav2$-7#SErd?tn*CWc&Q zhA3tR#uR3TU=0=q28K*V1_lNV5K+Rxz`&53pPU_^nrs9SVP}Af6dU`2RhKX`FfgPh z8wG*vECJbAY#apAtN{{05XJfo3=I0A#i>Qb`o#sMIjPC|E~#ayIr#;-sd**(x%nme i5F$Q4GcU6wK3=b&5^TRsZhlH>PO2Tq%wmxF0*n9~|0
    qM!gqwkZ!6~sg)hRJKJ2fxGPXlB^2^#|gLvDUbYEE$w$Y2drqS%Cifk8jC zIJKx)zqp_@CpB5$CABOyC%+&!HLpZJH@_qwLL}!GrRvAWXXa&=#K-FuRF-fsFfiEU Q=BJeAq}qY3F9sP50MLafSO5S3 literal 0 HcmV?d00001 diff --git a/moto/core/models.py b/moto/core/models.py new file mode 100644 index 000000000..f24974d56 --- /dev/null +++ b/moto/core/models.py @@ -0,0 +1,40 @@ +import functools +import re + +from httpretty import HTTPretty + + +class BaseBackend(object): + base_url = None + + def reset(self): + self = self.__class__() + + @property + def urls(self): + backend_module = self.__class__.__module__ + backend_urls_module_name = backend_module.replace("models", "urls") + backend_urls_module = __import__(backend_urls_module_name, fromlist=['urls']) + urls = backend_urls_module.urls + return urls + + def decorator(self, func): + @functools.wraps(func) + def wrapper(*args, **kw): + self.reset() + + HTTPretty.reset() + HTTPretty.enable() + + for method in HTTPretty.METHODS: + for key, value in self.urls.iteritems(): + HTTPretty.register_uri( + method=method, + uri=re.compile(self.base_url + key), + body=value, + ) + try: + return func(*args, **kw) + finally: + HTTPretty.disable() + return wrapper diff --git a/moto/core/models.pyc b/moto/core/models.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0eaf077ad6856a94d4ea33bce4428f9e9c117a8d GIT binary patch literal 1762 zcmZSn%*$0bT`4e`0ScHI7#JKF7#ND37#J8*7#LC*8FCmHqTp;shA2j`I1@t-6GJXD zLliRuV+u1vDhopzBSQ)cLkj~#GXq0p6e~z;um&pw14HKj|NsB{X)rP{FqCjIFfe$8 zgaj0&mXuVMa5FG4I3*URIwdA&r{<-=UBLtr2f0F@fq@~F0cBV2?jd}$zk#F$vKI| z#qsfAi4u@O#i==I8lbQN6U9ah3=I0A#i>Qb`o#sMIjPC|E~#ayIr#;-sd**(x%nme z5F$ChC{;fw4(gnoXp}9aJ&S890GPye0*+xN@-4Ne0&Kz0|P@*YC%q7 zGQ_p<@tL^=`9&r1@j)O%AsRucq=b)wfguSJaZv3g5=cTIJE7w7d5O8HCBoPxA;wY~ z#9&i+L7@u@Vg@E2Mj=K~Moz|LkRL(Lh2dgVP%>m-$YNyZ0EHk!J0n9o149}(pxYQ2 zni)X>UBko>tO3&M2TqfqXac2Nd5{GQ85lrXAt{Nmgb|viz$_+E;%BUgWdI2?Gq}VC zflRCL1Z!Yn$YKS_yTn>B#4s_`GJ_%wq>v31$)Jd3Vklu}$l?I2<^)Bocrzm?x@%Y% zni-fG3+))f3pE(Rs{|Q3z^S>0k)e-)AvipR0c;@`$aKbt6b96EkXn+FpHcz}fYPE& zaC%6}PpQ-ZWxgO#;tK)=J~+vw<|QWOq=M6cuWN{hze_MUT*0|Evm~`Bvm`aQxP%9s zMA9>hOHzyCK}LcCstBSjIX|}`Gba_C*pd>9Q{zjEa=_-LWEO+W2B#me8xo7si%UQ{ zv&(}(NeS%0>{Li*DND>LO$A2)SZ!KqUUCq~0~F;#P|_|hN-QWyEfNDoBq+5qFmW+) zF>)~pFv>7;GO{s>G4eApGYT?6>;}a-$nKK-{G4KNE(Yl@)&MyL?4BT51_p*8IR*v> zu*<-@5EA4T7a(g>Qj_zG5=-)nL_tmkMH2&~qL7~kC>Mi6Hy)g;;^TwBA|M5R`FW{9 z;vffscwj{ZMfnA(MJ1KsXbe(>yAu@SU>B3=#2`@F3JT9+knL=YY)qWY{2Usf5+Vqc zNrFJG1}B@0l9B>&VUI{<`AJ!+$t7STz-~YgWV#0IRU1eVW(RUvF~}i2j66&N%m4yr BXMz9# literal 0 HcmV?d00001 diff --git a/moto/ec2/__init__.py b/moto/ec2/__init__.py new file mode 100644 index 000000000..f64708fee --- /dev/null +++ b/moto/ec2/__init__.py @@ -0,0 +1,2 @@ +from .models import ec2_backend +mock_ec2 = ec2_backend.decorator \ No newline at end of file diff --git a/moto/ec2/__init__.pyc b/moto/ec2/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aad71507dad0bda4393b30aea7d51b4c9acc4713 GIT binary patch literal 234 zcmZSn%*!Pjs}z{b00m483=9qo3=GAx3=9k@3=AoZ3^@!8xr_`^j0}vaj0{;!3{lJs zDNGE(8q5p~44I4!3=A3|qJ*1)fgv^7C_X7MIXg8k#ZQBUfq|ifje&t7H$Npcr#J{? zLkTCy*wp0wqQsK?q7n|UY;tydYO;|ANFG5H8#6F4=!X`k78UCk7nJ6tChNPTmZj$8 x7v!eqmFVZ@m*hi;)MO+5`1s7c%#!$cy@E=xnKrrkDWy57b|8lpgS;fb2mpM8FhBqR literal 0 HcmV?d00001 diff --git a/moto/ec2/models.py b/moto/ec2/models.py new file mode 100644 index 000000000..6d6013d42 --- /dev/null +++ b/moto/ec2/models.py @@ -0,0 +1,44 @@ +from boto.ec2.instance import Instance, InstanceState, Reservation + +from moto.core import BaseBackend +from .utils import random_instance_id, random_reservation_id + + +class MockEC2(BaseBackend): + base_url = "https://ec2.us-east-1.amazonaws.com" + + def __init__(self): + self.reservations = {} + + def add_instance(self): + new_instance = Instance() + new_instance.id = random_instance_id() + new_instance._state = InstanceState(0, "pending") + + new_reservation = Reservation() + new_reservation.id = random_reservation_id() + new_reservation.instances = [new_instance] + self.reservations[new_reservation.id] = new_reservation + return new_reservation + + def terminate_instances(self, instance_ids): + terminated_instances = [] + for instance in self.all_instances(): + if instance.id in instance_ids: + instance._state = InstanceState(32, 'shutting-down') + terminated_instances.append(instance) + + return terminated_instances + + def all_instances(self): + instances = [] + for reservation in self.all_reservations(): + for instance in reservation.instances: + instances.append(instance) + return instances + + def all_reservations(self): + return self.reservations.values() + + +ec2_backend = MockEC2() \ No newline at end of file diff --git a/moto/ec2/models.pyc b/moto/ec2/models.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7d51b6a296cd827e5bdcb738f8944f6fc26fe51 GIT binary patch literal 2063 zcmZSn%**vSQzC#Ba!d?4EDX7<3{k8Mj48|vDJ%>*Yz(>V3{mV1xf~2p91M&ptPH8F3~7uEDQpZa z3=GW-43SZs45^$TRumUQ3Ohrv1_uKJL+1bg|Nm=%EH43ZJ@bl767!N%OL!R=7+{>> zlEjkK5^e?thM?5q)S|M)lFa-(4MqkA2C$%0VsWZdVsdtBUP>lNP=g61BgDYKP?VUL zlAjx&2{kl6Go?fnAzXwo3?#$Oz`)>}pPcRLYy=M!ka13+K(S_EU`S;Eg+&SjC@fMK zLB5J&W=LTIGguf>n86HIP++t$FhsF2q_BcT*cpO?HP}FgC^IlHWR#Q?6kF-*rzRWe zl@{x!CKi|I8tNtHCRXL=C6*WKCFkcRgKPz1kUyM38bN`P$-q#SwQ+ybJ8?G(F-Pu4H+01^h1kNi;DG&3rcfRll5Iv%Tjal3vyHQO7wH{ zOY$K^YO;}jZhlH?PO)A=B{){%<1_OzOXB0XK!$=`#lQ%5Bq-WI80^RxP^g1rx|Wfl zgb@_cHH-}LObjK=pv08I#L&#d01{zgC}9Q3)-o}auz?sgOdw@7j11|F3?Mc;h^%2? z$l?GovX~fbYM2;;!HL8#6Xc%~P+S#&;yW*0gAUSQ;87!r(v-VqjoMXJDvhVyJKhrH3qVfV;$+ zGt@FO)G#w-F@l0Pn~kAJn4yFTDcqSE;+esr$pTW=%*eo4D9lhO%n*(gvfm6P1BW6bgG;P1ILsLtvY6mOs>~1$4pT-3SQZ6kj}lPa zf&vdI5ful4LNo|eN+H4vECw#qkW>bNiY#zwfC=(~BuJ2ffk6@Ee^4HV_+Nlg6q1cW zkqE+I--Db5%6kl;wA9Q1_XsE{f^!Qvrppp@N>d?44LGL3P6HEUx=);efdQny7-SCv zBe-q=CyMy^yu{qp`1lf#!{g&~^HWN5KwMCEO-d|IjV~?A2?FKmAW$d=iGfN3kY|Hn zCW4KH5M;UyRE&ViiDFRNVPj-t;$-IJ=H%pL_tOAnf)bE*N%uA~ zfy + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + {{ reservation.id }} + 111122223333 + + + sg-245f6a01 + default + + + + {% for instance in reservation.instances %} + + {{ instance.id }} + ami-60a54009 + + 0 + pending + + + + + 0 + m1.small + 2007-08-07T11:51:50.000Z + + us-east-1b + + default + + + enabled + + true + + + sg-245f6a01 + default + + + paravirtual + + xen + false + + {% endfor %} + + """ + +EC2_DESCRIBE_INSTANCES = """ + fdcdcab1-ae5c-489e-9c33-4637c5dda355 + + {% for reservation in reservations %} + + {{ reservation.id }} + 111122223333 + + + sg-1a2b3c4d + my-security-group + + + + {% for instance in reservation.instances %} + + {{ instance.id }} + ami-1a2b3c4d + + 16 + {{ instance.state }} + + + + + gsg-keypair + 0 + + c1.medium + YYYY-MM-DDTHH:MM:SS+0000 + + us-west-2a + + default + + windows + + disabled + + subnet-1a2b3c4d + vpc-1a2b3c4d + 10.0.0.12 + 46.51.219.63 + true + + + sg-1a2b3c4d + my-security-group + + + x86_64 + ebs + /dev/sda1 + + + /dev/sda1 + + vol-1a2b3c4d + attached + YYYY-MM-DDTHH:MM:SS.SSSZ + true + + + + hvm + ABCDE1234567890123 + + + Name + Windows Instance + + + xen + + + eni-1a2b3c4d + subnet-1a2b3c4d + vpc-1a2b3c4d + Primary network interface + 111122223333 + in-use + 10.0.0.12 + 1b:2b:3c:4d:5e:6f + true + + + sg-1a2b3c4d + my-security-group + + + + eni-attach-1a2b3c4d + 0 + attached + YYYY-MM-DDTHH:MM:SS+0000 + true + + + 46.51.219.63 + 111122223333 + + + + 10.0.0.12 + true + + 46.51.219.63 + 111122223333 + + + + 10.0.0.14 + false + + 46.51.221.177 + 111122223333 + + + + + + + {% endfor %} + + + {% endfor %} + +""" + +EC2_TERMINATE_INSTANCES = """ + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + + {% for instance in instances %} + + {{ instance.id }} + + 32 + shutting-down + + + 16 + running + + + {% endfor %} + +""" \ No newline at end of file diff --git a/moto/ec2/responses.pyc b/moto/ec2/responses.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83c92271b2cc7a3bb0f6ded1839a8b260aeb0c5c GIT binary patch literal 9317 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 HOw5b`Mj0SX literal 0 HcmV?d00001 diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py new file mode 100644 index 000000000..190ff4cdf --- /dev/null +++ b/moto/ec2/utils.py @@ -0,0 +1,15 @@ +import random + + +def random_id(prefix=''): + size = 8 + chars = range(10) + ['a', 'b', 'c', 'd', 'e', 'f'] + + instance_tag = ''.join(unicode(random.choice(chars)) for x in range(size)) + return '{}-{}'.format(prefix, instance_tag) + +def random_instance_id(): + return random_id(prefix='i') + +def random_reservation_id(): + return random_id(prefix='r') diff --git a/moto/ec2/utils.pyc b/moto/ec2/utils.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5395cf96ad9b467770dcd93c858a9f35620c055 GIT binary patch literal 1121 zcmZSn%**v4L@6+t0ScHH7#JKF7#NE67#J8*7#LC*8FCmHq8J!bm>5!+8Cn<_q8J%c zSQuIu7^0XMQdq$ZW{|RA4K@Y_hRpx}|Nr+Z0hyM}$iTqB%)r3F4yB7@L1r>C)G{)Z zfDLSB1euw_0x~CsjUk1dA%%k>osB`flYt?HlOcXl7&xV=QC_g-@^s$O=CVkUvX6 z9xctwOwLb9Edd2aQDR<7elD1qoROcIoT>q`q69?f8GvoC0BbK{Wnf@P&PXgO)&M!C z*nok7K|i!OwWwIXxS%vAHCf*!wJbF!zaTd?uS7pLza$?*q$V5bmzHGa6zdgK7IQK% zFxaH0=A~8?6xo47pcrHi8$&V3@akIK>RN~+LENImy!6x(kYBU%GxNX>Ov^9IO)P;Z z0lB@PC^ap!0<5MuvnsU&6tbCl#U+V($*J)riRoaMf?Xd3k|N8^B_KCL0x3Q-1>~G! zki!`m*%+0WR2kuk5)`=3ph)2b#VI&ZrZ6!yGcX2&-Rl=501^j9L?*;V!VC-y5C?+7 z6U-vdfkF%n3@``6JfE4u4RQ-8bQ#ETV-c0zD2i}nQEG8&QCVV1W`16LW(ps|nHr$L p4FUyj5GZVdKzf42sTE2fb8T|-Q%ZAE?Le_m3`#&e%slLz%m8O*-T43j literal 0 HcmV?d00001 diff --git a/moto/s3/__init__.py b/moto/s3/__init__.py new file mode 100644 index 000000000..441b59965 --- /dev/null +++ b/moto/s3/__init__.py @@ -0,0 +1,2 @@ +from .models import s3_backend +mock_s3 = s3_backend.decorator \ No newline at end of file diff --git a/moto/s3/__init__.pyc b/moto/s3/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d172de9a46ae9d6213dc15f17b7ec0cfcee8935e GIT binary patch literal 231 zcmZSn%*)j^T`4e`0ScHH7#JKF7#NCW85kH+7#LC*8FCmHav2$-7#SE-85y#e7^0XN zQkWQmHJBL~7%~|d7#K7_LJ vE78x*FUf}x#m4&a@tJvvaql_7y;CdUj%5O=0XbHI zfq@~Ffgy?!f!G!Vna!0aBd|@*fC;IL;ugVhjunHH-{33=HuM z3^hz(2H2Qjusi&~+Dcd$7#Q*rb5l!L85kJK5_3vZH9)3-#fwvO(t<$d1%ZS#KmiFR ziVYYT81zGnQ;UlAiwjC~Qj_&vQp-|v@(XfP^Gft{^Gos}M6t1cZhlH?PO)A=WeEoZ z14Dd#W?p7Vd^{(}fgr0H7&#e}LBRsD286***9V0Y149-gC>(1ULEgv$dmxLMp_!3^ zF@=#Kiv=vo3R2O`$N&ihzhaOtl&TGCl{DBuW`NwCn_^l5qVrPAOF)991u2OosbDXG z`Dyt@xrrquASY#{R-|O6rxurh!zKviK(IJCT;g+6Ou^m<6Xb;f$i&o=#B^Se|3Qvn zVB%pEVAKFP8yY~M$cT?G;R1(NZhlH>PHKF75L`h)QGP*cQAuSG4+8@O*d+*pEH?## zLLU@2#URJAF>@vz=?$E~gFsOb#K*wE01jJ(C14hLAt}JXz#t5= z2^0csjNsJeo1dH=Y>XL(*2rNP#RSdLQOpb}OrVkkRN^p$8LZH9D2feK27!tIc2J%N zC7xng1_p+Vl9GaAD}8+pJ#9_BVq?9;+{CKp(4q-c6eWQpy%=0ZfO7yiK)?ifp#lnj8Ca+=FoKf^C_jQQ*h!!=t^`~l*MKrS zV=WW3xXJ?Oe4833SoVgb2asQaKw%vO3T#Mhg5nljvO=6656VU0bexx39uE-%djU+4 z<&P3j$R!u0CYGc^4U`9Y3KS0vjQote5RZY}2Et&Ef!tWbz>ozl$v}Psl~bVDfRw#p z=Yxx;^i-r0CkT{S!R`bTxwjPBlPg zgM9@qRDwX|1UM5U78IoBrGSfMaFPOh5nSG7r&faF3alTj77|(DS`id?*{PM_U;q>3 zg#{>87pIoQXQx)Gg8~9n*fB8jGKw+^FoCO0P;kIgqYG+qFoP=IS{8;1EruFqP!PDp z$}@n%gB2VYObppf3`Me_P^o2M2q=_gD3oOguVG<;fvQsPdK;Zx?{6OKr#wftZ&&bBe!K48S8brwm zj-jN);?(%kq8xBB83ZcMgCs!i1eHBOiqxuvgcukYBteb>RcmaFY)qWYoUEM8oa_)M zfno?;6NB0oddc}ksX?ID2spvyCuOB3mq1b+D8~hX%mU~AV&nKENFxiJdJqJ8=?D}! ZHjo\ + {{ bucket.name }}\ + notes/\ + /\ + 1000\ + AKIAIOSFODNN7EXAMPLE\ + 2006-03-01T12:00:00.183Z\ + Iuyz3d3P0aTou39dzbqaEXAMPLE=\ + """ + +S3_BUCKET_CREATE_RESPONSE = """ + + {{ bucket.name }} + +""" + +S3_OBJECT_RESPONSE = """ + + "asdlfkdalsjfsalfkjsadlfjsdjkk" + 2006-03-01T12:00:00.183Z + + """ \ No newline at end of file diff --git a/moto/s3/responses.pyc b/moto/s3/responses.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1f545e196188fd6038df01f6a95faf3ae05a528 GIT binary patch literal 2541 zcmZSn%*(ZZno?jg0~9bZFfceUFfbH*FfcHrFfgPrGUPBYc)Adv4$K>mQZDjwvEAdr3F$S;9LKG^MfspU{xH9&3$6UD|13=I0A#i>Qb`o#sM zIjPC|E~#ayIr#;-sd**(x%nme5Te*vzbLi1AV04-wOFs9vV+0FxLKKO+w#IGu4aFff2z2To_^jIeYDNnxM_#0*VdpmfHngQ13n`ImswrG7Ei zOb`SrVS+%JAP5vO-~ud6qgib z7JyS(5GZd1fl?$SJAk;L?2w&WSpu@5EHS4vHHZgf1W2klwIm)SB?L*}{!U)5&WPL* zBmq(fa$P}6QVA$kfYg^1B_^k8fOz24TUwMEpP84IA0)uQzz_uTC0IB+wGxudL1{k- zWIotmAj?1&gOYi6YGsfD0|Ns%je`lY6FSI4ARA$+9F)L|wLlq&NeG(Gg&5fw*}fw8WEp^}{f7}!8G+f`R9K=QgCD6cEj*4pSpWx&c5Yyyf>(=sdU^72bk zi}h{vpOKMJLZe~epk)6JcK7s?4^-ZksPOU7qGc+(Tu+fL{ppuT^!H&tvsl~Pn>=6D6F*LF=Ft9Q( z&@;3!jlsEGaEYweu{ktTIk94lqaz$uBjwOsPsLOoZBKYom`)2hwPx zj|gbH;_VC!3^vZ-5*HFkLC``BEe_DD5KyF`!~vIr0#vC~!E~g%}1wTn?6V4M|M5Q!6aZFR@N6PRU8jPD#uu&Pppz z%t_16Do#wvNy{ou$;!@#D6!E8s|R}=tlcNExWqRA4bnHW--8O)-X8B$mnf;Ctf7#K1c85kHem>3usO86NV7?Mhpvr|jri&BdV z^7D#QOL!O<7_w6<;R3}VmHH~hAg%fudfJ+P8Z02aoD2*MFipilAh!j93@!mlmKNm{ zYk-6h1lYCup~b01#rnksr8%j|`Yx$usX6%txv6<2`nmZf`4FPmSRbTaub{GogMop; ZCO1E&G$+*#WOgwd0|SE?6Eh<_BLIk-H%R~h literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..430bd5830 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +boto +httpretty +Jinja2 +mock +nose +sure \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..4bfde779e --- /dev/null +++ b/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import sys +from setuptools import setup, find_packages + +setup( + name='moto', + version='0.0.1', + description='Moto is a library that allows your python tests to easily mock out the boto library', + author='Steve Pulec', + author_email='spulec@gmail', + url='https://github.com/spulec/moto', + packages=find_packages() +) \ No newline at end of file diff --git a/tests/__init__.pyc b/tests/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a328373b15a0d37c2e61e72e9b96ff46ba6a8927 GIT binary patch literal 135 zcmZSn%*(a@k6d6f0~9baFfceUFfbIeFfcHrFfasbfJFQ>K+k`EgMMgnYEiL% zaY1QLYO=mdYFTPdenD<(UWtBgeo4N5NosLPv3`7fW?p7Ve7s&kWeEoZ1A|R&eoARh LsvXGaVvxxIiB26D literal 0 HcmV?d00001 diff --git a/tests/test_ec2/test_ec2.py b/tests/test_ec2/test_ec2.py new file mode 100644 index 000000000..90e7e1565 --- /dev/null +++ b/tests/test_ec2/test_ec2.py @@ -0,0 +1,29 @@ +import boto +from boto.ec2.instance import Reservation +from sure import expect + +from moto import mock_ec2 + + + +@mock_ec2 +def test_instance_launch_and_terminate(): + conn = boto.connect_ec2('the_key', 'the_secret') + reservation = conn.run_instances('') + reservation.should.be.a(Reservation) + reservation.instances.should.have.length_of(1) + instance = reservation.instances[0] + + reservations = conn.get_all_instances() + reservations.should.have.length_of(1) + reservations[0].id.should.equal(reservation.id) + instances = reservations[0].instances + instances.should.have.length_of(1) + instances[0].id.should.equal(instance.id) + instances[0].state.should.equal('pending') + + conn.terminate_instances(instances[0].id) + + reservations = conn.get_all_instances() + instance = reservations[0].instances[0] + instance.state.should.equal('shutting-down') diff --git a/tests/test_ec2/test_ec2.pyc b/tests/test_ec2/test_ec2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50053ae6920d0a62fcb0a4f522e1e713bda1f9bb GIT binary patch literal 1167 zcmZSn%**ATs}z{b00m483=9qo3=GBo3=9k@3=AoZ3^@!8Q4ls0Lk=TDE)zo(69Xei zj+r5cnIV^jA&LdUXJN=;Wyob?h+<=4Ol4z8VP$AxU}$D!h++qs6Rg3;z`&6C|NsC0 zej1Dn3=AdQ3=9lGsl};9Wr-!3`FRjQkfPLzg4E;^2%m$2fgv|PIXgZz*$C`RRt5$J zW(EcZXOJ^B85tN#7#Ok`K{li?F*GwV)G{#CFfe2>F{ChqEU#r`s9|KtVrIx0b9Zi zF$F5a&QQz3P{RV2N3n$kO(zpW7E~uxh8L`dham;(SO$hHK9ETum%)@WFk~UQ4lKhC zHW%b{CWb7y8SG$3r7$oAYkZf1&ICMc#dL8$|*uOKxqB{MI*m=_fI8Kos9nR)5DDf#7j8vG!WSQr=>lJZOP z!BLx>pO=@KTmp)?5|H|$(!BW0yyB9?yyVp45>PxBXXKaWq?CXXT~cZZ$fm>~uvMI( zlmb@@GBqQyEVTqAoRgZDUXl@?pH?Esz`&56S`wd_lY?X~$gs?m5>P5hEi6sU0keur z5=&A`gh5VBEy~TzODsu6Xwd+vEdf~qaxvKHMTk^c0tz&kvrBjw7#NTwi-SM{8Xz}= ziDF9z1_u4m;?$yI{o;bsoYZ7}m(;S=$u literal 0 HcmV?d00001 diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py new file mode 100644 index 000000000..0f8444766 --- /dev/null +++ b/tests/test_s3/test_s3.py @@ -0,0 +1,30 @@ +import boto +from boto.s3.key import Key + +from moto import mock_s3 + + +class MyModel(object): + def __init__(self, name, value): + self.name = name + self.value = value + + def save(self): + conn = boto.connect_s3('the_key', 'the_secret') + bucket = conn.get_bucket('mybucket') + k = Key(bucket) + k.key = self.name + k.set_contents_from_string(self.value) + + +@mock_s3 +def test_my_model_save(): + # Create Bucket so that test can run + conn = boto.connect_s3('the_key', 'the_secret') + conn.create_bucket('mybucket') + #################################### + + model_instance = MyModel('steve', 'is awesome') + model_instance.save() + + assert conn.get_bucket('mybucket').get_key('steve').get_contents_as_string() == 'is awesome' diff --git a/tests/test_s3/test_s3.pyc b/tests/test_s3/test_s3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8fe1e7deb573aede2baf0e881fae82d6a27c594f GIT binary patch literal 1514 zcmZSn%**w7no?jg0~9bbFfceUFfbH{GB7ZtFfgPrGUPBYL_ye03^|Mpxl9aEObm=5 zIcA0&W`|(4JHN#hGdY*APnL-gEWaTFfi0GGSo0I#4|9|Fo79h z1A@V}`+>EUurM$%OGJ^b+#l(=p%+Sop zP|E}g(i$c(n;GQAEEa|uW`=lH5ShgW7GVd;g5oe(17y4(IIK%DQsc8zD@(XQc4VZ+ z7pEo{rIvtQms^=snw*_lq5*OqI3SYpOY*@glk@ZPQj<$S5eCwjo>~$QQ5ysb9B^2H zqZnke1Sk?xOX8FB^GZ_lN{Zvtit=;gi%W_!^U@&!3UW;lDBQu8fXpsoV_;x_m{5Xe12 zphyqm1X&G=nc|YvveaTwh-DTlB$lTZ=jWzsfMkO}VnN&>b-bYLSCpDqk_t-|f;PeJcDxg#W%9S8CJXItXL(@bF9|Hq}V{vh6QAuWgo@-H2ei1l}2JwR|0ZHb9 zN{9H&yyB9?yyR5sL_`TFVnLZTKDQDS<*7OGpoAg;U$53CP=^ zJfT-?te2fy2~ParGz`l6L7;>SPRRL5S*gh-;HVCgrf&KHCs-Ru614+aSPY6c9!3Es I0cJ5?03$Lyo&W#< literal 0 HcmV?d00001